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