A Discrete-Event Network Simulator
API
ipv4-raw-socket-impl.cc
Go to the documentation of this file.
2
3#include "icmpv4.h"
4#include "ipv4-l3-protocol.h"
5
6#include "ns3/boolean.h"
7#include "ns3/inet-socket-address.h"
8#include "ns3/ipv4-packet-info-tag.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 "ns3/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);
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
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 bool subnetDirectedBroadcast = false;
280 {
281 uint32_t iif = ipv4->GetInterfaceForDevice(m_boundnetdevice);
282 for (uint32_t j = 0; j < ipv4->GetNAddresses(iif); j++)
283 {
284 Ipv4InterfaceAddress ifAddr = ipv4->GetAddress(iif, j);
285 if (dst.IsSubnetDirectedBroadcast(ifAddr.GetMask()))
286 {
287 subnetDirectedBroadcast = true;
288 }
289 }
290 }
291
292 if (dst.IsBroadcast() || subnetDirectedBroadcast)
293 {
294 Ptr<NetDevice> boundNetDevice = m_boundnetdevice;
295 if (ipv4->GetNInterfaces() == 1)
296 {
297 boundNetDevice = ipv4->GetNetDevice(0);
298 }
299 if (!boundNetDevice)
300 {
301 NS_LOG_DEBUG("dropped because no outgoing route.");
302 return -1;
303 }
304
305 Ipv4Header header;
306 uint32_t pktSize = p->GetSize();
307 if (!m_iphdrincl)
308 {
309 header.SetDestination(dst);
310 header.SetProtocol(m_protocol);
311 Ptr<Ipv4Route> route = Create<Ipv4Route>();
312 route->SetSource(src);
313 route->SetDestination(dst);
314 route->SetOutputDevice(boundNetDevice);
315 ipv4->Send(p, route->GetSource(), dst, m_protocol, route);
316 }
317 else
318 {
319 p->RemoveHeader(header);
320 dst = header.GetDestination();
321 src = header.GetSource();
322 pktSize += header.GetSerializedSize();
323 Ptr<Ipv4Route> route = Create<Ipv4Route>();
324 route->SetSource(src);
325 route->SetDestination(dst);
326 route->SetOutputDevice(boundNetDevice);
327 ipv4->SendWithHeader(p, header, route);
328 }
331 return pktSize;
332 }
333
334 if (ipv4->GetRoutingProtocol())
335 {
336 Ipv4Header header;
337 if (!m_iphdrincl)
338 {
339 header.SetDestination(dst);
340 header.SetProtocol(m_protocol);
341 }
342 else
343 {
344 p->RemoveHeader(header);
345 dst = header.GetDestination();
346 src = header.GetSource();
347 }
348 SocketErrno errno_ =
349 ERROR_NOTERROR; // do not use errno as it is the standard C last error number
350 Ptr<Ipv4Route> route;
351 Ptr<NetDevice> oif = m_boundnetdevice; // specify non-zero if bound to a source address
352 if (!oif && src != Ipv4Address::GetAny())
353 {
354 int32_t index = ipv4->GetInterfaceForAddress(src);
355 NS_ASSERT(index >= 0);
356 oif = ipv4->GetNetDevice(index);
357 NS_LOG_LOGIC("Set index " << oif << "from source " << src);
358 }
359
360 // TBD-- we could cache the route and just check its validity
361 route = ipv4->GetRoutingProtocol()->RouteOutput(p, header, oif, errno_);
362 if (route)
363 {
364 NS_LOG_LOGIC("Route exists");
365 uint32_t pktSize = p->GetSize();
366 if (!m_iphdrincl)
367 {
368 ipv4->Send(p, route->GetSource(), dst, m_protocol, route);
369 }
370 else
371 {
372 pktSize += header.GetSerializedSize();
373 ipv4->SendWithHeader(p, header, route);
374 }
377 return pktSize;
378 }
379 else
380 {
381 NS_LOG_DEBUG("dropped because no outgoing route.");
382 return -1;
383 }
384 }
385 return 0;
386}
387
390{
391 NS_LOG_FUNCTION(this);
392 uint32_t rx = 0;
393 for (std::list<Data>::const_iterator i = m_recv.begin(); i != m_recv.end(); ++i)
394 {
395 rx += (i->packet)->GetSize();
396 }
397 return rx;
398}
399
402{
403 NS_LOG_FUNCTION(this << maxSize << flags);
404 Address tmp;
405 return RecvFrom(maxSize, flags, tmp);
406}
407
410{
411 NS_LOG_FUNCTION(this << maxSize << flags << fromAddress);
412 if (m_recv.empty())
413 {
414 return nullptr;
415 }
416 struct Data data = m_recv.front();
417 m_recv.pop_front();
418 InetSocketAddress inet = InetSocketAddress(data.fromIp, data.fromProtocol);
419 fromAddress = inet;
420 if (data.packet->GetSize() > maxSize)
421 {
422 Ptr<Packet> first = data.packet->CreateFragment(0, maxSize);
423 if (!(flags & MSG_PEEK))
424 {
425 data.packet->RemoveAtStart(maxSize);
426 }
427 m_recv.push_front(data);
428 return first;
429 }
430 return data.packet;
431}
432
433void
435{
436 NS_LOG_FUNCTION(this << protocol);
437 m_protocol = protocol;
438}
439
440bool
442 Ipv4Header ipHeader,
443 Ptr<Ipv4Interface> incomingInterface)
444{
445 NS_LOG_FUNCTION(this << *p << ipHeader << incomingInterface);
446 if (m_shutdownRecv)
447 {
448 return false;
449 }
450
451 Ptr<NetDevice> boundNetDevice = Socket::GetBoundNetDevice();
452 if (boundNetDevice)
453 {
454 if (boundNetDevice != incomingInterface->GetDevice())
455 {
456 return false;
457 }
458 }
459
460 NS_LOG_LOGIC("src = " << m_src << " dst = " << m_dst);
461 if ((m_src == Ipv4Address::GetAny() || ipHeader.GetDestination() == m_src) &&
462 (m_dst == Ipv4Address::GetAny() || ipHeader.GetSource() == m_dst) &&
463 ipHeader.GetProtocol() == m_protocol)
464 {
465 Ptr<Packet> copy = p->Copy();
466 // Should check via getsockopt ()..
467 if (IsRecvPktInfo())
468 {
470 copy->RemovePacketTag(tag);
471 tag.SetAddress(ipHeader.GetDestination());
472 tag.SetTtl(ipHeader.GetTtl());
473 tag.SetRecvIf(incomingInterface->GetDevice()->GetIfIndex());
474 copy->AddPacketTag(tag);
475 }
476
477 // Check only version 4 options
478 if (IsIpRecvTos())
479 {
480 SocketIpTosTag ipTosTag;
481 ipTosTag.SetTos(ipHeader.GetTos());
482 copy->AddPacketTag(ipTosTag);
483 }
484
485 if (IsIpRecvTtl())
486 {
487 SocketIpTtlTag ipTtlTag;
488 ipTtlTag.SetTtl(ipHeader.GetTtl());
489 copy->AddPacketTag(ipTtlTag);
490 }
491
492 if (m_protocol == 1)
493 {
494 Icmpv4Header icmpHeader;
495 copy->PeekHeader(icmpHeader);
496 uint8_t type = icmpHeader.GetType();
497 if (type < 32 && ((uint32_t(1) << type) & m_icmpFilter))
498 {
499 // filter out icmp packet.
500 return false;
501 }
502 }
503 copy->AddHeader(ipHeader);
504 struct Data data;
505 data.packet = copy;
506 data.fromIp = ipHeader.GetSource();
507 data.fromProtocol = ipHeader.GetProtocol();
508 m_recv.push_back(data);
510 return true;
511 }
512 return false;
513}
514
515bool
517{
518 NS_LOG_FUNCTION(this << allowBroadcast);
519 if (!allowBroadcast)
520 {
521 return false;
522 }
523 return true;
524}
525
526bool
528{
529 NS_LOG_FUNCTION(this);
530 return true;
531}
532
533} // namespace ns3
a polymophic address class
Definition: address.h:92
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:43
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.
Ptr< NetDevice > GetDevice() 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.
Ptr< Node > GetNode() const override
Return the node this socket is associated with.
int GetPeerName(Address &address) const override
Get the peer address of a connected socket.
Ipv4Address m_src
Source address.
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.
std::list< struct Data > m_recv
Packet waiting to be processed.
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.
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))
enum Socket::SocketErrno GetErrno() const override
Get last error number.
uint16_t m_protocol
Protocol.
int Connect(const Address &address) override
Initiate a connection to a remote host.
int Bind6() override
Allocate a local IPv6 endpoint for this socket.
enum Socket::SocketErrno m_err
Last error number.
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.
enum Socket::SocketType GetSocketType() const override
Get socket type (NS3_SOCK_RAW)
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
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:986
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:979
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:305
bool ReplacePacketTag(Tag &tag)
Replace the value of a packet tag.
Definition: packet.cc:994
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:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
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: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:132
uint8_t data[writeSize]
IPv4 raw data and additional information.
uint32_t pktSize
packet size used for the simulation (in bytes)