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 
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_LOG_COMPONENT_DEFINE ("Ipv6L3Protocol");
53 
54 NS_OBJECT_ENSURE_REGISTERED (Ipv6L3Protocol);
55 
56 const uint16_t Ipv6L3Protocol::PROT_NUMBER = 0x86DD;
57 
59 {
60  static TypeId tid = TypeId ("ns3::Ipv6L3Protocol")
61  .SetParent<Ipv6> ()
62  .SetGroupName ("Internet")
63  .AddConstructor<Ipv6L3Protocol> ()
64  .AddAttribute ("DefaultTtl",
65  "The TTL value set by default on all "
66  "outgoing packets generated on this node.",
67  UintegerValue (64),
69  MakeUintegerChecker<uint8_t> ())
70  .AddAttribute ("DefaultTclass",
71  "The TCLASS value set by default on all "
72  "outgoing packets generated on this node.",
73  UintegerValue (0),
75  MakeUintegerChecker<uint8_t> ())
76  .AddAttribute ("InterfaceList",
77  "The set of IPv6 interfaces associated to this IPv6 stack.",
80  MakeObjectVectorChecker<Ipv6Interface> ())
81  .AddAttribute ("SendIcmpv6Redirect",
82  "Send the ICMPv6 Redirect when appropriate.",
83  BooleanValue (true),
87  .AddTraceSource ("Tx",
88  "Send IPv6 packet to outgoing interface.",
90  "ns3::Ipv6L3Protocol::TxRxTracedCallback")
91  .AddTraceSource ("Rx",
92  "Receive IPv6 packet from incoming interface.",
94  "ns3::Ipv6L3Protocol::TxRxTracedCallback")
95  .AddTraceSource ("Drop",
96  "Drop IPv6 packet",
98  "ns3::Ipv6L3Protocol::DropTracedCallback")
99 
100  .AddTraceSource ("SendOutgoing",
101  "A newly-generated packet by this node is "
102  "about to be queued for transmission",
104  "ns3::Ipv6L3Protocol::SentTracedCallback")
105  .AddTraceSource ("UnicastForward",
106  "A unicast IPv6 packet was received by this node "
107  "and is being forwarded to another node",
109  "ns3::Ipv6L3Protocol::SentTracedCallback")
110  .AddTraceSource ("LocalDeliver",
111  "An IPv6 packet was received by/for this node, "
112  "and it is being forward up the stack",
114  "ns3::Ipv6L3Protocol::SentTracedCallback")
115  ;
116  return tid;
117 }
118 
120  : m_nInterfaces (0)
121 {
123  m_pmtuCache = CreateObject<Ipv6PmtuCache> ();
124 }
125 
127 {
129 }
130 
132 {
134 
135  /* clear protocol and interface list */
136  for (L4List_t::iterator it = m_protocols.begin (); it != m_protocols.end (); ++it)
137  {
138  *it = 0;
139  }
140  m_protocols.clear ();
141 
142  /* remove interfaces */
143  for (Ipv6InterfaceList::iterator it = m_interfaces.begin (); it != m_interfaces.end (); ++it)
144  {
145  *it = 0;
146  }
147  m_interfaces.clear ();
148 
149  /* remove raw sockets */
150  for (SocketList::iterator it = m_sockets.begin (); it != m_sockets.end (); ++it)
151  {
152  *it = 0;
153  }
154  m_sockets.clear ();
155 
156  /* remove list of prefix */
157  for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin (); it != m_prefixes.end (); ++it)
158  {
159  (*it)->StopValidTimer ();
160  (*it)->StopPreferredTimer ();
161  (*it) = 0;
162  }
163  m_prefixes.clear ();
164 
165  m_node = 0;
166  m_routingProtocol = 0;
167  m_pmtuCache = 0;
169 }
170 
172 {
173  NS_LOG_FUNCTION (this << routingProtocol);
174  m_routingProtocol = routingProtocol;
175  m_routingProtocol->SetIpv6 (this);
176 }
177 
179 {
181  return m_routingProtocol;
182 }
183 
185 {
186  NS_LOG_FUNCTION (this << device);
187  Ptr<Node> node = GetObject<Node> ();
188  Ptr<Ipv6Interface> interface = CreateObject<Ipv6Interface> ();
189 
190  node->RegisterProtocolHandler (MakeCallback (&Ipv6L3Protocol::Receive, this), Ipv6L3Protocol::PROT_NUMBER, device);
191  interface->SetNode (m_node);
192  interface->SetDevice (device);
193  interface->SetForwarding (m_ipForward);
194  return AddIpv6Interface (interface);
195 }
196 
198 {
199  NS_LOG_FUNCTION (this << interface);
200  uint32_t index = m_nInterfaces;
201 
202  m_interfaces.push_back (interface);
203  m_nInterfaces++;
204  return index;
205 }
206 
208 {
209  NS_LOG_FUNCTION (this << index);
210  uint32_t tmp = 0;
211 
212  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
213  {
214  if (index == tmp)
215  {
216  return *it;
217  }
218  tmp++;
219  }
220  return 0;
221 }
222 
224 {
226  return m_nInterfaces;
227 }
228 
230 {
231  NS_LOG_FUNCTION (this << address);
232  int32_t index = 0;
233 
234  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
235  {
236  uint32_t j = 0;
237  uint32_t max = (*it)->GetNAddresses ();
238 
239  for (j = 0; j < max; j++)
240  {
241  if ((*it)->GetAddress (j).GetAddress () == address)
242  {
243  return index;
244  }
245  }
246  index++;
247  }
248  return -1;
249 }
250 
252 {
253  NS_LOG_FUNCTION (this << address << mask);
254  int32_t index = 0;
255 
256  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
257  {
258  uint32_t j = 0;
259  for (j = 0; j < (*it)->GetNAddresses (); j++)
260  {
261  if ((*it)->GetAddress (j).GetAddress ().CombinePrefix (mask) == address.CombinePrefix (mask))
262  {
263  return index;
264  }
265  }
266  index++;
267  }
268  return -1;
269 }
270 
272 {
273  NS_LOG_FUNCTION (this << i);
274  return GetInterface (i)->GetDevice ();
275 }
276 
278 {
279  NS_LOG_FUNCTION (this << device);
280  int32_t index = 0;
281 
282  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
283  {
284  if ((*it)->GetDevice () == device)
285  {
286  return index;
287  }
288  index++;
289  }
290  return -1;
291 }
292 
293 void Ipv6L3Protocol::AddAutoconfiguredAddress (uint32_t interface, Ipv6Address network, Ipv6Prefix mask, uint8_t flags, uint32_t validTime, uint32_t preferredTime, Ipv6Address defaultRouter)
294 {
295  NS_LOG_FUNCTION (this << interface << network << mask << (uint32_t)flags << validTime << preferredTime);
297 
298  Address addr = GetInterface (interface)->GetDevice ()->GetAddress ();
299 
300  if (flags & (1 << 6)) /* auto flag */
301  {
302  // In case of new MacAddress types, remember to change Ipv6L3Protocol::RemoveAutoconfiguredAddress as well
303  if (Mac64Address::IsMatchingType (addr))
304  {
306  }
307  else if (Mac48Address::IsMatchingType (addr))
308  {
310  }
311  else if (Mac16Address::IsMatchingType (addr))
312  {
314  }
315  else
316  {
317  NS_FATAL_ERROR ("Unknown method to make autoconfigured address for this kind of device.");
318  return;
319  }
320 
321  /* see if we have already the prefix */
322  for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin (); it != m_prefixes.end (); ++it)
323  {
324  if ((*it)->GetInterface () == interface && (*it)->GetPrefix () == network && (*it)->GetMask () == mask)
325  {
326  (*it)->StopPreferredTimer ();
327  (*it)->StopValidTimer ();
328  (*it)->StartPreferredTimer ();
329  return;
330  }
331  }
332 
333  /* no prefix found, add autoconfigured address and the prefix */
334  NS_LOG_INFO ("Autoconfigured address is :" << address.GetAddress ());
335  AddAddress (interface, address);
336 
337  /* add default router
338  * if a previous default route exists, the new ones is simply added
339  */
340  if (!defaultRouter.IsAny())
341  {
342  GetRoutingProtocol ()->NotifyAddRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
343  }
344 
345  Ptr<Ipv6AutoconfiguredPrefix> aPrefix = CreateObject<Ipv6AutoconfiguredPrefix> (m_node, interface, network, mask, preferredTime, validTime, defaultRouter);
346  aPrefix->StartPreferredTimer ();
347 
348  m_prefixes.push_back (aPrefix);
349  }
350 }
351 
352 void Ipv6L3Protocol::RemoveAutoconfiguredAddress (uint32_t interface, Ipv6Address network, Ipv6Prefix mask, Ipv6Address defaultRouter)
353 {
354  NS_LOG_FUNCTION (this << interface << network << mask);
355  Ptr<Ipv6Interface> iface = GetInterface (interface);
356  Address addr = iface->GetDevice ()->GetAddress ();
357  uint32_t max = iface->GetNAddresses ();
358  uint32_t i = 0;
359  Ipv6Address toFound;
360 
361  if (Mac64Address::IsMatchingType (addr))
362  {
364  }
365  else if (Mac48Address::IsMatchingType (addr))
366  {
368  }
369  else if (Mac16Address::IsMatchingType (addr))
370  {
372  }
373  else
374  {
375  NS_FATAL_ERROR ("Unknown method to make autoconfigured address for this kind of device.");
376  return;
377  }
378 
379  for (i = 0; i < max; i++)
380  {
381  if (iface->GetAddress (i).GetAddress () == toFound)
382  {
383  RemoveAddress (interface, i);
384  break;
385  }
386  }
387 
388  /* remove from list of autoconfigured address */
389  for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin (); it != m_prefixes.end (); ++it)
390  {
391  if ((*it)->GetInterface () == interface && (*it)->GetPrefix () == network && (*it)->GetMask () == mask)
392  {
393  *it = 0;
394  m_prefixes.erase (it);
395  break;
396  }
397  }
398 
399  GetRoutingProtocol ()->NotifyRemoveRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
400 }
401 
403 {
404  NS_LOG_FUNCTION (this << i << address);
405  Ptr<Ipv6Interface> interface = GetInterface (i);
406  bool ret = interface->AddAddress (address);
407 
408  if (m_routingProtocol != 0)
409  {
410  m_routingProtocol->NotifyAddAddress (i, address);
411  }
412  return ret;
413 }
414 
415 uint32_t Ipv6L3Protocol::GetNAddresses (uint32_t i) const
416 {
417  NS_LOG_FUNCTION (this << i);
418  Ptr<Ipv6Interface> interface = GetInterface (i);
419  return interface->GetNAddresses ();
420 }
421 
422 Ipv6InterfaceAddress Ipv6L3Protocol::GetAddress (uint32_t i, uint32_t addressIndex) const
423 {
424  NS_LOG_FUNCTION (this << i << addressIndex);
425  Ptr<Ipv6Interface> interface = GetInterface (i);
426  return interface->GetAddress (addressIndex);
427 }
428 
429 bool Ipv6L3Protocol::RemoveAddress (uint32_t i, uint32_t addressIndex)
430 {
431  NS_LOG_FUNCTION (this << i << addressIndex);
432  Ptr<Ipv6Interface> interface = GetInterface (i);
433  Ipv6InterfaceAddress address = interface->RemoveAddress (addressIndex);
434 
435  if (address != Ipv6InterfaceAddress ())
436  {
437  if (m_routingProtocol != 0)
438  {
439  m_routingProtocol->NotifyRemoveAddress (i, address);
440  }
441  return true;
442  }
443  return false;
444 }
445 
446 bool
448 {
449  NS_LOG_FUNCTION (this << i << address);
450 
451  if (address == Ipv6Address::GetLoopback())
452  {
453  NS_LOG_WARN ("Cannot remove loopback address.");
454  return false;
455  }
456  Ptr<Ipv6Interface> interface = GetInterface (i);
457  Ipv6InterfaceAddress ifAddr = interface->RemoveAddress (address);
458  if (ifAddr != Ipv6InterfaceAddress ())
459  {
460  if (m_routingProtocol != 0)
461  {
462  m_routingProtocol->NotifyRemoveAddress (i, ifAddr);
463  }
464  return true;
465  }
466  return false;
467 }
468 
469 void Ipv6L3Protocol::SetMetric (uint32_t i, uint16_t metric)
470 {
471  NS_LOG_FUNCTION (this << i << metric);
472  Ptr<Ipv6Interface> interface = GetInterface (i);
473  interface->SetMetric (metric);
474 }
475 
476 uint16_t Ipv6L3Protocol::GetMetric (uint32_t i) const
477 {
478  NS_LOG_FUNCTION (this << i);
479  Ptr<Ipv6Interface> interface = GetInterface (i);
480  return interface->GetMetric ();
481 }
482 
483 uint16_t Ipv6L3Protocol::GetMtu (uint32_t i) const
484 {
485  NS_LOG_FUNCTION (this << i);
486 
487  // RFC 1981, if PMTU is disabled, return the minimum MTU
488  if (!m_mtuDiscover)
489  {
490  return IPV6_MIN_MTU;
491  }
492 
493  Ptr<Ipv6Interface> interface = GetInterface (i);
494  return interface->GetDevice ()->GetMtu ();
495 }
496 
497 void Ipv6L3Protocol::SetPmtu (Ipv6Address dst, uint32_t pmtu)
498 {
499  NS_LOG_FUNCTION (this << dst << int(pmtu));
500  m_pmtuCache->SetPmtu (dst, pmtu);
501 }
502 
503 
504 bool Ipv6L3Protocol::IsUp (uint32_t i) const
505 {
506  NS_LOG_FUNCTION (this << i);
507  Ptr<Ipv6Interface> interface = GetInterface (i);
508  return interface->IsUp ();
509 }
510 
511 void Ipv6L3Protocol::SetUp (uint32_t i)
512 {
513  NS_LOG_FUNCTION (this << i);
514  Ptr<Ipv6Interface> interface = GetInterface (i);
515 
516  // RFC 2460, Section 5, pg. 24:
517  // IPv6 requires that every link in the internet have an MTU of 1280
518  // octets or greater. On any link that cannot convey a 1280-octet
519  // packet in one piece, link-specific fragmentation and reassembly must
520  // be provided at a layer below IPv6.
521  if (interface->GetDevice ()->GetMtu () >= 1280)
522  {
523  interface->SetUp ();
524 
525  if (m_routingProtocol != 0)
526  {
527  m_routingProtocol->NotifyInterfaceUp (i);
528  }
529  }
530  else
531  {
532  NS_LOG_LOGIC ("Interface " << int(i) << " is set to be down for IPv6. Reason: not respecting minimum IPv6 MTU (1280 octects)");
533  }
534 }
535 
536 void Ipv6L3Protocol::SetDown (uint32_t i)
537 {
538  NS_LOG_FUNCTION (this << i);
539  Ptr<Ipv6Interface> interface = GetInterface (i);
540 
541  interface->SetDown ();
542 
543  if (m_routingProtocol != 0)
544  {
545  m_routingProtocol->NotifyInterfaceDown (i);
546  }
547 }
548 
550 {
552  Ptr<Ipv6Interface> interface = CreateObject<Ipv6Interface> ();
553  Ptr<LoopbackNetDevice> device = 0;
554  uint32_t i = 0;
555 
556  /* see if we have already an loopback NetDevice */
557  for (i = 0; i < m_node->GetNDevices (); i++)
558  {
559  if ((device = DynamicCast<LoopbackNetDevice> (m_node->GetDevice (i))))
560  {
561  break;
562  }
563  }
564 
565  if (device == 0)
566  {
567  device = CreateObject<LoopbackNetDevice> ();
568  m_node->AddDevice (device);
569  }
570 
571  interface->SetDevice (device);
572  interface->SetNode (m_node);
574  interface->AddAddress (ifaceAddr);
575  uint32_t index = AddIpv6Interface (interface);
576  Ptr<Node> node = GetObject<Node> ();
577  node->RegisterProtocolHandler (MakeCallback (&Ipv6L3Protocol::Receive, this), Ipv6L3Protocol::PROT_NUMBER, device);
578  interface->SetUp ();
579 
580  if (m_routingProtocol != 0)
581  {
582  m_routingProtocol->NotifyInterfaceUp (index);
583  }
584 }
585 
586 bool Ipv6L3Protocol::IsForwarding (uint32_t i) const
587 {
588  NS_LOG_FUNCTION (this << i);
589  Ptr<Ipv6Interface> interface = GetInterface (i);
590 
591  NS_LOG_LOGIC ("Forwarding state: " << interface->IsForwarding ());
592  return interface->IsForwarding ();
593 }
594 
595 void Ipv6L3Protocol::SetForwarding (uint32_t i, bool val)
596 {
597  NS_LOG_FUNCTION (this << i << val);
598  Ptr<Ipv6Interface> interface = GetInterface (i);
599  interface->SetForwarding (val);
600 }
601 
603 {
604  NS_LOG_FUNCTION (this << interface << dest);
605  Ipv6Address ret;
606 
607  if (dest.IsLinkLocal () || dest.IsLinkLocalMulticast ())
608  {
609  for (uint32_t i = 0; i < GetNAddresses (interface); i++)
610  {
611  Ipv6InterfaceAddress test = GetAddress (interface, i);
613  {
614  return test.GetAddress ();
615  }
616  }
617  NS_ASSERT_MSG (false, "No link-local address found on interface " << interface);
618  }
619 
620  for (uint32_t i = 0; i < GetNAddresses (interface); i++)
621  {
622  Ipv6InterfaceAddress test = GetAddress (interface, i);
623 
624  if (test.GetScope () == Ipv6InterfaceAddress::GLOBAL)
625  {
626  if (test.IsInSameSubnet (dest))
627  {
628  return test.GetAddress ();
629  }
630  else
631  {
632  ret = test.GetAddress ();
633  }
634  }
635  }
636 
637  // no specific match found. Use a global address (any useful is fine).
638  return ret;
639 }
640 
641 void Ipv6L3Protocol::SetIpForward (bool forward)
642 {
643  NS_LOG_FUNCTION (this << forward);
644  m_ipForward = forward;
645 
646  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
647  {
648  (*it)->SetForwarding (forward);
649  }
650 }
651 
653 {
655  return m_ipForward;
656 }
657 
658 void Ipv6L3Protocol::SetMtuDiscover (bool mtuDiscover)
659 {
660  NS_LOG_FUNCTION (this << int(mtuDiscover));
661  m_mtuDiscover = mtuDiscover;
662 }
663 
665 {
666  NS_LOG_FUNCTION (this);
667  return m_mtuDiscover;
668 }
669 
670 void Ipv6L3Protocol::SetSendIcmpv6Redirect (bool sendIcmpv6Redirect)
671 {
672  NS_LOG_FUNCTION (this << sendIcmpv6Redirect);
673  m_sendIcmpv6Redirect = sendIcmpv6Redirect;
674 }
675 
677 {
679  return m_sendIcmpv6Redirect;
680 }
681 
683 {
685 
686  if (m_node == 0)
687  {
688  Ptr<Node> node = this->GetObject<Node> ();
689  // verify that it's a valid node and that
690  // the node has not been set before
691  if (node != 0)
692  {
693  this->SetNode (node);
694  }
695  }
697 }
698 
700 {
701  NS_LOG_FUNCTION (this << node);
702  m_node = node;
703  /* add LoopbackNetDevice if needed, and an Ipv6Interface on top of it */
704  SetupLoopback ();
705 }
706 
708 {
709  NS_LOG_FUNCTION (this << protocol);
710  m_protocols.push_back (protocol);
711 }
712 
714 {
715  NS_LOG_FUNCTION (this << protocol);
716  m_protocols.remove (protocol);
717 }
718 
720 {
721  NS_LOG_FUNCTION (this << protocolNumber);
722 
723  for (L4List_t::const_iterator i = m_protocols.begin (); i != m_protocols.end (); ++i)
724  {
725  if ((*i)->GetProtocolNumber () == protocolNumber)
726  {
727  return *i;
728  }
729  }
730  return 0;
731 }
732 
734 {
736  Ptr<Ipv6RawSocketImpl> sock = CreateObject<Ipv6RawSocketImpl> ();
737  sock->SetNode (m_node);
738  m_sockets.push_back (sock);
739  return sock;
740 }
741 
743 {
744  NS_LOG_FUNCTION (this << socket);
745 
746  for (SocketList::iterator it = m_sockets.begin (); it != m_sockets.end (); ++it)
747  {
748  if ((*it) == socket)
749  {
750  m_sockets.erase (it);
751  return;
752  }
753  }
754 }
755 
757 {
760 
761  if (protocol)
762  {
763  return protocol->GetObject<Icmpv6L4Protocol> ();
764  }
765  else
766  {
767  return 0;
768  }
769 }
770 
772 {
773  NS_LOG_FUNCTION (this << ttl);
774  m_defaultTtl = ttl;
775 }
776 
777 void Ipv6L3Protocol::SetDefaultTclass (uint8_t tclass)
778 {
779  NS_LOG_FUNCTION (this << tclass);
780  m_defaultTclass = tclass;
781 }
782 
783 void Ipv6L3Protocol::Send (Ptr<Packet> packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr<Ipv6Route> route)
784 {
785  NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)protocol << route);
786  Ipv6Header hdr;
787  uint8_t ttl = m_defaultTtl;
789  bool found = packet->RemovePacketTag (tag);
790 
791  if (found)
792  {
793  ttl = tag.GetHopLimit ();
794  }
795 
796  SocketIpv6TclassTag tclassTag;
797  uint8_t tclass = m_defaultTclass;
798  found = packet->RemovePacketTag (tclassTag);
799 
800  if (found)
801  {
802  tclass = tclassTag.GetTclass ();
803  }
804 
805  /* Handle 3 cases:
806  * 1) Packet is passed in with a route entry
807  * 2) Packet is passed in with a route entry but route->GetGateway is not set (e.g., same network)
808  * 3) route is NULL (e.g., a raw socket call or ICMPv6)
809  */
810 
811  /* 1) */
812  if (route && route->GetGateway () != Ipv6Address::GetZero ())
813  {
814  NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 1: passed in with a route");
815  hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
816  int32_t interface = GetInterfaceForDevice (route->GetOutputDevice ());
817  m_sendOutgoingTrace (hdr, packet, interface);
818  SendRealOut (route, packet, hdr);
819  return;
820  }
821 
822  /* 2) */
823  if (route && route->GetGateway () == Ipv6Address::GetZero ())
824  {
825  NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 1: probably sent to machine on same IPv6 network");
826  /* NS_FATAL_ERROR ("This case is not yet implemented"); */
827  hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
828  int32_t interface = GetInterfaceForDevice (route->GetOutputDevice ());
829  m_sendOutgoingTrace (hdr, packet, interface);
830  SendRealOut (route, packet, hdr);
831  return;
832  }
833 
834  /* 3) */
835  NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 3: passed in with no route " << destination);
837  Ptr<NetDevice> oif (0);
838  Ptr<Ipv6Route> newRoute = 0;
839 
840  hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
841 
842  //for link-local traffic, we need to determine the interface
843  if (source.IsLinkLocal ()
844  || destination.IsLinkLocal ()
845  || destination.IsLinkLocalMulticast ())
846  {
847  int32_t index = GetInterfaceForAddress (source);
848  NS_ASSERT_MSG (index >= 0, "Can not find an outgoing interface for a packet with src " << source << " and dst " << destination);
849  oif = GetNetDevice (index);
850  }
851 
852  newRoute = m_routingProtocol->RouteOutput (packet, hdr, oif, err);
853 
854  if (newRoute)
855  {
856  int32_t interface = GetInterfaceForDevice (newRoute->GetOutputDevice ());
857  m_sendOutgoingTrace (hdr, packet, interface);
858  SendRealOut (newRoute, packet, hdr);
859  }
860  else
861  {
862  NS_LOG_WARN ("No route to host, drop!");
864  }
865 }
866 
867 void Ipv6L3Protocol::Receive (Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
868 {
869  NS_LOG_FUNCTION (this << device << p << protocol << from << to << packetType);
870  NS_LOG_LOGIC ("Packet from " << from << " received on node " << m_node->GetId ());
871  uint32_t interface = 0;
872  Ptr<Packet> packet = p->Copy ();
873  Ptr<Ipv6Interface> ipv6Interface = 0;
874 
875  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin (); it != m_interfaces.end (); it++)
876  {
877  ipv6Interface = *it;
878 
879  if (ipv6Interface->GetDevice () == device)
880  {
881  if (ipv6Interface->IsUp ())
882  {
883  m_rxTrace (packet, m_node->GetObject<Ipv6> (), interface);
884  break;
885  }
886  else
887  {
888  NS_LOG_LOGIC ("Dropping received packet-- interface is down");
889  Ipv6Header hdr;
890  packet->RemoveHeader (hdr);
891  m_dropTrace (hdr, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv6> (), interface);
892  return;
893  }
894  }
895  interface++;
896  }
897 
898  Ipv6Header hdr;
899  packet->RemoveHeader (hdr);
900 
901  // Trim any residual frame padding from underlying devices
902  if (hdr.GetPayloadLength () < packet->GetSize ())
903  {
904  packet->RemoveAtEnd (packet->GetSize () - hdr.GetPayloadLength ());
905  }
906 
907  /* forward up to IPv6 raw sockets */
908  for (SocketList::iterator it = m_sockets.begin (); it != m_sockets.end (); ++it)
909  {
910  Ptr<Ipv6RawSocketImpl> socket = *it;
911  socket->ForwardUp (packet, hdr, device);
912  }
913 
915  Ptr<Ipv6Extension> ipv6Extension = 0;
916  uint8_t nextHeader = hdr.GetNextHeader ();
917  bool stopProcessing = false;
918  bool isDropped = false;
919  DropReason dropReason;
920 
921  if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
922  {
923  ipv6Extension = ipv6ExtensionDemux->GetExtension (nextHeader);
924 
925  if (ipv6Extension)
926  {
927  ipv6Extension->Process (packet, 0, hdr, hdr.GetDestinationAddress (), (uint8_t *)0, stopProcessing, isDropped, dropReason);
928  }
929 
930  if (isDropped)
931  {
932  m_dropTrace (hdr, packet, dropReason, m_node->GetObject<Ipv6> (), interface);
933  }
934 
935  if (stopProcessing)
936  {
937  return;
938  }
939  }
940 
941  if (!m_routingProtocol->RouteInput (packet, hdr, device,
946  {
947  NS_LOG_WARN ("No route found for forwarding packet. Drop.");
948  GetIcmpv6 ()->SendErrorDestinationUnreachable (p->Copy (), hdr.GetSourceAddress (), Icmpv6Header::ICMPV6_NO_ROUTE);
949  m_dropTrace (hdr, packet, DROP_NO_ROUTE, m_node->GetObject<Ipv6> (), interface);
950  }
951 }
952 
954 {
955  NS_LOG_FUNCTION (this << route << packet << ipHeader);
956 
957  if (!route)
958  {
959  NS_LOG_LOGIC ("No route to host, drop!.");
960  return;
961  }
962 
963  Ptr<NetDevice> dev = route->GetOutputDevice ();
964  int32_t interface = GetInterfaceForDevice (dev);
965  NS_ASSERT (interface >= 0);
966 
967  Ptr<Ipv6Interface> outInterface = GetInterface (interface);
968  NS_LOG_LOGIC ("Send via NetDevice ifIndex " << dev->GetIfIndex () << " Ipv6InterfaceIndex " << interface);
969 
970  // Check packet size
971  std::list<Ptr<Packet> > fragments;
972 
973  // Check if we have a Path MTU stored. If so, use it. Else, use the link MTU.
974  size_t targetMtu = (size_t)(m_pmtuCache->GetPmtu (ipHeader.GetDestinationAddress()));
975  if (targetMtu == 0)
976  {
977  targetMtu = dev->GetMtu ();
978  }
979 
980  if (packet->GetSize () > targetMtu + 40) /* 40 => size of IPv6 header */
981  {
982  // Router => drop
983 
984  bool fromMe = false;
985  for (uint32_t i=0; i<GetNInterfaces(); i++ )
986  {
987  for (uint32_t j=0; j<GetNAddresses(i); j++ )
988  {
989  if (GetAddress(i,j).GetAddress() == ipHeader.GetSourceAddress())
990  {
991  fromMe = true;
992  break;
993  }
994  }
995  }
996  if (!fromMe)
997  {
998  Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6 ();
999  if ( icmpv6 )
1000  {
1001  packet->AddHeader(ipHeader);
1002  icmpv6->SendErrorTooBig (packet, ipHeader.GetSourceAddress (), dev->GetMtu ());
1003  }
1004  return;
1005  }
1006 
1007  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux> ();
1008 
1009  packet->AddHeader (ipHeader);
1010 
1011  // To get specific method GetFragments from Ipv6ExtensionFragmentation
1012  Ipv6ExtensionFragment *ipv6Fragment = dynamic_cast<Ipv6ExtensionFragment *> (PeekPointer (ipv6ExtensionDemux->GetExtension (Ipv6Header::IPV6_EXT_FRAGMENTATION)));
1013  NS_ASSERT (ipv6Fragment != 0);
1014  ipv6Fragment->GetFragments (packet, targetMtu, fragments);
1015  }
1016 
1017  if (!route->GetGateway ().IsEqual (Ipv6Address::GetAny ()))
1018  {
1019  if (outInterface->IsUp ())
1020  {
1021  NS_LOG_LOGIC ("Send to gateway " << route->GetGateway ());
1022 
1023  if (fragments.size () != 0)
1024  {
1025  std::ostringstream oss;
1026 
1027  /* IPv6 header is already added in fragments */
1028  for (std::list<Ptr<Packet> >::const_iterator it = fragments.begin (); it != fragments.end (); it++)
1029  {
1030  m_txTrace (*it, m_node->GetObject<Ipv6> (), interface);
1031  outInterface->Send (*it, route->GetGateway ());
1032  }
1033  }
1034  else
1035  {
1036  packet->AddHeader (ipHeader);
1037  m_txTrace (packet, m_node->GetObject<Ipv6> (), interface);
1038  outInterface->Send (packet, route->GetGateway ());
1039  }
1040  }
1041  else
1042  {
1043  NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << route->GetGateway ());
1044  m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv6> (), interface);
1045  }
1046  }
1047  else
1048  {
1049  if (outInterface->IsUp ())
1050  {
1051  NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestinationAddress ());
1052 
1053  if (fragments.size () != 0)
1054  {
1055  std::ostringstream oss;
1056 
1057  /* IPv6 header is already added in fragments */
1058  for (std::list<Ptr<Packet> >::const_iterator it = fragments.begin (); it != fragments.end (); it++)
1059  {
1060  m_txTrace (*it, m_node->GetObject<Ipv6> (), interface);
1061  outInterface->Send (*it, ipHeader.GetDestinationAddress ());
1062  }
1063  }
1064  else
1065  {
1066  packet->AddHeader (ipHeader);
1067  m_txTrace (packet, m_node->GetObject<Ipv6> (), interface);
1068  outInterface->Send (packet, ipHeader.GetDestinationAddress ());
1069  }
1070  }
1071  else
1072  {
1073  NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << ipHeader.GetDestinationAddress ());
1074  m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv6> (), interface);
1075  }
1076  }
1077 }
1078 
1080 {
1081  NS_LOG_FUNCTION (this << rtentry << p << header);
1082  NS_LOG_LOGIC ("Forwarding logic for node: " << m_node->GetId ());
1083 
1084  // Drop RFC 3849 packets: 2001:db8::/32
1085  if (header.GetDestinationAddress().IsDocumentation())
1086  {
1087  NS_LOG_WARN ("Received a packet for 2001:db8::/32 (documentation class). Drop.");
1088  m_dropTrace (header, p, DROP_ROUTE_ERROR, m_node->GetObject<Ipv6> (), 0);
1089  return;
1090  }
1091 
1092  // Forwarding
1093  Ipv6Header ipHeader = header;
1094  Ptr<Packet> packet = p->Copy ();
1095  ipHeader.SetHopLimit (ipHeader.GetHopLimit () - 1);
1096 
1097  if (ipHeader.GetSourceAddress ().IsLinkLocal ())
1098  {
1099  /* no forward for link-local address */
1100  return;
1101  }
1102 
1103  if (ipHeader.GetHopLimit () == 0)
1104  {
1105  NS_LOG_WARN ("TTL exceeded. Drop.");
1106  m_dropTrace (ipHeader, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv6> (), 0);
1107  // Do not reply to multicast IPv6 address
1108  if (ipHeader.GetDestinationAddress ().IsMulticast () == false)
1109  {
1110  packet->AddHeader (ipHeader);
1111  GetIcmpv6 ()->SendErrorTimeExceeded (packet, ipHeader.GetSourceAddress (), Icmpv6Header::ICMPV6_HOPLIMIT);
1112  }
1113  return;
1114  }
1115 
1116  /* ICMPv6 Redirect */
1117 
1118  /* if we forward to a machine on the same network as the source,
1119  * we send him an ICMPv6 redirect message to notify him that a short route
1120  * exists.
1121  */
1122 
1123  /* Theoretically we should also check if the redirect target is on the same network
1124  * as the source node. On the other hand, we are sure that the router we're redirecting to
1125  * used a link-local address. As a consequence, they MUST be on the same network, the link-local net.
1126  */
1127 
1128  if (m_sendIcmpv6Redirect && (rtentry->GetOutputDevice ()==idev))
1129  {
1130  NS_LOG_LOGIC ("ICMPv6 redirect!");
1131  Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6 ();
1132  Address hardwareTarget;
1133  Ipv6Address dst = header.GetDestinationAddress ();
1134  Ipv6Address src = header.GetSourceAddress ();
1135  Ipv6Address target = rtentry->GetGateway ();
1136  Ptr<Packet> copy = p->Copy ();
1137 
1138  if (target.IsAny ())
1139  {
1140  target = dst;
1141  }
1142 
1143  copy->AddHeader (header);
1144  Ipv6Address linkLocal = GetInterface (GetInterfaceForDevice (rtentry->GetOutputDevice ()))->GetLinkLocalAddress ().GetAddress ();
1145 
1146  if (icmpv6->Lookup (target, rtentry->GetOutputDevice (), 0, &hardwareTarget))
1147  {
1148  icmpv6->SendRedirection (copy, linkLocal, src, target, dst, hardwareTarget);
1149  }
1150  else
1151  {
1152  icmpv6->SendRedirection (copy, linkLocal, src, target, dst, Address ());
1153  }
1154  }
1155  int32_t interface = GetInterfaceForDevice (rtentry->GetOutputDevice ());
1156  m_unicastForwardTrace (ipHeader, packet, interface);
1157  SendRealOut (rtentry, packet, ipHeader);
1158 }
1159 
1161 {
1162  NS_LOG_FUNCTION (this << mrtentry << p << header);
1163  NS_LOG_LOGIC ("Multicast forwarding logic for node: " << m_node->GetId ());
1164 
1165  std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap ();
1166  std::map<uint32_t, uint32_t>::iterator mapIter;
1167 
1168  for (mapIter = ttlMap.begin (); mapIter != ttlMap.end (); mapIter++)
1169  {
1170  uint32_t interfaceId = mapIter->first;
1171  //uint32_t outputTtl = mapIter->second; // Unused for now
1172  Ptr<Packet> packet = p->Copy ();
1173  Ipv6Header h = header;
1174  h.SetHopLimit (header.GetHopLimit () - 1);
1175  if (h.GetHopLimit () == 0)
1176  {
1177  NS_LOG_WARN ("TTL exceeded. Drop.");
1178  m_dropTrace (header, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv6> (), interfaceId);
1179  return;
1180  }
1181  NS_LOG_LOGIC ("Forward multicast via interface " << interfaceId);
1182  Ptr<Ipv6Route> rtentry = Create<Ipv6Route> ();
1183  rtentry->SetSource (h.GetSourceAddress ());
1184  rtentry->SetDestination (h.GetDestinationAddress ());
1185  rtentry->SetGateway (Ipv6Address::GetAny ());
1186  rtentry->SetOutputDevice (GetNetDevice (interfaceId));
1187  SendRealOut (rtentry, packet, h);
1188  continue;
1189  }
1190 }
1191 
1192 void Ipv6L3Protocol::LocalDeliver (Ptr<const Packet> packet, Ipv6Header const& ip, uint32_t iif)
1193 {
1194  NS_LOG_FUNCTION (this << packet << ip << iif);
1195  Ptr<Packet> p = packet->Copy ();
1196  Ptr<IpL4Protocol> protocol = 0;
1197  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux> ();
1198  Ptr<Ipv6Extension> ipv6Extension = 0;
1199  Ipv6Address src = ip.GetSourceAddress ();
1200  Ipv6Address dst = ip.GetDestinationAddress ();
1201  uint8_t nextHeader = ip.GetNextHeader ();
1202  uint8_t nextHeaderPosition = 0;
1203  bool isDropped = false;
1204  bool stopProcessing = false;
1205  DropReason dropReason;
1206 
1207  // check for a malformed hop-by-hop extension
1208  // this is a common case when forging IPv6 raw packets
1209  if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1210  {
1211  uint8_t buf;
1212  p->CopyData (&buf, 1);
1214  {
1215  NS_LOG_WARN("Double Ipv6Header::IPV6_EXT_HOP_BY_HOP in packet, dropping packet");
1216  return;
1217  }
1218  }
1219 
1220  /* process all the extensions found and the layer 4 protocol */
1221  do
1222  {
1223  /* it return 0 for non-extension (i.e. layer 4 protocol) */
1224  ipv6Extension = ipv6ExtensionDemux->GetExtension (nextHeader);
1225 
1226  if (ipv6Extension)
1227  {
1228  uint8_t nextHeaderStep = 0;
1229  uint8_t curHeader = nextHeader;
1230  nextHeaderStep = ipv6Extension->Process (p, nextHeaderPosition, ip, dst, &nextHeader, stopProcessing, isDropped, dropReason);
1231  nextHeaderPosition += nextHeaderStep;
1232 
1233  if (isDropped)
1234  {
1235  m_dropTrace (ip, packet, dropReason, m_node->GetObject<Ipv6> (), iif);
1236  }
1237 
1238  if (stopProcessing)
1239  {
1240  return;
1241  }
1242  NS_ASSERT_MSG (nextHeaderStep != 0 || curHeader == Ipv6Header::IPV6_EXT_FRAGMENTATION,
1243  "Zero-size IPv6 Option Header, aborting" << *packet );
1244  }
1245  else
1246  {
1247  protocol = GetProtocol (nextHeader);
1248  // For ICMPv6 Error packets
1249  Ptr<Packet> malformedPacket = packet->Copy ();
1250  malformedPacket->AddHeader (ip);
1251 
1252  if (!protocol)
1253  {
1254  NS_LOG_LOGIC ("Unknown Next Header. Drop!");
1255 
1256  if (nextHeaderPosition == 0)
1257  {
1258  GetIcmpv6 ()->SendErrorParameterError (malformedPacket, dst, Icmpv6Header::ICMPV6_UNKNOWN_NEXT_HEADER, 40);
1259  }
1260  else
1261  {
1262  GetIcmpv6 ()->SendErrorParameterError (malformedPacket, dst, Icmpv6Header::ICMPV6_UNKNOWN_NEXT_HEADER, ip.GetSerializedSize () + nextHeaderPosition);
1263  }
1265  break;
1266  }
1267  else
1268  {
1269  p->RemoveAtStart (nextHeaderPosition);
1270  /* protocol->Receive (p, src, dst, incomingInterface); */
1271 
1272  /* L4 protocol */
1273  Ptr<Packet> copy = p->Copy ();
1274 
1275  m_localDeliverTrace (ip, p, iif);
1276 
1277  enum IpL4Protocol::RxStatus status = protocol->Receive (p, ip, GetInterface (iif));
1278 
1279  switch (status)
1280  {
1281  case IpL4Protocol::RX_OK:
1282  break;
1284  break;
1286  break;
1288  if (ip.GetDestinationAddress ().IsMulticast ())
1289  {
1290  /* do not rely on multicast address */
1291  break;
1292  }
1293 
1294  copy->AddHeader (ip);
1295  GetIcmpv6 ()->SendErrorDestinationUnreachable (copy, ip.GetSourceAddress (), Icmpv6Header::ICMPV6_PORT_UNREACHABLE);
1296  }
1297  }
1298  }
1299  }
1300  while (ipv6Extension);
1301 }
1302 
1304 {
1305  NS_LOG_FUNCTION (this << p << ipHeader << sockErrno);
1306  NS_LOG_LOGIC ("Route input failure-- dropping packet to " << ipHeader << " with errno " << sockErrno);
1307  m_dropTrace (ipHeader, p, DROP_ROUTE_ERROR, m_node->GetObject<Ipv6> (), 0);
1308 }
1309 
1310 Ipv6Header Ipv6L3Protocol::BuildHeader (Ipv6Address src, Ipv6Address dst, uint8_t protocol, uint16_t payloadSize, uint8_t ttl, uint8_t tclass)
1311 {
1312  NS_LOG_FUNCTION (this << src << dst << (uint32_t)protocol << (uint32_t)payloadSize << (uint32_t)ttl << (uint32_t)tclass);
1313  Ipv6Header hdr;
1314 
1315  hdr.SetSourceAddress (src);
1316  hdr.SetDestinationAddress (dst);
1317  hdr.SetNextHeader (protocol);
1318  hdr.SetPayloadLength (payloadSize);
1319  hdr.SetHopLimit (ttl);
1320  hdr.SetTrafficClass (tclass);
1321  return hdr;
1322 }
1323 
1325 {
1326  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = CreateObject<Ipv6ExtensionDemux> ();
1327  ipv6ExtensionDemux->SetNode (m_node);
1328 
1329  Ptr<Ipv6ExtensionHopByHop> hopbyhopExtension = CreateObject<Ipv6ExtensionHopByHop> ();
1330  hopbyhopExtension->SetNode (m_node);
1331  Ptr<Ipv6ExtensionDestination> destinationExtension = CreateObject<Ipv6ExtensionDestination> ();
1332  destinationExtension->SetNode (m_node);
1333  Ptr<Ipv6ExtensionFragment> fragmentExtension = CreateObject<Ipv6ExtensionFragment> ();
1334  fragmentExtension->SetNode (m_node);
1335  Ptr<Ipv6ExtensionRouting> routingExtension = CreateObject<Ipv6ExtensionRouting> ();
1336  routingExtension->SetNode (m_node);
1337  // Ptr<Ipv6ExtensionESP> espExtension = CreateObject<Ipv6ExtensionESP> ();
1338  // Ptr<Ipv6ExtensionAH> ahExtension = CreateObject<Ipv6ExtensionAH> ();
1339 
1340  ipv6ExtensionDemux->Insert (hopbyhopExtension);
1341  ipv6ExtensionDemux->Insert (destinationExtension);
1342  ipv6ExtensionDemux->Insert (fragmentExtension);
1343  ipv6ExtensionDemux->Insert (routingExtension);
1344  // ipv6ExtensionDemux->Insert (espExtension);
1345  // ipv6ExtensionDemux->Insert (ahExtension);
1346 
1347  Ptr<Ipv6ExtensionRoutingDemux> routingExtensionDemux = CreateObject<Ipv6ExtensionRoutingDemux> ();
1348  routingExtensionDemux->SetNode (m_node);
1349  Ptr<Ipv6ExtensionLooseRouting> looseRoutingExtension = CreateObject<Ipv6ExtensionLooseRouting> ();
1350  looseRoutingExtension->SetNode (m_node);
1351  routingExtensionDemux->Insert (looseRoutingExtension);
1352 
1353  m_node->AggregateObject (routingExtensionDemux);
1354  m_node->AggregateObject (ipv6ExtensionDemux);
1355 }
1356 
1358 {
1359  Ptr<Ipv6OptionDemux> ipv6OptionDemux = CreateObject<Ipv6OptionDemux> ();
1360  ipv6OptionDemux->SetNode (m_node);
1361 
1362  Ptr<Ipv6OptionPad1> pad1Option = CreateObject<Ipv6OptionPad1> ();
1363  pad1Option->SetNode (m_node);
1364  Ptr<Ipv6OptionPadn> padnOption = CreateObject<Ipv6OptionPadn> ();
1365  padnOption->SetNode (m_node);
1366  Ptr<Ipv6OptionJumbogram> jumbogramOption = CreateObject<Ipv6OptionJumbogram> ();
1367  jumbogramOption->SetNode (m_node);
1368  Ptr<Ipv6OptionRouterAlert> routerAlertOption = CreateObject<Ipv6OptionRouterAlert> ();
1369  routerAlertOption->SetNode (m_node);
1370 
1371  ipv6OptionDemux->Insert (pad1Option);
1372  ipv6OptionDemux->Insert (padnOption);
1373  ipv6OptionDemux->Insert (jumbogramOption);
1374  ipv6OptionDemux->Insert (routerAlertOption);
1375 
1376  m_node->AggregateObject (ipv6OptionDemux);
1377 }
1378 
1380 {
1381  m_dropTrace (ipHeader, p, dropReason, m_node->GetObject<Ipv6> (), 0);
1382 }
1383 
1384 } /* namespace ns3 */
1385 
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:81
void SetPayloadLength(uint16_t len)
Set the "Payload length" field.
Definition: ipv6-header.cc:66
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.
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:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
virtual ~Ipv6L3Protocol()
Destructor.
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
void SetUp()
Enable this interface.
AttributeValue implementation for Boolean.
Definition: boolean.h:34
Ipv6L3Protocol()
Constructor.
bool IsLinkLocalMulticast() const
If the IPv6 address is link-local multicast (ff02::/16).
virtual void SetPmtu(Ipv6Address dst, uint32_t pmtu)
Set the Path MTU for the specified IPv6 destination address.
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer...
Definition: socket.h:1047
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
Ptr< NetDevice > GetNetDevice(uint32_t i)
Get device by index.
bool AddAddress(uint32_t i, Ipv6InterfaceAddress address)
Add an address on interface.
Ptr< Ipv6RoutingProtocol > m_routingProtocol
Routing protocol.
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:80
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...
IPv6 layer implementation.
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:81
Introspection did not find any typical Config paths.
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
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
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:272
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:562
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
Ipv6InterfaceAddress GetAddress(uint32_t index) const
Get an address from IPv6 interface.
static Ipv6Address MakeAutoconfiguredAddress(Mac16Address addr, Ipv6Address prefix)
Make the autoconfigured IPv6 address with Mac16Address.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
IPv6 address associated with an interface.
uint32_t GetNAddresses(uint32_t interface) const
Get number of address for an interface.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:766
Link-local address (fe80::/64)
void SetNextHeader(uint8_t next)
Set the "Next header" field.
Definition: ipv6-header.cc:76
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)
Destructor implementation.
Definition: object.cc:339
bool IsDocumentation() const
If the IPv6 address is a documentation address (2001:DB8::/32).
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
#define NS_FATAL_ERROR(msg)
Fatal error handling.
Definition: fatal-error.h:100
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
virtual bool GetSendIcmpv6Redirect() const
Get the ICMPv6 Redirect sending state.
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.
Ptr< Node > m_node
Node attached to stack.
TracedCallback< const Ipv6Header &, Ptr< const Packet >, uint32_t > m_localDeliverTrace
Trace of locally delivered packets.
bool IsUp() const
Is the interface UP ?
a polymophic address class
Definition: address.h:90
virtual void SetIpForward(bool forward)
Set IPv6 forwarding state.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
virtual void NotifyNewAggregate()
Notify other components connected to the node that a new stack member is now connected.
bool IsUp(uint32_t i) const
Is specified interface up ?
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:828
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.
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.
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:135
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:1296
virtual enum RxStatus Receive(Ptr< Packet > p, Ipv4Header const &header, Ptr< Ipv4Interface > incomingInterface)=0
Called from lower-level layers to send the packet up in the stack.
virtual void ReportDrop(Ipv6Header ipHeader, Ptr< Packet > p, DropReason dropReason)
Report a packet drop.
virtual Ptr< NetDevice > GetDevice() const
Get the NetDevice.
static TypeId GetTypeId()
Get the type ID of this class.
Ipv6InterfaceList m_interfaces
List of IPv6 interfaces.
void Send(Ptr< Packet > p, Ipv6Address dest)
Send a packet through this interface.
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:246
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
#define list
bool m_ipForward
Forwarding packets (i.e.
uint32_t GetNInterfaces() const
Get current number of interface on this stack.
TracedCallback< const Ipv6Header &, Ptr< const Packet >, uint32_t > m_unicastForwardTrace
Trace of unicast forwarded packets.
static Mac48Address ConvertFrom(const Address &address)
uint16_t GetMetric(uint32_t i) const
Get metric for an interface.
virtual void NotifyNewAggregate(void)
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:318
uint32_t GetNDevices(void) const
Definition: node.cc:143
void SetForwarding(bool forward)
Set forwarding enabled or not.
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
bool IsInSameSubnet(Ipv6Address b) const
Checks if the address is in the same subnet.
std::list< Ptr< Ipv6AutoconfiguredPrefix > >::iterator Ipv6AutoconfiguredPrefixListI
Iterator of the container of the IPv6 Autoconfigured addresses.
uint8_t GetHopLimit(void) const
Get the "Hop limit" field (TTL).
Definition: ipv6-header.cc:91
Ipv6AutoconfiguredPrefixList m_prefixes
List of IPv6 prefix received from RA.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LocalDeliver(Ptr< const Packet > p, Ipv6Header const &ip, uint32_t iif)
Deliver a packet.
void DeleteRawSocket(Ptr< Socket > socket)
Remove raw IPv6 socket.
virtual bool GetIpForward() const
Get IPv6 forwarding state.
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
static uint16_t GetStaticProtocolNumber()
Get ICMPv6 protocol number.
Ipv6Address SourceAddressSelection(uint32_t interface, Ipv6Address dest)
Choose the source address to use with destination address.
void IpForward(Ptr< const NetDevice > idev, Ptr< Ipv6Route > rtentry, Ptr< const Packet > p, const Ipv6Header &header)
Forward a packet.
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:1192
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:71
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:220
void SetupLoopback()
Setup loopback interface.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:90
void SetSourceAddress(Ipv6Address src)
Set the "Source address" field.
Definition: ipv6-header.cc:96
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:47
uint16_t GetMetric() const
Get the metric.
void SetRoutingProtocol(Ptr< Ipv6RoutingProtocol > routingProtocol)
Set routing protocol for this stack.
Ipv6InterfaceAddress::Scope_e GetScope() const
Get address scope.
void SetHopLimit(uint8_t limit)
Set the "Hop limit" field (TTL).
Definition: ipv6-header.cc:86
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:121
virtual Ptr< IpL4Protocol > GetProtocol(int protocolNumber) const
Get L4 protocol by protocol number.
uint32_t GetId(void) const
Definition: node.cc:107
Ptr< Icmpv6L4Protocol > GetIcmpv6() const
Get ICMPv6 protocol.
static Mac64Address ConvertFrom(const Address &address)
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:843
void Insert(Ptr< IpL4Protocol > protocol)
Add an L4 protocol.
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:101
uint16_t GetMtu(uint32_t i) const
Get MTU for an interface.
bool m_sendIcmpv6Redirect
Allow ICMPv6 Redirect sending state.
virtual void RegisterOptions()
Register the IPv6 Options.
TracedCallback< const Ipv6Header &, Ptr< const Packet >, uint32_t > m_sendOutgoingTrace
Trace of sent packets.
Describes an IPv6 prefix.
Definition: ipv6-address.h:389
void SetDown(uint32_t i)
set an interface down.
Ptr< T > CreateObject(void)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:524
void SetTrafficClass(uint8_t traffic)
Set the "Traffic class" field.
Definition: ipv6-header.cc:46
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:368
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.
Container for a set of ns3::Object pointers.
Ptr< Ipv6PmtuCache > m_pmtuCache
Path MTU Cache.
static bool IsMatchingType(const Address &address)
virtual bool GetMtuDiscover(void) const
Get IPv6 MTU discover state.
TracedCallback< Ptr< const Packet >, Ptr< Ipv6 >, uint32_t > m_txTrace
Callback to trace TX (transmission) packets.
virtual void SetMtuDiscover(bool mtuDiscover)
Set IPv6 MTU discover state.
Ipv6Address CombinePrefix(Ipv6Prefix const &prefix)
Combine this address with a prefix.
uint8_t m_defaultTclass
Default TCLASS for outgoing packets.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:455
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:57
void StartPreferredTimer()
Start the preferred timer.
void SetDestinationAddress(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:106
TypeId SetParent(TypeId tid)
Definition: type-id.cc:638
void test(void)
Example use of ns3::SystemThread.
SocketList m_sockets
List of IPv6 raw sockets.
static const uint16_t PROT_NUMBER
The protocol number for IPv6 (0x86DD).
Ptr< Ipv6Interface > GetInterface(uint32_t i) const
Get an interface.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:111
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.
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.