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