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.IsLocalhost ())
605  {
606  return Ipv6Address::GetLoopback ();
607  }
608 
609  if (dest.IsLinkLocal () || dest.IsLinkLocalMulticast ())
610  {
611  for (uint32_t i = 0; i < GetNAddresses (interface); i++)
612  {
613  Ipv6InterfaceAddress test = GetAddress (interface, i);
614  if (test.GetScope () == Ipv6InterfaceAddress::LINKLOCAL)
615  {
616  return test.GetAddress ();
617  }
618  }
619  NS_ASSERT_MSG (false, "No link-local address found on interface " << interface);
620  }
621 
622  for (uint32_t i = 0; i < GetNAddresses (interface); i++)
623  {
624  Ipv6InterfaceAddress test = GetAddress (interface, i);
625 
626  if (test.GetScope () == Ipv6InterfaceAddress::GLOBAL)
627  {
628  if (test.IsInSameSubnet (dest))
629  {
630  return test.GetAddress ();
631  }
632  else
633  {
634  ret = test.GetAddress ();
635  }
636  }
637  }
638 
639  // no specific match found. Use a global address (any useful is fine).
640  NS_ASSERT_MSG (!ret.IsAny (),
641  "Could not find any address for " << dest << " on interface " << interface);
642  return ret;
643 }
644 
645 void Ipv6L3Protocol::SetIpForward (bool forward)
646 {
647  NS_LOG_FUNCTION (this << forward);
648  m_ipForward = forward;
649 
650  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
651  {
652  (*it)->SetForwarding (forward);
653  }
654 }
655 
657 {
658  NS_LOG_FUNCTION (this);
659  return m_ipForward;
660 }
661 
662 void Ipv6L3Protocol::SetMtuDiscover (bool mtuDiscover)
663 {
664  NS_LOG_FUNCTION (this << int(mtuDiscover));
665  m_mtuDiscover = mtuDiscover;
666 }
667 
669 {
670  NS_LOG_FUNCTION (this);
671  return m_mtuDiscover;
672 }
673 
674 void Ipv6L3Protocol::SetSendIcmpv6Redirect (bool sendIcmpv6Redirect)
675 {
676  NS_LOG_FUNCTION (this << sendIcmpv6Redirect);
677  m_sendIcmpv6Redirect = sendIcmpv6Redirect;
678 }
679 
681 {
682  NS_LOG_FUNCTION (this);
683  return m_sendIcmpv6Redirect;
684 }
685 
687 {
688  NS_LOG_FUNCTION (this);
689 
690  if (m_node == 0)
691  {
692  Ptr<Node> node = this->GetObject<Node> ();
693  // verify that it's a valid node and that
694  // the node has not been set before
695  if (node != 0)
696  {
697  this->SetNode (node);
698  }
699  }
700 
702 }
703 
705 {
706  NS_LOG_FUNCTION (this << node);
707  m_node = node;
708  /* add LoopbackNetDevice if needed, and an Ipv6Interface on top of it */
709  SetupLoopback ();
710 }
711 
713 {
714  NS_LOG_FUNCTION (this << protocol);
715  L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), -1);
716  if (m_protocols.find (key) != m_protocols.end ())
717  {
718  NS_LOG_WARN ("Overwriting default protocol " << int(protocol->GetProtocolNumber ()));
719  }
720  m_protocols[key] = protocol;
721 }
722 
723 void Ipv6L3Protocol::Insert (Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
724 {
725  NS_LOG_FUNCTION (this << protocol << interfaceIndex);
726 
727  L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), interfaceIndex);
728  if (m_protocols.find (key) != m_protocols.end ())
729  {
730  NS_LOG_WARN ("Overwriting protocol " << int(protocol->GetProtocolNumber ()) << " on interface " << int(interfaceIndex));
731  }
732  m_protocols[key] = protocol;
733 }
734 
736 {
737  NS_LOG_FUNCTION (this << protocol);
738 
739  L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), -1);
740  L4List_t::iterator iter = m_protocols.find (key);
741  if (iter == m_protocols.end ())
742  {
743  NS_LOG_WARN ("Trying to remove an non-existent default protocol " << int(protocol->GetProtocolNumber ()));
744  }
745  else
746  {
747  m_protocols.erase (key);
748  }
749 }
750 
751 void Ipv6L3Protocol::Remove (Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
752 {
753  NS_LOG_FUNCTION (this << protocol << interfaceIndex);
754 
755  L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), interfaceIndex);
756  L4List_t::iterator iter = m_protocols.find (key);
757  if (iter == m_protocols.end ())
758  {
759  NS_LOG_WARN ("Trying to remove an non-existent protocol " << int(protocol->GetProtocolNumber ()) << " on interface " << int(interfaceIndex));
760  }
761  else
762  {
763  m_protocols.erase (key);
764  }
765 }
766 
768 {
769  NS_LOG_FUNCTION (this << protocolNumber);
770 
771  return GetProtocol (protocolNumber, -1);
772 }
773 
774 Ptr<IpL4Protocol> Ipv6L3Protocol::GetProtocol (int protocolNumber, int32_t interfaceIndex) const
775 {
776  NS_LOG_FUNCTION (this << protocolNumber << interfaceIndex);
777 
778  L4ListKey_t key;
779  L4List_t::const_iterator i;
780  if (interfaceIndex >= 0)
781  {
782  // try the interface-specific protocol.
783  key = std::make_pair (protocolNumber, interfaceIndex);
784  i = m_protocols.find (key);
785  if (i != m_protocols.end ())
786  {
787  return i->second;
788  }
789  }
790  // try the generic protocol.
791  key = std::make_pair (protocolNumber, -1);
792  i = m_protocols.find (key);
793  if (i != m_protocols.end ())
794  {
795  return i->second;
796  }
797 
798  return 0;
799 }
800 
802 {
803  NS_LOG_FUNCTION (this);
804  Ptr<Ipv6RawSocketImpl> sock = CreateObject<Ipv6RawSocketImpl> ();
805  sock->SetNode (m_node);
806  m_sockets.push_back (sock);
807  return sock;
808 }
809 
811 {
812  NS_LOG_FUNCTION (this << socket);
813 
814  for (SocketList::iterator it = m_sockets.begin (); it != m_sockets.end (); ++it)
815  {
816  if ((*it) == socket)
817  {
818  m_sockets.erase (it);
819  return;
820  }
821  }
822 }
823 
825 {
826  NS_LOG_FUNCTION (this);
828 
829  if (protocol)
830  {
831  return protocol->GetObject<Icmpv6L4Protocol> ();
832  }
833  else
834  {
835  return 0;
836  }
837 }
838 
840 {
841  NS_LOG_FUNCTION (this << ttl);
842  m_defaultTtl = ttl;
843 }
844 
845 void Ipv6L3Protocol::SetDefaultTclass (uint8_t tclass)
846 {
847  NS_LOG_FUNCTION (this << tclass);
848  m_defaultTclass = tclass;
849 }
850 
851 void Ipv6L3Protocol::Send (Ptr<Packet> packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr<Ipv6Route> route)
852 {
853  NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)protocol << route);
854  Ipv6Header hdr;
855  uint8_t ttl = m_defaultTtl;
857  bool found = packet->RemovePacketTag (tag);
858 
859  if (found)
860  {
861  ttl = tag.GetHopLimit ();
862  }
863 
864  SocketIpv6TclassTag tclassTag;
865  uint8_t tclass = m_defaultTclass;
866  found = packet->RemovePacketTag (tclassTag);
867 
868  if (found)
869  {
870  tclass = tclassTag.GetTclass ();
871  }
872 
873  /* Handle 3 cases:
874  * 1) Packet is passed in with a route entry
875  * 2) Packet is passed in with a route entry but route->GetGateway is not set (e.g., same network)
876  * 3) route is NULL (e.g., a raw socket call or ICMPv6)
877  */
878 
879  /* 1) */
880  if (route && route->GetGateway () != Ipv6Address::GetZero ())
881  {
882  NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 1: passed in with a route");
883  hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
884  int32_t interface = GetInterfaceForDevice (route->GetOutputDevice ());
885  m_sendOutgoingTrace (hdr, packet, interface);
886  SendRealOut (route, packet, hdr);
887  return;
888  }
889 
890  /* 2) */
891  if (route && route->GetGateway () == Ipv6Address::GetZero ())
892  {
893  NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 2: probably sent to machine on same IPv6 network");
894  hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
895  int32_t interface = GetInterfaceForDevice (route->GetOutputDevice ());
896  m_sendOutgoingTrace (hdr, packet, interface);
897  SendRealOut (route, packet, hdr);
898  return;
899  }
900 
901  /* 3) */
902  NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 3: passed in with no route " << destination);
904  Ptr<NetDevice> oif (0);
905  Ptr<Ipv6Route> newRoute = 0;
906 
907  hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
908 
909  //for link-local traffic, we need to determine the interface
910  if (source.IsLinkLocal ()
911  || destination.IsLinkLocal ()
912  || destination.IsLinkLocalMulticast ())
913  {
914  int32_t index = GetInterfaceForAddress (source);
915  NS_ASSERT_MSG (index >= 0, "Can not find an outgoing interface for a packet with src " << source << " and dst " << destination);
916  oif = GetNetDevice (index);
917  }
918 
919  newRoute = m_routingProtocol->RouteOutput (packet, hdr, oif, err);
920 
921  if (newRoute)
922  {
923  int32_t interface = GetInterfaceForDevice (newRoute->GetOutputDevice ());
924  m_sendOutgoingTrace (hdr, packet, interface);
925  SendRealOut (newRoute, packet, hdr);
926  }
927  else
928  {
929  NS_LOG_WARN ("No route to host, drop!");
930  m_dropTrace (hdr, packet, DROP_NO_ROUTE, this, GetInterfaceForDevice (oif));
931  }
932 }
933 
934 void Ipv6L3Protocol::Receive (Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
935 {
936  NS_LOG_FUNCTION (this << device << p << protocol << from << to << packetType);
937  NS_LOG_LOGIC ("Packet from " << from << " received on node " << m_node->GetId ());
938 
939  NS_ASSERT_MSG (GetInterfaceForDevice(device) != -1, "Received a packet from an interface that is not known to IPv6");
940  uint32_t interface = GetInterfaceForDevice(device);
941 
942  Ptr<Ipv6Interface> ipv6Interface = m_interfaces[interface];
943  Ptr<Packet> packet = p->Copy ();
944 
945  if (ipv6Interface->IsUp ())
946  {
947  m_rxTrace (packet, this, interface);
948  }
949  else
950  {
951  NS_LOG_LOGIC ("Dropping received packet-- interface is down");
952  Ipv6Header hdr;
953  packet->RemoveHeader (hdr);
954  m_dropTrace (hdr, packet, DROP_INTERFACE_DOWN, this, interface);
955  return;
956  }
957 
958  Ipv6Header hdr;
959  packet->RemoveHeader (hdr);
960 
961  // Trim any residual frame padding from underlying devices
962  if (hdr.GetPayloadLength () < packet->GetSize ())
963  {
964  packet->RemoveAtEnd (packet->GetSize () - hdr.GetPayloadLength ());
965  }
966 
967  // the packet is valid, we update the NDISC cache entry (if present)
968  Ptr<NdiscCache> ndiscCache = ipv6Interface->GetNdiscCache ();
969  if (ndiscCache)
970  {
971  // case one, it's a a direct routing.
972  NdiscCache::Entry *entry = ndiscCache->Lookup (hdr.GetSource ());
973  if (entry)
974  {
975  entry->UpdateReachableTimer ();
976  }
977  else
978  {
979  // It's not in the direct routing, so it's the router, and it could have multiple IP addresses.
980  // In doubt, update all of them.
981  // Note: it's a confirmed behavior for Linux routers.
982  std::list<NdiscCache::Entry *> entryList = ndiscCache->LookupInverse (from);
983  std::list<NdiscCache::Entry *>::iterator iter;
984  for (iter = entryList.begin (); iter != entryList.end (); iter ++)
985  {
986  (*iter)->UpdateReachableTimer ();
987  }
988  }
989  }
990 
991 
992 
993  /* forward up to IPv6 raw sockets */
994  for (SocketList::iterator it = m_sockets.begin (); it != m_sockets.end (); ++it)
995  {
996  Ptr<Ipv6RawSocketImpl> socket = *it;
997  socket->ForwardUp (packet, hdr, device);
998  }
999 
1000  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux> ();
1001  Ptr<Ipv6Extension> ipv6Extension = 0;
1002  uint8_t nextHeader = hdr.GetNextHeader ();
1003  bool stopProcessing = false;
1004  bool isDropped = false;
1005  DropReason dropReason;
1006 
1007  if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1008  {
1009  ipv6Extension = ipv6ExtensionDemux->GetExtension (nextHeader);
1010 
1011  if (ipv6Extension)
1012  {
1013  ipv6Extension->Process (packet, 0, hdr, hdr.GetDestination (), (uint8_t *)0, stopProcessing, isDropped, dropReason);
1014  }
1015 
1016  if (isDropped)
1017  {
1018  m_dropTrace (hdr, packet, dropReason, this, interface);
1019  }
1020 
1021  if (stopProcessing)
1022  {
1023  return;
1024  }
1025  }
1026 
1027  if (hdr.GetDestination ().IsAllNodesMulticast ())
1028  {
1029  LocalDeliver (packet, hdr, interface);
1030  return;
1031  }
1032  else if (hdr.GetDestination ().IsAllRoutersMulticast() && ipv6Interface->IsForwarding ())
1033  {
1034  LocalDeliver (packet, hdr, interface);
1035  return;
1036  }
1037  else if (hdr.GetDestination ().IsMulticast ())
1038  {
1039  bool isSolicited = ipv6Interface->IsSolicitedMulticastAddress (hdr.GetDestination ());
1040  bool isRegisteredOnInterface = IsRegisteredMulticastAddress (hdr.GetDestination (), interface);
1041  bool isRegisteredGlobally = IsRegisteredMulticastAddress (hdr.GetDestination ());
1042  if (isSolicited || isRegisteredGlobally || isRegisteredOnInterface)
1043  {
1044  LocalDeliver (packet, hdr, interface);
1045  // do not return, the packet could be handled by a routing protocol
1046  }
1047  }
1048 
1049 
1050  for (uint32_t j = 0; j < GetNInterfaces (); j++)
1051  {
1052  if (j == interface || !m_strongEndSystemModel)
1053  {
1054  for (uint32_t i = 0; i < GetNAddresses (j); i++)
1055  {
1056  Ipv6InterfaceAddress iaddr = GetAddress (j, i);
1057  Ipv6Address addr = iaddr.GetAddress ();
1058  if (addr == hdr.GetDestination ())
1059  {
1060  if (j == interface)
1061  {
1062  NS_LOG_LOGIC ("For me (destination " << addr << " match)");
1063  }
1064  else
1065  {
1066  NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << hdr.GetDestination ());
1067  }
1068  LocalDeliver (packet, hdr, interface);
1069  return;
1070  }
1071  NS_LOG_LOGIC ("Address " << addr << " not a match");
1072  }
1073  }
1074  }
1075 
1076  if (!m_routingProtocol->RouteInput (packet, hdr, device,
1081  {
1082  NS_LOG_WARN ("No route found for forwarding packet. Drop.");
1083  // Drop trace and ICMPs are courtesy of RouteInputError
1084  }
1085 }
1086 
1087 void
1089  Ptr<Ipv6> ipv6, uint32_t interface)
1090 {
1091  if (!m_txTrace.IsEmpty ())
1092  {
1093  Ptr<Packet> packetCopy = packet->Copy ();
1094  packetCopy->AddHeader (ipHeader);
1095  m_txTrace (packetCopy, ipv6, interface);
1096  }
1097 }
1098 
1100 {
1101  NS_LOG_FUNCTION (this << route << packet << ipHeader);
1102 
1103  if (!route)
1104  {
1105  NS_LOG_LOGIC ("No route to host, drop!.");
1106  return;
1107  }
1108 
1109  Ptr<NetDevice> dev = route->GetOutputDevice ();
1110  int32_t interface = GetInterfaceForDevice (dev);
1111  NS_ASSERT (interface >= 0);
1112 
1113  Ptr<Ipv6Interface> outInterface = GetInterface (interface);
1114  NS_LOG_LOGIC ("Send via NetDevice ifIndex " << dev->GetIfIndex () << " Ipv6InterfaceIndex " << interface);
1115 
1116  // Check packet size
1117  std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair> fragments;
1118 
1119  // Check if this is the source of the packet
1120  bool fromMe = false;
1121  for (uint32_t i = 0; i < GetNInterfaces (); i++ )
1122  {
1123  for (uint32_t j = 0; j < GetNAddresses (i); j++ )
1124  {
1125  if (GetAddress (i,j).GetAddress () == ipHeader.GetSource ())
1126  {
1127  fromMe = true;
1128  break;
1129  }
1130  }
1131  }
1132 
1133  size_t targetMtu = 0;
1134 
1135  // Check if we have a Path MTU stored. If so, use it. Else, use the link MTU.
1136  // Note: PMTU must not be cached in intermediate nodes, and must be checked only by the source node
1137  if (fromMe)
1138  {
1139  targetMtu = (size_t)(m_pmtuCache->GetPmtu (ipHeader.GetDestination ()));
1140  }
1141  if (targetMtu == 0)
1142  {
1143  targetMtu = dev->GetMtu ();
1144  }
1145 
1146  if (packet->GetSize () + ipHeader.GetSerializedSize () > targetMtu)
1147  {
1148  // Router => drop
1149  if (!fromMe)
1150  {
1151  Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6 ();
1152  if ( icmpv6 )
1153  {
1154  packet->AddHeader (ipHeader);
1155  icmpv6->SendErrorTooBig (packet, ipHeader.GetSource (), dev->GetMtu ());
1156  }
1157  return;
1158  }
1159 
1160  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux> ();
1161 
1162  // To get specific method GetFragments from Ipv6ExtensionFragmentation
1163  Ipv6ExtensionFragment *ipv6Fragment = dynamic_cast<Ipv6ExtensionFragment *> (PeekPointer (ipv6ExtensionDemux->GetExtension (Ipv6Header::IPV6_EXT_FRAGMENTATION)));
1164  NS_ASSERT (ipv6Fragment != 0);
1165  ipv6Fragment->GetFragments (packet, ipHeader, targetMtu, fragments);
1166  }
1167 
1168  if (route->GetGateway () != Ipv6Address::GetAny ())
1169  {
1170  if (outInterface->IsUp ())
1171  {
1172  NS_LOG_LOGIC ("Send to gateway " << route->GetGateway ());
1173 
1174  if (fragments.size () != 0)
1175  {
1176  std::ostringstream oss;
1177 
1178  for (std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair>::const_iterator it = fragments.begin (); it != fragments.end (); it++)
1179  {
1180  CallTxTrace (it->second, it->first, this, interface);
1181  outInterface->Send (it->first, it->second, route->GetGateway ());
1182  }
1183  }
1184  else
1185  {
1186  CallTxTrace (ipHeader, packet, this, interface);
1187  outInterface->Send (packet, ipHeader, route->GetGateway ());
1188  }
1189  }
1190  else
1191  {
1192  NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << route->GetGateway ());
1193  m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
1194  }
1195  }
1196  else
1197  {
1198  if (outInterface->IsUp ())
1199  {
1200  NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestination ());
1201 
1202  if (fragments.size () != 0)
1203  {
1204  std::ostringstream oss;
1205 
1206  for (std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair>::const_iterator it = fragments.begin (); it != fragments.end (); it++)
1207  {
1208  CallTxTrace (it->second, it->first, this, interface);
1209  outInterface->Send (it->first, it->second, ipHeader.GetDestination ());
1210  }
1211  }
1212  else
1213  {
1214  CallTxTrace (ipHeader, packet, this, interface);
1215  outInterface->Send (packet, ipHeader, ipHeader.GetDestination ());
1216  }
1217  }
1218  else
1219  {
1220  NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << ipHeader.GetDestination ());
1221  m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
1222  }
1223  }
1224 }
1225 
1227 {
1228  NS_LOG_FUNCTION (this << rtentry << p << header);
1229  NS_LOG_LOGIC ("Forwarding logic for node: " << m_node->GetId ());
1230 
1231  // Drop RFC 3849 packets: 2001:db8::/32
1232  if (header.GetDestination().IsDocumentation ())
1233  {
1234  NS_LOG_WARN ("Received a packet for 2001:db8::/32 (documentation class). Drop.");
1235  m_dropTrace (header, p, DROP_ROUTE_ERROR, this, 0);
1236  return;
1237  }
1238 
1239  // Forwarding
1240  Ipv6Header ipHeader = header;
1241  Ptr<Packet> packet = p->Copy ();
1242  ipHeader.SetHopLimit (ipHeader.GetHopLimit () - 1);
1243 
1244  if (ipHeader.GetSource ().IsLinkLocal ())
1245  {
1246  /* no forward for link-local address */
1247  return;
1248  }
1249 
1250  if (ipHeader.GetHopLimit () == 0)
1251  {
1252  NS_LOG_WARN ("TTL exceeded. Drop.");
1253  m_dropTrace (ipHeader, packet, DROP_TTL_EXPIRED, this, 0);
1254  // Do not reply to multicast IPv6 address
1255  if (ipHeader.GetDestination ().IsMulticast () == false)
1256  {
1257  packet->AddHeader (ipHeader);
1258  GetIcmpv6 ()->SendErrorTimeExceeded (packet, ipHeader.GetSource (), Icmpv6Header::ICMPV6_HOPLIMIT);
1259  }
1260  return;
1261  }
1262 
1263  /* ICMPv6 Redirect */
1264 
1265  /* if we forward to a machine on the same network as the source,
1266  * we send him an ICMPv6 redirect message to notify him that a short route
1267  * exists.
1268  */
1269 
1270  /* Theoretically we should also check if the redirect target is on the same network
1271  * as the source node. On the other hand, we are sure that the router we're redirecting to
1272  * used a link-local address. As a consequence, they MUST be on the same network, the link-local net.
1273  */
1274 
1275  if (m_sendIcmpv6Redirect && (rtentry->GetOutputDevice ()==idev))
1276  {
1277  NS_LOG_LOGIC ("ICMPv6 redirect!");
1278  Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6 ();
1279  Address hardwareTarget;
1280  Ipv6Address dst = header.GetDestination ();
1281  Ipv6Address src = header.GetSource ();
1282  Ipv6Address target = rtentry->GetGateway ();
1283  Ptr<Packet> copy = p->Copy ();
1284 
1285  if (target.IsAny ())
1286  {
1287  target = dst;
1288  }
1289 
1290  copy->AddHeader (header);
1291  Ipv6Address linkLocal = GetInterface (GetInterfaceForDevice (rtentry->GetOutputDevice ()))->GetLinkLocalAddress ().GetAddress ();
1292 
1293  if (icmpv6->Lookup (target, rtentry->GetOutputDevice (), 0, &hardwareTarget))
1294  {
1295  icmpv6->SendRedirection (copy, linkLocal, src, target, dst, hardwareTarget);
1296  }
1297  else
1298  {
1299  icmpv6->SendRedirection (copy, linkLocal, src, target, dst, Address ());
1300  }
1301  }
1302  // in case the packet still has a priority tag attached, remove it
1303  SocketPriorityTag priorityTag;
1304  packet->RemovePacketTag (priorityTag);
1305  int32_t interface = GetInterfaceForDevice (rtentry->GetOutputDevice ());
1306  m_unicastForwardTrace (ipHeader, packet, interface);
1307  SendRealOut (rtentry, packet, ipHeader);
1308 }
1309 
1311 {
1312  NS_LOG_FUNCTION (this << mrtentry << p << header);
1313  NS_LOG_LOGIC ("Multicast forwarding logic for node: " << m_node->GetId ());
1314 
1315  std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap ();
1316  std::map<uint32_t, uint32_t>::iterator mapIter;
1317 
1318  for (mapIter = ttlMap.begin (); mapIter != ttlMap.end (); mapIter++)
1319  {
1320  uint32_t interfaceId = mapIter->first;
1321  //uint32_t outputTtl = mapIter->second; // Unused for now
1322  Ptr<Packet> packet = p->Copy ();
1323  Ipv6Header h = header;
1324  h.SetHopLimit (header.GetHopLimit () - 1);
1325  if (h.GetHopLimit () == 0)
1326  {
1327  NS_LOG_WARN ("TTL exceeded. Drop.");
1328  m_dropTrace (header, packet, DROP_TTL_EXPIRED, this, interfaceId);
1329  return;
1330  }
1331  NS_LOG_LOGIC ("Forward multicast via interface " << interfaceId);
1332  Ptr<Ipv6Route> rtentry = Create<Ipv6Route> ();
1333  rtentry->SetSource (h.GetSource ());
1334  rtentry->SetDestination (h.GetDestination ());
1335  rtentry->SetGateway (Ipv6Address::GetAny ());
1336  rtentry->SetOutputDevice (GetNetDevice (interfaceId));
1337  SendRealOut (rtentry, packet, h);
1338  continue;
1339  }
1340 }
1341 
1342 void Ipv6L3Protocol::LocalDeliver (Ptr<const Packet> packet, Ipv6Header const& ip, uint32_t iif)
1343 {
1344  NS_LOG_FUNCTION (this << packet << ip << iif);
1345  Ptr<Packet> p = packet->Copy ();
1346  Ptr<IpL4Protocol> protocol = 0;
1347  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux> ();
1348  Ptr<Ipv6Extension> ipv6Extension = 0;
1349  Ipv6Address src = ip.GetSource ();
1350  Ipv6Address dst = ip.GetDestination ();
1351  uint8_t nextHeader = ip.GetNextHeader ();
1352  uint8_t nextHeaderPosition = 0;
1353  bool isDropped = false;
1354  bool stopProcessing = false;
1355  DropReason dropReason;
1356 
1357  // check for a malformed hop-by-hop extension
1358  // this is a common case when forging IPv6 raw packets
1359  if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1360  {
1361  uint8_t buf;
1362  p->CopyData (&buf, 1);
1364  {
1365  NS_LOG_WARN("Double Ipv6Header::IPV6_EXT_HOP_BY_HOP in packet, dropping packet");
1366  return;
1367  }
1368  }
1369 
1370  /* process all the extensions found and the layer 4 protocol */
1371  do
1372  {
1373  /* it return 0 for non-extension (i.e. layer 4 protocol) */
1374  ipv6Extension = ipv6ExtensionDemux->GetExtension (nextHeader);
1375 
1376  if (ipv6Extension)
1377  {
1378  uint8_t nextHeaderStep = 0;
1379  uint8_t curHeader = nextHeader;
1380  nextHeaderStep = ipv6Extension->Process (p, nextHeaderPosition, ip, dst, &nextHeader, stopProcessing, isDropped, dropReason);
1381  nextHeaderPosition += nextHeaderStep;
1382 
1383  if (isDropped)
1384  {
1385  m_dropTrace (ip, packet, dropReason, this, iif);
1386  }
1387 
1388  if (stopProcessing)
1389  {
1390  return;
1391  }
1392  NS_ASSERT_MSG (nextHeaderStep != 0 || curHeader == Ipv6Header::IPV6_EXT_FRAGMENTATION,
1393  "Zero-size IPv6 Option Header, aborting" << *packet );
1394  }
1395  else
1396  {
1397  protocol = GetProtocol (nextHeader, iif);
1398 
1399  if (!protocol)
1400  {
1401  NS_LOG_LOGIC ("Unknown Next Header. Drop!");
1402 
1403  // For ICMPv6 Error packets
1404  Ptr<Packet> malformedPacket = packet->Copy ();
1405  malformedPacket->AddHeader (ip);
1406 
1407  if (nextHeaderPosition == 0)
1408  {
1409  GetIcmpv6 ()->SendErrorParameterError (malformedPacket, dst, Icmpv6Header::ICMPV6_UNKNOWN_NEXT_HEADER, 40);
1410  }
1411  else
1412  {
1413  GetIcmpv6 ()->SendErrorParameterError (malformedPacket, dst, Icmpv6Header::ICMPV6_UNKNOWN_NEXT_HEADER, ip.GetSerializedSize () + nextHeaderPosition);
1414  }
1415  m_dropTrace (ip, p, DROP_UNKNOWN_PROTOCOL, this, iif);
1416  break;
1417  }
1418  else
1419  {
1420  p->RemoveAtStart (nextHeaderPosition);
1421  /* protocol->Receive (p, src, dst, incomingInterface); */
1422 
1423  /* L4 protocol */
1424  Ptr<Packet> copy = p->Copy ();
1425 
1426  m_localDeliverTrace (ip, p, iif);
1427 
1428  enum IpL4Protocol::RxStatus status = protocol->Receive (p, ip, GetInterface (iif));
1429 
1430  switch (status)
1431  {
1432  case IpL4Protocol::RX_OK:
1433  break;
1435  break;
1437  break;
1439  if (ip.GetDestination ().IsMulticast ())
1440  {
1441  /* do not rely on multicast address */
1442  break;
1443  }
1444 
1445  copy->AddHeader (ip);
1446  GetIcmpv6 ()->SendErrorDestinationUnreachable (copy, ip.GetSource (), Icmpv6Header::ICMPV6_PORT_UNREACHABLE);
1447  }
1448  }
1449  }
1450  }
1451  while (ipv6Extension);
1452 }
1453 
1455 {
1456  NS_LOG_FUNCTION (this << p << ipHeader << sockErrno);
1457  NS_LOG_LOGIC ("Route input failure-- dropping packet to " << ipHeader << " with errno " << sockErrno);
1458 
1459  m_dropTrace (ipHeader, p, DROP_ROUTE_ERROR, this, 0);
1460 
1461  if (!ipHeader.GetDestination ().IsMulticast ())
1462  {
1463  Ptr<Packet> packet = p->Copy ();
1464  packet->AddHeader (ipHeader);
1465  GetIcmpv6 ()->SendErrorDestinationUnreachable (packet, ipHeader.GetSource (), Icmpv6Header::ICMPV6_NO_ROUTE);
1466  }
1467 }
1468 
1469 Ipv6Header Ipv6L3Protocol::BuildHeader (Ipv6Address src, Ipv6Address dst, uint8_t protocol, uint16_t payloadSize, uint8_t ttl, uint8_t tclass)
1470 {
1471  NS_LOG_FUNCTION (this << src << dst << (uint32_t)protocol << (uint32_t)payloadSize << (uint32_t)ttl << (uint32_t)tclass);
1472  Ipv6Header hdr;
1473 
1474  hdr.SetSource (src);
1475  hdr.SetDestination (dst);
1476  hdr.SetNextHeader (protocol);
1477  hdr.SetPayloadLength (payloadSize);
1478  hdr.SetHopLimit (ttl);
1479  hdr.SetTrafficClass (tclass);
1480  return hdr;
1481 }
1482 
1484 {
1485  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = CreateObject<Ipv6ExtensionDemux> ();
1486  ipv6ExtensionDemux->SetNode (m_node);
1487 
1488  Ptr<Ipv6ExtensionHopByHop> hopbyhopExtension = CreateObject<Ipv6ExtensionHopByHop> ();
1489  hopbyhopExtension->SetNode (m_node);
1490  Ptr<Ipv6ExtensionDestination> destinationExtension = CreateObject<Ipv6ExtensionDestination> ();
1491  destinationExtension->SetNode (m_node);
1492  Ptr<Ipv6ExtensionFragment> fragmentExtension = CreateObject<Ipv6ExtensionFragment> ();
1493  fragmentExtension->SetNode (m_node);
1494  Ptr<Ipv6ExtensionRouting> routingExtension = CreateObject<Ipv6ExtensionRouting> ();
1495  routingExtension->SetNode (m_node);
1496  // Ptr<Ipv6ExtensionESP> espExtension = CreateObject<Ipv6ExtensionESP> ();
1497  // Ptr<Ipv6ExtensionAH> ahExtension = CreateObject<Ipv6ExtensionAH> ();
1498 
1499  ipv6ExtensionDemux->Insert (hopbyhopExtension);
1500  ipv6ExtensionDemux->Insert (destinationExtension);
1501  ipv6ExtensionDemux->Insert (fragmentExtension);
1502  ipv6ExtensionDemux->Insert (routingExtension);
1503  // ipv6ExtensionDemux->Insert (espExtension);
1504  // ipv6ExtensionDemux->Insert (ahExtension);
1505 
1506  Ptr<Ipv6ExtensionRoutingDemux> routingExtensionDemux = CreateObject<Ipv6ExtensionRoutingDemux> ();
1507  routingExtensionDemux->SetNode (m_node);
1508  Ptr<Ipv6ExtensionLooseRouting> looseRoutingExtension = CreateObject<Ipv6ExtensionLooseRouting> ();
1509  looseRoutingExtension->SetNode (m_node);
1510  routingExtensionDemux->Insert (looseRoutingExtension);
1511 
1512  m_node->AggregateObject (routingExtensionDemux);
1513  m_node->AggregateObject (ipv6ExtensionDemux);
1514 }
1515 
1517 {
1518  Ptr<Ipv6OptionDemux> ipv6OptionDemux = CreateObject<Ipv6OptionDemux> ();
1519  ipv6OptionDemux->SetNode (m_node);
1520 
1521  Ptr<Ipv6OptionPad1> pad1Option = CreateObject<Ipv6OptionPad1> ();
1522  pad1Option->SetNode (m_node);
1523  Ptr<Ipv6OptionPadn> padnOption = CreateObject<Ipv6OptionPadn> ();
1524  padnOption->SetNode (m_node);
1525  Ptr<Ipv6OptionJumbogram> jumbogramOption = CreateObject<Ipv6OptionJumbogram> ();
1526  jumbogramOption->SetNode (m_node);
1527  Ptr<Ipv6OptionRouterAlert> routerAlertOption = CreateObject<Ipv6OptionRouterAlert> ();
1528  routerAlertOption->SetNode (m_node);
1529 
1530  ipv6OptionDemux->Insert (pad1Option);
1531  ipv6OptionDemux->Insert (padnOption);
1532  ipv6OptionDemux->Insert (jumbogramOption);
1533  ipv6OptionDemux->Insert (routerAlertOption);
1534 
1535  m_node->AggregateObject (ipv6OptionDemux);
1536 }
1537 
1539 {
1540  m_dropTrace (ipHeader, p, dropReason, this, 0);
1541 }
1542 
1544 {
1545  NS_LOG_FUNCTION (address << interface);
1546 
1547  if (!address.IsMulticast ())
1548  {
1549  NS_LOG_WARN ("Not adding a non-multicast address " << address);
1550  return;
1551  }
1552 
1553  Ipv6RegisteredMulticastAddressKey_t key = std::make_pair (address, interface);
1554  m_multicastAddresses[key]++;
1555 }
1556 
1558 {
1560 
1561  if (!address.IsMulticast ())
1562  {
1563  NS_LOG_WARN ("Not adding a non-multicast address " << address);
1564  return;
1565  }
1566 
1568 }
1569 
1571 {
1572  NS_LOG_FUNCTION (address << interface);
1573 
1574  Ipv6RegisteredMulticastAddressKey_t key = std::make_pair (address, interface);
1575 
1576  m_multicastAddresses[key]--;
1577  if (m_multicastAddresses[key] == 0)
1578  {
1579  m_multicastAddresses.erase (key);
1580  }
1581 }
1582 
1584 {
1586 
1589  {
1591  }
1592 }
1593 
1595 {
1596  NS_LOG_FUNCTION (address << interface);
1597 
1598  Ipv6RegisteredMulticastAddressKey_t key = std::make_pair (address, interface);
1600 
1601  if (iter == m_multicastAddresses.end ())
1602  {
1603  return false;
1604  }
1605  return true;
1606 }
1607 
1609 {
1611 
1613 
1614  if (iter == m_multicastAddressesNoInterface.end ())
1615  {
1616  return false;
1617  }
1618  return true;
1619 }
1620 
1621 bool Ipv6L3Protocol::ReachabilityHint (uint32_t ipInterfaceIndex, Ipv6Address address)
1622 {
1623  if (ipInterfaceIndex >= m_interfaces.size ())
1624  {
1625  return false;
1626  }
1627 
1628  Ptr<NdiscCache> ndiscCache = m_interfaces[ipInterfaceIndex]->GetNdiscCache ();
1629  if (!ndiscCache)
1630  {
1631  return false;
1632  }
1633 
1634  NdiscCache::Entry* entry = ndiscCache->Lookup (address);
1635  if (!entry || entry->IsIncomplete ())
1636  {
1637  return false;
1638  }
1639 
1640 
1641  if (entry->IsReachable ())
1642  {
1643  entry->UpdateReachableTimer ();
1644  }
1645  else if (entry->IsPermanent ())
1646  {
1647  return true;
1648  }
1649  else if (entry->IsProbe ())
1650  {
1651  // we just confirm the entry's MAC address to get the waiting packets (if any)
1652  std::list<NdiscCache::Ipv6PayloadHeaderPair> waiting = entry->MarkReachable (entry->GetMacAddress ());
1653  for (std::list<NdiscCache::Ipv6PayloadHeaderPair>::const_iterator it = waiting.begin (); it != waiting.end (); it++)
1654  {
1655  ndiscCache->GetInterface ()->Send (it->first, it->second, it->second.GetSource ());
1656  }
1657  entry->ClearWaitingPacket ();
1658  entry->StartReachableTimer ();
1659  }
1660  else // STALE OR DELAY
1661  {
1662  entry->MarkReachable ();
1663  entry->StartReachableTimer ();
1664  }
1665 
1666 
1667  return true;
1668 }
1669 
1670 } /* namespace ns3 */
1671 
#define max(a, b)
Definition: 80211b.c:43
a polymophic address class
Definition: address.h:91
AttributeValue implementation for Boolean.
Definition: boolean.h:37
An implementation of the ICMPv6 protocol.
static uint16_t GetStaticProtocolNumber()
Get ICMPv6 protocol number.
@ AUTADDRCONF
Autonomous Address Configuration.
virtual int GetProtocolNumber(void) const =0
Returns the protocol number of this protocol.
virtual enum RxStatus Receive(Ptr< Packet > p, Ipv4Header const &header, Ptr< Ipv4Interface > incomingInterface)=0
Called from lower-level layers to send the packet up in the stack.
RxStatus
Rx status codes.
Describes an IPv6 address.
Definition: ipv6-address.h:50
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
bool IsDocumentation() const
If the IPv6 address is a documentation address (2001:DB8::/32).
bool IsAllNodesMulticast() const
If the IPv6 address is "all nodes multicast" (ff02::1/8).
bool IsLinkLocalMulticast() const
If the IPv6 address is link-local multicast (ff02::/16).
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
static Ipv6Address MakeAutoconfiguredAddress(Address addr, Ipv6Address prefix)
Make the autoconfigured IPv6 address from a Mac address.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
bool IsAny() const
If the IPv6 address is the "Any" address.
bool IsLocalhost() const
If the IPv6 address is localhost (::1).
static Ipv6Address GetLoopback()
Get the loopback address.
bool IsAllRoutersMulticast() const
If the IPv6 address is "all routers multicast" (ff02::2/8).
void StartPreferredTimer()
Start the preferred timer.
Demultiplexes IPv6 extensions.
IPv6 Extension Fragment.
void SetNode(Ptr< Node > node)
Set the node.
Packet header for IPv6.
Definition: ipv6-header.h:36
void SetDestination(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:115
uint8_t GetHopLimit(void) const
Get the "Hop limit" field (TTL).
Definition: ipv6-header.cc:90
Ipv6Address GetSource(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:105
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
Definition: ipv6-header.cc:163
void SetSource(Ipv6Address src)
Set the "Source address" field.
Definition: ipv6-header.cc:95
uint8_t GetNextHeader(void) const
Get the next header.
Definition: ipv6-header.cc:80
void SetHopLimit(uint8_t limit)
Set the "Hop limit" field (TTL).
Definition: ipv6-header.cc:85
void SetPayloadLength(uint16_t len)
Set the "Payload length" field.
Definition: ipv6-header.cc:65
uint16_t GetPayloadLength(void) const
Get the "Payload length" field.
Definition: ipv6-header.cc:70
void SetTrafficClass(uint8_t traffic)
Set the "Traffic class" field.
Definition: ipv6-header.cc:45
Ipv6Address GetDestination(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:125
void SetNextHeader(uint8_t next)
Set the "Next header" field.
Definition: ipv6-header.cc:75
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:82
IPv6 address associated with an interface.
Ipv6Address GetAddress() const
Get the IPv6 address.
@ LINKLOCAL
Link-local address (fe80::/64)
@ GLOBAL
Global address (2000::/3)
The IPv6 representation of a network interface.
Ipv6InterfaceAddress GetLinkLocalAddress() const
Get link-local address from IPv6 interface.
void SetForwarding(bool forward)
Set forwarding enabled or not.
void SetDown()
Disable this interface.
bool IsUp() const
Is the interface UP ?
Ipv6InterfaceAddress GetAddress(uint32_t index) const
Get an address from IPv6 interface.
void SetUp()
Enable this interface.
void Send(Ptr< Packet > p, const Ipv6Header &hdr, Ipv6Address dest)
Send a packet through this interface.
uint16_t GetMetric() const
Get the metric.
uint32_t GetNAddresses(void) const
Get number of addresses on this IPv6 interface.
void SetMetric(uint16_t metric)
Set the metric.
virtual Ptr< NetDevice > GetDevice() const
Get the NetDevice.
IPv6 layer implementation.
Ptr< Ipv6PmtuCache > m_pmtuCache
Path MTU Cache.
bool IsForwarding(uint32_t i) const
Is interface allows forwarding ?
void RouteInputError(Ptr< const Packet > p, const Ipv6Header &ipHeader, Socket::SocketErrno sockErrno)
Fallback when no route is found.
uint8_t m_defaultTclass
Default TCLASS for outgoing packets.
bool IsRegisteredMulticastAddress(Ipv6Address address) const
Checks if the address has been registered.
virtual ~Ipv6L3Protocol()
Destructor.
void AddAutoconfiguredAddress(uint32_t interface, Ipv6Address network, Ipv6Prefix mask, uint8_t flags, uint32_t validTime, uint32_t preferredTime, Ipv6Address defaultRouter=Ipv6Address::GetZero())
Add an autoconfigured address with RA information.
void SetForwarding(uint32_t i, bool val)
Enable or disable forwarding on interface.
Ipv6InterfaceAddress GetAddress(uint32_t interfaceIndex, uint32_t addressIndex) const
Get an address.
TracedCallback< Ptr< const Packet >, Ptr< Ipv6 >, uint32_t > m_txTrace
Callback to trace TX (transmission) packets.
bool m_sendIcmpv6Redirect
Allow ICMPv6 Redirect sending state.
virtual void RegisterExtensions()
Register the IPv6 Extensions.
Ptr< Icmpv6L4Protocol > GetIcmpv6() const
Get ICMPv6 protocol.
bool ReachabilityHint(uint32_t ipInterfaceIndex, Ipv6Address address)
Provides reachability hint for Neighbor Cache Entries from L4-L7 protocols.
uint8_t m_defaultTtl
Default TTL for outgoing packets.
TracedCallback< Ptr< const Packet >, Ptr< Ipv6 >, uint32_t > m_rxTrace
Callback to trace RX (reception) packets.
DropReason
Reason why a packet has been dropped.
@ DROP_ROUTE_ERROR
Route error.
@ DROP_TTL_EXPIRED
Packet TTL has expired.
@ DROP_INTERFACE_DOWN
Interface is down so can not send packet.
@ DROP_NO_ROUTE
No route to host.
@ DROP_UNKNOWN_PROTOCOL
Unknown L4 protocol.
uint16_t GetMetric(uint32_t i) const
Get metric for an interface.
bool m_ipForward
Forwarding packets (i.e.
Ipv6AutoconfiguredPrefixList m_prefixes
List of IPv6 prefix received from RA.
void CallTxTrace(const Ipv6Header &ipHeader, Ptr< Packet > packet, Ptr< Ipv6 > ipv6, uint32_t interface)
Make a copy of the packet, add the header and invoke the TX trace callback.
Ipv6InterfaceList m_interfaces
List of IPv6 interfaces.
Ipv6RegisteredMulticastAddressNoInterface_t m_multicastAddressesNoInterface
List of multicast IP addresses of interest for all the interfaces.
int32_t GetInterfaceForPrefix(Ipv6Address addr, Ipv6Prefix mask) const
Get interface index which match specified address/prefix.
SocketList m_sockets
List of IPv6 raw sockets.
Ipv6Header BuildHeader(Ipv6Address src, Ipv6Address dst, uint8_t protocol, uint16_t payloadSize, uint8_t hopLimit, uint8_t tclass)
Construct an IPv6 header.
void SetNode(Ptr< Node > node)
Set node associated with this stack.
Ptr< Node > m_node
Node attached to stack.
uint32_t AddInterface(Ptr< NetDevice > device)
Add IPv6 interface for a device.
Ptr< NetDevice > GetNetDevice(uint32_t i)
Get device by index.
Ptr< Ipv6RoutingProtocol > GetRoutingProtocol() const
Get current routing protocol used.
virtual bool GetIpForward() const
Get IPv6 forwarding state.
virtual bool GetSendIcmpv6Redirect() const
Get the ICMPv6 Redirect sending state.
L4List_t m_protocols
List of transport protocol.
Ptr< Ipv6Interface > GetInterface(uint32_t i) const
Get an interface.
void SetMetric(uint32_t i, uint16_t metric)
Set metric for an interface.
uint32_t m_nInterfaces
Number of IPv6 interfaces managed by the stack.
std::map< Ipv6Address, uint32_t >::const_iterator Ipv6RegisteredMulticastAddressNoInterfaceCIter_t
Container Const Iterator of the IPv6 multicast addresses.
void AddMulticastAddress(Ipv6Address address)
Adds a multicast address to the list of addresses to pass to local deliver.
int32_t GetInterfaceForAddress(Ipv6Address addr) const
Get interface index which has specified IPv6 address.
virtual void ReportDrop(Ipv6Header ipHeader, Ptr< Packet > p, DropReason dropReason)
Report a packet drop.
std::map< Ipv6RegisteredMulticastAddressKey_t, uint32_t >::const_iterator Ipv6RegisteredMulticastAddressCIter_t
Container Const Iterator of the IPv6 multicast addresses.
void SetupLoopback()
Setup loopback interface.
Ptr< Socket > CreateRawSocket()
Create raw IPv6 socket.
virtual Ptr< IpL4Protocol > GetProtocol(int protocolNumber) const
Get L4 protocol by protocol number.
Ipv6RegisteredMulticastAddress_t m_multicastAddresses
List of multicast IP addresses of interest, divided per interface.
void RemoveAutoconfiguredAddress(uint32_t interface, Ipv6Address network, Ipv6Prefix mask, Ipv6Address defaultRouter)
Remove an autoconfigured address.
bool RemoveAddress(uint32_t interfaceIndex, uint32_t addressIndex)
Remove an address from an interface.
virtual void Remove(Ptr< IpL4Protocol > protocol)
Remove a L4 protocol.
TracedCallback< const Ipv6Header &, Ptr< const Packet >, uint32_t > m_unicastForwardTrace
Trace of unicast forwarded packets.
Ipv6Address SourceAddressSelection(uint32_t interface, Ipv6Address dest)
Choose the source address to use with destination address.
bool m_mtuDiscover
MTU Discover (i.e.
void SetDefaultTtl(uint8_t ttl)
Set the default TTL.
void SetUp(uint32_t i)
Set an interface up.
void Receive(Ptr< NetDevice > device, Ptr< const Packet > p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Receive method when a packet arrive in the stack.
void LocalDeliver(Ptr< const Packet > p, Ipv6Header const &ip, uint32_t iif)
Deliver a packet.
virtual bool GetMtuDiscover(void) const
Get IPv6 MTU discover state.
void RemoveMulticastAddress(Ipv6Address address)
Removes a multicast address from the list of addresses to pass to local deliver.
virtual void SetMtuDiscover(bool mtuDiscover)
Set IPv6 MTU discover state.
void SetRoutingProtocol(Ptr< Ipv6RoutingProtocol > routingProtocol)
Set routing protocol for this stack.
uint32_t AddIpv6Interface(Ptr< Ipv6Interface > interface)
Add an IPv6 interface to the stack.
Ptr< Ipv6RoutingProtocol > m_routingProtocol
Routing protocol.
virtual void SetSendIcmpv6Redirect(bool sendIcmpv6Redirect)
Set the ICMPv6 Redirect sending state.
void IpMulticastForward(Ptr< const NetDevice > idev, Ptr< Ipv6MulticastRoute > mrtentry, Ptr< const Packet > p, const Ipv6Header &header)
Forward a multicast packet.
bool IsUp(uint32_t i) const
Is specified interface up ?
uint16_t GetMtu(uint32_t i) const
Get MTU for an interface.
TracedCallback< const Ipv6Header &, Ptr< const Packet >, uint32_t > m_sendOutgoingTrace
Trace of sent packets.
int32_t GetInterfaceForDevice(Ptr< const NetDevice > device) const
Get interface index which is on a specified net device.
void SetDown(uint32_t i)
set an interface down.
uint32_t GetNAddresses(uint32_t interface) const
Get number of address for an interface.
void DeleteRawSocket(Ptr< Socket > socket)
Remove raw IPv6 socket.
virtual void SetPmtu(Ipv6Address dst, uint32_t pmtu)
Set the Path MTU for the specified IPv6 destination address.
Ipv6InterfaceReverseContainer m_reverseInterfacesContainer
Container of NetDevice / Interface index associations.
bool m_strongEndSystemModel
Rejects packets directed to an interface with wrong address (RFC 1222).
TracedCallback< const Ipv6Header &, Ptr< const Packet >, DropReason, Ptr< Ipv6 >, uint32_t > m_dropTrace
Callback to trace drop packets.
virtual void Send(Ptr< Packet > packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr< Ipv6Route > route)
Higher-level layers call this method to send a packet down the stack to the MAC and PHY layers.
static const uint16_t PROT_NUMBER
The protocol number for IPv6 (0x86DD).
void SetDefaultTclass(uint8_t tclass)
Set the default TCLASS.
void IpForward(Ptr< const NetDevice > idev, Ptr< Ipv6Route > rtentry, Ptr< const Packet > p, const Ipv6Header &header)
Forward a packet.
virtual void RegisterOptions()
Register the IPv6 Options.
bool AddAddress(uint32_t i, Ipv6InterfaceAddress address, bool addOnLinkRoute=true)
Add an address on interface.
std::pair< Ipv6Address, uint64_t > Ipv6RegisteredMulticastAddressKey_t
IPv6 multicast addresses / interface key.
void SendRealOut(Ptr< Ipv6Route > route, Ptr< Packet > packet, Ipv6Header const &ipHeader)
Send packet with route.
std::pair< int, int32_t > L4ListKey_t
Container of the IPv6 L4 keys: protocol number, interface index.
virtual void NotifyNewAggregate()
Notify other components connected to the node that a new stack member is now connected.
virtual void DoDispose()
Dispose object.
Ipv6L3Protocol()
Constructor.
std::list< Ptr< Ipv6AutoconfiguredPrefix > >::iterator Ipv6AutoconfiguredPrefixListI
Iterator of the container of the IPv6 Autoconfigured addresses.
virtual void SetIpForward(bool forward)
Set IPv6 forwarding state.
uint32_t GetNInterfaces() const
Get current number of interface on this stack.
static TypeId GetTypeId()
Get the type ID of this class.
virtual void Insert(Ptr< IpL4Protocol > protocol)
Add a L4 protocol.
TracedCallback< const Ipv6Header &, Ptr< const Packet >, uint32_t > m_localDeliverTrace
Trace of locally delivered packets.
Describes an IPv6 prefix.
Definition: ipv6-address.h:456
void SetNode(Ptr< Node > node)
Set the node associated with this socket.
bool ForwardUp(Ptr< const Packet > p, Ipv6Header hdr, Ptr< NetDevice > device)
Forward up to receive method.
A record that holds information about a NdiscCache entry.
Definition: ndisc-cache.h:161
bool IsPermanent() const
Is the entry PERMANENT.
Definition: ndisc-cache.cc:587
void ClearWaitingPacket()
Clear the waiting packet list.
Definition: ndisc-cache.cc:264
void StartReachableTimer()
Start the reachable timer.
Definition: ndisc-cache.cc:424
void UpdateReachableTimer()
Update the reachable timer.
Definition: ndisc-cache.cc:438
Address GetMacAddress() const
Get the MAC address of this entry.
Definition: ndisc-cache.cc:593
std::list< Ipv6PayloadHeaderPair > MarkReachable(Address mac)
Changes the state to this entry to REACHABLE.
Definition: ndisc-cache.cc:510
bool IsIncomplete() const
Is the entry INCOMPLETE.
Definition: ndisc-cache.cc:575
bool IsProbe() const
Is the entry PROBE.
Definition: ndisc-cache.cc:581
bool IsReachable() const
Is the entry REACHABLE.
Definition: ndisc-cache.cc:563
virtual NdiscCache::Entry * Lookup(Ipv6Address dst)
Lookup in the cache.
Definition: ndisc-cache.cc:93
std::list< NdiscCache::Entry * > LookupInverse(Address dst)
Lookup in the cache for a MAC address.
Definition: ndisc-cache.cc:108
Ptr< Ipv6Interface > GetInterface() const
Get the Ipv6Interface associated with this cache.
Definition: ndisc-cache.cc:81
virtual Address GetAddress(void) const =0
virtual uint32_t GetIfIndex(void) const =0
virtual uint16_t GetMtu(void) const =0
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:297
uint32_t GetId(void) const
Definition: node.cc:109
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:130
uint32_t GetNDevices(void) const
Definition: node.cc:152
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:144
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:229
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:252
virtual void NotifyNewAggregate(void)
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:325
Container for a set of ns3::Object pointers.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:963
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:378
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
Definition: packet.cc:355
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Definition: packet.cc:362
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer.
Definition: socket.h:1165
uint8_t GetHopLimit(void) const
Get the tag's Hop Limit.
Definition: socket.cc:671
indicates whether the socket has IPV6_TCLASS set.
Definition: socket.h:1356
uint8_t GetTclass(void) const
Get the tag's Tclass.
Definition: socket.cc:906
indicates whether the socket has a priority set.
Definition: socket.h:1309
Introspection did not find any typical Config paths.
virtual void Receive(Ptr< NetDevice > device, Ptr< const Packet > p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Called by NetDevices, incoming packet.
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Hold an unsigned integer type.
Definition: uinteger.h:44
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: boolean.h:85
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:81
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:45
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:576
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
#define IPV6_MIN_MTU
Minimum IPv6 MTU, as defined by RFC 2460
address
Definition: first.py:44
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:415