A Discrete-Event Network Simulator
API
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"
26#include "ipv6-extension.h"
27#include "ipv6-interface.h"
28#include "ipv6-option-demux.h"
29#include "ipv6-option.h"
32#include "loopback-net-device.h"
33#include "ndisc-cache.h"
34
35#include "ns3/boolean.h"
36#include "ns3/callback.h"
37#include "ns3/ipv6-route.h"
38#include "ns3/ipv6-routing-protocol.h"
39#include "ns3/log.h"
40#include "ns3/mac16-address.h"
41#include "ns3/mac64-address.h"
42#include "ns3/node.h"
43#include "ns3/object-vector.h"
44#include "ns3/trace-source-accessor.h"
45#include "ns3/traffic-control-layer.h"
46#include "ns3/uinteger.h"
47#include "ns3/vector.h"
48
50#define IPV6_MIN_MTU 1280
51
52namespace ns3
53{
54
55NS_LOG_COMPONENT_DEFINE("Ipv6L3Protocol");
56
57NS_OBJECT_ENSURE_REGISTERED(Ipv6L3Protocol);
58
59const uint16_t Ipv6L3Protocol::PROT_NUMBER = 0x86DD;
60
61TypeId
63{
64 static TypeId tid =
65 TypeId("ns3::Ipv6L3Protocol")
66 .SetParent<Ipv6>()
67 .SetGroupName("Internet")
68 .AddConstructor<Ipv6L3Protocol>()
69 .AddAttribute("DefaultTtl",
70 "The TTL value set by default on all "
71 "outgoing packets generated on this node.",
72 UintegerValue(64),
74 MakeUintegerChecker<uint8_t>())
75 .AddAttribute("DefaultTclass",
76 "The TCLASS value set by default on all "
77 "outgoing packets generated on this node.",
80 MakeUintegerChecker<uint8_t>())
81 .AddAttribute("InterfaceList",
82 "The set of IPv6 interfaces associated to this IPv6 stack.",
85 MakeObjectVectorChecker<Ipv6Interface>())
86 .AddAttribute("SendIcmpv6Redirect",
87 "Send the ICMPv6 Redirect when appropriate.",
88 BooleanValue(true),
92 .AddAttribute("StrongEndSystemModel",
93 "Reject packets for an address not configured on the interface they're "
94 "coming from (RFC1222).",
95 BooleanValue(true),
98 .AddTraceSource("Tx",
99 "Send IPv6 packet to outgoing interface.",
101 "ns3::Ipv6L3Protocol::TxRxTracedCallback")
102 .AddTraceSource("Rx",
103 "Receive IPv6 packet from incoming interface.",
105 "ns3::Ipv6L3Protocol::TxRxTracedCallback")
106 .AddTraceSource("Drop",
107 "Drop IPv6 packet",
109 "ns3::Ipv6L3Protocol::DropTracedCallback")
110
111 .AddTraceSource("SendOutgoing",
112 "A newly-generated packet by this node is "
113 "about to be queued for transmission",
115 "ns3::Ipv6L3Protocol::SentTracedCallback")
116 .AddTraceSource("UnicastForward",
117 "A unicast IPv6 packet was received by this node "
118 "and is being forwarded to another node",
120 "ns3::Ipv6L3Protocol::SentTracedCallback")
121 .AddTraceSource("LocalDeliver",
122 "An IPv6 packet was received by/for this node, "
123 "and it is being forward up the stack",
125 "ns3::Ipv6L3Protocol::SentTracedCallback");
126 return tid;
127}
128
130 : m_nInterfaces(0)
131{
132 NS_LOG_FUNCTION(this);
133 m_pmtuCache = CreateObject<Ipv6PmtuCache>();
134
135 Ptr<Ipv6RawSocketFactoryImpl> rawFactoryImpl = CreateObject<Ipv6RawSocketFactoryImpl>();
136 AggregateObject(rawFactoryImpl);
137}
138
140{
141 NS_LOG_FUNCTION(this);
142}
143
144void
146{
147 NS_LOG_FUNCTION(this);
148
149 /* clear protocol and interface list */
150 for (L4List_t::iterator it = m_protocols.begin(); it != m_protocols.end(); ++it)
151 {
152 it->second = nullptr;
153 }
154 m_protocols.clear();
155
156 /* remove interfaces */
157 for (Ipv6InterfaceList::iterator it = m_interfaces.begin(); it != m_interfaces.end(); ++it)
158 {
159 *it = nullptr;
160 }
161 m_interfaces.clear();
163
164 /* remove raw sockets */
165 for (SocketList::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it)
166 {
167 *it = nullptr;
168 }
169 m_sockets.clear();
170
171 /* remove list of prefix */
172 for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
173 {
174 (*it)->StopValidTimer();
175 (*it)->StopPreferredTimer();
176 (*it) = nullptr;
177 }
178 m_prefixes.clear();
179
180 m_node = nullptr;
181 m_routingProtocol = nullptr;
182 m_pmtuCache = nullptr;
184}
185
186void
188{
189 NS_LOG_FUNCTION(this << routingProtocol);
190 m_routingProtocol = routingProtocol;
191 m_routingProtocol->SetIpv6(this);
192}
193
196{
197 NS_LOG_FUNCTION(this);
198 return m_routingProtocol;
199}
200
203{
204 NS_LOG_FUNCTION(this << device);
206
208
209 NS_ASSERT(tc);
210
213 device);
214
215 tc->RegisterProtocolHandler(MakeCallback(&Ipv6L3Protocol::Receive, this),
217 device);
218
219 interface->SetNode(m_node);
220 interface->SetDevice(device);
221 interface->SetTrafficControl(tc);
222 interface->SetForwarding(m_ipForward);
223 return AddIpv6Interface(interface);
224}
225
228{
229 NS_LOG_FUNCTION(this << interface);
230 uint32_t index = m_nInterfaces;
231
232 m_interfaces.push_back(interface);
233 m_reverseInterfacesContainer[interface->GetDevice()] = index;
235 return index;
236}
237
240{
241 NS_LOG_FUNCTION(this << index);
242
243 if (index < m_interfaces.size())
244 {
245 return m_interfaces[index];
246 }
247 return nullptr;
248}
249
252{
253 NS_LOG_FUNCTION(this);
254 return m_nInterfaces;
255}
256
259{
260 NS_LOG_FUNCTION(this << address);
261 int32_t index = 0;
262
263 for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin(); it != m_interfaces.end();
264 it++)
265 {
266 uint32_t j = 0;
267 uint32_t max = (*it)->GetNAddresses();
268
269 for (j = 0; j < max; j++)
270 {
271 if ((*it)->GetAddress(j).GetAddress() == address)
272 {
273 return index;
274 }
275 }
276 index++;
277 }
278 return -1;
279}
280
283{
284 NS_LOG_FUNCTION(this << address << mask);
285 int32_t index = 0;
286
287 for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin(); it != m_interfaces.end();
288 it++)
289 {
290 uint32_t j = 0;
291 for (j = 0; j < (*it)->GetNAddresses(); j++)
292 {
293 if ((*it)->GetAddress(j).GetAddress().CombinePrefix(mask) ==
294 address.CombinePrefix(mask))
295 {
296 return index;
297 }
298 }
299 index++;
300 }
301 return -1;
302}
303
306{
307 NS_LOG_FUNCTION(this << i);
308 return GetInterface(i)->GetDevice();
309}
310
313{
314 NS_LOG_FUNCTION(this << device);
315
316 Ipv6InterfaceReverseContainer::const_iterator iter = m_reverseInterfacesContainer.find(device);
317 if (iter != m_reverseInterfacesContainer.end())
318 {
319 return (*iter).second;
320 }
321
322 return -1;
323}
324
325void
327 Ipv6Address network,
328 Ipv6Prefix mask,
329 uint8_t flags,
330 uint32_t validTime,
331 uint32_t preferredTime,
332 Ipv6Address defaultRouter)
333{
334 NS_LOG_FUNCTION(this << interface << network << mask << (uint32_t)flags << validTime
335 << preferredTime);
337
338 Address addr = GetInterface(interface)->GetDevice()->GetAddress();
339
340 if (!defaultRouter.IsAny())
341 {
342 GetRoutingProtocol()->NotifyAddRoute(Ipv6Address::GetAny(),
343 Ipv6Prefix((uint8_t)0),
344 defaultRouter,
345 interface,
346 network);
347 }
348
349 bool onLink = false;
351 {
352 onLink = true;
353 }
354
355 if (flags & Icmpv6OptionPrefixInformation::AUTADDRCONF) /* auto flag */
356 {
358 address.SetOnLink(onLink);
359
360 /* see if we have already the prefix */
361 for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
362 {
363 if ((*it)->GetInterface() == interface && (*it)->GetPrefix() == network &&
364 (*it)->GetMask() == mask)
365 {
366 (*it)->StopPreferredTimer();
367 (*it)->StopValidTimer();
368 (*it)->StartPreferredTimer();
369 return;
370 }
371 }
372
373 /* no prefix found, add autoconfigured address and the prefix */
374 NS_LOG_INFO("Autoconfigured address is :" << address.GetAddress());
375 AddAddress(interface, address, onLink);
376
378 CreateObject<Ipv6AutoconfiguredPrefix>(m_node,
379 interface,
380 network,
381 mask,
382 preferredTime,
383 validTime,
384 defaultRouter);
385 aPrefix->StartPreferredTimer();
386
387 m_prefixes.push_back(aPrefix);
388 }
389
390 if (onLink) /* on-link flag */
391 {
392 /* add default router
393 * if a previous default route exists, the new ones is simply added
394 */
395 m_routingProtocol->NotifyAddRoute(network, mask, Ipv6Address::GetAny(), interface);
396 }
397}
398
399void
401 Ipv6Address network,
402 Ipv6Prefix mask,
403 Ipv6Address defaultRouter)
404{
405 NS_LOG_FUNCTION(this << interface << network << mask);
406 Ptr<Ipv6Interface> iface = GetInterface(interface);
407 Address addr = iface->GetDevice()->GetAddress();
408
409 Ipv6Address addressToFind = Ipv6Address::MakeAutoconfiguredAddress(addr, network);
410
411 for (uint32_t i = 0; i < iface->GetNAddresses(); i++)
412 {
413 if (iface->GetAddress(i).GetAddress() == addressToFind)
414 {
415 RemoveAddress(interface, i);
416 break;
417 }
418 }
419
420 /* remove from list of autoconfigured address */
421 for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
422 {
423 if ((*it)->GetInterface() == interface && (*it)->GetPrefix() == network &&
424 (*it)->GetMask() == mask)
425 {
426 *it = nullptr;
427 m_prefixes.erase(it);
428 break;
429 }
430 }
431
432 GetRoutingProtocol()->NotifyRemoveRoute(Ipv6Address::GetAny(),
433 Ipv6Prefix((uint8_t)0),
434 defaultRouter,
435 interface,
436 network);
437}
438
439bool
441{
442 NS_LOG_FUNCTION(this << i << address);
443 Ptr<Ipv6Interface> interface = GetInterface(i);
444 address.SetOnLink(addOnLinkRoute);
445 bool ret = interface->AddAddress(address);
446
448 {
449 m_routingProtocol->NotifyAddAddress(i, address);
450 }
451
452 if (addOnLinkRoute)
453 {
454 Ipv6Address networkAddress = address.GetAddress().CombinePrefix(address.GetPrefix());
455 Ipv6Prefix networkMask = address.GetPrefix();
456 GetRoutingProtocol()->NotifyAddRoute(networkAddress,
457 networkMask,
459 i);
460 }
461 return ret;
462}
463
466{
467 NS_LOG_FUNCTION(this << i);
468 Ptr<Ipv6Interface> interface = GetInterface(i);
469 return interface->GetNAddresses();
470}
471
474{
475 NS_LOG_FUNCTION(this << i << addressIndex);
476 Ptr<Ipv6Interface> interface = GetInterface(i);
477 return interface->GetAddress(addressIndex);
478}
479
480bool
482{
483 NS_LOG_FUNCTION(this << i << addressIndex);
484 Ptr<Ipv6Interface> interface = GetInterface(i);
485 Ipv6InterfaceAddress address = interface->RemoveAddress(addressIndex);
486
488 {
490 {
491 m_routingProtocol->NotifyRemoveAddress(i, address);
492 }
493 return true;
494 }
495 return false;
496}
497
498bool
500{
501 NS_LOG_FUNCTION(this << i << address);
502
504 {
505 NS_LOG_WARN("Cannot remove loopback address.");
506 return false;
507 }
508 Ptr<Ipv6Interface> interface = GetInterface(i);
509 Ipv6InterfaceAddress ifAddr = interface->RemoveAddress(address);
510 if (ifAddr != Ipv6InterfaceAddress())
511 {
513 {
514 m_routingProtocol->NotifyRemoveAddress(i, ifAddr);
515 }
516 return true;
517 }
518 return false;
519}
520
521void
523{
524 NS_LOG_FUNCTION(this << i << metric);
525 Ptr<Ipv6Interface> interface = GetInterface(i);
526 interface->SetMetric(metric);
527}
528
529uint16_t
531{
532 NS_LOG_FUNCTION(this << i);
533 Ptr<Ipv6Interface> interface = GetInterface(i);
534 return interface->GetMetric();
535}
536
537uint16_t
539{
540 NS_LOG_FUNCTION(this << i);
541
542 // RFC 1981, if PMTU is disabled, return the minimum MTU
543 if (!m_mtuDiscover)
544 {
545 return IPV6_MIN_MTU;
546 }
547
548 Ptr<Ipv6Interface> interface = GetInterface(i);
549 return interface->GetDevice()->GetMtu();
550}
551
552void
554{
555 NS_LOG_FUNCTION(this << dst << int(pmtu));
556 m_pmtuCache->SetPmtu(dst, pmtu);
557}
558
559bool
561{
562 NS_LOG_FUNCTION(this << i);
563 Ptr<Ipv6Interface> interface = GetInterface(i);
564 return interface->IsUp();
565}
566
567void
569{
570 NS_LOG_FUNCTION(this << i);
571 Ptr<Ipv6Interface> interface = GetInterface(i);
572
573 // RFC 2460, Section 5, pg. 24:
574 // IPv6 requires that every link in the internet have an MTU of 1280
575 // octets or greater. On any link that cannot convey a 1280-octet
576 // packet in one piece, link-specific fragmentation and reassembly must
577 // be provided at a layer below IPv6.
578 if (interface->GetDevice()->GetMtu() >= 1280)
579 {
580 interface->SetUp();
581
583 {
584 m_routingProtocol->NotifyInterfaceUp(i);
585 }
586 }
587 else
588 {
589 NS_LOG_LOGIC("Interface " << int(i)
590 << " is set to be down for IPv6. Reason: not respecting minimum "
591 "IPv6 MTU (1280 octets)");
592 }
593}
594
595void
597{
598 NS_LOG_FUNCTION(this << i);
599 Ptr<Ipv6Interface> interface = GetInterface(i);
600
601 interface->SetDown();
602
604 {
605 m_routingProtocol->NotifyInterfaceDown(i);
606 }
607}
608
609void
611{
612 NS_LOG_FUNCTION(this);
614 Ptr<LoopbackNetDevice> device = nullptr;
615 uint32_t i = 0;
616
617 /* see if we have already an loopback NetDevice */
618 for (i = 0; i < m_node->GetNDevices(); i++)
619 {
620 if ((device = DynamicCast<LoopbackNetDevice>(m_node->GetDevice(i))))
621 {
622 break;
623 }
624 }
625
626 if (!device)
627 {
628 device = CreateObject<LoopbackNetDevice>();
629 m_node->AddDevice(device);
630 }
631
632 interface->SetDevice(device);
633 interface->SetNode(m_node);
634 Ipv6InterfaceAddress ifaceAddr =
636 interface->AddAddress(ifaceAddr);
637 uint32_t index = AddIpv6Interface(interface);
638 Ptr<Node> node = GetObject<Node>();
641 device);
642 interface->SetUp();
643
645 {
646 m_routingProtocol->NotifyInterfaceUp(index);
647 }
648}
649
650bool
652{
653 NS_LOG_FUNCTION(this << i);
654 Ptr<Ipv6Interface> interface = GetInterface(i);
655
656 NS_LOG_LOGIC("Forwarding state: " << interface->IsForwarding());
657 return interface->IsForwarding();
658}
659
660void
662{
663 NS_LOG_FUNCTION(this << i << val);
664 Ptr<Ipv6Interface> interface = GetInterface(i);
665 interface->SetForwarding(val);
666}
667
670{
671 NS_LOG_FUNCTION(this << interface << dest);
672 Ipv6Address ret;
673
674 if (dest.IsLocalhost())
675 {
677 }
678
679 if (dest.IsLinkLocal() || dest.IsLinkLocalMulticast())
680 {
681 for (uint32_t i = 0; i < GetNAddresses(interface); i++)
682 {
683 Ipv6InterfaceAddress test = GetAddress(interface, i);
684 if (test.GetScope() == Ipv6InterfaceAddress::LINKLOCAL)
685 {
686 return test.GetAddress();
687 }
688 }
689 NS_ASSERT_MSG(false, "No link-local address found on interface " << interface);
690 }
691
692 for (uint32_t i = 0; i < GetNAddresses(interface); i++)
693 {
694 Ipv6InterfaceAddress test = GetAddress(interface, i);
695
696 if (test.GetScope() == Ipv6InterfaceAddress::GLOBAL)
697 {
698 if (test.IsInSameSubnet(dest))
699 {
700 return test.GetAddress();
701 }
702 else
703 {
704 ret = test.GetAddress();
705 }
706 }
707 }
708
709 // no specific match found. Use a global address (any useful is fine).
710 NS_ASSERT_MSG(!ret.IsAny(),
711 "Could not find any address for " << dest << " on interface " << interface);
712 return ret;
713}
714
715void
717{
718 NS_LOG_FUNCTION(this << forward);
719 m_ipForward = forward;
720
721 for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin(); it != m_interfaces.end();
722 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 L4List_t::iterator 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 L4List_t::iterator 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 L4ListKey_t key;
868 L4List_t::const_iterator i;
869 if (interfaceIndex >= 0)
870 {
871 // try the interface-specific protocol.
872 key = std::make_pair(protocolNumber, interfaceIndex);
873 i = m_protocols.find(key);
874 if (i != m_protocols.end())
875 {
876 return i->second;
877 }
878 }
879 // try the generic protocol.
880 key = std::make_pair(protocolNumber, -1);
881 i = m_protocols.find(key);
882 if (i != m_protocols.end())
883 {
884 return i->second;
885 }
886
887 return nullptr;
888}
889
892{
893 NS_LOG_FUNCTION(this);
894 Ptr<Ipv6RawSocketImpl> sock = CreateObject<Ipv6RawSocketImpl>();
895 sock->SetNode(m_node);
896 m_sockets.push_back(sock);
897 return sock;
898}
899
900void
902{
903 NS_LOG_FUNCTION(this << socket);
904
905 for (SocketList::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it)
906 {
907 if ((*it) == socket)
908 {
909 m_sockets.erase(it);
910 return;
911 }
912 }
913}
914
917{
918 NS_LOG_FUNCTION(this);
920
921 if (protocol)
922 {
923 return protocol->GetObject<Icmpv6L4Protocol>();
924 }
925 else
926 {
927 return nullptr;
928 }
929}
930
931void
933{
934 NS_LOG_FUNCTION(this << ttl);
935 m_defaultTtl = ttl;
936}
937
938void
940{
941 NS_LOG_FUNCTION(this << tclass);
942 m_defaultTclass = tclass;
943}
944
945void
947 Ipv6Address source,
948 Ipv6Address destination,
949 uint8_t protocol,
950 Ptr<Ipv6Route> route)
951{
952 NS_LOG_FUNCTION(this << packet << source << destination << (uint32_t)protocol << route);
953 Ipv6Header hdr;
954 uint8_t ttl = m_defaultTtl;
956 bool found = packet->RemovePacketTag(tag);
957
958 if (found)
959 {
960 ttl = tag.GetHopLimit();
961 }
962
963 SocketIpv6TclassTag tclassTag;
964 uint8_t tclass = m_defaultTclass;
965 found = packet->RemovePacketTag(tclassTag);
966
967 if (found)
968 {
969 tclass = tclassTag.GetTclass();
970 }
971
972 /* Handle 3 cases:
973 * 1) Packet is passed in with a route entry
974 * 2) Packet is passed in with a route entry but route->GetGateway is not set (e.g., same
975 * network) 3) route is NULL (e.g., a raw socket call or ICMPv6)
976 */
977
978 /* 1) */
979 if (route && route->GetGateway() != Ipv6Address::GetZero())
980 {
981 NS_LOG_LOGIC("Ipv6L3Protocol::Send case 1: passed in with a route");
982 hdr = BuildHeader(source, destination, protocol, packet->GetSize(), ttl, tclass);
983 int32_t interface = GetInterfaceForDevice(route->GetOutputDevice());
984 m_sendOutgoingTrace(hdr, packet, interface);
985 SendRealOut(route, packet, hdr);
986 return;
987 }
988
989 /* 2) */
990 if (route && route->GetGateway() == Ipv6Address::GetZero())
991 {
992 NS_LOG_LOGIC("Ipv6L3Protocol::Send case 2: probably sent to machine on same IPv6 network");
993 hdr = BuildHeader(source, destination, protocol, packet->GetSize(), ttl, tclass);
994 int32_t interface = GetInterfaceForDevice(route->GetOutputDevice());
995 m_sendOutgoingTrace(hdr, packet, interface);
996 SendRealOut(route, packet, hdr);
997 return;
998 }
999
1000 /* 3) */
1001 NS_LOG_LOGIC("Ipv6L3Protocol::Send case 3: passed in with no route " << destination);
1003 Ptr<NetDevice> oif(nullptr);
1004 Ptr<Ipv6Route> newRoute = nullptr;
1005
1006 hdr = BuildHeader(source, destination, protocol, packet->GetSize(), ttl, tclass);
1007
1008 // for link-local traffic, we need to determine the interface
1009 if (source.IsLinkLocal() || destination.IsLinkLocal() || destination.IsLinkLocalMulticast())
1010 {
1011 int32_t index = GetInterfaceForAddress(source);
1012 NS_ASSERT_MSG(index >= 0,
1013 "Can not find an outgoing interface for a packet with src "
1014 << source << " and dst " << destination);
1015 oif = GetNetDevice(index);
1016 }
1017
1018 newRoute = m_routingProtocol->RouteOutput(packet, hdr, oif, err);
1019
1020 if (newRoute)
1021 {
1022 int32_t interface = GetInterfaceForDevice(newRoute->GetOutputDevice());
1023 m_sendOutgoingTrace(hdr, packet, interface);
1024 SendRealOut(newRoute, packet, hdr);
1025 }
1026 else
1027 {
1028 NS_LOG_WARN("No route to host, drop!");
1029 m_dropTrace(hdr, packet, DROP_NO_ROUTE, this, GetInterfaceForDevice(oif));
1030 }
1031}
1032
1033void
1036 uint16_t protocol,
1037 const Address& from,
1038 const Address& to,
1039 NetDevice::PacketType packetType)
1040{
1041 NS_LOG_FUNCTION(this << device << p << protocol << from << to << packetType);
1042 NS_LOG_LOGIC("Packet from " << from << " received on node " << m_node->GetId());
1043
1045 "Received a packet from an interface that is not known to IPv6");
1046 uint32_t interface = GetInterfaceForDevice(device);
1047
1048 Ptr<Ipv6Interface> ipv6Interface = m_interfaces[interface];
1049 Ptr<Packet> packet = p->Copy();
1050
1051 if (ipv6Interface->IsUp())
1052 {
1053 m_rxTrace(packet, this, interface);
1054 }
1055 else
1056 {
1057 NS_LOG_LOGIC("Dropping received packet-- interface is down");
1058 Ipv6Header hdr;
1059 packet->RemoveHeader(hdr);
1060 m_dropTrace(hdr, packet, DROP_INTERFACE_DOWN, this, interface);
1061 return;
1062 }
1063
1064 Ipv6Header hdr;
1065 packet->RemoveHeader(hdr);
1066
1067 // Trim any residual frame padding from underlying devices
1068 if (hdr.GetPayloadLength() < packet->GetSize())
1069 {
1070 packet->RemoveAtEnd(packet->GetSize() - hdr.GetPayloadLength());
1071 }
1072
1073 // the packet is valid, we update the NDISC cache entry (if present)
1074 Ptr<NdiscCache> ndiscCache = ipv6Interface->GetNdiscCache();
1075 if (ndiscCache)
1076 {
1077 // case one, it's a a direct routing.
1078 NdiscCache::Entry* entry = ndiscCache->Lookup(hdr.GetSource());
1079 if (entry)
1080 {
1081 entry->UpdateReachableTimer();
1082 }
1083 else
1084 {
1085 // It's not in the direct routing, so it's the router, and it could have multiple IP
1086 // addresses. In doubt, update all of them. Note: it's a confirmed behavior for Linux
1087 // routers.
1088 std::list<NdiscCache::Entry*> entryList = ndiscCache->LookupInverse(from);
1089 std::list<NdiscCache::Entry*>::iterator iter;
1090 for (iter = entryList.begin(); iter != entryList.end(); iter++)
1091 {
1092 (*iter)->UpdateReachableTimer();
1093 }
1094 }
1095 }
1096
1097 /* forward up to IPv6 raw sockets */
1098 for (SocketList::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it)
1099 {
1100 Ptr<Ipv6RawSocketImpl> socket = *it;
1101 socket->ForwardUp(packet, hdr, device);
1102 }
1103
1105 Ptr<Ipv6Extension> ipv6Extension = nullptr;
1106 uint8_t nextHeader = hdr.GetNextHeader();
1107 bool stopProcessing = false;
1108 bool isDropped = false;
1109 DropReason dropReason;
1110
1111 if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1112 {
1113 ipv6Extension = ipv6ExtensionDemux->GetExtension(nextHeader);
1114
1115 if (ipv6Extension)
1116 {
1117 ipv6Extension->Process(packet,
1118 0,
1119 hdr,
1120 hdr.GetDestination(),
1121 (uint8_t*)nullptr,
1122 stopProcessing,
1123 isDropped,
1124 dropReason);
1125 }
1126
1127 if (isDropped)
1128 {
1129 m_dropTrace(hdr, packet, dropReason, this, interface);
1130 }
1131
1132 if (stopProcessing)
1133 {
1134 return;
1135 }
1136 }
1137
1139 {
1140 LocalDeliver(packet, hdr, interface);
1141 return;
1142 }
1143 else if (hdr.GetDestination().IsAllRoutersMulticast() && ipv6Interface->IsForwarding())
1144 {
1145 LocalDeliver(packet, hdr, interface);
1146 return;
1147 }
1148 else if (hdr.GetDestination().IsMulticast())
1149 {
1150 bool isSolicited = ipv6Interface->IsSolicitedMulticastAddress(hdr.GetDestination());
1151 bool isRegisteredOnInterface =
1153 bool isRegisteredGlobally = IsRegisteredMulticastAddress(hdr.GetDestination());
1154 if (isSolicited || isRegisteredGlobally || isRegisteredOnInterface)
1155 {
1156 LocalDeliver(packet, hdr, interface);
1157 // do not return, the packet could be handled by a routing protocol
1158 }
1159 }
1160
1161 for (uint32_t j = 0; j < GetNInterfaces(); j++)
1162 {
1163 if (j == interface || !m_strongEndSystemModel)
1164 {
1165 for (uint32_t i = 0; i < GetNAddresses(j); i++)
1166 {
1167 Ipv6InterfaceAddress iaddr = GetAddress(j, i);
1168 Ipv6Address addr = iaddr.GetAddress();
1169 if (addr == hdr.GetDestination())
1170 {
1171 if (j == interface)
1172 {
1173 NS_LOG_LOGIC("For me (destination " << addr << " match)");
1174 }
1175 else
1176 {
1177 NS_LOG_LOGIC("For me (destination " << addr
1178 << " match) on another interface "
1179 << hdr.GetDestination());
1180 }
1181 LocalDeliver(packet, hdr, interface);
1182 return;
1183 }
1184 NS_LOG_LOGIC("Address " << addr << " not a match");
1185 }
1186 }
1187 }
1188
1189 if (!m_routingProtocol->RouteInput(packet,
1190 hdr,
1191 device,
1196 {
1197 NS_LOG_WARN("No route found for forwarding packet. Drop.");
1198 // Drop trace and ICMPs are courtesy of RouteInputError
1199 }
1200}
1201
1202void
1204 Ptr<Packet> packet,
1205 Ptr<Ipv6> ipv6,
1206 uint32_t interface)
1207{
1208 if (!m_txTrace.IsEmpty())
1209 {
1210 Ptr<Packet> packetCopy = packet->Copy();
1211 packetCopy->AddHeader(ipHeader);
1212 m_txTrace(packetCopy, ipv6, interface);
1213 }
1214}
1215
1216void
1218{
1219 NS_LOG_FUNCTION(this << route << packet << ipHeader);
1220
1221 if (!route)
1222 {
1223 NS_LOG_LOGIC("No route to host, drop!.");
1224 return;
1225 }
1226
1227 Ptr<NetDevice> dev = route->GetOutputDevice();
1228 int32_t interface = GetInterfaceForDevice(dev);
1229 NS_ASSERT(interface >= 0);
1230
1231 Ptr<Ipv6Interface> outInterface = GetInterface(interface);
1232 NS_LOG_LOGIC("Send via NetDevice ifIndex " << dev->GetIfIndex() << " Ipv6InterfaceIndex "
1233 << interface);
1234
1235 // Check packet size
1236 std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair> fragments;
1237
1238 // Check if this is the source of the packet
1239 bool fromMe = false;
1240 for (uint32_t i = 0; i < GetNInterfaces(); i++)
1241 {
1242 for (uint32_t j = 0; j < GetNAddresses(i); j++)
1243 {
1244 if (GetAddress(i, j).GetAddress() == ipHeader.GetSource())
1245 {
1246 fromMe = true;
1247 break;
1248 }
1249 }
1250 }
1251
1252 size_t targetMtu = 0;
1253
1254 // Check if we have a Path MTU stored. If so, use it. Else, use the link MTU.
1255 // Note: PMTU must not be cached in intermediate nodes, and must be checked only by the source
1256 // node
1257 if (fromMe)
1258 {
1259 targetMtu = (size_t)(m_pmtuCache->GetPmtu(ipHeader.GetDestination()));
1260 }
1261 if (targetMtu == 0)
1262 {
1263 targetMtu = dev->GetMtu();
1264 }
1265
1266 if (packet->GetSize() + ipHeader.GetSerializedSize() > targetMtu)
1267 {
1268 // Router => drop
1269 if (!fromMe)
1270 {
1272 if (icmpv6)
1273 {
1274 packet->AddHeader(ipHeader);
1275 icmpv6->SendErrorTooBig(packet, ipHeader.GetSource(), dev->GetMtu());
1276 }
1277 return;
1278 }
1279
1281
1282 // To get specific method GetFragments from Ipv6ExtensionFragmentation
1283 Ipv6ExtensionFragment* ipv6Fragment = dynamic_cast<Ipv6ExtensionFragment*>(
1284 PeekPointer(ipv6ExtensionDemux->GetExtension(Ipv6Header::IPV6_EXT_FRAGMENTATION)));
1285 NS_ASSERT(ipv6Fragment != nullptr);
1286 ipv6Fragment->GetFragments(packet, ipHeader, targetMtu, fragments);
1287 }
1288
1289 if (route->GetGateway() != Ipv6Address::GetAny())
1290 {
1291 if (outInterface->IsUp())
1292 {
1293 NS_LOG_LOGIC("Send to gateway " << route->GetGateway());
1294
1295 if (fragments.size() != 0)
1296 {
1297 std::ostringstream oss;
1298
1299 for (std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair>::const_iterator it =
1300 fragments.begin();
1301 it != fragments.end();
1302 it++)
1303 {
1304 CallTxTrace(it->second, it->first, this, interface);
1305 outInterface->Send(it->first, it->second, route->GetGateway());
1306 }
1307 }
1308 else
1309 {
1310 CallTxTrace(ipHeader, packet, this, interface);
1311 outInterface->Send(packet, ipHeader, route->GetGateway());
1312 }
1313 }
1314 else
1315 {
1316 NS_LOG_LOGIC("Dropping-- outgoing interface is down: " << route->GetGateway());
1317 m_dropTrace(ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
1318 }
1319 }
1320 else
1321 {
1322 if (outInterface->IsUp())
1323 {
1324 NS_LOG_LOGIC("Send to destination " << ipHeader.GetDestination());
1325
1326 if (fragments.size() != 0)
1327 {
1328 std::ostringstream oss;
1329
1330 for (std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair>::const_iterator it =
1331 fragments.begin();
1332 it != fragments.end();
1333 it++)
1334 {
1335 CallTxTrace(it->second, it->first, this, interface);
1336 outInterface->Send(it->first, it->second, ipHeader.GetDestination());
1337 }
1338 }
1339 else
1340 {
1341 CallTxTrace(ipHeader, packet, this, interface);
1342 outInterface->Send(packet, ipHeader, ipHeader.GetDestination());
1343 }
1344 }
1345 else
1346 {
1347 NS_LOG_LOGIC("Dropping-- outgoing interface is down: " << ipHeader.GetDestination());
1348 m_dropTrace(ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
1349 }
1350 }
1351}
1352
1353void
1355 Ptr<Ipv6Route> rtentry,
1357 const Ipv6Header& header)
1358{
1359 NS_LOG_FUNCTION(this << rtentry << p << header);
1360 NS_LOG_LOGIC("Forwarding logic for node: " << m_node->GetId());
1361
1362 // Drop RFC 3849 packets: 2001:db8::/32
1363 if (header.GetDestination().IsDocumentation())
1364 {
1365 NS_LOG_WARN("Received a packet for 2001:db8::/32 (documentation class). Drop.");
1366 m_dropTrace(header, p, DROP_ROUTE_ERROR, this, 0);
1367 return;
1368 }
1369
1370 // Forwarding
1371 Ipv6Header ipHeader = header;
1372 Ptr<Packet> packet = p->Copy();
1373 ipHeader.SetHopLimit(ipHeader.GetHopLimit() - 1);
1374
1375 if (ipHeader.GetSource().IsLinkLocal())
1376 {
1377 /* no forward for link-local address */
1378 return;
1379 }
1380
1381 if (ipHeader.GetHopLimit() == 0)
1382 {
1383 NS_LOG_WARN("TTL exceeded. Drop.");
1384 m_dropTrace(ipHeader, packet, DROP_TTL_EXPIRED, this, 0);
1385 // Do not reply to multicast IPv6 address
1386 if (ipHeader.GetDestination().IsMulticast() == false)
1387 {
1388 packet->AddHeader(ipHeader);
1389 GetIcmpv6()->SendErrorTimeExceeded(packet,
1390 ipHeader.GetSource(),
1392 }
1393 return;
1394 }
1395
1396 /* ICMPv6 Redirect */
1397
1398 /* if we forward to a machine on the same network as the source,
1399 * we send him an ICMPv6 redirect message to notify him that a short route
1400 * exists.
1401 */
1402
1403 /* Theoretically we should also check if the redirect target is on the same network
1404 * as the source node. On the other hand, we are sure that the router we're redirecting to
1405 * used a link-local address. As a consequence, they MUST be on the same network, the link-local
1406 * net.
1407 */
1408
1409 if (m_sendIcmpv6Redirect && (rtentry->GetOutputDevice() == idev))
1410 {
1411 NS_LOG_LOGIC("ICMPv6 redirect!");
1413 Address hardwareTarget;
1414 Ipv6Address dst = header.GetDestination();
1415 Ipv6Address src = header.GetSource();
1416 Ipv6Address target = rtentry->GetGateway();
1417 Ptr<Packet> copy = p->Copy();
1418
1419 if (target.IsAny())
1420 {
1421 target = dst;
1422 }
1423
1424 copy->AddHeader(header);
1425 Ipv6Address linkLocal = GetInterface(GetInterfaceForDevice(rtentry->GetOutputDevice()))
1427 .GetAddress();
1428
1429 if (icmpv6->Lookup(target, rtentry->GetOutputDevice(), nullptr, &hardwareTarget))
1430 {
1431 icmpv6->SendRedirection(copy, linkLocal, src, target, dst, hardwareTarget);
1432 }
1433 else
1434 {
1435 icmpv6->SendRedirection(copy, linkLocal, src, target, dst, Address());
1436 }
1437 }
1438 // in case the packet still has a priority tag attached, remove it
1439 SocketPriorityTag priorityTag;
1440 packet->RemovePacketTag(priorityTag);
1441 int32_t interface = GetInterfaceForDevice(rtentry->GetOutputDevice());
1442 m_unicastForwardTrace(ipHeader, packet, interface);
1443 SendRealOut(rtentry, packet, ipHeader);
1444}
1445
1446void
1448 Ptr<Ipv6MulticastRoute> mrtentry,
1450 const Ipv6Header& header)
1451{
1452 NS_LOG_FUNCTION(this << mrtentry << p << header);
1453 NS_LOG_LOGIC("Multicast forwarding logic for node: " << m_node->GetId());
1454
1455 std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap();
1456 std::map<uint32_t, uint32_t>::iterator mapIter;
1457
1458 for (mapIter = ttlMap.begin(); mapIter != ttlMap.end(); mapIter++)
1459 {
1460 uint32_t interfaceId = mapIter->first;
1461 // uint32_t outputTtl = mapIter->second; // Unused for now
1462 Ptr<Packet> packet = p->Copy();
1463 Ipv6Header h = header;
1464 h.SetHopLimit(header.GetHopLimit() - 1);
1465 if (h.GetHopLimit() == 0)
1466 {
1467 NS_LOG_WARN("TTL exceeded. Drop.");
1468 m_dropTrace(header, packet, DROP_TTL_EXPIRED, this, interfaceId);
1469 return;
1470 }
1471 NS_LOG_LOGIC("Forward multicast via interface " << interfaceId);
1472 Ptr<Ipv6Route> rtentry = Create<Ipv6Route>();
1473 rtentry->SetSource(h.GetSource());
1474 rtentry->SetDestination(h.GetDestination());
1475 rtentry->SetGateway(Ipv6Address::GetAny());
1476 rtentry->SetOutputDevice(GetNetDevice(interfaceId));
1477 SendRealOut(rtentry, packet, h);
1478 }
1479}
1480
1481void
1483{
1484 NS_LOG_FUNCTION(this << packet << ip << iif);
1485 Ptr<Packet> p = packet->Copy();
1486 Ptr<IpL4Protocol> protocol = nullptr;
1488 Ptr<Ipv6Extension> ipv6Extension = nullptr;
1489 Ipv6Address src = ip.GetSource();
1490 Ipv6Address dst = ip.GetDestination();
1491 uint8_t nextHeader = ip.GetNextHeader();
1492 uint8_t nextHeaderPosition = 0;
1493 bool isDropped = false;
1494 bool stopProcessing = false;
1495 DropReason dropReason;
1496
1497 // check for a malformed hop-by-hop extension
1498 // this is a common case when forging IPv6 raw packets
1499 if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1500 {
1501 uint8_t buf;
1502 p->CopyData(&buf, 1);
1504 {
1505 NS_LOG_WARN("Double Ipv6Header::IPV6_EXT_HOP_BY_HOP in packet, dropping packet");
1506 return;
1507 }
1508 }
1509
1510 /* process all the extensions found and the layer 4 protocol */
1511 do
1512 {
1513 /* it return 0 for non-extension (i.e. layer 4 protocol) */
1514 ipv6Extension = ipv6ExtensionDemux->GetExtension(nextHeader);
1515
1516 if (ipv6Extension)
1517 {
1518 uint8_t nextHeaderStep = 0;
1519 uint8_t curHeader = nextHeader;
1520 nextHeaderStep = ipv6Extension->Process(p,
1521 nextHeaderPosition,
1522 ip,
1523 dst,
1524 &nextHeader,
1525 stopProcessing,
1526 isDropped,
1527 dropReason);
1528 nextHeaderPosition += nextHeaderStep;
1529
1530 if (isDropped)
1531 {
1532 m_dropTrace(ip, packet, dropReason, this, iif);
1533 }
1534
1535 if (stopProcessing)
1536 {
1537 return;
1538 }
1539 NS_ASSERT_MSG(nextHeaderStep != 0 || curHeader == Ipv6Header::IPV6_EXT_FRAGMENTATION,
1540 "Zero-size IPv6 Option Header, aborting" << *packet);
1541 }
1542 else
1543 {
1544 protocol = GetProtocol(nextHeader, iif);
1545
1546 if (!protocol)
1547 {
1548 NS_LOG_LOGIC("Unknown Next Header. Drop!");
1549
1550 // For ICMPv6 Error packets
1551 Ptr<Packet> malformedPacket = packet->Copy();
1552 malformedPacket->AddHeader(ip);
1553
1554 if (nextHeaderPosition == 0)
1555 {
1556 GetIcmpv6()->SendErrorParameterError(malformedPacket,
1557 dst,
1559 40);
1560 }
1561 else
1562 {
1563 GetIcmpv6()->SendErrorParameterError(malformedPacket,
1564 dst,
1566 ip.GetSerializedSize() +
1567 nextHeaderPosition);
1568 }
1569 m_dropTrace(ip, p, DROP_UNKNOWN_PROTOCOL, this, iif);
1570 break;
1571 }
1572 else
1573 {
1574 p->RemoveAtStart(nextHeaderPosition);
1575 /* protocol->Receive (p, src, dst, incomingInterface); */
1576
1577 /* L4 protocol */
1578 Ptr<Packet> copy = p->Copy();
1579
1580 m_localDeliverTrace(ip, p, iif);
1581
1582 enum IpL4Protocol::RxStatus status = protocol->Receive(p, ip, GetInterface(iif));
1583
1584 switch (status)
1585 {
1587 break;
1589 break;
1591 break;
1593 if (ip.GetDestination().IsMulticast())
1594 {
1595 /* do not rely on multicast address */
1596 break;
1597 }
1598
1599 copy->AddHeader(ip);
1600 GetIcmpv6()->SendErrorDestinationUnreachable(
1601 copy,
1602 ip.GetSource(),
1604 }
1605 }
1606 }
1607 } while (ipv6Extension);
1608}
1609
1610void
1612 const Ipv6Header& ipHeader,
1613 Socket::SocketErrno sockErrno)
1614{
1615 NS_LOG_FUNCTION(this << p << ipHeader << sockErrno);
1616 NS_LOG_LOGIC("Route input failure-- dropping packet to " << ipHeader << " with errno "
1617 << sockErrno);
1618
1619 m_dropTrace(ipHeader, p, DROP_ROUTE_ERROR, this, 0);
1620
1621 if (!ipHeader.GetDestination().IsMulticast())
1622 {
1623 Ptr<Packet> packet = p->Copy();
1624 packet->AddHeader(ipHeader);
1625 GetIcmpv6()->SendErrorDestinationUnreachable(packet,
1626 ipHeader.GetSource(),
1628 }
1629}
1630
1633 Ipv6Address dst,
1634 uint8_t protocol,
1635 uint16_t payloadSize,
1636 uint8_t ttl,
1637 uint8_t tclass)
1638{
1639 NS_LOG_FUNCTION(this << src << dst << (uint32_t)protocol << (uint32_t)payloadSize
1640 << (uint32_t)ttl << (uint32_t)tclass);
1641 Ipv6Header hdr;
1642
1643 hdr.SetSource(src);
1644 hdr.SetDestination(dst);
1645 hdr.SetNextHeader(protocol);
1646 hdr.SetPayloadLength(payloadSize);
1647 hdr.SetHopLimit(ttl);
1648 hdr.SetTrafficClass(tclass);
1649 return hdr;
1650}
1651
1652void
1654{
1655 Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = CreateObject<Ipv6ExtensionDemux>();
1656 ipv6ExtensionDemux->SetNode(m_node);
1657
1658 Ptr<Ipv6ExtensionHopByHop> hopbyhopExtension = CreateObject<Ipv6ExtensionHopByHop>();
1659 hopbyhopExtension->SetNode(m_node);
1660 Ptr<Ipv6ExtensionDestination> destinationExtension = CreateObject<Ipv6ExtensionDestination>();
1661 destinationExtension->SetNode(m_node);
1662 Ptr<Ipv6ExtensionFragment> fragmentExtension = CreateObject<Ipv6ExtensionFragment>();
1663 fragmentExtension->SetNode(m_node);
1664 Ptr<Ipv6ExtensionRouting> routingExtension = CreateObject<Ipv6ExtensionRouting>();
1665 routingExtension->SetNode(m_node);
1666 // Ptr<Ipv6ExtensionESP> espExtension = CreateObject<Ipv6ExtensionESP> ();
1667 // Ptr<Ipv6ExtensionAH> ahExtension = CreateObject<Ipv6ExtensionAH> ();
1668
1669 ipv6ExtensionDemux->Insert(hopbyhopExtension);
1670 ipv6ExtensionDemux->Insert(destinationExtension);
1671 ipv6ExtensionDemux->Insert(fragmentExtension);
1672 ipv6ExtensionDemux->Insert(routingExtension);
1673 // ipv6ExtensionDemux->Insert (espExtension);
1674 // ipv6ExtensionDemux->Insert (ahExtension);
1675
1676 Ptr<Ipv6ExtensionRoutingDemux> routingExtensionDemux =
1677 CreateObject<Ipv6ExtensionRoutingDemux>();
1678 routingExtensionDemux->SetNode(m_node);
1679 Ptr<Ipv6ExtensionLooseRouting> looseRoutingExtension =
1680 CreateObject<Ipv6ExtensionLooseRouting>();
1681 looseRoutingExtension->SetNode(m_node);
1682 routingExtensionDemux->Insert(looseRoutingExtension);
1683
1684 m_node->AggregateObject(routingExtensionDemux);
1685 m_node->AggregateObject(ipv6ExtensionDemux);
1686}
1687
1688void
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{
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{
1764
1767 {
1769 }
1770}
1771
1772bool
1774{
1775 NS_LOG_FUNCTION(address << interface);
1776
1777 Ipv6RegisteredMulticastAddressKey_t key = std::make_pair(address, interface);
1779
1780 if (iter == m_multicastAddresses.end())
1781 {
1782 return false;
1783 }
1784 return true;
1785}
1786
1787bool
1789{
1791
1794
1795 if (iter == m_multicastAddressesNoInterface.end())
1796 {
1797 return false;
1798 }
1799 return true;
1800}
1801
1802bool
1804{
1805 if (ipInterfaceIndex >= m_interfaces.size())
1806 {
1807 return false;
1808 }
1809
1810 Ptr<NdiscCache> ndiscCache = m_interfaces[ipInterfaceIndex]->GetNdiscCache();
1811 if (!ndiscCache)
1812 {
1813 return false;
1814 }
1815
1816 NdiscCache::Entry* entry = ndiscCache->Lookup(address);
1817 if (!entry || entry->IsIncomplete())
1818 {
1819 return false;
1820 }
1821
1822 if (entry->IsReachable())
1823 {
1824 entry->UpdateReachableTimer();
1825 }
1826 else if (entry->IsPermanent() || entry->IsAutoGenerated())
1827 {
1828 return true;
1829 }
1830 else if (entry->IsProbe())
1831 {
1832 // we just confirm the entry's MAC address to get the waiting packets (if any)
1833 std::list<NdiscCache::Ipv6PayloadHeaderPair> waiting =
1834 entry->MarkReachable(entry->GetMacAddress());
1835 for (std::list<NdiscCache::Ipv6PayloadHeaderPair>::const_iterator it = waiting.begin();
1836 it != waiting.end();
1837 it++)
1838 {
1839 ndiscCache->GetInterface()->Send(it->first, it->second, it->second.GetSource());
1840 }
1841 entry->ClearWaitingPacket();
1842 entry->StartReachableTimer();
1843 }
1844 else // STALE OR DELAY
1845 {
1846 entry->MarkReachable();
1847 entry->StartReachableTimer();
1848 }
1849
1850 return true;
1851}
1852
1853} /* namespace ns3 */
#define max(a, b)
Definition: 80211b.c:43
a polymophic address class
Definition: address.h:92
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.
virtual int GetProtocolNumber() const =0
Returns the protocol number of this protocol.
virtual enum RxStatus Receive(Ptr< Packet > p, const Ipv4Header &header, Ptr< Ipv4Interface > incomingInterface)=0
Called from lower-level layers to send the packet up in the stack.
RxStatus
Rx status codes.
Describes an IPv6 address.
Definition: ipv6-address.h:50
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).
void StartPreferredTimer()
Start the preferred timer.
Demultiplexes IPv6 extensions.
IPv6 Extension Fragment.
void SetNode(Ptr< Node > node)
Set the node.
Packet header for IPv6.
Definition: ipv6-header.h:36
void SetDestination(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:130
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:142
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:183
Ipv6Address GetSource() const
Get the "Source address" field.
Definition: ipv6-header.cc:118
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.
void SetForwarding(bool forward)
Set forwarding enabled or not.
void SetDown()
Disable this interface.
bool IsUp() const
Is the interface UP ?
uint32_t GetNAddresses() const
Get number of addresses on this IPv6 interface.
Ipv6InterfaceAddress GetAddress(uint32_t index) const
Get an address from IPv6 interface.
void SetUp()
Enable this interface.
void Send(Ptr< Packet > p, const Ipv6Header &hdr, Ipv6Address dest)
Send a packet through this interface.
uint16_t GetMetric() const
Get the metric.
void SetMetric(uint16_t metric)
Set the metric.
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.
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.
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_INTERFACE_DOWN
Interface is down so can not send packet.
@ 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.
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.
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.
Describes an IPv6 prefix.
Definition: ipv6-address.h:456
void SetNode(Ptr< Node > node)
Set the node associated with this socket.
bool ForwardUp(Ptr< const Packet > p, Ipv6Header hdr, Ptr< NetDevice > device)
Forward up to receive method.
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
virtual NdiscCache::Entry * Lookup(Ipv6Address dst)
Lookup in the cache.
Definition: ndisc-cache.cc:100
std::list< NdiscCache::Entry * > LookupInverse(Address dst)
Lookup in the cache for a MAC address.
Definition: ndisc-cache.cc:116
Ptr< Ipv6Interface > GetInterface() const
Get the Ipv6Interface associated with this cache.
Definition: ndisc-cache.cc:86
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
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:986
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:400
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
Definition: packet.cc:376
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Definition: packet.cc:384
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
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
Introspection did not find any typical Config paths.
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:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
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:45
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
address
Definition: first.py:40
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:691