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
ipv6->Send (p, route->GetSource (), dst,
m_protocol
, route);
248
}
249
else
250
{
251
NS_LOG_DEBUG
(
"No route, dropped!"
);
252
}
253
}
254
return
0;
255
}
256
257
Ptr<Packet>
Ipv6RawSocketImpl::Recv
(uint32_t maxSize, uint32_t flags)
258
{
259
NS_LOG_FUNCTION
(
this
<< maxSize << flags);
260
Address
tmp;
261
return
RecvFrom
(maxSize, flags, tmp);
262
}
263
264
Ptr<Packet>
Ipv6RawSocketImpl::RecvFrom
(uint32_t maxSize, uint32_t flags,
Address
& fromAddress)
265
{
266
NS_LOG_FUNCTION
(
this
<< maxSize << flags << fromAddress);
267
268
if
(
m_data
.empty ())
269
{
270
return
0;
271
}
272
273
/* get packet */
274
struct
Data
data =
m_data
.front ();
275
m_data
.pop_front ();
276
277
if
(data.
packet
->
GetSize
() > maxSize)
278
{
279
Ptr<Packet>
first = data.
packet
->
CreateFragment
(0, maxSize);
280
if
(!(flags & MSG_PEEK))
281
{
282
data.
packet
->
RemoveAtStart
(maxSize);
283
}
284
m_data
.push_front (data);
285
return
first;
286
}
287
288
fromAddress =
Inet6SocketAddress
(data.
fromIp
, data.
fromProtocol
);
289
return
data.
packet
;
290
}
291
292
uint32_t
Ipv6RawSocketImpl::GetTxAvailable
()
const
293
{
294
NS_LOG_FUNCTION_NOARGS
();
295
return
0xffffffff;
296
}
297
298
uint32_t
Ipv6RawSocketImpl::GetRxAvailable
()
const
299
{
300
NS_LOG_FUNCTION_NOARGS
();
301
uint32_t rx = 0;
302
303
for
(std::list<Data>::const_iterator it =
m_data
.begin (); it !=
m_data
.end (); ++it)
304
{
305
rx+= (it->packet)->GetSize ();
306
}
307
308
return
rx;
309
}
310
311
bool
Ipv6RawSocketImpl::ForwardUp
(
Ptr<const Packet>
p,
Ipv6Header
hdr,
Ptr<NetDevice>
device)
312
{
313
NS_LOG_FUNCTION
(
this
<< *p << hdr << device);
314
315
if
(
m_shutdownRecv
)
316
{
317
return
false
;
318
}
319
320
if
((
m_src
==
Ipv6Address::GetAny
() || hdr.
GetDestinationAddress
() ==
m_src
) &&
321
(
m_dst
==
Ipv6Address::GetAny
() || hdr.
GetSourceAddress
() ==
m_dst
) &&
322
hdr.
GetNextHeader
() ==
m_protocol
)
323
{
324
Ptr<Packet>
copy = p->
Copy
();
325
326
if
(
m_protocol
==
Icmpv6L4Protocol::GetStaticProtocolNumber
())
327
{
328
/* filter */
329
Icmpv6Header
icmpHeader;
330
copy->
PeekHeader
(icmpHeader);
331
uint8_t type = icmpHeader.
GetType
();
332
333
if
(
Icmpv6FilterWillBlock
(type))
334
{
335
/* packet filtered */
336
return
false
;
337
}
338
}
339
340
// Should check via getsockopt ()..
341
if
(
IsRecvPktInfo
())
342
{
343
Ipv6PacketInfoTag
tag;
344
copy->
RemovePacketTag
(tag);
345
tag.
SetRecvIf
(device->
GetIfIndex
());
346
copy->
AddPacketTag
(tag);
347
}
348
349
copy->
AddHeader
(hdr);
350
struct
Data
data;
351
data.
packet
= copy;
352
data.
fromIp
= hdr.
GetSourceAddress
();
353
data.
fromProtocol
= hdr.
GetNextHeader
();
354
m_data
.push_back (data);
355
NotifyDataRecv
();
356
return
true
;
357
}
358
return
false
;
359
}
360
361
bool
362
Ipv6RawSocketImpl::SetAllowBroadcast
(
bool
allowBroadcast)
363
{
364
if
(!allowBroadcast)
365
{
366
return
false
;
367
}
368
return
true
;
369
}
370
371
bool
372
Ipv6RawSocketImpl::GetAllowBroadcast
()
const
373
{
374
return
true
;
375
}
376
377
void
378
Ipv6RawSocketImpl::Icmpv6FilterSetPassAll
()
379
{
380
memset(&
m_icmpFilter
, 0xff,
sizeof
(
icmpv6Filter
));
381
}
382
383
void
384
Ipv6RawSocketImpl::Icmpv6FilterSetBlockAll
()
385
{
386
memset(&
m_icmpFilter
, 0x00,
sizeof
(
icmpv6Filter
));
387
}
388
389
void
390
Ipv6RawSocketImpl::Icmpv6FilterSetPass
(uint8_t type)
391
{
392
(
m_icmpFilter
.
icmpv6Filt
[(type) >> 5]) |= (uint32_t(1) << ((type) & 31));
393
}
394
395
void
396
Ipv6RawSocketImpl::Icmpv6FilterSetBlock
(uint8_t type)
397
{
398
(
m_icmpFilter
.
icmpv6Filt
[(type) >> 5]) &= ~(uint32_t(1) << ((type) & 31));
399
}
400
401
bool
402
Ipv6RawSocketImpl::Icmpv6FilterWillPass
(uint8_t type)
403
{
404
return
(((
m_icmpFilter
.
icmpv6Filt
[(type) >> 5]) & (uint32_t(1) << ((type) & 31))) != 0);
405
}
406
407
bool
408
Ipv6RawSocketImpl::Icmpv6FilterWillBlock
(uint8_t type)
409
{
410
return
(((
m_icmpFilter
.
icmpv6Filt
[(type) >> 5]) & (uint32_t(1) << ((type) & 31))) == 0);
411
}
412
413
}
/* namespace ns3 */
414
src
internet
model
ipv6-raw-socket-impl.cc
Generated on Tue Nov 13 2012 10:32:15 for ns-3 by
1.8.1.2