A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv6-raw-socket-impl.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007-2009 Strasbourg University
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
7 */
8
10
11#include "icmpv6-header.h"
12#include "icmpv6-l4-protocol.h"
13#include "ipv6-l3-protocol.h"
15#include "ipv6-route.h"
17
18#include "ns3/inet6-socket-address.h"
19#include "ns3/log.h"
20#include "ns3/node.h"
21#include "ns3/packet.h"
22#include "ns3/uinteger.h"
23
24#ifdef __WIN32__
25#include "win32-internet.h"
26#else
27#include <netinet/in.h>
28#include <sys/socket.h>
29#endif
30
31#include <sys/types.h>
32
33namespace ns3
34{
35
36NS_LOG_COMPONENT_DEFINE("Ipv6RawSocketImpl");
37
38NS_OBJECT_ENSURE_REGISTERED(Ipv6RawSocketImpl);
39
40TypeId
42{
43 static TypeId tid = TypeId("ns3::Ipv6RawSocketImpl")
45 .SetGroupName("Internet")
46 .AddAttribute("Protocol",
47 "Protocol number to match.",
51 return tid;
52}
53
66
70
71void
78
79void
81{
82 NS_LOG_FUNCTION(this << node);
83 m_node = node;
84}
85
88{
89 return m_node;
90}
91
94{
95 NS_LOG_FUNCTION(this);
96 return m_err;
97}
98
101{
102 return NS3_SOCK_RAW;
103}
104
105int
107{
108 NS_LOG_FUNCTION(this << address);
109
111 {
113 return -1;
114 }
116 m_src = ad.GetIpv6();
117 return 0;
118}
119
120int
122{
123 NS_LOG_FUNCTION(this);
125 return 0;
126}
127
128int
130{
131 return Bind();
132}
133
134int
136{
137 NS_LOG_FUNCTION(this);
138 address = Inet6SocketAddress(m_src, 0);
139 return 0;
140}
141
142int
144{
145 NS_LOG_FUNCTION(this << address);
146
147 if (m_dst.IsAny())
148 {
150 return -1;
151 }
152
153 address = Inet6SocketAddress(m_dst, 0);
154
155 return 0;
156}
157
158int
160{
161 NS_LOG_FUNCTION(this);
163
165 if (ipv6)
166 {
167 ipv6->DeleteRawSocket(this);
168 }
169 return 0;
170}
171
172int
174{
175 NS_LOG_FUNCTION(this);
176 m_shutdownSend = true;
177 return 0;
178}
179
180int
182{
183 NS_LOG_FUNCTION(this);
184 m_shutdownRecv = true;
185 return 0;
186}
187
188int
190{
191 NS_LOG_FUNCTION(this << address);
192
194 {
197 return -1;
198 }
200 m_dst = ad.GetIpv6();
202
203 return 0;
204}
205
206int
208{
209 NS_LOG_FUNCTION(this);
211 return -1;
212}
213
214int
216{
217 NS_LOG_FUNCTION(this << p << flags);
219 return SendTo(p, flags, to);
220}
221
222int
224{
225 NS_LOG_FUNCTION(this << p << flags << toAddress);
226
228 {
230 return -1;
231 }
232
233 if (m_shutdownSend)
234 {
235 return 0;
236 }
237
240 Ipv6Address dst = ad.GetIpv6();
241
242 if (IsManualIpv6Tclass())
243 {
244 SocketIpv6TclassTag ipTclassTag;
245 ipTclassTag.SetTclass(GetIpv6Tclass());
246 p->AddPacketTag(ipTclassTag);
247 }
248
249 if (IsManualIpv6HopLimit() && GetIpv6HopLimit() != 0 && !dst.IsMulticast())
250 {
253 p->AddPacketTag(tag);
254 }
255
256 if (ipv6->GetRoutingProtocol())
257 {
258 Ipv6Header hdr;
259 hdr.SetDestination(dst);
261 Ptr<Ipv6Route> route = nullptr;
262 Ptr<NetDevice> oif = m_boundnetdevice; // specify non-zero if bound to a specific device
263
264 if (!m_src.IsAny())
265 {
266 int32_t index = ipv6->GetInterfaceForAddress(m_src);
267 NS_ASSERT(index >= 0);
268 oif = ipv6->GetNetDevice(index);
269 }
270
271 route = ipv6->GetRoutingProtocol()->RouteOutput(p, hdr, oif, err);
272
273 if (route)
274 {
275 NS_LOG_LOGIC("Route exists");
277 {
278 /* calculate checksum here for ICMPv6 echo request (sent by ping6)
279 * as we cannot determine source IPv6 address at application level
280 */
281 uint8_t type;
282 p->CopyData(&type, sizeof(type));
284 {
285 Icmpv6Echo hdr(true);
286 p->RemoveHeader(hdr);
287 hdr.CalculatePseudoHeaderChecksum(route->GetSource(),
288 dst,
289 p->GetSize() + hdr.GetSerializedSize(),
291 p->AddHeader(hdr);
292 }
293 }
294
295 uint32_t pktSize = p->GetSize();
296 if (m_src.IsAny())
297 {
298 ipv6->Send(p, route->GetSource(), dst, m_protocol, route);
299 }
300 else
301 {
302 ipv6->Send(p, m_src, dst, m_protocol, route);
303 }
304 // Return only payload size (as Linux does).
307 return pktSize;
308 }
309 else
310 {
311 NS_LOG_DEBUG("No route, dropped!");
312 }
313 }
314 return 0;
315}
316
319{
320 NS_LOG_FUNCTION(this << maxSize << flags);
321 Address tmp;
322 return RecvFrom(maxSize, flags, tmp);
323}
324
327{
328 NS_LOG_FUNCTION(this << maxSize << flags << fromAddress);
329
330 if (m_data.empty())
331 {
332 return nullptr;
333 }
334
335 /* get packet */
336 Data data = m_data.front();
337 m_data.pop_front();
338 fromAddress = Inet6SocketAddress(data.fromIp, data.fromProtocol);
339 if (data.packet->GetSize() > maxSize)
340 {
341 Ptr<Packet> first = data.packet->CreateFragment(0, maxSize);
342 if (!(flags & MSG_PEEK))
343 {
344 data.packet->RemoveAtStart(maxSize);
345 }
346 m_data.push_front(data);
347 return first;
348 }
349
350 return data.packet;
351}
352
353void
356 std::vector<Ipv6Address> sourceAddresses)
357{
358 NS_LOG_FUNCTION(this << address << &filterMode << &sourceAddresses);
359
360 // We can join only one multicast group (or change its params)
362 "Can join only one IPv6 multicast group.");
363
365
367 if (ipv6l3)
368 {
369 if (filterMode == INCLUDE && sourceAddresses.empty())
370 {
371 // it is a leave
373 {
374 int32_t index = ipv6l3->GetInterfaceForDevice(m_boundnetdevice);
375 NS_ASSERT_MSG(index >= 0, "Interface without a valid index");
376 ipv6l3->RemoveMulticastAddress(address, index);
377 }
378 else
379 {
380 ipv6l3->RemoveMulticastAddress(address);
381 }
382 }
383 else
384 {
385 // it is a join or a modification
387 {
388 int32_t index = ipv6l3->GetInterfaceForDevice(m_boundnetdevice);
389 NS_ASSERT_MSG(index >= 0, "Interface without a valid index");
390 ipv6l3->AddMulticastAddress(address, index);
391 }
392 else
393 {
394 ipv6l3->AddMulticastAddress(address);
395 }
396 }
397 }
398}
399
402{
403 NS_LOG_FUNCTION(this);
404 return 0xffffffff;
405}
406
409{
410 NS_LOG_FUNCTION(this);
411 uint32_t rx = 0;
412
413 for (auto it = m_data.begin(); it != m_data.end(); ++it)
414 {
415 rx += (it->packet)->GetSize();
416 }
417
418 return rx;
419}
420
421bool
423{
424 NS_LOG_FUNCTION(this << *p << hdr << device);
425
426 if (m_shutdownRecv)
427 {
428 return false;
429 }
430
431 Ptr<NetDevice> boundNetDevice = Socket::GetBoundNetDevice();
432 if (boundNetDevice)
433 {
434 if (boundNetDevice != device)
435 {
436 return false;
437 }
438 }
439
440 if ((m_src == Ipv6Address::GetAny() || hdr.GetDestination() == m_src) &&
441 (m_dst == Ipv6Address::GetAny() || hdr.GetSource() == m_dst) &&
442 hdr.GetNextHeader() == m_protocol)
443 {
444 Ptr<Packet> copy = p->Copy();
445
447 {
448 /* filter */
449 Icmpv6Header icmpHeader;
450 copy->PeekHeader(icmpHeader);
451 uint8_t type = icmpHeader.GetType();
452
453 if (Icmpv6FilterWillBlock(type))
454 {
455 /* packet filtered */
456 return false;
457 }
458 }
459
460 // Should check via getsockopt ().
461 if (IsRecvPktInfo())
462 {
464 copy->RemovePacketTag(tag);
465 tag.SetAddress(hdr.GetDestination());
466 tag.SetHoplimit(hdr.GetHopLimit());
468 tag.SetRecvIf(device->GetIfIndex());
469 copy->AddPacketTag(tag);
470 }
471
472 // Check only version 6 options
473 if (IsIpv6RecvTclass())
474 {
475 SocketIpv6TclassTag ipTclassTag;
476 ipTclassTag.SetTclass(hdr.GetTrafficClass());
477 copy->AddPacketTag(ipTclassTag);
478 }
479
480 if (IsIpv6RecvHopLimit())
481 {
482 SocketIpv6HopLimitTag ipHopLimitTag;
483 ipHopLimitTag.SetHopLimit(hdr.GetHopLimit());
484 copy->AddPacketTag(ipHopLimitTag);
485 }
486
487 copy->AddHeader(hdr);
488 Data data;
489 data.packet = copy;
490 data.fromIp = hdr.GetSource();
491 data.fromProtocol = hdr.GetNextHeader();
492 m_data.push_back(data);
494 return true;
495 }
496 return false;
497}
498
499bool
501{
502 return allowBroadcast;
503}
504
505bool
507{
508 return true;
509}
510
511void
516
517void
522
523void
525{
526 m_icmpFilter.icmpv6Filt[type >> 5] |= (uint32_t(1) << (type & 31));
527}
528
529void
531{
532 m_icmpFilter.icmpv6Filt[(type) >> 5] &= ~(uint32_t(1) << (type & 31));
533}
534
535bool
537{
538 return ((m_icmpFilter.icmpv6Filt[type >> 5]) & (uint32_t(1) << (type & 31))) != 0;
539}
540
541bool
543{
544 return ((m_icmpFilter.icmpv6Filt[type >> 5]) & (uint32_t(1) << (type & 31))) == 0;
545}
546
547} /* namespace ns3 */
a polymophic address class
Definition address.h:90
ICMPv6 Echo message.
uint32_t GetSerializedSize() const override
Get the serialized size.
ICMPv6 header.
uint8_t GetType() const
Get the type field.
void CalculatePseudoHeaderChecksum(Ipv6Address src, Ipv6Address dst, uint16_t length, uint8_t protocol)
Calculate pseudo header checksum for IPv6.
static uint16_t GetStaticProtocolNumber()
Get ICMPv6 protocol number.
An Inet6 address class.
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
static bool IsMatchingType(const Address &addr)
If the address match.
Ipv6Address GetIpv6() const
Get the IPv6 address.
Describes an IPv6 address.
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
bool IsAny() const
If the IPv6 address is the "Any" address.
Packet header for IPv6.
Definition ipv6-header.h:24
void SetDestination(Ipv6Address dst)
Set the "Destination address" field.
uint8_t GetHopLimit() const
Get the "Hop limit" field (TTL).
uint8_t GetNextHeader() const
Get the next header.
Ipv6Address GetDestination() const
Get the "Destination address" field.
uint8_t GetTrafficClass() const
Get the "Traffic class" field.
Ipv6Address GetSource() const
Get the "Source address" field.
IPv6 layer implementation.
This class implements a tag that carries socket ancillary data to the socket interface.
void SetTrafficClass(uint8_t tclass)
Set the tag's Traffic Class.
void SetRecvIf(uint32_t ifindex)
Set the tag's receiving interface.
void SetHoplimit(uint8_t ttl)
Set the tag's Hop Limit.
void SetAddress(Ipv6Address addr)
Set the tag's address.
bool Icmpv6FilterWillBlock(uint8_t type)
Ask the filter about the status of one ICMPv6 type.
Socket::SocketErrno m_err
Last error number.
void Icmpv6FilterSetBlockAll()
Set the filter to block all the ICMPv6 types.
int Listen() override
Listen for incoming connections.
bool SetAllowBroadcast(bool allowBroadcast) override
Configure whether broadcast datagram transmissions are allowed.
int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress) override
Send data to a specified peer.
void SetNode(Ptr< Node > node)
Set the node associated with this socket.
uint32_t GetRxAvailable() const override
Return number of bytes which can be returned from one or multiple calls to Recv.
void Icmpv6FilterSetBlock(uint8_t type)
Set the filter to block one ICMPv6 type.
Ipv6Address m_src
Source address.
Icmpv6Filter m_icmpFilter
ICMPv6 filter.
int Bind6() override
Allocate a local IPv6 endpoint for this socket.
int Close() override
Close a socket.
int Send(Ptr< Packet > p, uint32_t flags) override
Send data (or dummy data) to the remote host.
int GetPeerName(Address &address) const override
Get the peer address of a connected socket.
bool GetAllowBroadcast() const override
Query whether broadcast datagram transmissions are allowed.
Ptr< Node > GetNode() const override
Return the node this socket is associated with.
Socket::SocketType GetSocketType() const override
Get socket type (NS3_SOCK_RAW)
static TypeId GetTypeId()
Get the type ID of this class.
bool m_shutdownRecv
Flag to shutdown receive capability.
Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress) override
Read a single packet from the socket and retrieve the sender address.
int Bind() override
Allocate a local IPv4 endpoint for this socket.
int GetSockName(Address &address) const override
Get socket address.
bool m_shutdownSend
Flag to shutdown send capability.
bool ForwardUp(Ptr< const Packet > p, Ipv6Header hdr, Ptr< NetDevice > device)
Forward up to receive method.
int Connect(const Address &address) override
Initiate a connection to a remote host.
bool Icmpv6FilterWillPass(uint8_t type)
Ask the filter about the status of one ICMPv6 type.
uint32_t GetTxAvailable() const override
Returns the number of bytes which can be sent in a single call to Send.
Socket::SocketErrno GetErrno() const override
Get last error number.
Ipv6Address m_dst
Destination address.
void DoDispose() override
Dispose object.
std::list< Data > m_data
Packet waiting to be processed.
void Icmpv6FilterSetPass(uint8_t type)
Set the filter to pass one ICMPv6 type.
void Ipv6JoinGroup(Ipv6Address address, Socket::Ipv6MulticastFilterMode filterMode, std::vector< Ipv6Address > sourceAddresses) override
Joins a IPv6 multicast group.
void Icmpv6FilterSetPassAll()
Clean the ICMPv6 filter structure.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
Smart pointer class similar to boost::intrusive_ptr.
A low-level Socket API based loosely on the BSD Socket API.
Definition socket.h:57
Ptr< NetDevice > GetBoundNetDevice()
Returns socket's bound NetDevice, if any.
Definition socket.cc:336
Ptr< Packet > Recv()
Read a single packet from the socket.
Definition socket.cc:163
virtual void Ipv6LeaveGroup()
Leaves IPv6 multicast group this socket is joined to.
Definition socket.cc:569
void NotifySend(uint32_t spaceAvailable)
Notify through the callback (if set) that some data have been sent.
Definition socket.cc:281
bool IsRecvPktInfo() const
Get status indicating whether enable/disable packet information to socket.
Definition socket.cc:350
Ipv6Address m_ipv6MulticastGroupAddress
IPv6 multicast group address.
Definition socket.h:1073
SocketType
Enumeration of the possible socket types.
Definition socket.h:96
@ NS3_SOCK_RAW
Definition socket.h:100
void NotifyDataRecv()
Notify through the callback (if set) that some data have been received.
Definition socket.cc:291
Ipv6MulticastFilterMode
Enumeration of the possible filter of a socket.
Definition socket.h:132
Ptr< NetDevice > m_boundnetdevice
the device this socket is bound to (might be null).
Definition socket.h:1070
bool IsIpv6RecvTclass() const
Ask if the socket is currently passing information about IPv6 Traffic Class up the stack.
Definition socket.cc:493
bool IsIpv6RecvHopLimit() const
Ask if the socket is currently passing information about IPv6 Hop Limit up the stack.
Definition socket.cc:543
virtual uint8_t GetIpv6HopLimit() const
Query the value of IP Hop Limit field of this socket.
Definition socket.cc:531
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition socket.h:73
@ ERROR_INVAL
Definition socket.h:82
@ ERROR_OPNOTSUPP
Definition socket.h:80
@ ERROR_NOTERROR
Definition socket.h:74
@ ERROR_NOTCONN
Definition socket.h:76
void NotifyDataSent(uint32_t size)
Notify through the callback (if set) that some data have been sent.
Definition socket.cc:271
void NotifyConnectionSucceeded()
Notify through the callback (if set) that the connection has been established.
Definition socket.cc:203
void DoDispose() override
Destructor implementation.
Definition socket.cc:301
uint8_t GetIpv6Tclass() const
Query the value of IPv6 Traffic Class field of this socket.
Definition socket.cc:481
bool IsManualIpv6HopLimit() const
Checks if the socket has a specific IPv6 Hop Limit set.
Definition socket.cc:369
bool IsManualIpv6Tclass() const
Checks if the socket has a specific IPv6 Tclass set.
Definition socket.cc:357
void NotifyConnectionFailed()
Notify through the callback (if set) that the connection has not been established due to an error.
Definition socket.cc:213
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer.
Definition socket.h:1161
void SetHopLimit(uint8_t hopLimit)
Set the tag's Hop Limit.
Definition socket.cc:657
indicates whether the socket has IPV6_TCLASS set.
Definition socket.h:1355
void SetTclass(uint8_t tclass)
Set the tag's Tclass.
Definition socket.cc:899
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#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:35
Definition first.py:1
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition uinteger.h:35
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.
uint8_t data[writeSize]
IPv6 raw data and additional information.
Struct to hold the ICMPv6 filter.
uint32_t icmpv6Filt[8]
ICMPv6 filter specification.
uint32_t pktSize
packet size used for the simulation (in bytes)