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