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