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
ipv4-raw-socket-impl.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
#include <netinet/in.h>
3
#include <sys/socket.h>
4
#include <sys/types.h>
5
#include "
ipv4-raw-socket-impl.h
"
6
#include "
ipv4-l3-protocol.h
"
7
#include "
icmpv4.h
"
8
#include "ns3/ipv4-packet-info-tag.h"
9
#include "ns3/inet-socket-address.h"
10
#include "ns3/node.h"
11
#include "ns3/packet.h"
12
#include "ns3/uinteger.h"
13
#include "ns3/boolean.h"
14
#include "ns3/log.h"
15
16
NS_LOG_COMPONENT_DEFINE
(
"Ipv4RawSocketImpl"
);
17
18
namespace
ns3 {
19
20
NS_OBJECT_ENSURE_REGISTERED
(Ipv4RawSocketImpl);
21
22
TypeId
23
Ipv4RawSocketImpl::GetTypeId
(
void
)
24
{
25
static
TypeId
tid =
TypeId
(
"ns3::Ipv4RawSocketImpl"
)
26
.
SetParent
<
Socket
> ()
27
.AddAttribute (
"Protocol"
,
"Protocol number to match."
,
28
UintegerValue
(0),
29
MakeUintegerAccessor (&
Ipv4RawSocketImpl::m_protocol
),
30
MakeUintegerChecker<uint16_t> ())
31
.AddAttribute (
"IcmpFilter"
,
32
"Any icmp header whose type field matches a bit in this filter is dropped. Type must be less than 32."
,
33
UintegerValue
(0),
34
MakeUintegerAccessor (&
Ipv4RawSocketImpl::m_icmpFilter
),
35
MakeUintegerChecker<uint32_t> ())
36
//
37
// from raw (7), linux, returned length of Send/Recv should be
38
//
39
// | IP_HDRINC on | off |
40
// ----------+---------------+-------------+-
41
// Send(Ipv4)| hdr + payload | payload |
42
// Recv(Ipv4)| hdr + payload | hdr+payload |
43
// ----------+---------------+-------------+-
44
.AddAttribute (
"IpHeaderInclude"
,
45
"Include IP Header information (a.k.a setsockopt (IP_HDRINCL))."
,
46
BooleanValue
(
false
),
47
MakeBooleanAccessor (&
Ipv4RawSocketImpl::m_iphdrincl
),
48
MakeBooleanChecker ())
49
;
50
return
tid;
51
}
52
53
Ipv4RawSocketImpl::Ipv4RawSocketImpl
()
54
{
55
NS_LOG_FUNCTION
(
this
);
56
m_err
=
Socket::ERROR_NOTERROR
;
57
m_node
= 0;
58
m_src
=
Ipv4Address::GetAny
();
59
m_dst
=
Ipv4Address::GetAny
();
60
m_protocol
= 0;
61
m_shutdownSend
=
false
;
62
m_shutdownRecv
=
false
;
63
}
64
65
void
66
Ipv4RawSocketImpl::SetNode
(
Ptr<Node>
node)
67
{
68
NS_LOG_FUNCTION
(
this
<< node);
69
m_node
= node;
70
}
71
72
void
73
Ipv4RawSocketImpl::DoDispose
(
void
)
74
{
75
NS_LOG_FUNCTION
(
this
);
76
m_node
= 0;
77
Socket::DoDispose
();
78
}
79
80
enum
Socket::SocketErrno
81
Ipv4RawSocketImpl::GetErrno
(
void
)
const
82
{
83
NS_LOG_FUNCTION
(
this
);
84
return
m_err
;
85
}
86
87
enum
Socket::SocketType
88
Ipv4RawSocketImpl::GetSocketType
(
void
)
const
89
{
90
NS_LOG_FUNCTION
(
this
);
91
return
NS3_SOCK_RAW
;
92
}
93
94
Ptr<Node>
95
Ipv4RawSocketImpl::GetNode
(
void
)
const
96
{
97
NS_LOG_FUNCTION
(
this
);
98
return
m_node
;
99
}
100
int
101
Ipv4RawSocketImpl::Bind
(
const
Address
&address)
102
{
103
NS_LOG_FUNCTION
(
this
<< address);
104
if
(!
InetSocketAddress::IsMatchingType
(address))
105
{
106
m_err
=
Socket::ERROR_INVAL
;
107
return
-1;
108
}
109
InetSocketAddress
ad =
InetSocketAddress::ConvertFrom
(address);
110
m_src
= ad.
GetIpv4
();
111
return
0;
112
}
113
int
114
Ipv4RawSocketImpl::Bind
(
void
)
115
{
116
NS_LOG_FUNCTION
(
this
);
117
m_src
=
Ipv4Address::GetAny
();
118
return
0;
119
}
120
int
121
Ipv4RawSocketImpl::Bind6
(
void
)
122
{
123
NS_LOG_FUNCTION
(
this
);
124
return
(-1);
125
}
126
int
127
Ipv4RawSocketImpl::GetSockName
(
Address
&address)
const
128
{
129
NS_LOG_FUNCTION
(
this
<< address);
130
address =
InetSocketAddress
(
m_src
, 0);
131
return
0;
132
}
133
int
134
Ipv4RawSocketImpl::Close
(
void
)
135
{
136
NS_LOG_FUNCTION
(
this
);
137
Ptr<Ipv4>
ipv4 =
m_node
->
GetObject
<
Ipv4
> ();
138
if
(ipv4 != 0)
139
{
140
ipv4->
DeleteRawSocket
(
this
);
141
}
142
return
0;
143
}
144
int
145
Ipv4RawSocketImpl::ShutdownSend
(
void
)
146
{
147
NS_LOG_FUNCTION
(
this
);
148
m_shutdownSend
=
true
;
149
return
0;
150
}
151
int
152
Ipv4RawSocketImpl::ShutdownRecv
(
void
)
153
{
154
NS_LOG_FUNCTION
(
this
);
155
m_shutdownRecv
=
true
;
156
return
0;
157
}
158
int
159
Ipv4RawSocketImpl::Connect
(
const
Address
&address)
160
{
161
NS_LOG_FUNCTION
(
this
<< address);
162
if
(!
InetSocketAddress::IsMatchingType
(address))
163
{
164
m_err
=
Socket::ERROR_INVAL
;
165
return
-1;
166
}
167
InetSocketAddress
ad =
InetSocketAddress::ConvertFrom
(address);
168
m_dst
= ad.
GetIpv4
();
169
return
0;
170
}
171
int
172
Ipv4RawSocketImpl::Listen
(
void
)
173
{
174
NS_LOG_FUNCTION
(
this
);
175
m_err
=
Socket::ERROR_OPNOTSUPP
;
176
return
-1;
177
}
178
uint32_t
179
Ipv4RawSocketImpl::GetTxAvailable
(
void
)
const
180
{
181
NS_LOG_FUNCTION
(
this
);
182
return
0xffffffff;
183
}
184
int
185
Ipv4RawSocketImpl::Send
(
Ptr<Packet>
p, uint32_t flags)
186
{
187
NS_LOG_FUNCTION
(
this
<< p << flags);
188
InetSocketAddress
to =
InetSocketAddress
(
m_dst
,
m_protocol
);
189
return
SendTo
(p, flags, to);
190
}
191
int
192
Ipv4RawSocketImpl::SendTo
(
Ptr<Packet>
p, uint32_t flags,
193
const
Address
&toAddress)
194
{
195
NS_LOG_FUNCTION
(
this
<< p << flags << toAddress);
196
if
(!
InetSocketAddress::IsMatchingType
(toAddress))
197
{
198
m_err
=
Socket::ERROR_INVAL
;
199
return
-1;
200
}
201
if
(
m_shutdownSend
)
202
{
203
return
0;
204
}
205
InetSocketAddress
ad =
InetSocketAddress::ConvertFrom
(toAddress);
206
Ptr<Ipv4>
ipv4 =
m_node
->
GetObject
<
Ipv4
> ();
207
Ipv4Address
dst = ad.
GetIpv4
();
208
Ipv4Address
src =
m_src
;
209
if
(ipv4->
GetRoutingProtocol
())
210
{
211
Ipv4Header
header;
212
if
(!
m_iphdrincl
)
213
{
214
header.
SetDestination
(dst);
215
header.
SetProtocol
(
m_protocol
);
216
}
217
else
218
{
219
p->
RemoveHeader
(header);
220
dst = header.
GetDestination
();
221
src = header.
GetSource
();
222
}
223
SocketErrno
errno_ =
ERROR_NOTERROR
;
//do not use errno as it is the standard C last error number
224
Ptr<Ipv4Route>
route;
225
Ptr<NetDevice>
oif =
m_boundnetdevice
;
//specify non-zero if bound to a source address
226
if
(!oif && src !=
Ipv4Address::GetAny
())
227
{
228
int32_t index = ipv4->
GetInterfaceForAddress
(src);
229
NS_ASSERT
(index >= 0);
230
oif = ipv4->
GetNetDevice
(index);
231
NS_LOG_LOGIC
(
"Set index "
<< oif <<
"from source "
<< src);
232
}
233
234
// TBD-- we could cache the route and just check its validity
235
route = ipv4->
GetRoutingProtocol
()->
RouteOutput
(p, header, oif, errno_);
236
if
(route != 0)
237
{
238
NS_LOG_LOGIC
(
"Route exists"
);
239
if
(!
m_iphdrincl
)
240
{
241
ipv4->
Send
(p, route->
GetSource
(), dst,
m_protocol
, route);
242
}
243
else
244
{
245
ipv4->
SendWithHeader
(p, header, route);
246
}
247
NotifyDataSent
(p->
GetSize
());
248
NotifySend
(
GetTxAvailable
());
249
return
p->
GetSize
();
250
}
251
else
252
{
253
NS_LOG_DEBUG
(
"dropped because no outgoing route."
);
254
return
-1;
255
}
256
}
257
return
0;
258
}
259
uint32_t
260
Ipv4RawSocketImpl::GetRxAvailable
(
void
)
const
261
{
262
NS_LOG_FUNCTION
(
this
);
263
uint32_t rx = 0;
264
for
(std::list<Data>::const_iterator i =
m_recv
.begin (); i !=
m_recv
.end (); ++i)
265
{
266
rx += (i->packet)->GetSize ();
267
}
268
return
rx;
269
}
270
Ptr<Packet>
271
Ipv4RawSocketImpl::Recv
(uint32_t maxSize, uint32_t flags)
272
{
273
NS_LOG_FUNCTION
(
this
<< maxSize << flags);
274
Address
tmp;
275
return
RecvFrom
(maxSize, flags, tmp);
276
}
277
Ptr<Packet>
278
Ipv4RawSocketImpl::RecvFrom
(uint32_t maxSize, uint32_t flags,
279
Address
&fromAddress)
280
{
281
NS_LOG_FUNCTION
(
this
<< maxSize << flags << fromAddress);
282
if
(
m_recv
.empty ())
283
{
284
return
0;
285
}
286
struct
Data
data =
m_recv
.front ();
287
m_recv
.pop_front ();
288
InetSocketAddress
inet =
InetSocketAddress
(data.
fromIp
, data.
fromProtocol
);
289
fromAddress = inet;
290
if
(data.
packet
->
GetSize
() > maxSize)
291
{
292
Ptr<Packet>
first = data.
packet
->
CreateFragment
(0, maxSize);
293
if
(!(flags & MSG_PEEK))
294
{
295
data.
packet
->
RemoveAtStart
(maxSize);
296
}
297
m_recv
.push_front (data);
298
return
first;
299
}
300
return
data.
packet
;
301
}
302
303
void
304
Ipv4RawSocketImpl::SetProtocol
(uint16_t protocol)
305
{
306
NS_LOG_FUNCTION
(
this
<< protocol);
307
m_protocol
= protocol;
308
}
309
310
bool
311
Ipv4RawSocketImpl::ForwardUp
(
Ptr<const Packet>
p,
Ipv4Header
ipHeader,
Ptr<Ipv4Interface>
incomingInterface)
312
{
313
NS_LOG_FUNCTION
(
this
<< *p << ipHeader << incomingInterface);
314
if
(
m_shutdownRecv
)
315
{
316
return
false
;
317
}
318
319
Ptr<NetDevice>
boundNetDevice =
Socket::GetBoundNetDevice
();
320
if
(boundNetDevice)
321
{
322
if
(boundNetDevice != incomingInterface->
GetDevice
())
323
{
324
return
false
;
325
}
326
}
327
328
NS_LOG_LOGIC
(
"src = "
<<
m_src
<<
" dst = "
<<
m_dst
);
329
if
((
m_src
==
Ipv4Address::GetAny
() || ipHeader.
GetDestination
() ==
m_src
) &&
330
(
m_dst
==
Ipv4Address::GetAny
() || ipHeader.
GetSource
() ==
m_dst
) &&
331
ipHeader.
GetProtocol
() ==
m_protocol
)
332
{
333
Ptr<Packet>
copy = p->
Copy
();
334
// Should check via getsockopt ()..
335
if
(
IsRecvPktInfo
())
336
{
337
Ipv4PacketInfoTag
tag;
338
copy->
RemovePacketTag
(tag);
339
tag.
SetRecvIf
(incomingInterface->
GetDevice
()->
GetIfIndex
());
340
copy->
AddPacketTag
(tag);
341
}
342
if
(
m_protocol
== 1)
343
{
344
Icmpv4Header
icmpHeader;
345
copy->
PeekHeader
(icmpHeader);
346
uint8_t type = icmpHeader.
GetType
();
347
if
(type < 32 &&
348
((uint32_t(1) << type) &
m_icmpFilter
))
349
{
350
// filter out icmp packet.
351
return
false
;
352
}
353
}
354
copy->
AddHeader
(ipHeader);
355
struct
Data
data;
356
data.
packet
= copy;
357
data.
fromIp
= ipHeader.
GetSource
();
358
data.
fromProtocol
= ipHeader.
GetProtocol
();
359
m_recv
.push_back (data);
360
NotifyDataRecv
();
361
return
true
;
362
}
363
return
false
;
364
}
365
366
bool
367
Ipv4RawSocketImpl::SetAllowBroadcast
(
bool
allowBroadcast)
368
{
369
NS_LOG_FUNCTION
(
this
<< allowBroadcast);
370
if
(!allowBroadcast)
371
{
372
return
false
;
373
}
374
return
true
;
375
}
376
377
bool
378
Ipv4RawSocketImpl::GetAllowBroadcast
()
const
379
{
380
NS_LOG_FUNCTION
(
this
);
381
return
true
;
382
}
383
384
}
// namespace ns3
src
internet
model
ipv4-raw-socket-impl.cc
Generated on Tue May 14 2013 11:08:22 for ns-3 by
1.8.1.2