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
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 NS_LOG_FUNCTION(this);
195 return m_routingProtocol;
196}
197
200{
201 NS_LOG_FUNCTION(this << device);
203
205
206 NS_ASSERT(tc);
207
210 device);
211
212 tc->RegisterProtocolHandler(MakeCallback(&Ipv6L3Protocol::Receive, this),
214 device);
215
216 interface->SetNode(m_node);
217 interface->SetDevice(device);
218 interface->SetTrafficControl(tc);
219 interface->SetForwarding(m_ipForward);
220 return AddIpv6Interface(interface);
221}
222
225{
226 NS_LOG_FUNCTION(this << interface);
227 uint32_t index = m_nInterfaces;
228
229 m_interfaces.push_back(interface);
230 m_reverseInterfacesContainer[interface->GetDevice()] = index;
232 return index;
233}
234
237{
238 NS_LOG_FUNCTION(this << index);
239
240 if (index < m_interfaces.size())
241 {
242 return m_interfaces[index];
243 }
244 return nullptr;
245}
246
249{
250 NS_LOG_FUNCTION(this);
251 return m_nInterfaces;
252}
253
256{
257 NS_LOG_FUNCTION(this << address);
258 int32_t index = 0;
259
260 for (auto it = m_interfaces.begin(); it != m_interfaces.end(); it++)
261 {
262 uint32_t j = 0;
263 uint32_t max = (*it)->GetNAddresses();
264
265 for (j = 0; j < max; j++)
266 {
267 if ((*it)->GetAddress(j).GetAddress() == address)
268 {
269 return index;
270 }
271 }
272 index++;
273 }
274 return -1;
275}
276
279{
280 NS_LOG_FUNCTION(this << address << mask);
281 int32_t index = 0;
282
283 for (auto it = m_interfaces.begin(); it != m_interfaces.end(); it++)
284 {
285 uint32_t j = 0;
286 for (j = 0; j < (*it)->GetNAddresses(); j++)
287 {
288 if ((*it)->GetAddress(j).GetAddress().CombinePrefix(mask) ==
289 address.CombinePrefix(mask))
290 {
291 return index;
292 }
293 }
294 index++;
295 }
296 return -1;
297}
298
301{
302 NS_LOG_FUNCTION(this << i);
303 return GetInterface(i)->GetDevice();
304}
305
308{
309 NS_LOG_FUNCTION(this << device);
310
311 auto iter = m_reverseInterfacesContainer.find(device);
312 if (iter != m_reverseInterfacesContainer.end())
313 {
314 return (*iter).second;
315 }
316
317 return -1;
318}
319
320void
322 Ipv6Address network,
323 Ipv6Prefix mask,
324 uint8_t flags,
325 uint32_t validTime,
326 uint32_t preferredTime,
327 Ipv6Address defaultRouter)
328{
329 NS_LOG_FUNCTION(this << interface << network << mask << (uint32_t)flags << validTime
330 << preferredTime);
331 Ipv6InterfaceAddress address;
332
333 Address addr = GetInterface(interface)->GetDevice()->GetAddress();
334
335 if (!defaultRouter.IsAny())
336 {
337 GetRoutingProtocol()->NotifyAddRoute(Ipv6Address::GetAny(),
338 Ipv6Prefix((uint8_t)0),
339 defaultRouter,
340 interface,
341 network);
342 }
343
344 bool onLink = false;
346 {
347 onLink = true;
348 }
349
350 if (flags & Icmpv6OptionPrefixInformation::AUTADDRCONF) /* auto flag */
351 {
352 address = Ipv6Address::MakeAutoconfiguredAddress(addr, network);
353 address.SetOnLink(onLink);
354
355 /* see if we have already the prefix */
356 for (auto it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
357 {
358 if ((*it)->GetInterface() == interface && (*it)->GetPrefix() == network &&
359 (*it)->GetMask() == mask)
360 {
361 (*it)->StopPreferredTimer();
362 (*it)->StopValidTimer();
363 (*it)->StartPreferredTimer();
364 return;
365 }
366 }
367
368 /* no prefix found, add autoconfigured address and the prefix */
369 NS_LOG_INFO("Autoconfigured address is :" << address.GetAddress());
370 AddAddress(interface, address, onLink);
371
373 CreateObject<Ipv6AutoconfiguredPrefix>(m_node,
374 interface,
375 network,
376 mask,
377 preferredTime,
378 validTime,
379 defaultRouter);
380 aPrefix->StartPreferredTimer();
381
382 m_prefixes.push_back(aPrefix);
383 }
384
385 if (onLink) /* on-link flag */
386 {
387 /* add default router
388 * if a previous default route exists, the new ones is simply added
389 */
390 m_routingProtocol->NotifyAddRoute(network, mask, Ipv6Address::GetAny(), interface);
391 }
392}
393
394void
396 Ipv6Address network,
397 Ipv6Prefix mask,
398 Ipv6Address defaultRouter)
399{
400 NS_LOG_FUNCTION(this << interface << network << mask);
401 Ptr<Ipv6Interface> iface = GetInterface(interface);
402 Address addr = iface->GetDevice()->GetAddress();
403
404 Ipv6Address addressToFind = Ipv6Address::MakeAutoconfiguredAddress(addr, network);
405
406 for (uint32_t i = 0; i < iface->GetNAddresses(); i++)
407 {
408 if (iface->GetAddress(i).GetAddress() == addressToFind)
409 {
410 RemoveAddress(interface, i);
411 break;
412 }
413 }
414
415 /* remove from list of autoconfigured address */
416 for (auto it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
417 {
418 if ((*it)->GetInterface() == interface && (*it)->GetPrefix() == network &&
419 (*it)->GetMask() == mask)
420 {
421 *it = nullptr;
422 m_prefixes.erase(it);
423 break;
424 }
425 }
426
427 GetRoutingProtocol()->NotifyRemoveRoute(Ipv6Address::GetAny(),
428 Ipv6Prefix((uint8_t)0),
429 defaultRouter,
430 interface,
431 network);
432}
433
434bool
436{
437 NS_LOG_FUNCTION(this << i << address);
438 Ptr<Ipv6Interface> interface = GetInterface(i);
439 address.SetOnLink(addOnLinkRoute);
440 bool ret = interface->AddAddress(address);
441
442 if (m_routingProtocol)
443 {
444 m_routingProtocol->NotifyAddAddress(i, address);
445 }
446
447 if (addOnLinkRoute)
448 {
449 Ipv6Address networkAddress = address.GetAddress().CombinePrefix(address.GetPrefix());
450 Ipv6Prefix networkMask = address.GetPrefix();
451 GetRoutingProtocol()->NotifyAddRoute(networkAddress,
452 networkMask,
453 Ipv6Address::GetZero(),
454 i);
455 }
456 return ret;
457}
458
461{
462 NS_LOG_FUNCTION(this << i);
463 Ptr<Ipv6Interface> interface = GetInterface(i);
464 return interface->GetNAddresses();
465}
466
469{
470 NS_LOG_FUNCTION(this << i << addressIndex);
471 Ptr<Ipv6Interface> interface = GetInterface(i);
472 return interface->GetAddress(addressIndex);
473}
474
475bool
477{
478 NS_LOG_FUNCTION(this << i << addressIndex);
479 Ptr<Ipv6Interface> interface = GetInterface(i);
480 Ipv6InterfaceAddress address = interface->RemoveAddress(addressIndex);
481
482 if (address != Ipv6InterfaceAddress())
483 {
484 if (m_routingProtocol)
485 {
486 m_routingProtocol->NotifyRemoveAddress(i, address);
487 }
488 return true;
489 }
490 return false;
491}
492
493bool
495{
496 NS_LOG_FUNCTION(this << i << address);
497
498 if (address == Ipv6Address::GetLoopback())
499 {
500 NS_LOG_WARN("Cannot remove loopback address.");
501 return false;
502 }
503 Ptr<Ipv6Interface> interface = GetInterface(i);
504 Ipv6InterfaceAddress ifAddr = interface->RemoveAddress(address);
505 if (ifAddr != Ipv6InterfaceAddress())
506 {
507 if (m_routingProtocol)
508 {
509 m_routingProtocol->NotifyRemoveAddress(i, ifAddr);
510 }
511 return true;
512 }
513 return false;
514}
515
516void
518{
519 NS_LOG_FUNCTION(this << i << metric);
520 Ptr<Ipv6Interface> interface = GetInterface(i);
521 interface->SetMetric(metric);
522}
523
524uint16_t
526{
527 NS_LOG_FUNCTION(this << i);
528 Ptr<Ipv6Interface> interface = GetInterface(i);
529 return interface->GetMetric();
530}
531
532uint16_t
534{
535 NS_LOG_FUNCTION(this << i);
536
537 // RFC 1981, if PMTU is disabled, return the minimum MTU
538 if (!m_mtuDiscover)
539 {
540 return IPV6_MIN_MTU;
541 }
542
543 Ptr<Ipv6Interface> interface = GetInterface(i);
544 return interface->GetDevice()->GetMtu();
545}
546
547void
549{
550 NS_LOG_FUNCTION(this << dst << int(pmtu));
551 m_pmtuCache->SetPmtu(dst, pmtu);
552}
553
554bool
556{
557 NS_LOG_FUNCTION(this << i);
558 Ptr<Ipv6Interface> interface = GetInterface(i);
559 return interface->IsUp();
560}
561
562void
564{
565 NS_LOG_FUNCTION(this << i);
566 Ptr<Ipv6Interface> interface = GetInterface(i);
567
568 // RFC 2460, Section 5, pg. 24:
569 // IPv6 requires that every link in the internet have an MTU of 1280
570 // octets or greater. On any link that cannot convey a 1280-octet
571 // packet in one piece, link-specific fragmentation and reassembly must
572 // be provided at a layer below IPv6.
573 if (interface->GetDevice()->GetMtu() >= 1280)
574 {
575 interface->SetUp();
576
577 if (m_routingProtocol)
578 {
579 m_routingProtocol->NotifyInterfaceUp(i);
580 }
581 }
582 else
583 {
584 NS_LOG_LOGIC("Interface " << int(i)
585 << " is set to be down for IPv6. Reason: not respecting minimum "
586 "IPv6 MTU (1280 octets)");
587 }
588}
589
590void
592{
593 NS_LOG_FUNCTION(this << i);
594 Ptr<Ipv6Interface> interface = GetInterface(i);
595
596 interface->SetDown();
597
598 if (m_routingProtocol)
599 {
600 m_routingProtocol->NotifyInterfaceDown(i);
601 }
602}
603
604void
606{
607 NS_LOG_FUNCTION(this);
609 Ptr<LoopbackNetDevice> device = nullptr;
610 uint32_t i = 0;
611
612 /* see if we have already an loopback NetDevice */
613 for (i = 0; i < m_node->GetNDevices(); i++)
614 {
615 if ((device = DynamicCast<LoopbackNetDevice>(m_node->GetDevice(i))))
616 {
617 break;
618 }
619 }
620
621 if (!device)
622 {
623 device = CreateObject<LoopbackNetDevice>();
624 m_node->AddDevice(device);
625 }
626
627 interface->SetDevice(device);
628 interface->SetNode(m_node);
629 Ipv6InterfaceAddress ifaceAddr =
631 interface->AddAddress(ifaceAddr);
632 uint32_t index = AddIpv6Interface(interface);
633 Ptr<Node> node = GetObject<Node>();
634 node->RegisterProtocolHandler(MakeCallback(&Ipv6L3Protocol::Receive, this),
636 device);
637 interface->SetUp();
638
640 {
641 m_routingProtocol->NotifyInterfaceUp(index);
642 }
643}
644
645bool
647{
648 NS_LOG_FUNCTION(this << i);
649 Ptr<Ipv6Interface> interface = GetInterface(i);
650
651 NS_LOG_LOGIC("Forwarding state: " << interface->IsForwarding());
652 return interface->IsForwarding();
653}
654
655void
657{
658 NS_LOG_FUNCTION(this << i << val);
659 Ptr<Ipv6Interface> interface = GetInterface(i);
660 interface->SetForwarding(val);
661}
662
665{
666 NS_LOG_FUNCTION(this << interface << dest);
667 Ipv6Address ret;
668
669 if (dest.IsLocalhost())
670 {
672 }
673
674 if (dest.IsLinkLocal() || dest.IsLinkLocalMulticast())
675 {
676 for (uint32_t i = 0; i < GetNAddresses(interface); i++)
677 {
678 Ipv6InterfaceAddress test = GetAddress(interface, i);
679 if (test.GetScope() == Ipv6InterfaceAddress::LINKLOCAL)
680 {
681 return test.GetAddress();
682 }
683 }
684 NS_ASSERT_MSG(false, "No link-local address found on interface " << interface);
685 }
686
687 for (uint32_t i = 0; i < GetNAddresses(interface); i++)
688 {
689 Ipv6InterfaceAddress test = GetAddress(interface, i);
690
691 if (test.GetScope() == Ipv6InterfaceAddress::GLOBAL)
692 {
693 if (test.IsInSameSubnet(dest))
694 {
695 return test.GetAddress();
696 }
697 else
698 {
699 ret = test.GetAddress();
700 }
701 }
702 }
703
704 // no specific match found. Use a global address (any useful is fine).
705 NS_ASSERT_MSG(!ret.IsAny(),
706 "Could not find any address for " << dest << " on interface " << interface);
707 return ret;
708}
709
710void
712{
713 NS_LOG_FUNCTION(this << forward);
714 m_ipForward = forward;
715
716 for (auto it = m_interfaces.begin(); it != m_interfaces.end(); it++)
717 {
718 (*it)->SetForwarding(forward);
719 }
720}
721
722bool
724{
725 NS_LOG_FUNCTION(this);
726 return m_ipForward;
727}
728
729void
731{
732 NS_LOG_FUNCTION(this << int(mtuDiscover));
733 m_mtuDiscover = mtuDiscover;
734}
735
736bool
738{
739 NS_LOG_FUNCTION(this);
740 return m_mtuDiscover;
741}
742
743void
745{
746 NS_LOG_FUNCTION(this << sendIcmpv6Redirect);
747 m_sendIcmpv6Redirect = sendIcmpv6Redirect;
748}
749
750bool
752{
753 NS_LOG_FUNCTION(this);
755}
756
757void
759{
760 NS_LOG_FUNCTION(this);
761
762 if (!m_node)
763 {
764 Ptr<Node> node = this->GetObject<Node>();
765 // verify that it's a valid node and that
766 // the node has not been set before
767 if (node)
768 {
769 this->SetNode(node);
770 }
771 }
772
774}
775
776void
778{
779 NS_LOG_FUNCTION(this << node);
780 m_node = node;
781 /* add LoopbackNetDevice if needed, and an Ipv6Interface on top of it */
783}
784
785void
787{
788 NS_LOG_FUNCTION(this << protocol);
789 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), -1);
790 if (m_protocols.find(key) != m_protocols.end())
791 {
792 NS_LOG_WARN("Overwriting default protocol " << int(protocol->GetProtocolNumber()));
793 }
794 m_protocols[key] = protocol;
795}
796
797void
799{
800 NS_LOG_FUNCTION(this << protocol << interfaceIndex);
801
802 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), interfaceIndex);
803 if (m_protocols.find(key) != m_protocols.end())
804 {
805 NS_LOG_WARN("Overwriting protocol " << int(protocol->GetProtocolNumber())
806 << " on interface " << int(interfaceIndex));
807 }
808 m_protocols[key] = protocol;
809}
810
811void
813{
814 NS_LOG_FUNCTION(this << protocol);
815
816 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), -1);
817 auto iter = m_protocols.find(key);
818 if (iter == m_protocols.end())
819 {
820 NS_LOG_WARN("Trying to remove an non-existent default protocol "
821 << int(protocol->GetProtocolNumber()));
822 }
823 else
824 {
825 m_protocols.erase(key);
826 }
827}
828
829void
831{
832 NS_LOG_FUNCTION(this << protocol << interfaceIndex);
833
834 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), interfaceIndex);
835 auto iter = m_protocols.find(key);
836 if (iter == m_protocols.end())
837 {
838 NS_LOG_WARN("Trying to remove an non-existent protocol "
839 << int(protocol->GetProtocolNumber()) << " on interface "
840 << int(interfaceIndex));
841 }
842 else
843 {
844 m_protocols.erase(key);
845 }
846}
847
849Ipv6L3Protocol::GetProtocol(int protocolNumber) const
850{
851 NS_LOG_FUNCTION(this << protocolNumber);
852
853 return GetProtocol(protocolNumber, -1);
854}
855
857Ipv6L3Protocol::GetProtocol(int protocolNumber, int32_t interfaceIndex) const
858{
859 NS_LOG_FUNCTION(this << protocolNumber << interfaceIndex);
860
861 if (interfaceIndex >= 0)
862 {
863 // try the interface-specific protocol.
864 auto key = std::make_pair(protocolNumber, interfaceIndex);
865 auto i = m_protocols.find(key);
866 if (i != m_protocols.end())
867 {
868 return i->second;
869 }
870 }
871 // try the generic protocol.
872 auto key = std::make_pair(protocolNumber, -1);
873 auto i = m_protocols.find(key);
874 if (i != m_protocols.end())
875 {
876 return i->second;
877 }
878
879 return nullptr;
880}
881
884{
885 NS_LOG_FUNCTION(this);
886 Ptr<Ipv6RawSocketImpl> sock = CreateObject<Ipv6RawSocketImpl>();
887 sock->SetNode(m_node);
888 m_sockets.push_back(sock);
889 return sock;
890}
891
892void
894{
895 NS_LOG_FUNCTION(this << socket);
896
897 for (auto it = m_sockets.begin(); it != m_sockets.end(); ++it)
898 {
899 if ((*it) == socket)
900 {
901 m_sockets.erase(it);
902 return;
903 }
904 }
905}
906
909{
910 NS_LOG_FUNCTION(this);
912
913 if (protocol)
914 {
915 return protocol->GetObject<Icmpv6L4Protocol>();
916 }
917 else
918 {
919 return nullptr;
920 }
921}
922
923void
925{
926 NS_LOG_FUNCTION(this << ttl);
927 m_defaultTtl = ttl;
928}
929
930void
932{
933 NS_LOG_FUNCTION(this << tclass);
934 m_defaultTclass = tclass;
935}
936
937void
939 Ipv6Address source,
940 Ipv6Address destination,
941 uint8_t protocol,
942 Ptr<Ipv6Route> route)
943{
944 NS_LOG_FUNCTION(this << packet << source << destination << (uint32_t)protocol << route);
945 Ipv6Header hdr;
946 uint8_t ttl = m_defaultTtl;
948 bool found = packet->RemovePacketTag(tag);
949
950 if (found)
951 {
952 ttl = tag.GetHopLimit();
953 }
954
955 SocketIpv6TclassTag tclassTag;
956 uint8_t tclass = m_defaultTclass;
957 found = packet->RemovePacketTag(tclassTag);
958
959 if (found)
960 {
961 tclass = tclassTag.GetTclass();
962 }
963
964 /* Handle 3 cases:
965 * 1) Packet is passed in with a route entry
966 * 2) Packet is passed in with a route entry but route->GetGateway is not set (e.g., same
967 * network) 3) route is NULL (e.g., a raw socket call or ICMPv6)
968 */
969
970 /* 1) */
971 if (route && route->GetGateway() != Ipv6Address::GetZero())
972 {
973 NS_LOG_LOGIC("Ipv6L3Protocol::Send case 1: passed in with a route");
974 hdr = BuildHeader(source, destination, protocol, packet->GetSize(), ttl, tclass);
975 int32_t interface = GetInterfaceForDevice(route->GetOutputDevice());
976 m_sendOutgoingTrace(hdr, packet, interface);
977 SendRealOut(route, packet, hdr);
978 return;
979 }
980
981 /* 2) */
982 if (route && route->GetGateway() == Ipv6Address::GetZero())
983 {
984 NS_LOG_LOGIC("Ipv6L3Protocol::Send case 2: probably sent to machine on same IPv6 network");
985 hdr = BuildHeader(source, destination, protocol, packet->GetSize(), ttl, tclass);
986 int32_t interface = GetInterfaceForDevice(route->GetOutputDevice());
987 m_sendOutgoingTrace(hdr, packet, interface);
988 SendRealOut(route, packet, hdr);
989 return;
990 }
991
992 /* 3) */
993 NS_LOG_LOGIC("Ipv6L3Protocol::Send case 3: passed in with no route " << destination);
995 Ptr<NetDevice> oif(nullptr);
996 Ptr<Ipv6Route> newRoute = nullptr;
997
998 hdr = BuildHeader(source, destination, protocol, packet->GetSize(), ttl, tclass);
999
1000 // for link-local traffic, we need to determine the interface
1001 if (source.IsLinkLocal() || destination.IsLinkLocal() || destination.IsLinkLocalMulticast())
1002 {
1003 int32_t index = GetInterfaceForAddress(source);
1004 NS_ASSERT_MSG(index >= 0,
1005 "Can not find an outgoing interface for a packet with src "
1006 << source << " and dst " << destination);
1007 oif = GetNetDevice(index);
1008 }
1009
1010 newRoute = m_routingProtocol->RouteOutput(packet, hdr, oif, err);
1011
1012 if (newRoute)
1013 {
1014 int32_t interface = GetInterfaceForDevice(newRoute->GetOutputDevice());
1015 m_sendOutgoingTrace(hdr, packet, interface);
1016 SendRealOut(newRoute, packet, hdr);
1017 }
1018 else
1019 {
1020 NS_LOG_WARN("No route to host, drop!");
1021 m_dropTrace(hdr, packet, DROP_NO_ROUTE, this, GetInterfaceForDevice(oif));
1022 }
1023}
1024
1025void
1028 uint16_t protocol,
1029 const Address& from,
1030 const Address& to,
1031 NetDevice::PacketType packetType)
1032{
1033 NS_LOG_FUNCTION(this << device << p << protocol << from << to << packetType);
1034 NS_LOG_LOGIC("Packet from " << from << " received on node " << m_node->GetId());
1035
1037 "Received a packet from an interface that is not known to IPv6");
1038 uint32_t interface = GetInterfaceForDevice(device);
1039
1040 Ptr<Ipv6Interface> ipv6Interface = m_interfaces[interface];
1041 Ptr<Packet> packet = p->Copy();
1042
1043 if (ipv6Interface->IsUp())
1044 {
1045 m_rxTrace(packet, this, interface);
1046 }
1047 else
1048 {
1049 NS_LOG_LOGIC("Dropping received packet-- interface is down");
1050 Ipv6Header hdr;
1051 packet->RemoveHeader(hdr);
1052 m_dropTrace(hdr, packet, DROP_INTERFACE_DOWN, this, interface);
1053 return;
1054 }
1055
1056 Ipv6Header hdr;
1057 packet->RemoveHeader(hdr);
1058
1059 // Trim any residual frame padding from underlying devices
1060 if (hdr.GetPayloadLength() < packet->GetSize())
1061 {
1062 packet->RemoveAtEnd(packet->GetSize() - hdr.GetPayloadLength());
1063 }
1064
1065 // the packet is valid, we update the NDISC cache entry (if present)
1066 Ptr<NdiscCache> ndiscCache = ipv6Interface->GetNdiscCache();
1067 if (ndiscCache)
1068 {
1069 // case one, it's a a direct routing.
1070 NdiscCache::Entry* entry = ndiscCache->Lookup(hdr.GetSource());
1071 if (entry)
1072 {
1073 entry->UpdateReachableTimer();
1074 }
1075 else
1076 {
1077 // It's not in the direct routing, so it's the router, and it could have multiple IP
1078 // addresses. In doubt, update all of them. Note: it's a confirmed behavior for Linux
1079 // routers.
1080 std::list<NdiscCache::Entry*> entryList = ndiscCache->LookupInverse(from);
1081 for (auto iter = entryList.begin(); iter != entryList.end(); iter++)
1082 {
1083 (*iter)->UpdateReachableTimer();
1084 }
1085 }
1086 }
1087
1088 /* forward up to IPv6 raw sockets */
1089 for (auto it = m_sockets.begin(); it != m_sockets.end(); ++it)
1090 {
1091 Ptr<Ipv6RawSocketImpl> socket = *it;
1092 socket->ForwardUp(packet, hdr, device);
1093 }
1094
1095 Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux>();
1096 Ptr<Ipv6Extension> ipv6Extension = nullptr;
1097 uint8_t nextHeader = hdr.GetNextHeader();
1098 bool stopProcessing = false;
1099 bool isDropped = false;
1100 DropReason dropReason;
1101
1102 if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1103 {
1104 ipv6Extension = ipv6ExtensionDemux->GetExtension(nextHeader);
1105
1106 if (ipv6Extension)
1107 {
1108 ipv6Extension->Process(packet,
1109 0,
1110 hdr,
1111 hdr.GetDestination(),
1112 (uint8_t*)nullptr,
1113 stopProcessing,
1114 isDropped,
1115 dropReason);
1116 }
1117
1118 if (isDropped)
1119 {
1120 m_dropTrace(hdr, packet, dropReason, this, interface);
1121 }
1122
1123 if (stopProcessing)
1124 {
1125 return;
1126 }
1127 }
1128
1130 {
1131 LocalDeliver(packet, hdr, interface);
1132 return;
1133 }
1134 else if (hdr.GetDestination().IsAllRoutersMulticast() && ipv6Interface->IsForwarding())
1135 {
1136 LocalDeliver(packet, hdr, interface);
1137 return;
1138 }
1139 else if (hdr.GetDestination().IsMulticast())
1140 {
1141 bool isSolicited = ipv6Interface->IsSolicitedMulticastAddress(hdr.GetDestination());
1142 bool isRegisteredOnInterface =
1143 IsRegisteredMulticastAddress(hdr.GetDestination(), interface);
1144 bool isRegisteredGlobally = IsRegisteredMulticastAddress(hdr.GetDestination());
1145 if (isSolicited || isRegisteredGlobally || isRegisteredOnInterface)
1146 {
1147 LocalDeliver(packet, hdr, interface);
1148 // do not return, the packet could be handled by a routing protocol
1149 }
1150 }
1151
1152 for (uint32_t j = 0; j < GetNInterfaces(); j++)
1153 {
1154 for (uint32_t i = 0; i < GetNAddresses(j); i++)
1155 {
1156 Ipv6InterfaceAddress iaddr = GetAddress(j, i);
1157 Ipv6Address addr = iaddr.GetAddress();
1158 if (addr == hdr.GetDestination())
1159 {
1160 if (j == interface)
1161 {
1162 NS_LOG_LOGIC("For me (destination " << addr << " match)");
1163 LocalDeliver(packet, hdr, interface);
1164 return;
1165 }
1166 else if (!GetStrongEndSystemModel())
1167 {
1168 NS_LOG_LOGIC("For me (destination "
1169 << addr
1170 << " match) on another interface with Weak End System Model"
1171 << hdr.GetDestination());
1172 LocalDeliver(packet, hdr, interface);
1173 return;
1174 }
1175 else
1176 {
1178 "For me (destination "
1179 << addr
1180 << " match) on another interface with Strong End System Model - discarding"
1181 << hdr.GetDestination());
1182 m_dropTrace(hdr, packet, DROP_NO_ROUTE, this, interface);
1183 return;
1184 }
1185 }
1186 NS_LOG_LOGIC("Address " << addr << " not a match");
1187 }
1188 }
1189
1190 if (!m_routingProtocol->RouteInput(packet, hdr, device, m_ucb, m_mcb, m_lcb, m_ecb))
1191 {
1192 NS_LOG_WARN("No route found for forwarding packet. Drop.");
1193 // Drop trace and ICMPs are courtesy of RouteInputError
1194 }
1195}
1196
1197void
1199 Ptr<Packet> packet,
1200 Ptr<Ipv6> ipv6,
1201 uint32_t interface)
1202{
1203 if (!m_txTrace.IsEmpty())
1204 {
1205 Ptr<Packet> packetCopy = packet->Copy();
1206 packetCopy->AddHeader(ipHeader);
1207 m_txTrace(packetCopy, ipv6, interface);
1208 }
1209}
1210
1211void
1213{
1214 NS_LOG_FUNCTION(this << route << packet << ipHeader);
1215
1216 if (!route)
1217 {
1218 NS_LOG_LOGIC("No route to host, drop!.");
1219 return;
1220 }
1221
1222 Ptr<NetDevice> dev = route->GetOutputDevice();
1223 int32_t interface = GetInterfaceForDevice(dev);
1224 NS_ASSERT(interface >= 0);
1225
1226 Ptr<Ipv6Interface> outInterface = GetInterface(interface);
1227 NS_LOG_LOGIC("Send via NetDevice ifIndex " << dev->GetIfIndex() << " Ipv6InterfaceIndex "
1228 << interface);
1229
1230 // Check packet size
1231 std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair> fragments;
1232
1233 // Check if this is the source of the packet
1234 bool fromMe = false;
1235 for (uint32_t i = 0; i < GetNInterfaces(); i++)
1236 {
1237 for (uint32_t j = 0; j < GetNAddresses(i); j++)
1238 {
1239 if (GetAddress(i, j).GetAddress() == ipHeader.GetSource())
1240 {
1241 fromMe = true;
1242 break;
1243 }
1244 }
1245 }
1246
1247 size_t targetMtu = 0;
1248
1249 // Check if we have a Path MTU stored. If so, use it. Else, use the link MTU.
1250 // Note: PMTU must not be cached in intermediate nodes, and must be checked only by the source
1251 // node
1252 if (fromMe)
1253 {
1254 targetMtu = (size_t)(m_pmtuCache->GetPmtu(ipHeader.GetDestination()));
1255 }
1256 if (targetMtu == 0)
1257 {
1258 targetMtu = dev->GetMtu();
1259 }
1260
1261 if (packet->GetSize() + ipHeader.GetSerializedSize() > targetMtu)
1262 {
1263 // Router => drop
1264 if (!fromMe)
1265 {
1266 Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6();
1267 if (icmpv6)
1268 {
1269 packet->AddHeader(ipHeader);
1270 icmpv6->SendErrorTooBig(packet, ipHeader.GetSource(), dev->GetMtu());
1271 }
1272 return;
1273 }
1274
1275 Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux>();
1276
1277 // To get specific method GetFragments from Ipv6ExtensionFragmentation
1278 Ipv6ExtensionFragment* ipv6Fragment = dynamic_cast<Ipv6ExtensionFragment*>(
1279 PeekPointer(ipv6ExtensionDemux->GetExtension(Ipv6Header::IPV6_EXT_FRAGMENTATION)));
1280 NS_ASSERT(ipv6Fragment != nullptr);
1281 ipv6Fragment->GetFragments(packet, ipHeader, targetMtu, fragments);
1282 }
1283
1284 if (route->GetGateway() != Ipv6Address::GetAny())
1285 {
1286 if (outInterface->IsUp())
1287 {
1288 NS_LOG_LOGIC("Send to gateway " << route->GetGateway());
1289
1290 if (!fragments.empty())
1291 {
1292 std::ostringstream oss;
1293
1294 for (auto it = fragments.begin(); it != fragments.end(); it++)
1295 {
1296 CallTxTrace(it->second, it->first, this, interface);
1297 outInterface->Send(it->first, it->second, route->GetGateway());
1298 }
1299 }
1300 else
1301 {
1302 CallTxTrace(ipHeader, packet, this, interface);
1303 outInterface->Send(packet, ipHeader, route->GetGateway());
1304 }
1305 }
1306 else
1307 {
1308 NS_LOG_LOGIC("Dropping-- outgoing interface is down: " << route->GetGateway());
1309 m_dropTrace(ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
1310 }
1311 }
1312 else
1313 {
1314 if (outInterface->IsUp())
1315 {
1316 NS_LOG_LOGIC("Send to destination " << ipHeader.GetDestination());
1317
1318 if (!fragments.empty())
1319 {
1320 std::ostringstream oss;
1321
1322 for (auto it = fragments.begin(); it != fragments.end(); it++)
1323 {
1324 CallTxTrace(it->second, it->first, this, interface);
1325 outInterface->Send(it->first, it->second, ipHeader.GetDestination());
1326 }
1327 }
1328 else
1329 {
1330 CallTxTrace(ipHeader, packet, this, interface);
1331 outInterface->Send(packet, ipHeader, ipHeader.GetDestination());
1332 }
1333 }
1334 else
1335 {
1336 NS_LOG_LOGIC("Dropping-- outgoing interface is down: " << ipHeader.GetDestination());
1337 m_dropTrace(ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
1338 }
1339 }
1340}
1341
1342void
1344 Ptr<Ipv6Route> rtentry,
1346 const Ipv6Header& header)
1347{
1348 NS_LOG_FUNCTION(this << rtentry << p << header);
1349 NS_LOG_LOGIC("Forwarding logic for node: " << m_node->GetId());
1350
1351 // Drop RFC 3849 packets: 2001:db8::/32
1352 if (header.GetDestination().IsDocumentation())
1353 {
1354 NS_LOG_WARN("Received a packet for 2001:db8::/32 (documentation class). Drop.");
1355 m_dropTrace(header, p, DROP_ROUTE_ERROR, this, 0);
1356 return;
1357 }
1358
1359 // Forwarding
1360 Ipv6Header ipHeader = header;
1361 Ptr<Packet> packet = p->Copy();
1362 ipHeader.SetHopLimit(ipHeader.GetHopLimit() - 1);
1363
1364 if (ipHeader.GetSource().IsLinkLocal())
1365 {
1366 /* no forward for link-local address */
1367 return;
1368 }
1369
1370 if (ipHeader.GetHopLimit() == 0)
1371 {
1372 NS_LOG_WARN("TTL exceeded. Drop.");
1373 m_dropTrace(ipHeader, packet, DROP_TTL_EXPIRED, this, 0);
1374 // Do not reply to multicast IPv6 address
1375 if (!ipHeader.GetDestination().IsMulticast())
1376 {
1377 packet->AddHeader(ipHeader);
1378 GetIcmpv6()->SendErrorTimeExceeded(packet,
1379 ipHeader.GetSource(),
1381 }
1382 return;
1383 }
1384
1385 /* ICMPv6 Redirect */
1386
1387 /* if we forward to a machine on the same network as the source,
1388 * we send him an ICMPv6 redirect message to notify him that a short route
1389 * exists.
1390 */
1391
1392 /* Theoretically we should also check if the redirect target is on the same network
1393 * as the source node. On the other hand, we are sure that the router we're redirecting to
1394 * used a link-local address. As a consequence, they MUST be on the same network, the link-local
1395 * net.
1396 */
1397
1398 if (m_sendIcmpv6Redirect && (rtentry->GetOutputDevice() == idev))
1399 {
1400 NS_LOG_LOGIC("ICMPv6 redirect!");
1402 Address hardwareTarget;
1403 Ipv6Address dst = header.GetDestination();
1404 Ipv6Address src = header.GetSource();
1405 Ipv6Address target = rtentry->GetGateway();
1406 Ptr<Packet> copy = p->Copy();
1407
1408 if (target.IsAny())
1409 {
1410 target = dst;
1411 }
1412
1413 copy->AddHeader(header);
1414 Ipv6Address linkLocal = GetInterface(GetInterfaceForDevice(rtentry->GetOutputDevice()))
1416 .GetAddress();
1417
1418 if (icmpv6->Lookup(target, rtentry->GetOutputDevice(), nullptr, &hardwareTarget))
1419 {
1420 icmpv6->SendRedirection(copy, linkLocal, src, target, dst, hardwareTarget);
1421 }
1422 else
1423 {
1424 icmpv6->SendRedirection(copy, linkLocal, src, target, dst, Address());
1425 }
1426 }
1427 // in case the packet still has a priority tag attached, remove it
1428 SocketPriorityTag priorityTag;
1429 packet->RemovePacketTag(priorityTag);
1430 int32_t interface = GetInterfaceForDevice(rtentry->GetOutputDevice());
1431 m_unicastForwardTrace(ipHeader, packet, interface);
1432 SendRealOut(rtentry, packet, ipHeader);
1433}
1434
1435void
1437 Ptr<Ipv6MulticastRoute> mrtentry,
1439 const Ipv6Header& header)
1440{
1441 NS_LOG_FUNCTION(this << mrtentry << p << header);
1442 NS_LOG_LOGIC("Multicast forwarding logic for node: " << m_node->GetId());
1443
1444 std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap();
1445
1446 for (auto mapIter = ttlMap.begin(); mapIter != ttlMap.end(); mapIter++)
1447 {
1448 uint32_t interfaceId = mapIter->first;
1449 // uint32_t outputTtl = mapIter->second; // Unused for now
1450 Ptr<Packet> packet = p->Copy();
1451 Ipv6Header h = header;
1452 h.SetHopLimit(header.GetHopLimit() - 1);
1453 if (h.GetHopLimit() == 0)
1454 {
1455 NS_LOG_WARN("TTL exceeded. Drop.");
1456 m_dropTrace(header, packet, DROP_TTL_EXPIRED, this, interfaceId);
1457 return;
1458 }
1459 NS_LOG_LOGIC("Forward multicast via interface " << interfaceId);
1460 Ptr<Ipv6Route> rtentry = Create<Ipv6Route>();
1461 rtentry->SetSource(h.GetSource());
1462 rtentry->SetDestination(h.GetDestination());
1463 rtentry->SetGateway(Ipv6Address::GetAny());
1464 rtentry->SetOutputDevice(GetNetDevice(interfaceId));
1465 SendRealOut(rtentry, packet, h);
1466 }
1467}
1468
1469void
1471{
1472 NS_LOG_FUNCTION(this << packet << ip << iif);
1473 Ptr<Packet> p = packet->Copy();
1474 Ptr<IpL4Protocol> protocol = nullptr;
1476 Ptr<Ipv6Extension> ipv6Extension = nullptr;
1477 Ipv6Address src = ip.GetSource();
1478 Ipv6Address dst = ip.GetDestination();
1479 uint8_t nextHeader = ip.GetNextHeader();
1480 uint8_t nextHeaderPosition = 0;
1481 bool isDropped = false;
1482 bool stopProcessing = false;
1483 DropReason dropReason;
1484
1485 // check for a malformed hop-by-hop extension
1486 // this is a common case when forging IPv6 raw packets
1487 if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1488 {
1489 uint8_t buf;
1490 p->CopyData(&buf, 1);
1492 {
1493 NS_LOG_WARN("Double Ipv6Header::IPV6_EXT_HOP_BY_HOP in packet, dropping packet");
1494 return;
1495 }
1496 }
1497
1498 /* process all the extensions found and the layer 4 protocol */
1499 do
1500 {
1501 /* it return 0 for non-extension (i.e. layer 4 protocol) */
1502 ipv6Extension = ipv6ExtensionDemux->GetExtension(nextHeader);
1503
1504 if (ipv6Extension)
1505 {
1506 uint8_t nextHeaderStep = 0;
1507 uint8_t curHeader = nextHeader;
1508 nextHeaderStep = ipv6Extension->Process(p,
1509 nextHeaderPosition,
1510 ip,
1511 dst,
1512 &nextHeader,
1513 stopProcessing,
1514 isDropped,
1515 dropReason);
1516 nextHeaderPosition += nextHeaderStep;
1517
1518 if (isDropped)
1519 {
1520 m_dropTrace(ip, packet, dropReason, this, iif);
1521 }
1522
1523 if (stopProcessing)
1524 {
1525 return;
1526 }
1527 NS_ASSERT_MSG(nextHeaderStep != 0 || curHeader == Ipv6Header::IPV6_EXT_FRAGMENTATION,
1528 "Zero-size IPv6 Option Header, aborting" << *packet);
1529 }
1530 else
1531 {
1532 protocol = GetProtocol(nextHeader, iif);
1533
1534 if (!protocol)
1535 {
1536 NS_LOG_LOGIC("Unknown Next Header. Drop!");
1537
1538 // For ICMPv6 Error packets
1539 Ptr<Packet> malformedPacket = packet->Copy();
1540 malformedPacket->AddHeader(ip);
1541
1542 if (nextHeaderPosition == 0)
1543 {
1544 GetIcmpv6()->SendErrorParameterError(malformedPacket,
1545 dst,
1547 40);
1548 }
1549 else
1550 {
1551 GetIcmpv6()->SendErrorParameterError(malformedPacket,
1552 dst,
1554 ip.GetSerializedSize() +
1555 nextHeaderPosition);
1556 }
1557 m_dropTrace(ip, p, DROP_UNKNOWN_PROTOCOL, this, iif);
1558 break;
1559 }
1560 else
1561 {
1562 p->RemoveAtStart(nextHeaderPosition);
1563 /* protocol->Receive (p, src, dst, incomingInterface); */
1564
1565 // Options have been processed, and the packet is good.
1566 // We need to adjust the IP header fields
1567 Ipv6Header newIpHeader = ip;
1568 newIpHeader.SetNextHeader(nextHeader);
1569 newIpHeader.SetPayloadLength(p->GetSize());
1570
1571 /* L4 protocol */
1572 Ptr<Packet> copy = p->Copy();
1573
1574 m_localDeliverTrace(newIpHeader, p, iif);
1575
1576 IpL4Protocol::RxStatus status =
1577 protocol->Receive(p, newIpHeader, GetInterface(iif));
1578
1579 switch (status)
1580 {
1582 break;
1584 break;
1586 break;
1588 if (newIpHeader.GetDestination().IsMulticast())
1589 {
1590 /* do not rely on multicast address */
1591 break;
1592 }
1593
1594 copy->AddHeader(newIpHeader);
1595 GetIcmpv6()->SendErrorDestinationUnreachable(
1596 copy,
1597 newIpHeader.GetSource(),
1599 }
1600 }
1601 }
1602 } while (ipv6Extension);
1603}
1604
1605void
1607 const Ipv6Header& ipHeader,
1608 Socket::SocketErrno sockErrno)
1609{
1610 NS_LOG_FUNCTION(this << p << ipHeader << sockErrno);
1611 NS_LOG_LOGIC("Route input failure-- dropping packet to " << ipHeader << " with errno "
1612 << sockErrno);
1613
1614 m_dropTrace(ipHeader, p, DROP_ROUTE_ERROR, this, 0);
1615
1616 if (!ipHeader.GetDestination().IsMulticast())
1617 {
1618 Ptr<Packet> packet = p->Copy();
1619 packet->AddHeader(ipHeader);
1620 GetIcmpv6()->SendErrorDestinationUnreachable(packet,
1621 ipHeader.GetSource(),
1623 }
1624}
1625
1628 Ipv6Address dst,
1629 uint8_t protocol,
1630 uint16_t payloadSize,
1631 uint8_t ttl,
1632 uint8_t tclass)
1633{
1634 NS_LOG_FUNCTION(this << src << dst << (uint32_t)protocol << (uint32_t)payloadSize
1635 << (uint32_t)ttl << (uint32_t)tclass);
1636 Ipv6Header hdr;
1637
1638 hdr.SetSource(src);
1639 hdr.SetDestination(dst);
1640 hdr.SetNextHeader(protocol);
1641 hdr.SetPayloadLength(payloadSize);
1642 hdr.SetHopLimit(ttl);
1643 hdr.SetTrafficClass(tclass);
1644 return hdr;
1645}
1646
1647void
1649{
1651 {
1652 return;
1653 }
1654 Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = CreateObject<Ipv6ExtensionDemux>();
1655 ipv6ExtensionDemux->SetNode(m_node);
1656
1657 Ptr<Ipv6ExtensionHopByHop> hopbyhopExtension = CreateObject<Ipv6ExtensionHopByHop>();
1658 hopbyhopExtension->SetNode(m_node);
1659 Ptr<Ipv6ExtensionDestination> destinationExtension = CreateObject<Ipv6ExtensionDestination>();
1660 destinationExtension->SetNode(m_node);
1661 Ptr<Ipv6ExtensionFragment> fragmentExtension = CreateObject<Ipv6ExtensionFragment>();
1662 fragmentExtension->SetNode(m_node);
1663 Ptr<Ipv6ExtensionRouting> routingExtension = CreateObject<Ipv6ExtensionRouting>();
1664 routingExtension->SetNode(m_node);
1665 // Ptr<Ipv6ExtensionESP> espExtension = CreateObject<Ipv6ExtensionESP> ();
1666 // Ptr<Ipv6ExtensionAH> ahExtension = CreateObject<Ipv6ExtensionAH> ();
1667
1668 ipv6ExtensionDemux->Insert(hopbyhopExtension);
1669 ipv6ExtensionDemux->Insert(destinationExtension);
1670 ipv6ExtensionDemux->Insert(fragmentExtension);
1671 ipv6ExtensionDemux->Insert(routingExtension);
1672 // ipv6ExtensionDemux->Insert (espExtension);
1673 // ipv6ExtensionDemux->Insert (ahExtension);
1674
1675 Ptr<Ipv6ExtensionRoutingDemux> routingExtensionDemux =
1676 CreateObject<Ipv6ExtensionRoutingDemux>();
1677 routingExtensionDemux->SetNode(m_node);
1678 Ptr<Ipv6ExtensionLooseRouting> looseRoutingExtension =
1679 CreateObject<Ipv6ExtensionLooseRouting>();
1680 looseRoutingExtension->SetNode(m_node);
1681 routingExtensionDemux->Insert(looseRoutingExtension);
1682
1683 m_node->AggregateObject(routingExtensionDemux);
1684 m_node->AggregateObject(ipv6ExtensionDemux);
1685}
1686
1687void
1689{
1691 {
1692 return;
1693 }
1694 Ptr<Ipv6OptionDemux> ipv6OptionDemux = CreateObject<Ipv6OptionDemux>();
1695 ipv6OptionDemux->SetNode(m_node);
1696
1697 Ptr<Ipv6OptionPad1> pad1Option = CreateObject<Ipv6OptionPad1>();
1698 pad1Option->SetNode(m_node);
1699 Ptr<Ipv6OptionPadn> padnOption = CreateObject<Ipv6OptionPadn>();
1700 padnOption->SetNode(m_node);
1701 Ptr<Ipv6OptionJumbogram> jumbogramOption = CreateObject<Ipv6OptionJumbogram>();
1702 jumbogramOption->SetNode(m_node);
1703 Ptr<Ipv6OptionRouterAlert> routerAlertOption = CreateObject<Ipv6OptionRouterAlert>();
1704 routerAlertOption->SetNode(m_node);
1705
1706 ipv6OptionDemux->Insert(pad1Option);
1707 ipv6OptionDemux->Insert(padnOption);
1708 ipv6OptionDemux->Insert(jumbogramOption);
1709 ipv6OptionDemux->Insert(routerAlertOption);
1710
1711 m_node->AggregateObject(ipv6OptionDemux);
1712}
1713
1714void
1716{
1717 m_dropTrace(ipHeader, p, dropReason, this, 0);
1718}
1719
1720void
1722{
1723 NS_LOG_FUNCTION(address << interface);
1724
1725 if (!address.IsMulticast())
1726 {
1727 NS_LOG_WARN("Not adding a non-multicast address " << address);
1728 return;
1729 }
1730
1731 Ipv6RegisteredMulticastAddressKey_t key = std::make_pair(address, interface);
1732 m_multicastAddresses[key]++;
1733}
1734
1735void
1737{
1738 NS_LOG_FUNCTION(address);
1739
1740 if (!address.IsMulticast())
1741 {
1742 NS_LOG_WARN("Not adding a non-multicast address " << address);
1743 return;
1744 }
1745
1747}
1748
1749void
1751{
1752 NS_LOG_FUNCTION(address << interface);
1753
1754 Ipv6RegisteredMulticastAddressKey_t key = std::make_pair(address, interface);
1755
1756 m_multicastAddresses[key]--;
1757 if (m_multicastAddresses[key] == 0)
1758 {
1759 m_multicastAddresses.erase(key);
1760 }
1761}
1762
1763void
1765{
1766 NS_LOG_FUNCTION(address);
1767
1769 if (m_multicastAddressesNoInterface[address] == 0)
1770 {
1771 m_multicastAddressesNoInterface.erase(address);
1772 }
1773}
1774
1775bool
1777{
1778 NS_LOG_FUNCTION(address << interface);
1779
1780 Ipv6RegisteredMulticastAddressKey_t key = std::make_pair(address, interface);
1781 auto iter = m_multicastAddresses.find(key);
1782
1783 return iter != m_multicastAddresses.end();
1784}
1785
1786bool
1788{
1789 NS_LOG_FUNCTION(address);
1790
1791 auto iter = m_multicastAddressesNoInterface.find(address);
1792
1793 return iter != m_multicastAddressesNoInterface.end();
1794}
1795
1796bool
1798{
1799 if (ipInterfaceIndex >= m_interfaces.size())
1800 {
1801 return false;
1802 }
1803
1804 Ptr<NdiscCache> ndiscCache = m_interfaces[ipInterfaceIndex]->GetNdiscCache();
1805 if (!ndiscCache)
1806 {
1807 return false;
1808 }
1809
1810 NdiscCache::Entry* entry = ndiscCache->Lookup(address);
1811 if (!entry || entry->IsIncomplete())
1812 {
1813 return false;
1814 }
1815
1816 if (entry->IsReachable())
1817 {
1818 entry->UpdateReachableTimer();
1819 }
1820 else if (entry->IsPermanent() || entry->IsAutoGenerated())
1821 {
1822 return true;
1823 }
1824 else if (entry->IsProbe())
1825 {
1826 // we just confirm the entry's MAC address to get the waiting packets (if any)
1827 std::list<NdiscCache::Ipv6PayloadHeaderPair> waiting =
1828 entry->MarkReachable(entry->GetMacAddress());
1829 for (auto it = waiting.begin(); it != waiting.end(); it++)
1830 {
1831 ndiscCache->GetInterface()->Send(it->first, it->second, it->second.GetSource());
1832 }
1833 entry->ClearWaitingPacket();
1834 entry->StartReachableTimer();
1835 }
1836 else // STALE OR DELAY
1837 {
1838 entry->MarkReachable();
1839 entry->StartReachableTimer();
1840 }
1841
1842 return true;
1843}
1844
1845void
1847{
1848 NS_LOG_FUNCTION(this << model);
1849 m_strongEndSystemModel = model;
1850}
1851
1852bool
1854{
1855 NS_LOG_FUNCTION(this);
1857}
1858
1859} /* 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:138
uint32_t GetNDevices() const
Definition: node.cc:162
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:152
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:238
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:449
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:704
-ns3 Test suite for the ns3 wrapper script