A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
34 #include "loopback-net-device.h"
35 #include "ipv6-l3-protocol.h"
36 #include "ipv6-interface.h"
37 #include "ipv6-raw-socket-impl.h"
39 #include "ipv6-extension-demux.h"
40 #include "ipv6-extension.h"
41 #include "ipv6-extension-header.h"
42 #include "ipv6-option-demux.h"
43 #include "ipv6-option.h"
44 #include "icmpv6-l4-protocol.h"
45 #include "ndisc-cache.h"
46 
48 #define IPV6_MIN_MTU 1280
49 
50 namespace ns3 {
51 
52 NS_OBJECT_ENSURE_REGISTERED (Ipv6L3Protocol)
53  ;
54 
55 NS_LOG_COMPONENT_DEFINE ("Ipv6L3Protocol")
56  ;
57 
58 const uint16_t Ipv6L3Protocol::PROT_NUMBER = 0x86DD;
59 
61 {
62  static TypeId tid = TypeId ("ns3::Ipv6L3Protocol")
63  .SetParent<Ipv6> ()
64  .AddConstructor<Ipv6L3Protocol> ()
65  .AddAttribute ("DefaultTtl", "The TTL value set by default on all outgoing packets generated on this node.",
66  UintegerValue (64),
67  MakeUintegerAccessor (&Ipv6L3Protocol::m_defaultTtl),
68  MakeUintegerChecker<uint8_t> ())
69  .AddAttribute ("DefaultTclass", "The TCLASS value set by default on all outgoing packets generated on this node.",
70  UintegerValue (0),
71  MakeUintegerAccessor (&Ipv6L3Protocol::m_defaultTclass),
72  MakeUintegerChecker<uint8_t> ())
73  .AddAttribute ("InterfaceList", "The set of IPv6 interfaces associated to this IPv6 stack.",
76  MakeObjectVectorChecker<Ipv6Interface> ())
77  .AddAttribute ("SendIcmpv6Redirect", "Send the ICMPv6 Redirect when appropriate.",
78  BooleanValue (true),
79  MakeBooleanAccessor (&Ipv6L3Protocol::SetSendIcmpv6Redirect,
81  MakeBooleanChecker ())
82  .AddTraceSource ("Tx", "Send IPv6 packet to outgoing interface.",
84  .AddTraceSource ("Rx", "Receive IPv6 packet from incoming interface.",
86  .AddTraceSource ("Drop", "Drop IPv6 packet",
88  ;
89  return tid;
90 }
91 
93  : m_nInterfaces (0)
94 {
96  m_pmtuCache = CreateObject<Ipv6PmtuCache> ();
97 }
98 
100 {
102 }
103 
105 {
107 
108  /* clear protocol and interface list */
109  for (L4List_t::iterator it = m_protocols.begin (); it != m_protocols.end (); ++it)
110  {
111  *it = 0;
112  }
113  m_protocols.clear ();
114 
115  /* remove interfaces */
116  for (Ipv6InterfaceList::iterator it = m_interfaces.begin (); it != m_interfaces.end (); ++it)
117  {
118  *it = 0;
119  }
120  m_interfaces.clear ();
121 
122  /* remove raw sockets */
123  for (SocketList::iterator it = m_sockets.begin (); it != m_sockets.end (); ++it)
124  {
125  *it = 0;
126  }
127  m_sockets.clear ();
128 
129  /* remove list of prefix */
130  for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin (); it != m_prefixes.end (); ++it)
131  {
132  (*it)->StopValidTimer ();
133  (*it)->StopPreferredTimer ();
134  (*it) = 0;
135  }
136  m_prefixes.clear ();
137 
138  m_node = 0;
139  m_routingProtocol = 0;
140  m_pmtuCache = 0;
142 }
143 
145 {
146  NS_LOG_FUNCTION (this << routingProtocol);
147  m_routingProtocol = routingProtocol;
148  m_routingProtocol->SetIpv6 (this);
149 }
150 
152 {
154  return m_routingProtocol;
155 }
156 
158 {
159  NS_LOG_FUNCTION (this << device);
160  Ptr<Node> node = GetObject<Node> ();
161  Ptr<Ipv6Interface> interface = CreateObject<Ipv6Interface> ();
162 
164  interface->SetNode (m_node);
165  interface->SetDevice (device);
166  interface->SetForwarding (m_ipForward);
167  return AddIpv6Interface (interface);
168 }
169 
171 {
172  NS_LOG_FUNCTION (this << interface);
173  uint32_t index = m_nInterfaces;
174 
175  m_interfaces.push_back (interface);
176  m_nInterfaces++;
177  return index;
178 }
179 
181 {
182  NS_LOG_FUNCTION (this << index);
183  uint32_t tmp = 0;
184 
185  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
186  {
187  if (index == tmp)
188  {
189  return *it;
190  }
191  tmp++;
192  }
193  return 0;
194 }
195 
197 {
199  return m_nInterfaces;
200 }
201 
203 {
204  NS_LOG_FUNCTION (this << address);
205  int32_t index = 0;
206 
207  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
208  {
209  uint32_t j = 0;
210  uint32_t max = (*it)->GetNAddresses ();
211 
212  for (j = 0; j < max; j++)
213  {
214  if ((*it)->GetAddress (j).GetAddress () == address)
215  {
216  return index;
217  }
218  }
219  index++;
220  }
221  return -1;
222 }
223 
225 {
226  NS_LOG_FUNCTION (this << address << mask);
227  int32_t index = 0;
228 
229  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
230  {
231  uint32_t j = 0;
232  for (j = 0; j < (*it)->GetNAddresses (); j++)
233  {
234  if ((*it)->GetAddress (j).GetAddress ().CombinePrefix (mask) == address.CombinePrefix (mask))
235  {
236  return index;
237  }
238  }
239  index++;
240  }
241  return -1;
242 }
243 
245 {
246  NS_LOG_FUNCTION (this << i);
247  return GetInterface (i)->GetDevice ();
248 }
249 
251 {
252  NS_LOG_FUNCTION (this << device);
253  int32_t index = 0;
254 
255  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
256  {
257  if ((*it)->GetDevice () == device)
258  {
259  return index;
260  }
261  index++;
262  }
263  return -1;
264 }
265 
266 void Ipv6L3Protocol::AddAutoconfiguredAddress (uint32_t interface, Ipv6Address network, Ipv6Prefix mask, uint8_t flags, uint32_t validTime, uint32_t preferredTime, Ipv6Address defaultRouter)
267 {
268  NS_LOG_FUNCTION (this << interface << network << mask << (uint32_t)flags << validTime << preferredTime);
270 
271  Address addr = GetInterface (interface)->GetDevice ()->GetAddress ();
272 
273  if (flags & (1 << 6)) /* auto flag */
274  {
275  // In case of new MacAddress types, remember to change Ipv6L3Protocol::RemoveAutoconfiguredAddress as well
276  if (Mac64Address::IsMatchingType (addr))
277  {
279  }
280  else if (Mac48Address::IsMatchingType (addr))
281  {
283  }
284  else if (Mac16Address::IsMatchingType (addr))
285  {
287  }
288  else
289  {
290  NS_FATAL_ERROR ("Unknown method to make autoconfigured address for this kind of device.");
291  return;
292  }
293 
294  /* see if we have already the prefix */
295  for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin (); it != m_prefixes.end (); ++it)
296  {
297  if ((*it)->GetInterface () == interface && (*it)->GetPrefix () == network && (*it)->GetMask () == mask)
298  {
299  (*it)->StopPreferredTimer ();
300  (*it)->StopValidTimer ();
301  (*it)->StartPreferredTimer ();
302  return;
303  }
304  }
305 
306  /* no prefix found, add autoconfigured address and the prefix */
307  NS_LOG_INFO ("Autoconfigured address is :" << address.GetAddress ());
308  AddAddress (interface, address);
309 
310  /* add default router
311  * if a previous default route exists, the new ones is simply added
312  */
313  if (!defaultRouter.IsAny())
314  {
315  GetRoutingProtocol ()->NotifyAddRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
316  }
317 
318  Ptr<Ipv6AutoconfiguredPrefix> aPrefix = CreateObject<Ipv6AutoconfiguredPrefix> (m_node, interface, network, mask, preferredTime, validTime, defaultRouter);
319  aPrefix->StartPreferredTimer ();
320 
321  m_prefixes.push_back (aPrefix);
322  }
323 }
324 
325 void Ipv6L3Protocol::RemoveAutoconfiguredAddress (uint32_t interface, Ipv6Address network, Ipv6Prefix mask, Ipv6Address defaultRouter)
326 {
327  NS_LOG_FUNCTION (this << interface << network << mask);
328  Ptr<Ipv6Interface> iface = GetInterface (interface);
329  Address addr = iface->GetDevice ()->GetAddress ();
330  uint32_t max = iface->GetNAddresses ();
331  uint32_t i = 0;
332  Ipv6Address toFound;
333 
334  if (Mac64Address::IsMatchingType (addr))
335  {
337  }
338  else if (Mac48Address::IsMatchingType (addr))
339  {
341  }
342  else if (Mac16Address::IsMatchingType (addr))
343  {
345  }
346  else
347  {
348  NS_FATAL_ERROR ("Unknown method to make autoconfigured address for this kind of device.");
349  return;
350  }
351 
352  for (i = 0; i < max; i++)
353  {
354  if (iface->GetAddress (i).GetAddress () == toFound)
355  {
356  RemoveAddress (interface, i);
357  break;
358  }
359  }
360 
361  /* remove from list of autoconfigured address */
362  for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin (); it != m_prefixes.end (); ++it)
363  {
364  if ((*it)->GetInterface () == interface && (*it)->GetPrefix () == network && (*it)->GetMask () == mask)
365  {
366  *it = 0;
367  m_prefixes.erase (it);
368  break;
369  }
370  }
371 
372  GetRoutingProtocol ()->NotifyRemoveRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
373 }
374 
376 {
377  NS_LOG_FUNCTION (this << i << address);
378  Ptr<Ipv6Interface> interface = GetInterface (i);
379  bool ret = interface->AddAddress (address);
380 
381  if (m_routingProtocol != 0)
382  {
383  m_routingProtocol->NotifyAddAddress (i, address);
384  }
385  return ret;
386 }
387 
388 uint32_t Ipv6L3Protocol::GetNAddresses (uint32_t i) const
389 {
390  NS_LOG_FUNCTION (this << i);
391  Ptr<Ipv6Interface> interface = GetInterface (i);
392  return interface->GetNAddresses ();
393 }
394 
395 Ipv6InterfaceAddress Ipv6L3Protocol::GetAddress (uint32_t i, uint32_t addressIndex) const
396 {
397  NS_LOG_FUNCTION (this << i << addressIndex);
398  Ptr<Ipv6Interface> interface = GetInterface (i);
399  return interface->GetAddress (addressIndex);
400 }
401 
402 bool Ipv6L3Protocol::RemoveAddress (uint32_t i, uint32_t addressIndex)
403 {
404  NS_LOG_FUNCTION (this << i << addressIndex);
405  Ptr<Ipv6Interface> interface = GetInterface (i);
406  Ipv6InterfaceAddress address = interface->RemoveAddress (addressIndex);
407 
408  if (address != Ipv6InterfaceAddress ())
409  {
410  if (m_routingProtocol != 0)
411  {
412  m_routingProtocol->NotifyRemoveAddress (i, address);
413  }
414  return true;
415  }
416  return false;
417 }
418 
419 bool
421 {
422  NS_LOG_FUNCTION (this << i << address);
423 
424  if (address == Ipv6Address::GetLoopback())
425  {
426  NS_LOG_WARN ("Cannot remove loopback address.");
427  return false;
428  }
429  Ptr<Ipv6Interface> interface = GetInterface (i);
430  Ipv6InterfaceAddress ifAddr = interface->RemoveAddress (address);
431  if (ifAddr != Ipv6InterfaceAddress ())
432  {
433  if (m_routingProtocol != 0)
434  {
435  m_routingProtocol->NotifyRemoveAddress (i, ifAddr);
436  }
437  return true;
438  }
439  return false;
440 }
441 
442 void Ipv6L3Protocol::SetMetric (uint32_t i, uint16_t metric)
443 {
444  NS_LOG_FUNCTION (this << i << metric);
445  Ptr<Ipv6Interface> interface = GetInterface (i);
446  interface->SetMetric (metric);
447 }
448 
449 uint16_t Ipv6L3Protocol::GetMetric (uint32_t i) const
450 {
451  NS_LOG_FUNCTION (this << i);
452  Ptr<Ipv6Interface> interface = GetInterface (i);
453  return interface->GetMetric ();
454 }
455 
456 uint16_t Ipv6L3Protocol::GetMtu (uint32_t i) const
457 {
458  NS_LOG_FUNCTION (this << i);
459 
460  // RFC 1981, if PMTU is disabled, return the minimum MTU
461  if (!m_mtuDiscover)
462  {
463  return IPV6_MIN_MTU;
464  }
465 
466  Ptr<Ipv6Interface> interface = GetInterface (i);
467  return interface->GetDevice ()->GetMtu ();
468 }
469 
470 void Ipv6L3Protocol::SetPmtu (Ipv6Address dst, uint32_t pmtu)
471 {
472  NS_LOG_FUNCTION (this << dst << int(pmtu));
473  m_pmtuCache->SetPmtu (dst, pmtu);
474 }
475 
476 
477 bool Ipv6L3Protocol::IsUp (uint32_t i) const
478 {
479  NS_LOG_FUNCTION (this << i);
480  Ptr<Ipv6Interface> interface = GetInterface (i);
481  return interface->IsUp ();
482 }
483 
484 void Ipv6L3Protocol::SetUp (uint32_t i)
485 {
486  NS_LOG_FUNCTION (this << i);
487  Ptr<Ipv6Interface> interface = GetInterface (i);
488 
489  // RFC 2460, Section 5, pg. 24:
490  // IPv6 requires that every link in the internet have an MTU of 1280
491  // octets or greater. On any link that cannot convey a 1280-octet
492  // packet in one piece, link-specific fragmentation and reassembly must
493  // be provided at a layer below IPv6.
494  if (interface->GetDevice ()->GetMtu () >= 1280)
495  {
496  interface->SetUp ();
497 
498  if (m_routingProtocol != 0)
499  {
500  m_routingProtocol->NotifyInterfaceUp (i);
501  }
502  }
503  else
504  {
505  NS_LOG_LOGIC ("Interface " << int(i) << " is set to be down for IPv6. Reason: not respecting minimum IPv6 MTU (1280 octects)");
506  }
507 }
508 
509 void Ipv6L3Protocol::SetDown (uint32_t i)
510 {
511  NS_LOG_FUNCTION (this << i);
512  Ptr<Ipv6Interface> interface = GetInterface (i);
513 
514  interface->SetDown ();
515 
516  if (m_routingProtocol != 0)
517  {
518  m_routingProtocol->NotifyInterfaceDown (i);
519  }
520 }
521 
523 {
525  Ptr<Ipv6Interface> interface = CreateObject<Ipv6Interface> ();
526  Ptr<LoopbackNetDevice> device = 0;
527  uint32_t i = 0;
528 
529  /* see if we have already an loopback NetDevice */
530  for (i = 0; i < m_node->GetNDevices (); i++)
531  {
532  if ((device = DynamicCast<LoopbackNetDevice> (m_node->GetDevice (i))))
533  {
534  break;
535  }
536  }
537 
538  if (device == 0)
539  {
540  device = CreateObject<LoopbackNetDevice> ();
541  m_node->AddDevice (device);
542  }
543 
544  interface->SetDevice (device);
545  interface->SetNode (m_node);
547  interface->AddAddress (ifaceAddr);
548  uint32_t index = AddIpv6Interface (interface);
549  Ptr<Node> node = GetObject<Node> ();
551  interface->SetUp ();
552 
553  if (m_routingProtocol != 0)
554  {
555  m_routingProtocol->NotifyInterfaceUp (index);
556  }
557 }
558 
559 bool Ipv6L3Protocol::IsForwarding (uint32_t i) const
560 {
561  NS_LOG_FUNCTION (this << i);
562  Ptr<Ipv6Interface> interface = GetInterface (i);
563 
564  NS_LOG_LOGIC ("Forwarding state: " << interface->IsForwarding ());
565  return interface->IsForwarding ();
566 }
567 
568 void Ipv6L3Protocol::SetForwarding (uint32_t i, bool val)
569 {
570  NS_LOG_FUNCTION (this << i << val);
571  Ptr<Ipv6Interface> interface = GetInterface (i);
572  interface->SetForwarding (val);
573 }
574 
575 void Ipv6L3Protocol::SetIpForward (bool forward)
576 {
577  NS_LOG_FUNCTION (this << forward);
578  m_ipForward = forward;
579 
580  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
581  {
582  (*it)->SetForwarding (forward);
583  }
584 }
585 
587 {
589  return m_ipForward;
590 }
591 
592 void Ipv6L3Protocol::SetMtuDiscover (bool mtuDiscover)
593 {
594  NS_LOG_FUNCTION (this << int(mtuDiscover));
595  m_mtuDiscover = mtuDiscover;
596 }
597 
599 {
600  NS_LOG_FUNCTION (this);
601  return m_mtuDiscover;
602 }
603 
604 void Ipv6L3Protocol::SetSendIcmpv6Redirect (bool sendIcmpv6Redirect)
605 {
606  NS_LOG_FUNCTION (this << sendIcmpv6Redirect);
607  m_sendIcmpv6Redirect = sendIcmpv6Redirect;
608 }
609 
611 {
613  return m_sendIcmpv6Redirect;
614 }
615 
617 {
619 
620  if (m_node == 0)
621  {
622  Ptr<Node> node = this->GetObject<Node> ();
623  // verify that it's a valid node and that
624  // the node has not been set before
625  if (node != 0)
626  {
627  this->SetNode (node);
628  }
629  }
631 }
632 
634 {
635  NS_LOG_FUNCTION (this << node);
636  m_node = node;
637  /* add LoopbackNetDevice if needed, and an Ipv6Interface on top of it */
638  SetupLoopback ();
639 }
640 
642 {
643  NS_LOG_FUNCTION (this << protocol);
644  m_protocols.push_back (protocol);
645 }
646 
648 {
649  NS_LOG_FUNCTION (this << protocol);
650  m_protocols.remove (protocol);
651 }
652 
654 {
655  NS_LOG_FUNCTION (this << protocolNumber);
656 
657  for (L4List_t::const_iterator i = m_protocols.begin (); i != m_protocols.end (); ++i)
658  {
659  if ((*i)->GetProtocolNumber () == protocolNumber)
660  {
661  return *i;
662  }
663  }
664  return 0;
665 }
666 
668 {
670  Ptr<Ipv6RawSocketImpl> sock = CreateObject<Ipv6RawSocketImpl> ();
671  sock->SetNode (m_node);
672  m_sockets.push_back (sock);
673  return sock;
674 }
675 
677 {
678  NS_LOG_FUNCTION (this << socket);
679 
680  for (SocketList::iterator it = m_sockets.begin (); it != m_sockets.end (); ++it)
681  {
682  if ((*it) == socket)
683  {
684  m_sockets.erase (it);
685  return;
686  }
687  }
688 }
689 
691 {
694 
695  if (protocol)
696  {
697  return protocol->GetObject<Icmpv6L4Protocol> ();
698  }
699  else
700  {
701  return 0;
702  }
703 }
704 
706 {
707  NS_LOG_FUNCTION (this << ttl);
708  m_defaultTtl = ttl;
709 }
710 
711 void Ipv6L3Protocol::SetDefaultTclass (uint8_t tclass)
712 {
713  NS_LOG_FUNCTION (this << tclass);
714  m_defaultTclass = tclass;
715 }
716 
717 void Ipv6L3Protocol::Send (Ptr<Packet> packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr<Ipv6Route> route)
718 {
719  NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)protocol << route);
720  Ipv6Header hdr;
721  uint8_t ttl = m_defaultTtl;
723  bool found = packet->RemovePacketTag (tag);
724 
725  if (found)
726  {
727  ttl = tag.GetHopLimit ();
728  }
729 
730  SocketIpv6TclassTag tclassTag;
731  uint8_t tclass = m_defaultTclass;
732  found = packet->RemovePacketTag (tclassTag);
733 
734  if (found)
735  {
736  tclass = tclassTag.GetTclass ();
737  }
738 
739  /* Handle 3 cases:
740  * 1) Packet is passed in with a route entry
741  * 2) Packet is passed in with a route entry but route->GetGateway is not set (e.g., same network)
742  * 3) route is NULL (e.g., a raw socket call or ICMPv6)
743  */
744 
745  /* 1) */
746  if (route && route->GetGateway () != Ipv6Address::GetZero ())
747  {
748  NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 1: passed in with a route");
749  hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
750  SendRealOut (route, packet, hdr);
751  return;
752  }
753 
754  /* 2) */
755  if (route && route->GetGateway () == Ipv6Address::GetZero ())
756  {
757  NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 1: probably sent to machine on same IPv6 network");
758  /* NS_FATAL_ERROR ("This case is not yet implemented"); */
759  hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
760  SendRealOut (route, packet, hdr);
761  return;
762  }
763 
764  /* 3) */
765  NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 3: passed in with no route " << destination);
767  Ptr<NetDevice> oif (0);
768  Ptr<Ipv6Route> newRoute = 0;
769 
770  hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
771 
772  //for link-local traffic, we need to determine the interface
773  if (source.IsLinkLocal ()
774  || destination.IsLinkLocal ()
775  || destination.IsAllNodesMulticast ()
776  || destination.IsAllRoutersMulticast ()
777  || destination.IsAllHostsMulticast ()
778  || destination.IsSolicitedMulticast ())
779  {
780  int32_t index = GetInterfaceForAddress (source);
781  NS_ASSERT (index >= 0);
782  oif = GetNetDevice (index);
783  }
784 
785  newRoute = m_routingProtocol->RouteOutput (packet, hdr, oif, err);
786 
787  if (newRoute)
788  {
789  SendRealOut (newRoute, packet, hdr);
790  }
791  else
792  {
793  NS_LOG_WARN ("No route to host, drop!");
795  }
796 }
797 
798 void Ipv6L3Protocol::Receive (Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
799 {
800  NS_LOG_FUNCTION (this << device << p << protocol << from << to << packetType);
801  NS_LOG_LOGIC ("Packet from " << from << " received on node " << m_node->GetId ());
802  uint32_t interface = 0;
803  Ptr<Packet> packet = p->Copy ();
804  Ptr<Ipv6Interface> ipv6Interface = 0;
805 
806  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
807  {
808  ipv6Interface = *it;
809 
810  if (ipv6Interface->GetDevice () == device)
811  {
812  if (ipv6Interface->IsUp ())
813  {
814  m_rxTrace (packet, m_node->GetObject<Ipv6> (), interface);
815  break;
816  }
817  else
818  {
819  NS_LOG_LOGIC ("Dropping received packet-- interface is down");
820  Ipv6Header hdr;
821  packet->RemoveHeader (hdr);
822  m_dropTrace (hdr, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv6> (), interface);
823  return;
824  }
825  }
826  interface++;
827  }
828 
829  Ipv6Header hdr;
830  packet->RemoveHeader (hdr);
831 
832  // Trim any residual frame padding from underlying devices
833  if (hdr.GetPayloadLength () < packet->GetSize ())
834  {
835  packet->RemoveAtEnd (packet->GetSize () - hdr.GetPayloadLength ());
836  }
837 
838  /* forward up to IPv6 raw sockets */
839  for (SocketList::iterator it = m_sockets.begin (); it != m_sockets.end (); ++it)
840  {
841  Ptr<Ipv6RawSocketImpl> socket = *it;
842  socket->ForwardUp (packet, hdr, device);
843  }
844 
846  Ptr<Ipv6Extension> ipv6Extension = 0;
847  uint8_t nextHeader = hdr.GetNextHeader ();
848  bool isDropped = false;
849 
850  if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
851  {
852  ipv6Extension = ipv6ExtensionDemux->GetExtension (nextHeader);
853 
854  if (ipv6Extension)
855  {
856  ipv6Extension->Process (packet, 0, hdr, hdr.GetDestinationAddress (), (uint8_t *)0, isDropped);
857  }
858 
859  if (isDropped)
860  {
861  return;
862  }
863  }
864 
865  if (!m_routingProtocol->RouteInput (packet, hdr, device,
870  {
871  NS_LOG_WARN ("No route found for forwarding packet. Drop.");
872  m_dropTrace (hdr, packet, DROP_NO_ROUTE, m_node->GetObject<Ipv6> (), interface);
873  }
874 }
875 
877 {
878  NS_LOG_FUNCTION (this << route << packet << ipHeader);
879 
880  if (!route)
881  {
882  NS_LOG_LOGIC ("No route to host, drop!.");
883  return;
884  }
885 
886  Ptr<NetDevice> dev = route->GetOutputDevice ();
887  int32_t interface = GetInterfaceForDevice (dev);
888  NS_ASSERT (interface >= 0);
889 
890  Ptr<Ipv6Interface> outInterface = GetInterface (interface);
891  NS_LOG_LOGIC ("Send via NetDevice ifIndex " << dev->GetIfIndex () << " Ipv6InterfaceIndex " << interface);
892 
893  // Check packet size
894  std::list<Ptr<Packet> > fragments;
895 
896  // Check if we have a Path MTU stored. If so, use it. Else, use the link MTU.
897  size_t targetMtu = (size_t)(m_pmtuCache->GetPmtu (ipHeader.GetDestinationAddress()));
898  if (targetMtu == 0)
899  {
900  targetMtu = dev->GetMtu ();
901  }
902 
903  if (packet->GetSize () > targetMtu + 40) /* 40 => size of IPv6 header */
904  {
905  // Router => drop
906 
907  bool fromMe = false;
908  for (uint32_t i=0; i<GetNInterfaces(); i++ )
909  {
910  for (uint32_t j=0; j<GetNAddresses(i); j++ )
911  {
912  if (GetAddress(i,j).GetAddress() == ipHeader.GetSourceAddress())
913  {
914  fromMe = true;
915  break;
916  }
917  }
918  }
919  if (!fromMe)
920  {
921  Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6 ();
922  if ( icmpv6 )
923  {
924  packet->AddHeader(ipHeader);
925  icmpv6->SendErrorTooBig (packet, ipHeader.GetSourceAddress (), dev->GetMtu ());
926  }
927  return;
928  }
929 
931 
932  packet->AddHeader (ipHeader);
933 
934  // To get specific method GetFragments from Ipv6ExtensionFragmentation
935  Ipv6ExtensionFragment *ipv6Fragment = dynamic_cast<Ipv6ExtensionFragment *> (PeekPointer (ipv6ExtensionDemux->GetExtension (Ipv6Header::IPV6_EXT_FRAGMENTATION)));
936  NS_ASSERT (ipv6Fragment != 0);
937  ipv6Fragment->GetFragments (packet, targetMtu, fragments);
938  }
939 
940  if (!route->GetGateway ().IsEqual (Ipv6Address::GetAny ()))
941  {
942  if (outInterface->IsUp ())
943  {
944  NS_LOG_LOGIC ("Send to gateway " << route->GetGateway ());
945 
946  if (fragments.size () != 0)
947  {
948  std::ostringstream oss;
949 
950  /* IPv6 header is already added in fragments */
951  for (std::list<Ptr<Packet> >::const_iterator it = fragments.begin (); it != fragments.end (); it++)
952  {
953  m_txTrace (*it, m_node->GetObject<Ipv6> (), interface);
954  outInterface->Send (*it, route->GetGateway ());
955  }
956  }
957  else
958  {
959  packet->AddHeader (ipHeader);
960  m_txTrace (packet, m_node->GetObject<Ipv6> (), interface);
961  outInterface->Send (packet, route->GetGateway ());
962  }
963  }
964  else
965  {
966  NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << route->GetGateway ());
967  m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv6> (), interface);
968  }
969  }
970  else
971  {
972  if (outInterface->IsUp ())
973  {
974  NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestinationAddress ());
975 
976  if (fragments.size () != 0)
977  {
978  std::ostringstream oss;
979 
980  /* IPv6 header is already added in fragments */
981  for (std::list<Ptr<Packet> >::const_iterator it = fragments.begin (); it != fragments.end (); it++)
982  {
983  m_txTrace (*it, m_node->GetObject<Ipv6> (), interface);
984  outInterface->Send (*it, ipHeader.GetDestinationAddress ());
985  }
986  }
987  else
988  {
989  packet->AddHeader (ipHeader);
990  m_txTrace (packet, m_node->GetObject<Ipv6> (), interface);
991  outInterface->Send (packet, ipHeader.GetDestinationAddress ());
992  }
993  }
994  else
995  {
996  NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << ipHeader.GetDestinationAddress ());
997  m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv6> (), interface);
998  }
999  }
1000 }
1001 
1003 {
1004  NS_LOG_FUNCTION (this << rtentry << p << header);
1005  NS_LOG_LOGIC ("Forwarding logic for node: " << m_node->GetId ());
1006 
1007  // Drop RFC 3849 packets: 2001:db8::/32
1008  if (header.GetDestinationAddress().IsDocumentation())
1009  {
1010  NS_LOG_WARN ("Received a packet for 2001:db8::/32 (documentation class). Drop.");
1011  m_dropTrace (header, p, DROP_ROUTE_ERROR, m_node->GetObject<Ipv6> (), 0);
1012  return;
1013  }
1014 
1015  // Forwarding
1016  Ipv6Header ipHeader = header;
1017  Ptr<Packet> packet = p->Copy ();
1018  ipHeader.SetHopLimit (ipHeader.GetHopLimit () - 1);
1019 
1020  if (ipHeader.GetSourceAddress ().IsLinkLocal ())
1021  {
1022  /* no forward for link-local address */
1023  return;
1024  }
1025 
1026  if (ipHeader.GetHopLimit () == 0)
1027  {
1028  NS_LOG_WARN ("TTL exceeded. Drop.");
1029  m_dropTrace (ipHeader, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv6> (), 0);
1030  // Do not reply to ICMPv6 or to multicast IPv6 address
1031  if (ipHeader.GetNextHeader () != Icmpv6L4Protocol::PROT_NUMBER
1032  && ipHeader.GetDestinationAddress ().IsMulticast () == false)
1033  {
1034  packet->AddHeader (ipHeader);
1035  GetIcmpv6 ()->SendErrorTimeExceeded (packet, ipHeader.GetSourceAddress (), Icmpv6Header::ICMPV6_HOPLIMIT);
1036  }
1037  return;
1038  }
1039 
1040  /* ICMPv6 Redirect */
1041 
1042  /* if we forward to a machine on the same network as the source,
1043  * we send him an ICMPv6 redirect message to notify him that a short route
1044  * exists.
1045  */
1046 
1047  /* Theoretically we should also check if the redirect target is on the same network
1048  * as the source node. On the other hand, we are sure that the router we're redirecting to
1049  * used a link-local address. As a consequence, they MUST be on the same network, the link-local net.
1050  */
1051 
1052  if (m_sendIcmpv6Redirect && (rtentry->GetOutputDevice ()==idev))
1053  {
1054  NS_LOG_LOGIC ("ICMPv6 redirect!");
1055  Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6 ();
1056  Address hardwareTarget;
1057  Ipv6Address dst = header.GetDestinationAddress ();
1058  Ipv6Address src = header.GetSourceAddress ();
1059  Ipv6Address target = rtentry->GetGateway ();
1060  Ptr<Packet> copy = p->Copy ();
1061 
1062  if (target.IsAny ())
1063  {
1064  target = dst;
1065  }
1066 
1067  copy->AddHeader (header);
1068  Ipv6Address linkLocal = GetInterface (GetInterfaceForDevice (rtentry->GetOutputDevice ()))->GetLinkLocalAddress ().GetAddress ();
1069 
1070  if (icmpv6->Lookup (target, rtentry->GetOutputDevice (), 0, &hardwareTarget))
1071  {
1072  icmpv6->SendRedirection (copy, linkLocal, src, target, dst, hardwareTarget);
1073  }
1074  else
1075  {
1076  icmpv6->SendRedirection (copy, linkLocal, src, target, dst, Address ());
1077  }
1078  }
1079 
1080  SendRealOut (rtentry, packet, ipHeader);
1081 }
1082 
1084 {
1085  NS_LOG_FUNCTION (this << mrtentry << p << header);
1086  NS_LOG_LOGIC ("Multicast forwarding logic for node: " << m_node->GetId ());
1087 
1088  std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap ();
1089  std::map<uint32_t, uint32_t>::iterator mapIter;
1090 
1091  for (mapIter = ttlMap.begin (); mapIter != ttlMap.end (); mapIter++)
1092  {
1093  uint32_t interfaceId = mapIter->first;
1094  //uint32_t outputTtl = mapIter->second; // Unused for now
1095  Ptr<Packet> packet = p->Copy ();
1096  Ipv6Header h = header;
1097  h.SetHopLimit (header.GetHopLimit () - 1);
1098  if (h.GetHopLimit () == 0)
1099  {
1100  NS_LOG_WARN ("TTL exceeded. Drop.");
1101  m_dropTrace (header, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv6> (), interfaceId);
1102  return;
1103  }
1104  NS_LOG_LOGIC ("Forward multicast via interface " << interfaceId);
1105  Ptr<Ipv6Route> rtentry = Create<Ipv6Route> ();
1106  rtentry->SetSource (h.GetSourceAddress ());
1107  rtentry->SetDestination (h.GetDestinationAddress ());
1108  rtentry->SetGateway (Ipv6Address::GetAny ());
1109  rtentry->SetOutputDevice (GetNetDevice (interfaceId));
1110  SendRealOut (rtentry, packet, h);
1111  continue;
1112  }
1113 }
1114 
1115 void Ipv6L3Protocol::LocalDeliver (Ptr<const Packet> packet, Ipv6Header const& ip, uint32_t iif)
1116 {
1117  NS_LOG_FUNCTION (this << packet << ip << iif);
1118  Ptr<Packet> p = packet->Copy ();
1119  Ptr<IpL4Protocol> protocol = 0;
1120  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux> ();
1121  Ptr<Ipv6Extension> ipv6Extension = 0;
1122  Ipv6Address src = ip.GetSourceAddress ();
1123  Ipv6Address dst = ip.GetDestinationAddress ();
1124  uint8_t nextHeader = ip.GetNextHeader ();
1125  uint8_t nextHeaderPosition = 0;
1126  bool isDropped = false;
1127 
1128  // check for a malformed hop-by-hop extension
1129  // this is a common case when forging IPv6 raw packets
1130  if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1131  {
1132  uint8_t buf;
1133  p->CopyData (&buf, 1);
1135  {
1136  NS_LOG_WARN("Double Ipv6Header::IPV6_EXT_HOP_BY_HOP in packet, dropping packet");
1137  return;
1138  }
1139  }
1140 
1141  /* process all the extensions found and the layer 4 protocol */
1142  do
1143  {
1144  /* it return 0 for non-extension (i.e. layer 4 protocol) */
1145  ipv6Extension = ipv6ExtensionDemux->GetExtension (nextHeader);
1146 
1147  if (ipv6Extension)
1148  {
1149  uint8_t nextHeaderStep = 0;
1150  uint8_t curHeader = nextHeader;
1151  nextHeaderStep = ipv6Extension->Process (p, nextHeaderPosition, ip, dst, &nextHeader, isDropped);
1152  nextHeaderPosition += nextHeaderStep;
1153 
1154  if (isDropped)
1155  {
1156  return;
1157  }
1158  NS_ASSERT_MSG (nextHeaderStep != 0 || curHeader == Ipv6Header::IPV6_EXT_FRAGMENTATION,
1159  "Zero-size IPv6 Option Header, aborting" << *packet );
1160  }
1161  else
1162  {
1163  protocol = GetProtocol (nextHeader);
1164  // For ICMPv6 Error packets
1165  Ptr<Packet> malformedPacket = packet->Copy ();
1166  malformedPacket->AddHeader (ip);
1167 
1168  if (!protocol)
1169  {
1170  NS_LOG_LOGIC ("Unknown Next Header. Drop!");
1171 
1172  if (nextHeaderPosition == 0)
1173  {
1174  GetIcmpv6 ()->SendErrorParameterError (malformedPacket, dst, Icmpv6Header::ICMPV6_UNKNOWN_NEXT_HEADER, 40);
1175  }
1176  else
1177  {
1178  GetIcmpv6 ()->SendErrorParameterError (malformedPacket, dst, Icmpv6Header::ICMPV6_UNKNOWN_NEXT_HEADER, ip.GetSerializedSize () + nextHeaderPosition);
1179  }
1181  break;
1182  }
1183  else
1184  {
1185  p->RemoveAtStart (nextHeaderPosition);
1186  /* protocol->Receive (p, src, dst, incomingInterface); */
1187 
1188  /* L4 protocol */
1189  Ptr<Packet> copy = p->Copy ();
1190  enum IpL4Protocol::RxStatus status = protocol->Receive (p, ip, GetInterface (iif));
1191 
1192  switch (status)
1193  {
1194  case IpL4Protocol::RX_OK:
1195  break;
1197  break;
1199  break;
1201  if (ip.GetDestinationAddress ().IsMulticast ())
1202  {
1203  /* do not rely on multicast address */
1204  break;
1205  }
1206 
1207  copy->AddHeader (ip);
1208  GetIcmpv6 ()->SendErrorDestinationUnreachable (copy, ip.GetSourceAddress (), Icmpv6Header::ICMPV6_PORT_UNREACHABLE);
1209  }
1210  }
1211  }
1212  }
1213  while (ipv6Extension);
1214 }
1215 
1217 {
1218  NS_LOG_FUNCTION (this << p << ipHeader << sockErrno);
1219  NS_LOG_LOGIC ("Route input failure-- dropping packet to " << ipHeader << " with errno " << sockErrno);
1220  m_dropTrace (ipHeader, p, DROP_ROUTE_ERROR, m_node->GetObject<Ipv6> (), 0);
1221 }
1222 
1223 Ipv6Header Ipv6L3Protocol::BuildHeader (Ipv6Address src, Ipv6Address dst, uint8_t protocol, uint16_t payloadSize, uint8_t ttl, uint8_t tclass)
1224 {
1225  NS_LOG_FUNCTION (this << src << dst << (uint32_t)protocol << (uint32_t)payloadSize << (uint32_t)ttl << (uint32_t)tclass);
1226  Ipv6Header hdr;
1227 
1228  hdr.SetSourceAddress (src);
1229  hdr.SetDestinationAddress (dst);
1230  hdr.SetNextHeader (protocol);
1231  hdr.SetPayloadLength (payloadSize);
1232  hdr.SetHopLimit (ttl);
1233  hdr.SetTrafficClass (tclass);
1234  return hdr;
1235 }
1236 
1238 {
1239  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = CreateObject<Ipv6ExtensionDemux> ();
1240  ipv6ExtensionDemux->SetNode (m_node);
1241 
1242  Ptr<Ipv6ExtensionHopByHop> hopbyhopExtension = CreateObject<Ipv6ExtensionHopByHop> ();
1243  hopbyhopExtension->SetNode (m_node);
1244  Ptr<Ipv6ExtensionDestination> destinationExtension = CreateObject<Ipv6ExtensionDestination> ();
1245  destinationExtension->SetNode (m_node);
1246  Ptr<Ipv6ExtensionFragment> fragmentExtension = CreateObject<Ipv6ExtensionFragment> ();
1247  fragmentExtension->SetNode (m_node);
1248  Ptr<Ipv6ExtensionRouting> routingExtension = CreateObject<Ipv6ExtensionRouting> ();
1249  routingExtension->SetNode (m_node);
1250  // Ptr<Ipv6ExtensionESP> espExtension = CreateObject<Ipv6ExtensionESP> ();
1251  // Ptr<Ipv6ExtensionAH> ahExtension = CreateObject<Ipv6ExtensionAH> ();
1252 
1253  ipv6ExtensionDemux->Insert (hopbyhopExtension);
1254  ipv6ExtensionDemux->Insert (destinationExtension);
1255  ipv6ExtensionDemux->Insert (fragmentExtension);
1256  ipv6ExtensionDemux->Insert (routingExtension);
1257  // ipv6ExtensionDemux->Insert (espExtension);
1258  // ipv6ExtensionDemux->Insert (ahExtension);
1259 
1260  Ptr<Ipv6ExtensionRoutingDemux> routingExtensionDemux = CreateObject<Ipv6ExtensionRoutingDemux> ();
1261  routingExtensionDemux->SetNode (m_node);
1262  Ptr<Ipv6ExtensionLooseRouting> looseRoutingExtension = CreateObject<Ipv6ExtensionLooseRouting> ();
1263  looseRoutingExtension->SetNode (m_node);
1264  routingExtensionDemux->Insert (looseRoutingExtension);
1265 
1266  m_node->AggregateObject (routingExtensionDemux);
1267  m_node->AggregateObject (ipv6ExtensionDemux);
1268 }
1269 
1271 {
1272  Ptr<Ipv6OptionDemux> ipv6OptionDemux = CreateObject<Ipv6OptionDemux> ();
1273  ipv6OptionDemux->SetNode (m_node);
1274 
1275  Ptr<Ipv6OptionPad1> pad1Option = CreateObject<Ipv6OptionPad1> ();
1276  pad1Option->SetNode (m_node);
1277  Ptr<Ipv6OptionPadn> padnOption = CreateObject<Ipv6OptionPadn> ();
1278  padnOption->SetNode (m_node);
1279  Ptr<Ipv6OptionJumbogram> jumbogramOption = CreateObject<Ipv6OptionJumbogram> ();
1280  jumbogramOption->SetNode (m_node);
1281  Ptr<Ipv6OptionRouterAlert> routerAlertOption = CreateObject<Ipv6OptionRouterAlert> ();
1282  routerAlertOption->SetNode (m_node);
1283 
1284  ipv6OptionDemux->Insert (pad1Option);
1285  ipv6OptionDemux->Insert (padnOption);
1286  ipv6OptionDemux->Insert (jumbogramOption);
1287  ipv6OptionDemux->Insert (routerAlertOption);
1288 
1289  m_node->AggregateObject (ipv6OptionDemux);
1290 }
1291 
1292 } /* namespace ns3 */
1293 
void SetNode(Ptr< Node > node)
Set the node associated with this socket.
bool IsAny() const
If the IPv6 address is the "Any" address.
void GetFragments(Ptr< Packet > packet, uint32_t fragmentSize, std::list< Ptr< Packet > > &listFragments)
Fragment a packet.
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
Definition: ipv6-header.cc:144
static bool IsMatchingType(const Address &address)
uint8_t GetNextHeader(void) const
Get the next header.
Definition: ipv6-header.cc:82
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberContainer)
Definition: object-vector.h:51
void SetPayloadLength(uint16_t len)
Set the "Payload length" field.
Definition: ipv6-header.cc:67
static Ipv6Address GetLoopback()
Get the loopback address.
Ipv6Header BuildHeader(Ipv6Address src, Ipv6Address dst, uint8_t protocol, uint16_t payloadSize, uint8_t hopLimit, uint8_t tclass)
Construct an IPv6 header.
void SetForwarding(uint32_t i, bool val)
Enable or disable forwarding on interface.
Doxygen introspection did not find any typical Config paths.
Definition: ipv6-header.h:33
bool AddAddress(Ipv6InterfaceAddress iface)
Add an IPv6 address.
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
virtual ~Ipv6L3Protocol()
Destructor.
void SetUp()
Enable this interface.
Hold a bool native type.
Definition: boolean.h:38
Ipv6L3Protocol()
Constructor.
virtual void SetPmtu(Ipv6Address dst, uint32_t pmtu)
Set the Path MTU for the specified IPv6 destination address.
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer...
Definition: socket.h:1044
NS_LOG_COMPONENT_DEFINE("GrantedTimeWindowMpiInterface")
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.
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:79
static Mac16Address ConvertFrom(const Address &address)
static bool IsMatchingType(const Address &address)
Ptr< Ipv6RoutingProtocol > GetRoutingProtocol() const
Get current routing protocol used.
uint32_t AddIpv6Interface(Ptr< Ipv6Interface > interface)
Add an IPv6 interface to the stack.
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...
Doxygen introspection did not find any typical Config paths.
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
bool IsAllRoutersMulticast() const
If the IPv6 address is "all routers multicast" (ff02::2/8).
Interface is down so can not send packet.
void SetNode(Ptr< Node > node)
Set the node.
#define NS_ASSERT(condition)
Definition: assert.h:64
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
Ipv6InterfaceAddress GetAddress(uint32_t index) const
Get an address from IPv6 interface.
static Ipv6Address MakeAutoconfiguredAddress(Mac16Address addr, Ipv6Address prefix)
Make the autoconfigured IPv6 address with Mac16Address.
IPv6 address associated with an interface.
static const uint8_t PROT_NUMBER
ICMPv6 protocol number (58).
uint32_t GetNAddresses(uint32_t interface) const
Get number of address for an interface.
uint32_t GetSize(void) const
Definition: packet.h:650
void SetNextHeader(uint8_t next)
Set the "Next header" field.
Definition: ipv6-header.cc:77
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.
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:336
bool IsDocumentation() const
If the IPv6 address is a documentation address (2001:DB8::/32).
#define NS_LOG_INFO(msg)
Definition: log.h:298
bool IsAllHostsMulticast() const
If the IPv6 address is "all hosts multicast" (ff02::3/8).
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
virtual bool GetSendIcmpv6Redirect() const
Get the ICMPv6 Redirect sending state.
bool IsAllNodesMulticast() const
If the IPv6 address is "all nodes multicast" (ff02::1/8).
virtual void DoDispose()
Dispose object.
void SetMetric(uint32_t i, uint16_t metric)
Set metric for an interface.
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.
bool IsUp() const
Is the interface UP ?
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
a polymophic address class
Definition: address.h:86
virtual void SetIpForward(bool forward)
Set IPv6 forwarding state.
virtual void NotifyNewAggregate()
Notify other components connected to the node that a new stack member is now connected.
Ptr< T > CreateObject(void)
Definition: object.h:420
bool IsUp(uint32_t i) const
Is specified interface up ?
uint32_t m_nInterfaces
Number of IPv6 interfaces managed by the stack.
void SetDefaultTclass(uint8_t tclass)
Set the default TCLASS.
Ipv6Address GetAddress() const
Get the IPv6 address.
uint32_t GetNAddresses(void) const
Get number of addresses on this IPv6 interface.
void SetMetric(uint16_t metric)
Set the metric.
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Definition: packet.cc:353
int32_t GetInterfaceForPrefix(Ipv6Address addr, Ipv6Prefix mask) const
Get interface index which match specified address/prefix.
uint8_t GetTclass(void) const
Get the tag's Tclass.
Definition: socket.cc:827
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:46
L4List_t m_protocols
List of transport protocol.
void SetDefaultTtl(uint8_t ttl)
Set the default TTL.
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
void IpMulticastForward(Ptr< const NetDevice > idev, Ptr< Ipv6MulticastRoute > mrtentry, Ptr< const Packet > p, const Ipv6Header &header)
Forward a multicast packet.
T * PeekPointer(const Ptr< T > &p)
Definition: ptr.h:279
Ptr< NetDevice > GetDevice(uint32_t index) const
Definition: node.cc:132
void SetUp(uint32_t i)
Set an interface up.
An implementation of the ICMPv6 protocol.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
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 Ptr< NetDevice > GetDevice() const
Get the NetDevice.
static TypeId GetTypeId()
Get the type ID of this class.
Ipv6InterfaceList m_interfaces
List of IPv6 interfaces.
void AggregateObject(Ptr< Object > other)
Definition: object.cc:243
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
#define list
bool m_ipForward
Forwarding packets (i.e.
uint32_t GetNInterfaces() const
Get current number of interface on this stack.
static Mac48Address ConvertFrom(const Address &address)
uint16_t GetMetric(uint32_t i) const
Get metric for an interface.
virtual void NotifyNewAggregate(void)
This method is invoked whenever two sets of objects are aggregated together.
Definition: object.cc:315
uint32_t GetNDevices(void) const
Definition: node.cc:140
void SetForwarding(bool forward)
Set forwarding enabled or not.
Ptr< Packet > Copy(void) const
Definition: packet.cc:122
std::list< Ptr< Ipv6AutoconfiguredPrefix > >::iterator Ipv6AutoconfiguredPrefixListI
Iterator of the container of the IPv6 Autoconfigured addresses.
uint8_t GetHopLimit(void) const
Get the "Hop limit" field (TTL).
Definition: ipv6-header.cc:92
Ipv6AutoconfiguredPrefixList m_prefixes
List of IPv6 prefix received from RA.
void LocalDeliver(Ptr< const Packet > p, Ipv6Header const &ip, uint32_t iif)
Deliver a packet.
void DeleteRawSocket(Ptr< Socket > socket)
Remove raw IPv6 socket.
virtual bool GetIpForward() const
Get IPv6 forwarding state.
static uint16_t GetStaticProtocolNumber()
Get ICMPv6 protocol number.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
void IpForward(Ptr< const NetDevice > idev, Ptr< Ipv6Route > rtentry, Ptr< const Packet > p, const Ipv6Header &header)
Forward a packet.
Ipv6InterfaceAddress GetAddress(uint32_t interfaceIndex, uint32_t addressIndex) const
Get an address.
uint8_t m_defaultTtl
Default TTL for outgoing packets.
indicates whether the socket has IPV6_TCLASS set.
Definition: socket.h:1189
TracedCallback< const Ipv6Header &, Ptr< const Packet >, DropReason, Ptr< Ipv6 >, uint32_t > m_dropTrace
Callback to trace drop packets.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
TracedCallback< Ptr< const Packet >, Ptr< Ipv6 >, uint32_t > m_rxTrace
Callback to trace RX (reception) packets.
int32_t GetInterfaceForDevice(Ptr< const NetDevice > device) const
Get interface index which is on a specified net device.
uint16_t GetPayloadLength(void) const
Get the "Payload length" field.
Definition: ipv6-header.cc:72
void SetNode(Ptr< Node > node)
Set node associated with this stack.
bool IsForwarding(uint32_t i) const
Is interface allows forwarding ?
void RemoveAutoconfiguredAddress(uint32_t interface, Ipv6Address network, Ipv6Prefix mask, Ipv6Address defaultRouter)
Remove an autoconfigured address.
void SendRealOut(Ptr< Ipv6Route > route, Ptr< Packet > packet, Ipv6Header const &ipHeader)
Send packet with route.
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:217
void SetupLoopback()
Setup loopback interface.
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
void SetSourceAddress(Ipv6Address src)
Set the "Source address" field.
Definition: ipv6-header.cc:97
Doxygen introspection did not find any typical Config paths.
virtual void RegisterExtensions()
Register the IPv6 Extensions.
uint8_t GetHopLimit(void) const
Get the tag's Hop Limit.
Definition: socket.cc:651
Ipv6InterfaceAddress GetLinkLocalAddress() const
Get link-local address from IPv6 interface.
Describes an IPv6 address.
Definition: ipv6-address.h:46
uint16_t GetMetric() const
Get the metric.
void SetRoutingProtocol(Ptr< Ipv6RoutingProtocol > routingProtocol)
Set routing protocol for this stack.
bool IsSolicitedMulticast() const
If the IPv6 address is a Solicited multicast address.
void SetHopLimit(uint8_t limit)
Set the "Hop limit" field (TTL).
Definition: ipv6-header.cc:87
uint32_t AddDevice(Ptr< NetDevice > device)
Definition: node.cc:118
Ptr< IpL4Protocol > GetProtocol(int protocolNumber) const
Get L4 protocol by protocol number.
uint32_t GetId(void) const
Definition: node.cc:104
Ptr< Icmpv6L4Protocol > GetIcmpv6() const
Get ICMPv6 protocol.
static Mac64Address ConvertFrom(const Address &address)
#define NS_LOG_WARN(msg)
Definition: log.h:280
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:848
void Insert(Ptr< IpL4Protocol > protocol)
Add an L4 protocol.
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:102
uint16_t GetMtu(uint32_t i) const
Get MTU for an interface.
bool m_sendIcmpv6Redirect
Allow ICMPv6 Redirect sending state.
virtual void RegisterOptions()
Register the IPv6 Options.
Describes an IPv6 prefix.
Definition: ipv6-address.h:387
void SetDown(uint32_t i)
set an interface down.
void SetTrafficClass(uint8_t traffic)
Set the "Traffic class" field.
Definition: ipv6-header.cc:47
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:381
RxStatus
Rx status codes.
bool m_mtuDiscover
MTU Discover (i.e.
int32_t GetInterfaceForAddress(Ipv6Address addr) const
Get interface index which has specified IPv6 address.
tuple address
Definition: first.py:37
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:270
contain a set of ns3::Object pointers.
Ptr< Ipv6PmtuCache > m_pmtuCache
Path MTU Cache.
static bool IsMatchingType(const Address &address)
virtual bool GetMtuDiscover(void) const
Get IPv6 MTU discover state.
TracedCallback< Ptr< const Packet >, Ptr< Ipv6 >, uint32_t > m_txTrace
Callback to trace TX (transmission) packets.
virtual void SetMtuDiscover(bool mtuDiscover)
Set IPv6 MTU discover state.
Ipv6Address CombinePrefix(Ipv6Prefix const &prefix)
Combine this address with a prefix.
uint8_t m_defaultTclass
Default TCLASS for outgoing packets.
Ptr< T > GetObject(void) const
Definition: object.h:361
void SetDown()
Disable this interface.
a unique identifier for an interface.
Definition: type-id.h:49
void StartPreferredTimer()
Start the preferred timer.
void SetDestinationAddress(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:107
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
SocketList m_sockets
List of IPv6 raw sockets.
static const uint16_t PROT_NUMBER
The protocol number for IPv6 (0x86DD).
Ptr< Ipv6Interface > GetInterface(uint32_t i) const
Get an interface.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:112
void Remove(Ptr< IpL4Protocol > protocol)
Remove an L4 protocol.
void AddAutoconfiguredAddress(uint32_t interface, Ipv6Address network, Ipv6Prefix mask, uint8_t flags, uint32_t validTime, uint32_t preferredTime, Ipv6Address defaultRouter=Ipv6Address::GetZero())
Add an autoconfigured address with RA information.
virtual void SetSendIcmpv6Redirect(bool sendIcmpv6Redirect)
Set the ICMPv6 Redirect sending state.
void RouteInputError(Ptr< const Packet > p, const Ipv6Header &ipHeader, Socket::SocketErrno sockErrno)
Fallback when no route is found.