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