A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv6-l3-protocol.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007-2009 Strasbourg University
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
18 */
19
20#include "ipv6-l3-protocol.h"
21
22#include "icmpv6-l4-protocol.h"
25#include "ipv6-extension.h"
26#include "ipv6-interface.h"
27#include "ipv6-option-demux.h"
28#include "ipv6-option.h"
31#include "ipv6-route.h"
33#include "loopback-net-device.h"
34#include "ndisc-cache.h"
35
36#include "ns3/boolean.h"
37#include "ns3/callback.h"
38#include "ns3/log.h"
39#include "ns3/mac16-address.h"
40#include "ns3/mac64-address.h"
41#include "ns3/node.h"
42#include "ns3/object-vector.h"
43#include "ns3/trace-source-accessor.h"
44#include "ns3/traffic-control-layer.h"
45#include "ns3/uinteger.h"
46#include "ns3/vector.h"
47
48/// Minimum IPv6 MTU, as defined by \RFC{2460}
49#define IPV6_MIN_MTU 1280
50
51namespace ns3
52{
53
54NS_LOG_COMPONENT_DEFINE("Ipv6L3Protocol");
55
56NS_OBJECT_ENSURE_REGISTERED(Ipv6L3Protocol);
57
58const uint16_t Ipv6L3Protocol::PROT_NUMBER = 0x86DD;
59
60TypeId
62{
63 static TypeId tid =
64 TypeId("ns3::Ipv6L3Protocol")
65 .SetParent<Ipv6>()
66 .SetGroupName("Internet")
67 .AddConstructor<Ipv6L3Protocol>()
68 .AddAttribute("DefaultTtl",
69 "The TTL value set by default on all "
70 "outgoing packets generated on this node.",
71 UintegerValue(64),
73 MakeUintegerChecker<uint8_t>())
74 .AddAttribute("DefaultTclass",
75 "The TCLASS value set by default on all "
76 "outgoing packets generated on this node.",
79 MakeUintegerChecker<uint8_t>())
80 .AddAttribute("InterfaceList",
81 "The set of IPv6 interfaces associated to this IPv6 stack.",
84 MakeObjectVectorChecker<Ipv6Interface>())
85 .AddAttribute("SendIcmpv6Redirect",
86 "Send the ICMPv6 Redirect when appropriate.",
87 BooleanValue(true),
91 .AddTraceSource("Tx",
92 "Send IPv6 packet to outgoing interface.",
94 "ns3::Ipv6L3Protocol::TxRxTracedCallback")
95 .AddTraceSource("Rx",
96 "Receive IPv6 packet from incoming interface.",
98 "ns3::Ipv6L3Protocol::TxRxTracedCallback")
99 .AddTraceSource("Drop",
100 "Drop IPv6 packet",
102 "ns3::Ipv6L3Protocol::DropTracedCallback")
103
104 .AddTraceSource("SendOutgoing",
105 "A newly-generated packet by this node is "
106 "about to be queued for transmission",
108 "ns3::Ipv6L3Protocol::SentTracedCallback")
109 .AddTraceSource("UnicastForward",
110 "A unicast IPv6 packet was received by this node "
111 "and is being forwarded to another node",
113 "ns3::Ipv6L3Protocol::SentTracedCallback")
114 .AddTraceSource("LocalDeliver",
115 "An IPv6 packet was received by/for this node, "
116 "and it is being forward up the stack",
118 "ns3::Ipv6L3Protocol::SentTracedCallback");
119 return tid;
120}
121
123 : m_nInterfaces(0)
124{
125 NS_LOG_FUNCTION(this);
126 m_pmtuCache = CreateObject<Ipv6PmtuCache>();
127
128 Ptr<Ipv6RawSocketFactoryImpl> rawFactoryImpl = CreateObject<Ipv6RawSocketFactoryImpl>();
129 AggregateObject(rawFactoryImpl);
134}
135
137{
138 NS_LOG_FUNCTION(this);
139}
140
141void
143{
144 NS_LOG_FUNCTION(this);
145
146 /* clear protocol and interface list */
147 for (auto it = m_protocols.begin(); it != m_protocols.end(); ++it)
148 {
149 it->second = nullptr;
150 }
151 m_protocols.clear();
152
153 /* remove interfaces */
154 for (auto it = m_interfaces.begin(); it != m_interfaces.end(); ++it)
155 {
156 *it = nullptr;
157 }
158 m_interfaces.clear();
160
161 /* remove raw sockets */
162 for (auto it = m_sockets.begin(); it != m_sockets.end(); ++it)
163 {
164 *it = nullptr;
165 }
166 m_sockets.clear();
167
168 /* remove list of prefix */
169 for (auto it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
170 {
171 (*it)->StopValidTimer();
172 (*it)->StopPreferredTimer();
173 (*it) = nullptr;
174 }
175 m_prefixes.clear();
176
177 m_node = nullptr;
178 m_routingProtocol = nullptr;
179 m_pmtuCache = nullptr;
181}
182
183void
185{
186 NS_LOG_FUNCTION(this << routingProtocol);
187 m_routingProtocol = routingProtocol;
188 m_routingProtocol->SetIpv6(this);
189}
190
193{
194 return m_routingProtocol;
195}
196
199{
200 NS_LOG_FUNCTION(this << device);
202
204
205 NS_ASSERT(tc);
206
209 device);
210
211 tc->RegisterProtocolHandler(MakeCallback(&Ipv6L3Protocol::Receive, this),
213 device);
214
215 interface->SetNode(m_node);
216 interface->SetDevice(device);
217 interface->SetTrafficControl(tc);
218 interface->SetForwarding(m_ipForward);
219 return AddIpv6Interface(interface);
220}
221
224{
225 NS_LOG_FUNCTION(this << interface);
226 uint32_t index = m_nInterfaces;
227
228 m_interfaces.push_back(interface);
229 m_reverseInterfacesContainer[interface->GetDevice()] = index;
231 return index;
232}
233
236{
237 if (index < m_interfaces.size())
238 {
239 return m_interfaces[index];
240 }
241 return nullptr;
242}
243
246{
247 return m_nInterfaces;
248}
249
252{
253 int32_t index = 0;
254
255 for (auto it = m_interfaces.begin(); it != m_interfaces.end(); it++)
256 {
257 uint32_t j = 0;
258 uint32_t max = (*it)->GetNAddresses();
259
260 for (j = 0; j < max; j++)
261 {
262 if ((*it)->GetAddress(j).GetAddress() == address)
263 {
264 return index;
265 }
266 }
267 index++;
268 }
269 return -1;
270}
271
274{
275 int32_t index = 0;
276
277 for (auto it = m_interfaces.begin(); it != m_interfaces.end(); it++)
278 {
279 uint32_t j = 0;
280 for (j = 0; j < (*it)->GetNAddresses(); j++)
281 {
282 if ((*it)->GetAddress(j).GetAddress().CombinePrefix(mask) ==
283 address.CombinePrefix(mask))
284 {
285 return index;
286 }
287 }
288 index++;
289 }
290 return -1;
291}
292
295{
296 return GetInterface(i)->GetDevice();
297}
298
301{
302 auto iter = m_reverseInterfacesContainer.find(device);
303 if (iter != m_reverseInterfacesContainer.end())
304 {
305 return (*iter).second;
306 }
307
308 return -1;
309}
310
311void
313 Ipv6Address network,
314 Ipv6Prefix mask,
315 uint8_t flags,
316 uint32_t validTime,
317 uint32_t preferredTime,
318 Ipv6Address defaultRouter)
319{
320 NS_LOG_FUNCTION(this << interface << network << mask << (uint32_t)flags << validTime
321 << preferredTime);
322 Ipv6InterfaceAddress address;
323
324 Address addr = GetInterface(interface)->GetDevice()->GetAddress();
325
326 if (!defaultRouter.IsAny())
327 {
328 GetRoutingProtocol()->NotifyAddRoute(Ipv6Address::GetAny(),
329 Ipv6Prefix((uint8_t)0),
330 defaultRouter,
331 interface,
332 network);
333 }
334
335 bool onLink = false;
337 {
338 onLink = true;
339 }
340
341 if (flags & Icmpv6OptionPrefixInformation::AUTADDRCONF) /* auto flag */
342 {
343 address = Ipv6Address::MakeAutoconfiguredAddress(addr, network);
344 address.SetOnLink(onLink);
345
346 /* see if we have already the prefix */
347 for (auto it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
348 {
349 if ((*it)->GetInterface() == interface && (*it)->GetPrefix() == network &&
350 (*it)->GetMask() == mask)
351 {
352 (*it)->StopPreferredTimer();
353 (*it)->StopValidTimer();
354 (*it)->StartPreferredTimer();
355 return;
356 }
357 }
358
359 /* no prefix found, add autoconfigured address and the prefix */
360 NS_LOG_INFO("Autoconfigured address is :" << address.GetAddress());
361 AddAddress(interface, address, onLink);
362
364 CreateObject<Ipv6AutoconfiguredPrefix>(m_node,
365 interface,
366 network,
367 mask,
368 preferredTime,
369 validTime,
370 defaultRouter);
371 aPrefix->StartPreferredTimer();
372
373 m_prefixes.push_back(aPrefix);
374 }
375
376 if (onLink) /* on-link flag */
377 {
378 /* add default router
379 * if a previous default route exists, the new ones is simply added
380 */
381 m_routingProtocol->NotifyAddRoute(network, mask, Ipv6Address::GetAny(), interface);
382 }
383}
384
385void
387 Ipv6Address network,
388 Ipv6Prefix mask,
389 Ipv6Address defaultRouter)
390{
391 NS_LOG_FUNCTION(this << interface << network << mask);
392 Ptr<Ipv6Interface> iface = GetInterface(interface);
393 Address addr = iface->GetDevice()->GetAddress();
394
395 Ipv6Address addressToFind = Ipv6Address::MakeAutoconfiguredAddress(addr, network);
396
397 for (uint32_t i = 0; i < iface->GetNAddresses(); i++)
398 {
399 if (iface->GetAddress(i).GetAddress() == addressToFind)
400 {
401 RemoveAddress(interface, i);
402 break;
403 }
404 }
405
406 /* remove from list of autoconfigured address */
407 for (auto it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
408 {
409 if ((*it)->GetInterface() == interface && (*it)->GetPrefix() == network &&
410 (*it)->GetMask() == mask)
411 {
412 *it = nullptr;
413 m_prefixes.erase(it);
414 break;
415 }
416 }
417
418 GetRoutingProtocol()->NotifyRemoveRoute(Ipv6Address::GetAny(),
419 Ipv6Prefix((uint8_t)0),
420 defaultRouter,
421 interface,
422 network);
423}
424
425bool
427{
428 NS_LOG_FUNCTION(this << i << address);
429 Ptr<Ipv6Interface> interface = GetInterface(i);
430 address.SetOnLink(addOnLinkRoute);
431 bool ret = interface->AddAddress(address);
432
433 if (m_routingProtocol)
434 {
435 m_routingProtocol->NotifyAddAddress(i, address);
436 }
437
438 if (addOnLinkRoute)
439 {
440 Ipv6Address networkAddress = address.GetAddress().CombinePrefix(address.GetPrefix());
441 Ipv6Prefix networkMask = address.GetPrefix();
442 GetRoutingProtocol()->NotifyAddRoute(networkAddress,
443 networkMask,
444 Ipv6Address::GetZero(),
445 i);
446 }
447 return ret;
448}
449
452{
453 Ptr<Ipv6Interface> interface = GetInterface(i);
454 return interface->GetNAddresses();
455}
456
459{
460 Ptr<Ipv6Interface> interface = GetInterface(i);
461 return interface->GetAddress(addressIndex);
462}
463
464bool
466{
467 NS_LOG_FUNCTION(this << i << addressIndex);
468 Ptr<Ipv6Interface> interface = GetInterface(i);
469 Ipv6InterfaceAddress address = interface->RemoveAddress(addressIndex);
470
471 if (address != Ipv6InterfaceAddress())
472 {
473 if (m_routingProtocol)
474 {
475 m_routingProtocol->NotifyRemoveAddress(i, address);
476 }
477 return true;
478 }
479 return false;
480}
481
482bool
484{
485 NS_LOG_FUNCTION(this << i << address);
486
487 if (address == Ipv6Address::GetLoopback())
488 {
489 NS_LOG_WARN("Cannot remove loopback address.");
490 return false;
491 }
492 Ptr<Ipv6Interface> interface = GetInterface(i);
493 Ipv6InterfaceAddress ifAddr = interface->RemoveAddress(address);
494 if (ifAddr != Ipv6InterfaceAddress())
495 {
496 if (m_routingProtocol)
497 {
498 m_routingProtocol->NotifyRemoveAddress(i, ifAddr);
499 }
500 return true;
501 }
502 return false;
503}
504
505void
507{
508 NS_LOG_FUNCTION(this << i << metric);
509 Ptr<Ipv6Interface> interface = GetInterface(i);
510 interface->SetMetric(metric);
511}
512
513uint16_t
515{
516 Ptr<Ipv6Interface> interface = GetInterface(i);
517 return interface->GetMetric();
518}
519
520uint16_t
522{
523 // RFC 1981, if PMTU is disabled, return the minimum MTU
524 if (!m_mtuDiscover)
525 {
526 return IPV6_MIN_MTU;
527 }
528
529 Ptr<Ipv6Interface> interface = GetInterface(i);
530 return interface->GetDevice()->GetMtu();
531}
532
533void
535{
536 NS_LOG_FUNCTION(this << dst << int(pmtu));
537 m_pmtuCache->SetPmtu(dst, pmtu);
538}
539
540bool
542{
543 Ptr<Ipv6Interface> interface = GetInterface(i);
544 return interface->IsUp();
545}
546
547void
549{
550 NS_LOG_FUNCTION(this << i);
551 Ptr<Ipv6Interface> interface = GetInterface(i);
552
553 // RFC 2460, Section 5, pg. 24:
554 // IPv6 requires that every link in the internet have an MTU of 1280
555 // octets or greater. On any link that cannot convey a 1280-octet
556 // packet in one piece, link-specific fragmentation and reassembly must
557 // be provided at a layer below IPv6.
558 if (interface->GetDevice()->GetMtu() >= 1280)
559 {
560 interface->SetUp();
561
562 if (m_routingProtocol)
563 {
564 m_routingProtocol->NotifyInterfaceUp(i);
565 }
566 }
567 else
568 {
569 NS_LOG_LOGIC("Interface " << int(i)
570 << " is set to be down for IPv6. Reason: not respecting minimum "
571 "IPv6 MTU (1280 octets)");
572 }
573}
574
575void
577{
578 NS_LOG_FUNCTION(this << i);
579 Ptr<Ipv6Interface> interface = GetInterface(i);
580
581 interface->SetDown();
582
583 if (m_routingProtocol)
584 {
585 m_routingProtocol->NotifyInterfaceDown(i);
586 }
587}
588
589void
591{
592 NS_LOG_FUNCTION(this);
594 Ptr<LoopbackNetDevice> device = nullptr;
595 uint32_t i = 0;
596
597 /* see if we have already an loopback NetDevice */
598 for (i = 0; i < m_node->GetNDevices(); i++)
599 {
600 if ((device = DynamicCast<LoopbackNetDevice>(m_node->GetDevice(i))))
601 {
602 break;
603 }
604 }
605
606 if (!device)
607 {
608 device = CreateObject<LoopbackNetDevice>();
609 m_node->AddDevice(device);
610 }
611
612 interface->SetDevice(device);
613 interface->SetNode(m_node);
614 Ipv6InterfaceAddress ifaceAddr =
616 interface->AddAddress(ifaceAddr);
617 uint32_t index = AddIpv6Interface(interface);
618 Ptr<Node> node = GetObject<Node>();
619 node->RegisterProtocolHandler(MakeCallback(&Ipv6L3Protocol::Receive, this),
621 device);
622 interface->SetUp();
623
625 {
626 m_routingProtocol->NotifyInterfaceUp(index);
627 }
628}
629
630bool
632{
633 Ptr<Ipv6Interface> interface = GetInterface(i);
634
635 NS_LOG_LOGIC("Forwarding state: " << interface->IsForwarding());
636 return interface->IsForwarding();
637}
638
639void
641{
642 NS_LOG_FUNCTION(this << i << val);
643 Ptr<Ipv6Interface> interface = GetInterface(i);
644 interface->SetForwarding(val);
645}
646
649{
650 NS_LOG_FUNCTION(this << interface << dest);
651 Ipv6Address ret;
652
653 if (dest.IsLocalhost())
654 {
656 }
657
658 if (dest.IsLinkLocal() || dest.IsLinkLocalMulticast())
659 {
660 for (uint32_t i = 0; i < GetNAddresses(interface); i++)
661 {
662 Ipv6InterfaceAddress test = GetAddress(interface, i);
663 if (test.GetScope() == Ipv6InterfaceAddress::LINKLOCAL)
664 {
665 return test.GetAddress();
666 }
667 }
668 NS_ASSERT_MSG(false, "No link-local address found on interface " << interface);
669 }
670
671 for (uint32_t i = 0; i < GetNAddresses(interface); i++)
672 {
673 Ipv6InterfaceAddress test = GetAddress(interface, i);
674
675 if (test.GetScope() == Ipv6InterfaceAddress::GLOBAL)
676 {
677 if (test.IsInSameSubnet(dest))
678 {
679 return test.GetAddress();
680 }
681 else
682 {
683 ret = test.GetAddress();
684 }
685 }
686 }
687
688 // no specific match found. Use a global address (any useful is fine).
689 NS_ASSERT_MSG(!ret.IsAny(),
690 "Could not find any address for " << dest << " on interface " << interface);
691 return ret;
692}
693
694void
696{
697 NS_LOG_FUNCTION(this << forward);
698 m_ipForward = forward;
699
700 for (auto it = m_interfaces.begin(); it != m_interfaces.end(); it++)
701 {
702 (*it)->SetForwarding(forward);
703 }
704}
705
706bool
708{
709 return m_ipForward;
710}
711
712void
714{
715 NS_LOG_FUNCTION(this << int(mtuDiscover));
716 m_mtuDiscover = mtuDiscover;
717}
718
719bool
721{
722 return m_mtuDiscover;
723}
724
725void
727{
728 NS_LOG_FUNCTION(this << sendIcmpv6Redirect);
729 m_sendIcmpv6Redirect = sendIcmpv6Redirect;
730}
731
732bool
734{
736}
737
738void
740{
741 NS_LOG_FUNCTION(this);
742
743 if (!m_node)
744 {
745 Ptr<Node> node = this->GetObject<Node>();
746 // verify that it's a valid node and that
747 // the node has not been set before
748 if (node)
749 {
750 this->SetNode(node);
751 }
752 }
753
755}
756
757void
759{
760 NS_LOG_FUNCTION(this << node);
761 m_node = node;
762 /* add LoopbackNetDevice if needed, and an Ipv6Interface on top of it */
764}
765
766void
768{
769 NS_LOG_FUNCTION(this << protocol);
770 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), -1);
771 if (m_protocols.find(key) != m_protocols.end())
772 {
773 NS_LOG_WARN("Overwriting default protocol " << int(protocol->GetProtocolNumber()));
774 }
775 m_protocols[key] = protocol;
776}
777
778void
780{
781 NS_LOG_FUNCTION(this << protocol << interfaceIndex);
782
783 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), interfaceIndex);
784 if (m_protocols.find(key) != m_protocols.end())
785 {
786 NS_LOG_WARN("Overwriting protocol " << int(protocol->GetProtocolNumber())
787 << " on interface " << int(interfaceIndex));
788 }
789 m_protocols[key] = protocol;
790}
791
792void
794{
795 NS_LOG_FUNCTION(this << protocol);
796
797 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), -1);
798 auto iter = m_protocols.find(key);
799 if (iter == m_protocols.end())
800 {
801 NS_LOG_WARN("Trying to remove an non-existent default protocol "
802 << int(protocol->GetProtocolNumber()));
803 }
804 else
805 {
806 m_protocols.erase(key);
807 }
808}
809
810void
812{
813 NS_LOG_FUNCTION(this << protocol << interfaceIndex);
814
815 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), interfaceIndex);
816 auto iter = m_protocols.find(key);
817 if (iter == m_protocols.end())
818 {
819 NS_LOG_WARN("Trying to remove an non-existent protocol "
820 << int(protocol->GetProtocolNumber()) << " on interface "
821 << int(interfaceIndex));
822 }
823 else
824 {
825 m_protocols.erase(key);
826 }
827}
828
830Ipv6L3Protocol::GetProtocol(int protocolNumber) const
831{
832 return GetProtocol(protocolNumber, -1);
833}
834
836Ipv6L3Protocol::GetProtocol(int protocolNumber, int32_t interfaceIndex) const
837{
838 if (interfaceIndex >= 0)
839 {
840 // try the interface-specific protocol.
841 auto key = std::make_pair(protocolNumber, interfaceIndex);
842 auto i = m_protocols.find(key);
843 if (i != m_protocols.end())
844 {
845 return i->second;
846 }
847 }
848 // try the generic protocol.
849 auto key = std::make_pair(protocolNumber, -1);
850 auto i = m_protocols.find(key);
851 if (i != m_protocols.end())
852 {
853 return i->second;
854 }
855
856 return nullptr;
857}
858
861{
862 NS_LOG_FUNCTION(this);
863 Ptr<Ipv6RawSocketImpl> sock = CreateObject<Ipv6RawSocketImpl>();
864 sock->SetNode(m_node);
865 m_sockets.push_back(sock);
866 return sock;
867}
868
869void
871{
872 NS_LOG_FUNCTION(this << socket);
873
874 for (auto it = m_sockets.begin(); it != m_sockets.end(); ++it)
875 {
876 if ((*it) == socket)
877 {
878 m_sockets.erase(it);
879 return;
880 }
881 }
882}
883
886{
888
889 if (protocol)
890 {
891 return protocol->GetObject<Icmpv6L4Protocol>();
892 }
893 else
894 {
895 return nullptr;
896 }
897}
898
899void
901{
902 NS_LOG_FUNCTION(this << ttl);
903 m_defaultTtl = ttl;
904}
905
906void
908{
909 NS_LOG_FUNCTION(this << tclass);
910 m_defaultTclass = tclass;
911}
912
913void
915 Ipv6Address source,
916 Ipv6Address destination,
917 uint8_t protocol,
918 Ptr<Ipv6Route> route)
919{
920 NS_LOG_FUNCTION(this << packet << source << destination << (uint32_t)protocol << route);
921 Ipv6Header hdr;
922 uint8_t ttl = m_defaultTtl;
924 bool found = packet->RemovePacketTag(tag);
925
926 if (found)
927 {
928 ttl = tag.GetHopLimit();
929 }
930
931 SocketIpv6TclassTag tclassTag;
932 uint8_t tclass = m_defaultTclass;
933 found = packet->RemovePacketTag(tclassTag);
934
935 if (found)
936 {
937 tclass = tclassTag.GetTclass();
938 }
939
940 /* Handle 3 cases:
941 * 1) Packet is passed in with a route entry
942 * 2) Packet is passed in with a route entry but route->GetGateway is not set (e.g., same
943 * network) 3) route is NULL (e.g., a raw socket call or ICMPv6)
944 */
945
946 /* 1) */
947 if (route && route->GetGateway() != Ipv6Address::GetZero())
948 {
949 NS_LOG_LOGIC("Ipv6L3Protocol::Send case 1: passed in with a route");
950 hdr = BuildHeader(source, destination, protocol, packet->GetSize(), ttl, tclass);
951 int32_t interface = GetInterfaceForDevice(route->GetOutputDevice());
952 m_sendOutgoingTrace(hdr, packet, interface);
953 SendRealOut(route, packet, hdr);
954 return;
955 }
956
957 /* 2) */
958 if (route && route->GetGateway() == Ipv6Address::GetZero())
959 {
960 NS_LOG_LOGIC("Ipv6L3Protocol::Send case 2: probably sent to machine on same IPv6 network");
961 hdr = BuildHeader(source, destination, protocol, packet->GetSize(), ttl, tclass);
962 int32_t interface = GetInterfaceForDevice(route->GetOutputDevice());
963 m_sendOutgoingTrace(hdr, packet, interface);
964 SendRealOut(route, packet, hdr);
965 return;
966 }
967
968 /* 3) */
969 NS_LOG_LOGIC("Ipv6L3Protocol::Send case 3: passed in with no route " << destination);
971 Ptr<NetDevice> oif(nullptr);
972 Ptr<Ipv6Route> newRoute = nullptr;
973
974 hdr = BuildHeader(source, destination, protocol, packet->GetSize(), ttl, tclass);
975
976 // for link-local traffic, we need to determine the interface
977 if (source.IsLinkLocal() || destination.IsLinkLocal() || destination.IsLinkLocalMulticast())
978 {
979 int32_t index = GetInterfaceForAddress(source);
980 NS_ASSERT_MSG(index >= 0,
981 "Can not find an outgoing interface for a packet with src "
982 << source << " and dst " << destination);
983 oif = GetNetDevice(index);
984 }
985
986 newRoute = m_routingProtocol->RouteOutput(packet, hdr, oif, err);
987
988 if (newRoute)
989 {
990 int32_t interface = GetInterfaceForDevice(newRoute->GetOutputDevice());
991 m_sendOutgoingTrace(hdr, packet, interface);
992 SendRealOut(newRoute, packet, hdr);
993 }
994 else
995 {
996 NS_LOG_WARN("No route to host, drop!");
997 m_dropTrace(hdr, packet, DROP_NO_ROUTE, this, GetInterfaceForDevice(oif));
998 }
999}
1000
1001void
1004 uint16_t protocol,
1005 const Address& from,
1006 const Address& to,
1007 NetDevice::PacketType packetType)
1008{
1009 NS_LOG_FUNCTION(this << device << p << protocol << from << to << packetType);
1010 NS_LOG_LOGIC("Packet from " << from << " received on node " << m_node->GetId());
1011
1013 "Received a packet from an interface that is not known to IPv6");
1014 uint32_t interface = GetInterfaceForDevice(device);
1015
1016 Ptr<Ipv6Interface> ipv6Interface = m_interfaces[interface];
1017 Ptr<Packet> packet = p->Copy();
1018
1019 if (ipv6Interface->IsUp())
1020 {
1021 m_rxTrace(packet, this, interface);
1022 }
1023 else
1024 {
1025 NS_LOG_LOGIC("Dropping received packet-- interface is down");
1026 Ipv6Header hdr;
1027 packet->RemoveHeader(hdr);
1028 m_dropTrace(hdr, packet, DROP_INTERFACE_DOWN, this, interface);
1029 return;
1030 }
1031
1032 Ipv6Header hdr;
1033 packet->RemoveHeader(hdr);
1034
1035 // Trim any residual frame padding from underlying devices
1036 if (hdr.GetPayloadLength() < packet->GetSize())
1037 {
1038 packet->RemoveAtEnd(packet->GetSize() - hdr.GetPayloadLength());
1039 }
1040
1041 // the packet is valid, we update the NDISC cache entry (if present)
1042 Ptr<NdiscCache> ndiscCache = ipv6Interface->GetNdiscCache();
1043 if (ndiscCache)
1044 {
1045 // case one, it's a a direct routing.
1046 NdiscCache::Entry* entry = ndiscCache->Lookup(hdr.GetSource());
1047 if (entry)
1048 {
1049 entry->UpdateReachableTimer();
1050 }
1051 else
1052 {
1053 // It's not in the direct routing, so it's the router, and it could have multiple IP
1054 // addresses. In doubt, update all of them. Note: it's a confirmed behavior for Linux
1055 // routers.
1056 std::list<NdiscCache::Entry*> entryList = ndiscCache->LookupInverse(from);
1057 for (auto iter = entryList.begin(); iter != entryList.end(); iter++)
1058 {
1059 (*iter)->UpdateReachableTimer();
1060 }
1061 }
1062 }
1063
1064 /* forward up to IPv6 raw sockets */
1065 for (auto it = m_sockets.begin(); it != m_sockets.end(); ++it)
1066 {
1067 Ptr<Ipv6RawSocketImpl> socket = *it;
1068 socket->ForwardUp(packet, hdr, device);
1069 }
1070
1071 Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux>();
1072 Ptr<Ipv6Extension> ipv6Extension = nullptr;
1073 uint8_t nextHeader = hdr.GetNextHeader();
1074 bool stopProcessing = false;
1075 bool isDropped = false;
1076 DropReason dropReason;
1077
1078 if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1079 {
1080 ipv6Extension = ipv6ExtensionDemux->GetExtension(nextHeader);
1081
1082 if (ipv6Extension)
1083 {
1084 ipv6Extension->Process(packet,
1085 0,
1086 hdr,
1087 hdr.GetDestination(),
1088 (uint8_t*)nullptr,
1089 stopProcessing,
1090 isDropped,
1091 dropReason);
1092 }
1093
1094 if (isDropped)
1095 {
1096 m_dropTrace(hdr, packet, dropReason, this, interface);
1097 }
1098
1099 if (stopProcessing)
1100 {
1101 return;
1102 }
1103 }
1104
1106 {
1107 LocalDeliver(packet, hdr, interface);
1108 return;
1109 }
1110 else if (hdr.GetDestination().IsAllRoutersMulticast() && ipv6Interface->IsForwarding())
1111 {
1112 LocalDeliver(packet, hdr, interface);
1113 return;
1114 }
1115 else if (hdr.GetDestination().IsMulticast())
1116 {
1117 bool isSolicited = ipv6Interface->IsSolicitedMulticastAddress(hdr.GetDestination());
1118 bool isRegisteredOnInterface =
1119 IsRegisteredMulticastAddress(hdr.GetDestination(), interface);
1120 bool isRegisteredGlobally = IsRegisteredMulticastAddress(hdr.GetDestination());
1121 if (isSolicited || isRegisteredGlobally || isRegisteredOnInterface)
1122 {
1123 LocalDeliver(packet, hdr, interface);
1124 // do not return, the packet could be handled by a routing protocol
1125 }
1126 }
1127
1128 for (uint32_t j = 0; j < GetNInterfaces(); j++)
1129 {
1130 for (uint32_t i = 0; i < GetNAddresses(j); i++)
1131 {
1132 Ipv6InterfaceAddress iaddr = GetAddress(j, i);
1133 Ipv6Address addr = iaddr.GetAddress();
1134 if (addr == hdr.GetDestination())
1135 {
1136 if (j == interface)
1137 {
1138 NS_LOG_LOGIC("For me (destination " << addr << " match)");
1139 LocalDeliver(packet, hdr, interface);
1140 return;
1141 }
1142 else if (!GetStrongEndSystemModel())
1143 {
1144 NS_LOG_LOGIC("For me (destination "
1145 << addr
1146 << " match) on another interface with Weak End System Model"
1147 << hdr.GetDestination());
1148 LocalDeliver(packet, hdr, interface);
1149 return;
1150 }
1151 else
1152 {
1154 "For me (destination "
1155 << addr
1156 << " match) on another interface with Strong End System Model - discarding"
1157 << hdr.GetDestination());
1158 m_dropTrace(hdr, packet, DROP_NO_ROUTE, this, interface);
1159 return;
1160 }
1161 }
1162 NS_LOG_LOGIC("Address " << addr << " not a match");
1163 }
1164 }
1165
1166 if (!m_routingProtocol->RouteInput(packet, hdr, device, m_ucb, m_mcb, m_lcb, m_ecb))
1167 {
1168 NS_LOG_WARN("No route found for forwarding packet. Drop.");
1169 // Drop trace and ICMPs are courtesy of RouteInputError
1170 }
1171}
1172
1173void
1175 Ptr<Packet> packet,
1176 Ptr<Ipv6> ipv6,
1177 uint32_t interface)
1178{
1179 if (!m_txTrace.IsEmpty())
1180 {
1181 Ptr<Packet> packetCopy = packet->Copy();
1182 packetCopy->AddHeader(ipHeader);
1183 m_txTrace(packetCopy, ipv6, interface);
1184 }
1185}
1186
1187void
1189{
1190 NS_LOG_FUNCTION(this << route << packet << ipHeader);
1191
1192 if (!route)
1193 {
1194 NS_LOG_LOGIC("No route to host, drop!.");
1195 return;
1196 }
1197
1198 Ptr<NetDevice> dev = route->GetOutputDevice();
1199 int32_t interface = GetInterfaceForDevice(dev);
1200 NS_ASSERT(interface >= 0);
1201
1202 Ptr<Ipv6Interface> outInterface = GetInterface(interface);
1203 NS_LOG_LOGIC("Send via NetDevice ifIndex " << dev->GetIfIndex() << " Ipv6InterfaceIndex "
1204 << interface);
1205
1206 // Check packet size
1207 std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair> fragments;
1208
1209 // Check if this is the source of the packet
1210 bool fromMe = false;
1211 for (uint32_t i = 0; i < GetNInterfaces(); i++)
1212 {
1213 for (uint32_t j = 0; j < GetNAddresses(i); j++)
1214 {
1215 if (GetAddress(i, j).GetAddress() == ipHeader.GetSource())
1216 {
1217 fromMe = true;
1218 break;
1219 }
1220 }
1221 }
1222
1223 size_t targetMtu = 0;
1224
1225 // Check if we have a Path MTU stored. If so, use it. Else, use the link MTU.
1226 // Note: PMTU must not be cached in intermediate nodes, and must be checked only by the source
1227 // node
1228 if (fromMe)
1229 {
1230 targetMtu = (size_t)(m_pmtuCache->GetPmtu(ipHeader.GetDestination()));
1231 }
1232 if (targetMtu == 0)
1233 {
1234 targetMtu = dev->GetMtu();
1235 }
1236
1237 if (packet->GetSize() + ipHeader.GetSerializedSize() > targetMtu)
1238 {
1239 // Router => drop
1240 if (!fromMe)
1241 {
1242 Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6();
1243 if (icmpv6)
1244 {
1245 packet->AddHeader(ipHeader);
1246 icmpv6->SendErrorTooBig(packet, ipHeader.GetSource(), dev->GetMtu());
1247 }
1248 return;
1249 }
1250
1251 Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux>();
1252
1253 // To get specific method GetFragments from Ipv6ExtensionFragmentation
1254 Ipv6ExtensionFragment* ipv6Fragment = dynamic_cast<Ipv6ExtensionFragment*>(
1255 PeekPointer(ipv6ExtensionDemux->GetExtension(Ipv6Header::IPV6_EXT_FRAGMENTATION)));
1256 NS_ASSERT(ipv6Fragment != nullptr);
1257 ipv6Fragment->GetFragments(packet, ipHeader, targetMtu, fragments);
1258 }
1259
1260 if (route->GetGateway() != Ipv6Address::GetAny())
1261 {
1262 if (outInterface->IsUp())
1263 {
1264 NS_LOG_LOGIC("Send to gateway " << route->GetGateway());
1265
1266 if (!fragments.empty())
1267 {
1268 std::ostringstream oss;
1269
1270 for (auto it = fragments.begin(); it != fragments.end(); it++)
1271 {
1272 CallTxTrace(it->second, it->first, this, interface);
1273 outInterface->Send(it->first, it->second, route->GetGateway());
1274 }
1275 }
1276 else
1277 {
1278 CallTxTrace(ipHeader, packet, this, interface);
1279 outInterface->Send(packet, ipHeader, route->GetGateway());
1280 }
1281 }
1282 else
1283 {
1284 NS_LOG_LOGIC("Dropping-- outgoing interface is down: " << route->GetGateway());
1285 m_dropTrace(ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
1286 }
1287 }
1288 else
1289 {
1290 if (outInterface->IsUp())
1291 {
1292 NS_LOG_LOGIC("Send to destination " << ipHeader.GetDestination());
1293
1294 if (!fragments.empty())
1295 {
1296 std::ostringstream oss;
1297
1298 for (auto it = fragments.begin(); it != fragments.end(); it++)
1299 {
1300 CallTxTrace(it->second, it->first, this, interface);
1301 outInterface->Send(it->first, it->second, ipHeader.GetDestination());
1302 }
1303 }
1304 else
1305 {
1306 CallTxTrace(ipHeader, packet, this, interface);
1307 outInterface->Send(packet, ipHeader, ipHeader.GetDestination());
1308 }
1309 }
1310 else
1311 {
1312 NS_LOG_LOGIC("Dropping-- outgoing interface is down: " << ipHeader.GetDestination());
1313 m_dropTrace(ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
1314 }
1315 }
1316}
1317
1318void
1320 Ptr<Ipv6Route> rtentry,
1322 const Ipv6Header& header)
1323{
1324 NS_LOG_FUNCTION(this << rtentry << p << header);
1325 NS_LOG_LOGIC("Forwarding logic for node: " << m_node->GetId());
1326
1327 // Drop RFC 3849 packets: 2001:db8::/32
1328 if (header.GetDestination().IsDocumentation())
1329 {
1330 NS_LOG_WARN("Received a packet for 2001:db8::/32 (documentation class). Drop.");
1331 m_dropTrace(header, p, DROP_ROUTE_ERROR, this, 0);
1332 return;
1333 }
1334
1335 // Forwarding
1336 Ipv6Header ipHeader = header;
1337 Ptr<Packet> packet = p->Copy();
1338 ipHeader.SetHopLimit(ipHeader.GetHopLimit() - 1);
1339
1340 if (ipHeader.GetSource().IsLinkLocal())
1341 {
1342 /* no forward for link-local address */
1343 return;
1344 }
1345
1346 if (ipHeader.GetHopLimit() == 0)
1347 {
1348 NS_LOG_WARN("TTL exceeded. Drop.");
1349 m_dropTrace(ipHeader, packet, DROP_TTL_EXPIRED, this, 0);
1350 // Do not reply to multicast IPv6 address
1351 if (!ipHeader.GetDestination().IsMulticast())
1352 {
1353 packet->AddHeader(ipHeader);
1354 GetIcmpv6()->SendErrorTimeExceeded(packet,
1355 ipHeader.GetSource(),
1357 }
1358 return;
1359 }
1360
1361 /* ICMPv6 Redirect */
1362
1363 /* if we forward to a machine on the same network as the source,
1364 * we send him an ICMPv6 redirect message to notify him that a short route
1365 * exists.
1366 */
1367
1368 /* Theoretically we should also check if the redirect target is on the same network
1369 * as the source node. On the other hand, we are sure that the router we're redirecting to
1370 * used a link-local address. As a consequence, they MUST be on the same network, the link-local
1371 * net.
1372 */
1373
1374 if (m_sendIcmpv6Redirect && (rtentry->GetOutputDevice() == idev))
1375 {
1376 NS_LOG_LOGIC("ICMPv6 redirect!");
1378 Address hardwareTarget;
1379 Ipv6Address dst = header.GetDestination();
1380 Ipv6Address src = header.GetSource();
1381 Ipv6Address target = rtentry->GetGateway();
1382 Ptr<Packet> copy = p->Copy();
1383
1384 if (target.IsAny())
1385 {
1386 target = dst;
1387 }
1388
1389 copy->AddHeader(header);
1390 Ipv6Address linkLocal = GetInterface(GetInterfaceForDevice(rtentry->GetOutputDevice()))
1392 .GetAddress();
1393
1394 if (icmpv6->Lookup(target, rtentry->GetOutputDevice(), nullptr, &hardwareTarget))
1395 {
1396 icmpv6->SendRedirection(copy, linkLocal, src, target, dst, hardwareTarget);
1397 }
1398 else
1399 {
1400 icmpv6->SendRedirection(copy, linkLocal, src, target, dst, Address());
1401 }
1402 }
1403 // in case the packet still has a priority tag attached, remove it
1404 SocketPriorityTag priorityTag;
1405 packet->RemovePacketTag(priorityTag);
1406 int32_t interface = GetInterfaceForDevice(rtentry->GetOutputDevice());
1407 m_unicastForwardTrace(ipHeader, packet, interface);
1408 SendRealOut(rtentry, packet, ipHeader);
1409}
1410
1411void
1413 Ptr<Ipv6MulticastRoute> mrtentry,
1415 const Ipv6Header& header)
1416{
1417 NS_LOG_FUNCTION(this << mrtentry << p << header);
1418 NS_LOG_LOGIC("Multicast forwarding logic for node: " << m_node->GetId());
1419
1420 std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap();
1421
1422 for (auto mapIter = ttlMap.begin(); mapIter != ttlMap.end(); mapIter++)
1423 {
1424 uint32_t interfaceId = mapIter->first;
1425 // uint32_t outputTtl = mapIter->second; // Unused for now
1426 Ptr<Packet> packet = p->Copy();
1427 Ipv6Header h = header;
1428 h.SetHopLimit(header.GetHopLimit() - 1);
1429 if (h.GetHopLimit() == 0)
1430 {
1431 NS_LOG_WARN("TTL exceeded. Drop.");
1432 m_dropTrace(header, packet, DROP_TTL_EXPIRED, this, interfaceId);
1433 return;
1434 }
1435 NS_LOG_LOGIC("Forward multicast via interface " << interfaceId);
1436 Ptr<Ipv6Route> rtentry = Create<Ipv6Route>();
1437 rtentry->SetSource(h.GetSource());
1438 rtentry->SetDestination(h.GetDestination());
1439 rtentry->SetGateway(Ipv6Address::GetAny());
1440 rtentry->SetOutputDevice(GetNetDevice(interfaceId));
1441 SendRealOut(rtentry, packet, h);
1442 }
1443}
1444
1445void
1447{
1448 NS_LOG_FUNCTION(this << packet << ip << iif);
1449 Ptr<Packet> p = packet->Copy();
1450 Ptr<IpL4Protocol> protocol = nullptr;
1452 Ptr<Ipv6Extension> ipv6Extension = nullptr;
1453 Ipv6Address src = ip.GetSource();
1454 Ipv6Address dst = ip.GetDestination();
1455 uint8_t nextHeader = ip.GetNextHeader();
1456 uint8_t nextHeaderPosition = 0;
1457 bool isDropped = false;
1458 bool stopProcessing = false;
1459 DropReason dropReason;
1460
1461 // check for a malformed hop-by-hop extension
1462 // this is a common case when forging IPv6 raw packets
1463 if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1464 {
1465 uint8_t buf;
1466 p->CopyData(&buf, 1);
1468 {
1469 NS_LOG_WARN("Double Ipv6Header::IPV6_EXT_HOP_BY_HOP in packet, dropping packet");
1470 return;
1471 }
1472 }
1473
1474 /* process all the extensions found and the layer 4 protocol */
1475 do
1476 {
1477 /* it return 0 for non-extension (i.e. layer 4 protocol) */
1478 ipv6Extension = ipv6ExtensionDemux->GetExtension(nextHeader);
1479
1480 if (ipv6Extension)
1481 {
1482 uint8_t nextHeaderStep = 0;
1483 uint8_t curHeader = nextHeader;
1484 nextHeaderStep = ipv6Extension->Process(p,
1485 nextHeaderPosition,
1486 ip,
1487 dst,
1488 &nextHeader,
1489 stopProcessing,
1490 isDropped,
1491 dropReason);
1492 nextHeaderPosition += nextHeaderStep;
1493
1494 if (isDropped)
1495 {
1496 m_dropTrace(ip, packet, dropReason, this, iif);
1497 }
1498
1499 if (stopProcessing)
1500 {
1501 return;
1502 }
1503 NS_ASSERT_MSG(nextHeaderStep != 0 || curHeader == Ipv6Header::IPV6_EXT_FRAGMENTATION,
1504 "Zero-size IPv6 Option Header, aborting" << *packet);
1505 }
1506 else
1507 {
1508 protocol = GetProtocol(nextHeader, iif);
1509
1510 if (!protocol)
1511 {
1512 NS_LOG_LOGIC("Unknown Next Header. Drop!");
1513
1514 // For ICMPv6 Error packets
1515 Ptr<Packet> malformedPacket = packet->Copy();
1516 malformedPacket->AddHeader(ip);
1517
1518 if (nextHeaderPosition == 0)
1519 {
1520 GetIcmpv6()->SendErrorParameterError(malformedPacket,
1521 dst,
1523 40);
1524 }
1525 else
1526 {
1527 GetIcmpv6()->SendErrorParameterError(malformedPacket,
1528 dst,
1530 ip.GetSerializedSize() +
1531 nextHeaderPosition);
1532 }
1533 m_dropTrace(ip, p, DROP_UNKNOWN_PROTOCOL, this, iif);
1534 break;
1535 }
1536 else
1537 {
1538 p->RemoveAtStart(nextHeaderPosition);
1539 /* protocol->Receive (p, src, dst, incomingInterface); */
1540
1541 // Options have been processed, and the packet is good.
1542 // We need to adjust the IP header fields
1543 Ipv6Header newIpHeader = ip;
1544 newIpHeader.SetNextHeader(nextHeader);
1545 newIpHeader.SetPayloadLength(p->GetSize());
1546
1547 /* L4 protocol */
1548 Ptr<Packet> copy = p->Copy();
1549
1550 m_localDeliverTrace(newIpHeader, p, iif);
1551
1552 IpL4Protocol::RxStatus status =
1553 protocol->Receive(p, newIpHeader, GetInterface(iif));
1554
1555 switch (status)
1556 {
1558 break;
1560 break;
1562 break;
1564 if (newIpHeader.GetDestination().IsMulticast())
1565 {
1566 /* do not rely on multicast address */
1567 break;
1568 }
1569
1570 copy->AddHeader(newIpHeader);
1571 GetIcmpv6()->SendErrorDestinationUnreachable(
1572 copy,
1573 newIpHeader.GetSource(),
1575 }
1576 }
1577 }
1578 } while (ipv6Extension);
1579}
1580
1581void
1583 const Ipv6Header& ipHeader,
1584 Socket::SocketErrno sockErrno)
1585{
1586 NS_LOG_FUNCTION(this << p << ipHeader << sockErrno);
1587 NS_LOG_LOGIC("Route input failure-- dropping packet to " << ipHeader << " with errno "
1588 << sockErrno);
1589
1590 m_dropTrace(ipHeader, p, DROP_ROUTE_ERROR, this, 0);
1591
1592 if (!ipHeader.GetDestination().IsMulticast())
1593 {
1594 Ptr<Packet> packet = p->Copy();
1595 packet->AddHeader(ipHeader);
1596 GetIcmpv6()->SendErrorDestinationUnreachable(packet,
1597 ipHeader.GetSource(),
1599 }
1600}
1601
1604 Ipv6Address dst,
1605 uint8_t protocol,
1606 uint16_t payloadSize,
1607 uint8_t ttl,
1608 uint8_t tclass)
1609{
1610 NS_LOG_FUNCTION(this << src << dst << (uint32_t)protocol << (uint32_t)payloadSize
1611 << (uint32_t)ttl << (uint32_t)tclass);
1612 Ipv6Header hdr;
1613
1614 hdr.SetSource(src);
1615 hdr.SetDestination(dst);
1616 hdr.SetNextHeader(protocol);
1617 hdr.SetPayloadLength(payloadSize);
1618 hdr.SetHopLimit(ttl);
1619 hdr.SetTrafficClass(tclass);
1620 return hdr;
1621}
1622
1623void
1625{
1627 {
1628 return;
1629 }
1630 Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = CreateObject<Ipv6ExtensionDemux>();
1631 ipv6ExtensionDemux->SetNode(m_node);
1632
1633 Ptr<Ipv6ExtensionHopByHop> hopbyhopExtension = CreateObject<Ipv6ExtensionHopByHop>();
1634 hopbyhopExtension->SetNode(m_node);
1635 Ptr<Ipv6ExtensionDestination> destinationExtension = CreateObject<Ipv6ExtensionDestination>();
1636 destinationExtension->SetNode(m_node);
1637 Ptr<Ipv6ExtensionFragment> fragmentExtension = CreateObject<Ipv6ExtensionFragment>();
1638 fragmentExtension->SetNode(m_node);
1639 Ptr<Ipv6ExtensionRouting> routingExtension = CreateObject<Ipv6ExtensionRouting>();
1640 routingExtension->SetNode(m_node);
1641 // Ptr<Ipv6ExtensionESP> espExtension = CreateObject<Ipv6ExtensionESP> ();
1642 // Ptr<Ipv6ExtensionAH> ahExtension = CreateObject<Ipv6ExtensionAH> ();
1643
1644 ipv6ExtensionDemux->Insert(hopbyhopExtension);
1645 ipv6ExtensionDemux->Insert(destinationExtension);
1646 ipv6ExtensionDemux->Insert(fragmentExtension);
1647 ipv6ExtensionDemux->Insert(routingExtension);
1648 // ipv6ExtensionDemux->Insert (espExtension);
1649 // ipv6ExtensionDemux->Insert (ahExtension);
1650
1651 Ptr<Ipv6ExtensionRoutingDemux> routingExtensionDemux =
1652 CreateObject<Ipv6ExtensionRoutingDemux>();
1653 routingExtensionDemux->SetNode(m_node);
1654 Ptr<Ipv6ExtensionLooseRouting> looseRoutingExtension =
1655 CreateObject<Ipv6ExtensionLooseRouting>();
1656 looseRoutingExtension->SetNode(m_node);
1657 routingExtensionDemux->Insert(looseRoutingExtension);
1658
1659 m_node->AggregateObject(routingExtensionDemux);
1660 m_node->AggregateObject(ipv6ExtensionDemux);
1661}
1662
1663void
1665{
1667 {
1668 return;
1669 }
1670 Ptr<Ipv6OptionDemux> ipv6OptionDemux = CreateObject<Ipv6OptionDemux>();
1671 ipv6OptionDemux->SetNode(m_node);
1672
1673 Ptr<Ipv6OptionPad1> pad1Option = CreateObject<Ipv6OptionPad1>();
1674 pad1Option->SetNode(m_node);
1675 Ptr<Ipv6OptionPadn> padnOption = CreateObject<Ipv6OptionPadn>();
1676 padnOption->SetNode(m_node);
1677 Ptr<Ipv6OptionJumbogram> jumbogramOption = CreateObject<Ipv6OptionJumbogram>();
1678 jumbogramOption->SetNode(m_node);
1679 Ptr<Ipv6OptionRouterAlert> routerAlertOption = CreateObject<Ipv6OptionRouterAlert>();
1680 routerAlertOption->SetNode(m_node);
1681
1682 ipv6OptionDemux->Insert(pad1Option);
1683 ipv6OptionDemux->Insert(padnOption);
1684 ipv6OptionDemux->Insert(jumbogramOption);
1685 ipv6OptionDemux->Insert(routerAlertOption);
1686
1687 m_node->AggregateObject(ipv6OptionDemux);
1688}
1689
1690void
1692{
1693 m_dropTrace(ipHeader, p, dropReason, this, 0);
1694}
1695
1696void
1698{
1699 NS_LOG_FUNCTION(address << interface);
1700
1701 if (!address.IsMulticast())
1702 {
1703 NS_LOG_WARN("Not adding a non-multicast address " << address);
1704 return;
1705 }
1706
1707 Ipv6RegisteredMulticastAddressKey_t key = std::make_pair(address, interface);
1708 m_multicastAddresses[key]++;
1709}
1710
1711void
1713{
1714 NS_LOG_FUNCTION(address);
1715
1716 if (!address.IsMulticast())
1717 {
1718 NS_LOG_WARN("Not adding a non-multicast address " << address);
1719 return;
1720 }
1721
1723}
1724
1725void
1727{
1728 NS_LOG_FUNCTION(address << interface);
1729
1730 Ipv6RegisteredMulticastAddressKey_t key = std::make_pair(address, interface);
1731
1732 m_multicastAddresses[key]--;
1733 if (m_multicastAddresses[key] == 0)
1734 {
1735 m_multicastAddresses.erase(key);
1736 }
1737}
1738
1739void
1741{
1742 NS_LOG_FUNCTION(address);
1743
1745 if (m_multicastAddressesNoInterface[address] == 0)
1746 {
1747 m_multicastAddressesNoInterface.erase(address);
1748 }
1749}
1750
1751bool
1753{
1754 Ipv6RegisteredMulticastAddressKey_t key = std::make_pair(address, interface);
1755 auto iter = m_multicastAddresses.find(key);
1756
1757 return iter != m_multicastAddresses.end();
1758}
1759
1760bool
1762{
1763 auto iter = m_multicastAddressesNoInterface.find(address);
1764
1765 return iter != m_multicastAddressesNoInterface.end();
1766}
1767
1768bool
1770{
1771 if (ipInterfaceIndex >= m_interfaces.size())
1772 {
1773 return false;
1774 }
1775
1776 Ptr<NdiscCache> ndiscCache = m_interfaces[ipInterfaceIndex]->GetNdiscCache();
1777 if (!ndiscCache)
1778 {
1779 return false;
1780 }
1781
1782 NdiscCache::Entry* entry = ndiscCache->Lookup(address);
1783 if (!entry || entry->IsIncomplete())
1784 {
1785 return false;
1786 }
1787
1788 if (entry->IsReachable())
1789 {
1790 entry->UpdateReachableTimer();
1791 }
1792 else if (entry->IsPermanent() || entry->IsAutoGenerated())
1793 {
1794 return true;
1795 }
1796 else if (entry->IsProbe())
1797 {
1798 // we just confirm the entry's MAC address to get the waiting packets (if any)
1799 std::list<NdiscCache::Ipv6PayloadHeaderPair> waiting =
1800 entry->MarkReachable(entry->GetMacAddress());
1801 for (auto it = waiting.begin(); it != waiting.end(); it++)
1802 {
1803 ndiscCache->GetInterface()->Send(it->first, it->second, it->second.GetSource());
1804 }
1805 entry->ClearWaitingPacket();
1806 entry->StartReachableTimer();
1807 }
1808 else // STALE OR DELAY
1809 {
1810 entry->MarkReachable();
1811 entry->StartReachableTimer();
1812 }
1813
1814 return true;
1815}
1816
1817void
1819{
1820 NS_LOG_FUNCTION(this << model);
1821 m_strongEndSystemModel = model;
1822}
1823
1824bool
1826{
1828}
1829
1830} /* namespace ns3 */
a polymophic address class
Definition: address.h:101
AttributeValue implementation for Boolean.
Definition: boolean.h:37
An implementation of the ICMPv6 protocol.
static uint16_t GetStaticProtocolNumber()
Get ICMPv6 protocol number.
@ AUTADDRCONF
Autonomous Address Configuration.
RxStatus
Rx status codes.
Describes an IPv6 address.
Definition: ipv6-address.h:49
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
bool IsDocumentation() const
If the IPv6 address is a documentation address (2001:DB8::/32).
bool IsAllNodesMulticast() const
If the IPv6 address is "all nodes multicast" (ff02::1/8).
bool IsLinkLocalMulticast() const
If the IPv6 address is link-local multicast (ff02::/16).
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
static Ipv6Address MakeAutoconfiguredAddress(Address addr, Ipv6Address prefix)
Make the autoconfigured IPv6 address from a Mac address.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
bool IsAny() const
If the IPv6 address is the "Any" address.
bool IsLocalhost() const
If the IPv6 address is localhost (::1).
static Ipv6Address GetLoopback()
Get the loopback address.
bool IsAllRoutersMulticast() const
If the IPv6 address is "all routers multicast" (ff02::2/8).
Demultiplexes IPv6 extensions.
IPv6 Extension Fragment.
Packet header for IPv6.
Definition: ipv6-header.h:35
void SetDestination(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:118
void SetSource(Ipv6Address src)
Set the "Source address" field.
Definition: ipv6-header.cc:106
uint8_t GetHopLimit() const
Get the "Hop limit" field (TTL).
Definition: ipv6-header.cc:100
uint8_t GetNextHeader() const
Get the next header.
Definition: ipv6-header.cc:88
void SetHopLimit(uint8_t limit)
Set the "Hop limit" field (TTL).
Definition: ipv6-header.cc:94
Ipv6Address GetDestination() const
Get the "Destination address" field.
Definition: ipv6-header.cc:124
uint16_t GetPayloadLength() const
Get the "Payload length" field.
Definition: ipv6-header.cc:76
void SetPayloadLength(uint16_t len)
Set the "Payload length" field.
Definition: ipv6-header.cc:70
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
Definition: ipv6-header.cc:159
Ipv6Address GetSource() const
Get the "Source address" field.
Definition: ipv6-header.cc:112
void SetTrafficClass(uint8_t traffic)
Set the "Traffic class" field.
Definition: ipv6-header.cc:46
void SetNextHeader(uint8_t next)
Set the "Next header" field.
Definition: ipv6-header.cc:82
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:82
IPv6 address associated with an interface.
Ipv6Address GetAddress() const
Get the IPv6 address.
@ LINKLOCAL
Link-local address (fe80::/64)
@ GLOBAL
Global address (2000::/3)
The IPv6 representation of a network interface.
Ipv6InterfaceAddress GetLinkLocalAddress() const
Get link-local address from IPv6 interface.
virtual Ptr< NetDevice > GetDevice() const
Get the NetDevice.
IPv6 layer implementation.
bool GetIpForward() const override
Get IPv6 forwarding state.
Ptr< Ipv6PmtuCache > m_pmtuCache
Path MTU Cache.
Ipv6RoutingProtocol::MulticastForwardCallback m_mcb
Multicast forward callback.
void SetForwarding(uint32_t i, bool val) override
Enable or disable forwarding on interface.
void SetPmtu(Ipv6Address dst, uint32_t pmtu) override
Set the Path MTU for the specified IPv6 destination address.
void RegisterOptions() override
Register the IPv6 Options.
void RouteInputError(Ptr< const Packet > p, const Ipv6Header &ipHeader, Socket::SocketErrno sockErrno)
Fallback when no route is found.
uint8_t m_defaultTclass
Default TCLASS for outgoing packets.
bool IsRegisteredMulticastAddress(Ipv6Address address) const
Checks if the address has been registered.
Ptr< Ipv6RoutingProtocol > GetRoutingProtocol() const override
Get current routing protocol used.
bool GetMtuDiscover() const override
Get IPv6 MTU discover state.
bool AddAddress(uint32_t i, Ipv6InterfaceAddress address, bool addOnLinkRoute=true) override
Add an address on interface.
uint16_t GetMetric(uint32_t i) const override
Get metric for an interface.
Ipv6RoutingProtocol::UnicastForwardCallback m_ucb
Unicast forward callback.
void AddAutoconfiguredAddress(uint32_t interface, Ipv6Address network, Ipv6Prefix mask, uint8_t flags, uint32_t validTime, uint32_t preferredTime, Ipv6Address defaultRouter=Ipv6Address::GetZero())
Add an autoconfigured address with RA information.
void SetUp(uint32_t i) override
Set an interface up.
TracedCallback< Ptr< const Packet >, Ptr< Ipv6 >, uint32_t > m_txTrace
Callback to trace TX (transmission) packets.
bool IsForwarding(uint32_t i) const override
Is interface allows forwarding ?
void SetStrongEndSystemModel(bool model) override
Set or unset the Strong End System Model.
bool m_sendIcmpv6Redirect
Allow ICMPv6 Redirect sending state.
Ptr< Icmpv6L4Protocol > GetIcmpv6() const
Get ICMPv6 protocol.
bool ReachabilityHint(uint32_t ipInterfaceIndex, Ipv6Address address)
Provides reachability hint for Neighbor Cache Entries from L4-L7 protocols.
uint8_t m_defaultTtl
Default TTL for outgoing packets.
void SetMetric(uint32_t i, uint16_t metric) override
Set metric for an interface.
TracedCallback< Ptr< const Packet >, Ptr< Ipv6 >, uint32_t > m_rxTrace
Callback to trace RX (reception) packets.
TracedCallback< const Ipv6Header &, Ptr< const Packet >, DropReason, Ptr< Ipv6 >, uint32_t > m_dropTrace
Callback to trace drop packets.
DropReason
Reason why a packet has been dropped.
@ DROP_ROUTE_ERROR
Route error.
@ DROP_TTL_EXPIRED
Packet TTL has expired.
@ DROP_NO_ROUTE
No route to host.
@ DROP_UNKNOWN_PROTOCOL
Unknown L4 protocol.
uint32_t GetNAddresses(uint32_t interface) const override
Get number of address for an interface.
int32_t GetInterfaceForDevice(Ptr< const NetDevice > device) const override
Get interface index which is on a specified net device.
void RegisterExtensions() override
Register the IPv6 Extensions.
TracedCallback< const Ipv6Header &, Ptr< const Packet >, uint32_t > m_sendOutgoingTrace
Trace of sent packets.
bool m_ipForward
Forwarding packets (i.e.
Ipv6AutoconfiguredPrefixList m_prefixes
List of IPv6 prefix received from RA.
void CallTxTrace(const Ipv6Header &ipHeader, Ptr< Packet > packet, Ptr< Ipv6 > ipv6, uint32_t interface)
Make a copy of the packet, add the header and invoke the TX trace callback.
Ipv6InterfaceList m_interfaces
List of IPv6 interfaces.
void Remove(Ptr< IpL4Protocol > protocol) override
Remove a L4 protocol.
Ipv6RegisteredMulticastAddressNoInterface_t m_multicastAddressesNoInterface
List of multicast IP addresses of interest for all the interfaces.
Ipv6InterfaceAddress GetAddress(uint32_t interfaceIndex, uint32_t addressIndex) const override
Get an address.
SocketList m_sockets
List of IPv6 raw sockets.
Ipv6Header BuildHeader(Ipv6Address src, Ipv6Address dst, uint8_t protocol, uint16_t payloadSize, uint8_t hopLimit, uint8_t tclass)
Construct an IPv6 header.
void SetNode(Ptr< Node > node)
Set node associated with this stack.
Ipv6Address SourceAddressSelection(uint32_t interface, Ipv6Address dest) override
Choose the source address to use with destination address.
Ptr< Node > m_node
Node attached to stack.
virtual bool GetSendIcmpv6Redirect() const
Get the ICMPv6 Redirect sending state.
L4List_t m_protocols
List of transport protocol.
Ptr< Ipv6Interface > GetInterface(uint32_t i) const
Get an interface.
TracedCallback< const Ipv6Header &, Ptr< const Packet >, uint32_t > m_unicastForwardTrace
Trace of unicast forwarded packets.
uint32_t m_nInterfaces
Number of IPv6 interfaces managed by the stack.
void AddMulticastAddress(Ipv6Address address)
Adds a multicast address to the list of addresses to pass to local deliver.
virtual void ReportDrop(Ipv6Header ipHeader, Ptr< Packet > p, DropReason dropReason)
Report a packet drop.
void Send(Ptr< Packet > packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr< Ipv6Route > route) override
Higher-level layers call this method to send a packet down the stack to the MAC and PHY layers.
void SetupLoopback()
Setup loopback interface.
Ptr< IpL4Protocol > GetProtocol(int protocolNumber) const override
Get L4 protocol by protocol number.
Ptr< Socket > CreateRawSocket()
Create raw IPv6 socket.
Ipv6RegisteredMulticastAddress_t m_multicastAddresses
List of multicast IP addresses of interest, divided per interface.
void RemoveAutoconfiguredAddress(uint32_t interface, Ipv6Address network, Ipv6Prefix mask, Ipv6Address defaultRouter)
Remove an autoconfigured address.
uint16_t GetMtu(uint32_t i) const override
Get MTU for an interface.
void Insert(Ptr< IpL4Protocol > protocol) override
Add a L4 protocol.
bool m_mtuDiscover
MTU Discover (i.e.
void SetDefaultTtl(uint8_t ttl)
Set the default TTL.
uint32_t AddInterface(Ptr< NetDevice > device) override
Add IPv6 interface for a device.
Ipv6RoutingProtocol::ErrorCallback m_ecb
Error callback.
bool RemoveAddress(uint32_t interfaceIndex, uint32_t addressIndex) override
Remove an address from an interface.
void Receive(Ptr< NetDevice > device, Ptr< const Packet > p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Receive method when a packet arrive in the stack.
Ptr< NetDevice > GetNetDevice(uint32_t i) override
Get device by index.
void RemoveMulticastAddress(Ipv6Address address)
Removes a multicast address from the list of addresses to pass to local deliver.
void SetDown(uint32_t i) override
set an interface down.
void DoDispose() override
Dispose object.
uint32_t AddIpv6Interface(Ptr< Ipv6Interface > interface)
Add an IPv6 interface to the stack.
Ptr< Ipv6RoutingProtocol > m_routingProtocol
Routing protocol.
virtual void SetSendIcmpv6Redirect(bool sendIcmpv6Redirect)
Set the ICMPv6 Redirect sending state.
void NotifyNewAggregate() override
Notify other components connected to the node that a new stack member is now connected.
void IpMulticastForward(Ptr< const NetDevice > idev, Ptr< Ipv6MulticastRoute > mrtentry, Ptr< const Packet > p, const Ipv6Header &header)
Forward a multicast packet.
~Ipv6L3Protocol() override
Destructor.
void DeleteRawSocket(Ptr< Socket > socket)
Remove raw IPv6 socket.
Ipv6InterfaceReverseContainer m_reverseInterfacesContainer
Container of NetDevice / Interface index associations.
void SendRealOut(Ptr< Ipv6Route > route, Ptr< Packet > packet, const Ipv6Header &ipHeader)
Send packet with route.
bool m_strongEndSystemModel
Rejects packets directed to an interface with wrong address (RFC 1222).
TracedCallback< const Ipv6Header &, Ptr< const Packet >, uint32_t > m_localDeliverTrace
Trace of locally delivered packets.
int32_t GetInterfaceForPrefix(Ipv6Address addr, Ipv6Prefix mask) const override
Get interface index which match specified address/prefix.
static const uint16_t PROT_NUMBER
The protocol number for IPv6 (0x86DD).
void SetDefaultTclass(uint8_t tclass)
Set the default TCLASS.
void IpForward(Ptr< const NetDevice > idev, Ptr< Ipv6Route > rtentry, Ptr< const Packet > p, const Ipv6Header &header)
Forward a packet.
uint32_t GetNInterfaces() const override
Get current number of interface on this stack.
bool IsUp(uint32_t i) const override
Is specified interface up ?
void SetRoutingProtocol(Ptr< Ipv6RoutingProtocol > routingProtocol) override
Set routing protocol for this stack.
std::pair< Ipv6Address, uint64_t > Ipv6RegisteredMulticastAddressKey_t
IPv6 multicast addresses / interface key.
Ipv6RoutingProtocol::LocalDeliverCallback m_lcb
Local delivery callback.
std::pair< int, int32_t > L4ListKey_t
Container of the IPv6 L4 keys: protocol number, interface index.
bool GetStrongEndSystemModel() const override
Get the Strong End System Model status.
int32_t GetInterfaceForAddress(Ipv6Address addr) const override
Get interface index which has specified IPv6 address.
Ipv6L3Protocol()
Constructor.
void SetIpForward(bool forward) override
Set IPv6 forwarding state.
void LocalDeliver(Ptr< const Packet > p, const Ipv6Header &ip, uint32_t iif)
Deliver a packet.
static TypeId GetTypeId()
Get the type ID of this class.
void SetMtuDiscover(bool mtuDiscover) override
Set IPv6 MTU discover state.
IPv6 Option Demux.
Describes an IPv6 prefix.
Definition: ipv6-address.h:455
A record that holds information about a NdiscCache entry.
Definition: ndisc-cache.h:167
bool IsPermanent() const
Is the entry PERMANENT.
Definition: ndisc-cache.cc:659
void ClearWaitingPacket()
Clear the waiting packet list.
Definition: ndisc-cache.cc:286
void StartReachableTimer()
Start the reachable timer.
Definition: ndisc-cache.cc:469
void UpdateReachableTimer()
Update the reachable timer.
Definition: ndisc-cache.cc:484
Address GetMacAddress() const
Get the MAC address of this entry.
Definition: ndisc-cache.cc:673
std::list< Ipv6PayloadHeaderPair > MarkReachable(Address mac)
Changes the state to this entry to REACHABLE.
Definition: ndisc-cache.cc:562
bool IsIncomplete() const
Is the entry INCOMPLETE.
Definition: ndisc-cache.cc:645
bool IsProbe() const
Is the entry PROBE.
Definition: ndisc-cache.cc:652
bool IsAutoGenerated() const
Is the entry STATIC_AUTOGENERATED.
Definition: ndisc-cache.cc:666
bool IsReachable() const
Is the entry REACHABLE.
Definition: ndisc-cache.cc:631
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:300
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:135
uint32_t GetNDevices() const
Definition: node.cc:158
uint32_t GetId() const
Definition: node.cc:117
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:149
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:231
virtual void NotifyNewAggregate()
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:423
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:522
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:309
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:444
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:84
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer.
Definition: socket.h:1172
uint8_t GetHopLimit() const
Get the tag's Hop Limit.
Definition: socket.cc:674
indicates whether the socket has IPV6_TCLASS set.
Definition: socket.h:1366
uint8_t GetTclass() const
Get the tag's Tclass.
Definition: socket.cc:916
indicates whether the socket has a priority set.
Definition: socket.h:1318
The Traffic Control layer aims at introducing an equivalent of the Linux Traffic Control infrastructu...
virtual void Receive(Ptr< NetDevice > device, Ptr< const Packet > p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Called by NetDevices, incoming packet.
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
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
#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:86
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:81
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
Definition: object-vector.h:40
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:76
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_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_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:630
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
#define IPV6_MIN_MTU
Minimum IPv6 MTU, as defined by RFC 2460
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:454
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:706
-ns3 Test suite for the ns3 wrapper script