A Discrete-Event Network Simulator
API
ipv6-l3-protocol.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2007-2009 Strasbourg University
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
19 */
20
21#include "ns3/log.h"
22#include "ns3/node.h"
23#include "ns3/uinteger.h"
24#include "ns3/vector.h"
25#include "ns3/boolean.h"
26#include "ns3/callback.h"
27#include "ns3/trace-source-accessor.h"
28#include "ns3/object-vector.h"
29#include "ns3/ipv6-routing-protocol.h"
30#include "ns3/ipv6-route.h"
31#include "ns3/mac16-address.h"
32#include "ns3/mac64-address.h"
33#include "ns3/traffic-control-layer.h"
34
35#include "loopback-net-device.h"
36#include "ipv6-l3-protocol.h"
37#include "ipv6-interface.h"
41#include "ipv6-extension.h"
43#include "ipv6-option-demux.h"
44#include "ipv6-option.h"
45#include "icmpv6-l4-protocol.h"
46#include "ndisc-cache.h"
48
50#define IPV6_MIN_MTU 1280
51
52namespace ns3 {
53
54NS_LOG_COMPONENT_DEFINE ("Ipv6L3Protocol");
55
56NS_OBJECT_ENSURE_REGISTERED (Ipv6L3Protocol);
57
58const uint16_t Ipv6L3Protocol::PROT_NUMBER = 0x86DD;
59
61{
62 static TypeId tid = TypeId ("ns3::Ipv6L3Protocol")
63 .SetParent<Ipv6> ()
64 .SetGroupName ("Internet")
65 .AddConstructor<Ipv6L3Protocol> ()
66 .AddAttribute ("DefaultTtl",
67 "The TTL value set by default on all "
68 "outgoing packets generated on this node.",
69 UintegerValue (64),
71 MakeUintegerChecker<uint8_t> ())
72 .AddAttribute ("DefaultTclass",
73 "The TCLASS value set by default on all "
74 "outgoing packets generated on this node.",
75 UintegerValue (0),
77 MakeUintegerChecker<uint8_t> ())
78 .AddAttribute ("InterfaceList",
79 "The set of IPv6 interfaces associated to this IPv6 stack.",
82 MakeObjectVectorChecker<Ipv6Interface> ())
83 .AddAttribute ("SendIcmpv6Redirect",
84 "Send the ICMPv6 Redirect when appropriate.",
85 BooleanValue (true),
89 .AddAttribute ("StrongEndSystemModel",
90 "Reject packets for an address not configured on the interface they're coming from (RFC1222).",
91 BooleanValue (true),
94 .AddTraceSource ("Tx",
95 "Send IPv6 packet to outgoing interface.",
97 "ns3::Ipv6L3Protocol::TxRxTracedCallback")
98 .AddTraceSource ("Rx",
99 "Receive IPv6 packet from incoming interface.",
101 "ns3::Ipv6L3Protocol::TxRxTracedCallback")
102 .AddTraceSource ("Drop",
103 "Drop IPv6 packet",
105 "ns3::Ipv6L3Protocol::DropTracedCallback")
106
107 .AddTraceSource ("SendOutgoing",
108 "A newly-generated packet by this node is "
109 "about to be queued for transmission",
111 "ns3::Ipv6L3Protocol::SentTracedCallback")
112 .AddTraceSource ("UnicastForward",
113 "A unicast IPv6 packet was received by this node "
114 "and is being forwarded to another node",
116 "ns3::Ipv6L3Protocol::SentTracedCallback")
117 .AddTraceSource ("LocalDeliver",
118 "An IPv6 packet was received by/for this node, "
119 "and it is being forward up the stack",
121 "ns3::Ipv6L3Protocol::SentTracedCallback")
122 ;
123 return tid;
124}
125
127 : m_nInterfaces (0)
128{
129 NS_LOG_FUNCTION (this);
130 m_pmtuCache = CreateObject<Ipv6PmtuCache> ();
131
132 Ptr<Ipv6RawSocketFactoryImpl> rawFactoryImpl = CreateObject<Ipv6RawSocketFactoryImpl> ();
133 AggregateObject (rawFactoryImpl);
134}
135
137{
138 NS_LOG_FUNCTION (this);
139}
140
142{
143 NS_LOG_FUNCTION (this);
144
145 /* clear protocol and interface list */
146 for (L4List_t::iterator it = m_protocols.begin (); it != m_protocols.end (); ++it)
147 {
148 it->second = 0;
149 }
150 m_protocols.clear ();
151
152 /* remove interfaces */
153 for (Ipv6InterfaceList::iterator it = m_interfaces.begin (); it != m_interfaces.end (); ++it)
154 {
155 *it = 0;
156 }
157 m_interfaces.clear ();
159
160 /* remove raw sockets */
161 for (SocketList::iterator it = m_sockets.begin (); it != m_sockets.end (); ++it)
162 {
163 *it = 0;
164 }
165 m_sockets.clear ();
166
167 /* remove list of prefix */
168 for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin (); it != m_prefixes.end (); ++it)
169 {
170 (*it)->StopValidTimer ();
171 (*it)->StopPreferredTimer ();
172 (*it) = 0;
173 }
174 m_prefixes.clear ();
175
176 m_node = 0;
178 m_pmtuCache = 0;
180}
181
183{
184 NS_LOG_FUNCTION (this << routingProtocol);
185 m_routingProtocol = routingProtocol;
186 m_routingProtocol->SetIpv6 (this);
187}
188
190{
191 NS_LOG_FUNCTION (this);
192 return m_routingProtocol;
193}
194
196{
197 NS_LOG_FUNCTION (this << device);
199
201
202 NS_ASSERT (tc != 0);
203
206
207 tc->RegisterProtocolHandler (MakeCallback (&Ipv6L3Protocol::Receive, this),
209
210 interface->SetNode (m_node);
211 interface->SetDevice (device);
212 interface->SetTrafficControl (tc);
213 interface->SetForwarding (m_ipForward);
214 return AddIpv6Interface (interface);
215}
216
218{
219 NS_LOG_FUNCTION (this << interface);
220 uint32_t index = m_nInterfaces;
221
222 m_interfaces.push_back (interface);
223 m_reverseInterfacesContainer[interface->GetDevice ()] = index;
225 return index;
226}
227
229{
230 NS_LOG_FUNCTION (this << index);
231
232 if (index < m_interfaces.size ())
233 {
234 return m_interfaces[index];
235 }
236 return 0;
237}
238
240{
241 NS_LOG_FUNCTION (this);
242 return m_nInterfaces;
243}
244
246{
247 NS_LOG_FUNCTION (this << address);
248 int32_t index = 0;
249
250 for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
251 {
252 uint32_t j = 0;
253 uint32_t max = (*it)->GetNAddresses ();
254
255 for (j = 0; j < max; j++)
256 {
257 if ((*it)->GetAddress (j).GetAddress () == address)
258 {
259 return index;
260 }
261 }
262 index++;
263 }
264 return -1;
265}
266
268{
269 NS_LOG_FUNCTION (this << address << mask);
270 int32_t index = 0;
271
272 for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
273 {
274 uint32_t j = 0;
275 for (j = 0; j < (*it)->GetNAddresses (); j++)
276 {
277 if ((*it)->GetAddress (j).GetAddress ().CombinePrefix (mask) == address.CombinePrefix (mask))
278 {
279 return index;
280 }
281 }
282 index++;
283 }
284 return -1;
285}
286
288{
289 NS_LOG_FUNCTION (this << i);
290 return GetInterface (i)->GetDevice ();
291}
292
294{
295 NS_LOG_FUNCTION (this << device);
296
297 Ipv6InterfaceReverseContainer::const_iterator iter = m_reverseInterfacesContainer.find (device);
298 if (iter != m_reverseInterfacesContainer.end ())
299 {
300 return (*iter).second;
301 }
302
303 return -1;
304}
305
306void Ipv6L3Protocol::AddAutoconfiguredAddress (uint32_t interface, Ipv6Address network, Ipv6Prefix mask, uint8_t flags, uint32_t validTime, uint32_t preferredTime, Ipv6Address defaultRouter)
307{
308 NS_LOG_FUNCTION (this << interface << network << mask << (uint32_t)flags << validTime << preferredTime);
310
311 Address addr = GetInterface (interface)->GetDevice ()->GetAddress ();
312
313 if (!defaultRouter.IsAny())
314 {
315 GetRoutingProtocol ()->NotifyAddRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
316 }
317
318 bool onLink = false;
320 {
321 onLink = true;
322 }
323
324 if (flags & Icmpv6OptionPrefixInformation::AUTADDRCONF) /* auto flag */
325 {
327 address.SetOnLink (onLink);
328
329 /* see if we have already the prefix */
330 for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin (); it != m_prefixes.end (); ++it)
331 {
332 if ((*it)->GetInterface () == interface && (*it)->GetPrefix () == network && (*it)->GetMask () == mask)
333 {
334 (*it)->StopPreferredTimer ();
335 (*it)->StopValidTimer ();
336 (*it)->StartPreferredTimer ();
337 return;
338 }
339 }
340
341 /* no prefix found, add autoconfigured address and the prefix */
342 NS_LOG_INFO ("Autoconfigured address is :" << address.GetAddress ());
343 AddAddress (interface, address, onLink);
344
345 Ptr<Ipv6AutoconfiguredPrefix> aPrefix = CreateObject<Ipv6AutoconfiguredPrefix> (m_node, interface, network, mask, preferredTime, validTime, defaultRouter);
346 aPrefix->StartPreferredTimer ();
347
348 m_prefixes.push_back (aPrefix);
349 }
350
351 if (onLink) /* on-link flag */
352 {
353 /* add default router
354 * if a previous default route exists, the new ones is simply added
355 */
356 m_routingProtocol->NotifyAddRoute (network, mask, Ipv6Address::GetAny (), interface);
357 }
358}
359
361{
362 NS_LOG_FUNCTION (this << interface << network << mask);
363 Ptr<Ipv6Interface> iface = GetInterface (interface);
364 Address addr = iface->GetDevice ()->GetAddress ();
365
366 Ipv6Address addressToFind = Ipv6Address::MakeAutoconfiguredAddress (addr, network);
367
368 for (uint32_t i = 0; i < iface->GetNAddresses (); i++)
369 {
370 if (iface->GetAddress (i).GetAddress () == addressToFind)
371 {
372 RemoveAddress (interface, i);
373 break;
374 }
375 }
376
377 /* remove from list of autoconfigured address */
378 for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin (); it != m_prefixes.end (); ++it)
379 {
380 if ((*it)->GetInterface () == interface && (*it)->GetPrefix () == network && (*it)->GetMask () == mask)
381 {
382 *it = 0;
383 m_prefixes.erase (it);
384 break;
385 }
386 }
387
388 GetRoutingProtocol ()->NotifyRemoveRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
389}
390
392{
393 NS_LOG_FUNCTION (this << i << address);
394 Ptr<Ipv6Interface> interface = GetInterface (i);
395 address.SetOnLink (addOnLinkRoute);
396 bool ret = interface->AddAddress (address);
397
398 if (m_routingProtocol != 0)
399 {
400 m_routingProtocol->NotifyAddAddress (i, address);
401 }
402
403 if (addOnLinkRoute)
404 {
405 Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
406 Ipv6Prefix networkMask = address.GetPrefix ();
407 GetRoutingProtocol ()->NotifyAddRoute (networkAddress, networkMask, Ipv6Address::GetZero (), i);
408 }
409 return ret;
410}
411
413{
414 NS_LOG_FUNCTION (this << i);
415 Ptr<Ipv6Interface> interface = GetInterface (i);
416 return interface->GetNAddresses ();
417}
418
420{
421 NS_LOG_FUNCTION (this << i << addressIndex);
422 Ptr<Ipv6Interface> interface = GetInterface (i);
423 return interface->GetAddress (addressIndex);
424}
425
427{
428 NS_LOG_FUNCTION (this << i << addressIndex);
429 Ptr<Ipv6Interface> interface = GetInterface (i);
430 Ipv6InterfaceAddress address = interface->RemoveAddress (addressIndex);
431
433 {
434 if (m_routingProtocol != 0)
435 {
436 m_routingProtocol->NotifyRemoveAddress (i, address);
437 }
438 return true;
439 }
440 return false;
441}
442
443bool
445{
446 NS_LOG_FUNCTION (this << i << address);
447
449 {
450 NS_LOG_WARN ("Cannot remove loopback address.");
451 return false;
452 }
453 Ptr<Ipv6Interface> interface = GetInterface (i);
454 Ipv6InterfaceAddress ifAddr = interface->RemoveAddress (address);
455 if (ifAddr != Ipv6InterfaceAddress ())
456 {
457 if (m_routingProtocol != 0)
458 {
459 m_routingProtocol->NotifyRemoveAddress (i, ifAddr);
460 }
461 return true;
462 }
463 return false;
464}
465
466void Ipv6L3Protocol::SetMetric (uint32_t i, uint16_t metric)
467{
468 NS_LOG_FUNCTION (this << i << metric);
469 Ptr<Ipv6Interface> interface = GetInterface (i);
470 interface->SetMetric (metric);
471}
472
474{
475 NS_LOG_FUNCTION (this << i);
476 Ptr<Ipv6Interface> interface = GetInterface (i);
477 return interface->GetMetric ();
478}
479
481{
482 NS_LOG_FUNCTION (this << i);
483
484 // RFC 1981, if PMTU is disabled, return the minimum MTU
485 if (!m_mtuDiscover)
486 {
487 return IPV6_MIN_MTU;
488 }
489
490 Ptr<Ipv6Interface> interface = GetInterface (i);
491 return interface->GetDevice ()->GetMtu ();
492}
493
495{
496 NS_LOG_FUNCTION (this << dst << int(pmtu));
497 m_pmtuCache->SetPmtu (dst, pmtu);
498}
499
500
502{
503 NS_LOG_FUNCTION (this << i);
504 Ptr<Ipv6Interface> interface = GetInterface (i);
505 return interface->IsUp ();
506}
507
509{
510 NS_LOG_FUNCTION (this << i);
511 Ptr<Ipv6Interface> interface = GetInterface (i);
512
513 // RFC 2460, Section 5, pg. 24:
514 // IPv6 requires that every link in the internet have an MTU of 1280
515 // octets or greater. On any link that cannot convey a 1280-octet
516 // packet in one piece, link-specific fragmentation and reassembly must
517 // be provided at a layer below IPv6.
518 if (interface->GetDevice ()->GetMtu () >= 1280)
519 {
520 interface->SetUp ();
521
522 if (m_routingProtocol != 0)
523 {
524 m_routingProtocol->NotifyInterfaceUp (i);
525 }
526 }
527 else
528 {
529 NS_LOG_LOGIC ("Interface " << int(i) << " is set to be down for IPv6. Reason: not respecting minimum IPv6 MTU (1280 octets)");
530 }
531}
532
534{
535 NS_LOG_FUNCTION (this << i);
536 Ptr<Ipv6Interface> interface = GetInterface (i);
537
538 interface->SetDown ();
539
540 if (m_routingProtocol != 0)
541 {
542 m_routingProtocol->NotifyInterfaceDown (i);
543 }
544}
545
547{
548 NS_LOG_FUNCTION (this);
550 Ptr<LoopbackNetDevice> device = 0;
551 uint32_t i = 0;
552
553 /* see if we have already an loopback NetDevice */
554 for (i = 0; i < m_node->GetNDevices (); i++)
555 {
556 if ((device = DynamicCast<LoopbackNetDevice> (m_node->GetDevice (i))))
557 {
558 break;
559 }
560 }
561
562 if (device == 0)
563 {
564 device = CreateObject<LoopbackNetDevice> ();
565 m_node->AddDevice (device);
566 }
567
568 interface->SetDevice (device);
569 interface->SetNode (m_node);
571 interface->AddAddress (ifaceAddr);
572 uint32_t index = AddIpv6Interface (interface);
573 Ptr<Node> node = GetObject<Node> ();
575 interface->SetUp ();
576
577 if (m_routingProtocol != 0)
578 {
579 m_routingProtocol->NotifyInterfaceUp (index);
580 }
581}
582
584{
585 NS_LOG_FUNCTION (this << i);
586 Ptr<Ipv6Interface> interface = GetInterface (i);
587
588 NS_LOG_LOGIC ("Forwarding state: " << interface->IsForwarding ());
589 return interface->IsForwarding ();
590}
591
593{
594 NS_LOG_FUNCTION (this << i << val);
595 Ptr<Ipv6Interface> interface = GetInterface (i);
596 interface->SetForwarding (val);
597}
598
600{
601 NS_LOG_FUNCTION (this << interface << dest);
602 Ipv6Address ret;
603
604 if (dest.IsLocalhost ())
605 {
606 return Ipv6Address::GetLoopback ();
607 }
608
609 if (dest.IsLinkLocal () || dest.IsLinkLocalMulticast ())
610 {
611 for (uint32_t i = 0; i < GetNAddresses (interface); i++)
612 {
613 Ipv6InterfaceAddress test = GetAddress (interface, i);
614 if (test.GetScope () == Ipv6InterfaceAddress::LINKLOCAL)
615 {
616 return test.GetAddress ();
617 }
618 }
619 NS_ASSERT_MSG (false, "No link-local address found on interface " << interface);
620 }
621
622 for (uint32_t i = 0; i < GetNAddresses (interface); i++)
623 {
624 Ipv6InterfaceAddress test = GetAddress (interface, i);
625
626 if (test.GetScope () == Ipv6InterfaceAddress::GLOBAL)
627 {
628 if (test.IsInSameSubnet (dest))
629 {
630 return test.GetAddress ();
631 }
632 else
633 {
634 ret = test.GetAddress ();
635 }
636 }
637 }
638
639 // no specific match found. Use a global address (any useful is fine).
640 NS_ASSERT_MSG (!ret.IsAny (),
641 "Could not find any address for " << dest << " on interface " << interface);
642 return ret;
643}
644
646{
647 NS_LOG_FUNCTION (this << forward);
648 m_ipForward = forward;
649
650 for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
651 {
652 (*it)->SetForwarding (forward);
653 }
654}
655
657{
658 NS_LOG_FUNCTION (this);
659 return m_ipForward;
660}
661
662void Ipv6L3Protocol::SetMtuDiscover (bool mtuDiscover)
663{
664 NS_LOG_FUNCTION (this << int(mtuDiscover));
665 m_mtuDiscover = mtuDiscover;
666}
667
669{
670 NS_LOG_FUNCTION (this);
671 return m_mtuDiscover;
672}
673
674void Ipv6L3Protocol::SetSendIcmpv6Redirect (bool sendIcmpv6Redirect)
675{
676 NS_LOG_FUNCTION (this << sendIcmpv6Redirect);
677 m_sendIcmpv6Redirect = sendIcmpv6Redirect;
678}
679
681{
682 NS_LOG_FUNCTION (this);
684}
685
687{
688 NS_LOG_FUNCTION (this);
689
690 if (m_node == 0)
691 {
692 Ptr<Node> node = this->GetObject<Node> ();
693 // verify that it's a valid node and that
694 // the node has not been set before
695 if (node != 0)
696 {
697 this->SetNode (node);
698 }
699 }
700
702}
703
705{
706 NS_LOG_FUNCTION (this << node);
707 m_node = node;
708 /* add LoopbackNetDevice if needed, and an Ipv6Interface on top of it */
709 SetupLoopback ();
710}
711
713{
714 NS_LOG_FUNCTION (this << protocol);
715 L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), -1);
716 if (m_protocols.find (key) != m_protocols.end ())
717 {
718 NS_LOG_WARN ("Overwriting default protocol " << int(protocol->GetProtocolNumber ()));
719 }
720 m_protocols[key] = protocol;
721}
722
723void Ipv6L3Protocol::Insert (Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
724{
725 NS_LOG_FUNCTION (this << protocol << interfaceIndex);
726
727 L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), interfaceIndex);
728 if (m_protocols.find (key) != m_protocols.end ())
729 {
730 NS_LOG_WARN ("Overwriting protocol " << int(protocol->GetProtocolNumber ()) << " on interface " << int(interfaceIndex));
731 }
732 m_protocols[key] = protocol;
733}
734
736{
737 NS_LOG_FUNCTION (this << protocol);
738
739 L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), -1);
740 L4List_t::iterator iter = m_protocols.find (key);
741 if (iter == m_protocols.end ())
742 {
743 NS_LOG_WARN ("Trying to remove an non-existent default protocol " << int(protocol->GetProtocolNumber ()));
744 }
745 else
746 {
747 m_protocols.erase (key);
748 }
749}
750
751void Ipv6L3Protocol::Remove (Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
752{
753 NS_LOG_FUNCTION (this << protocol << interfaceIndex);
754
755 L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), interfaceIndex);
756 L4List_t::iterator iter = m_protocols.find (key);
757 if (iter == m_protocols.end ())
758 {
759 NS_LOG_WARN ("Trying to remove an non-existent protocol " << int(protocol->GetProtocolNumber ()) << " on interface " << int(interfaceIndex));
760 }
761 else
762 {
763 m_protocols.erase (key);
764 }
765}
766
768{
769 NS_LOG_FUNCTION (this << protocolNumber);
770
771 return GetProtocol (protocolNumber, -1);
772}
773
774Ptr<IpL4Protocol> Ipv6L3Protocol::GetProtocol (int protocolNumber, int32_t interfaceIndex) const
775{
776 NS_LOG_FUNCTION (this << protocolNumber << interfaceIndex);
777
778 L4ListKey_t key;
779 L4List_t::const_iterator i;
780 if (interfaceIndex >= 0)
781 {
782 // try the interface-specific protocol.
783 key = std::make_pair (protocolNumber, interfaceIndex);
784 i = m_protocols.find (key);
785 if (i != m_protocols.end ())
786 {
787 return i->second;
788 }
789 }
790 // try the generic protocol.
791 key = std::make_pair (protocolNumber, -1);
792 i = m_protocols.find (key);
793 if (i != m_protocols.end ())
794 {
795 return i->second;
796 }
797
798 return 0;
799}
800
802{
803 NS_LOG_FUNCTION (this);
804 Ptr<Ipv6RawSocketImpl> sock = CreateObject<Ipv6RawSocketImpl> ();
805 sock->SetNode (m_node);
806 m_sockets.push_back (sock);
807 return sock;
808}
809
811{
812 NS_LOG_FUNCTION (this << socket);
813
814 for (SocketList::iterator it = m_sockets.begin (); it != m_sockets.end (); ++it)
815 {
816 if ((*it) == socket)
817 {
818 m_sockets.erase (it);
819 return;
820 }
821 }
822}
823
825{
826 NS_LOG_FUNCTION (this);
828
829 if (protocol)
830 {
831 return protocol->GetObject<Icmpv6L4Protocol> ();
832 }
833 else
834 {
835 return 0;
836 }
837}
838
840{
841 NS_LOG_FUNCTION (this << ttl);
842 m_defaultTtl = ttl;
843}
844
846{
847 NS_LOG_FUNCTION (this << tclass);
848 m_defaultTclass = tclass;
849}
850
851void Ipv6L3Protocol::Send (Ptr<Packet> packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr<Ipv6Route> route)
852{
853 NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)protocol << route);
854 Ipv6Header hdr;
855 uint8_t ttl = m_defaultTtl;
857 bool found = packet->RemovePacketTag (tag);
858
859 if (found)
860 {
861 ttl = tag.GetHopLimit ();
862 }
863
864 SocketIpv6TclassTag tclassTag;
865 uint8_t tclass = m_defaultTclass;
866 found = packet->RemovePacketTag (tclassTag);
867
868 if (found)
869 {
870 tclass = tclassTag.GetTclass ();
871 }
872
873 /* Handle 3 cases:
874 * 1) Packet is passed in with a route entry
875 * 2) Packet is passed in with a route entry but route->GetGateway is not set (e.g., same network)
876 * 3) route is NULL (e.g., a raw socket call or ICMPv6)
877 */
878
879 /* 1) */
880 if (route && route->GetGateway () != Ipv6Address::GetZero ())
881 {
882 NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 1: passed in with a route");
883 hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
884 int32_t interface = GetInterfaceForDevice (route->GetOutputDevice ());
885 m_sendOutgoingTrace (hdr, packet, interface);
886 SendRealOut (route, packet, hdr);
887 return;
888 }
889
890 /* 2) */
891 if (route && route->GetGateway () == Ipv6Address::GetZero ())
892 {
893 NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 2: probably sent to machine on same IPv6 network");
894 hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
895 int32_t interface = GetInterfaceForDevice (route->GetOutputDevice ());
896 m_sendOutgoingTrace (hdr, packet, interface);
897 SendRealOut (route, packet, hdr);
898 return;
899 }
900
901 /* 3) */
902 NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 3: passed in with no route " << destination);
904 Ptr<NetDevice> oif (0);
905 Ptr<Ipv6Route> newRoute = 0;
906
907 hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
908
909 //for link-local traffic, we need to determine the interface
910 if (source.IsLinkLocal ()
911 || destination.IsLinkLocal ()
912 || destination.IsLinkLocalMulticast ())
913 {
914 int32_t index = GetInterfaceForAddress (source);
915 NS_ASSERT_MSG (index >= 0, "Can not find an outgoing interface for a packet with src " << source << " and dst " << destination);
916 oif = GetNetDevice (index);
917 }
918
919 newRoute = m_routingProtocol->RouteOutput (packet, hdr, oif, err);
920
921 if (newRoute)
922 {
923 int32_t interface = GetInterfaceForDevice (newRoute->GetOutputDevice ());
924 m_sendOutgoingTrace (hdr, packet, interface);
925 SendRealOut (newRoute, packet, hdr);
926 }
927 else
928 {
929 NS_LOG_WARN ("No route to host, drop!");
930 m_dropTrace (hdr, packet, DROP_NO_ROUTE, this, GetInterfaceForDevice (oif));
931 }
932}
933
934void Ipv6L3Protocol::Receive (Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
935{
936 NS_LOG_FUNCTION (this << device << p << protocol << from << to << packetType);
937 NS_LOG_LOGIC ("Packet from " << from << " received on node " << m_node->GetId ());
938
939 NS_ASSERT_MSG (GetInterfaceForDevice(device) != -1, "Received a packet from an interface that is not known to IPv6");
940 uint32_t interface = GetInterfaceForDevice(device);
941
942 Ptr<Ipv6Interface> ipv6Interface = m_interfaces[interface];
943 Ptr<Packet> packet = p->Copy ();
944
945 if (ipv6Interface->IsUp ())
946 {
947 m_rxTrace (packet, this, interface);
948 }
949 else
950 {
951 NS_LOG_LOGIC ("Dropping received packet-- interface is down");
952 Ipv6Header hdr;
953 packet->RemoveHeader (hdr);
954 m_dropTrace (hdr, packet, DROP_INTERFACE_DOWN, this, interface);
955 return;
956 }
957
958 Ipv6Header hdr;
959 packet->RemoveHeader (hdr);
960
961 // Trim any residual frame padding from underlying devices
962 if (hdr.GetPayloadLength () < packet->GetSize ())
963 {
964 packet->RemoveAtEnd (packet->GetSize () - hdr.GetPayloadLength ());
965 }
966
967 // the packet is valid, we update the NDISC cache entry (if present)
968 Ptr<NdiscCache> ndiscCache = ipv6Interface->GetNdiscCache ();
969 if (ndiscCache)
970 {
971 // case one, it's a a direct routing.
972 NdiscCache::Entry *entry = ndiscCache->Lookup (hdr.GetSource ());
973 if (entry)
974 {
975 entry->UpdateReachableTimer ();
976 }
977 else
978 {
979 // It's not in the direct routing, so it's the router, and it could have multiple IP addresses.
980 // In doubt, update all of them.
981 // Note: it's a confirmed behavior for Linux routers.
982 std::list<NdiscCache::Entry *> entryList = ndiscCache->LookupInverse (from);
983 std::list<NdiscCache::Entry *>::iterator iter;
984 for (iter = entryList.begin (); iter != entryList.end (); iter ++)
985 {
986 (*iter)->UpdateReachableTimer ();
987 }
988 }
989 }
990
991
992
993 /* forward up to IPv6 raw sockets */
994 for (SocketList::iterator it = m_sockets.begin (); it != m_sockets.end (); ++it)
995 {
996 Ptr<Ipv6RawSocketImpl> socket = *it;
997 socket->ForwardUp (packet, hdr, device);
998 }
999
1001 Ptr<Ipv6Extension> ipv6Extension = 0;
1002 uint8_t nextHeader = hdr.GetNextHeader ();
1003 bool stopProcessing = false;
1004 bool isDropped = false;
1005 DropReason dropReason;
1006
1007 if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1008 {
1009 ipv6Extension = ipv6ExtensionDemux->GetExtension (nextHeader);
1010
1011 if (ipv6Extension)
1012 {
1013 ipv6Extension->Process (packet, 0, hdr, hdr.GetDestination (), (uint8_t *)0, stopProcessing, isDropped, dropReason);
1014 }
1015
1016 if (isDropped)
1017 {
1018 m_dropTrace (hdr, packet, dropReason, this, interface);
1019 }
1020
1021 if (stopProcessing)
1022 {
1023 return;
1024 }
1025 }
1026
1027 if (hdr.GetDestination ().IsAllNodesMulticast ())
1028 {
1029 LocalDeliver (packet, hdr, interface);
1030 return;
1031 }
1032 else if (hdr.GetDestination ().IsAllRoutersMulticast() && ipv6Interface->IsForwarding ())
1033 {
1034 LocalDeliver (packet, hdr, interface);
1035 return;
1036 }
1037 else if (hdr.GetDestination ().IsMulticast ())
1038 {
1039 bool isSolicited = ipv6Interface->IsSolicitedMulticastAddress (hdr.GetDestination ());
1040 bool isRegisteredOnInterface = IsRegisteredMulticastAddress (hdr.GetDestination (), interface);
1041 bool isRegisteredGlobally = IsRegisteredMulticastAddress (hdr.GetDestination ());
1042 if (isSolicited || isRegisteredGlobally || isRegisteredOnInterface)
1043 {
1044 LocalDeliver (packet, hdr, interface);
1045 // do not return, the packet could be handled by a routing protocol
1046 }
1047 }
1048
1049
1050 for (uint32_t j = 0; j < GetNInterfaces (); j++)
1051 {
1052 if (j == interface || !m_strongEndSystemModel)
1053 {
1054 for (uint32_t i = 0; i < GetNAddresses (j); i++)
1055 {
1056 Ipv6InterfaceAddress iaddr = GetAddress (j, i);
1057 Ipv6Address addr = iaddr.GetAddress ();
1058 if (addr == hdr.GetDestination ())
1059 {
1060 if (j == interface)
1061 {
1062 NS_LOG_LOGIC ("For me (destination " << addr << " match)");
1063 }
1064 else
1065 {
1066 NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << hdr.GetDestination ());
1067 }
1068 LocalDeliver (packet, hdr, interface);
1069 return;
1070 }
1071 NS_LOG_LOGIC ("Address " << addr << " not a match");
1072 }
1073 }
1074 }
1075
1076 if (!m_routingProtocol->RouteInput (packet, hdr, device,
1081 {
1082 NS_LOG_WARN ("No route found for forwarding packet. Drop.");
1083 // Drop trace and ICMPs are courtesy of RouteInputError
1084 }
1085}
1086
1087void
1089 Ptr<Ipv6> ipv6, uint32_t interface)
1090{
1091 if (!m_txTrace.IsEmpty ())
1092 {
1093 Ptr<Packet> packetCopy = packet->Copy ();
1094 packetCopy->AddHeader (ipHeader);
1095 m_txTrace (packetCopy, ipv6, interface);
1096 }
1097}
1098
1100{
1101 NS_LOG_FUNCTION (this << route << packet << ipHeader);
1102
1103 if (!route)
1104 {
1105 NS_LOG_LOGIC ("No route to host, drop!.");
1106 return;
1107 }
1108
1109 Ptr<NetDevice> dev = route->GetOutputDevice ();
1110 int32_t interface = GetInterfaceForDevice (dev);
1111 NS_ASSERT (interface >= 0);
1112
1113 Ptr<Ipv6Interface> outInterface = GetInterface (interface);
1114 NS_LOG_LOGIC ("Send via NetDevice ifIndex " << dev->GetIfIndex () << " Ipv6InterfaceIndex " << interface);
1115
1116 // Check packet size
1117 std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair> fragments;
1118
1119 // Check if this is the source of the packet
1120 bool fromMe = false;
1121 for (uint32_t i = 0; i < GetNInterfaces (); i++ )
1122 {
1123 for (uint32_t j = 0; j < GetNAddresses (i); j++ )
1124 {
1125 if (GetAddress (i,j).GetAddress () == ipHeader.GetSource ())
1126 {
1127 fromMe = true;
1128 break;
1129 }
1130 }
1131 }
1132
1133 size_t targetMtu = 0;
1134
1135 // Check if we have a Path MTU stored. If so, use it. Else, use the link MTU.
1136 // Note: PMTU must not be cached in intermediate nodes, and must be checked only by the source node
1137 if (fromMe)
1138 {
1139 targetMtu = (size_t)(m_pmtuCache->GetPmtu (ipHeader.GetDestination ()));
1140 }
1141 if (targetMtu == 0)
1142 {
1143 targetMtu = dev->GetMtu ();
1144 }
1145
1146 if (packet->GetSize () + ipHeader.GetSerializedSize () > targetMtu)
1147 {
1148 // Router => drop
1149 if (!fromMe)
1150 {
1151 Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6 ();
1152 if ( icmpv6 )
1153 {
1154 packet->AddHeader (ipHeader);
1155 icmpv6->SendErrorTooBig (packet, ipHeader.GetSource (), dev->GetMtu ());
1156 }
1157 return;
1158 }
1159
1161
1162 // To get specific method GetFragments from Ipv6ExtensionFragmentation
1163 Ipv6ExtensionFragment *ipv6Fragment = dynamic_cast<Ipv6ExtensionFragment *> (PeekPointer (ipv6ExtensionDemux->GetExtension (Ipv6Header::IPV6_EXT_FRAGMENTATION)));
1164 NS_ASSERT (ipv6Fragment != 0);
1165 ipv6Fragment->GetFragments (packet, ipHeader, targetMtu, fragments);
1166 }
1167
1168 if (route->GetGateway () != Ipv6Address::GetAny ())
1169 {
1170 if (outInterface->IsUp ())
1171 {
1172 NS_LOG_LOGIC ("Send to gateway " << route->GetGateway ());
1173
1174 if (fragments.size () != 0)
1175 {
1176 std::ostringstream oss;
1177
1178 for (std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair>::const_iterator it = fragments.begin (); it != fragments.end (); it++)
1179 {
1180 CallTxTrace (it->second, it->first, this, interface);
1181 outInterface->Send (it->first, it->second, route->GetGateway ());
1182 }
1183 }
1184 else
1185 {
1186 CallTxTrace (ipHeader, packet, this, interface);
1187 outInterface->Send (packet, ipHeader, route->GetGateway ());
1188 }
1189 }
1190 else
1191 {
1192 NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << route->GetGateway ());
1193 m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
1194 }
1195 }
1196 else
1197 {
1198 if (outInterface->IsUp ())
1199 {
1200 NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestination ());
1201
1202 if (fragments.size () != 0)
1203 {
1204 std::ostringstream oss;
1205
1206 for (std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair>::const_iterator it = fragments.begin (); it != fragments.end (); it++)
1207 {
1208 CallTxTrace (it->second, it->first, this, interface);
1209 outInterface->Send (it->first, it->second, ipHeader.GetDestination ());
1210 }
1211 }
1212 else
1213 {
1214 CallTxTrace (ipHeader, packet, this, interface);
1215 outInterface->Send (packet, ipHeader, ipHeader.GetDestination ());
1216 }
1217 }
1218 else
1219 {
1220 NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << ipHeader.GetDestination ());
1221 m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
1222 }
1223 }
1224}
1225
1227{
1228 NS_LOG_FUNCTION (this << rtentry << p << header);
1229 NS_LOG_LOGIC ("Forwarding logic for node: " << m_node->GetId ());
1230
1231 // Drop RFC 3849 packets: 2001:db8::/32
1232 if (header.GetDestination().IsDocumentation ())
1233 {
1234 NS_LOG_WARN ("Received a packet for 2001:db8::/32 (documentation class). Drop.");
1235 m_dropTrace (header, p, DROP_ROUTE_ERROR, this, 0);
1236 return;
1237 }
1238
1239 // Forwarding
1240 Ipv6Header ipHeader = header;
1241 Ptr<Packet> packet = p->Copy ();
1242 ipHeader.SetHopLimit (ipHeader.GetHopLimit () - 1);
1243
1244 if (ipHeader.GetSource ().IsLinkLocal ())
1245 {
1246 /* no forward for link-local address */
1247 return;
1248 }
1249
1250 if (ipHeader.GetHopLimit () == 0)
1251 {
1252 NS_LOG_WARN ("TTL exceeded. Drop.");
1253 m_dropTrace (ipHeader, packet, DROP_TTL_EXPIRED, this, 0);
1254 // Do not reply to multicast IPv6 address
1255 if (ipHeader.GetDestination ().IsMulticast () == false)
1256 {
1257 packet->AddHeader (ipHeader);
1258 GetIcmpv6 ()->SendErrorTimeExceeded (packet, ipHeader.GetSource (), Icmpv6Header::ICMPV6_HOPLIMIT);
1259 }
1260 return;
1261 }
1262
1263 /* ICMPv6 Redirect */
1264
1265 /* if we forward to a machine on the same network as the source,
1266 * we send him an ICMPv6 redirect message to notify him that a short route
1267 * exists.
1268 */
1269
1270 /* Theoretically we should also check if the redirect target is on the same network
1271 * as the source node. On the other hand, we are sure that the router we're redirecting to
1272 * used a link-local address. As a consequence, they MUST be on the same network, the link-local net.
1273 */
1274
1275 if (m_sendIcmpv6Redirect && (rtentry->GetOutputDevice ()==idev))
1276 {
1277 NS_LOG_LOGIC ("ICMPv6 redirect!");
1278 Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6 ();
1279 Address hardwareTarget;
1280 Ipv6Address dst = header.GetDestination ();
1281 Ipv6Address src = header.GetSource ();
1282 Ipv6Address target = rtentry->GetGateway ();
1283 Ptr<Packet> copy = p->Copy ();
1284
1285 if (target.IsAny ())
1286 {
1287 target = dst;
1288 }
1289
1290 copy->AddHeader (header);
1291 Ipv6Address linkLocal = GetInterface (GetInterfaceForDevice (rtentry->GetOutputDevice ()))->GetLinkLocalAddress ().GetAddress ();
1292
1293 if (icmpv6->Lookup (target, rtentry->GetOutputDevice (), 0, &hardwareTarget))
1294 {
1295 icmpv6->SendRedirection (copy, linkLocal, src, target, dst, hardwareTarget);
1296 }
1297 else
1298 {
1299 icmpv6->SendRedirection (copy, linkLocal, src, target, dst, Address ());
1300 }
1301 }
1302 // in case the packet still has a priority tag attached, remove it
1303 SocketPriorityTag priorityTag;
1304 packet->RemovePacketTag (priorityTag);
1305 int32_t interface = GetInterfaceForDevice (rtentry->GetOutputDevice ());
1306 m_unicastForwardTrace (ipHeader, packet, interface);
1307 SendRealOut (rtentry, packet, ipHeader);
1308}
1309
1311{
1312 NS_LOG_FUNCTION (this << mrtentry << p << header);
1313 NS_LOG_LOGIC ("Multicast forwarding logic for node: " << m_node->GetId ());
1314
1315 std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap ();
1316 std::map<uint32_t, uint32_t>::iterator mapIter;
1317
1318 for (mapIter = ttlMap.begin (); mapIter != ttlMap.end (); mapIter++)
1319 {
1320 uint32_t interfaceId = mapIter->first;
1321 //uint32_t outputTtl = mapIter->second; // Unused for now
1322 Ptr<Packet> packet = p->Copy ();
1323 Ipv6Header h = header;
1324 h.SetHopLimit (header.GetHopLimit () - 1);
1325 if (h.GetHopLimit () == 0)
1326 {
1327 NS_LOG_WARN ("TTL exceeded. Drop.");
1328 m_dropTrace (header, packet, DROP_TTL_EXPIRED, this, interfaceId);
1329 return;
1330 }
1331 NS_LOG_LOGIC ("Forward multicast via interface " << interfaceId);
1332 Ptr<Ipv6Route> rtentry = Create<Ipv6Route> ();
1333 rtentry->SetSource (h.GetSource ());
1334 rtentry->SetDestination (h.GetDestination ());
1335 rtentry->SetGateway (Ipv6Address::GetAny ());
1336 rtentry->SetOutputDevice (GetNetDevice (interfaceId));
1337 SendRealOut (rtentry, packet, h);
1338 continue;
1339 }
1340}
1341
1343{
1344 NS_LOG_FUNCTION (this << packet << ip << iif);
1345 Ptr<Packet> p = packet->Copy ();
1346 Ptr<IpL4Protocol> protocol = 0;
1348 Ptr<Ipv6Extension> ipv6Extension = 0;
1349 Ipv6Address src = ip.GetSource ();
1350 Ipv6Address dst = ip.GetDestination ();
1351 uint8_t nextHeader = ip.GetNextHeader ();
1352 uint8_t nextHeaderPosition = 0;
1353 bool isDropped = false;
1354 bool stopProcessing = false;
1355 DropReason dropReason;
1356
1357 // check for a malformed hop-by-hop extension
1358 // this is a common case when forging IPv6 raw packets
1359 if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1360 {
1361 uint8_t buf;
1362 p->CopyData (&buf, 1);
1364 {
1365 NS_LOG_WARN("Double Ipv6Header::IPV6_EXT_HOP_BY_HOP in packet, dropping packet");
1366 return;
1367 }
1368 }
1369
1370 /* process all the extensions found and the layer 4 protocol */
1371 do
1372 {
1373 /* it return 0 for non-extension (i.e. layer 4 protocol) */
1374 ipv6Extension = ipv6ExtensionDemux->GetExtension (nextHeader);
1375
1376 if (ipv6Extension)
1377 {
1378 uint8_t nextHeaderStep = 0;
1379 uint8_t curHeader = nextHeader;
1380 nextHeaderStep = ipv6Extension->Process (p, nextHeaderPosition, ip, dst, &nextHeader, stopProcessing, isDropped, dropReason);
1381 nextHeaderPosition += nextHeaderStep;
1382
1383 if (isDropped)
1384 {
1385 m_dropTrace (ip, packet, dropReason, this, iif);
1386 }
1387
1388 if (stopProcessing)
1389 {
1390 return;
1391 }
1392 NS_ASSERT_MSG (nextHeaderStep != 0 || curHeader == Ipv6Header::IPV6_EXT_FRAGMENTATION,
1393 "Zero-size IPv6 Option Header, aborting" << *packet );
1394 }
1395 else
1396 {
1397 protocol = GetProtocol (nextHeader, iif);
1398
1399 if (!protocol)
1400 {
1401 NS_LOG_LOGIC ("Unknown Next Header. Drop!");
1402
1403 // For ICMPv6 Error packets
1404 Ptr<Packet> malformedPacket = packet->Copy ();
1405 malformedPacket->AddHeader (ip);
1406
1407 if (nextHeaderPosition == 0)
1408 {
1409 GetIcmpv6 ()->SendErrorParameterError (malformedPacket, dst, Icmpv6Header::ICMPV6_UNKNOWN_NEXT_HEADER, 40);
1410 }
1411 else
1412 {
1413 GetIcmpv6 ()->SendErrorParameterError (malformedPacket, dst, Icmpv6Header::ICMPV6_UNKNOWN_NEXT_HEADER, ip.GetSerializedSize () + nextHeaderPosition);
1414 }
1415 m_dropTrace (ip, p, DROP_UNKNOWN_PROTOCOL, this, iif);
1416 break;
1417 }
1418 else
1419 {
1420 p->RemoveAtStart (nextHeaderPosition);
1421 /* protocol->Receive (p, src, dst, incomingInterface); */
1422
1423 /* L4 protocol */
1424 Ptr<Packet> copy = p->Copy ();
1425
1426 m_localDeliverTrace (ip, p, iif);
1427
1428 enum IpL4Protocol::RxStatus status = protocol->Receive (p, ip, GetInterface (iif));
1429
1430 switch (status)
1431 {
1433 break;
1435 break;
1437 break;
1439 if (ip.GetDestination ().IsMulticast ())
1440 {
1441 /* do not rely on multicast address */
1442 break;
1443 }
1444
1445 copy->AddHeader (ip);
1446 GetIcmpv6 ()->SendErrorDestinationUnreachable (copy, ip.GetSource (), Icmpv6Header::ICMPV6_PORT_UNREACHABLE);
1447 }
1448 }
1449 }
1450 }
1451 while (ipv6Extension);
1452}
1453
1455{
1456 NS_LOG_FUNCTION (this << p << ipHeader << sockErrno);
1457 NS_LOG_LOGIC ("Route input failure-- dropping packet to " << ipHeader << " with errno " << sockErrno);
1458
1459 m_dropTrace (ipHeader, p, DROP_ROUTE_ERROR, this, 0);
1460
1461 if (!ipHeader.GetDestination ().IsMulticast ())
1462 {
1463 Ptr<Packet> packet = p->Copy ();
1464 packet->AddHeader (ipHeader);
1465 GetIcmpv6 ()->SendErrorDestinationUnreachable (packet, ipHeader.GetSource (), Icmpv6Header::ICMPV6_NO_ROUTE);
1466 }
1467}
1468
1469Ipv6Header Ipv6L3Protocol::BuildHeader (Ipv6Address src, Ipv6Address dst, uint8_t protocol, uint16_t payloadSize, uint8_t ttl, uint8_t tclass)
1470{
1471 NS_LOG_FUNCTION (this << src << dst << (uint32_t)protocol << (uint32_t)payloadSize << (uint32_t)ttl << (uint32_t)tclass);
1472 Ipv6Header hdr;
1473
1474 hdr.SetSource (src);
1475 hdr.SetDestination (dst);
1476 hdr.SetNextHeader (protocol);
1477 hdr.SetPayloadLength (payloadSize);
1478 hdr.SetHopLimit (ttl);
1479 hdr.SetTrafficClass (tclass);
1480 return hdr;
1481}
1482
1484{
1485 Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = CreateObject<Ipv6ExtensionDemux> ();
1486 ipv6ExtensionDemux->SetNode (m_node);
1487
1488 Ptr<Ipv6ExtensionHopByHop> hopbyhopExtension = CreateObject<Ipv6ExtensionHopByHop> ();
1489 hopbyhopExtension->SetNode (m_node);
1490 Ptr<Ipv6ExtensionDestination> destinationExtension = CreateObject<Ipv6ExtensionDestination> ();
1491 destinationExtension->SetNode (m_node);
1492 Ptr<Ipv6ExtensionFragment> fragmentExtension = CreateObject<Ipv6ExtensionFragment> ();
1493 fragmentExtension->SetNode (m_node);
1494 Ptr<Ipv6ExtensionRouting> routingExtension = CreateObject<Ipv6ExtensionRouting> ();
1495 routingExtension->SetNode (m_node);
1496 // Ptr<Ipv6ExtensionESP> espExtension = CreateObject<Ipv6ExtensionESP> ();
1497 // Ptr<Ipv6ExtensionAH> ahExtension = CreateObject<Ipv6ExtensionAH> ();
1498
1499 ipv6ExtensionDemux->Insert (hopbyhopExtension);
1500 ipv6ExtensionDemux->Insert (destinationExtension);
1501 ipv6ExtensionDemux->Insert (fragmentExtension);
1502 ipv6ExtensionDemux->Insert (routingExtension);
1503 // ipv6ExtensionDemux->Insert (espExtension);
1504 // ipv6ExtensionDemux->Insert (ahExtension);
1505
1506 Ptr<Ipv6ExtensionRoutingDemux> routingExtensionDemux = CreateObject<Ipv6ExtensionRoutingDemux> ();
1507 routingExtensionDemux->SetNode (m_node);
1508 Ptr<Ipv6ExtensionLooseRouting> looseRoutingExtension = CreateObject<Ipv6ExtensionLooseRouting> ();
1509 looseRoutingExtension->SetNode (m_node);
1510 routingExtensionDemux->Insert (looseRoutingExtension);
1511
1512 m_node->AggregateObject (routingExtensionDemux);
1513 m_node->AggregateObject (ipv6ExtensionDemux);
1514}
1515
1517{
1518 Ptr<Ipv6OptionDemux> ipv6OptionDemux = CreateObject<Ipv6OptionDemux> ();
1519 ipv6OptionDemux->SetNode (m_node);
1520
1521 Ptr<Ipv6OptionPad1> pad1Option = CreateObject<Ipv6OptionPad1> ();
1522 pad1Option->SetNode (m_node);
1523 Ptr<Ipv6OptionPadn> padnOption = CreateObject<Ipv6OptionPadn> ();
1524 padnOption->SetNode (m_node);
1525 Ptr<Ipv6OptionJumbogram> jumbogramOption = CreateObject<Ipv6OptionJumbogram> ();
1526 jumbogramOption->SetNode (m_node);
1527 Ptr<Ipv6OptionRouterAlert> routerAlertOption = CreateObject<Ipv6OptionRouterAlert> ();
1528 routerAlertOption->SetNode (m_node);
1529
1530 ipv6OptionDemux->Insert (pad1Option);
1531 ipv6OptionDemux->Insert (padnOption);
1532 ipv6OptionDemux->Insert (jumbogramOption);
1533 ipv6OptionDemux->Insert (routerAlertOption);
1534
1535 m_node->AggregateObject (ipv6OptionDemux);
1536}
1537
1539{
1540 m_dropTrace (ipHeader, p, dropReason, this, 0);
1541}
1542
1544{
1545 NS_LOG_FUNCTION (address << interface);
1546
1547 if (!address.IsMulticast ())
1548 {
1549 NS_LOG_WARN ("Not adding a non-multicast address " << address);
1550 return;
1551 }
1552
1553 Ipv6RegisteredMulticastAddressKey_t key = std::make_pair (address, interface);
1554 m_multicastAddresses[key]++;
1555}
1556
1558{
1560
1561 if (!address.IsMulticast ())
1562 {
1563 NS_LOG_WARN ("Not adding a non-multicast address " << address);
1564 return;
1565 }
1566
1568}
1569
1571{
1572 NS_LOG_FUNCTION (address << interface);
1573
1574 Ipv6RegisteredMulticastAddressKey_t key = std::make_pair (address, interface);
1575
1576 m_multicastAddresses[key]--;
1577 if (m_multicastAddresses[key] == 0)
1578 {
1579 m_multicastAddresses.erase (key);
1580 }
1581}
1582
1584{
1586
1589 {
1591 }
1592}
1593
1595{
1596 NS_LOG_FUNCTION (address << interface);
1597
1598 Ipv6RegisteredMulticastAddressKey_t key = std::make_pair (address, interface);
1600
1601 if (iter == m_multicastAddresses.end ())
1602 {
1603 return false;
1604 }
1605 return true;
1606}
1607
1609{
1611
1613
1614 if (iter == m_multicastAddressesNoInterface.end ())
1615 {
1616 return false;
1617 }
1618 return true;
1619}
1620
1622{
1623 if (ipInterfaceIndex >= m_interfaces.size ())
1624 {
1625 return false;
1626 }
1627
1628 Ptr<NdiscCache> ndiscCache = m_interfaces[ipInterfaceIndex]->GetNdiscCache ();
1629 if (!ndiscCache)
1630 {
1631 return false;
1632 }
1633
1634 NdiscCache::Entry* entry = ndiscCache->Lookup (address);
1635 if (!entry || entry->IsIncomplete ())
1636 {
1637 return false;
1638 }
1639
1640
1641 if (entry->IsReachable ())
1642 {
1643 entry->UpdateReachableTimer ();
1644 }
1645 else if (entry->IsPermanent ())
1646 {
1647 return true;
1648 }
1649 else if (entry->IsProbe ())
1650 {
1651 // we just confirm the entry's MAC address to get the waiting packets (if any)
1652 std::list<NdiscCache::Ipv6PayloadHeaderPair> waiting = entry->MarkReachable (entry->GetMacAddress ());
1653 for (std::list<NdiscCache::Ipv6PayloadHeaderPair>::const_iterator it = waiting.begin (); it != waiting.end (); it++)
1654 {
1655 ndiscCache->GetInterface ()->Send (it->first, it->second, it->second.GetSource ());
1656 }
1657 entry->ClearWaitingPacket ();
1658 entry->StartReachableTimer ();
1659 }
1660 else // STALE OR DELAY
1661 {
1662 entry->MarkReachable ();
1663 entry->StartReachableTimer ();
1664 }
1665
1666
1667 return true;
1668}
1669
1670} /* namespace ns3 */
1671
#define max(a, b)
Definition: 80211b.c:43
a polymophic address class
Definition: address.h:91
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(void) const =0
Returns the protocol number of this protocol.
virtual enum RxStatus Receive(Ptr< Packet > p, Ipv4Header const &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:115
uint8_t GetHopLimit(void) const
Get the "Hop limit" field (TTL).
Definition: ipv6-header.cc:90
Ipv6Address GetSource(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:105
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
Definition: ipv6-header.cc:163
void SetSource(Ipv6Address src)
Set the "Source address" field.
Definition: ipv6-header.cc:95
uint8_t GetNextHeader(void) const
Get the next header.
Definition: ipv6-header.cc:80
void SetHopLimit(uint8_t limit)
Set the "Hop limit" field (TTL).
Definition: ipv6-header.cc:85
void SetPayloadLength(uint16_t len)
Set the "Payload length" field.
Definition: ipv6-header.cc:65
uint16_t GetPayloadLength(void) const
Get the "Payload length" field.
Definition: ipv6-header.cc:70
void SetTrafficClass(uint8_t traffic)
Set the "Traffic class" field.
Definition: ipv6-header.cc:45
Ipv6Address GetDestination(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:125
void SetNextHeader(uint8_t next)
Set the "Next header" field.
Definition: ipv6-header.cc:75
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 ?
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.
uint32_t GetNAddresses(void) const
Get number of addresses on this IPv6 interface.
void SetMetric(uint16_t metric)
Set the metric.
virtual Ptr< NetDevice > GetDevice() const
Get the NetDevice.
IPv6 layer implementation.
Ptr< Ipv6PmtuCache > m_pmtuCache
Path MTU Cache.
bool IsForwarding(uint32_t i) const
Is interface allows forwarding ?
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.
std::map< Ipv6RegisteredMulticastAddressKey_t, uint32_t >::const_iterator Ipv6RegisteredMulticastAddressCIter_t
Container Const Iterator of the IPv6 multicast addresses.
virtual ~Ipv6L3Protocol()
Destructor.
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 SetForwarding(uint32_t i, bool val)
Enable or disable forwarding on interface.
Ipv6InterfaceAddress GetAddress(uint32_t interfaceIndex, uint32_t addressIndex) const
Get an address.
TracedCallback< Ptr< const Packet >, Ptr< Ipv6 >, uint32_t > m_txTrace
Callback to trace TX (transmission) packets.
bool m_sendIcmpv6Redirect
Allow ICMPv6 Redirect sending state.
virtual void RegisterExtensions()
Register the IPv6 Extensions.
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.
TracedCallback< Ptr< const Packet >, Ptr< Ipv6 >, uint32_t > m_rxTrace
Callback to trace RX (reception) 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.
uint16_t GetMetric(uint32_t i) const
Get metric for an interface.
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.
Ipv6RegisteredMulticastAddressNoInterface_t m_multicastAddressesNoInterface
List of multicast IP addresses of interest for all the interfaces.
int32_t GetInterfaceForPrefix(Ipv6Address addr, Ipv6Prefix mask) const
Get interface index which match specified address/prefix.
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.
Ptr< Node > m_node
Node attached to stack.
uint32_t AddInterface(Ptr< NetDevice > device)
Add IPv6 interface for a device.
Ptr< NetDevice > GetNetDevice(uint32_t i)
Get device by index.
Ptr< Ipv6RoutingProtocol > GetRoutingProtocol() const
Get current routing protocol used.
virtual bool GetIpForward() const
Get IPv6 forwarding state.
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.
void SetMetric(uint32_t i, uint16_t metric)
Set metric for an interface.
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.
int32_t GetInterfaceForAddress(Ipv6Address addr) const
Get interface index which has specified IPv6 address.
virtual void ReportDrop(Ipv6Header ipHeader, Ptr< Packet > p, DropReason dropReason)
Report a packet drop.
void SetupLoopback()
Setup loopback interface.
Ptr< Socket > CreateRawSocket()
Create raw IPv6 socket.
virtual Ptr< IpL4Protocol > GetProtocol(int protocolNumber) const
Get L4 protocol by protocol number.
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.
bool RemoveAddress(uint32_t interfaceIndex, uint32_t addressIndex)
Remove an address from an interface.
virtual void Remove(Ptr< IpL4Protocol > protocol)
Remove a L4 protocol.
TracedCallback< const Ipv6Header &, Ptr< const Packet >, uint32_t > m_unicastForwardTrace
Trace of unicast forwarded packets.
Ipv6Address SourceAddressSelection(uint32_t interface, Ipv6Address dest)
Choose the source address to use with destination address.
bool m_mtuDiscover
MTU Discover (i.e.
void SetDefaultTtl(uint8_t ttl)
Set the default TTL.
void SetUp(uint32_t i)
Set an interface up.
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.
void LocalDeliver(Ptr< const Packet > p, Ipv6Header const &ip, uint32_t iif)
Deliver a packet.
std::map< Ipv6Address, uint32_t >::const_iterator Ipv6RegisteredMulticastAddressNoInterfaceCIter_t
Container Const Iterator of the IPv6 multicast addresses.
virtual bool GetMtuDiscover(void) const
Get IPv6 MTU discover state.
void RemoveMulticastAddress(Ipv6Address address)
Removes a multicast address from the list of addresses to pass to local deliver.
virtual void SetMtuDiscover(bool mtuDiscover)
Set IPv6 MTU discover state.
void SetRoutingProtocol(Ptr< Ipv6RoutingProtocol > routingProtocol)
Set routing protocol for this stack.
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 IpMulticastForward(Ptr< const NetDevice > idev, Ptr< Ipv6MulticastRoute > mrtentry, Ptr< const Packet > p, const Ipv6Header &header)
Forward a multicast packet.
bool IsUp(uint32_t i) const
Is specified interface up ?
uint16_t GetMtu(uint32_t i) const
Get MTU for an interface.
TracedCallback< const Ipv6Header &, Ptr< const Packet >, uint32_t > m_sendOutgoingTrace
Trace of sent packets.
int32_t GetInterfaceForDevice(Ptr< const NetDevice > device) const
Get interface index which is on a specified net device.
void SetDown(uint32_t i)
set an interface down.
uint32_t GetNAddresses(uint32_t interface) const
Get number of address for an interface.
void DeleteRawSocket(Ptr< Socket > socket)
Remove raw IPv6 socket.
virtual void SetPmtu(Ipv6Address dst, uint32_t pmtu)
Set the Path MTU for the specified IPv6 destination address.
Ipv6InterfaceReverseContainer m_reverseInterfacesContainer
Container of NetDevice / Interface index associations.
bool m_strongEndSystemModel
Rejects packets directed to an interface with wrong address (RFC 1222).
TracedCallback< const Ipv6Header &, Ptr< const Packet >, DropReason, Ptr< Ipv6 >, uint32_t > m_dropTrace
Callback to trace drop packets.
virtual void Send(Ptr< Packet > packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr< Ipv6Route > route)
Higher-level layers call this method to send a packet down the stack to the MAC and PHY layers.
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.
virtual void RegisterOptions()
Register the IPv6 Options.
bool AddAddress(uint32_t i, Ipv6InterfaceAddress address, bool addOnLinkRoute=true)
Add an address on interface.
std::pair< Ipv6Address, uint64_t > Ipv6RegisteredMulticastAddressKey_t
IPv6 multicast addresses / interface key.
void SendRealOut(Ptr< Ipv6Route > route, Ptr< Packet > packet, Ipv6Header const &ipHeader)
Send packet with route.
std::pair< int, int32_t > L4ListKey_t
Container of the IPv6 L4 keys: protocol number, interface index.
virtual void NotifyNewAggregate()
Notify other components connected to the node that a new stack member is now connected.
virtual void DoDispose()
Dispose object.
Ipv6L3Protocol()
Constructor.
virtual void SetIpForward(bool forward)
Set IPv6 forwarding state.
uint32_t GetNInterfaces() const
Get current number of interface on this stack.
static TypeId GetTypeId()
Get the type ID of this class.
virtual void Insert(Ptr< IpL4Protocol > protocol)
Add a L4 protocol.
TracedCallback< const Ipv6Header &, Ptr< const Packet >, uint32_t > m_localDeliverTrace
Trace of locally delivered packets.
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:161
bool IsPermanent() const
Is the entry PERMANENT.
Definition: ndisc-cache.cc:587
void ClearWaitingPacket()
Clear the waiting packet list.
Definition: ndisc-cache.cc:264
void StartReachableTimer()
Start the reachable timer.
Definition: ndisc-cache.cc:424
void UpdateReachableTimer()
Update the reachable timer.
Definition: ndisc-cache.cc:438
Address GetMacAddress() const
Get the MAC address of this entry.
Definition: ndisc-cache.cc:593
std::list< Ipv6PayloadHeaderPair > MarkReachable(Address mac)
Changes the state to this entry to REACHABLE.
Definition: ndisc-cache.cc:510
bool IsIncomplete() const
Is the entry INCOMPLETE.
Definition: ndisc-cache.cc:575
bool IsProbe() const
Is the entry PROBE.
Definition: ndisc-cache.cc:581
bool IsReachable() const
Is the entry REACHABLE.
Definition: ndisc-cache.cc:563
virtual NdiscCache::Entry * Lookup(Ipv6Address dst)
Lookup in the cache.
Definition: ndisc-cache.cc:93
std::list< NdiscCache::Entry * > LookupInverse(Address dst)
Lookup in the cache for a MAC address.
Definition: ndisc-cache.cc:108
Ptr< Ipv6Interface > GetInterface() const
Get the Ipv6Interface associated with this cache.
Definition: ndisc-cache.cc:81
virtual Address GetAddress(void) const =0
virtual uint32_t GetIfIndex(void) const =0
virtual uint16_t GetMtu(void) const =0
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:297
uint32_t GetId(void) const
Definition: node.cc:109
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:130
uint32_t GetNDevices(void) const
Definition: node.cc:152
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:144
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:229
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:252
virtual void NotifyNewAggregate(void)
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:325
Container for a set of ns3::Object pointers.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:963
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:378
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
Definition: packet.cc:355
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Definition: packet.cc:362
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer.
Definition: socket.h:1165
uint8_t GetHopLimit(void) const
Get the tag's Hop Limit.
Definition: socket.cc:671
indicates whether the socket has IPV6_TCLASS set.
Definition: socket.h:1356
uint8_t GetTclass(void) const
Get the tag's Tclass.
Definition: socket.cc:906
indicates whether the socket has a priority set.
Definition: socket.h:1309
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:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Hold an unsigned integer type.
Definition: uinteger.h:44
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#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:88
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:85
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:81
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:45
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#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:265
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:576
#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:44
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:415
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648