A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
udp-socket-impl.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8
9#include "udp-socket-impl.h"
10
11#include "ipv4-end-point.h"
12#include "ipv4-header.h"
14#include "ipv4-route.h"
16#include "ipv4.h"
17#include "ipv6-end-point.h"
18#include "ipv6-l3-protocol.h"
20#include "ipv6-route.h"
22#include "ipv6.h"
23#include "udp-l4-protocol.h"
24
25#include "ns3/inet-socket-address.h"
26#include "ns3/inet6-socket-address.h"
27#include "ns3/log.h"
28#include "ns3/node.h"
29#include "ns3/trace-source-accessor.h"
30
31#include <limits>
32
33namespace ns3
34{
35
36NS_LOG_COMPONENT_DEFINE("UdpSocketImpl");
37
38NS_OBJECT_ENSURE_REGISTERED(UdpSocketImpl);
39
40// The correct maximum UDP message size is 65507, as determined by the following formula:
41// 0xffff - (sizeof(IP Header) + sizeof(UDP Header)) = 65535-(20+8) = 65507
42// \todo MAX_IPV4_UDP_DATAGRAM_SIZE is correct only for IPv4
43static const uint32_t MAX_IPV4_UDP_DATAGRAM_SIZE = 65507; //!< Maximum UDP datagram size
44
45// Add attributes generic to all UdpSockets to base class UdpSocket
48{
49 static TypeId tid =
50 TypeId("ns3::UdpSocketImpl")
52 .SetGroupName("Internet")
53 .AddConstructor<UdpSocketImpl>()
54 .AddTraceSource("Drop",
55 "Drop UDP packet due to receive buffer overflow",
57 "ns3::Packet::TracedCallback")
58 .AddAttribute("IcmpCallback",
59 "Callback invoked whenever an icmp error is received on this socket.",
63 .AddAttribute("IcmpCallback6",
64 "Callback invoked whenever an icmpv6 error is received on this socket.",
68 return tid;
69}
70
72 : m_endPoint(nullptr),
73 m_endPoint6(nullptr),
74 m_node(nullptr),
75 m_udp(nullptr),
76 m_errno(ERROR_NOTERROR),
77 m_shutdownSend(false),
78 m_shutdownRecv(false),
79 m_connected(false),
80 m_rxAvailable(0)
81{
82 NS_LOG_FUNCTION(this);
83 m_allowBroadcast = false;
84}
85
87{
88 NS_LOG_FUNCTION(this);
89
90 /// \todo leave any multicast groups that have been joined
91 m_node = nullptr;
92 /**
93 * Note: actually this function is called AFTER
94 * UdpSocketImpl::Destroy or UdpSocketImpl::Destroy6
95 * so the code below is unnecessary in normal operations
96 */
97 if (m_endPoint != nullptr)
98 {
100 /**
101 * Note that this piece of code is a bit tricky:
102 * when DeAllocate is called, it will call into
103 * Ipv4EndPointDemux::Deallocate which triggers
104 * a delete of the associated endPoint which triggers
105 * in turn a call to the method UdpSocketImpl::Destroy below
106 * will will zero the m_endPoint field.
107 */
108 NS_ASSERT(m_endPoint != nullptr);
109 m_udp->DeAllocate(m_endPoint);
110 NS_ASSERT(m_endPoint == nullptr);
111 }
112 if (m_endPoint6 != nullptr)
113 {
115 /**
116 * Note that this piece of code is a bit tricky:
117 * when DeAllocate is called, it will call into
118 * Ipv4EndPointDemux::Deallocate which triggers
119 * a delete of the associated endPoint which triggers
120 * in turn a call to the method UdpSocketImpl::Destroy below
121 * will will zero the m_endPoint field.
122 */
123 NS_ASSERT(m_endPoint6 != nullptr);
124 m_udp->DeAllocate(m_endPoint6);
125 NS_ASSERT(m_endPoint6 == nullptr);
126 }
127 m_udp = nullptr;
128}
129
130void
132{
133 NS_LOG_FUNCTION(this << node);
134 m_node = node;
135}
136
137void
139{
140 NS_LOG_FUNCTION(this << udp);
141 m_udp = udp;
142}
143
146{
147 NS_LOG_FUNCTION(this);
148 return m_errno;
149}
150
153{
154 return NS3_SOCK_DGRAM;
155}
156
159{
160 NS_LOG_FUNCTION(this);
161 return m_node;
162}
163
164void
166{
167 NS_LOG_FUNCTION(this);
168 if (m_udp)
169 {
170 m_udp->RemoveSocket(this);
171 }
172 m_endPoint = nullptr;
173}
174
175void
177{
178 NS_LOG_FUNCTION(this);
179 if (m_udp)
180 {
181 m_udp->RemoveSocket(this);
182 }
183 m_endPoint6 = nullptr;
184}
185
186/* Deallocate the end point and cancel all the timers */
187void
189{
190 if (m_endPoint != nullptr)
191 {
192 m_udp->DeAllocate(m_endPoint);
193 m_endPoint = nullptr;
194 }
195 if (m_endPoint6 != nullptr)
196 {
197 m_udp->DeAllocate(m_endPoint6);
198 m_endPoint6 = nullptr;
199 }
200}
201
202int
204{
205 NS_LOG_FUNCTION(this);
206 bool done = false;
207 if (m_endPoint != nullptr)
208 {
215 done = true;
216 }
217 if (m_endPoint6 != nullptr)
218 {
225 done = true;
226 }
227 if (done)
228 {
229 m_shutdownRecv = false;
230 m_shutdownSend = false;
231 return 0;
232 }
233 return -1;
234}
235
236int
238{
239 NS_LOG_FUNCTION(this);
240 m_endPoint = m_udp->Allocate();
242 {
244 }
245 return FinishBind();
246}
247
248int
250{
251 NS_LOG_FUNCTION(this);
252 m_endPoint6 = m_udp->Allocate6();
254 {
256 }
257 return FinishBind();
258}
259
260int
262{
263 NS_LOG_FUNCTION(this << address);
264
266 {
267 NS_ASSERT_MSG(m_endPoint == nullptr, "Endpoint already allocated.");
268
270 Ipv4Address ipv4 = transport.GetIpv4();
271 uint16_t port = transport.GetPort();
272 if (ipv4 == Ipv4Address::GetAny() && port == 0)
273 {
274 m_endPoint = m_udp->Allocate();
275 }
276 else if (ipv4 == Ipv4Address::GetAny() && port != 0)
277 {
278 m_endPoint = m_udp->Allocate(GetBoundNetDevice(), port);
279 }
280 else if (ipv4 != Ipv4Address::GetAny() && port == 0)
281 {
282 m_endPoint = m_udp->Allocate(ipv4);
283 }
284 else if (ipv4 != Ipv4Address::GetAny() && port != 0)
285 {
286 m_endPoint = m_udp->Allocate(GetBoundNetDevice(), ipv4, port);
287 }
288 if (nullptr == m_endPoint)
289 {
291 return -1;
292 }
294 {
296 }
297 }
298 else if (Inet6SocketAddress::IsMatchingType(address))
299 {
300 NS_ASSERT_MSG(m_endPoint == nullptr, "Endpoint already allocated.");
301
303 Ipv6Address ipv6 = transport.GetIpv6();
304 uint16_t port = transport.GetPort();
305 if (ipv6 == Ipv6Address::GetAny() && port == 0)
306 {
307 m_endPoint6 = m_udp->Allocate6();
308 }
309 else if (ipv6 == Ipv6Address::GetAny() && port != 0)
310 {
311 m_endPoint6 = m_udp->Allocate6(GetBoundNetDevice(), port);
312 }
313 else if (ipv6 != Ipv6Address::GetAny() && port == 0)
314 {
315 m_endPoint6 = m_udp->Allocate6(ipv6);
316 }
317 else if (ipv6 != Ipv6Address::GetAny() && port != 0)
318 {
319 m_endPoint6 = m_udp->Allocate6(GetBoundNetDevice(), ipv6, port);
320 }
321 if (nullptr == m_endPoint6)
322 {
324 return -1;
325 }
327 {
329 }
330
331 if (ipv6.IsMulticast())
332 {
334 if (ipv6l3)
335 {
336 if (!m_boundnetdevice)
337 {
338 ipv6l3->AddMulticastAddress(ipv6);
339 }
340 else
341 {
342 uint32_t index = ipv6l3->GetInterfaceForDevice(m_boundnetdevice);
343 ipv6l3->AddMulticastAddress(m_endPoint6->GetLocalAddress(), index);
344 }
345 }
346 }
347 }
348 else
349 {
350 NS_LOG_ERROR("Not IsMatchingType");
352 return -1;
353 }
354
355 return FinishBind();
356}
357
358int
360{
361 NS_LOG_FUNCTION(this);
362 m_shutdownSend = true;
363 return 0;
364}
365
366int
368{
369 NS_LOG_FUNCTION(this);
370 m_shutdownRecv = true;
371 if (m_endPoint)
372 {
373 m_endPoint->SetRxEnabled(false);
374 }
375 if (m_endPoint6)
376 {
378 }
379 return 0;
380}
381
382int
384{
385 NS_LOG_FUNCTION(this);
387 {
389 return -1;
390 }
392 m_shutdownRecv = true;
393 m_shutdownSend = true;
395 return 0;
396}
397
398int
400{
401 NS_LOG_FUNCTION(this << address);
403 {
405 m_defaultAddress = Address(transport.GetIpv4());
406 m_defaultPort = transport.GetPort();
407 m_connected = true;
409 }
410 else if (Inet6SocketAddress::IsMatchingType(address))
411 {
413 m_defaultAddress = Address(transport.GetIpv6());
414 m_defaultPort = transport.GetPort();
415 m_connected = true;
417 }
418 else
419 {
421 return -1;
422 }
423
424 return 0;
425}
426
427int
429{
431 return -1;
432}
433
434int
436{
437 NS_LOG_FUNCTION(this << p << flags);
438
439 if (!m_connected)
440 {
442 return -1;
443 }
444
445 return DoSend(p);
446}
447
448int
450{
451 NS_LOG_FUNCTION(this << p);
453 {
454 if (Bind() == -1)
455 {
456 NS_ASSERT(m_endPoint == nullptr);
457 return -1;
458 }
459 NS_ASSERT(m_endPoint != nullptr);
460 }
462 {
463 if (Bind6() == -1)
464 {
465 NS_ASSERT(m_endPoint6 == nullptr);
466 return -1;
467 }
468 NS_ASSERT(m_endPoint6 != nullptr);
469 }
470 if (m_shutdownSend)
471 {
473 return -1;
474 }
475
477 {
479 }
481 {
483 }
484
486 return -1;
487}
488
489int
491{
492 NS_LOG_FUNCTION(this << p << dest << port << (uint16_t)tos);
494 {
495 NS_LOG_LOGIC("Bound interface number " << m_boundnetdevice->GetIfIndex());
496 }
497 if (m_endPoint == nullptr)
498 {
499 if (Bind() == -1)
500 {
501 NS_ASSERT(m_endPoint == nullptr);
502 return -1;
503 }
504 NS_ASSERT(m_endPoint != nullptr);
505 }
506 if (m_shutdownSend)
507 {
509 return -1;
510 }
511
512 if (p->GetSize() > GetTxAvailable())
513 {
515 return -1;
516 }
517
518 uint8_t priority = GetPriority();
519 if (tos)
520 {
521 SocketIpTosTag ipTosTag;
522 ipTosTag.SetTos(tos);
523 // This packet may already have a SocketIpTosTag (see BUG 2440)
524 p->ReplacePacketTag(ipTosTag);
525 priority = IpTos2Priority(tos);
526 }
527
528 if (priority)
529 {
530 SocketPriorityTag priorityTag;
531 priorityTag.SetPriority(priority);
532 p->ReplacePacketTag(priorityTag);
533 }
534
535 Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4>();
536
537 // Locally override the IP TTL for this socket
538 // We cannot directly modify the TTL at this stage, so we set a Packet tag
539 // The destination can be either multicast, unicast/anycast, or
540 // either all-hosts broadcast or limited (subnet-directed) broadcast.
541 // For the latter two broadcast types, the TTL will later be set to one
542 // irrespective of what is set in these socket options. So, this tagging
543 // may end up setting the TTL of a limited broadcast packet to be
544 // the same as a unicast, but it will be fixed further down the stack
545 if (m_ipMulticastTtl != 0 && dest.IsMulticast())
546 {
547 SocketIpTtlTag tag;
549 p->AddPacketTag(tag);
550 }
551 else if (IsManualIpTtl() && GetIpTtl() != 0 && !dest.IsMulticast() && !dest.IsBroadcast())
552 {
553 SocketIpTtlTag tag;
554 tag.SetTtl(GetIpTtl());
555 p->AddPacketTag(tag);
556 }
557 {
559 bool found = p->RemovePacketTag(tag);
560 if (!found)
561 {
562 if (m_mtuDiscover)
563 {
564 tag.Enable();
565 }
566 else
567 {
568 tag.Disable();
569 }
570 p->AddPacketTag(tag);
571 }
572 }
573
574 // Note that some systems will only send limited broadcast packets
575 // out of the "default" interface; here we send it out all interfaces
576 if (dest.IsBroadcast())
577 {
578 if (!m_allowBroadcast)
579 {
581 return -1;
582 }
583 NS_LOG_LOGIC("Limited broadcast start.");
584 for (uint32_t i = 0; i < ipv4->GetNInterfaces(); i++)
585 {
586 // Get the primary address
587 Ipv4InterfaceAddress iaddr = ipv4->GetAddress(i, 0);
588 Ipv4Address addri = iaddr.GetLocal();
589 if (addri == Ipv4Address("127.0.0.1"))
590 {
591 continue;
592 }
593 // Check if interface-bound socket
595 {
596 if (ipv4->GetNetDevice(i) != m_boundnetdevice)
597 {
598 continue;
599 }
600 }
601 NS_LOG_LOGIC("Sending one copy from " << addri << " to " << dest);
602 m_udp->Send(p->Copy(), addri, dest, m_endPoint->GetLocalPort(), port);
603 NotifyDataSent(p->GetSize());
605 }
606 NS_LOG_LOGIC("Limited broadcast end.");
607 return p->GetSize();
608 }
610 {
611 m_udp->Send(p->Copy(),
613 dest,
615 port,
616 nullptr);
617 NotifyDataSent(p->GetSize());
619 return p->GetSize();
620 }
621 else if (ipv4->GetRoutingProtocol())
622 {
623 Ipv4Header header;
624 header.SetDestination(dest);
626 Socket::SocketErrno errno_;
627 Ptr<Ipv4Route> route;
628 Ptr<NetDevice> oif = m_boundnetdevice; // specify non-zero if bound to a specific device
629 // TBD-- we could cache the route and just check its validity
630 route = ipv4->GetRoutingProtocol()->RouteOutput(p, header, oif, errno_);
631 if (route)
632 {
633 NS_LOG_LOGIC("Route exists");
634 if (!m_allowBroadcast)
635 {
636 // Here we try to route subnet-directed broadcasts
637 uint32_t outputIfIndex = ipv4->GetInterfaceForDevice(route->GetOutputDevice());
638 uint32_t ifNAddr = ipv4->GetNAddresses(outputIfIndex);
639 for (uint32_t addrI = 0; addrI < ifNAddr; ++addrI)
640 {
641 Ipv4InterfaceAddress ifAddr = ipv4->GetAddress(outputIfIndex, addrI);
642 if (dest == ifAddr.GetBroadcast())
643 {
645 return -1;
646 }
647 }
648 }
649
650 header.SetSource(route->GetSource());
651 m_udp->Send(p->Copy(),
652 header.GetSource(),
653 header.GetDestination(),
655 port,
656 route);
657 NotifyDataSent(p->GetSize());
658 return p->GetSize();
659 }
660 else
661 {
662 NS_LOG_LOGIC("No route to destination");
663 NS_LOG_ERROR(errno_);
664 m_errno = errno_;
665 return -1;
666 }
667 }
668 else
669 {
670 NS_LOG_ERROR("ERROR_NOROUTETOHOST");
672 return -1;
673 }
674
675 return 0;
676}
677
678int
680{
681 NS_LOG_FUNCTION(this << p << dest << port);
682
683 if (dest.IsIpv4MappedAddress())
684 {
685 return DoSendTo(p, dest.GetIpv4MappedAddress(), port, 0);
686 }
688 {
689 NS_LOG_LOGIC("Bound interface number " << m_boundnetdevice->GetIfIndex());
690 }
691 if (m_endPoint6 == nullptr)
692 {
693 if (Bind6() == -1)
694 {
695 NS_ASSERT(m_endPoint6 == nullptr);
696 return -1;
697 }
698 NS_ASSERT(m_endPoint6 != nullptr);
699 }
700 if (m_shutdownSend)
701 {
703 return -1;
704 }
705
706 if (p->GetSize() > GetTxAvailable())
707 {
709 return -1;
710 }
711
712 if (IsManualIpv6Tclass())
713 {
714 SocketIpv6TclassTag ipTclassTag;
715 ipTclassTag.SetTclass(GetIpv6Tclass());
716 p->AddPacketTag(ipTclassTag);
717 }
718
719 uint8_t priority = GetPriority();
720 if (priority)
721 {
722 SocketPriorityTag priorityTag;
723 priorityTag.SetPriority(priority);
724 p->ReplacePacketTag(priorityTag);
725 }
726
727 Ptr<Ipv6> ipv6 = m_node->GetObject<Ipv6>();
728
729 // Locally override the IP TTL for this socket
730 // We cannot directly modify the TTL at this stage, so we set a Packet tag
731 // The destination can be either multicast, unicast/anycast, or
732 // either all-hosts broadcast or limited (subnet-directed) broadcast.
733 // For the latter two broadcast types, the TTL will later be set to one
734 // irrespective of what is set in these socket options. So, this tagging
735 // may end up setting the TTL of a limited broadcast packet to be
736 // the same as a unicast, but it will be fixed further down the stack
737 if (m_ipMulticastTtl != 0 && dest.IsMulticast())
738 {
741 p->AddPacketTag(tag);
742 }
743 else if (IsManualIpv6HopLimit() && GetIpv6HopLimit() != 0 && !dest.IsMulticast())
744 {
747 p->AddPacketTag(tag);
748 }
749 // There is no analogous to an IPv4 broadcast address in IPv6.
750 // Instead, we use a set of link-local, site-local, and global
751 // multicast addresses. The Ipv6 routing layers should all
752 // provide an interface-specific route to these addresses such
753 // that we can treat these multicast addresses as "not broadcast"
754
756 {
757 m_udp->Send(p->Copy(),
759 dest,
761 port,
762 nullptr);
763 NotifyDataSent(p->GetSize());
765 return p->GetSize();
766 }
767 else if (ipv6->GetRoutingProtocol())
768 {
769 Ipv6Header header;
770 header.SetDestination(dest);
772 Socket::SocketErrno errno_;
773 Ptr<Ipv6Route> route;
774 Ptr<NetDevice> oif = m_boundnetdevice; // specify non-zero if bound to a specific device
775 // TBD-- we could cache the route and just check its validity
776 route = ipv6->GetRoutingProtocol()->RouteOutput(p, header, oif, errno_);
777 if (route)
778 {
779 NS_LOG_LOGIC("Route exists");
780 header.SetSource(route->GetSource());
781 m_udp->Send(p->Copy(),
782 header.GetSource(),
783 header.GetDestination(),
785 port,
786 route);
787 NotifyDataSent(p->GetSize());
788 return p->GetSize();
789 }
790 else
791 {
792 NS_LOG_LOGIC("No route to destination");
793 NS_LOG_ERROR(errno_);
794 m_errno = errno_;
795 return -1;
796 }
797 }
798 else
799 {
800 NS_LOG_ERROR("ERROR_NOROUTETOHOST");
802 return -1;
803 }
804
805 return 0;
806}
807
808// maximum message size for UDP broadcast is limited by MTU
809// size of underlying link; we are not checking that now.
810// \todo Check MTU size of underlying link
813{
814 NS_LOG_FUNCTION(this);
815 // No finite send buffer is modelled, but we must respect
816 // the maximum size of an IP datagram (65535 bytes - headers).
818}
819
820int
822{
823 NS_LOG_FUNCTION(this << p << flags << address);
825 {
827 Ipv4Address ipv4 = transport.GetIpv4();
828 uint16_t port = transport.GetPort();
829 return DoSendTo(p, ipv4, port, GetIpTos());
830 }
831 else if (Inet6SocketAddress::IsMatchingType(address))
832 {
834 Ipv6Address ipv6 = transport.GetIpv6();
835 uint16_t port = transport.GetPort();
836 return DoSendTo(p, ipv6, port);
837 }
838 return -1;
839}
840
843{
844 NS_LOG_FUNCTION(this);
845 // We separately maintain this state to avoid walking the queue
846 // every time this might be called
847 return m_rxAvailable;
848}
849
852{
853 NS_LOG_FUNCTION(this << maxSize << flags);
854
855 Address fromAddress;
856 Ptr<Packet> packet = RecvFrom(maxSize, flags, fromAddress);
857 return packet;
858}
859
862{
863 NS_LOG_FUNCTION(this << maxSize << flags);
864
865 if (m_deliveryQueue.empty())
866 {
868 return nullptr;
869 }
870 Ptr<Packet> p = m_deliveryQueue.front().first;
871 fromAddress = m_deliveryQueue.front().second;
872
873 if (p->GetSize() <= maxSize)
874 {
875 m_deliveryQueue.pop();
876 m_rxAvailable -= p->GetSize();
877 }
878 else
879 {
880 p = nullptr;
881 }
882 return p;
883}
884
885int
887{
888 NS_LOG_FUNCTION(this << address);
889 if (m_endPoint != nullptr)
890 {
892 }
893 else if (m_endPoint6 != nullptr)
894 {
896 }
897 else
898 { // It is possible to call this method on a socket without a name
899 // in which case, behavior is unspecified
900 // Should this return an InetSocketAddress or an Inet6SocketAddress?
902 }
903 return 0;
904}
905
906int
908{
909 NS_LOG_FUNCTION(this << address);
910
911 if (!m_connected)
912 {
914 return -1;
915 }
916
918 {
920 address = InetSocketAddress(addr, m_defaultPort);
921 }
923 {
925 address = Inet6SocketAddress(addr, m_defaultPort);
926 }
927 else
928 {
929 NS_ASSERT_MSG(false, "unexpected address type");
930 }
931
932 return 0;
933}
934
935int
937{
938 NS_LOG_FUNCTION(interface << groupAddress);
939 /*
940 1) sanity check interface
941 2) sanity check that it has not been called yet on this interface/group
942 3) determine address family of groupAddress
943 4) locally store a list of (interface, groupAddress)
944 5) call ipv4->MulticastJoinGroup () or Ipv6->MulticastJoinGroup ()
945 */
946 return 0;
947}
948
949int
951{
952 NS_LOG_FUNCTION(interface << groupAddress);
953 /*
954 1) sanity check interface
955 2) determine address family of groupAddress
956 3) delete from local list of (interface, groupAddress); raise a LOG_WARN
957 if not already present (but return 0)
958 5) call ipv4->MulticastLeaveGroup () or Ipv6->MulticastLeaveGroup ()
959 */
960 return 0;
961}
962
963void
965{
966 NS_LOG_FUNCTION(netdevice);
967
968 Ptr<NetDevice> oldBoundNetDevice = m_boundnetdevice;
969
970 Socket::BindToNetDevice(netdevice); // Includes sanity check
971 if (m_endPoint != nullptr)
972 {
973 m_endPoint->BindToNetDevice(netdevice);
974 }
975
976 if (m_endPoint6 != nullptr)
977 {
978 m_endPoint6->BindToNetDevice(netdevice);
979
980 // The following is to fix the multicast distribution inside the node
981 // and to upgrade it to the actual bound NetDevice.
983 {
985 if (ipv6l3)
986 {
987 // Cleanup old one
988 if (oldBoundNetDevice)
989 {
990 uint32_t index = ipv6l3->GetInterfaceForDevice(oldBoundNetDevice);
991 ipv6l3->RemoveMulticastAddress(m_endPoint6->GetLocalAddress(), index);
992 }
993 else
994 {
995 ipv6l3->RemoveMulticastAddress(m_endPoint6->GetLocalAddress());
996 }
997 // add new one
998 if (netdevice)
999 {
1000 uint32_t index = ipv6l3->GetInterfaceForDevice(netdevice);
1001 ipv6l3->AddMulticastAddress(m_endPoint6->GetLocalAddress(), index);
1002 }
1003 else
1004 {
1005 ipv6l3->AddMulticastAddress(m_endPoint6->GetLocalAddress());
1006 }
1007 }
1008 }
1009 }
1010}
1011
1012void
1014 Ipv4Header header,
1015 uint16_t port,
1016 Ptr<Ipv4Interface> incomingInterface)
1017{
1018 NS_LOG_FUNCTION(this << packet << header << port);
1019
1020 if (m_shutdownRecv)
1021 {
1022 return;
1023 }
1024
1025 // Should check via getsockopt ()..
1026 if (IsRecvPktInfo())
1027 {
1029 packet->RemovePacketTag(tag);
1030 tag.SetAddress(header.GetDestination());
1031 tag.SetTtl(header.GetTtl());
1032 tag.SetRecvIf(incomingInterface->GetDevice()->GetIfIndex());
1033 packet->AddPacketTag(tag);
1034 }
1035
1036 // Check only version 4 options
1037 if (IsIpRecvTos())
1038 {
1039 SocketIpTosTag ipTosTag;
1040 ipTosTag.SetTos(header.GetTos());
1041 packet->AddPacketTag(ipTosTag);
1042 }
1043
1044 if (IsIpRecvTtl())
1045 {
1046 SocketIpTtlTag ipTtlTag;
1047 ipTtlTag.SetTtl(header.GetTtl());
1048 packet->AddPacketTag(ipTtlTag);
1049 }
1050
1051 // in case the packet still has a priority tag attached, remove it
1052 SocketPriorityTag priorityTag;
1053 packet->RemovePacketTag(priorityTag);
1054
1055 if ((m_rxAvailable + packet->GetSize()) <= m_rcvBufSize)
1056 {
1057 Address address = InetSocketAddress(header.GetSource(), port);
1058 m_deliveryQueue.emplace(packet, address);
1059 m_rxAvailable += packet->GetSize();
1061 }
1062 else
1063 {
1064 // In general, this case should not occur unless the
1065 // receiving application reads data from this socket slowly
1066 // in comparison to the arrival rate
1067 //
1068 // drop and trace packet
1069 NS_LOG_WARN("No receive buffer space available. Drop.");
1070 m_dropTrace(packet);
1071 }
1072}
1073
1074void
1076 Ipv6Header header,
1077 uint16_t port,
1078 Ptr<Ipv6Interface> incomingInterface)
1079{
1080 NS_LOG_FUNCTION(this << packet << header.GetSource() << port);
1081
1082 if (m_shutdownRecv)
1083 {
1084 return;
1085 }
1086
1087 // Should check via getsockopt ().
1088 if (IsRecvPktInfo())
1089 {
1091 packet->RemovePacketTag(tag);
1092 tag.SetAddress(header.GetDestination());
1093 tag.SetHoplimit(header.GetHopLimit());
1094 tag.SetTrafficClass(header.GetTrafficClass());
1095 tag.SetRecvIf(incomingInterface->GetDevice()->GetIfIndex());
1096 packet->AddPacketTag(tag);
1097 }
1098
1099 // Check only version 6 options
1100 if (IsIpv6RecvTclass())
1101 {
1102 SocketIpv6TclassTag ipTclassTag;
1103 ipTclassTag.SetTclass(header.GetTrafficClass());
1104 packet->AddPacketTag(ipTclassTag);
1105 }
1106
1107 if (IsIpv6RecvHopLimit())
1108 {
1109 SocketIpv6HopLimitTag ipHopLimitTag;
1110 ipHopLimitTag.SetHopLimit(header.GetHopLimit());
1111 packet->AddPacketTag(ipHopLimitTag);
1112 }
1113
1114 // in case the packet still has a priority tag attached, remove it
1115 SocketPriorityTag priorityTag;
1116 packet->RemovePacketTag(priorityTag);
1117
1118 if ((m_rxAvailable + packet->GetSize()) <= m_rcvBufSize)
1119 {
1120 Address address = Inet6SocketAddress(header.GetSource(), port);
1121 m_deliveryQueue.emplace(packet, address);
1122 m_rxAvailable += packet->GetSize();
1124 }
1125 else
1126 {
1127 // In general, this case should not occur unless the
1128 // receiving application reads data from this socket slowly
1129 // in comparison to the arrival rate
1130 //
1131 // drop and trace packet
1132 NS_LOG_WARN("No receive buffer space available. Drop.");
1133 m_dropTrace(packet);
1134 }
1135}
1136
1137void
1139 uint8_t icmpTtl,
1140 uint8_t icmpType,
1141 uint8_t icmpCode,
1142 uint32_t icmpInfo)
1143{
1144 NS_LOG_FUNCTION(this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType
1145 << (uint32_t)icmpCode << icmpInfo);
1146 if (!m_icmpCallback.IsNull())
1147 {
1148 m_icmpCallback(icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
1149 }
1150}
1151
1152void
1154 uint8_t icmpTtl,
1155 uint8_t icmpType,
1156 uint8_t icmpCode,
1157 uint32_t icmpInfo)
1158{
1159 NS_LOG_FUNCTION(this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType
1160 << (uint32_t)icmpCode << icmpInfo);
1161 if (!m_icmpCallback6.IsNull())
1162 {
1163 m_icmpCallback6(icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
1164 }
1165}
1166
1167void
1172
1175{
1176 return m_rcvBufSize;
1177}
1178
1179void
1181{
1182 m_ipMulticastTtl = ipTtl;
1183}
1184
1185uint8_t
1190
1191void
1196
1197int32_t
1199{
1200 return m_ipMulticastIf;
1201}
1202
1203void
1205{
1206 m_ipMulticastLoop = loop;
1207}
1208
1209bool
1214
1215void
1217{
1218 m_mtuDiscover = discover;
1219}
1220
1221bool
1223{
1224 return m_mtuDiscover;
1225}
1226
1227bool
1229{
1230 m_allowBroadcast = allowBroadcast;
1231 return true;
1232}
1233
1234bool
1239
1240void
1243 std::vector<Ipv6Address> sourceAddresses)
1244{
1245 NS_LOG_FUNCTION(this << address << &filterMode << &sourceAddresses);
1246
1247 // We can join only one multicast group (or change its params)
1249 "Can join only one IPv6 multicast group.");
1250
1252
1254 if (ipv6l3)
1255 {
1256 if (filterMode == INCLUDE && sourceAddresses.empty())
1257 {
1258 // it is a leave
1259 if (m_boundnetdevice)
1260 {
1261 int32_t index = ipv6l3->GetInterfaceForDevice(m_boundnetdevice);
1262 NS_ASSERT_MSG(index >= 0, "Interface without a valid index");
1263 ipv6l3->RemoveMulticastAddress(address, index);
1264 }
1265 else
1266 {
1267 ipv6l3->RemoveMulticastAddress(address);
1268 }
1269 }
1270 else
1271 {
1272 // it is a join or a modification
1273 if (m_boundnetdevice)
1274 {
1275 int32_t index = ipv6l3->GetInterfaceForDevice(m_boundnetdevice);
1276 NS_ASSERT_MSG(index >= 0, "Interface without a valid index");
1277 ipv6l3->AddMulticastAddress(address, index);
1278 }
1279 else
1280 {
1281 ipv6l3->AddMulticastAddress(address);
1282 }
1283 }
1284 }
1285}
1286
1287} // namespace ns3
a polymophic address class
Definition address.h:90
AttributeValue implementation for Callback.
Definition callback.h:786
An Inet6 address class.
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
uint16_t GetPort() const
Get the port.
static bool IsMatchingType(const Address &addr)
If the address match.
Ipv6Address GetIpv6() const
Get the IPv6 address.
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.
bool IsMulticast() const
static Ipv4Address ConvertFrom(const Address &address)
static Ipv4Address GetZero()
static bool IsMatchingType(const Address &address)
bool IsBroadcast() const
static Ipv4Address GetAny()
void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
void SetDestroyCallback(Callback< void > callback)
Set the default destroy callback.
Ipv4Address GetLocalAddress() const
Get the local address.
uint16_t GetLocalPort() const
Get the local port.
void SetRxEnabled(bool enabled)
Enable or Disable the endpoint Rx capability.
void SetIcmpCallback(Callback< void, Ipv4Address, uint8_t, uint8_t, uint8_t, uint32_t > callback)
Set the ICMP callback.
void SetRxCallback(Callback< void, Ptr< Packet >, Ipv4Header, uint16_t, Ptr< Ipv4Interface > > callback)
Set the reception callback.
Packet header for IPv4.
Definition ipv4-header.h:23
void SetDestination(Ipv4Address destination)
Ipv4Address GetSource() const
uint8_t GetTos() const
Ipv4Address GetDestination() const
void SetProtocol(uint8_t num)
uint8_t GetTtl() const
void SetSource(Ipv4Address source)
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition ipv4.h:69
a class to store IPv4 address information on an interface
Ipv4Address GetLocal() const
Get the local address.
Ipv4Address GetBroadcast() const
Get the broadcast address.
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.
Describes an IPv6 address.
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
bool IsIpv4MappedAddress() const
If the address is an IPv4-mapped address.
bool IsAny() const
If the IPv6 address is the "Any" address.
static Ipv6Address ConvertFrom(const Address &address)
Convert the Address object into an Ipv6Address ones.
Ipv4Address GetIpv4MappedAddress() const
Return the Ipv4 address.
static bool IsMatchingType(const Address &address)
If the Address matches the type.
uint16_t GetLocalPort() const
Get the local port.
void SetIcmpCallback(Callback< void, Ipv6Address, uint8_t, uint8_t, uint8_t, uint32_t > callback)
Set the ICMP callback.
Ipv6Address GetLocalAddress() const
Get the local address.
void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
void SetRxEnabled(bool enabled)
Enable or Disable the endpoint Rx capability.
void SetRxCallback(Callback< void, Ptr< Packet >, Ipv6Header, uint16_t, Ptr< Ipv6Interface > > callback)
Set the reception callback.
void SetDestroyCallback(Callback< void > callback)
Set the default destroy callback.
Packet header for IPv6.
Definition ipv6-header.h:24
void SetDestination(Ipv6Address dst)
Set the "Destination address" field.
void SetSource(Ipv6Address src)
Set the "Source address" field.
uint8_t GetHopLimit() const
Get the "Hop limit" field (TTL).
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.
void SetNextHeader(uint8_t next)
Set the "Next header" field.
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition ipv6.h:71
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.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
Smart pointer class similar to boost::intrusive_ptr.
Ptr< NetDevice > GetBoundNetDevice()
Returns socket's bound NetDevice, if any.
Definition socket.cc:336
bool IsIpRecvTtl() const
Ask if the socket is currently passing information about IP_TTL up the stack.
Definition socket.cc:518
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
bool IsManualIpTtl() const
Checks if the socket has a specific IPv4 TTL set.
Definition socket.cc:363
void NotifySend(uint32_t spaceAvailable)
Notify through the callback (if set) that some data have been sent.
Definition socket.cc:281
virtual uint8_t GetIpTtl() const
Query the value of IP Time to Live field of this socket.
Definition socket.cc:506
bool IsRecvPktInfo() const
Get status indicating whether enable/disable packet information to socket.
Definition socket.cc:350
uint8_t GetIpTos() const
Query the value of IP Type of Service of this socket.
Definition socket.cc:439
Ipv6Address m_ipv6MulticastGroupAddress
IPv6 multicast group address.
Definition socket.h:1073
SocketType
Enumeration of the possible socket types.
Definition socket.h:96
@ NS3_SOCK_DGRAM
Definition socket.h:99
static uint8_t IpTos2Priority(uint8_t ipTos)
Return the priority corresponding to a given TOS value.
Definition socket.cc:388
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
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition socket.cc:316
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_NOROUTETOHOST
Definition socket.h:84
@ ERROR_SHUTDOWN
Definition socket.h:79
@ ERROR_INVAL
Definition socket.h:82
@ ERROR_ADDRINUSE
Definition socket.h:87
@ ERROR_AGAIN
Definition socket.h:78
@ ERROR_OPNOTSUPP
Definition socket.h:80
@ ERROR_AFNOSUPPORT
Definition socket.h:81
@ ERROR_BADF
Definition socket.h:83
@ ERROR_ADDRNOTAVAIL
Definition socket.h:86
@ ERROR_NOTCONN
Definition socket.h:76
@ ERROR_MSGSIZE
Definition socket.h:77
bool IsIpRecvTos() const
Ask if the socket is currently passing information about IP Type of Service up the stack.
Definition socket.cc:451
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
uint8_t GetPriority() const
Query the priority value of this socket.
Definition socket.cc:382
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
indicates whether the socket has IP_TOS set.
Definition socket.h:1260
void SetTos(uint8_t tos)
Set the tag's TOS.
Definition socket.cc:787
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer.
Definition socket.h:1113
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition socket.cc:593
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
indicates whether the socket has a priority set.
Definition socket.h:1307
void SetPriority(uint8_t priority)
Set the tag's priority.
Definition socket.cc:843
indicates whether packets should be sent out with the DF (Don't Fragment) flag set.
Definition socket.h:1209
void Enable()
Enables the DF (Don't Fragment) flag.
Definition socket.cc:716
void Disable()
Disables the DF (Don't Fragment) flag.
Definition socket.cc:723
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
static const uint8_t PROT_NUMBER
protocol number (0x11)
(abstract) base class of all UdpSockets
Definition udp-socket.h:37
A sockets interface to UDP.
void SetUdp(Ptr< UdpL4Protocol > udp)
Set the associated UDP L4 protocol.
uint32_t GetTxAvailable() const override
Returns the number of bytes which can be sent in a single call to Send.
void SetIpMulticastTtl(uint8_t ipTtl) override
Set the IP multicast TTL.
bool m_allowBroadcast
Allow send broadcast packets.
int MulticastJoinGroup(uint32_t interfaceIndex, const Address &groupAddress) override
Corresponds to socket option MCAST_JOIN_GROUP.
static TypeId GetTypeId()
Get the type ID.
bool GetIpMulticastLoop() const override
Get the IP multicast loop capability.
bool GetMtuDiscover() const override
Get the MTU discover capability.
int GetPeerName(Address &address) const override
Get the peer address of a connected socket.
void Destroy()
Kill this socket by zeroing its attributes (IPv4)
void ForwardUp6(Ptr< Packet > packet, Ipv6Header header, uint16_t port, Ptr< Ipv6Interface > incomingInterface)
Called by the L3 protocol when it received a packet to pass on to TCP.
int DoSendTo(Ptr< Packet > p, Ipv4Address daddr, uint16_t dport, uint8_t tos)
Send a packet to a specific destination and port (IPv4)
Callback< void, Ipv6Address, uint8_t, uint8_t, uint8_t, uint32_t > m_icmpCallback6
ICMPv6 callback.
void BindToNetDevice(Ptr< NetDevice > netdevice) override
Bind a socket to specific device.
int Close() override
Close a socket.
int FinishBind()
Finish the binding process.
bool m_connected
Connection established.
void ForwardIcmp(Ipv4Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo)
Called by the L3 protocol when it received an ICMP packet to pass on to TCP.
int Listen() override
Listen for incoming connections.
Callback< void, Ipv4Address, uint8_t, uint8_t, uint8_t, uint32_t > m_icmpCallback
ICMP callback.
SocketErrno m_errno
Socket error code.
uint8_t m_ipMulticastTtl
Multicast TTL.
int GetSockName(Address &address) const override
Get socket address.
Ipv4EndPoint * m_endPoint
the IPv4 endpoint
int32_t m_ipMulticastIf
Multicast Interface.
void SetIpMulticastIf(int32_t ipIf) override
Set the IP multicast interface.
void SetRcvBufSize(uint32_t size) override
Set the receiving buffer size.
uint8_t GetIpMulticastTtl() const override
Get the IP multicast TTL.
SocketType GetSocketType() const override
std::queue< std::pair< Ptr< Packet >, Address > > m_deliveryQueue
Queue for incoming packets.
uint32_t m_rxAvailable
Number of available bytes to be received.
Ptr< Node > GetNode() const override
Return the node this socket is associated with.
TracedCallback< Ptr< const Packet > > m_dropTrace
Trace for dropped packets.
void Ipv6JoinGroup(Ipv6Address address, Socket::Ipv6MulticastFilterMode filterMode, std::vector< Ipv6Address > sourceAddresses) override
Joins a IPv6 multicast group.
uint32_t m_rcvBufSize
Receive buffer size.
Address m_defaultAddress
Default address.
UdpSocketImpl()
Create an unbound udp socket.
int Bind6() override
Allocate a local IPv6 endpoint for this socket.
uint16_t m_defaultPort
Default port.
bool m_shutdownSend
Send no longer allowed.
int Send(Ptr< Packet > p, uint32_t flags) override
Send data (or dummy data) to the remote host.
bool m_ipMulticastLoop
Allow multicast loop.
int SendTo(Ptr< Packet > p, uint32_t flags, const Address &address) override
Send data to a specified peer.
int32_t GetIpMulticastIf() const override
Get the IP multicast interface.
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_mtuDiscover
Allow MTU discovery.
bool m_shutdownRecv
Receive no longer allowed.
void SetNode(Ptr< Node > node)
Set the associated node.
bool GetAllowBroadcast() const override
Query whether broadcast datagram transmissions are allowed.
void ForwardUp(Ptr< Packet > packet, Ipv4Header header, uint16_t port, Ptr< Ipv4Interface > incomingInterface)
Called by the L3 protocol when it received a packet to pass on to TCP.
int Connect(const Address &address) override
Initiate a connection to a remote host.
Ptr< UdpL4Protocol > m_udp
the associated UDP L4 protocol
void SetMtuDiscover(bool discover) override
Set the MTU discover capability.
Ipv6EndPoint * m_endPoint6
the IPv6 endpoint
int MulticastLeaveGroup(uint32_t interfaceIndex, const Address &groupAddress) override
Corresponds to socket option MCAST_LEAVE_GROUP.
void Destroy6()
Kill this socket by zeroing its attributes (IPv6)
void DeallocateEndPoint()
Deallocate m_endPoint and m_endPoint6.
int Bind() override
Allocate a local IPv4 endpoint for this socket.
int ShutdownSend() override
SocketErrno GetErrno() const override
Get last error number.
int DoSend(Ptr< Packet > p)
Send a packet.
uint32_t GetRxAvailable() const override
Return number of bytes which can be returned from one or multiple calls to Recv.
bool SetAllowBroadcast(bool allowBroadcast) override
Configure whether broadcast datagram transmissions are allowed.
void SetIpMulticastLoop(bool loop) override
Set the IP multicast loop capability.
Ptr< Node > m_node
the associated node
void ForwardIcmp6(Ipv6Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo)
Called by the L3 protocol when it received an ICMPv6 packet to pass on to TCP.
uint32_t GetRcvBufSize() const override
Get the receiving buffer size.
int ShutdownRecv() override
uint16_t port
Definition dsdv-manet.cc:33
#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
Ptr< const AttributeAccessor > MakeCallbackAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition callback.h:818
Ptr< const AttributeChecker > MakeCallbackChecker()
Definition callback.cc:77
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:243
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#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_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:250
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684
static const uint32_t MAX_IPV4_UDP_DATAGRAM_SIZE
Maximum UDP datagram size.