A Discrete-Event Network Simulator
API
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>
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
16namespace ns3 {
17
18NS_LOG_COMPONENT_DEFINE ("Ipv4RawSocketImpl");
19
20NS_OBJECT_ENSURE_REGISTERED (Ipv4RawSocketImpl);
21
22TypeId
24{
25 static TypeId tid = TypeId ("ns3::Ipv4RawSocketImpl")
26 .SetParent<Socket> ()
27 .SetGroupName ("Internet")
28 .AddAttribute ("Protocol", "Protocol number to match.",
29 UintegerValue (0),
31 MakeUintegerChecker<uint16_t> ())
32 .AddAttribute ("IcmpFilter",
33 "Any icmp header whose type field matches a bit in this filter is dropped. Type must be less than 32.",
34 UintegerValue (0),
36 MakeUintegerChecker<uint32_t> ())
37 //
38 // from raw (7), linux, returned length of Send/Recv should be
39 //
40 // | IP_HDRINC on | off |
41 // ----------+---------------+-------------+-
42 // Send(Ipv4)| hdr + payload | payload |
43 // Recv(Ipv4)| hdr + payload | hdr+payload |
44 // ----------+---------------+-------------+-
45 .AddAttribute ("IpHeaderInclude",
46 "Include IP Header information (a.k.a setsockopt (IP_HDRINCL)).",
47 BooleanValue (false),
50 ;
51 return tid;
52}
53
55{
56 NS_LOG_FUNCTION (this);
58 m_node = 0;
61 m_protocol = 0;
62 m_shutdownSend = false;
63 m_shutdownRecv = false;
64}
65
66void
68{
69 NS_LOG_FUNCTION (this << node);
70 m_node = node;
71}
72
73void
75{
76 NS_LOG_FUNCTION (this);
77 m_node = 0;
79}
80
83{
84 NS_LOG_FUNCTION (this);
85 return m_err;
86}
87
90{
91 NS_LOG_FUNCTION (this);
92 return NS3_SOCK_RAW;
93}
94
97{
98 NS_LOG_FUNCTION (this);
99 return m_node;
100}
101int
103{
104 NS_LOG_FUNCTION (this << address);
106 {
108 return -1;
109 }
111 m_src = ad.GetIpv4 ();
112 return 0;
113}
114int
116{
117 NS_LOG_FUNCTION (this);
119 return 0;
120}
121int
123{
124 NS_LOG_FUNCTION (this);
125 return (-1);
126}
127int
129{
130 NS_LOG_FUNCTION (this << address);
132 return 0;
133}
134int
136{
137 NS_LOG_FUNCTION (this << address);
138
139 if (m_dst == Ipv4Address::GetAny ())
140 {
142 return -1;
143 }
144
146
147 return 0;
148}
149int
151{
152 NS_LOG_FUNCTION (this);
153 Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
154 if (ipv4 != 0)
155 {
156 ipv4->DeleteRawSocket (this);
157 }
158 return 0;
159}
160int
162{
163 NS_LOG_FUNCTION (this);
164 m_shutdownSend = true;
165 return 0;
166}
167int
169{
170 NS_LOG_FUNCTION (this);
171 m_shutdownRecv = true;
172 return 0;
173}
174int
176{
177 NS_LOG_FUNCTION (this << address);
179 {
181 return -1;
182 }
184 m_dst = ad.GetIpv4 ();
185 SetIpTos (ad.GetTos ());
186
187 return 0;
188}
189int
191{
192 NS_LOG_FUNCTION (this);
194 return -1;
195}
198{
199 NS_LOG_FUNCTION (this);
200 return 0xffffffff;
201}
202int
204{
205 NS_LOG_FUNCTION (this << p << flags);
207 to.SetTos (GetIpTos ());
208 return SendTo (p, flags, to);
209}
210int
212 const Address &toAddress)
213{
214 NS_LOG_FUNCTION (this << p << flags << toAddress);
215 if (!InetSocketAddress::IsMatchingType (toAddress))
216 {
218 return -1;
219 }
220 if (m_shutdownSend)
221 {
222 return 0;
223 }
224
226 Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
227 Ipv4Address dst = ad.GetIpv4 ();
228 Ipv4Address src = m_src;
229 uint8_t tos = ad.GetTos ();
230
231 uint8_t priority = GetPriority ();
232 if (tos)
233 {
234 SocketIpTosTag ipTosTag;
235 ipTosTag.SetTos (tos);
236 // This packet may already have a SocketIpTosTag (see BUG 2440)
237 p->ReplacePacketTag (ipTosTag);
238 priority = IpTos2Priority (tos);
239 }
240 if (priority)
241 {
242 SocketPriorityTag priorityTag;
243 priorityTag.SetPriority (priority);
244 p->ReplacePacketTag (priorityTag);
245 }
246
247 if (IsManualIpTtl () && GetIpTtl () != 0 && !dst.IsMulticast () && !dst.IsBroadcast ())
248 {
249 SocketIpTtlTag tag;
250 tag.SetTtl (GetIpTtl ());
251 p->AddPacketTag (tag);
252 }
253
254 bool subnetDirectedBroadcast = false;
256 {
257 uint32_t iif = ipv4->GetInterfaceForDevice (m_boundnetdevice);
258 for (uint32_t j = 0; j < ipv4->GetNAddresses (iif); j++)
259 {
260 Ipv4InterfaceAddress ifAddr = ipv4->GetAddress (iif, j);
261 if (dst.IsSubnetDirectedBroadcast (ifAddr.GetMask ()))
262 {
263 subnetDirectedBroadcast = true;
264 }
265 }
266 }
267
268 if (dst.IsBroadcast () || subnetDirectedBroadcast)
269 {
270 Ptr <NetDevice> boundNetDevice = m_boundnetdevice;
271 if (ipv4->GetNInterfaces () == 1)
272 {
273 boundNetDevice = ipv4->GetNetDevice (0);
274 }
275 if (boundNetDevice == 0)
276 {
277 NS_LOG_DEBUG ("dropped because no outgoing route.");
278 return -1;
279 }
280
281 Ipv4Header header;
282 uint32_t pktSize = p->GetSize ();
283 if (!m_iphdrincl)
284 {
285 header.SetDestination (dst);
286 header.SetProtocol (m_protocol);
287 Ptr<Ipv4Route> route = Create <Ipv4Route> ();
288 route->SetSource (src);
289 route->SetDestination (dst);
290 route->SetOutputDevice (boundNetDevice);
291 ipv4->Send (p, route->GetSource (), dst, m_protocol, route);
292 }
293 else
294 {
295 p->RemoveHeader (header);
296 dst = header.GetDestination ();
297 src = header.GetSource ();
298 pktSize += header.GetSerializedSize ();
299 Ptr<Ipv4Route> route = Create <Ipv4Route> ();
300 route->SetSource (src);
301 route->SetDestination (dst);
302 route->SetOutputDevice (boundNetDevice);
303 ipv4->SendWithHeader (p, header, route);
304 }
307 return pktSize;
308 }
309
310
311 if (ipv4->GetRoutingProtocol ())
312 {
313 Ipv4Header header;
314 if (!m_iphdrincl)
315 {
316 header.SetDestination (dst);
317 header.SetProtocol (m_protocol);
318 }
319 else
320 {
321 p->RemoveHeader (header);
322 dst = header.GetDestination ();
323 src = header.GetSource ();
324 }
325 SocketErrno errno_ = ERROR_NOTERROR; //do not use errno as it is the standard C last error number
326 Ptr<Ipv4Route> route;
327 Ptr<NetDevice> oif = m_boundnetdevice; //specify non-zero if bound to a source address
328 if (!oif && src != Ipv4Address::GetAny ())
329 {
330 int32_t index = ipv4->GetInterfaceForAddress (src);
331 NS_ASSERT (index >= 0);
332 oif = ipv4->GetNetDevice (index);
333 NS_LOG_LOGIC ("Set index " << oif << "from source " << src);
334 }
335
336 // TBD-- we could cache the route and just check its validity
337 route = ipv4->GetRoutingProtocol ()->RouteOutput (p, header, oif, errno_);
338 if (route != 0)
339 {
340 NS_LOG_LOGIC ("Route exists");
341 uint32_t pktSize = p->GetSize ();
342 if (!m_iphdrincl)
343 {
344 ipv4->Send (p, route->GetSource (), dst, m_protocol, route);
345 }
346 else
347 {
348 pktSize += header.GetSerializedSize ();
349 ipv4->SendWithHeader (p, header, route);
350 }
353 return pktSize;
354 }
355 else
356 {
357 NS_LOG_DEBUG ("dropped because no outgoing route.");
358 return -1;
359 }
360 }
361 return 0;
362}
365{
366 NS_LOG_FUNCTION (this);
367 uint32_t rx = 0;
368 for (std::list<Data>::const_iterator i = m_recv.begin (); i != m_recv.end (); ++i)
369 {
370 rx += (i->packet)->GetSize ();
371 }
372 return rx;
373}
376{
377 NS_LOG_FUNCTION (this << maxSize << flags);
378 Address tmp;
379 return RecvFrom (maxSize, flags, tmp);
380}
383 Address &fromAddress)
384{
385 NS_LOG_FUNCTION (this << maxSize << flags << fromAddress);
386 if (m_recv.empty ())
387 {
388 return 0;
389 }
390 struct Data data = m_recv.front ();
391 m_recv.pop_front ();
392 InetSocketAddress inet = InetSocketAddress (data.fromIp, data.fromProtocol);
393 fromAddress = inet;
394 if (data.packet->GetSize () > maxSize)
395 {
396 Ptr<Packet> first = data.packet->CreateFragment (0, maxSize);
397 if (!(flags & MSG_PEEK))
398 {
399 data.packet->RemoveAtStart (maxSize);
400 }
401 m_recv.push_front (data);
402 return first;
403 }
404 return data.packet;
405}
406
407void
409{
410 NS_LOG_FUNCTION (this << protocol);
411 m_protocol = protocol;
412}
413
414bool
416{
417 NS_LOG_FUNCTION (this << *p << ipHeader << incomingInterface);
418 if (m_shutdownRecv)
419 {
420 return false;
421 }
422
423 Ptr<NetDevice> boundNetDevice = Socket::GetBoundNetDevice();
424 if (boundNetDevice)
425 {
426 if (boundNetDevice != incomingInterface->GetDevice())
427 {
428 return false;
429 }
430 }
431
432 NS_LOG_LOGIC ("src = " << m_src << " dst = " << m_dst);
433 if ((m_src == Ipv4Address::GetAny () || ipHeader.GetDestination () == m_src) &&
434 (m_dst == Ipv4Address::GetAny () || ipHeader.GetSource () == m_dst) &&
435 ipHeader.GetProtocol () == m_protocol)
436 {
437 Ptr<Packet> copy = p->Copy ();
438 // Should check via getsockopt ()..
439 if (IsRecvPktInfo ())
440 {
442 copy->RemovePacketTag (tag);
443 tag.SetAddress (ipHeader.GetDestination ());
444 tag.SetTtl (ipHeader.GetTtl ());
445 tag.SetRecvIf (incomingInterface->GetDevice ()->GetIfIndex ());
446 copy->AddPacketTag (tag);
447 }
448
449 //Check only version 4 options
450 if (IsIpRecvTos ())
451 {
452 SocketIpTosTag ipTosTag;
453 ipTosTag.SetTos (ipHeader.GetTos ());
454 copy->AddPacketTag (ipTosTag);
455 }
456
457 if (IsIpRecvTtl ())
458 {
459 SocketIpTtlTag ipTtlTag;
460 ipTtlTag.SetTtl (ipHeader.GetTtl ());
461 copy->AddPacketTag (ipTtlTag);
462 }
463
464 if (m_protocol == 1)
465 {
466 Icmpv4Header icmpHeader;
467 copy->PeekHeader (icmpHeader);
468 uint8_t type = icmpHeader.GetType ();
469 if (type < 32 &&
470 ((uint32_t(1) << type) & m_icmpFilter))
471 {
472 // filter out icmp packet.
473 return false;
474 }
475 }
476 copy->AddHeader (ipHeader);
477 struct Data data;
478 data.packet = copy;
479 data.fromIp = ipHeader.GetSource ();
480 data.fromProtocol = ipHeader.GetProtocol ();
481 m_recv.push_back (data);
483 return true;
484 }
485 return false;
486}
487
488bool
490{
491 NS_LOG_FUNCTION (this << allowBroadcast);
492 if (!allowBroadcast)
493 {
494 return false;
495 }
496 return true;
497}
498
499bool
501{
502 NS_LOG_FUNCTION (this);
503 return true;
504}
505
506} // namespace ns3
a polymophic address class
Definition: address.h:91
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Base class for all the ICMP packet headers.
Definition: icmpv4.h:41
uint8_t GetType(void) const
Get ICMP type.
Definition: icmpv4.cc:121
an Inet address class
uint8_t GetTos(void) const
Ipv4Address GetIpv4(void) const
static bool IsMatchingType(const Address &address)
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:41
static Ipv4Address GetAny(void)
Packet header for IPv4.
Definition: ipv4-header.h:34
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
virtual uint32_t GetSerializedSize(void) const
Definition: ipv4-header.cc:375
uint8_t GetTos(void) const
Definition: ipv4-header.cc:194
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:272
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:278
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:265
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:77
a class to store IPv4 address information on an interface
Ipv4Mask GetMask(void) const
Get the network mask.
Ptr< NetDevice > GetDevice(void) const
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.
virtual int GetPeerName(Address &address) const
Get the peer address of a connected socket.
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)
Send data to a specified peer.
virtual int ShutdownSend(void)
Ipv4Address m_src
Source address.
virtual int ShutdownRecv(void)
virtual int Bind()
Allocate a local IPv4 endpoint for this socket.
virtual int Connect(const Address &address)
Initiate a connection to a remote host.
virtual uint32_t GetRxAvailable(void) const
Return number of bytes which can be returned from one or multiple calls to Recv.
virtual void DoDispose(void)
Destructor implementation.
Ipv4Address m_dst
Destination address.
static TypeId GetTypeId(void)
Get the type ID of this class.
std::list< struct Data > m_recv
Packet waiting to be processed.
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)
Read a single packet from the socket and retrieve the sender address.
virtual enum Socket::SocketType GetSocketType(void) const
Get socket type (NS3_SOCK_RAW)
void SetProtocol(uint16_t protocol)
Set protocol field.
virtual int Close(void)
Close a socket.
virtual int GetSockName(Address &address) const
Get socket address.
bool m_iphdrincl
Include IP Header information (a.k.a setsockopt (IP_HDRINCL))
uint16_t m_protocol
Protocol.
virtual bool GetAllowBroadcast() const
Query whether broadcast datagram transmissions are allowed.
virtual bool SetAllowBroadcast(bool allowBroadcast)
Configure whether broadcast datagram transmissions are allowed.
virtual int Listen(void)
Listen for incoming connections.
enum Socket::SocketErrno m_err
Last error number.
virtual uint32_t GetTxAvailable(void) const
Returns the number of bytes which can be sent in a single call to Send.
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.
virtual Ptr< Node > GetNode(void) const
Return the node this socket is associated with.
void SetNode(Ptr< Node > node)
Set the node associated with this socket.
virtual int Bind6()
Allocate a local IPv6 endpoint for this socket.
virtual enum Socket::SocketErrno GetErrno() const
Get last error number.
bool m_shutdownSend
Flag to shutdown send capability.
virtual int Send(Ptr< Packet > p, uint32_t flags)
Send data (or dummy data) to the remote host.
virtual uint32_t GetIfIndex(void) const =0
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:963
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:956
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:290
bool ReplacePacketTag(Tag &tag)
Replace the value of a packet tag.
Definition: packet.cc:970
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
A low-level Socket API based loosely on the BSD Socket API.
Definition: socket.h:67
Ptr< NetDevice > GetBoundNetDevice()
Returns socket's bound NetDevice, if any.
Definition: socket.cc:351
uint8_t GetPriority(void) const
Query the priority value of this socket.
Definition: socket.cc:396
bool IsIpRecvTtl(void) const
Ask if the socket is currently passing information about IP_TTL up the stack.
Definition: socket.cc:532
void SetIpTos(uint8_t ipTos)
Manually set IP Type of Service field.
Definition: socket.cc:437
void NotifySend(uint32_t spaceAvailable)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:295
bool IsRecvPktInfo() const
Get status indicating whether enable/disable packet information to socket.
Definition: socket.cc:364
virtual void DoDispose(void)
Destructor implementation.
Definition: socket.cc:315
SocketType
Enumeration of the possible socket types.
Definition: socket.h:104
@ NS3_SOCK_RAW
Definition: socket.h:108
static uint8_t IpTos2Priority(uint8_t ipTos)
Return the priority corresponding to a given TOS value.
Definition: socket.cc:402
bool IsManualIpTtl(void) const
Checks if the socket has a specific IPv4 TTL set.
Definition: socket.cc:377
bool IsIpRecvTos(void) const
Ask if the socket is currently passing information about IP Type of Service up the stack.
Definition: socket.cc:465
void NotifyDataRecv(void)
Notify through the callback (if set) that some data have been received.
Definition: socket.cc:305
Ptr< NetDevice > m_boundnetdevice
the device this socket is bound to (might be null).
Definition: socket.h:1077
virtual uint8_t GetIpTtl(void) const
Query the value of IP Time to Live field of this socket.
Definition: socket.cc:520
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
@ ERROR_INVAL
Definition: socket.h:91
@ ERROR_OPNOTSUPP
Definition: socket.h:89
@ ERROR_NOTERROR
Definition: socket.h:83
@ ERROR_NOTCONN
Definition: socket.h:85
void NotifyDataSent(uint32_t size)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:285
uint8_t GetIpTos(void) const
Query the value of IP Type of Service of this socket.
Definition: socket.cc:453
Ptr< Packet > Recv(void)
Read a single packet from the socket.
Definition: socket.cc:175
indicates whether the socket has IP_TOS set.
Definition: socket.h:1263
void SetTos(uint8_t tos)
Set the tag's TOS.
Definition: socket.cc:785
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer.
Definition: socket.h:1117
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition: socket.cc:604
indicates whether the socket has a priority set.
Definition: socket.h:1309
void SetPriority(uint8_t priority)
Set the tag's priority.
Definition: socket.cc:842
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Hold an unsigned integer type.
Definition: uinteger.h:44
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:85
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:45
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#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:45
Definition: first.py:1
address
Definition: first.py:40
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:129
uint8_t data[writeSize]
IPv4 raw data and additional information.
uint32_t pktSize
packet size used for the simulation (in bytes)
Definition: wifi-bianchi.cc:89