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