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  uint32_t tmp = 0;
229 
230  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
231  {
232  if (index == tmp)
233  {
234  return *it;
235  }
236  tmp++;
237  }
238  return 0;
239 }
240 
242 {
244  return m_nInterfaces;
245 }
246 
248 {
249  NS_LOG_FUNCTION (this << address);
250  int32_t index = 0;
251 
252  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
253  {
254  uint32_t j = 0;
255  uint32_t max = (*it)->GetNAddresses ();
256 
257  for (j = 0; j < max; j++)
258  {
259  if ((*it)->GetAddress (j).GetAddress () == address)
260  {
261  return index;
262  }
263  }
264  index++;
265  }
266  return -1;
267 }
268 
270 {
271  NS_LOG_FUNCTION (this << address << mask);
272  int32_t index = 0;
273 
274  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
275  {
276  uint32_t j = 0;
277  for (j = 0; j < (*it)->GetNAddresses (); j++)
278  {
279  if ((*it)->GetAddress (j).GetAddress ().CombinePrefix (mask) == address.CombinePrefix (mask))
280  {
281  return index;
282  }
283  }
284  index++;
285  }
286  return -1;
287 }
288 
290 {
291  NS_LOG_FUNCTION (this << i);
292  return GetInterface (i)->GetDevice ();
293 }
294 
296 {
297  NS_LOG_FUNCTION (this << device);
298 
299  Ipv6InterfaceReverseContainer::const_iterator iter = m_reverseInterfacesContainer.find (device);
300  if (iter != m_reverseInterfacesContainer.end ())
301  {
302  return (*iter).second;
303  }
304 
305  return -1;
306 }
307 
308 void Ipv6L3Protocol::AddAutoconfiguredAddress (uint32_t interface, Ipv6Address network, Ipv6Prefix mask, uint8_t flags, uint32_t validTime, uint32_t preferredTime, Ipv6Address defaultRouter)
309 {
310  NS_LOG_FUNCTION (this << interface << network << mask << (uint32_t)flags << validTime << preferredTime);
312 
313  Address addr = GetInterface (interface)->GetDevice ()->GetAddress ();
314 
315  if (flags & (1 << 6)) /* auto flag */
316  {
317  // In case of new MacAddress types, remember to change Ipv6L3Protocol::RemoveAutoconfiguredAddress as well
318  if (Mac64Address::IsMatchingType (addr))
319  {
321  }
322  else if (Mac48Address::IsMatchingType (addr))
323  {
325  }
326  else if (Mac16Address::IsMatchingType (addr))
327  {
329  }
330  else
331  {
332  NS_FATAL_ERROR ("Unknown method to make autoconfigured address for this kind of device.");
333  return;
334  }
335 
336  /* see if we have already the prefix */
337  for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin (); it != m_prefixes.end (); ++it)
338  {
339  if ((*it)->GetInterface () == interface && (*it)->GetPrefix () == network && (*it)->GetMask () == mask)
340  {
341  (*it)->StopPreferredTimer ();
342  (*it)->StopValidTimer ();
343  (*it)->StartPreferredTimer ();
344  return;
345  }
346  }
347 
348  /* no prefix found, add autoconfigured address and the prefix */
349  NS_LOG_INFO ("Autoconfigured address is :" << address.GetAddress ());
350  AddAddress (interface, address);
351 
352  /* add default router
353  * if a previous default route exists, the new ones is simply added
354  */
355  if (!defaultRouter.IsAny())
356  {
357  GetRoutingProtocol ()->NotifyAddRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
358  }
359 
360  Ptr<Ipv6AutoconfiguredPrefix> aPrefix = CreateObject<Ipv6AutoconfiguredPrefix> (m_node, interface, network, mask, preferredTime, validTime, defaultRouter);
361  aPrefix->StartPreferredTimer ();
362 
363  m_prefixes.push_back (aPrefix);
364  }
365 }
366 
367 void Ipv6L3Protocol::RemoveAutoconfiguredAddress (uint32_t interface, Ipv6Address network, Ipv6Prefix mask, Ipv6Address defaultRouter)
368 {
369  NS_LOG_FUNCTION (this << interface << network << mask);
370  Ptr<Ipv6Interface> iface = GetInterface (interface);
371  Address addr = iface->GetDevice ()->GetAddress ();
372  uint32_t max = iface->GetNAddresses ();
373  uint32_t i = 0;
374  Ipv6Address toFound;
375 
376  if (Mac64Address::IsMatchingType (addr))
377  {
379  }
380  else if (Mac48Address::IsMatchingType (addr))
381  {
383  }
384  else if (Mac16Address::IsMatchingType (addr))
385  {
387  }
388  else
389  {
390  NS_FATAL_ERROR ("Unknown method to make autoconfigured address for this kind of device.");
391  return;
392  }
393 
394  for (i = 0; i < max; i++)
395  {
396  if (iface->GetAddress (i).GetAddress () == toFound)
397  {
398  RemoveAddress (interface, i);
399  break;
400  }
401  }
402 
403  /* remove from list of autoconfigured address */
404  for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin (); it != m_prefixes.end (); ++it)
405  {
406  if ((*it)->GetInterface () == interface && (*it)->GetPrefix () == network && (*it)->GetMask () == mask)
407  {
408  *it = 0;
409  m_prefixes.erase (it);
410  break;
411  }
412  }
413 
414  GetRoutingProtocol ()->NotifyRemoveRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
415 }
416 
418 {
419  NS_LOG_FUNCTION (this << i << address);
420  Ptr<Ipv6Interface> interface = GetInterface (i);
421  bool ret = interface->AddAddress (address);
422 
423  if (m_routingProtocol != 0)
424  {
425  m_routingProtocol->NotifyAddAddress (i, address);
426  }
427  return ret;
428 }
429 
430 uint32_t Ipv6L3Protocol::GetNAddresses (uint32_t i) const
431 {
432  NS_LOG_FUNCTION (this << i);
433  Ptr<Ipv6Interface> interface = GetInterface (i);
434  return interface->GetNAddresses ();
435 }
436 
437 Ipv6InterfaceAddress Ipv6L3Protocol::GetAddress (uint32_t i, uint32_t addressIndex) const
438 {
439  NS_LOG_FUNCTION (this << i << addressIndex);
440  Ptr<Ipv6Interface> interface = GetInterface (i);
441  return interface->GetAddress (addressIndex);
442 }
443 
444 bool Ipv6L3Protocol::RemoveAddress (uint32_t i, uint32_t addressIndex)
445 {
446  NS_LOG_FUNCTION (this << i << addressIndex);
447  Ptr<Ipv6Interface> interface = GetInterface (i);
448  Ipv6InterfaceAddress address = interface->RemoveAddress (addressIndex);
449 
450  if (address != Ipv6InterfaceAddress ())
451  {
452  if (m_routingProtocol != 0)
453  {
454  m_routingProtocol->NotifyRemoveAddress (i, address);
455  }
456  return true;
457  }
458  return false;
459 }
460 
461 bool
463 {
464  NS_LOG_FUNCTION (this << i << address);
465 
466  if (address == Ipv6Address::GetLoopback())
467  {
468  NS_LOG_WARN ("Cannot remove loopback address.");
469  return false;
470  }
471  Ptr<Ipv6Interface> interface = GetInterface (i);
472  Ipv6InterfaceAddress ifAddr = interface->RemoveAddress (address);
473  if (ifAddr != Ipv6InterfaceAddress ())
474  {
475  if (m_routingProtocol != 0)
476  {
477  m_routingProtocol->NotifyRemoveAddress (i, ifAddr);
478  }
479  return true;
480  }
481  return false;
482 }
483 
484 void Ipv6L3Protocol::SetMetric (uint32_t i, uint16_t metric)
485 {
486  NS_LOG_FUNCTION (this << i << metric);
487  Ptr<Ipv6Interface> interface = GetInterface (i);
488  interface->SetMetric (metric);
489 }
490 
491 uint16_t Ipv6L3Protocol::GetMetric (uint32_t i) const
492 {
493  NS_LOG_FUNCTION (this << i);
494  Ptr<Ipv6Interface> interface = GetInterface (i);
495  return interface->GetMetric ();
496 }
497 
498 uint16_t Ipv6L3Protocol::GetMtu (uint32_t i) const
499 {
500  NS_LOG_FUNCTION (this << i);
501 
502  // RFC 1981, if PMTU is disabled, return the minimum MTU
503  if (!m_mtuDiscover)
504  {
505  return IPV6_MIN_MTU;
506  }
507 
508  Ptr<Ipv6Interface> interface = GetInterface (i);
509  return interface->GetDevice ()->GetMtu ();
510 }
511 
512 void Ipv6L3Protocol::SetPmtu (Ipv6Address dst, uint32_t pmtu)
513 {
514  NS_LOG_FUNCTION (this << dst << int(pmtu));
515  m_pmtuCache->SetPmtu (dst, pmtu);
516 }
517 
518 
519 bool Ipv6L3Protocol::IsUp (uint32_t i) const
520 {
521  NS_LOG_FUNCTION (this << i);
522  Ptr<Ipv6Interface> interface = GetInterface (i);
523  return interface->IsUp ();
524 }
525 
526 void Ipv6L3Protocol::SetUp (uint32_t i)
527 {
528  NS_LOG_FUNCTION (this << i);
529  Ptr<Ipv6Interface> interface = GetInterface (i);
530 
531  // RFC 2460, Section 5, pg. 24:
532  // IPv6 requires that every link in the internet have an MTU of 1280
533  // octets or greater. On any link that cannot convey a 1280-octet
534  // packet in one piece, link-specific fragmentation and reassembly must
535  // be provided at a layer below IPv6.
536  if (interface->GetDevice ()->GetMtu () >= 1280)
537  {
538  interface->SetUp ();
539 
540  if (m_routingProtocol != 0)
541  {
542  m_routingProtocol->NotifyInterfaceUp (i);
543  }
544  }
545  else
546  {
547  NS_LOG_LOGIC ("Interface " << int(i) << " is set to be down for IPv6. Reason: not respecting minimum IPv6 MTU (1280 octets)");
548  }
549 }
550 
551 void Ipv6L3Protocol::SetDown (uint32_t i)
552 {
553  NS_LOG_FUNCTION (this << i);
554  Ptr<Ipv6Interface> interface = GetInterface (i);
555 
556  interface->SetDown ();
557 
558  if (m_routingProtocol != 0)
559  {
560  m_routingProtocol->NotifyInterfaceDown (i);
561  }
562 }
563 
565 {
567  Ptr<Ipv6Interface> interface = CreateObject<Ipv6Interface> ();
568  Ptr<LoopbackNetDevice> device = 0;
569  uint32_t i = 0;
570 
571  /* see if we have already an loopback NetDevice */
572  for (i = 0; i < m_node->GetNDevices (); i++)
573  {
574  if ((device = DynamicCast<LoopbackNetDevice> (m_node->GetDevice (i))))
575  {
576  break;
577  }
578  }
579 
580  if (device == 0)
581  {
582  device = CreateObject<LoopbackNetDevice> ();
583  m_node->AddDevice (device);
584  }
585 
586  interface->SetDevice (device);
587  interface->SetNode (m_node);
589  interface->AddAddress (ifaceAddr);
590  uint32_t index = AddIpv6Interface (interface);
591  Ptr<Node> node = GetObject<Node> ();
592  node->RegisterProtocolHandler (MakeCallback (&Ipv6L3Protocol::Receive, this), Ipv6L3Protocol::PROT_NUMBER, device);
593  interface->SetUp ();
594 
595  if (m_routingProtocol != 0)
596  {
597  m_routingProtocol->NotifyInterfaceUp (index);
598  }
599 }
600 
601 bool Ipv6L3Protocol::IsForwarding (uint32_t i) const
602 {
603  NS_LOG_FUNCTION (this << i);
604  Ptr<Ipv6Interface> interface = GetInterface (i);
605 
606  NS_LOG_LOGIC ("Forwarding state: " << interface->IsForwarding ());
607  return interface->IsForwarding ();
608 }
609 
610 void Ipv6L3Protocol::SetForwarding (uint32_t i, bool val)
611 {
612  NS_LOG_FUNCTION (this << i << val);
613  Ptr<Ipv6Interface> interface = GetInterface (i);
614  interface->SetForwarding (val);
615 }
616 
618 {
619  NS_LOG_FUNCTION (this << interface << dest);
620  Ipv6Address ret;
621 
622  if (dest.IsLinkLocal () || dest.IsLinkLocalMulticast ())
623  {
624  for (uint32_t i = 0; i < GetNAddresses (interface); i++)
625  {
626  Ipv6InterfaceAddress test = GetAddress (interface, i);
628  {
629  return test.GetAddress ();
630  }
631  }
632  NS_ASSERT_MSG (false, "No link-local address found on interface " << interface);
633  }
634 
635  for (uint32_t i = 0; i < GetNAddresses (interface); i++)
636  {
637  Ipv6InterfaceAddress test = GetAddress (interface, i);
638 
639  if (test.GetScope () == Ipv6InterfaceAddress::GLOBAL)
640  {
641  if (test.IsInSameSubnet (dest))
642  {
643  return test.GetAddress ();
644  }
645  else
646  {
647  ret = test.GetAddress ();
648  }
649  }
650  }
651 
652  // no specific match found. Use a global address (any useful is fine).
653  return ret;
654 }
655 
656 void Ipv6L3Protocol::SetIpForward (bool forward)
657 {
658  NS_LOG_FUNCTION (this << forward);
659  m_ipForward = forward;
660 
661  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
662  {
663  (*it)->SetForwarding (forward);
664  }
665 }
666 
668 {
670  return m_ipForward;
671 }
672 
673 void Ipv6L3Protocol::SetMtuDiscover (bool mtuDiscover)
674 {
675  NS_LOG_FUNCTION (this << int(mtuDiscover));
676  m_mtuDiscover = mtuDiscover;
677 }
678 
680 {
681  NS_LOG_FUNCTION (this);
682  return m_mtuDiscover;
683 }
684 
685 void Ipv6L3Protocol::SetSendIcmpv6Redirect (bool sendIcmpv6Redirect)
686 {
687  NS_LOG_FUNCTION (this << sendIcmpv6Redirect);
688  m_sendIcmpv6Redirect = sendIcmpv6Redirect;
689 }
690 
692 {
694  return m_sendIcmpv6Redirect;
695 }
696 
698 {
700 
701  if (m_node == 0)
702  {
703  Ptr<Node> node = this->GetObject<Node> ();
704  // verify that it's a valid node and that
705  // the node has not been set before
706  if (node != 0)
707  {
708  this->SetNode (node);
709  }
710  }
712 }
713 
715 {
716  NS_LOG_FUNCTION (this << node);
717  m_node = node;
718  /* add LoopbackNetDevice if needed, and an Ipv6Interface on top of it */
719  SetupLoopback ();
720 }
721 
723 {
724  NS_LOG_FUNCTION (this << protocol);
725  L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), -1);
726  if (m_protocols.find (key) != m_protocols.end ())
727  {
728  NS_LOG_WARN ("Overwriting default protocol " << int(protocol->GetProtocolNumber ()));
729  }
730  m_protocols[key] = protocol;
731 }
732 
733 void Ipv6L3Protocol::Insert (Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
734 {
735  NS_LOG_FUNCTION (this << protocol << interfaceIndex);
736 
737  L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), interfaceIndex);
738  if (m_protocols.find (key) != m_protocols.end ())
739  {
740  NS_LOG_WARN ("Overwriting protocol " << int(protocol->GetProtocolNumber ()) << " on interface " << int(interfaceIndex));
741  }
742  m_protocols[key] = protocol;
743 }
744 
746 {
747  NS_LOG_FUNCTION (this << protocol);
748 
749  L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), -1);
750  L4List_t::iterator iter = m_protocols.find (key);
751  if (iter == m_protocols.end ())
752  {
753  NS_LOG_WARN ("Trying to remove an non-existent default protocol " << int(protocol->GetProtocolNumber ()));
754  }
755  else
756  {
757  m_protocols.erase (key);
758  }
759 }
760 
761 void Ipv6L3Protocol::Remove (Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
762 {
763  NS_LOG_FUNCTION (this << protocol << interfaceIndex);
764 
765  L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), interfaceIndex);
766  L4List_t::iterator iter = m_protocols.find (key);
767  if (iter == m_protocols.end ())
768  {
769  NS_LOG_WARN ("Trying to remove an non-existent protocol " << int(protocol->GetProtocolNumber ()) << " on interface " << int(interfaceIndex));
770  }
771  else
772  {
773  m_protocols.erase (key);
774  }
775 }
776 
778 {
779  NS_LOG_FUNCTION (this << protocolNumber);
780 
781  return GetProtocol (protocolNumber, -1);
782 }
783 
784 Ptr<IpL4Protocol> Ipv6L3Protocol::GetProtocol (int protocolNumber, int32_t interfaceIndex) const
785 {
786  NS_LOG_FUNCTION (this << protocolNumber << interfaceIndex);
787 
788  L4ListKey_t key;
789  L4List_t::const_iterator i;
790  if (interfaceIndex >= 0)
791  {
792  // try the interface-specific protocol.
793  key = std::make_pair (protocolNumber, interfaceIndex);
794  i = m_protocols.find (key);
795  if (i != m_protocols.end ())
796  {
797  return i->second;
798  }
799  }
800  // try the generic protocol.
801  key = std::make_pair (protocolNumber, -1);
802  i = m_protocols.find (key);
803  if (i != m_protocols.end ())
804  {
805  return i->second;
806  }
807 
808  return 0;
809 }
810 
812 {
814  Ptr<Ipv6RawSocketImpl> sock = CreateObject<Ipv6RawSocketImpl> ();
815  sock->SetNode (m_node);
816  m_sockets.push_back (sock);
817  return sock;
818 }
819 
821 {
822  NS_LOG_FUNCTION (this << socket);
823 
824  for (SocketList::iterator it = m_sockets.begin (); it != m_sockets.end (); ++it)
825  {
826  if ((*it) == socket)
827  {
828  m_sockets.erase (it);
829  return;
830  }
831  }
832 }
833 
835 {
838 
839  if (protocol)
840  {
841  return protocol->GetObject<Icmpv6L4Protocol> ();
842  }
843  else
844  {
845  return 0;
846  }
847 }
848 
850 {
851  NS_LOG_FUNCTION (this << ttl);
852  m_defaultTtl = ttl;
853 }
854 
855 void Ipv6L3Protocol::SetDefaultTclass (uint8_t tclass)
856 {
857  NS_LOG_FUNCTION (this << tclass);
858  m_defaultTclass = tclass;
859 }
860 
861 void Ipv6L3Protocol::Send (Ptr<Packet> packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr<Ipv6Route> route)
862 {
863  NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)protocol << route);
864  Ipv6Header hdr;
865  uint8_t ttl = m_defaultTtl;
867  bool found = packet->RemovePacketTag (tag);
868 
869  if (found)
870  {
871  ttl = tag.GetHopLimit ();
872  }
873 
874  SocketIpv6TclassTag tclassTag;
875  uint8_t tclass = m_defaultTclass;
876  found = packet->RemovePacketTag (tclassTag);
877 
878  if (found)
879  {
880  tclass = tclassTag.GetTclass ();
881  }
882 
883  /* Handle 3 cases:
884  * 1) Packet is passed in with a route entry
885  * 2) Packet is passed in with a route entry but route->GetGateway is not set (e.g., same network)
886  * 3) route is NULL (e.g., a raw socket call or ICMPv6)
887  */
888 
889  /* 1) */
890  if (route && route->GetGateway () != Ipv6Address::GetZero ())
891  {
892  NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 1: passed in with a route");
893  hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
894  int32_t interface = GetInterfaceForDevice (route->GetOutputDevice ());
895  m_sendOutgoingTrace (hdr, packet, interface);
896  SendRealOut (route, packet, hdr);
897  return;
898  }
899 
900  /* 2) */
901  if (route && route->GetGateway () == Ipv6Address::GetZero ())
902  {
903  NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 1: probably sent to machine on same IPv6 network");
904  /* NS_FATAL_ERROR ("This case is not yet implemented"); */
905  hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
906  int32_t interface = GetInterfaceForDevice (route->GetOutputDevice ());
907  m_sendOutgoingTrace (hdr, packet, interface);
908  SendRealOut (route, packet, hdr);
909  return;
910  }
911 
912  /* 3) */
913  NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 3: passed in with no route " << destination);
915  Ptr<NetDevice> oif (0);
916  Ptr<Ipv6Route> newRoute = 0;
917 
918  hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
919 
920  //for link-local traffic, we need to determine the interface
921  if (source.IsLinkLocal ()
922  || destination.IsLinkLocal ()
923  || destination.IsLinkLocalMulticast ())
924  {
925  int32_t index = GetInterfaceForAddress (source);
926  NS_ASSERT_MSG (index >= 0, "Can not find an outgoing interface for a packet with src " << source << " and dst " << destination);
927  oif = GetNetDevice (index);
928  }
929 
930  newRoute = m_routingProtocol->RouteOutput (packet, hdr, oif, err);
931 
932  if (newRoute)
933  {
934  int32_t interface = GetInterfaceForDevice (newRoute->GetOutputDevice ());
935  m_sendOutgoingTrace (hdr, packet, interface);
936  SendRealOut (newRoute, packet, hdr);
937  }
938  else
939  {
940  NS_LOG_WARN ("No route to host, drop!");
942  }
943 }
944 
945 void Ipv6L3Protocol::Receive (Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
946 {
947  NS_LOG_FUNCTION (this << device << p << protocol << from << to << packetType);
948  NS_LOG_LOGIC ("Packet from " << from << " received on node " << m_node->GetId ());
949 
950  NS_ASSERT_MSG (GetInterfaceForDevice(device) != -1, "Received a packet from an interface that is not known to IPv6");
951  uint32_t interface = GetInterfaceForDevice(device);
952 
953  Ptr<Ipv6Interface> ipv6Interface = m_interfaces[interface];
954  Ptr<Packet> packet = p->Copy ();
955 
956  if (ipv6Interface->IsUp ())
957  {
958  m_rxTrace (packet, m_node->GetObject<Ipv6> (), interface);
959  }
960  else
961  {
962  NS_LOG_LOGIC ("Dropping received packet-- interface is down");
963  Ipv6Header hdr;
964  packet->RemoveHeader (hdr);
965  m_dropTrace (hdr, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv6> (), interface);
966  return;
967  }
968 
969  Ipv6Header hdr;
970  packet->RemoveHeader (hdr);
971 
972  // Trim any residual frame padding from underlying devices
973  if (hdr.GetPayloadLength () < packet->GetSize ())
974  {
975  packet->RemoveAtEnd (packet->GetSize () - hdr.GetPayloadLength ());
976  }
977 
978  // the packet is valid, we update the NDISC cache entry (if present)
979  Ptr<NdiscCache> ndiscCache = ipv6Interface->GetNdiscCache ();
980  if (ndiscCache)
981  {
982  // case one, it's a a direct routing.
983  NdiscCache::Entry *entry = ndiscCache->Lookup (hdr.GetSourceAddress ());
984  if (entry)
985  {
986  entry->UpdateReachableTimer ();
987  }
988  else
989  {
990  // It's not in the direct routing, so it's the router, and it could have multiple IP addresses.
991  // In doubt, update all of them.
992  // Note: it's a confirmed behavior for Linux routers.
993  std::list<NdiscCache::Entry *> entryList = ndiscCache->LookupInverse (from);
994  std::list<NdiscCache::Entry *>::iterator iter;
995  for (iter = entryList.begin (); iter != entryList.end (); iter ++)
996  {
997  (*iter)->UpdateReachableTimer ();
998  }
999  }
1000  }
1001 
1002 
1003 
1004  /* forward up to IPv6 raw sockets */
1005  for (SocketList::iterator it = m_sockets.begin (); it != m_sockets.end (); ++it)
1006  {
1007  Ptr<Ipv6RawSocketImpl> socket = *it;
1008  socket->ForwardUp (packet, hdr, device);
1009  }
1010 
1011  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux> ();
1012  Ptr<Ipv6Extension> ipv6Extension = 0;
1013  uint8_t nextHeader = hdr.GetNextHeader ();
1014  bool stopProcessing = false;
1015  bool isDropped = false;
1016  DropReason dropReason;
1017 
1018  if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1019  {
1020  ipv6Extension = ipv6ExtensionDemux->GetExtension (nextHeader);
1021 
1022  if (ipv6Extension)
1023  {
1024  ipv6Extension->Process (packet, 0, hdr, hdr.GetDestinationAddress (), (uint8_t *)0, stopProcessing, isDropped, dropReason);
1025  }
1026 
1027  if (isDropped)
1028  {
1029  m_dropTrace (hdr, packet, dropReason, m_node->GetObject<Ipv6> (), interface);
1030  }
1031 
1032  if (stopProcessing)
1033  {
1034  return;
1035  }
1036  }
1037 
1039  {
1040  LocalDeliver (packet, hdr, interface);
1041  return;
1042  }
1043  else if (hdr.GetDestinationAddress ().IsAllRoutersMulticast() && ipv6Interface->IsForwarding ())
1044  {
1045  LocalDeliver (packet, hdr, interface);
1046  return;
1047  }
1048  else if (hdr.GetDestinationAddress ().IsMulticast ())
1049  {
1050  bool isSolicited = ipv6Interface->IsSolicitedMulticastAddress (hdr.GetDestinationAddress ());
1051  bool isRegisteredOnInterface = IsRegisteredMulticastAddress (hdr.GetDestinationAddress (), interface);
1052  bool isRegisteredGlobally = IsRegisteredMulticastAddress (hdr.GetDestinationAddress ());
1053  if (isSolicited || isRegisteredGlobally || isRegisteredOnInterface)
1054  {
1055  LocalDeliver (packet, hdr, interface);
1056  // do not return, the packet could be handled by a routing protocol
1057  }
1058  }
1059 
1060 
1061  for (uint32_t j = 0; j < GetNInterfaces (); j++)
1062  {
1063  if (j == interface || !m_strongEndSystemModel)
1064  {
1065  for (uint32_t i = 0; i < GetNAddresses (j); i++)
1066  {
1067  Ipv6InterfaceAddress iaddr = GetAddress (j, i);
1068  Ipv6Address addr = iaddr.GetAddress ();
1069  if (addr.IsEqual (hdr.GetDestinationAddress ()))
1070  {
1071  if (j == interface)
1072  {
1073  NS_LOG_LOGIC ("For me (destination " << addr << " match)");
1074  }
1075  else
1076  {
1077  NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << hdr.GetDestinationAddress ());
1078  }
1079  LocalDeliver (packet, hdr, interface);
1080  return;
1081  }
1082  NS_LOG_LOGIC ("Address " << addr << " not a match");
1083  }
1084  }
1085  }
1086 
1087  if (!m_routingProtocol->RouteInput (packet, hdr, device,
1092  {
1093  NS_LOG_WARN ("No route found for forwarding packet. Drop.");
1094  // Drop trace and ICMPs are courtesy of RouteInputError
1095  }
1096 }
1097 
1098 void
1100  Ptr<Ipv6> ipv6, uint32_t interface)
1101 {
1102  Ptr<Packet> packetCopy = packet->Copy ();
1103  packetCopy->AddHeader (ipHeader);
1104  m_txTrace (packetCopy, ipv6, interface);
1105 }
1106 
1108 {
1109  NS_LOG_FUNCTION (this << route << packet << ipHeader);
1110 
1111  if (!route)
1112  {
1113  NS_LOG_LOGIC ("No route to host, drop!.");
1114  return;
1115  }
1116 
1117  Ptr<NetDevice> dev = route->GetOutputDevice ();
1118  int32_t interface = GetInterfaceForDevice (dev);
1119  NS_ASSERT (interface >= 0);
1120 
1121  Ptr<Ipv6Interface> outInterface = GetInterface (interface);
1122  NS_LOG_LOGIC ("Send via NetDevice ifIndex " << dev->GetIfIndex () << " Ipv6InterfaceIndex " << interface);
1123 
1124  // Check packet size
1125  std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair> fragments;
1126 
1127  // Check if we have a Path MTU stored. If so, use it. Else, use the link MTU.
1128  size_t targetMtu = (size_t)(m_pmtuCache->GetPmtu (ipHeader.GetDestinationAddress()));
1129  if (targetMtu == 0)
1130  {
1131  targetMtu = dev->GetMtu ();
1132  }
1133 
1134  if (packet->GetSize () > targetMtu + 40) /* 40 => size of IPv6 header */
1135  {
1136  // Router => drop
1137 
1138  bool fromMe = false;
1139  for (uint32_t i=0; i<GetNInterfaces(); i++ )
1140  {
1141  for (uint32_t j=0; j<GetNAddresses(i); j++ )
1142  {
1143  if (GetAddress(i,j).GetAddress() == ipHeader.GetSourceAddress())
1144  {
1145  fromMe = true;
1146  break;
1147  }
1148  }
1149  }
1150  if (!fromMe)
1151  {
1152  Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6 ();
1153  if ( icmpv6 )
1154  {
1155  packet->AddHeader(ipHeader);
1156  icmpv6->SendErrorTooBig (packet, ipHeader.GetSourceAddress (), dev->GetMtu ());
1157  }
1158  return;
1159  }
1160 
1161  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux> ();
1162 
1163  // To get specific method GetFragments from Ipv6ExtensionFragmentation
1164  Ipv6ExtensionFragment *ipv6Fragment = dynamic_cast<Ipv6ExtensionFragment *> (PeekPointer (ipv6ExtensionDemux->GetExtension (Ipv6Header::IPV6_EXT_FRAGMENTATION)));
1165  NS_ASSERT (ipv6Fragment != 0);
1166  ipv6Fragment->GetFragments (packet, ipHeader, targetMtu, fragments);
1167  }
1168 
1169  if (!route->GetGateway ().IsEqual (Ipv6Address::GetAny ()))
1170  {
1171  if (outInterface->IsUp ())
1172  {
1173  NS_LOG_LOGIC ("Send to gateway " << route->GetGateway ());
1174 
1175  if (fragments.size () != 0)
1176  {
1177  std::ostringstream oss;
1178 
1179  for (std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair>::const_iterator it = fragments.begin (); it != fragments.end (); it++)
1180  {
1181  CallTxTrace (it->second, it->first, m_node->GetObject<Ipv6> (), interface);
1182  outInterface->Send (it->first, it->second, route->GetGateway ());
1183  }
1184  }
1185  else
1186  {
1187  CallTxTrace (ipHeader, packet, m_node->GetObject<Ipv6> (), interface);
1188  outInterface->Send (packet, ipHeader, route->GetGateway ());
1189  }
1190  }
1191  else
1192  {
1193  NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << route->GetGateway ());
1194  m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv6> (), interface);
1195  }
1196  }
1197  else
1198  {
1199  if (outInterface->IsUp ())
1200  {
1201  NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestinationAddress ());
1202 
1203  if (fragments.size () != 0)
1204  {
1205  std::ostringstream oss;
1206 
1207  for (std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair>::const_iterator it = fragments.begin (); it != fragments.end (); it++)
1208  {
1209  CallTxTrace (it->second, it->first, m_node->GetObject<Ipv6> (), interface);
1210  outInterface->Send (it->first, it->second, ipHeader.GetDestinationAddress ());
1211  }
1212  }
1213  else
1214  {
1215  CallTxTrace (ipHeader, packet, m_node->GetObject<Ipv6> (), interface);
1216  outInterface->Send (packet, ipHeader, ipHeader.GetDestinationAddress ());
1217  }
1218  }
1219  else
1220  {
1221  NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << ipHeader.GetDestinationAddress ());
1222  m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv6> (), interface);
1223  }
1224  }
1225 }
1226 
1228 {
1229  NS_LOG_FUNCTION (this << rtentry << p << header);
1230  NS_LOG_LOGIC ("Forwarding logic for node: " << m_node->GetId ());
1231 
1232  // Drop RFC 3849 packets: 2001:db8::/32
1233  if (header.GetDestinationAddress().IsDocumentation ())
1234  {
1235  NS_LOG_WARN ("Received a packet for 2001:db8::/32 (documentation class). Drop.");
1236  m_dropTrace (header, p, DROP_ROUTE_ERROR, m_node->GetObject<Ipv6> (), 0);
1237  return;
1238  }
1239 
1240  // Forwarding
1241  Ipv6Header ipHeader = header;
1242  Ptr<Packet> packet = p->Copy ();
1243  ipHeader.SetHopLimit (ipHeader.GetHopLimit () - 1);
1244 
1245  if (ipHeader.GetSourceAddress ().IsLinkLocal ())
1246  {
1247  /* no forward for link-local address */
1248  return;
1249  }
1250 
1251  if (ipHeader.GetHopLimit () == 0)
1252  {
1253  NS_LOG_WARN ("TTL exceeded. Drop.");
1254  m_dropTrace (ipHeader, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv6> (), 0);
1255  // Do not reply to multicast IPv6 address
1256  if (ipHeader.GetDestinationAddress ().IsMulticast () == false)
1257  {
1258  packet->AddHeader (ipHeader);
1259  GetIcmpv6 ()->SendErrorTimeExceeded (packet, ipHeader.GetSourceAddress (), Icmpv6Header::ICMPV6_HOPLIMIT);
1260  }
1261  return;
1262  }
1263 
1264  /* ICMPv6 Redirect */
1265 
1266  /* if we forward to a machine on the same network as the source,
1267  * we send him an ICMPv6 redirect message to notify him that a short route
1268  * exists.
1269  */
1270 
1271  /* Theoretically we should also check if the redirect target is on the same network
1272  * as the source node. On the other hand, we are sure that the router we're redirecting to
1273  * used a link-local address. As a consequence, they MUST be on the same network, the link-local net.
1274  */
1275 
1276  if (m_sendIcmpv6Redirect && (rtentry->GetOutputDevice ()==idev))
1277  {
1278  NS_LOG_LOGIC ("ICMPv6 redirect!");
1279  Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6 ();
1280  Address hardwareTarget;
1281  Ipv6Address dst = header.GetDestinationAddress ();
1282  Ipv6Address src = header.GetSourceAddress ();
1283  Ipv6Address target = rtentry->GetGateway ();
1284  Ptr<Packet> copy = p->Copy ();
1285 
1286  if (target.IsAny ())
1287  {
1288  target = dst;
1289  }
1290 
1291  copy->AddHeader (header);
1292  Ipv6Address linkLocal = GetInterface (GetInterfaceForDevice (rtentry->GetOutputDevice ()))->GetLinkLocalAddress ().GetAddress ();
1293 
1294  if (icmpv6->Lookup (target, rtentry->GetOutputDevice (), 0, &hardwareTarget))
1295  {
1296  icmpv6->SendRedirection (copy, linkLocal, src, target, dst, hardwareTarget);
1297  }
1298  else
1299  {
1300  icmpv6->SendRedirection (copy, linkLocal, src, target, dst, Address ());
1301  }
1302  }
1303  // in case the packet still has a priority tag attached, remove it
1304  SocketPriorityTag priorityTag;
1305  packet->RemovePacketTag (priorityTag);
1306  int32_t interface = GetInterfaceForDevice (rtentry->GetOutputDevice ());
1307  m_unicastForwardTrace (ipHeader, packet, interface);
1308  SendRealOut (rtentry, packet, ipHeader);
1309 }
1310 
1312 {
1313  NS_LOG_FUNCTION (this << mrtentry << p << header);
1314  NS_LOG_LOGIC ("Multicast forwarding logic for node: " << m_node->GetId ());
1315 
1316  std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap ();
1317  std::map<uint32_t, uint32_t>::iterator mapIter;
1318 
1319  for (mapIter = ttlMap.begin (); mapIter != ttlMap.end (); mapIter++)
1320  {
1321  uint32_t interfaceId = mapIter->first;
1322  //uint32_t outputTtl = mapIter->second; // Unused for now
1323  Ptr<Packet> packet = p->Copy ();
1324  Ipv6Header h = header;
1325  h.SetHopLimit (header.GetHopLimit () - 1);
1326  if (h.GetHopLimit () == 0)
1327  {
1328  NS_LOG_WARN ("TTL exceeded. Drop.");
1329  m_dropTrace (header, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv6> (), interfaceId);
1330  return;
1331  }
1332  NS_LOG_LOGIC ("Forward multicast via interface " << interfaceId);
1333  Ptr<Ipv6Route> rtentry = Create<Ipv6Route> ();
1334  rtentry->SetSource (h.GetSourceAddress ());
1335  rtentry->SetDestination (h.GetDestinationAddress ());
1336  rtentry->SetGateway (Ipv6Address::GetAny ());
1337  rtentry->SetOutputDevice (GetNetDevice (interfaceId));
1338  SendRealOut (rtentry, packet, h);
1339  continue;
1340  }
1341 }
1342 
1343 void Ipv6L3Protocol::LocalDeliver (Ptr<const Packet> packet, Ipv6Header const& ip, uint32_t iif)
1344 {
1345  NS_LOG_FUNCTION (this << packet << ip << iif);
1346  Ptr<Packet> p = packet->Copy ();
1347  Ptr<IpL4Protocol> protocol = 0;
1348  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux> ();
1349  Ptr<Ipv6Extension> ipv6Extension = 0;
1350  Ipv6Address src = ip.GetSourceAddress ();
1351  Ipv6Address dst = ip.GetDestinationAddress ();
1352  uint8_t nextHeader = ip.GetNextHeader ();
1353  uint8_t nextHeaderPosition = 0;
1354  bool isDropped = false;
1355  bool stopProcessing = false;
1356  DropReason dropReason;
1357 
1358  // check for a malformed hop-by-hop extension
1359  // this is a common case when forging IPv6 raw packets
1360  if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1361  {
1362  uint8_t buf;
1363  p->CopyData (&buf, 1);
1365  {
1366  NS_LOG_WARN("Double Ipv6Header::IPV6_EXT_HOP_BY_HOP in packet, dropping packet");
1367  return;
1368  }
1369  }
1370 
1371  /* process all the extensions found and the layer 4 protocol */
1372  do
1373  {
1374  /* it return 0 for non-extension (i.e. layer 4 protocol) */
1375  ipv6Extension = ipv6ExtensionDemux->GetExtension (nextHeader);
1376 
1377  if (ipv6Extension)
1378  {
1379  uint8_t nextHeaderStep = 0;
1380  uint8_t curHeader = nextHeader;
1381  nextHeaderStep = ipv6Extension->Process (p, nextHeaderPosition, ip, dst, &nextHeader, stopProcessing, isDropped, dropReason);
1382  nextHeaderPosition += nextHeaderStep;
1383 
1384  if (isDropped)
1385  {
1386  m_dropTrace (ip, packet, dropReason, m_node->GetObject<Ipv6> (), iif);
1387  }
1388 
1389  if (stopProcessing)
1390  {
1391  return;
1392  }
1393  NS_ASSERT_MSG (nextHeaderStep != 0 || curHeader == Ipv6Header::IPV6_EXT_FRAGMENTATION,
1394  "Zero-size IPv6 Option Header, aborting" << *packet );
1395  }
1396  else
1397  {
1398  protocol = GetProtocol (nextHeader, iif);
1399 
1400  if (!protocol)
1401  {
1402  NS_LOG_LOGIC ("Unknown Next Header. Drop!");
1403 
1404  // For ICMPv6 Error packets
1405  Ptr<Packet> malformedPacket = packet->Copy ();
1406  malformedPacket->AddHeader (ip);
1407 
1408  if (nextHeaderPosition == 0)
1409  {
1410  GetIcmpv6 ()->SendErrorParameterError (malformedPacket, dst, Icmpv6Header::ICMPV6_UNKNOWN_NEXT_HEADER, 40);
1411  }
1412  else
1413  {
1414  GetIcmpv6 ()->SendErrorParameterError (malformedPacket, dst, Icmpv6Header::ICMPV6_UNKNOWN_NEXT_HEADER, ip.GetSerializedSize () + nextHeaderPosition);
1415  }
1417  break;
1418  }
1419  else
1420  {
1421  p->RemoveAtStart (nextHeaderPosition);
1422  /* protocol->Receive (p, src, dst, incomingInterface); */
1423 
1424  /* L4 protocol */
1425  Ptr<Packet> copy = p->Copy ();
1426 
1427  m_localDeliverTrace (ip, p, iif);
1428 
1429  enum IpL4Protocol::RxStatus status = protocol->Receive (p, ip, GetInterface (iif));
1430 
1431  switch (status)
1432  {
1433  case IpL4Protocol::RX_OK:
1434  break;
1436  break;
1438  break;
1440  if (ip.GetDestinationAddress ().IsMulticast ())
1441  {
1442  /* do not rely on multicast address */
1443  break;
1444  }
1445 
1446  copy->AddHeader (ip);
1447  GetIcmpv6 ()->SendErrorDestinationUnreachable (copy, ip.GetSourceAddress (), Icmpv6Header::ICMPV6_PORT_UNREACHABLE);
1448  }
1449  }
1450  }
1451  }
1452  while (ipv6Extension);
1453 }
1454 
1456 {
1457  NS_LOG_FUNCTION (this << p << ipHeader << sockErrno);
1458  NS_LOG_LOGIC ("Route input failure-- dropping packet to " << ipHeader << " with errno " << sockErrno);
1459 
1460  m_dropTrace (ipHeader, p, DROP_ROUTE_ERROR, m_node->GetObject<Ipv6> (), 0);
1461 
1462  if (!ipHeader.GetDestinationAddress ().IsMulticast ())
1463  {
1464  Ptr<Packet> packet = p->Copy ();
1465  packet->AddHeader (ipHeader);
1466  GetIcmpv6 ()->SendErrorDestinationUnreachable (packet, ipHeader.GetSourceAddress (), Icmpv6Header::ICMPV6_NO_ROUTE);
1467  }
1468 }
1469 
1470 Ipv6Header Ipv6L3Protocol::BuildHeader (Ipv6Address src, Ipv6Address dst, uint8_t protocol, uint16_t payloadSize, uint8_t ttl, uint8_t tclass)
1471 {
1472  NS_LOG_FUNCTION (this << src << dst << (uint32_t)protocol << (uint32_t)payloadSize << (uint32_t)ttl << (uint32_t)tclass);
1473  Ipv6Header hdr;
1474 
1475  hdr.SetSourceAddress (src);
1476  hdr.SetDestinationAddress (dst);
1477  hdr.SetNextHeader (protocol);
1478  hdr.SetPayloadLength (payloadSize);
1479  hdr.SetHopLimit (ttl);
1480  hdr.SetTrafficClass (tclass);
1481  return hdr;
1482 }
1483 
1485 {
1486  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = CreateObject<Ipv6ExtensionDemux> ();
1487  ipv6ExtensionDemux->SetNode (m_node);
1488 
1489  Ptr<Ipv6ExtensionHopByHop> hopbyhopExtension = CreateObject<Ipv6ExtensionHopByHop> ();
1490  hopbyhopExtension->SetNode (m_node);
1491  Ptr<Ipv6ExtensionDestination> destinationExtension = CreateObject<Ipv6ExtensionDestination> ();
1492  destinationExtension->SetNode (m_node);
1493  Ptr<Ipv6ExtensionFragment> fragmentExtension = CreateObject<Ipv6ExtensionFragment> ();
1494  fragmentExtension->SetNode (m_node);
1495  Ptr<Ipv6ExtensionRouting> routingExtension = CreateObject<Ipv6ExtensionRouting> ();
1496  routingExtension->SetNode (m_node);
1497  // Ptr<Ipv6ExtensionESP> espExtension = CreateObject<Ipv6ExtensionESP> ();
1498  // Ptr<Ipv6ExtensionAH> ahExtension = CreateObject<Ipv6ExtensionAH> ();
1499 
1500  ipv6ExtensionDemux->Insert (hopbyhopExtension);
1501  ipv6ExtensionDemux->Insert (destinationExtension);
1502  ipv6ExtensionDemux->Insert (fragmentExtension);
1503  ipv6ExtensionDemux->Insert (routingExtension);
1504  // ipv6ExtensionDemux->Insert (espExtension);
1505  // ipv6ExtensionDemux->Insert (ahExtension);
1506 
1507  Ptr<Ipv6ExtensionRoutingDemux> routingExtensionDemux = CreateObject<Ipv6ExtensionRoutingDemux> ();
1508  routingExtensionDemux->SetNode (m_node);
1509  Ptr<Ipv6ExtensionLooseRouting> looseRoutingExtension = CreateObject<Ipv6ExtensionLooseRouting> ();
1510  looseRoutingExtension->SetNode (m_node);
1511  routingExtensionDemux->Insert (looseRoutingExtension);
1512 
1513  m_node->AggregateObject (routingExtensionDemux);
1514  m_node->AggregateObject (ipv6ExtensionDemux);
1515 }
1516 
1518 {
1519  Ptr<Ipv6OptionDemux> ipv6OptionDemux = CreateObject<Ipv6OptionDemux> ();
1520  ipv6OptionDemux->SetNode (m_node);
1521 
1522  Ptr<Ipv6OptionPad1> pad1Option = CreateObject<Ipv6OptionPad1> ();
1523  pad1Option->SetNode (m_node);
1524  Ptr<Ipv6OptionPadn> padnOption = CreateObject<Ipv6OptionPadn> ();
1525  padnOption->SetNode (m_node);
1526  Ptr<Ipv6OptionJumbogram> jumbogramOption = CreateObject<Ipv6OptionJumbogram> ();
1527  jumbogramOption->SetNode (m_node);
1528  Ptr<Ipv6OptionRouterAlert> routerAlertOption = CreateObject<Ipv6OptionRouterAlert> ();
1529  routerAlertOption->SetNode (m_node);
1530 
1531  ipv6OptionDemux->Insert (pad1Option);
1532  ipv6OptionDemux->Insert (padnOption);
1533  ipv6OptionDemux->Insert (jumbogramOption);
1534  ipv6OptionDemux->Insert (routerAlertOption);
1535 
1536  m_node->AggregateObject (ipv6OptionDemux);
1537 }
1538 
1540 {
1541  m_dropTrace (ipHeader, p, dropReason, m_node->GetObject<Ipv6> (), 0);
1542 }
1543 
1545 {
1546  NS_LOG_FUNCTION (address << interface);
1547 
1548  if (!address.IsMulticast ())
1549  {
1550  NS_LOG_WARN ("Not adding a non-multicast address " << address);
1551  return;
1552  }
1553 
1554  Ipv6RegisteredMulticastAddressKey_t key = std::make_pair (address, interface);
1555  m_multicastAddresses[key]++;
1556 }
1557 
1559 {
1560  NS_LOG_FUNCTION (address);
1561 
1562  if (!address.IsMulticast ())
1563  {
1564  NS_LOG_WARN ("Not adding a non-multicast address " << address);
1565  return;
1566  }
1567 
1569 }
1570 
1572 {
1573  NS_LOG_FUNCTION (address << interface);
1574 
1575  Ipv6RegisteredMulticastAddressKey_t key = std::make_pair (address, interface);
1576 
1577  m_multicastAddresses[key]--;
1578  if (m_multicastAddresses[key] == 0)
1579  {
1580  m_multicastAddresses.erase (key);
1581  }
1582 }
1583 
1585 {
1586  NS_LOG_FUNCTION (address);
1587 
1589  if (m_multicastAddressesNoInterface[address] == 0)
1590  {
1591  m_multicastAddressesNoInterface.erase (address);
1592  }
1593 }
1594 
1596 {
1597  NS_LOG_FUNCTION (address << interface);
1598 
1599  Ipv6RegisteredMulticastAddressKey_t key = std::make_pair (address, interface);
1601 
1602  if (iter == m_multicastAddresses.end ())
1603  {
1604  return false;
1605  }
1606  return true;
1607 }
1608 
1610 {
1611  NS_LOG_FUNCTION (address);
1612 
1614 
1615  if (iter == m_multicastAddressesNoInterface.end ())
1616  {
1617  return false;
1618  }
1619  return true;
1620 }
1621 
1622 } /* namespace ns3 */
1623 
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:268
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:34
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:1160
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
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:462
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:81
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:606
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:562
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:792
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:244
#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:340
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:1304
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.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
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:122
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:333
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:1351
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.
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:431
void SetupLoopback()
Setup loopback interface.
std::list< NdiscCache::Entry * > LookupInverse(Address dst)
Lookup in the cache for a MAC address.
Definition: ndisc-cache.cc:103
#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:91
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:228
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:831
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:531
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:356
A record that holds information about a NdiscCache entry.
Definition: ndisc-cache.h:153
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:904
void test(void)
Example use of ns3::SystemThread.
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:257
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.