A Discrete-Event Network Simulator
API
ipv6-l3-protocol.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007-2009 Strasbourg University
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
18  */
19 
20 #include "ipv6-l3-protocol.h"
21 
22 #include "icmpv6-l4-protocol.h"
24 #include "ipv6-extension-demux.h"
25 #include "ipv6-extension-header.h"
26 #include "ipv6-extension.h"
27 #include "ipv6-interface.h"
28 #include "ipv6-option-demux.h"
29 #include "ipv6-option.h"
31 #include "ipv6-raw-socket-impl.h"
32 #include "loopback-net-device.h"
33 #include "ndisc-cache.h"
34 
35 #include "ns3/boolean.h"
36 #include "ns3/callback.h"
37 #include "ns3/ipv6-route.h"
38 #include "ns3/ipv6-routing-protocol.h"
39 #include "ns3/log.h"
40 #include "ns3/mac16-address.h"
41 #include "ns3/mac64-address.h"
42 #include "ns3/node.h"
43 #include "ns3/object-vector.h"
44 #include "ns3/trace-source-accessor.h"
45 #include "ns3/traffic-control-layer.h"
46 #include "ns3/uinteger.h"
47 #include "ns3/vector.h"
48 
50 #define IPV6_MIN_MTU 1280
51 
52 namespace ns3
53 {
54 
55 NS_LOG_COMPONENT_DEFINE("Ipv6L3Protocol");
56 
57 NS_OBJECT_ENSURE_REGISTERED(Ipv6L3Protocol);
58 
59 const uint16_t Ipv6L3Protocol::PROT_NUMBER = 0x86DD;
60 
61 TypeId
63 {
64  static TypeId tid =
65  TypeId("ns3::Ipv6L3Protocol")
66  .SetParent<Ipv6>()
67  .SetGroupName("Internet")
68  .AddConstructor<Ipv6L3Protocol>()
69  .AddAttribute("DefaultTtl",
70  "The TTL value set by default on all "
71  "outgoing packets generated on this node.",
72  UintegerValue(64),
74  MakeUintegerChecker<uint8_t>())
75  .AddAttribute("DefaultTclass",
76  "The TCLASS value set by default on all "
77  "outgoing packets generated on this node.",
78  UintegerValue(0),
80  MakeUintegerChecker<uint8_t>())
81  .AddAttribute("InterfaceList",
82  "The set of IPv6 interfaces associated to this IPv6 stack.",
85  MakeObjectVectorChecker<Ipv6Interface>())
86  .AddAttribute("SendIcmpv6Redirect",
87  "Send the ICMPv6 Redirect when appropriate.",
88  BooleanValue(true),
92  .AddAttribute("StrongEndSystemModel",
93  "Reject packets for an address not configured on the interface they're "
94  "coming from (RFC1222).",
95  BooleanValue(true),
98  .AddTraceSource("Tx",
99  "Send IPv6 packet to outgoing interface.",
101  "ns3::Ipv6L3Protocol::TxRxTracedCallback")
102  .AddTraceSource("Rx",
103  "Receive IPv6 packet from incoming interface.",
105  "ns3::Ipv6L3Protocol::TxRxTracedCallback")
106  .AddTraceSource("Drop",
107  "Drop IPv6 packet",
109  "ns3::Ipv6L3Protocol::DropTracedCallback")
110 
111  .AddTraceSource("SendOutgoing",
112  "A newly-generated packet by this node is "
113  "about to be queued for transmission",
115  "ns3::Ipv6L3Protocol::SentTracedCallback")
116  .AddTraceSource("UnicastForward",
117  "A unicast IPv6 packet was received by this node "
118  "and is being forwarded to another node",
120  "ns3::Ipv6L3Protocol::SentTracedCallback")
121  .AddTraceSource("LocalDeliver",
122  "An IPv6 packet was received by/for this node, "
123  "and it is being forward up the stack",
125  "ns3::Ipv6L3Protocol::SentTracedCallback");
126  return tid;
127 }
128 
130  : m_nInterfaces(0)
131 {
132  NS_LOG_FUNCTION(this);
133  m_pmtuCache = CreateObject<Ipv6PmtuCache>();
134 
135  Ptr<Ipv6RawSocketFactoryImpl> rawFactoryImpl = CreateObject<Ipv6RawSocketFactoryImpl>();
136  AggregateObject(rawFactoryImpl);
137 }
138 
140 {
141  NS_LOG_FUNCTION(this);
142 }
143 
144 void
146 {
147  NS_LOG_FUNCTION(this);
148 
149  /* clear protocol and interface list */
150  for (L4List_t::iterator it = m_protocols.begin(); it != m_protocols.end(); ++it)
151  {
152  it->second = nullptr;
153  }
154  m_protocols.clear();
155 
156  /* remove interfaces */
157  for (Ipv6InterfaceList::iterator it = m_interfaces.begin(); it != m_interfaces.end(); ++it)
158  {
159  *it = nullptr;
160  }
161  m_interfaces.clear();
163 
164  /* remove raw sockets */
165  for (SocketList::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it)
166  {
167  *it = nullptr;
168  }
169  m_sockets.clear();
170 
171  /* remove list of prefix */
172  for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
173  {
174  (*it)->StopValidTimer();
175  (*it)->StopPreferredTimer();
176  (*it) = nullptr;
177  }
178  m_prefixes.clear();
179 
180  m_node = nullptr;
181  m_routingProtocol = nullptr;
182  m_pmtuCache = nullptr;
184 }
185 
186 void
188 {
189  NS_LOG_FUNCTION(this << routingProtocol);
190  m_routingProtocol = routingProtocol;
191  m_routingProtocol->SetIpv6(this);
192 }
193 
196 {
197  NS_LOG_FUNCTION(this);
198  return m_routingProtocol;
199 }
200 
201 uint32_t
203 {
204  NS_LOG_FUNCTION(this << device);
206 
208 
209  NS_ASSERT(tc);
210 
213  device);
214 
215  tc->RegisterProtocolHandler(MakeCallback(&Ipv6L3Protocol::Receive, this),
217  device);
218 
219  interface->SetNode(m_node);
220  interface->SetDevice(device);
221  interface->SetTrafficControl(tc);
222  interface->SetForwarding(m_ipForward);
223  return AddIpv6Interface(interface);
224 }
225 
226 uint32_t
228 {
229  NS_LOG_FUNCTION(this << interface);
230  uint32_t index = m_nInterfaces;
231 
232  m_interfaces.push_back(interface);
233  m_reverseInterfacesContainer[interface->GetDevice()] = index;
234  m_nInterfaces++;
235  return index;
236 }
237 
239 Ipv6L3Protocol::GetInterface(uint32_t index) const
240 {
241  NS_LOG_FUNCTION(this << index);
242 
243  if (index < m_interfaces.size())
244  {
245  return m_interfaces[index];
246  }
247  return nullptr;
248 }
249 
250 uint32_t
252 {
253  NS_LOG_FUNCTION(this);
254  return m_nInterfaces;
255 }
256 
257 int32_t
259 {
260  NS_LOG_FUNCTION(this << address);
261  int32_t index = 0;
262 
263  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin(); it != m_interfaces.end();
264  it++)
265  {
266  uint32_t j = 0;
267  uint32_t max = (*it)->GetNAddresses();
268 
269  for (j = 0; j < max; j++)
270  {
271  if ((*it)->GetAddress(j).GetAddress() == address)
272  {
273  return index;
274  }
275  }
276  index++;
277  }
278  return -1;
279 }
280 
281 int32_t
283 {
284  NS_LOG_FUNCTION(this << address << mask);
285  int32_t index = 0;
286 
287  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin(); it != m_interfaces.end();
288  it++)
289  {
290  uint32_t j = 0;
291  for (j = 0; j < (*it)->GetNAddresses(); j++)
292  {
293  if ((*it)->GetAddress(j).GetAddress().CombinePrefix(mask) ==
294  address.CombinePrefix(mask))
295  {
296  return index;
297  }
298  }
299  index++;
300  }
301  return -1;
302 }
303 
306 {
307  NS_LOG_FUNCTION(this << i);
308  return GetInterface(i)->GetDevice();
309 }
310 
311 int32_t
313 {
314  NS_LOG_FUNCTION(this << device);
315 
316  Ipv6InterfaceReverseContainer::const_iterator iter = m_reverseInterfacesContainer.find(device);
317  if (iter != m_reverseInterfacesContainer.end())
318  {
319  return (*iter).second;
320  }
321 
322  return -1;
323 }
324 
325 void
327  Ipv6Address network,
328  Ipv6Prefix mask,
329  uint8_t flags,
330  uint32_t validTime,
331  uint32_t preferredTime,
332  Ipv6Address defaultRouter)
333 {
334  NS_LOG_FUNCTION(this << interface << network << mask << (uint32_t)flags << validTime
335  << preferredTime);
337 
338  Address addr = GetInterface(interface)->GetDevice()->GetAddress();
339 
340  if (!defaultRouter.IsAny())
341  {
342  GetRoutingProtocol()->NotifyAddRoute(Ipv6Address::GetAny(),
343  Ipv6Prefix((uint8_t)0),
344  defaultRouter,
345  interface,
346  network);
347  }
348 
349  bool onLink = false;
351  {
352  onLink = true;
353  }
354 
355  if (flags & Icmpv6OptionPrefixInformation::AUTADDRCONF) /* auto flag */
356  {
358  address.SetOnLink(onLink);
359 
360  /* see if we have already the prefix */
361  for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
362  {
363  if ((*it)->GetInterface() == interface && (*it)->GetPrefix() == network &&
364  (*it)->GetMask() == mask)
365  {
366  (*it)->StopPreferredTimer();
367  (*it)->StopValidTimer();
368  (*it)->StartPreferredTimer();
369  return;
370  }
371  }
372 
373  /* no prefix found, add autoconfigured address and the prefix */
374  NS_LOG_INFO("Autoconfigured address is :" << address.GetAddress());
375  AddAddress(interface, address, onLink);
376 
378  CreateObject<Ipv6AutoconfiguredPrefix>(m_node,
379  interface,
380  network,
381  mask,
382  preferredTime,
383  validTime,
384  defaultRouter);
385  aPrefix->StartPreferredTimer();
386 
387  m_prefixes.push_back(aPrefix);
388  }
389 
390  if (onLink) /* on-link flag */
391  {
392  /* add default router
393  * if a previous default route exists, the new ones is simply added
394  */
395  m_routingProtocol->NotifyAddRoute(network, mask, Ipv6Address::GetAny(), interface);
396  }
397 }
398 
399 void
401  Ipv6Address network,
402  Ipv6Prefix mask,
403  Ipv6Address defaultRouter)
404 {
405  NS_LOG_FUNCTION(this << interface << network << mask);
406  Ptr<Ipv6Interface> iface = GetInterface(interface);
407  Address addr = iface->GetDevice()->GetAddress();
408 
409  Ipv6Address addressToFind = Ipv6Address::MakeAutoconfiguredAddress(addr, network);
410 
411  for (uint32_t i = 0; i < iface->GetNAddresses(); i++)
412  {
413  if (iface->GetAddress(i).GetAddress() == addressToFind)
414  {
415  RemoveAddress(interface, i);
416  break;
417  }
418  }
419 
420  /* remove from list of autoconfigured address */
421  for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
422  {
423  if ((*it)->GetInterface() == interface && (*it)->GetPrefix() == network &&
424  (*it)->GetMask() == mask)
425  {
426  *it = nullptr;
427  m_prefixes.erase(it);
428  break;
429  }
430  }
431 
432  GetRoutingProtocol()->NotifyRemoveRoute(Ipv6Address::GetAny(),
433  Ipv6Prefix((uint8_t)0),
434  defaultRouter,
435  interface,
436  network);
437 }
438 
439 bool
440 Ipv6L3Protocol::AddAddress(uint32_t i, Ipv6InterfaceAddress address, bool addOnLinkRoute)
441 {
442  NS_LOG_FUNCTION(this << i << address);
443  Ptr<Ipv6Interface> interface = GetInterface(i);
444  address.SetOnLink(addOnLinkRoute);
445  bool ret = interface->AddAddress(address);
446 
447  if (m_routingProtocol)
448  {
449  m_routingProtocol->NotifyAddAddress(i, address);
450  }
451 
452  if (addOnLinkRoute)
453  {
454  Ipv6Address networkAddress = address.GetAddress().CombinePrefix(address.GetPrefix());
455  Ipv6Prefix networkMask = address.GetPrefix();
456  GetRoutingProtocol()->NotifyAddRoute(networkAddress,
457  networkMask,
459  i);
460  }
461  return ret;
462 }
463 
464 uint32_t
466 {
467  NS_LOG_FUNCTION(this << i);
468  Ptr<Ipv6Interface> interface = GetInterface(i);
469  return interface->GetNAddresses();
470 }
471 
473 Ipv6L3Protocol::GetAddress(uint32_t i, uint32_t addressIndex) const
474 {
475  NS_LOG_FUNCTION(this << i << addressIndex);
476  Ptr<Ipv6Interface> interface = GetInterface(i);
477  return interface->GetAddress(addressIndex);
478 }
479 
480 bool
481 Ipv6L3Protocol::RemoveAddress(uint32_t i, uint32_t addressIndex)
482 {
483  NS_LOG_FUNCTION(this << i << addressIndex);
484  Ptr<Ipv6Interface> interface = GetInterface(i);
485  Ipv6InterfaceAddress address = interface->RemoveAddress(addressIndex);
486 
487  if (address != Ipv6InterfaceAddress())
488  {
489  if (m_routingProtocol)
490  {
491  m_routingProtocol->NotifyRemoveAddress(i, address);
492  }
493  return true;
494  }
495  return false;
496 }
497 
498 bool
500 {
501  NS_LOG_FUNCTION(this << i << address);
502 
504  {
505  NS_LOG_WARN("Cannot remove loopback address.");
506  return false;
507  }
508  Ptr<Ipv6Interface> interface = GetInterface(i);
509  Ipv6InterfaceAddress ifAddr = interface->RemoveAddress(address);
510  if (ifAddr != Ipv6InterfaceAddress())
511  {
512  if (m_routingProtocol)
513  {
514  m_routingProtocol->NotifyRemoveAddress(i, ifAddr);
515  }
516  return true;
517  }
518  return false;
519 }
520 
521 void
522 Ipv6L3Protocol::SetMetric(uint32_t i, uint16_t metric)
523 {
524  NS_LOG_FUNCTION(this << i << metric);
525  Ptr<Ipv6Interface> interface = GetInterface(i);
526  interface->SetMetric(metric);
527 }
528 
529 uint16_t
530 Ipv6L3Protocol::GetMetric(uint32_t i) const
531 {
532  NS_LOG_FUNCTION(this << i);
533  Ptr<Ipv6Interface> interface = GetInterface(i);
534  return interface->GetMetric();
535 }
536 
537 uint16_t
538 Ipv6L3Protocol::GetMtu(uint32_t i) const
539 {
540  NS_LOG_FUNCTION(this << i);
541 
542  // RFC 1981, if PMTU is disabled, return the minimum MTU
543  if (!m_mtuDiscover)
544  {
545  return IPV6_MIN_MTU;
546  }
547 
548  Ptr<Ipv6Interface> interface = GetInterface(i);
549  return interface->GetDevice()->GetMtu();
550 }
551 
552 void
554 {
555  NS_LOG_FUNCTION(this << dst << int(pmtu));
556  m_pmtuCache->SetPmtu(dst, pmtu);
557 }
558 
559 bool
560 Ipv6L3Protocol::IsUp(uint32_t i) const
561 {
562  NS_LOG_FUNCTION(this << i);
563  Ptr<Ipv6Interface> interface = GetInterface(i);
564  return interface->IsUp();
565 }
566 
567 void
569 {
570  NS_LOG_FUNCTION(this << i);
571  Ptr<Ipv6Interface> interface = GetInterface(i);
572 
573  // RFC 2460, Section 5, pg. 24:
574  // IPv6 requires that every link in the internet have an MTU of 1280
575  // octets or greater. On any link that cannot convey a 1280-octet
576  // packet in one piece, link-specific fragmentation and reassembly must
577  // be provided at a layer below IPv6.
578  if (interface->GetDevice()->GetMtu() >= 1280)
579  {
580  interface->SetUp();
581 
582  if (m_routingProtocol)
583  {
584  m_routingProtocol->NotifyInterfaceUp(i);
585  }
586  }
587  else
588  {
589  NS_LOG_LOGIC("Interface " << int(i)
590  << " is set to be down for IPv6. Reason: not respecting minimum "
591  "IPv6 MTU (1280 octets)");
592  }
593 }
594 
595 void
597 {
598  NS_LOG_FUNCTION(this << i);
599  Ptr<Ipv6Interface> interface = GetInterface(i);
600 
601  interface->SetDown();
602 
603  if (m_routingProtocol)
604  {
605  m_routingProtocol->NotifyInterfaceDown(i);
606  }
607 }
608 
609 void
611 {
612  NS_LOG_FUNCTION(this);
614  Ptr<LoopbackNetDevice> device = nullptr;
615  uint32_t i = 0;
616 
617  /* see if we have already an loopback NetDevice */
618  for (i = 0; i < m_node->GetNDevices(); i++)
619  {
620  if ((device = DynamicCast<LoopbackNetDevice>(m_node->GetDevice(i))))
621  {
622  break;
623  }
624  }
625 
626  if (!device)
627  {
628  device = CreateObject<LoopbackNetDevice>();
629  m_node->AddDevice(device);
630  }
631 
632  interface->SetDevice(device);
633  interface->SetNode(m_node);
634  Ipv6InterfaceAddress ifaceAddr =
636  interface->AddAddress(ifaceAddr);
637  uint32_t index = AddIpv6Interface(interface);
638  Ptr<Node> node = GetObject<Node>();
641  device);
642  interface->SetUp();
643 
644  if (m_routingProtocol)
645  {
646  m_routingProtocol->NotifyInterfaceUp(index);
647  }
648 }
649 
650 bool
652 {
653  NS_LOG_FUNCTION(this << i);
654  Ptr<Ipv6Interface> interface = GetInterface(i);
655 
656  NS_LOG_LOGIC("Forwarding state: " << interface->IsForwarding());
657  return interface->IsForwarding();
658 }
659 
660 void
661 Ipv6L3Protocol::SetForwarding(uint32_t i, bool val)
662 {
663  NS_LOG_FUNCTION(this << i << val);
664  Ptr<Ipv6Interface> interface = GetInterface(i);
665  interface->SetForwarding(val);
666 }
667 
670 {
671  NS_LOG_FUNCTION(this << interface << dest);
672  Ipv6Address ret;
673 
674  if (dest.IsLocalhost())
675  {
676  return Ipv6Address::GetLoopback();
677  }
678 
679  if (dest.IsLinkLocal() || dest.IsLinkLocalMulticast())
680  {
681  for (uint32_t i = 0; i < GetNAddresses(interface); i++)
682  {
683  Ipv6InterfaceAddress test = GetAddress(interface, i);
684  if (test.GetScope() == Ipv6InterfaceAddress::LINKLOCAL)
685  {
686  return test.GetAddress();
687  }
688  }
689  NS_ASSERT_MSG(false, "No link-local address found on interface " << interface);
690  }
691 
692  for (uint32_t i = 0; i < GetNAddresses(interface); i++)
693  {
694  Ipv6InterfaceAddress test = GetAddress(interface, i);
695 
696  if (test.GetScope() == Ipv6InterfaceAddress::GLOBAL)
697  {
698  if (test.IsInSameSubnet(dest))
699  {
700  return test.GetAddress();
701  }
702  else
703  {
704  ret = test.GetAddress();
705  }
706  }
707  }
708 
709  // no specific match found. Use a global address (any useful is fine).
710  NS_ASSERT_MSG(!ret.IsAny(),
711  "Could not find any address for " << dest << " on interface " << interface);
712  return ret;
713 }
714 
715 void
717 {
718  NS_LOG_FUNCTION(this << forward);
719  m_ipForward = forward;
720 
721  for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin(); it != m_interfaces.end();
722  it++)
723  {
724  (*it)->SetForwarding(forward);
725  }
726 }
727 
728 bool
730 {
731  NS_LOG_FUNCTION(this);
732  return m_ipForward;
733 }
734 
735 void
737 {
738  NS_LOG_FUNCTION(this << int(mtuDiscover));
739  m_mtuDiscover = mtuDiscover;
740 }
741 
742 bool
744 {
745  NS_LOG_FUNCTION(this);
746  return m_mtuDiscover;
747 }
748 
749 void
751 {
752  NS_LOG_FUNCTION(this << sendIcmpv6Redirect);
753  m_sendIcmpv6Redirect = sendIcmpv6Redirect;
754 }
755 
756 bool
758 {
759  NS_LOG_FUNCTION(this);
760  return m_sendIcmpv6Redirect;
761 }
762 
763 void
765 {
766  NS_LOG_FUNCTION(this);
767 
768  if (!m_node)
769  {
770  Ptr<Node> node = this->GetObject<Node>();
771  // verify that it's a valid node and that
772  // the node has not been set before
773  if (node)
774  {
775  this->SetNode(node);
776  }
777  }
778 
780 }
781 
782 void
784 {
785  NS_LOG_FUNCTION(this << node);
786  m_node = node;
787  /* add LoopbackNetDevice if needed, and an Ipv6Interface on top of it */
788  SetupLoopback();
789 }
790 
791 void
793 {
794  NS_LOG_FUNCTION(this << protocol);
795  L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), -1);
796  if (m_protocols.find(key) != m_protocols.end())
797  {
798  NS_LOG_WARN("Overwriting default protocol " << int(protocol->GetProtocolNumber()));
799  }
800  m_protocols[key] = protocol;
801 }
802 
803 void
804 Ipv6L3Protocol::Insert(Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
805 {
806  NS_LOG_FUNCTION(this << protocol << interfaceIndex);
807 
808  L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), interfaceIndex);
809  if (m_protocols.find(key) != m_protocols.end())
810  {
811  NS_LOG_WARN("Overwriting protocol " << int(protocol->GetProtocolNumber())
812  << " on interface " << int(interfaceIndex));
813  }
814  m_protocols[key] = protocol;
815 }
816 
817 void
819 {
820  NS_LOG_FUNCTION(this << protocol);
821 
822  L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), -1);
823  L4List_t::iterator iter = m_protocols.find(key);
824  if (iter == m_protocols.end())
825  {
826  NS_LOG_WARN("Trying to remove an non-existent default protocol "
827  << int(protocol->GetProtocolNumber()));
828  }
829  else
830  {
831  m_protocols.erase(key);
832  }
833 }
834 
835 void
836 Ipv6L3Protocol::Remove(Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
837 {
838  NS_LOG_FUNCTION(this << protocol << interfaceIndex);
839 
840  L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), interfaceIndex);
841  L4List_t::iterator iter = m_protocols.find(key);
842  if (iter == m_protocols.end())
843  {
844  NS_LOG_WARN("Trying to remove an non-existent protocol "
845  << int(protocol->GetProtocolNumber()) << " on interface "
846  << int(interfaceIndex));
847  }
848  else
849  {
850  m_protocols.erase(key);
851  }
852 }
853 
855 Ipv6L3Protocol::GetProtocol(int protocolNumber) const
856 {
857  NS_LOG_FUNCTION(this << protocolNumber);
858 
859  return GetProtocol(protocolNumber, -1);
860 }
861 
863 Ipv6L3Protocol::GetProtocol(int protocolNumber, int32_t interfaceIndex) const
864 {
865  NS_LOG_FUNCTION(this << protocolNumber << interfaceIndex);
866 
867  L4ListKey_t key;
868  L4List_t::const_iterator i;
869  if (interfaceIndex >= 0)
870  {
871  // try the interface-specific protocol.
872  key = std::make_pair(protocolNumber, interfaceIndex);
873  i = m_protocols.find(key);
874  if (i != m_protocols.end())
875  {
876  return i->second;
877  }
878  }
879  // try the generic protocol.
880  key = std::make_pair(protocolNumber, -1);
881  i = m_protocols.find(key);
882  if (i != m_protocols.end())
883  {
884  return i->second;
885  }
886 
887  return nullptr;
888 }
889 
892 {
893  NS_LOG_FUNCTION(this);
894  Ptr<Ipv6RawSocketImpl> sock = CreateObject<Ipv6RawSocketImpl>();
895  sock->SetNode(m_node);
896  m_sockets.push_back(sock);
897  return sock;
898 }
899 
900 void
902 {
903  NS_LOG_FUNCTION(this << socket);
904 
905  for (SocketList::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it)
906  {
907  if ((*it) == socket)
908  {
909  m_sockets.erase(it);
910  return;
911  }
912  }
913 }
914 
917 {
918  NS_LOG_FUNCTION(this);
920 
921  if (protocol)
922  {
923  return protocol->GetObject<Icmpv6L4Protocol>();
924  }
925  else
926  {
927  return nullptr;
928  }
929 }
930 
931 void
933 {
934  NS_LOG_FUNCTION(this << ttl);
935  m_defaultTtl = ttl;
936 }
937 
938 void
940 {
941  NS_LOG_FUNCTION(this << tclass);
942  m_defaultTclass = tclass;
943 }
944 
945 void
947  Ipv6Address source,
948  Ipv6Address destination,
949  uint8_t protocol,
950  Ptr<Ipv6Route> route)
951 {
952  NS_LOG_FUNCTION(this << packet << source << destination << (uint32_t)protocol << route);
953  Ipv6Header hdr;
954  uint8_t ttl = m_defaultTtl;
956  bool found = packet->RemovePacketTag(tag);
957 
958  if (found)
959  {
960  ttl = tag.GetHopLimit();
961  }
962 
963  SocketIpv6TclassTag tclassTag;
964  uint8_t tclass = m_defaultTclass;
965  found = packet->RemovePacketTag(tclassTag);
966 
967  if (found)
968  {
969  tclass = tclassTag.GetTclass();
970  }
971 
972  /* Handle 3 cases:
973  * 1) Packet is passed in with a route entry
974  * 2) Packet is passed in with a route entry but route->GetGateway is not set (e.g., same
975  * network) 3) route is NULL (e.g., a raw socket call or ICMPv6)
976  */
977 
978  /* 1) */
979  if (route && route->GetGateway() != Ipv6Address::GetZero())
980  {
981  NS_LOG_LOGIC("Ipv6L3Protocol::Send case 1: passed in with a route");
982  hdr = BuildHeader(source, destination, protocol, packet->GetSize(), ttl, tclass);
983  int32_t interface = GetInterfaceForDevice(route->GetOutputDevice());
984  m_sendOutgoingTrace(hdr, packet, interface);
985  SendRealOut(route, packet, hdr);
986  return;
987  }
988 
989  /* 2) */
990  if (route && route->GetGateway() == Ipv6Address::GetZero())
991  {
992  NS_LOG_LOGIC("Ipv6L3Protocol::Send case 2: probably sent to machine on same IPv6 network");
993  hdr = BuildHeader(source, destination, protocol, packet->GetSize(), ttl, tclass);
994  int32_t interface = GetInterfaceForDevice(route->GetOutputDevice());
995  m_sendOutgoingTrace(hdr, packet, interface);
996  SendRealOut(route, packet, hdr);
997  return;
998  }
999 
1000  /* 3) */
1001  NS_LOG_LOGIC("Ipv6L3Protocol::Send case 3: passed in with no route " << destination);
1002  Socket::SocketErrno err;
1003  Ptr<NetDevice> oif(nullptr);
1004  Ptr<Ipv6Route> newRoute = nullptr;
1005 
1006  hdr = BuildHeader(source, destination, protocol, packet->GetSize(), ttl, tclass);
1007 
1008  // for link-local traffic, we need to determine the interface
1009  if (source.IsLinkLocal() || destination.IsLinkLocal() || destination.IsLinkLocalMulticast())
1010  {
1011  int32_t index = GetInterfaceForAddress(source);
1012  NS_ASSERT_MSG(index >= 0,
1013  "Can not find an outgoing interface for a packet with src "
1014  << source << " and dst " << destination);
1015  oif = GetNetDevice(index);
1016  }
1017 
1018  newRoute = m_routingProtocol->RouteOutput(packet, hdr, oif, err);
1019 
1020  if (newRoute)
1021  {
1022  int32_t interface = GetInterfaceForDevice(newRoute->GetOutputDevice());
1023  m_sendOutgoingTrace(hdr, packet, interface);
1024  SendRealOut(newRoute, packet, hdr);
1025  }
1026  else
1027  {
1028  NS_LOG_WARN("No route to host, drop!");
1029  m_dropTrace(hdr, packet, DROP_NO_ROUTE, this, GetInterfaceForDevice(oif));
1030  }
1031 }
1032 
1033 void
1036  uint16_t protocol,
1037  const Address& from,
1038  const Address& to,
1039  NetDevice::PacketType packetType)
1040 {
1041  NS_LOG_FUNCTION(this << device << p << protocol << from << to << packetType);
1042  NS_LOG_LOGIC("Packet from " << from << " received on node " << m_node->GetId());
1043 
1044  NS_ASSERT_MSG(GetInterfaceForDevice(device) != -1,
1045  "Received a packet from an interface that is not known to IPv6");
1046  uint32_t interface = GetInterfaceForDevice(device);
1047 
1048  Ptr<Ipv6Interface> ipv6Interface = m_interfaces[interface];
1049  Ptr<Packet> packet = p->Copy();
1050 
1051  if (ipv6Interface->IsUp())
1052  {
1053  m_rxTrace(packet, this, interface);
1054  }
1055  else
1056  {
1057  NS_LOG_LOGIC("Dropping received packet-- interface is down");
1058  Ipv6Header hdr;
1059  packet->RemoveHeader(hdr);
1060  m_dropTrace(hdr, packet, DROP_INTERFACE_DOWN, this, interface);
1061  return;
1062  }
1063 
1064  Ipv6Header hdr;
1065  packet->RemoveHeader(hdr);
1066 
1067  // Trim any residual frame padding from underlying devices
1068  if (hdr.GetPayloadLength() < packet->GetSize())
1069  {
1070  packet->RemoveAtEnd(packet->GetSize() - hdr.GetPayloadLength());
1071  }
1072 
1073  // the packet is valid, we update the NDISC cache entry (if present)
1074  Ptr<NdiscCache> ndiscCache = ipv6Interface->GetNdiscCache();
1075  if (ndiscCache)
1076  {
1077  // case one, it's a a direct routing.
1078  NdiscCache::Entry* entry = ndiscCache->Lookup(hdr.GetSource());
1079  if (entry)
1080  {
1081  entry->UpdateReachableTimer();
1082  }
1083  else
1084  {
1085  // It's not in the direct routing, so it's the router, and it could have multiple IP
1086  // addresses. In doubt, update all of them. Note: it's a confirmed behavior for Linux
1087  // routers.
1088  std::list<NdiscCache::Entry*> entryList = ndiscCache->LookupInverse(from);
1089  std::list<NdiscCache::Entry*>::iterator iter;
1090  for (iter = entryList.begin(); iter != entryList.end(); iter++)
1091  {
1092  (*iter)->UpdateReachableTimer();
1093  }
1094  }
1095  }
1096 
1097  /* forward up to IPv6 raw sockets */
1098  for (SocketList::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it)
1099  {
1100  Ptr<Ipv6RawSocketImpl> socket = *it;
1101  socket->ForwardUp(packet, hdr, device);
1102  }
1103 
1105  Ptr<Ipv6Extension> ipv6Extension = nullptr;
1106  uint8_t nextHeader = hdr.GetNextHeader();
1107  bool stopProcessing = false;
1108  bool isDropped = false;
1109  DropReason dropReason;
1110 
1111  if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1112  {
1113  ipv6Extension = ipv6ExtensionDemux->GetExtension(nextHeader);
1114 
1115  if (ipv6Extension)
1116  {
1117  ipv6Extension->Process(packet,
1118  0,
1119  hdr,
1120  hdr.GetDestination(),
1121  (uint8_t*)nullptr,
1122  stopProcessing,
1123  isDropped,
1124  dropReason);
1125  }
1126 
1127  if (isDropped)
1128  {
1129  m_dropTrace(hdr, packet, dropReason, this, interface);
1130  }
1131 
1132  if (stopProcessing)
1133  {
1134  return;
1135  }
1136  }
1137 
1138  if (hdr.GetDestination().IsAllNodesMulticast())
1139  {
1140  LocalDeliver(packet, hdr, interface);
1141  return;
1142  }
1143  else if (hdr.GetDestination().IsAllRoutersMulticast() && ipv6Interface->IsForwarding())
1144  {
1145  LocalDeliver(packet, hdr, interface);
1146  return;
1147  }
1148  else if (hdr.GetDestination().IsMulticast())
1149  {
1150  bool isSolicited = ipv6Interface->IsSolicitedMulticastAddress(hdr.GetDestination());
1151  bool isRegisteredOnInterface =
1152  IsRegisteredMulticastAddress(hdr.GetDestination(), interface);
1153  bool isRegisteredGlobally = IsRegisteredMulticastAddress(hdr.GetDestination());
1154  if (isSolicited || isRegisteredGlobally || isRegisteredOnInterface)
1155  {
1156  LocalDeliver(packet, hdr, interface);
1157  // do not return, the packet could be handled by a routing protocol
1158  }
1159  }
1160 
1161  for (uint32_t j = 0; j < GetNInterfaces(); j++)
1162  {
1163  if (j == interface || !m_strongEndSystemModel)
1164  {
1165  for (uint32_t i = 0; i < GetNAddresses(j); i++)
1166  {
1167  Ipv6InterfaceAddress iaddr = GetAddress(j, i);
1168  Ipv6Address addr = iaddr.GetAddress();
1169  if (addr == hdr.GetDestination())
1170  {
1171  if (j == interface)
1172  {
1173  NS_LOG_LOGIC("For me (destination " << addr << " match)");
1174  }
1175  else
1176  {
1177  NS_LOG_LOGIC("For me (destination " << addr
1178  << " match) on another interface "
1179  << hdr.GetDestination());
1180  }
1181  LocalDeliver(packet, hdr, interface);
1182  return;
1183  }
1184  NS_LOG_LOGIC("Address " << addr << " not a match");
1185  }
1186  }
1187  }
1188 
1189  if (!m_routingProtocol->RouteInput(packet,
1190  hdr,
1191  device,
1196  {
1197  NS_LOG_WARN("No route found for forwarding packet. Drop.");
1198  // Drop trace and ICMPs are courtesy of RouteInputError
1199  }
1200 }
1201 
1202 void
1204  Ptr<Packet> packet,
1205  Ptr<Ipv6> ipv6,
1206  uint32_t interface)
1207 {
1208  if (!m_txTrace.IsEmpty())
1209  {
1210  Ptr<Packet> packetCopy = packet->Copy();
1211  packetCopy->AddHeader(ipHeader);
1212  m_txTrace(packetCopy, ipv6, interface);
1213  }
1214 }
1215 
1216 void
1218 {
1219  NS_LOG_FUNCTION(this << route << packet << ipHeader);
1220 
1221  if (!route)
1222  {
1223  NS_LOG_LOGIC("No route to host, drop!.");
1224  return;
1225  }
1226 
1227  Ptr<NetDevice> dev = route->GetOutputDevice();
1228  int32_t interface = GetInterfaceForDevice(dev);
1229  NS_ASSERT(interface >= 0);
1230 
1231  Ptr<Ipv6Interface> outInterface = GetInterface(interface);
1232  NS_LOG_LOGIC("Send via NetDevice ifIndex " << dev->GetIfIndex() << " Ipv6InterfaceIndex "
1233  << interface);
1234 
1235  // Check packet size
1236  std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair> fragments;
1237 
1238  // Check if this is the source of the packet
1239  bool fromMe = false;
1240  for (uint32_t i = 0; i < GetNInterfaces(); i++)
1241  {
1242  for (uint32_t j = 0; j < GetNAddresses(i); j++)
1243  {
1244  if (GetAddress(i, j).GetAddress() == ipHeader.GetSource())
1245  {
1246  fromMe = true;
1247  break;
1248  }
1249  }
1250  }
1251 
1252  size_t targetMtu = 0;
1253 
1254  // Check if we have a Path MTU stored. If so, use it. Else, use the link MTU.
1255  // Note: PMTU must not be cached in intermediate nodes, and must be checked only by the source
1256  // node
1257  if (fromMe)
1258  {
1259  targetMtu = (size_t)(m_pmtuCache->GetPmtu(ipHeader.GetDestination()));
1260  }
1261  if (targetMtu == 0)
1262  {
1263  targetMtu = dev->GetMtu();
1264  }
1265 
1266  if (packet->GetSize() + ipHeader.GetSerializedSize() > targetMtu)
1267  {
1268  // Router => drop
1269  if (!fromMe)
1270  {
1271  Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6();
1272  if (icmpv6)
1273  {
1274  packet->AddHeader(ipHeader);
1275  icmpv6->SendErrorTooBig(packet, ipHeader.GetSource(), dev->GetMtu());
1276  }
1277  return;
1278  }
1279 
1281 
1282  // To get specific method GetFragments from Ipv6ExtensionFragmentation
1283  Ipv6ExtensionFragment* ipv6Fragment = dynamic_cast<Ipv6ExtensionFragment*>(
1284  PeekPointer(ipv6ExtensionDemux->GetExtension(Ipv6Header::IPV6_EXT_FRAGMENTATION)));
1285  NS_ASSERT(ipv6Fragment != nullptr);
1286  ipv6Fragment->GetFragments(packet, ipHeader, targetMtu, fragments);
1287  }
1288 
1289  if (route->GetGateway() != Ipv6Address::GetAny())
1290  {
1291  if (outInterface->IsUp())
1292  {
1293  NS_LOG_LOGIC("Send to gateway " << route->GetGateway());
1294 
1295  if (!fragments.empty())
1296  {
1297  std::ostringstream oss;
1298 
1299  for (std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair>::const_iterator it =
1300  fragments.begin();
1301  it != fragments.end();
1302  it++)
1303  {
1304  CallTxTrace(it->second, it->first, this, interface);
1305  outInterface->Send(it->first, it->second, route->GetGateway());
1306  }
1307  }
1308  else
1309  {
1310  CallTxTrace(ipHeader, packet, this, interface);
1311  outInterface->Send(packet, ipHeader, route->GetGateway());
1312  }
1313  }
1314  else
1315  {
1316  NS_LOG_LOGIC("Dropping-- outgoing interface is down: " << route->GetGateway());
1317  m_dropTrace(ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
1318  }
1319  }
1320  else
1321  {
1322  if (outInterface->IsUp())
1323  {
1324  NS_LOG_LOGIC("Send to destination " << ipHeader.GetDestination());
1325 
1326  if (!fragments.empty())
1327  {
1328  std::ostringstream oss;
1329 
1330  for (std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair>::const_iterator it =
1331  fragments.begin();
1332  it != fragments.end();
1333  it++)
1334  {
1335  CallTxTrace(it->second, it->first, this, interface);
1336  outInterface->Send(it->first, it->second, ipHeader.GetDestination());
1337  }
1338  }
1339  else
1340  {
1341  CallTxTrace(ipHeader, packet, this, interface);
1342  outInterface->Send(packet, ipHeader, ipHeader.GetDestination());
1343  }
1344  }
1345  else
1346  {
1347  NS_LOG_LOGIC("Dropping-- outgoing interface is down: " << ipHeader.GetDestination());
1348  m_dropTrace(ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
1349  }
1350  }
1351 }
1352 
1353 void
1355  Ptr<Ipv6Route> rtentry,
1357  const Ipv6Header& header)
1358 {
1359  NS_LOG_FUNCTION(this << rtentry << p << header);
1360  NS_LOG_LOGIC("Forwarding logic for node: " << m_node->GetId());
1361 
1362  // Drop RFC 3849 packets: 2001:db8::/32
1363  if (header.GetDestination().IsDocumentation())
1364  {
1365  NS_LOG_WARN("Received a packet for 2001:db8::/32 (documentation class). Drop.");
1366  m_dropTrace(header, p, DROP_ROUTE_ERROR, this, 0);
1367  return;
1368  }
1369 
1370  // Forwarding
1371  Ipv6Header ipHeader = header;
1372  Ptr<Packet> packet = p->Copy();
1373  ipHeader.SetHopLimit(ipHeader.GetHopLimit() - 1);
1374 
1375  if (ipHeader.GetSource().IsLinkLocal())
1376  {
1377  /* no forward for link-local address */
1378  return;
1379  }
1380 
1381  if (ipHeader.GetHopLimit() == 0)
1382  {
1383  NS_LOG_WARN("TTL exceeded. Drop.");
1384  m_dropTrace(ipHeader, packet, DROP_TTL_EXPIRED, this, 0);
1385  // Do not reply to multicast IPv6 address
1386  if (ipHeader.GetDestination().IsMulticast() == false)
1387  {
1388  packet->AddHeader(ipHeader);
1389  GetIcmpv6()->SendErrorTimeExceeded(packet,
1390  ipHeader.GetSource(),
1392  }
1393  return;
1394  }
1395 
1396  /* ICMPv6 Redirect */
1397 
1398  /* if we forward to a machine on the same network as the source,
1399  * we send him an ICMPv6 redirect message to notify him that a short route
1400  * exists.
1401  */
1402 
1403  /* Theoretically we should also check if the redirect target is on the same network
1404  * as the source node. On the other hand, we are sure that the router we're redirecting to
1405  * used a link-local address. As a consequence, they MUST be on the same network, the link-local
1406  * net.
1407  */
1408 
1409  if (m_sendIcmpv6Redirect && (rtentry->GetOutputDevice() == idev))
1410  {
1411  NS_LOG_LOGIC("ICMPv6 redirect!");
1412  Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6();
1413  Address hardwareTarget;
1414  Ipv6Address dst = header.GetDestination();
1415  Ipv6Address src = header.GetSource();
1416  Ipv6Address target = rtentry->GetGateway();
1417  Ptr<Packet> copy = p->Copy();
1418 
1419  if (target.IsAny())
1420  {
1421  target = dst;
1422  }
1423 
1424  copy->AddHeader(header);
1425  Ipv6Address linkLocal = GetInterface(GetInterfaceForDevice(rtentry->GetOutputDevice()))
1427  .GetAddress();
1428 
1429  if (icmpv6->Lookup(target, rtentry->GetOutputDevice(), nullptr, &hardwareTarget))
1430  {
1431  icmpv6->SendRedirection(copy, linkLocal, src, target, dst, hardwareTarget);
1432  }
1433  else
1434  {
1435  icmpv6->SendRedirection(copy, linkLocal, src, target, dst, Address());
1436  }
1437  }
1438  // in case the packet still has a priority tag attached, remove it
1439  SocketPriorityTag priorityTag;
1440  packet->RemovePacketTag(priorityTag);
1441  int32_t interface = GetInterfaceForDevice(rtentry->GetOutputDevice());
1442  m_unicastForwardTrace(ipHeader, packet, interface);
1443  SendRealOut(rtentry, packet, ipHeader);
1444 }
1445 
1446 void
1448  Ptr<Ipv6MulticastRoute> mrtentry,
1450  const Ipv6Header& header)
1451 {
1452  NS_LOG_FUNCTION(this << mrtentry << p << header);
1453  NS_LOG_LOGIC("Multicast forwarding logic for node: " << m_node->GetId());
1454 
1455  std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap();
1456  std::map<uint32_t, uint32_t>::iterator mapIter;
1457 
1458  for (mapIter = ttlMap.begin(); mapIter != ttlMap.end(); mapIter++)
1459  {
1460  uint32_t interfaceId = mapIter->first;
1461  // uint32_t outputTtl = mapIter->second; // Unused for now
1462  Ptr<Packet> packet = p->Copy();
1463  Ipv6Header h = header;
1464  h.SetHopLimit(header.GetHopLimit() - 1);
1465  if (h.GetHopLimit() == 0)
1466  {
1467  NS_LOG_WARN("TTL exceeded. Drop.");
1468  m_dropTrace(header, packet, DROP_TTL_EXPIRED, this, interfaceId);
1469  return;
1470  }
1471  NS_LOG_LOGIC("Forward multicast via interface " << interfaceId);
1472  Ptr<Ipv6Route> rtentry = Create<Ipv6Route>();
1473  rtentry->SetSource(h.GetSource());
1474  rtentry->SetDestination(h.GetDestination());
1475  rtentry->SetGateway(Ipv6Address::GetAny());
1476  rtentry->SetOutputDevice(GetNetDevice(interfaceId));
1477  SendRealOut(rtentry, packet, h);
1478  }
1479 }
1480 
1481 void
1483 {
1484  NS_LOG_FUNCTION(this << packet << ip << iif);
1485  Ptr<Packet> p = packet->Copy();
1486  Ptr<IpL4Protocol> protocol = nullptr;
1488  Ptr<Ipv6Extension> ipv6Extension = nullptr;
1489  Ipv6Address src = ip.GetSource();
1490  Ipv6Address dst = ip.GetDestination();
1491  uint8_t nextHeader = ip.GetNextHeader();
1492  uint8_t nextHeaderPosition = 0;
1493  bool isDropped = false;
1494  bool stopProcessing = false;
1495  DropReason dropReason;
1496 
1497  // check for a malformed hop-by-hop extension
1498  // this is a common case when forging IPv6 raw packets
1499  if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1500  {
1501  uint8_t buf;
1502  p->CopyData(&buf, 1);
1504  {
1505  NS_LOG_WARN("Double Ipv6Header::IPV6_EXT_HOP_BY_HOP in packet, dropping packet");
1506  return;
1507  }
1508  }
1509 
1510  /* process all the extensions found and the layer 4 protocol */
1511  do
1512  {
1513  /* it return 0 for non-extension (i.e. layer 4 protocol) */
1514  ipv6Extension = ipv6ExtensionDemux->GetExtension(nextHeader);
1515 
1516  if (ipv6Extension)
1517  {
1518  uint8_t nextHeaderStep = 0;
1519  uint8_t curHeader = nextHeader;
1520  nextHeaderStep = ipv6Extension->Process(p,
1521  nextHeaderPosition,
1522  ip,
1523  dst,
1524  &nextHeader,
1525  stopProcessing,
1526  isDropped,
1527  dropReason);
1528  nextHeaderPosition += nextHeaderStep;
1529 
1530  if (isDropped)
1531  {
1532  m_dropTrace(ip, packet, dropReason, this, iif);
1533  }
1534 
1535  if (stopProcessing)
1536  {
1537  return;
1538  }
1539  NS_ASSERT_MSG(nextHeaderStep != 0 || curHeader == Ipv6Header::IPV6_EXT_FRAGMENTATION,
1540  "Zero-size IPv6 Option Header, aborting" << *packet);
1541  }
1542  else
1543  {
1544  protocol = GetProtocol(nextHeader, iif);
1545 
1546  if (!protocol)
1547  {
1548  NS_LOG_LOGIC("Unknown Next Header. Drop!");
1549 
1550  // For ICMPv6 Error packets
1551  Ptr<Packet> malformedPacket = packet->Copy();
1552  malformedPacket->AddHeader(ip);
1553 
1554  if (nextHeaderPosition == 0)
1555  {
1556  GetIcmpv6()->SendErrorParameterError(malformedPacket,
1557  dst,
1559  40);
1560  }
1561  else
1562  {
1563  GetIcmpv6()->SendErrorParameterError(malformedPacket,
1564  dst,
1566  ip.GetSerializedSize() +
1567  nextHeaderPosition);
1568  }
1569  m_dropTrace(ip, p, DROP_UNKNOWN_PROTOCOL, this, iif);
1570  break;
1571  }
1572  else
1573  {
1574  p->RemoveAtStart(nextHeaderPosition);
1575  /* protocol->Receive (p, src, dst, incomingInterface); */
1576 
1577  /* L4 protocol */
1578  Ptr<Packet> copy = p->Copy();
1579 
1580  m_localDeliverTrace(ip, p, iif);
1581 
1582  enum IpL4Protocol::RxStatus status = protocol->Receive(p, ip, GetInterface(iif));
1583 
1584  switch (status)
1585  {
1586  case IpL4Protocol::RX_OK:
1587  break;
1589  break;
1591  break;
1593  if (ip.GetDestination().IsMulticast())
1594  {
1595  /* do not rely on multicast address */
1596  break;
1597  }
1598 
1599  copy->AddHeader(ip);
1600  GetIcmpv6()->SendErrorDestinationUnreachable(
1601  copy,
1602  ip.GetSource(),
1604  }
1605  }
1606  }
1607  } while (ipv6Extension);
1608 }
1609 
1610 void
1612  const Ipv6Header& ipHeader,
1613  Socket::SocketErrno sockErrno)
1614 {
1615  NS_LOG_FUNCTION(this << p << ipHeader << sockErrno);
1616  NS_LOG_LOGIC("Route input failure-- dropping packet to " << ipHeader << " with errno "
1617  << sockErrno);
1618 
1619  m_dropTrace(ipHeader, p, DROP_ROUTE_ERROR, this, 0);
1620 
1621  if (!ipHeader.GetDestination().IsMulticast())
1622  {
1623  Ptr<Packet> packet = p->Copy();
1624  packet->AddHeader(ipHeader);
1625  GetIcmpv6()->SendErrorDestinationUnreachable(packet,
1626  ipHeader.GetSource(),
1628  }
1629 }
1630 
1631 Ipv6Header
1633  Ipv6Address dst,
1634  uint8_t protocol,
1635  uint16_t payloadSize,
1636  uint8_t ttl,
1637  uint8_t tclass)
1638 {
1639  NS_LOG_FUNCTION(this << src << dst << (uint32_t)protocol << (uint32_t)payloadSize
1640  << (uint32_t)ttl << (uint32_t)tclass);
1641  Ipv6Header hdr;
1642 
1643  hdr.SetSource(src);
1644  hdr.SetDestination(dst);
1645  hdr.SetNextHeader(protocol);
1646  hdr.SetPayloadLength(payloadSize);
1647  hdr.SetHopLimit(ttl);
1648  hdr.SetTrafficClass(tclass);
1649  return hdr;
1650 }
1651 
1652 void
1654 {
1655  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = CreateObject<Ipv6ExtensionDemux>();
1656  ipv6ExtensionDemux->SetNode(m_node);
1657 
1658  Ptr<Ipv6ExtensionHopByHop> hopbyhopExtension = CreateObject<Ipv6ExtensionHopByHop>();
1659  hopbyhopExtension->SetNode(m_node);
1660  Ptr<Ipv6ExtensionDestination> destinationExtension = CreateObject<Ipv6ExtensionDestination>();
1661  destinationExtension->SetNode(m_node);
1662  Ptr<Ipv6ExtensionFragment> fragmentExtension = CreateObject<Ipv6ExtensionFragment>();
1663  fragmentExtension->SetNode(m_node);
1664  Ptr<Ipv6ExtensionRouting> routingExtension = CreateObject<Ipv6ExtensionRouting>();
1665  routingExtension->SetNode(m_node);
1666  // Ptr<Ipv6ExtensionESP> espExtension = CreateObject<Ipv6ExtensionESP> ();
1667  // Ptr<Ipv6ExtensionAH> ahExtension = CreateObject<Ipv6ExtensionAH> ();
1668 
1669  ipv6ExtensionDemux->Insert(hopbyhopExtension);
1670  ipv6ExtensionDemux->Insert(destinationExtension);
1671  ipv6ExtensionDemux->Insert(fragmentExtension);
1672  ipv6ExtensionDemux->Insert(routingExtension);
1673  // ipv6ExtensionDemux->Insert (espExtension);
1674  // ipv6ExtensionDemux->Insert (ahExtension);
1675 
1676  Ptr<Ipv6ExtensionRoutingDemux> routingExtensionDemux =
1677  CreateObject<Ipv6ExtensionRoutingDemux>();
1678  routingExtensionDemux->SetNode(m_node);
1679  Ptr<Ipv6ExtensionLooseRouting> looseRoutingExtension =
1680  CreateObject<Ipv6ExtensionLooseRouting>();
1681  looseRoutingExtension->SetNode(m_node);
1682  routingExtensionDemux->Insert(looseRoutingExtension);
1683 
1684  m_node->AggregateObject(routingExtensionDemux);
1685  m_node->AggregateObject(ipv6ExtensionDemux);
1686 }
1687 
1688 void
1690 {
1691  Ptr<Ipv6OptionDemux> ipv6OptionDemux = CreateObject<Ipv6OptionDemux>();
1692  ipv6OptionDemux->SetNode(m_node);
1693 
1694  Ptr<Ipv6OptionPad1> pad1Option = CreateObject<Ipv6OptionPad1>();
1695  pad1Option->SetNode(m_node);
1696  Ptr<Ipv6OptionPadn> padnOption = CreateObject<Ipv6OptionPadn>();
1697  padnOption->SetNode(m_node);
1698  Ptr<Ipv6OptionJumbogram> jumbogramOption = CreateObject<Ipv6OptionJumbogram>();
1699  jumbogramOption->SetNode(m_node);
1700  Ptr<Ipv6OptionRouterAlert> routerAlertOption = CreateObject<Ipv6OptionRouterAlert>();
1701  routerAlertOption->SetNode(m_node);
1702 
1703  ipv6OptionDemux->Insert(pad1Option);
1704  ipv6OptionDemux->Insert(padnOption);
1705  ipv6OptionDemux->Insert(jumbogramOption);
1706  ipv6OptionDemux->Insert(routerAlertOption);
1707 
1708  m_node->AggregateObject(ipv6OptionDemux);
1709 }
1710 
1711 void
1713 {
1714  m_dropTrace(ipHeader, p, dropReason, this, 0);
1715 }
1716 
1717 void
1719 {
1720  NS_LOG_FUNCTION(address << interface);
1721 
1722  if (!address.IsMulticast())
1723  {
1724  NS_LOG_WARN("Not adding a non-multicast address " << address);
1725  return;
1726  }
1727 
1728  Ipv6RegisteredMulticastAddressKey_t key = std::make_pair(address, interface);
1729  m_multicastAddresses[key]++;
1730 }
1731 
1732 void
1734 {
1736 
1737  if (!address.IsMulticast())
1738  {
1739  NS_LOG_WARN("Not adding a non-multicast address " << address);
1740  return;
1741  }
1742 
1744 }
1745 
1746 void
1748 {
1749  NS_LOG_FUNCTION(address << interface);
1750 
1751  Ipv6RegisteredMulticastAddressKey_t key = std::make_pair(address, interface);
1752 
1753  m_multicastAddresses[key]--;
1754  if (m_multicastAddresses[key] == 0)
1755  {
1756  m_multicastAddresses.erase(key);
1757  }
1758 }
1759 
1760 void
1762 {
1764 
1767  {
1769  }
1770 }
1771 
1772 bool
1774 {
1775  NS_LOG_FUNCTION(address << interface);
1776 
1777  Ipv6RegisteredMulticastAddressKey_t key = std::make_pair(address, interface);
1779 
1780  if (iter == m_multicastAddresses.end())
1781  {
1782  return false;
1783  }
1784  return true;
1785 }
1786 
1787 bool
1789 {
1791 
1794 
1795  if (iter == m_multicastAddressesNoInterface.end())
1796  {
1797  return false;
1798  }
1799  return true;
1800 }
1801 
1802 bool
1804 {
1805  if (ipInterfaceIndex >= m_interfaces.size())
1806  {
1807  return false;
1808  }
1809 
1810  Ptr<NdiscCache> ndiscCache = m_interfaces[ipInterfaceIndex]->GetNdiscCache();
1811  if (!ndiscCache)
1812  {
1813  return false;
1814  }
1815 
1816  NdiscCache::Entry* entry = ndiscCache->Lookup(address);
1817  if (!entry || entry->IsIncomplete())
1818  {
1819  return false;
1820  }
1821 
1822  if (entry->IsReachable())
1823  {
1824  entry->UpdateReachableTimer();
1825  }
1826  else if (entry->IsPermanent() || entry->IsAutoGenerated())
1827  {
1828  return true;
1829  }
1830  else if (entry->IsProbe())
1831  {
1832  // we just confirm the entry's MAC address to get the waiting packets (if any)
1833  std::list<NdiscCache::Ipv6PayloadHeaderPair> waiting =
1834  entry->MarkReachable(entry->GetMacAddress());
1835  for (std::list<NdiscCache::Ipv6PayloadHeaderPair>::const_iterator it = waiting.begin();
1836  it != waiting.end();
1837  it++)
1838  {
1839  ndiscCache->GetInterface()->Send(it->first, it->second, it->second.GetSource());
1840  }
1841  entry->ClearWaitingPacket();
1842  entry->StartReachableTimer();
1843  }
1844  else // STALE OR DELAY
1845  {
1846  entry->MarkReachable();
1847  entry->StartReachableTimer();
1848  }
1849 
1850  return true;
1851 }
1852 
1853 } /* namespace ns3 */
#define max(a, b)
Definition: 80211b.c:43
a polymophic address class
Definition: address.h:100
AttributeValue implementation for Boolean.
Definition: boolean.h:37
An implementation of the ICMPv6 protocol.
static uint16_t GetStaticProtocolNumber()
Get ICMPv6 protocol number.
@ AUTADDRCONF
Autonomous Address Configuration.
virtual RxStatus Receive(Ptr< Packet > p, const Ipv4Header &header, Ptr< Ipv4Interface > incomingInterface)=0
Called from lower-level layers to send the packet up in the stack.
virtual int GetProtocolNumber() const =0
Returns the protocol number of this protocol.
RxStatus
Rx status codes.
Describes an IPv6 address.
Definition: ipv6-address.h:50
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
bool IsDocumentation() const
If the IPv6 address is a documentation address (2001:DB8::/32).
bool IsAllNodesMulticast() const
If the IPv6 address is "all nodes multicast" (ff02::1/8).
bool IsLinkLocalMulticast() const
If the IPv6 address is link-local multicast (ff02::/16).
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
static Ipv6Address MakeAutoconfiguredAddress(Address addr, Ipv6Address prefix)
Make the autoconfigured IPv6 address from a Mac address.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
bool IsAny() const
If the IPv6 address is the "Any" address.
bool IsLocalhost() const
If the IPv6 address is localhost (::1).
static Ipv6Address GetLoopback()
Get the loopback address.
bool IsAllRoutersMulticast() const
If the IPv6 address is "all routers multicast" (ff02::2/8).
void StartPreferredTimer()
Start the preferred timer.
Demultiplexes IPv6 extensions.
IPv6 Extension Fragment.
void SetNode(Ptr< Node > node)
Set the node.
Packet header for IPv6.
Definition: ipv6-header.h:36
void SetDestination(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:118
void SetSource(Ipv6Address src)
Set the "Source address" field.
Definition: ipv6-header.cc:106
uint8_t GetHopLimit() const
Get the "Hop limit" field (TTL).
Definition: ipv6-header.cc:100
uint8_t GetNextHeader() const
Get the next header.
Definition: ipv6-header.cc:88
void SetHopLimit(uint8_t limit)
Set the "Hop limit" field (TTL).
Definition: ipv6-header.cc:94
Ipv6Address GetDestination() const
Get the "Destination address" field.
Definition: ipv6-header.cc:124
uint16_t GetPayloadLength() const
Get the "Payload length" field.
Definition: ipv6-header.cc:76
void SetPayloadLength(uint16_t len)
Set the "Payload length" field.
Definition: ipv6-header.cc:70
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
Definition: ipv6-header.cc:159
Ipv6Address GetSource() const
Get the "Source address" field.
Definition: ipv6-header.cc:112
void SetTrafficClass(uint8_t traffic)
Set the "Traffic class" field.
Definition: ipv6-header.cc:46
void SetNextHeader(uint8_t next)
Set the "Next header" field.
Definition: ipv6-header.cc:82
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:82
IPv6 address associated with an interface.
Ipv6Address GetAddress() const
Get the IPv6 address.
@ LINKLOCAL
Link-local address (fe80::/64)
@ GLOBAL
Global address (2000::/3)
The IPv6 representation of a network interface.
Ipv6InterfaceAddress GetLinkLocalAddress() const
Get link-local address from IPv6 interface.
void SetForwarding(bool forward)
Set forwarding enabled or not.
void SetDown()
Disable this interface.
bool IsUp() const
Is the interface UP ?
uint32_t GetNAddresses() const
Get number of addresses on this IPv6 interface.
Ipv6InterfaceAddress GetAddress(uint32_t index) const
Get an address from IPv6 interface.
void SetUp()
Enable this interface.
void Send(Ptr< Packet > p, const Ipv6Header &hdr, Ipv6Address dest)
Send a packet through this interface.
uint16_t GetMetric() const
Get the metric.
void SetMetric(uint16_t metric)
Set the metric.
virtual Ptr< NetDevice > GetDevice() const
Get the NetDevice.
IPv6 layer implementation.
bool GetIpForward() const override
Get IPv6 forwarding state.
Ptr< Ipv6PmtuCache > m_pmtuCache
Path MTU Cache.
void SetForwarding(uint32_t i, bool val) override
Enable or disable forwarding on interface.
void SetPmtu(Ipv6Address dst, uint32_t pmtu) override
Set the Path MTU for the specified IPv6 destination address.
void RegisterOptions() override
Register the IPv6 Options.
void RouteInputError(Ptr< const Packet > p, const Ipv6Header &ipHeader, Socket::SocketErrno sockErrno)
Fallback when no route is found.
uint8_t m_defaultTclass
Default TCLASS for outgoing packets.
bool IsRegisteredMulticastAddress(Ipv6Address address) const
Checks if the address has been registered.
Ptr< Ipv6RoutingProtocol > GetRoutingProtocol() const override
Get current routing protocol used.
bool GetMtuDiscover() const override
Get IPv6 MTU discover state.
bool AddAddress(uint32_t i, Ipv6InterfaceAddress address, bool addOnLinkRoute=true) override
Add an address on interface.
uint16_t GetMetric(uint32_t i) const override
Get metric for an interface.
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.
void SetUp(uint32_t i) override
Set an interface up.
TracedCallback< Ptr< const Packet >, Ptr< Ipv6 >, uint32_t > m_txTrace
Callback to trace TX (transmission) packets.
bool IsForwarding(uint32_t i) const override
Is interface allows forwarding ?
bool m_sendIcmpv6Redirect
Allow ICMPv6 Redirect sending state.
Ptr< Icmpv6L4Protocol > GetIcmpv6() const
Get ICMPv6 protocol.
bool ReachabilityHint(uint32_t ipInterfaceIndex, Ipv6Address address)
Provides reachability hint for Neighbor Cache Entries from L4-L7 protocols.
uint8_t m_defaultTtl
Default TTL for outgoing packets.
void SetMetric(uint32_t i, uint16_t metric) override
Set metric for an interface.
TracedCallback< Ptr< const Packet >, Ptr< Ipv6 >, uint32_t > m_rxTrace
Callback to trace RX (reception) packets.
TracedCallback< const Ipv6Header &, Ptr< const Packet >, DropReason, Ptr< Ipv6 >, uint32_t > m_dropTrace
Callback to trace drop packets.
DropReason
Reason why a packet has been dropped.
@ DROP_ROUTE_ERROR
Route error.
@ DROP_TTL_EXPIRED
Packet TTL has expired.
@ DROP_INTERFACE_DOWN
Interface is down so can not send packet.
@ DROP_NO_ROUTE
No route to host.
@ DROP_UNKNOWN_PROTOCOL
Unknown L4 protocol.
uint32_t GetNAddresses(uint32_t interface) const override
Get number of address for an interface.
int32_t GetInterfaceForDevice(Ptr< const NetDevice > device) const override
Get interface index which is on a specified net device.
void RegisterExtensions() override
Register the IPv6 Extensions.
TracedCallback< const Ipv6Header &, Ptr< const Packet >, uint32_t > m_sendOutgoingTrace
Trace of sent packets.
bool m_ipForward
Forwarding packets (i.e.
Ipv6AutoconfiguredPrefixList m_prefixes
List of IPv6 prefix received from RA.
void CallTxTrace(const Ipv6Header &ipHeader, Ptr< Packet > packet, Ptr< Ipv6 > ipv6, uint32_t interface)
Make a copy of the packet, add the header and invoke the TX trace callback.
Ipv6InterfaceList m_interfaces
List of IPv6 interfaces.
std::list< Ptr< Ipv6AutoconfiguredPrefix > >::iterator Ipv6AutoconfiguredPrefixListI
Iterator of the container of the IPv6 Autoconfigured addresses.
void Remove(Ptr< IpL4Protocol > protocol) override
Remove a L4 protocol.
Ipv6RegisteredMulticastAddressNoInterface_t m_multicastAddressesNoInterface
List of multicast IP addresses of interest for all the interfaces.
Ipv6InterfaceAddress GetAddress(uint32_t interfaceIndex, uint32_t addressIndex) const override
Get an address.
SocketList m_sockets
List of IPv6 raw sockets.
Ipv6Header BuildHeader(Ipv6Address src, Ipv6Address dst, uint8_t protocol, uint16_t payloadSize, uint8_t hopLimit, uint8_t tclass)
Construct an IPv6 header.
void SetNode(Ptr< Node > node)
Set node associated with this stack.
Ipv6Address SourceAddressSelection(uint32_t interface, Ipv6Address dest) override
Choose the source address to use with destination address.
Ptr< Node > m_node
Node attached to stack.
virtual bool GetSendIcmpv6Redirect() const
Get the ICMPv6 Redirect sending state.
L4List_t m_protocols
List of transport protocol.
Ptr< Ipv6Interface > GetInterface(uint32_t i) const
Get an interface.
TracedCallback< const Ipv6Header &, Ptr< const Packet >, uint32_t > m_unicastForwardTrace
Trace of unicast forwarded packets.
uint32_t m_nInterfaces
Number of IPv6 interfaces managed by the stack.
std::map< Ipv6Address, uint32_t >::const_iterator Ipv6RegisteredMulticastAddressNoInterfaceCIter_t
Container Const Iterator of the IPv6 multicast addresses.
void AddMulticastAddress(Ipv6Address address)
Adds a multicast address to the list of addresses to pass to local deliver.
virtual void ReportDrop(Ipv6Header ipHeader, Ptr< Packet > p, DropReason dropReason)
Report a packet drop.
std::map< Ipv6RegisteredMulticastAddressKey_t, uint32_t >::const_iterator Ipv6RegisteredMulticastAddressCIter_t
Container Const Iterator of the IPv6 multicast addresses.
void Send(Ptr< Packet > packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr< Ipv6Route > route) override
Higher-level layers call this method to send a packet down the stack to the MAC and PHY layers.
void SetupLoopback()
Setup loopback interface.
Ptr< IpL4Protocol > GetProtocol(int protocolNumber) const override
Get L4 protocol by protocol number.
Ptr< Socket > CreateRawSocket()
Create raw IPv6 socket.
Ipv6RegisteredMulticastAddress_t m_multicastAddresses
List of multicast IP addresses of interest, divided per interface.
void RemoveAutoconfiguredAddress(uint32_t interface, Ipv6Address network, Ipv6Prefix mask, Ipv6Address defaultRouter)
Remove an autoconfigured address.
uint16_t GetMtu(uint32_t i) const override
Get MTU for an interface.
void Insert(Ptr< IpL4Protocol > protocol) override
Add a L4 protocol.
bool m_mtuDiscover
MTU Discover (i.e.
void SetDefaultTtl(uint8_t ttl)
Set the default TTL.
uint32_t AddInterface(Ptr< NetDevice > device) override
Add IPv6 interface for a device.
bool RemoveAddress(uint32_t interfaceIndex, uint32_t addressIndex) override
Remove an address from an interface.
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.
Ptr< NetDevice > GetNetDevice(uint32_t i) override
Get device by index.
void RemoveMulticastAddress(Ipv6Address address)
Removes a multicast address from the list of addresses to pass to local deliver.
void SetDown(uint32_t i) override
set an interface down.
void DoDispose() override
Dispose object.
uint32_t AddIpv6Interface(Ptr< Ipv6Interface > interface)
Add an IPv6 interface to the stack.
Ptr< Ipv6RoutingProtocol > m_routingProtocol
Routing protocol.
virtual void SetSendIcmpv6Redirect(bool sendIcmpv6Redirect)
Set the ICMPv6 Redirect sending state.
void NotifyNewAggregate() override
Notify other components connected to the node that a new stack member is now connected.
void IpMulticastForward(Ptr< const NetDevice > idev, Ptr< Ipv6MulticastRoute > mrtentry, Ptr< const Packet > p, const Ipv6Header &header)
Forward a multicast packet.
~Ipv6L3Protocol() override
Destructor.
void DeleteRawSocket(Ptr< Socket > socket)
Remove raw IPv6 socket.
Ipv6InterfaceReverseContainer m_reverseInterfacesContainer
Container of NetDevice / Interface index associations.
void SendRealOut(Ptr< Ipv6Route > route, Ptr< Packet > packet, const Ipv6Header &ipHeader)
Send packet with route.
bool m_strongEndSystemModel
Rejects packets directed to an interface with wrong address (RFC 1222).
TracedCallback< const Ipv6Header &, Ptr< const Packet >, uint32_t > m_localDeliverTrace
Trace of locally delivered packets.
int32_t GetInterfaceForPrefix(Ipv6Address addr, Ipv6Prefix mask) const override
Get interface index which match specified address/prefix.
static const uint16_t PROT_NUMBER
The protocol number for IPv6 (0x86DD).
void SetDefaultTclass(uint8_t tclass)
Set the default TCLASS.
void IpForward(Ptr< const NetDevice > idev, Ptr< Ipv6Route > rtentry, Ptr< const Packet > p, const Ipv6Header &header)
Forward a packet.
uint32_t GetNInterfaces() const override
Get current number of interface on this stack.
bool IsUp(uint32_t i) const override
Is specified interface up ?
void SetRoutingProtocol(Ptr< Ipv6RoutingProtocol > routingProtocol) override
Set routing protocol for this stack.
std::pair< Ipv6Address, uint64_t > Ipv6RegisteredMulticastAddressKey_t
IPv6 multicast addresses / interface key.
std::pair< int, int32_t > L4ListKey_t
Container of the IPv6 L4 keys: protocol number, interface index.
int32_t GetInterfaceForAddress(Ipv6Address addr) const override
Get interface index which has specified IPv6 address.
Ipv6L3Protocol()
Constructor.
void SetIpForward(bool forward) override
Set IPv6 forwarding state.
void LocalDeliver(Ptr< const Packet > p, const Ipv6Header &ip, uint32_t iif)
Deliver a packet.
static TypeId GetTypeId()
Get the type ID of this class.
void SetMtuDiscover(bool mtuDiscover) override
Set IPv6 MTU discover state.
Describes an IPv6 prefix.
Definition: ipv6-address.h:456
void SetNode(Ptr< Node > node)
Set the node associated with this socket.
bool ForwardUp(Ptr< const Packet > p, Ipv6Header hdr, Ptr< NetDevice > device)
Forward up to receive method.
A record that holds information about a NdiscCache entry.
Definition: ndisc-cache.h:167
bool IsPermanent() const
Is the entry PERMANENT.
Definition: ndisc-cache.cc:659
void ClearWaitingPacket()
Clear the waiting packet list.
Definition: ndisc-cache.cc:286
void StartReachableTimer()
Start the reachable timer.
Definition: ndisc-cache.cc:469
void UpdateReachableTimer()
Update the reachable timer.
Definition: ndisc-cache.cc:484
Address GetMacAddress() const
Get the MAC address of this entry.
Definition: ndisc-cache.cc:673
std::list< Ipv6PayloadHeaderPair > MarkReachable(Address mac)
Changes the state to this entry to REACHABLE.
Definition: ndisc-cache.cc:562
bool IsIncomplete() const
Is the entry INCOMPLETE.
Definition: ndisc-cache.cc:645
bool IsProbe() const
Is the entry PROBE.
Definition: ndisc-cache.cc:652
bool IsAutoGenerated() const
Is the entry STATIC_AUTOGENERATED.
Definition: ndisc-cache.cc:666
bool IsReachable() const
Is the entry REACHABLE.
Definition: ndisc-cache.cc:631
virtual NdiscCache::Entry * Lookup(Ipv6Address dst)
Lookup in the cache.
Definition: ndisc-cache.cc:100
std::list< NdiscCache::Entry * > LookupInverse(Address dst)
Lookup in the cache for a MAC address.
Definition: ndisc-cache.cc:116
Ptr< Ipv6Interface > GetInterface() const
Get the Ipv6Interface associated with this cache.
Definition: ndisc-cache.cc:86
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:300
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:138
uint32_t GetNDevices() const
Definition: node.cc:162
uint32_t GetId() const
Definition: node.cc:117
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:152
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:242
virtual void NotifyNewAggregate()
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:332
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:259
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:986
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:400
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
Definition: packet.cc:376
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Definition: packet.cc:384
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:84
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer.
Definition: socket.h:1170
uint8_t GetHopLimit() const
Get the tag's Hop Limit.
Definition: socket.cc:672
indicates whether the socket has IPV6_TCLASS set.
Definition: socket.h:1364
uint8_t GetTclass() const
Get the tag's Tclass.
Definition: socket.cc:914
indicates whether the socket has a priority set.
Definition: socket.h:1316
The Traffic Control layer aims at introducing an equivalent of the Linux Traffic Control infrastructu...
virtual void Receive(Ptr< NetDevice > device, Ptr< const Packet > p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Called by NetDevices, incoming packet.
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#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:86
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:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
Definition: object-vector.h:40
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:76
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:46
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:579
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
#define IPV6_MIN_MTU
Minimum IPv6 MTU, as defined by RFC 2460
address
Definition: first.py:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:707
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:488