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