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
1105 if (hdr.GetDestination().IsAllNodesMulticast() ||
1106 (hdr.GetDestination().IsAllRoutersMulticast() && ipv6Interface->IsForwarding()))
1107 {
1108 LocalDeliver(packet, hdr, interface);
1109 return;
1110 }
1111 else if (hdr.GetDestination().IsMulticast())
1112 {
1113 bool isSolicited = ipv6Interface->IsSolicitedMulticastAddress(hdr.GetDestination());
1114 bool isRegisteredOnInterface =
1115 IsRegisteredMulticastAddress(hdr.GetDestination(), interface);
1116 bool isRegisteredGlobally = IsRegisteredMulticastAddress(hdr.GetDestination());
1117 if (isSolicited || isRegisteredGlobally || isRegisteredOnInterface)
1118 {
1119 LocalDeliver(packet, hdr, interface);
1120 // do not return, the packet could be handled by a routing protocol
1121 }
1122 }
1123
1124 for (uint32_t j = 0; j < GetNInterfaces(); j++)
1125 {
1126 for (uint32_t i = 0; i < GetNAddresses(j); i++)
1127 {
1128 Ipv6InterfaceAddress iaddr = GetAddress(j, i);
1129 Ipv6Address addr = iaddr.GetAddress();
1130 if (addr == hdr.GetDestination())
1131 {
1132 if (j == interface)
1133 {
1134 NS_LOG_LOGIC("For me (destination " << addr << " match)");
1135 LocalDeliver(packet, hdr, interface);
1136 return;
1137 }
1138 else if (!GetStrongEndSystemModel())
1139 {
1140 NS_LOG_LOGIC("For me (destination "
1141 << addr
1142 << " match) on another interface with Weak End System Model"
1143 << hdr.GetDestination());
1144 LocalDeliver(packet, hdr, interface);
1145 return;
1146 }
1147 else
1148 {
1150 "For me (destination "
1151 << addr
1152 << " match) on another interface with Strong End System Model - discarding"
1153 << hdr.GetDestination());
1154 m_dropTrace(hdr, packet, DROP_NO_ROUTE, this, interface);
1155 return;
1156 }
1157 }
1158 NS_LOG_LOGIC("Address " << addr << " not a match");
1159 }
1160 }
1161
1162 if (!m_routingProtocol->RouteInput(packet, hdr, device, m_ucb, m_mcb, m_lcb, m_ecb))
1163 {
1164 NS_LOG_WARN("No route found for forwarding packet. Drop.");
1165 // Drop trace and ICMPs are courtesy of RouteInputError
1166 }
1167}
1168
1169void
1171 Ptr<Packet> packet,
1172 Ptr<Ipv6> ipv6,
1173 uint32_t interface)
1174{
1175 if (!m_txTrace.IsEmpty())
1176 {
1177 Ptr<Packet> packetCopy = packet->Copy();
1178 packetCopy->AddHeader(ipHeader);
1179 m_txTrace(packetCopy, ipv6, interface);
1180 }
1181}
1182
1183void
1185{
1186 NS_LOG_FUNCTION(this << route << packet << ipHeader);
1187
1188 if (!route)
1189 {
1190 NS_LOG_LOGIC("No route to host, drop!.");
1191 return;
1192 }
1193
1194 Ptr<NetDevice> dev = route->GetOutputDevice();
1195 int32_t interface = GetInterfaceForDevice(dev);
1196 NS_ASSERT(interface >= 0);
1197
1198 Ptr<Ipv6Interface> outInterface = GetInterface(interface);
1199 NS_LOG_LOGIC("Send via NetDevice ifIndex " << dev->GetIfIndex() << " Ipv6InterfaceIndex "
1200 << interface);
1201
1202 // Check packet size
1203 std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair> fragments;
1204
1205 // Check if this is the source of the packet
1206 bool fromMe = false;
1207 for (uint32_t i = 0; i < GetNInterfaces(); i++)
1208 {
1209 for (uint32_t j = 0; j < GetNAddresses(i); j++)
1210 {
1211 if (GetAddress(i, j).GetAddress() == ipHeader.GetSource())
1212 {
1213 fromMe = true;
1214 break;
1215 }
1216 }
1217 }
1218
1219 size_t targetMtu = 0;
1220
1221 // Check if we have a Path MTU stored. If so, use it. Else, use the link MTU.
1222 // Note: PMTU must not be cached in intermediate nodes, and must be checked only by the source
1223 // node
1224 if (fromMe)
1225 {
1226 targetMtu = (size_t)(m_pmtuCache->GetPmtu(ipHeader.GetDestination()));
1227 }
1228 if (targetMtu == 0)
1229 {
1230 targetMtu = dev->GetMtu();
1231 }
1232
1233 if (packet->GetSize() + ipHeader.GetSerializedSize() > targetMtu)
1234 {
1235 // Router => drop
1236 if (!fromMe)
1237 {
1238 Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6();
1239 if (icmpv6)
1240 {
1241 packet->AddHeader(ipHeader);
1242 icmpv6->SendErrorTooBig(packet, ipHeader.GetSource(), dev->GetMtu());
1243 }
1244 return;
1245 }
1246
1247 Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux>();
1248
1249 // To get specific method GetFragments from Ipv6ExtensionFragmentation
1250 Ipv6ExtensionFragment* ipv6Fragment = dynamic_cast<Ipv6ExtensionFragment*>(
1251 PeekPointer(ipv6ExtensionDemux->GetExtension(Ipv6Header::IPV6_EXT_FRAGMENTATION)));
1252 NS_ASSERT(ipv6Fragment != nullptr);
1253 ipv6Fragment->GetFragments(packet, ipHeader, targetMtu, fragments);
1254 }
1255
1256 if (route->GetGateway() != Ipv6Address::GetAny())
1257 {
1258 if (outInterface->IsUp())
1259 {
1260 NS_LOG_LOGIC("Send to gateway " << route->GetGateway());
1261
1262 if (!fragments.empty())
1263 {
1264 std::ostringstream oss;
1265
1266 for (auto it = fragments.begin(); it != fragments.end(); it++)
1267 {
1268 CallTxTrace(it->second, it->first, this, interface);
1269 outInterface->Send(it->first, it->second, route->GetGateway());
1270 }
1271 }
1272 else
1273 {
1274 CallTxTrace(ipHeader, packet, this, interface);
1275 outInterface->Send(packet, ipHeader, route->GetGateway());
1276 }
1277 }
1278 else
1279 {
1280 NS_LOG_LOGIC("Dropping-- outgoing interface is down: " << route->GetGateway());
1281 m_dropTrace(ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
1282 }
1283 }
1284 else
1285 {
1286 if (outInterface->IsUp())
1287 {
1288 NS_LOG_LOGIC("Send to destination " << ipHeader.GetDestination());
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, ipHeader.GetDestination());
1298 }
1299 }
1300 else
1301 {
1302 CallTxTrace(ipHeader, packet, this, interface);
1303 outInterface->Send(packet, ipHeader, ipHeader.GetDestination());
1304 }
1305 }
1306 else
1307 {
1308 NS_LOG_LOGIC("Dropping-- outgoing interface is down: " << ipHeader.GetDestination());
1309 m_dropTrace(ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
1310 }
1311 }
1312}
1313
1314void
1316 Ptr<Ipv6Route> rtentry,
1318 const Ipv6Header& header)
1319{
1320 NS_LOG_FUNCTION(this << rtentry << p << header);
1321 NS_LOG_LOGIC("Forwarding logic for node: " << m_node->GetId());
1322
1323 // Drop RFC 3849 packets: 2001:db8::/32
1324 if (header.GetDestination().IsDocumentation())
1325 {
1326 NS_LOG_WARN("Received a packet for 2001:db8::/32 (documentation class). Drop.");
1327 m_dropTrace(header, p, DROP_ROUTE_ERROR, this, 0);
1328 return;
1329 }
1330
1331 // Forwarding
1332 Ipv6Header ipHeader = header;
1333 Ptr<Packet> packet = p->Copy();
1334 ipHeader.SetHopLimit(ipHeader.GetHopLimit() - 1);
1335
1336 if (ipHeader.GetSource().IsLinkLocal())
1337 {
1338 /* no forward for link-local address */
1339 return;
1340 }
1341
1342 if (ipHeader.GetHopLimit() == 0)
1343 {
1344 NS_LOG_WARN("TTL exceeded. Drop.");
1345 m_dropTrace(ipHeader, packet, DROP_TTL_EXPIRED, this, 0);
1346 // Do not reply to multicast IPv6 address
1347 if (!ipHeader.GetDestination().IsMulticast())
1348 {
1349 packet->AddHeader(ipHeader);
1350 GetIcmpv6()->SendErrorTimeExceeded(packet,
1351 ipHeader.GetSource(),
1353 }
1354 return;
1355 }
1356
1357 /* ICMPv6 Redirect */
1358
1359 /* if we forward to a machine on the same network as the source,
1360 * we send him an ICMPv6 redirect message to notify him that a short route
1361 * exists.
1362 */
1363
1364 /* Theoretically we should also check if the redirect target is on the same network
1365 * as the source node. On the other hand, we are sure that the router we're redirecting to
1366 * used a link-local address. As a consequence, they MUST be on the same network, the link-local
1367 * net.
1368 */
1369
1370 if (m_sendIcmpv6Redirect && (rtentry->GetOutputDevice() == idev))
1371 {
1372 NS_LOG_LOGIC("ICMPv6 redirect!");
1374 Address hardwareTarget;
1375 Ipv6Address dst = header.GetDestination();
1376 Ipv6Address src = header.GetSource();
1377 Ipv6Address target = rtentry->GetGateway();
1378 Ptr<Packet> copy = p->Copy();
1379
1380 if (target.IsAny())
1381 {
1382 target = dst;
1383 }
1384
1385 copy->AddHeader(header);
1386 Ipv6Address linkLocal = GetInterface(GetInterfaceForDevice(rtentry->GetOutputDevice()))
1388 .GetAddress();
1389
1390 if (icmpv6->Lookup(target, rtentry->GetOutputDevice(), nullptr, &hardwareTarget))
1391 {
1392 icmpv6->SendRedirection(copy, linkLocal, src, target, dst, hardwareTarget);
1393 }
1394 else
1395 {
1396 icmpv6->SendRedirection(copy, linkLocal, src, target, dst, Address());
1397 }
1398 }
1399 // in case the packet still has a priority tag attached, remove it
1400 SocketPriorityTag priorityTag;
1401 packet->RemovePacketTag(priorityTag);
1402 int32_t interface = GetInterfaceForDevice(rtentry->GetOutputDevice());
1403 m_unicastForwardTrace(ipHeader, packet, interface);
1404 SendRealOut(rtentry, packet, ipHeader);
1405}
1406
1407void
1409 Ptr<Ipv6MulticastRoute> mrtentry,
1411 const Ipv6Header& header)
1412{
1413 NS_LOG_FUNCTION(this << mrtentry << p << header);
1414 NS_LOG_LOGIC("Multicast forwarding logic for node: " << m_node->GetId());
1415
1416 std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap();
1417
1418 for (auto mapIter = ttlMap.begin(); mapIter != ttlMap.end(); mapIter++)
1419 {
1420 uint32_t interfaceId = mapIter->first;
1421 // uint32_t outputTtl = mapIter->second; // Unused for now
1422 Ptr<Packet> packet = p->Copy();
1423 Ipv6Header h = header;
1424 h.SetHopLimit(header.GetHopLimit() - 1);
1425 if (h.GetHopLimit() == 0)
1426 {
1427 NS_LOG_WARN("TTL exceeded. Drop.");
1428 m_dropTrace(header, packet, DROP_TTL_EXPIRED, this, interfaceId);
1429 return;
1430 }
1431 NS_LOG_LOGIC("Forward multicast via interface " << interfaceId);
1432 Ptr<Ipv6Route> rtentry = Create<Ipv6Route>();
1433 rtentry->SetSource(h.GetSource());
1434 rtentry->SetDestination(h.GetDestination());
1435 rtentry->SetGateway(Ipv6Address::GetAny());
1436 rtentry->SetOutputDevice(GetNetDevice(interfaceId));
1437 SendRealOut(rtentry, packet, h);
1438 }
1439}
1440
1441void
1443{
1444 NS_LOG_FUNCTION(this << packet << ip << iif);
1445 Ptr<Packet> p = packet->Copy();
1446 Ptr<IpL4Protocol> protocol = nullptr;
1448 Ptr<Ipv6Extension> ipv6Extension = nullptr;
1449 Ipv6Address src = ip.GetSource();
1450 Ipv6Address dst = ip.GetDestination();
1451 uint8_t nextHeader = ip.GetNextHeader();
1452 uint8_t nextHeaderPosition = 0;
1453 bool isDropped = false;
1454 bool stopProcessing = false;
1455 DropReason dropReason;
1456
1457 // check for a malformed hop-by-hop extension
1458 // this is a common case when forging IPv6 raw packets
1459 if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1460 {
1461 uint8_t buf;
1462 p->CopyData(&buf, 1);
1464 {
1465 NS_LOG_WARN("Double Ipv6Header::IPV6_EXT_HOP_BY_HOP in packet, dropping packet");
1466 return;
1467 }
1468 }
1469
1470 /* process all the extensions found and the layer 4 protocol */
1471 do
1472 {
1473 /* it return 0 for non-extension (i.e. layer 4 protocol) */
1474 ipv6Extension = ipv6ExtensionDemux->GetExtension(nextHeader);
1475
1476 if (ipv6Extension)
1477 {
1478 uint8_t nextHeaderStep = 0;
1479 uint8_t curHeader = nextHeader;
1480 nextHeaderStep = ipv6Extension->Process(p,
1481 nextHeaderPosition,
1482 ip,
1483 dst,
1484 &nextHeader,
1485 stopProcessing,
1486 isDropped,
1487 dropReason);
1488 nextHeaderPosition += nextHeaderStep;
1489
1490 if (isDropped)
1491 {
1492 m_dropTrace(ip, packet, dropReason, this, iif);
1493 }
1494
1495 if (stopProcessing)
1496 {
1497 return;
1498 }
1499 NS_ASSERT_MSG(nextHeaderStep != 0 || curHeader == Ipv6Header::IPV6_EXT_FRAGMENTATION,
1500 "Zero-size IPv6 Option Header, aborting" << *packet);
1501 }
1502 else
1503 {
1504 protocol = GetProtocol(nextHeader, iif);
1505
1506 if (!protocol)
1507 {
1508 NS_LOG_LOGIC("Unknown Next Header. Drop!");
1509
1510 // For ICMPv6 Error packets
1511 Ptr<Packet> malformedPacket = packet->Copy();
1512 malformedPacket->AddHeader(ip);
1513
1514 if (nextHeaderPosition == 0)
1515 {
1516 GetIcmpv6()->SendErrorParameterError(malformedPacket,
1517 dst,
1519 40);
1520 }
1521 else
1522 {
1523 GetIcmpv6()->SendErrorParameterError(malformedPacket,
1524 dst,
1526 ip.GetSerializedSize() +
1527 nextHeaderPosition);
1528 }
1529 m_dropTrace(ip, p, DROP_UNKNOWN_PROTOCOL, this, iif);
1530 break;
1531 }
1532 else
1533 {
1534 p->RemoveAtStart(nextHeaderPosition);
1535 /* protocol->Receive (p, src, dst, incomingInterface); */
1536
1537 // Options have been processed, and the packet is good.
1538 // We need to adjust the IP header fields
1539 Ipv6Header newIpHeader = ip;
1540 newIpHeader.SetNextHeader(nextHeader);
1541 newIpHeader.SetPayloadLength(p->GetSize());
1542
1543 /* L4 protocol */
1544 Ptr<Packet> copy = p->Copy();
1545
1546 m_localDeliverTrace(newIpHeader, p, iif);
1547
1548 IpL4Protocol::RxStatus status =
1549 protocol->Receive(p, newIpHeader, GetInterface(iif));
1550
1551 switch (status)
1552 {
1556 break;
1558 if (newIpHeader.GetDestination().IsMulticast())
1559 {
1560 /* do not rely on multicast address */
1561 break;
1562 }
1563
1564 copy->AddHeader(newIpHeader);
1565 GetIcmpv6()->SendErrorDestinationUnreachable(
1566 copy,
1567 newIpHeader.GetSource(),
1569 }
1570 }
1571 }
1572 } while (ipv6Extension);
1573}
1574
1575void
1577 const Ipv6Header& ipHeader,
1578 Socket::SocketErrno sockErrno)
1579{
1580 NS_LOG_FUNCTION(this << p << ipHeader << sockErrno);
1581 NS_LOG_LOGIC("Route input failure-- dropping packet to " << ipHeader << " with errno "
1582 << sockErrno);
1583
1584 m_dropTrace(ipHeader, p, DROP_ROUTE_ERROR, this, 0);
1585
1586 if (!ipHeader.GetDestination().IsMulticast())
1587 {
1588 Ptr<Packet> packet = p->Copy();
1589 packet->AddHeader(ipHeader);
1590 GetIcmpv6()->SendErrorDestinationUnreachable(packet,
1591 ipHeader.GetSource(),
1593 }
1594}
1595
1598 Ipv6Address dst,
1599 uint8_t protocol,
1600 uint16_t payloadSize,
1601 uint8_t ttl,
1602 uint8_t tclass)
1603{
1604 NS_LOG_FUNCTION(this << src << dst << (uint32_t)protocol << (uint32_t)payloadSize
1605 << (uint32_t)ttl << (uint32_t)tclass);
1606 Ipv6Header hdr;
1607
1608 hdr.SetSource(src);
1609 hdr.SetDestination(dst);
1610 hdr.SetNextHeader(protocol);
1611 hdr.SetPayloadLength(payloadSize);
1612 hdr.SetHopLimit(ttl);
1613 hdr.SetTrafficClass(tclass);
1614 return hdr;
1615}
1616
1617void
1619{
1621 {
1622 return;
1623 }
1624 Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = CreateObject<Ipv6ExtensionDemux>();
1625 ipv6ExtensionDemux->SetNode(m_node);
1626
1627 Ptr<Ipv6ExtensionHopByHop> hopbyhopExtension = CreateObject<Ipv6ExtensionHopByHop>();
1628 hopbyhopExtension->SetNode(m_node);
1629 Ptr<Ipv6ExtensionDestination> destinationExtension = CreateObject<Ipv6ExtensionDestination>();
1630 destinationExtension->SetNode(m_node);
1631 Ptr<Ipv6ExtensionFragment> fragmentExtension = CreateObject<Ipv6ExtensionFragment>();
1632 fragmentExtension->SetNode(m_node);
1633 Ptr<Ipv6ExtensionRouting> routingExtension = CreateObject<Ipv6ExtensionRouting>();
1634 routingExtension->SetNode(m_node);
1635 // Ptr<Ipv6ExtensionESP> espExtension = CreateObject<Ipv6ExtensionESP> ();
1636 // Ptr<Ipv6ExtensionAH> ahExtension = CreateObject<Ipv6ExtensionAH> ();
1637
1638 ipv6ExtensionDemux->Insert(hopbyhopExtension);
1639 ipv6ExtensionDemux->Insert(destinationExtension);
1640 ipv6ExtensionDemux->Insert(fragmentExtension);
1641 ipv6ExtensionDemux->Insert(routingExtension);
1642 // ipv6ExtensionDemux->Insert (espExtension);
1643 // ipv6ExtensionDemux->Insert (ahExtension);
1644
1645 Ptr<Ipv6ExtensionRoutingDemux> routingExtensionDemux =
1646 CreateObject<Ipv6ExtensionRoutingDemux>();
1647 routingExtensionDemux->SetNode(m_node);
1648 Ptr<Ipv6ExtensionLooseRouting> looseRoutingExtension =
1649 CreateObject<Ipv6ExtensionLooseRouting>();
1650 looseRoutingExtension->SetNode(m_node);
1651 routingExtensionDemux->Insert(looseRoutingExtension);
1652
1653 m_node->AggregateObject(routingExtensionDemux);
1654 m_node->AggregateObject(ipv6ExtensionDemux);
1655}
1656
1657void
1659{
1661 {
1662 return;
1663 }
1664 Ptr<Ipv6OptionDemux> ipv6OptionDemux = CreateObject<Ipv6OptionDemux>();
1665 ipv6OptionDemux->SetNode(m_node);
1666
1667 Ptr<Ipv6OptionPad1> pad1Option = CreateObject<Ipv6OptionPad1>();
1668 pad1Option->SetNode(m_node);
1669 Ptr<Ipv6OptionPadn> padnOption = CreateObject<Ipv6OptionPadn>();
1670 padnOption->SetNode(m_node);
1671 Ptr<Ipv6OptionJumbogram> jumbogramOption = CreateObject<Ipv6OptionJumbogram>();
1672 jumbogramOption->SetNode(m_node);
1673 Ptr<Ipv6OptionRouterAlert> routerAlertOption = CreateObject<Ipv6OptionRouterAlert>();
1674 routerAlertOption->SetNode(m_node);
1675
1676 ipv6OptionDemux->Insert(pad1Option);
1677 ipv6OptionDemux->Insert(padnOption);
1678 ipv6OptionDemux->Insert(jumbogramOption);
1679 ipv6OptionDemux->Insert(routerAlertOption);
1680
1681 m_node->AggregateObject(ipv6OptionDemux);
1682}
1683
1684void
1686{
1687 m_dropTrace(ipHeader, p, dropReason, this, 0);
1688}
1689
1690void
1692{
1693 NS_LOG_FUNCTION(address << interface);
1694
1695 if (!address.IsMulticast())
1696 {
1697 NS_LOG_WARN("Not adding a non-multicast address " << address);
1698 return;
1699 }
1700
1701 Ipv6RegisteredMulticastAddressKey_t key = std::make_pair(address, interface);
1702 m_multicastAddresses[key]++;
1703}
1704
1705void
1707{
1708 NS_LOG_FUNCTION(address);
1709
1710 if (!address.IsMulticast())
1711 {
1712 NS_LOG_WARN("Not adding a non-multicast address " << address);
1713 return;
1714 }
1715
1717}
1718
1719void
1721{
1722 NS_LOG_FUNCTION(address << interface);
1723
1724 Ipv6RegisteredMulticastAddressKey_t key = std::make_pair(address, interface);
1725
1726 m_multicastAddresses[key]--;
1727 if (m_multicastAddresses[key] == 0)
1728 {
1729 m_multicastAddresses.erase(key);
1730 }
1731}
1732
1733void
1735{
1736 NS_LOG_FUNCTION(address);
1737
1739 if (m_multicastAddressesNoInterface[address] == 0)
1740 {
1741 m_multicastAddressesNoInterface.erase(address);
1742 }
1743}
1744
1745bool
1747{
1748 Ipv6RegisteredMulticastAddressKey_t key = std::make_pair(address, interface);
1749 auto iter = m_multicastAddresses.find(key);
1750
1751 return iter != m_multicastAddresses.end();
1752}
1753
1754bool
1756{
1757 auto iter = m_multicastAddressesNoInterface.find(address);
1758
1759 return iter != m_multicastAddressesNoInterface.end();
1760}
1761
1762bool
1764{
1765 if (ipInterfaceIndex >= m_interfaces.size())
1766 {
1767 return false;
1768 }
1769
1770 Ptr<NdiscCache> ndiscCache = m_interfaces[ipInterfaceIndex]->GetNdiscCache();
1771 if (!ndiscCache)
1772 {
1773 return false;
1774 }
1775
1776 NdiscCache::Entry* entry = ndiscCache->Lookup(address);
1777 if (!entry || entry->IsIncomplete())
1778 {
1779 return false;
1780 }
1781
1782 if (entry->IsReachable())
1783 {
1784 entry->UpdateReachableTimer();
1785 }
1786 else if (entry->IsPermanent() || entry->IsAutoGenerated())
1787 {
1788 return true;
1789 }
1790 else if (entry->IsProbe())
1791 {
1792 // we just confirm the entry's MAC address to get the waiting packets (if any)
1793 std::list<NdiscCache::Ipv6PayloadHeaderPair> waiting =
1794 entry->MarkReachable(entry->GetMacAddress());
1795 for (auto it = waiting.begin(); it != waiting.end(); it++)
1796 {
1797 ndiscCache->GetInterface()->Send(it->first, it->second, it->second.GetSource());
1798 }
1799 entry->ClearWaitingPacket();
1800 entry->StartReachableTimer();
1801 }
1802 else // STALE OR DELAY
1803 {
1804 entry->MarkReachable();
1805 entry->StartReachableTimer();
1806 }
1807
1808 return true;
1809}
1810
1811void
1813{
1814 NS_LOG_FUNCTION(this << model);
1815 m_strongEndSystemModel = model;
1816}
1817
1818bool
1820{
1822}
1823
1824} /* namespace ns3 */
a polymophic address class
Definition: address.h:101
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
#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.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
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:700
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
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 > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:81
-ns3 Test suite for the ns3 wrapper script