A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv4-raw-socket-impl.cc
Go to the documentation of this file.
2
3#include "icmpv4.h"
6
7#include "ns3/boolean.h"
8#include "ns3/inet-socket-address.h"
9#include "ns3/log.h"
10#include "ns3/node.h"
11#include "ns3/packet.h"
12#include "ns3/uinteger.h"
13
14#ifdef __WIN32__
15#include "win32-internet.h"
16#else
17#include <netinet/in.h>
18#include <sys/socket.h>
19#endif
20
21#include <sys/types.h>
22
23namespace ns3
24{
25
26NS_LOG_COMPONENT_DEFINE("Ipv4RawSocketImpl");
27
28NS_OBJECT_ENSURE_REGISTERED(Ipv4RawSocketImpl);
29
30TypeId
32{
33 static TypeId tid =
34 TypeId("ns3::Ipv4RawSocketImpl")
36 .SetGroupName("Internet")
37 .AddAttribute("Protocol",
38 "Protocol number to match.",
41 MakeUintegerChecker<uint16_t>())
42 .AddAttribute("IcmpFilter",
43 "Any icmp header whose type field matches a bit in this filter is "
44 "dropped. Type must be less than 32.",
47 MakeUintegerChecker<uint32_t>())
48 //
49 // from raw (7), linux, returned length of Send/Recv should be
50 //
51 // | IP_HDRINC on | off |
52 // ----------+---------------+-------------+-
53 // Send(Ipv4)| hdr + payload | payload |
54 // Recv(Ipv4)| hdr + payload | hdr+payload |
55 // ----------+---------------+-------------+-
56 .AddAttribute("IpHeaderInclude",
57 "Include IP Header information (a.k.a setsockopt (IP_HDRINCL)).",
58 BooleanValue(false),
61 return tid;
62}
63
65{
66 NS_LOG_FUNCTION(this);
68 m_node = nullptr;
71 m_protocol = 0;
72 m_shutdownSend = false;
73 m_shutdownRecv = false;
74}
75
76void
78{
79 NS_LOG_FUNCTION(this << node);
80 m_node = node;
81}
82
83void
85{
86 NS_LOG_FUNCTION(this);
87 m_node = nullptr;
89}
90
93{
94 NS_LOG_FUNCTION(this);
95 return m_err;
96}
97
100{
101 NS_LOG_FUNCTION(this);
102 return NS3_SOCK_RAW;
103}
104
107{
108 NS_LOG_FUNCTION(this);
109 return m_node;
110}
111
112int
114{
115 NS_LOG_FUNCTION(this << address);
117 {
119 return -1;
120 }
122 m_src = ad.GetIpv4();
123 return 0;
124}
125
126int
128{
129 NS_LOG_FUNCTION(this);
131 return 0;
132}
133
134int
136{
137 NS_LOG_FUNCTION(this);
138 return (-1);
139}
140
141int
143{
144 NS_LOG_FUNCTION(this << address);
145 address = InetSocketAddress(m_src, 0);
146 return 0;
147}
148
149int
151{
152 NS_LOG_FUNCTION(this << address);
153
154 if (m_dst == Ipv4Address::GetAny())
155 {
157 return -1;
158 }
159
160 address = InetSocketAddress(m_dst, 0);
161
162 return 0;
163}
164
165int
167{
168 NS_LOG_FUNCTION(this);
169 Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4>();
170 if (ipv4)
171 {
172 ipv4->DeleteRawSocket(this);
173 }
174 return 0;
175}
176
177int
179{
180 NS_LOG_FUNCTION(this);
181 m_shutdownSend = true;
182 return 0;
183}
184
185int
187{
188 NS_LOG_FUNCTION(this);
189 m_shutdownRecv = true;
190 return 0;
191}
192
193int
195{
196 NS_LOG_FUNCTION(this << address);
198 {
201 return -1;
202 }
204 m_dst = ad.GetIpv4();
205 SetIpTos(ad.GetTos());
207
208 return 0;
209}
210
211int
213{
214 NS_LOG_FUNCTION(this);
216 return -1;
217}
218
221{
222 NS_LOG_FUNCTION(this);
223 return 0xffffffff;
224}
225
226int
228{
229 NS_LOG_FUNCTION(this << p << flags);
231 to.SetTos(GetIpTos());
232 return SendTo(p, flags, to);
233}
234
235int
237{
238 NS_LOG_FUNCTION(this << p << flags << toAddress);
239 if (!InetSocketAddress::IsMatchingType(toAddress))
240 {
242 return -1;
243 }
244 if (m_shutdownSend)
245 {
246 return 0;
247 }
248
250 Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4>();
251 Ipv4Address dst = ad.GetIpv4();
252 Ipv4Address src = m_src;
253 uint8_t tos = ad.GetTos();
254
255 uint8_t priority = GetPriority();
256 if (tos)
257 {
258 SocketIpTosTag ipTosTag;
259 ipTosTag.SetTos(tos);
260 // This packet may already have a SocketIpTosTag (see BUG 2440)
261 p->ReplacePacketTag(ipTosTag);
262 priority = IpTos2Priority(tos);
263 }
264 if (priority)
265 {
266 SocketPriorityTag priorityTag;
267 priorityTag.SetPriority(priority);
268 p->ReplacePacketTag(priorityTag);
269 }
270
271 if (IsManualIpTtl() && GetIpTtl() != 0 && !dst.IsMulticast() && !dst.IsBroadcast())
272 {
273 SocketIpTtlTag tag;
274 tag.SetTtl(GetIpTtl());
275 p->AddPacketTag(tag);
276 }
277
278 Ptr<NetDevice> boundNetDevice = m_boundnetdevice;
279
280 if (!m_src.IsAny())
281 {
282 int32_t index = ipv4->GetInterfaceForAddress(m_src);
283 NS_ASSERT(index >= 0);
284 boundNetDevice = ipv4->GetNetDevice(index);
285 }
286
287 bool subnetDirectedBroadcast = false;
288 if (boundNetDevice)
289 {
290 uint32_t iif = ipv4->GetInterfaceForDevice(boundNetDevice);
291 for (uint32_t j = 0; j < ipv4->GetNAddresses(iif); j++)
292 {
293 Ipv4InterfaceAddress ifAddr = ipv4->GetAddress(iif, j);
294 if (dst.IsSubnetDirectedBroadcast(ifAddr.GetMask()))
295 {
296 subnetDirectedBroadcast = true;
297 }
298 }
299 }
300
301 if (dst.IsBroadcast() || subnetDirectedBroadcast)
302 {
303 if (ipv4->GetNInterfaces() == 1)
304 {
305 boundNetDevice = ipv4->GetNetDevice(0);
306 }
307 if (!boundNetDevice)
308 {
309 NS_LOG_DEBUG("dropped because no outgoing route.");
310 return -1;
311 }
312
313 Ipv4Header header;
314 uint32_t pktSize = p->GetSize();
315 if (!m_iphdrincl)
316 {
317 header.SetDestination(dst);
318 header.SetProtocol(m_protocol);
319 Ptr<Ipv4Route> route = Create<Ipv4Route>();
320 route->SetSource(src);
321 route->SetDestination(dst);
322 route->SetOutputDevice(boundNetDevice);
323 route->SetGateway("0.0.0.0");
324 ipv4->Send(p, route->GetSource(), dst, m_protocol, route);
325 }
326 else
327 {
328 p->RemoveHeader(header);
329 dst = header.GetDestination();
330 src = header.GetSource();
331 pktSize += header.GetSerializedSize();
332 Ptr<Ipv4Route> route = Create<Ipv4Route>();
333 route->SetSource(src);
334 route->SetDestination(dst);
335 route->SetOutputDevice(boundNetDevice);
336 route->SetGateway("0.0.0.0");
337 ipv4->SendWithHeader(p, header, route);
338 }
341 return pktSize;
342 }
343
344 if (ipv4->GetRoutingProtocol())
345 {
346 Ipv4Header header;
347 if (!m_iphdrincl)
348 {
349 header.SetDestination(dst);
350 header.SetProtocol(m_protocol);
351 }
352 else
353 {
354 p->RemoveHeader(header);
355 dst = header.GetDestination();
356 src = header.GetSource();
357 }
358 SocketErrno errno_ =
359 ERROR_NOTERROR; // do not use errno as it is the standard C last error number
360 Ptr<Ipv4Route> route;
361 Ptr<NetDevice> oif = m_boundnetdevice; // specify non-zero if bound to a source address
362 if (!oif && src != Ipv4Address::GetAny())
363 {
364 int32_t index = ipv4->GetInterfaceForAddress(src);
365 NS_ASSERT(index >= 0);
366 oif = ipv4->GetNetDevice(index);
367 NS_LOG_LOGIC("Set index " << oif << "from source " << src);
368 }
369
370 // TBD-- we could cache the route and just check its validity
371 route = ipv4->GetRoutingProtocol()->RouteOutput(p, header, oif, errno_);
372 if (route)
373 {
374 NS_LOG_LOGIC("Route exists");
375 uint32_t pktSize = p->GetSize();
376 if (!m_iphdrincl)
377 {
378 ipv4->Send(p, route->GetSource(), dst, m_protocol, route);
379 }
380 else
381 {
382 pktSize += header.GetSerializedSize();
383 ipv4->SendWithHeader(p, header, route);
384 }
387 return pktSize;
388 }
389 else
390 {
391 NS_LOG_DEBUG("dropped because no outgoing route.");
392 return -1;
393 }
394 }
395 return 0;
396}
397
400{
401 NS_LOG_FUNCTION(this);
402 uint32_t rx = 0;
403 for (std::list<Data>::const_iterator i = m_recv.begin(); i != m_recv.end(); ++i)
404 {
405 rx += (i->packet)->GetSize();
406 }
407 return rx;
408}
409
412{
413 NS_LOG_FUNCTION(this << maxSize << flags);
414 Address tmp;
415 return RecvFrom(maxSize, flags, tmp);
416}
417
420{
421 NS_LOG_FUNCTION(this << maxSize << flags << fromAddress);
422 if (m_recv.empty())
423 {
424 return nullptr;
425 }
426 Data data = m_recv.front();
427 m_recv.pop_front();
428 InetSocketAddress inet = InetSocketAddress(data.fromIp, data.fromProtocol);
429 fromAddress = inet;
430 if (data.packet->GetSize() > maxSize)
431 {
432 Ptr<Packet> first = data.packet->CreateFragment(0, maxSize);
433 if (!(flags & MSG_PEEK))
434 {
435 data.packet->RemoveAtStart(maxSize);
436 }
437 m_recv.push_front(data);
438 return first;
439 }
440 return data.packet;
441}
442
443void
445{
446 NS_LOG_FUNCTION(this << protocol);
447 m_protocol = protocol;
448}
449
450bool
452 Ipv4Header ipHeader,
453 Ptr<Ipv4Interface> incomingInterface)
454{
455 NS_LOG_FUNCTION(this << *p << ipHeader << incomingInterface);
456 if (m_shutdownRecv)
457 {
458 return false;
459 }
460
461 Ptr<NetDevice> boundNetDevice = Socket::GetBoundNetDevice();
462 if (boundNetDevice)
463 {
464 if (boundNetDevice != incomingInterface->GetDevice())
465 {
466 return false;
467 }
468 }
469
470 NS_LOG_LOGIC("src = " << m_src << " dst = " << m_dst);
471 if ((m_src == Ipv4Address::GetAny() || ipHeader.GetDestination() == m_src) &&
472 (m_dst == Ipv4Address::GetAny() || ipHeader.GetSource() == m_dst) &&
473 ipHeader.GetProtocol() == m_protocol)
474 {
475 Ptr<Packet> copy = p->Copy();
476 // Should check via getsockopt ()..
477 if (IsRecvPktInfo())
478 {
480 copy->RemovePacketTag(tag);
481 tag.SetAddress(ipHeader.GetDestination());
482 tag.SetTtl(ipHeader.GetTtl());
483 tag.SetRecvIf(incomingInterface->GetDevice()->GetIfIndex());
484 copy->AddPacketTag(tag);
485 }
486
487 // Check only version 4 options
488 if (IsIpRecvTos())
489 {
490 SocketIpTosTag ipTosTag;
491 ipTosTag.SetTos(ipHeader.GetTos());
492 copy->AddPacketTag(ipTosTag);
493 }
494
495 if (IsIpRecvTtl())
496 {
497 SocketIpTtlTag ipTtlTag;
498 ipTtlTag.SetTtl(ipHeader.GetTtl());
499 copy->AddPacketTag(ipTtlTag);
500 }
501
502 if (m_protocol == 1)
503 {
504 Icmpv4Header icmpHeader;
505 copy->PeekHeader(icmpHeader);
506 uint8_t type = icmpHeader.GetType();
507 if (type < 32 && ((uint32_t(1) << type) & m_icmpFilter))
508 {
509 // filter out icmp packet.
510 return false;
511 }
512 }
513 copy->AddHeader(ipHeader);
514 Data data;
515 data.packet = copy;
516 data.fromIp = ipHeader.GetSource();
517 data.fromProtocol = ipHeader.GetProtocol();
518 m_recv.push_back(data);
520 return true;
521 }
522 return false;
523}
524
525bool
527{
528 NS_LOG_FUNCTION(this << allowBroadcast);
529 return allowBroadcast;
530}
531
532bool
534{
535 NS_LOG_FUNCTION(this);
536 return true;
537}
538
539} // namespace ns3
a polymophic address class
Definition: address.h:100
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Base class for all the ICMP packet headers.
Definition: icmpv4.h:42
uint8_t GetType() const
Get ICMP type.
Definition: icmpv4.cc:130
an Inet address class
static bool IsMatchingType(const Address &address)
Ipv4Address GetIpv4() const
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
bool IsAny() const
static Ipv4Address GetAny()
Packet header for IPv4.
Definition: ipv4-header.h:34
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:309
Ipv4Address GetSource() const
Definition: ipv4-header.cc:302
uint8_t GetTos() const
Definition: ipv4-header.cc:196
uint8_t GetProtocol() const
Definition: ipv4-header.cc:281
Ipv4Address GetDestination() const
Definition: ipv4-header.cc:316
uint32_t GetSerializedSize() const override
Definition: ipv4-header.cc:384
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:288
uint8_t GetTtl() const
Definition: ipv4-header.cc:274
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:79
a class to store IPv4 address information on an interface
Ipv4Mask GetMask() const
Get the network mask.
This class implements Linux struct pktinfo in order to deliver ancillary information to the socket in...
void SetRecvIf(uint32_t ifindex)
Set the tag's receiving interface.
void SetAddress(Ipv4Address addr)
Set the tag's address.
void SetTtl(uint8_t ttl)
Set the tag's Time to Live Implemented, but not used in the stack yet.
Ptr< Node > GetNode() const override
Return the node this socket is associated with.
Socket::SocketType GetSocketType() const override
Get socket type (NS3_SOCK_RAW)
int GetPeerName(Address &address) const override
Get the peer address of a connected socket.
Ipv4Address m_src
Source address.
std::list< Data > m_recv
Packet waiting to be processed.
int Bind() override
Allocate a local IPv4 endpoint for this socket.
int Send(Ptr< Packet > p, uint32_t flags) override
Send data (or dummy data) to the remote host.
Ipv4Address m_dst
Destination address.
void DoDispose() override
Destructor implementation.
int Close() override
Close a socket.
int Listen() override
Listen for incoming connections.
bool GetAllowBroadcast() const override
Query whether broadcast datagram transmissions are allowed.
uint32_t GetRxAvailable() const override
Return number of bytes which can be returned from one or multiple calls to Recv.
Socket::SocketErrno m_err
Last error number.
void SetProtocol(uint16_t protocol)
Set protocol field.
Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress) override
Read a single packet from the socket and retrieve the sender address.
bool m_iphdrincl
Include IP Header information (a.k.a setsockopt (IP_HDRINCL))
uint16_t m_protocol
Protocol.
Socket::SocketErrno GetErrno() const override
Get last error number.
int Connect(const Address &address) override
Initiate a connection to a remote host.
int Bind6() override
Allocate a local IPv6 endpoint for this socket.
bool SetAllowBroadcast(bool allowBroadcast) override
Configure whether broadcast datagram transmissions are allowed.
bool ForwardUp(Ptr< const Packet > p, Ipv4Header ipHeader, Ptr< Ipv4Interface > incomingInterface)
Forward up to receive method.
uint32_t m_icmpFilter
ICMPv4 filter specification.
bool m_shutdownRecv
Flag to shutdown receive capability.
static TypeId GetTypeId()
Get the type ID of this class.
void SetNode(Ptr< Node > node)
Set the node associated with this socket.
uint32_t GetTxAvailable() const override
Returns the number of bytes which can be sent in a single call to Send.
bool m_shutdownSend
Flag to shutdown send capability.
int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress) override
Send data to a specified peer.
int GetSockName(Address &address) const override
Get socket address.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
A low-level Socket API based loosely on the BSD Socket API.
Definition: socket.h:68
Ptr< NetDevice > GetBoundNetDevice()
Returns socket's bound NetDevice, if any.
Definition: socket.cc:345
bool IsIpRecvTtl() const
Ask if the socket is currently passing information about IP_TTL up the stack.
Definition: socket.cc:527
Ptr< Packet > Recv()
Read a single packet from the socket.
Definition: socket.cc:172
bool IsManualIpTtl() const
Checks if the socket has a specific IPv4 TTL set.
Definition: socket.cc:372
void SetIpTos(uint8_t ipTos)
Manually set IP Type of Service field.
Definition: socket.cc:432
void NotifySend(uint32_t spaceAvailable)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:290
virtual uint8_t GetIpTtl() const
Query the value of IP Time to Live field of this socket.
Definition: socket.cc:515
bool IsRecvPktInfo() const
Get status indicating whether enable/disable packet information to socket.
Definition: socket.cc:359
uint8_t GetIpTos() const
Query the value of IP Type of Service of this socket.
Definition: socket.cc:448
SocketType
Enumeration of the possible socket types.
Definition: socket.h:107
@ NS3_SOCK_RAW
Definition: socket.h:111
static uint8_t IpTos2Priority(uint8_t ipTos)
Return the priority corresponding to a given TOS value.
Definition: socket.cc:397
void NotifyDataRecv()
Notify through the callback (if set) that some data have been received.
Definition: socket.cc:300
Ptr< NetDevice > m_boundnetdevice
the device this socket is bound to (might be null).
Definition: socket.h:1079
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:84
@ ERROR_INVAL
Definition: socket.h:93
@ ERROR_OPNOTSUPP
Definition: socket.h:91
@ ERROR_NOTERROR
Definition: socket.h:85
@ ERROR_NOTCONN
Definition: socket.h:87
bool IsIpRecvTos() const
Ask if the socket is currently passing information about IP Type of Service up the stack.
Definition: socket.cc:460
void NotifyDataSent(uint32_t size)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:280
void NotifyConnectionSucceeded()
Notify through the callback (if set) that the connection has been established.
Definition: socket.cc:212
uint8_t GetPriority() const
Query the priority value of this socket.
Definition: socket.cc:391
void DoDispose() override
Destructor implementation.
Definition: socket.cc:310
void NotifyConnectionFailed()
Notify through the callback (if set) that the connection has not been established due to an error.
Definition: socket.cc:222
indicates whether the socket has IP_TOS set.
Definition: socket.h:1269
void SetTos(uint8_t tos)
Set the tag's TOS.
Definition: socket.cc:796
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer.
Definition: socket.h:1122
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition: socket.cc:602
indicates whether the socket has a priority set.
Definition: socket.h:1316
void SetPriority(uint8_t priority)
Set the tag's priority.
Definition: socket.cc:852
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Definition: first.py:1
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint32_t GetSize(Ptr< const Packet > packet, const WifiMacHeader *hdr, bool isAmpdu)
Return the total size of the packet after WifiMacHeader and FCS trailer have been added.
Definition: wifi-utils.cc:132
uint8_t data[writeSize]
IPv4 raw data and additional information.
uint32_t pktSize
packet size used for the simulation (in bytes)