A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
ipv6-raw-socket-impl.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2007-2009 Strasbourg University
4
*
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 2 as
7
* published by the Free Software Foundation;
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
*
18
* Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
19
*/
20
21
#include <netinet/in.h>
22
#include <sys/socket.h>
23
#include <sys/types.h>
24
#include "ns3/inet6-socket-address.h"
25
#include "ns3/node.h"
26
#include "ns3/packet.h"
27
#include "ns3/uinteger.h"
28
#include "ns3/log.h"
29
#include "ns3/ipv6-route.h"
30
#include "ns3/ipv6-routing-protocol.h"
31
#include "ns3/ipv6-packet-info-tag.h"
32
33
#include "
ipv6-l3-protocol.h
"
34
#include "
ipv6-raw-socket-impl.h
"
35
#include "
icmpv6-header.h
"
36
#include "
icmpv6-l4-protocol.h
"
37
38
namespace
ns3
39
{
40
41
NS_LOG_COMPONENT_DEFINE
(
"Ipv6RawSocketImpl"
);
42
43
44
NS_OBJECT_ENSURE_REGISTERED
(Ipv6RawSocketImpl);
45
46
TypeId
Ipv6RawSocketImpl::GetTypeId
()
47
{
48
static
TypeId
tid =
TypeId
(
"ns3::Ipv6RawSocketImpl"
)
49
.
SetParent
<
Socket
> ()
50
.AddAttribute (
"Protocol"
,
"Protocol number to match."
,
51
UintegerValue
(0),
52
MakeUintegerAccessor (&
Ipv6RawSocketImpl::m_protocol
),
53
MakeUintegerChecker<uint16_t> ())
54
;
55
return
tid;
56
}
57
58
Ipv6RawSocketImpl::Ipv6RawSocketImpl
()
59
{
60
NS_LOG_FUNCTION_NOARGS
();
61
m_err
=
Socket::ERROR_NOTERROR
;
62
m_node
= 0;
63
m_src
=
Ipv6Address::GetAny
();
64
m_dst
=
Ipv6Address::GetAny
();
65
m_protocol
= 0;
66
m_shutdownSend
=
false
;
67
m_shutdownRecv
=
false
;
68
Icmpv6FilterSetPassAll
();
69
}
70
71
Ipv6RawSocketImpl::~Ipv6RawSocketImpl
()
72
{
73
}
74
75
void
Ipv6RawSocketImpl::DoDispose
()
76
{
77
NS_LOG_FUNCTION_NOARGS
();
78
m_node
= 0;
79
Socket::DoDispose
();
80
}
81
82
void
Ipv6RawSocketImpl::SetNode
(
Ptr<Node>
node)
83
{
84
NS_LOG_FUNCTION
(
this
<< node);
85
m_node
= node;
86
}
87
88
Ptr<Node>
Ipv6RawSocketImpl::GetNode
()
const
89
{
90
return
m_node
;
91
}
92
93
enum
Socket::SocketErrno
Ipv6RawSocketImpl::GetErrno
()
const
94
{
95
NS_LOG_FUNCTION_NOARGS
();
96
return
m_err
;
97
}
98
99
enum
Socket::SocketType
Ipv6RawSocketImpl::GetSocketType
()
const
100
{
101
return
NS3_SOCK_RAW
;
102
}
103
104
int
Ipv6RawSocketImpl::Bind
(
const
Address
&
address
)
105
{
106
NS_LOG_FUNCTION
(
this
<< address);
107
108
if
(!
Inet6SocketAddress::IsMatchingType
(address))
109
{
110
m_err
=
Socket::ERROR_INVAL
;
111
return
-1;
112
}
113
Inet6SocketAddress
ad =
Inet6SocketAddress::ConvertFrom
(address);
114
m_src
= ad.
GetIpv6
();
115
return
0;
116
}
117
118
int
Ipv6RawSocketImpl::Bind
()
119
{
120
NS_LOG_FUNCTION_NOARGS
();
121
m_src
=
Ipv6Address::GetAny
();
122
return
0;
123
}
124
125
int
Ipv6RawSocketImpl::Bind6
()
126
{
127
return
(
Bind
());
128
}
129
130
int
Ipv6RawSocketImpl::GetSockName
(
Address
&
address
)
const
131
{
132
NS_LOG_FUNCTION_NOARGS
();
133
address =
Inet6SocketAddress
(
m_src
, 0);
134
return
0;
135
}
136
137
int
Ipv6RawSocketImpl::Close
()
138
{
139
NS_LOG_FUNCTION_NOARGS
();
140
Ptr<Ipv6L3Protocol>
ipv6 =
m_node
->
GetObject
<
Ipv6L3Protocol
> ();
141
142
if
(ipv6)
143
{
144
ipv6->DeleteRawSocket (
this
);
145
}
146
return
0;
147
}
148
149
int
Ipv6RawSocketImpl::ShutdownSend
()
150
{
151
NS_LOG_FUNCTION_NOARGS
();
152
m_shutdownSend
=
true
;
153
return
0;
154
}
155
156
int
Ipv6RawSocketImpl::ShutdownRecv
()
157
{
158
NS_LOG_FUNCTION_NOARGS
();
159
m_shutdownRecv
=
true
;
160
return
0;
161
}
162
163
int
Ipv6RawSocketImpl::Connect
(
const
Address
&
address
)
164
{
165
NS_LOG_FUNCTION
(
this
<< address);
166
167
if
(!
Inet6SocketAddress::IsMatchingType
(address))
168
{
169
m_err
=
Socket::ERROR_INVAL
;
170
return
-1;
171
}
172
173
Inet6SocketAddress
ad =
Inet6SocketAddress::ConvertFrom
(address);
174
m_dst
= ad.
GetIpv6
();
175
return
0;
176
}
177
178
int
Ipv6RawSocketImpl::Listen
()
179
{
180
NS_LOG_FUNCTION_NOARGS
();
181
m_err
=
Socket::ERROR_OPNOTSUPP
;
182
return
-1;
183
}
184
185
int
Ipv6RawSocketImpl::Send
(
Ptr<Packet>
p, uint32_t flags)
186
{
187
NS_LOG_FUNCTION
(
this
<< p << flags);
188
Inet6SocketAddress
to =
Inet6SocketAddress
(
m_dst
,
m_protocol
);
189
return
SendTo
(p, flags, to);
190
}
191
192
int
Ipv6RawSocketImpl::SendTo
(
Ptr<Packet>
p, uint32_t flags,
const
Address
& toAddress)
193
{
194
NS_LOG_FUNCTION
(
this
<< p << flags << toAddress);
195
196
if
(!
Inet6SocketAddress::IsMatchingType
(toAddress))
197
{
198
m_err
=
Socket::ERROR_INVAL
;
199
return
-1;
200
}
201
202
if
(
m_shutdownSend
)
203
{
204
return
0;
205
}
206
207
Inet6SocketAddress
ad =
Inet6SocketAddress::ConvertFrom
(toAddress);
208
Ptr<Ipv6L3Protocol>
ipv6 =
m_node
->
GetObject
<
Ipv6L3Protocol
> ();
209
Ipv6Address
dst = ad.
GetIpv6
();
210
211
if
(ipv6->GetRoutingProtocol ())
212
{
213
Ipv6Header
hdr;
214
hdr.
SetDestinationAddress
(dst);
215
SocketErrno
err =
ERROR_NOTERROR
;
216
Ptr<Ipv6Route>
route = 0;
217
Ptr<NetDevice>
oif (0);
/*specify non-zero if bound to a source address */
218
219
if
(!
m_src
.
IsAny
())
220
{
221
int32_t index = ipv6->GetInterfaceForAddress (
m_src
);
222
NS_ASSERT
(index >= 0);
223
oif = ipv6->GetNetDevice (index);
224
}
225
226
route = ipv6->GetRoutingProtocol ()->RouteOutput (p, hdr, oif, err);
227
228
if
(route)
229
{
230
NS_LOG_LOGIC
(
"Route exists"
);
231
if
(
m_protocol
==
Icmpv6L4Protocol::GetStaticProtocolNumber
())
232
{
233
/* calculate checksum here for ICMPv6 echo request (sent by ping6)
234
* as we cannot determine source IPv6 address at application level
235
*/
236
uint8_t type;
237
p->
CopyData
(&type,
sizeof
(type));
238
if
(type ==
Icmpv6Header::ICMPV6_ECHO_REQUEST
)
239
{
240
Icmpv6Echo
hdr (1);
241
p->
RemoveHeader
(hdr);
242
hdr.
CalculatePseudoHeaderChecksum
(route->GetSource (), dst, p->
GetSize
() + hdr.
GetSerializedSize
(),
Icmpv6L4Protocol::GetStaticProtocolNumber
());
243
p->
AddHeader
(hdr);
244
}
245
}
246
247
if
(
m_src
.
IsAny
())
248
{
249
ipv6->Send (p, route->GetSource (), dst,
m_protocol
, route);
250
}
251
else
252
{
253
ipv6->Send (p,
m_src
, dst,
m_protocol
, route);
254
}
255
// Return only payload size (as Linux does).
256
return
p->
GetSize
() - hdr.
GetSerializedSize
();
257
}
258
else
259
{
260
NS_LOG_DEBUG
(
"No route, dropped!"
);
261
}
262
}
263
return
0;
264
}
265
266
Ptr<Packet>
Ipv6RawSocketImpl::Recv
(uint32_t maxSize, uint32_t flags)
267
{
268
NS_LOG_FUNCTION
(
this
<< maxSize << flags);
269
Address
tmp;
270
return
RecvFrom
(maxSize, flags, tmp);
271
}
272
273
Ptr<Packet>
Ipv6RawSocketImpl::RecvFrom
(uint32_t maxSize, uint32_t flags,
Address
& fromAddress)
274
{
275
NS_LOG_FUNCTION
(
this
<< maxSize << flags << fromAddress);
276
277
if
(
m_data
.empty ())
278
{
279
return
0;
280
}
281
282
/* get packet */
283
struct
Data
data =
m_data
.front ();
284
m_data
.pop_front ();
285
fromAddress =
Inet6SocketAddress
(data.
fromIp
, data.
fromProtocol
);
286
if
(data.
packet
->
GetSize
() > maxSize)
287
{
288
Ptr<Packet>
first
= data.
packet
->
CreateFragment
(0, maxSize);
289
if
(!(flags & MSG_PEEK))
290
{
291
data.
packet
->
RemoveAtStart
(maxSize);
292
}
293
m_data
.push_front (data);
294
return
first
;
295
}
296
297
return
data.
packet
;
298
}
299
300
uint32_t
Ipv6RawSocketImpl::GetTxAvailable
()
const
301
{
302
NS_LOG_FUNCTION_NOARGS
();
303
return
0xffffffff;
304
}
305
306
uint32_t
Ipv6RawSocketImpl::GetRxAvailable
()
const
307
{
308
NS_LOG_FUNCTION_NOARGS
();
309
uint32_t rx = 0;
310
311
for
(std::list<Data>::const_iterator it =
m_data
.begin (); it !=
m_data
.end (); ++it)
312
{
313
rx+= (it->packet)->GetSize ();
314
}
315
316
return
rx;
317
}
318
319
bool
Ipv6RawSocketImpl::ForwardUp
(
Ptr<const Packet>
p,
Ipv6Header
hdr,
Ptr<NetDevice>
device)
320
{
321
NS_LOG_FUNCTION
(
this
<< *p << hdr << device);
322
323
if
(
m_shutdownRecv
)
324
{
325
return
false
;
326
}
327
328
Ptr<NetDevice>
boundNetDevice =
Socket::GetBoundNetDevice
();
329
if
(boundNetDevice)
330
{
331
if
(boundNetDevice != device)
332
{
333
return
false
;
334
}
335
}
336
337
if
((
m_src
==
Ipv6Address::GetAny
() || hdr.
GetDestinationAddress
() ==
m_src
) &&
338
(
m_dst
==
Ipv6Address::GetAny
() || hdr.
GetSourceAddress
() ==
m_dst
) &&
339
hdr.
GetNextHeader
() ==
m_protocol
)
340
{
341
Ptr<Packet>
copy = p->
Copy
();
342
343
if
(
m_protocol
==
Icmpv6L4Protocol::GetStaticProtocolNumber
())
344
{
345
/* filter */
346
Icmpv6Header
icmpHeader;
347
copy->
PeekHeader
(icmpHeader);
348
uint8_t type = icmpHeader.
GetType
();
349
350
if
(
Icmpv6FilterWillBlock
(type))
351
{
352
/* packet filtered */
353
return
false
;
354
}
355
}
356
357
// Should check via getsockopt ()..
358
if
(
IsRecvPktInfo
())
359
{
360
Ipv6PacketInfoTag
tag;
361
copy->
RemovePacketTag
(tag);
362
tag.
SetRecvIf
(device->
GetIfIndex
());
363
copy->
AddPacketTag
(tag);
364
}
365
366
copy->
AddHeader
(hdr);
367
struct
Data
data;
368
data.
packet
= copy;
369
data.
fromIp
= hdr.
GetSourceAddress
();
370
data.
fromProtocol
= hdr.
GetNextHeader
();
371
m_data
.push_back (data);
372
NotifyDataRecv
();
373
return
true
;
374
}
375
return
false
;
376
}
377
378
bool
379
Ipv6RawSocketImpl::SetAllowBroadcast
(
bool
allowBroadcast)
380
{
381
if
(!allowBroadcast)
382
{
383
return
false
;
384
}
385
return
true
;
386
}
387
388
bool
389
Ipv6RawSocketImpl::GetAllowBroadcast
()
const
390
{
391
return
true
;
392
}
393
394
void
395
Ipv6RawSocketImpl::Icmpv6FilterSetPassAll
()
396
{
397
memset(&
m_icmpFilter
, 0xff,
sizeof
(
icmpv6Filter
));
398
}
399
400
void
401
Ipv6RawSocketImpl::Icmpv6FilterSetBlockAll
()
402
{
403
memset(&
m_icmpFilter
, 0x00,
sizeof
(
icmpv6Filter
));
404
}
405
406
void
407
Ipv6RawSocketImpl::Icmpv6FilterSetPass
(uint8_t type)
408
{
409
(
m_icmpFilter
.
icmpv6Filt
[(type) >> 5]) |= (uint32_t(1) << ((type) & 31));
410
}
411
412
void
413
Ipv6RawSocketImpl::Icmpv6FilterSetBlock
(uint8_t type)
414
{
415
(
m_icmpFilter
.
icmpv6Filt
[(type) >> 5]) &= ~(uint32_t(1) << ((type) & 31));
416
}
417
418
bool
419
Ipv6RawSocketImpl::Icmpv6FilterWillPass
(uint8_t type)
420
{
421
return
(((
m_icmpFilter
.
icmpv6Filt
[(type) >> 5]) & (uint32_t(1) << ((type) & 31))) != 0);
422
}
423
424
bool
425
Ipv6RawSocketImpl::Icmpv6FilterWillBlock
(uint8_t type)
426
{
427
return
(((
m_icmpFilter
.
icmpv6Filt
[(type) >> 5]) & (uint32_t(1) << ((type) & 31))) == 0);
428
}
429
430
}
/* namespace ns3 */
431
src
internet
model
ipv6-raw-socket-impl.cc
Generated on Fri Aug 30 2013 01:42:52 for ns-3 by
1.8.1.2