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