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
m_node
= node;
69
}
70
71
void
72
Ipv4RawSocketImpl::DoDispose
(
void
)
73
{
74
NS_LOG_FUNCTION
(
this
);
75
m_node
= 0;
76
Socket::DoDispose
();
77
}
78
79
enum
Socket::SocketErrno
80
Ipv4RawSocketImpl::GetErrno
(
void
)
const
81
{
82
NS_LOG_FUNCTION
(
this
);
83
return
m_err
;
84
}
85
86
enum
Socket::SocketType
87
Ipv4RawSocketImpl::GetSocketType
(
void
)
const
88
{
89
return
NS3_SOCK_RAW
;
90
}
91
92
Ptr<Node>
93
Ipv4RawSocketImpl::GetNode
(
void
)
const
94
{
95
NS_LOG_FUNCTION
(
this
);
96
return
m_node
;
97
}
98
int
99
Ipv4RawSocketImpl::Bind
(
const
Address
&address)
100
{
101
NS_LOG_FUNCTION
(
this
<< address);
102
if
(!
InetSocketAddress::IsMatchingType
(address))
103
{
104
m_err
=
Socket::ERROR_INVAL
;
105
return
-1;
106
}
107
InetSocketAddress
ad =
InetSocketAddress::ConvertFrom
(address);
108
m_src
= ad.
GetIpv4
();
109
return
0;
110
}
111
int
112
Ipv4RawSocketImpl::Bind
(
void
)
113
{
114
NS_LOG_FUNCTION
(
this
);
115
m_src
=
Ipv4Address::GetAny
();
116
return
0;
117
}
118
int
119
Ipv4RawSocketImpl::Bind6
(
void
)
120
{
121
return
(-1);
122
}
123
int
124
Ipv4RawSocketImpl::GetSockName
(
Address
&address)
const
125
{
126
address =
InetSocketAddress
(
m_src
, 0);
127
return
0;
128
}
129
int
130
Ipv4RawSocketImpl::Close
(
void
)
131
{
132
NS_LOG_FUNCTION
(
this
);
133
Ptr<Ipv4>
ipv4 =
m_node
->
GetObject
<
Ipv4
> ();
134
if
(ipv4 != 0)
135
{
136
ipv4->
DeleteRawSocket
(
this
);
137
}
138
return
0;
139
}
140
int
141
Ipv4RawSocketImpl::ShutdownSend
(
void
)
142
{
143
NS_LOG_FUNCTION
(
this
);
144
m_shutdownSend
=
true
;
145
return
0;
146
}
147
int
148
Ipv4RawSocketImpl::ShutdownRecv
(
void
)
149
{
150
NS_LOG_FUNCTION
(
this
);
151
m_shutdownRecv
=
true
;
152
return
0;
153
}
154
int
155
Ipv4RawSocketImpl::Connect
(
const
Address
&address)
156
{
157
NS_LOG_FUNCTION
(
this
<< address);
158
if
(!
InetSocketAddress::IsMatchingType
(address))
159
{
160
m_err
=
Socket::ERROR_INVAL
;
161
return
-1;
162
}
163
InetSocketAddress
ad =
InetSocketAddress::ConvertFrom
(address);
164
m_dst
= ad.
GetIpv4
();
165
return
0;
166
}
167
int
168
Ipv4RawSocketImpl::Listen
(
void
)
169
{
170
NS_LOG_FUNCTION
(
this
);
171
m_err
=
Socket::ERROR_OPNOTSUPP
;
172
return
-1;
173
}
174
uint32_t
175
Ipv4RawSocketImpl::GetTxAvailable
(
void
)
const
176
{
177
NS_LOG_FUNCTION
(
this
);
178
return
0xffffffff;
179
}
180
int
181
Ipv4RawSocketImpl::Send
(
Ptr<Packet>
p, uint32_t flags)
182
{
183
NS_LOG_FUNCTION
(
this
<< p << flags);
184
InetSocketAddress
to =
InetSocketAddress
(
m_dst
,
m_protocol
);
185
return
SendTo
(p, flags, to);
186
}
187
int
188
Ipv4RawSocketImpl::SendTo
(
Ptr<Packet>
p, uint32_t flags,
189
const
Address
&toAddress)
190
{
191
NS_LOG_FUNCTION
(
this
<< p << flags << toAddress);
192
if
(!
InetSocketAddress::IsMatchingType
(toAddress))
193
{
194
m_err
=
Socket::ERROR_INVAL
;
195
return
-1;
196
}
197
if
(
m_shutdownSend
)
198
{
199
return
0;
200
}
201
InetSocketAddress
ad =
InetSocketAddress::ConvertFrom
(toAddress);
202
Ptr<Ipv4>
ipv4 =
m_node
->
GetObject
<
Ipv4
> ();
203
Ipv4Address
dst = ad.
GetIpv4
();
204
Ipv4Address
src =
m_src
;
205
if
(ipv4->
GetRoutingProtocol
())
206
{
207
Ipv4Header
header;
208
if
(!
m_iphdrincl
)
209
{
210
header.
SetDestination
(dst);
211
header.
SetProtocol
(
m_protocol
);
212
}
213
else
214
{
215
p->
RemoveHeader
(header);
216
dst = header.
GetDestination
();
217
src = header.
GetSource
();
218
}
219
SocketErrno
errno_ =
ERROR_NOTERROR
;
//do not use errno as it is the standard C last error number
220
Ptr<Ipv4Route>
route;
221
Ptr<NetDevice>
oif =
m_boundnetdevice
;
//specify non-zero if bound to a source address
222
if
(!oif && src !=
Ipv4Address::GetAny
())
223
{
224
int32_t index = ipv4->
GetInterfaceForAddress
(src);
225
NS_ASSERT
(index >= 0);
226
oif = ipv4->
GetNetDevice
(index);
227
NS_LOG_LOGIC
(
"Set index "
<< oif <<
"from source "
<< src);
228
}
229
230
// TBD-- we could cache the route and just check its validity
231
route = ipv4->
GetRoutingProtocol
()->
RouteOutput
(p, header, oif, errno_);
232
if
(route != 0)
233
{
234
NS_LOG_LOGIC
(
"Route exists"
);
235
if
(!
m_iphdrincl
)
236
{
237
ipv4->
Send
(p, route->
GetSource
(), dst,
m_protocol
, route);
238
}
239
else
240
{
241
ipv4->
SendWithHeader
(p, header, route);
242
}
243
NotifyDataSent
(p->
GetSize
());
244
NotifySend
(
GetTxAvailable
());
245
return
p->
GetSize
();
246
}
247
else
248
{
249
NS_LOG_DEBUG
(
"dropped because no outgoing route."
);
250
return
-1;
251
}
252
}
253
return
0;
254
}
255
uint32_t
256
Ipv4RawSocketImpl::GetRxAvailable
(
void
)
const
257
{
258
NS_LOG_FUNCTION
(
this
);
259
uint32_t rx = 0;
260
for
(std::list<Data>::const_iterator i =
m_recv
.begin (); i !=
m_recv
.end (); ++i)
261
{
262
rx += (i->packet)->GetSize ();
263
}
264
return
rx;
265
}
266
Ptr<Packet>
267
Ipv4RawSocketImpl::Recv
(uint32_t maxSize, uint32_t flags)
268
{
269
NS_LOG_FUNCTION
(
this
<< maxSize << flags);
270
Address
tmp;
271
return
RecvFrom
(maxSize, flags, tmp);
272
}
273
Ptr<Packet>
274
Ipv4RawSocketImpl::RecvFrom
(uint32_t maxSize, uint32_t flags,
275
Address
&fromAddress)
276
{
277
NS_LOG_FUNCTION
(
this
<< maxSize << flags << fromAddress);
278
if
(
m_recv
.empty ())
279
{
280
return
0;
281
}
282
struct
Data
data =
m_recv
.front ();
283
m_recv
.pop_front ();
284
InetSocketAddress
inet =
InetSocketAddress
(data.
fromIp
, data.
fromProtocol
);
285
fromAddress = inet;
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_recv
.push_front (data);
294
return
first;
295
}
296
return
data.
packet
;
297
}
298
299
void
300
Ipv4RawSocketImpl::SetProtocol
(uint16_t protocol)
301
{
302
NS_LOG_FUNCTION
(
this
<< protocol);
303
m_protocol
= protocol;
304
}
305
306
bool
307
Ipv4RawSocketImpl::ForwardUp
(
Ptr<const Packet>
p,
Ipv4Header
ipHeader,
Ptr<Ipv4Interface>
incomingInterface)
308
{
309
NS_LOG_FUNCTION
(
this
<< *p << ipHeader << incomingInterface);
310
if
(
m_shutdownRecv
)
311
{
312
return
false
;
313
}
314
NS_LOG_LOGIC
(
"src = "
<<
m_src
<<
" dst = "
<<
m_dst
);
315
if
((
m_src
==
Ipv4Address::GetAny
() || ipHeader.
GetDestination
() ==
m_src
) &&
316
(
m_dst
==
Ipv4Address::GetAny
() || ipHeader.
GetSource
() ==
m_dst
) &&
317
ipHeader.
GetProtocol
() ==
m_protocol
)
318
{
319
Ptr<Packet>
copy = p->
Copy
();
320
// Should check via getsockopt ()..
321
if
(
IsRecvPktInfo
())
322
{
323
Ipv4PacketInfoTag
tag;
324
copy->
RemovePacketTag
(tag);
325
tag.
SetRecvIf
(incomingInterface->
GetDevice
()->
GetIfIndex
());
326
copy->
AddPacketTag
(tag);
327
}
328
if
(
m_protocol
== 1)
329
{
330
Icmpv4Header
icmpHeader;
331
copy->
PeekHeader
(icmpHeader);
332
uint8_t type = icmpHeader.
GetType
();
333
if
(type < 32 &&
334
((uint32_t(1) << type) &
m_icmpFilter
))
335
{
336
// filter out icmp packet.
337
return
false
;
338
}
339
}
340
copy->
AddHeader
(ipHeader);
341
struct
Data
data;
342
data.
packet
= copy;
343
data.
fromIp
= ipHeader.
GetSource
();
344
data.
fromProtocol
= ipHeader.
GetProtocol
();
345
m_recv
.push_back (data);
346
NotifyDataRecv
();
347
return
true
;
348
}
349
return
false
;
350
}
351
352
bool
353
Ipv4RawSocketImpl::SetAllowBroadcast
(
bool
allowBroadcast)
354
{
355
if
(!allowBroadcast)
356
{
357
return
false
;
358
}
359
return
true
;
360
}
361
362
bool
363
Ipv4RawSocketImpl::GetAllowBroadcast
()
const
364
{
365
return
true
;
366
}
367
368
}
// namespace ns3
src
internet
model
ipv4-raw-socket-impl.cc
Generated on Tue Oct 9 2012 16:45:38 for ns-3 by
1.8.1.2