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.h"
26 #include "ipv6-interface.h"
27 #include "ipv6-option-demux.h"
28 #include "ipv6-option.h"
30 #include "ipv6-raw-socket-impl.h"
31 #include "ipv6-route.h"
32 #include "ipv6-routing-protocol.h"
33 #include "loopback-net-device.h"
34 #include "ndisc-cache.h"
35 
36 #include "ns3/boolean.h"
37 #include "ns3/callback.h"
38 #include "ns3/log.h"
39 #include "ns3/mac16-address.h"
40 #include "ns3/mac64-address.h"
41 #include "ns3/node.h"
42 #include "ns3/object-vector.h"
43 #include "ns3/trace-source-accessor.h"
44 #include "ns3/traffic-control-layer.h"
45 #include "ns3/uinteger.h"
46 #include "ns3/vector.h"
47 
49 #define IPV6_MIN_MTU 1280
50 
51 namespace ns3
52 {
53 
54 NS_LOG_COMPONENT_DEFINE("Ipv6L3Protocol");
55 
56 NS_OBJECT_ENSURE_REGISTERED(Ipv6L3Protocol);
57 
58 const uint16_t Ipv6L3Protocol::PROT_NUMBER = 0x86DD;
59 
60 TypeId
62 {
63  static TypeId tid =
64  TypeId("ns3::Ipv6L3Protocol")
65  .SetParent<Ipv6>()
66  .SetGroupName("Internet")
67  .AddConstructor<Ipv6L3Protocol>()
68  .AddAttribute("DefaultTtl",
69  "The TTL value set by default on all "
70  "outgoing packets generated on this node.",
71  UintegerValue(64),
73  MakeUintegerChecker<uint8_t>())
74  .AddAttribute("DefaultTclass",
75  "The TCLASS value set by default on all "
76  "outgoing packets generated on this node.",
77  UintegerValue(0),
79  MakeUintegerChecker<uint8_t>())
80  .AddAttribute("InterfaceList",
81  "The set of IPv6 interfaces associated to this IPv6 stack.",
84  MakeObjectVectorChecker<Ipv6Interface>())
85  .AddAttribute("SendIcmpv6Redirect",
86  "Send the ICMPv6 Redirect when appropriate.",
87  BooleanValue(true),
91  .AddTraceSource("Tx",
92  "Send IPv6 packet to outgoing interface.",
94  "ns3::Ipv6L3Protocol::TxRxTracedCallback")
95  .AddTraceSource("Rx",
96  "Receive IPv6 packet from incoming interface.",
98  "ns3::Ipv6L3Protocol::TxRxTracedCallback")
99  .AddTraceSource("Drop",
100  "Drop IPv6 packet",
102  "ns3::Ipv6L3Protocol::DropTracedCallback")
103 
104  .AddTraceSource("SendOutgoing",
105  "A newly-generated packet by this node is "
106  "about to be queued for transmission",
108  "ns3::Ipv6L3Protocol::SentTracedCallback")
109  .AddTraceSource("UnicastForward",
110  "A unicast IPv6 packet was received by this node "
111  "and is being forwarded to another node",
113  "ns3::Ipv6L3Protocol::SentTracedCallback")
114  .AddTraceSource("LocalDeliver",
115  "An IPv6 packet was received by/for this node, "
116  "and it is being forward up the stack",
118  "ns3::Ipv6L3Protocol::SentTracedCallback");
119  return tid;
120 }
121 
123  : m_nInterfaces(0)
124 {
125  NS_LOG_FUNCTION(this);
126  m_pmtuCache = CreateObject<Ipv6PmtuCache>();
127 
128  Ptr<Ipv6RawSocketFactoryImpl> rawFactoryImpl = CreateObject<Ipv6RawSocketFactoryImpl>();
129  AggregateObject(rawFactoryImpl);
134 }
135 
137 {
138  NS_LOG_FUNCTION(this);
139 }
140 
141 void
143 {
144  NS_LOG_FUNCTION(this);
145 
146  /* clear protocol and interface list */
147  for (auto it = m_protocols.begin(); it != m_protocols.end(); ++it)
148  {
149  it->second = nullptr;
150  }
151  m_protocols.clear();
152 
153  /* remove interfaces */
154  for (auto it = m_interfaces.begin(); it != m_interfaces.end(); ++it)
155  {
156  *it = nullptr;
157  }
158  m_interfaces.clear();
160 
161  /* remove raw sockets */
162  for (auto it = m_sockets.begin(); it != m_sockets.end(); ++it)
163  {
164  *it = nullptr;
165  }
166  m_sockets.clear();
167 
168  /* remove list of prefix */
169  for (auto it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
170  {
171  (*it)->StopValidTimer();
172  (*it)->StopPreferredTimer();
173  (*it) = nullptr;
174  }
175  m_prefixes.clear();
176 
177  m_node = nullptr;
178  m_routingProtocol = nullptr;
179  m_pmtuCache = nullptr;
181 }
182 
183 void
185 {
186  NS_LOG_FUNCTION(this << routingProtocol);
187  m_routingProtocol = routingProtocol;
188  m_routingProtocol->SetIpv6(this);
189 }
190 
193 {
194  NS_LOG_FUNCTION(this);
195  return m_routingProtocol;
196 }
197 
198 uint32_t
200 {
201  NS_LOG_FUNCTION(this << device);
203 
205 
206  NS_ASSERT(tc);
207 
210  device);
211 
212  tc->RegisterProtocolHandler(MakeCallback(&Ipv6L3Protocol::Receive, this),
214  device);
215 
216  interface->SetNode(m_node);
217  interface->SetDevice(device);
218  interface->SetTrafficControl(tc);
219  interface->SetForwarding(m_ipForward);
220  return AddIpv6Interface(interface);
221 }
222 
223 uint32_t
225 {
226  NS_LOG_FUNCTION(this << interface);
227  uint32_t index = m_nInterfaces;
228 
229  m_interfaces.push_back(interface);
230  m_reverseInterfacesContainer[interface->GetDevice()] = index;
231  m_nInterfaces++;
232  return index;
233 }
234 
236 Ipv6L3Protocol::GetInterface(uint32_t index) const
237 {
238  NS_LOG_FUNCTION(this << index);
239 
240  if (index < m_interfaces.size())
241  {
242  return m_interfaces[index];
243  }
244  return nullptr;
245 }
246 
247 uint32_t
249 {
250  NS_LOG_FUNCTION(this);
251  return m_nInterfaces;
252 }
253 
254 int32_t
256 {
257  NS_LOG_FUNCTION(this << address);
258  int32_t index = 0;
259 
260  for (auto it = m_interfaces.begin(); it != m_interfaces.end(); it++)
261  {
262  uint32_t j = 0;
263  uint32_t max = (*it)->GetNAddresses();
264 
265  for (j = 0; j < max; j++)
266  {
267  if ((*it)->GetAddress(j).GetAddress() == address)
268  {
269  return index;
270  }
271  }
272  index++;
273  }
274  return -1;
275 }
276 
277 int32_t
279 {
280  NS_LOG_FUNCTION(this << address << mask);
281  int32_t index = 0;
282 
283  for (auto it = m_interfaces.begin(); it != m_interfaces.end(); it++)
284  {
285  uint32_t j = 0;
286  for (j = 0; j < (*it)->GetNAddresses(); j++)
287  {
288  if ((*it)->GetAddress(j).GetAddress().CombinePrefix(mask) ==
289  address.CombinePrefix(mask))
290  {
291  return index;
292  }
293  }
294  index++;
295  }
296  return -1;
297 }
298 
301 {
302  NS_LOG_FUNCTION(this << i);
303  return GetInterface(i)->GetDevice();
304 }
305 
306 int32_t
308 {
309  NS_LOG_FUNCTION(this << device);
310 
311  auto iter = m_reverseInterfacesContainer.find(device);
312  if (iter != m_reverseInterfacesContainer.end())
313  {
314  return (*iter).second;
315  }
316 
317  return -1;
318 }
319 
320 void
322  Ipv6Address network,
323  Ipv6Prefix mask,
324  uint8_t flags,
325  uint32_t validTime,
326  uint32_t preferredTime,
327  Ipv6Address defaultRouter)
328 {
329  NS_LOG_FUNCTION(this << interface << network << mask << (uint32_t)flags << validTime
330  << preferredTime);
332 
333  Address addr = GetInterface(interface)->GetDevice()->GetAddress();
334 
335  if (!defaultRouter.IsAny())
336  {
337  GetRoutingProtocol()->NotifyAddRoute(Ipv6Address::GetAny(),
338  Ipv6Prefix((uint8_t)0),
339  defaultRouter,
340  interface,
341  network);
342  }
343 
344  bool onLink = false;
346  {
347  onLink = true;
348  }
349 
350  if (flags & Icmpv6OptionPrefixInformation::AUTADDRCONF) /* auto flag */
351  {
353  address.SetOnLink(onLink);
354 
355  /* see if we have already the prefix */
356  for (auto it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
357  {
358  if ((*it)->GetInterface() == interface && (*it)->GetPrefix() == network &&
359  (*it)->GetMask() == mask)
360  {
361  (*it)->StopPreferredTimer();
362  (*it)->StopValidTimer();
363  (*it)->StartPreferredTimer();
364  return;
365  }
366  }
367 
368  /* no prefix found, add autoconfigured address and the prefix */
369  NS_LOG_INFO("Autoconfigured address is :" << address.GetAddress());
370  AddAddress(interface, address, onLink);
371 
373  CreateObject<Ipv6AutoconfiguredPrefix>(m_node,
374  interface,
375  network,
376  mask,
377  preferredTime,
378  validTime,
379  defaultRouter);
380  aPrefix->StartPreferredTimer();
381 
382  m_prefixes.push_back(aPrefix);
383  }
384 
385  if (onLink) /* on-link flag */
386  {
387  /* add default router
388  * if a previous default route exists, the new ones is simply added
389  */
390  m_routingProtocol->NotifyAddRoute(network, mask, Ipv6Address::GetAny(), interface);
391  }
392 }
393 
394 void
396  Ipv6Address network,
397  Ipv6Prefix mask,
398  Ipv6Address defaultRouter)
399 {
400  NS_LOG_FUNCTION(this << interface << network << mask);
401  Ptr<Ipv6Interface> iface = GetInterface(interface);
402  Address addr = iface->GetDevice()->GetAddress();
403 
404  Ipv6Address addressToFind = Ipv6Address::MakeAutoconfiguredAddress(addr, network);
405 
406  for (uint32_t i = 0; i < iface->GetNAddresses(); i++)
407  {
408  if (iface->GetAddress(i).GetAddress() == addressToFind)
409  {
410  RemoveAddress(interface, i);
411  break;
412  }
413  }
414 
415  /* remove from list of autoconfigured address */
416  for (auto it = m_prefixes.begin(); it != m_prefixes.end(); ++it)
417  {
418  if ((*it)->GetInterface() == interface && (*it)->GetPrefix() == network &&
419  (*it)->GetMask() == mask)
420  {
421  *it = nullptr;
422  m_prefixes.erase(it);
423  break;
424  }
425  }
426 
427  GetRoutingProtocol()->NotifyRemoveRoute(Ipv6Address::GetAny(),
428  Ipv6Prefix((uint8_t)0),
429  defaultRouter,
430  interface,
431  network);
432 }
433 
434 bool
435 Ipv6L3Protocol::AddAddress(uint32_t i, Ipv6InterfaceAddress address, bool addOnLinkRoute)
436 {
437  NS_LOG_FUNCTION(this << i << address);
438  Ptr<Ipv6Interface> interface = GetInterface(i);
439  address.SetOnLink(addOnLinkRoute);
440  bool ret = interface->AddAddress(address);
441 
442  if (m_routingProtocol)
443  {
444  m_routingProtocol->NotifyAddAddress(i, address);
445  }
446 
447  if (addOnLinkRoute)
448  {
449  Ipv6Address networkAddress = address.GetAddress().CombinePrefix(address.GetPrefix());
450  Ipv6Prefix networkMask = address.GetPrefix();
451  GetRoutingProtocol()->NotifyAddRoute(networkAddress,
452  networkMask,
454  i);
455  }
456  return ret;
457 }
458 
459 uint32_t
461 {
462  NS_LOG_FUNCTION(this << i);
463  Ptr<Ipv6Interface> interface = GetInterface(i);
464  return interface->GetNAddresses();
465 }
466 
468 Ipv6L3Protocol::GetAddress(uint32_t i, uint32_t addressIndex) const
469 {
470  NS_LOG_FUNCTION(this << i << addressIndex);
471  Ptr<Ipv6Interface> interface = GetInterface(i);
472  return interface->GetAddress(addressIndex);
473 }
474 
475 bool
476 Ipv6L3Protocol::RemoveAddress(uint32_t i, uint32_t addressIndex)
477 {
478  NS_LOG_FUNCTION(this << i << addressIndex);
479  Ptr<Ipv6Interface> interface = GetInterface(i);
480  Ipv6InterfaceAddress address = interface->RemoveAddress(addressIndex);
481 
482  if (address != Ipv6InterfaceAddress())
483  {
484  if (m_routingProtocol)
485  {
486  m_routingProtocol->NotifyRemoveAddress(i, address);
487  }
488  return true;
489  }
490  return false;
491 }
492 
493 bool
495 {
496  NS_LOG_FUNCTION(this << i << address);
497 
499  {
500  NS_LOG_WARN("Cannot remove loopback address.");
501  return false;
502  }
503  Ptr<Ipv6Interface> interface = GetInterface(i);
504  Ipv6InterfaceAddress ifAddr = interface->RemoveAddress(address);
505  if (ifAddr != Ipv6InterfaceAddress())
506  {
507  if (m_routingProtocol)
508  {
509  m_routingProtocol->NotifyRemoveAddress(i, ifAddr);
510  }
511  return true;
512  }
513  return false;
514 }
515 
516 void
517 Ipv6L3Protocol::SetMetric(uint32_t i, uint16_t metric)
518 {
519  NS_LOG_FUNCTION(this << i << metric);
520  Ptr<Ipv6Interface> interface = GetInterface(i);
521  interface->SetMetric(metric);
522 }
523 
524 uint16_t
525 Ipv6L3Protocol::GetMetric(uint32_t i) const
526 {
527  NS_LOG_FUNCTION(this << i);
528  Ptr<Ipv6Interface> interface = GetInterface(i);
529  return interface->GetMetric();
530 }
531 
532 uint16_t
533 Ipv6L3Protocol::GetMtu(uint32_t i) const
534 {
535  NS_LOG_FUNCTION(this << i);
536 
537  // RFC 1981, if PMTU is disabled, return the minimum MTU
538  if (!m_mtuDiscover)
539  {
540  return IPV6_MIN_MTU;
541  }
542 
543  Ptr<Ipv6Interface> interface = GetInterface(i);
544  return interface->GetDevice()->GetMtu();
545 }
546 
547 void
549 {
550  NS_LOG_FUNCTION(this << dst << int(pmtu));
551  m_pmtuCache->SetPmtu(dst, pmtu);
552 }
553 
554 bool
555 Ipv6L3Protocol::IsUp(uint32_t i) const
556 {
557  NS_LOG_FUNCTION(this << i);
558  Ptr<Ipv6Interface> interface = GetInterface(i);
559  return interface->IsUp();
560 }
561 
562 void
564 {
565  NS_LOG_FUNCTION(this << i);
566  Ptr<Ipv6Interface> interface = GetInterface(i);
567 
568  // RFC 2460, Section 5, pg. 24:
569  // IPv6 requires that every link in the internet have an MTU of 1280
570  // octets or greater. On any link that cannot convey a 1280-octet
571  // packet in one piece, link-specific fragmentation and reassembly must
572  // be provided at a layer below IPv6.
573  if (interface->GetDevice()->GetMtu() >= 1280)
574  {
575  interface->SetUp();
576 
577  if (m_routingProtocol)
578  {
579  m_routingProtocol->NotifyInterfaceUp(i);
580  }
581  }
582  else
583  {
584  NS_LOG_LOGIC("Interface " << int(i)
585  << " is set to be down for IPv6. Reason: not respecting minimum "
586  "IPv6 MTU (1280 octets)");
587  }
588 }
589 
590 void
592 {
593  NS_LOG_FUNCTION(this << i);
594  Ptr<Ipv6Interface> interface = GetInterface(i);
595 
596  interface->SetDown();
597 
598  if (m_routingProtocol)
599  {
600  m_routingProtocol->NotifyInterfaceDown(i);
601  }
602 }
603 
604 void
606 {
607  NS_LOG_FUNCTION(this);
609  Ptr<LoopbackNetDevice> device = nullptr;
610  uint32_t i = 0;
611 
612  /* see if we have already an loopback NetDevice */
613  for (i = 0; i < m_node->GetNDevices(); i++)
614  {
615  if ((device = DynamicCast<LoopbackNetDevice>(m_node->GetDevice(i))))
616  {
617  break;
618  }
619  }
620 
621  if (!device)
622  {
623  device = CreateObject<LoopbackNetDevice>();
624  m_node->AddDevice(device);
625  }
626 
627  interface->SetDevice(device);
628  interface->SetNode(m_node);
629  Ipv6InterfaceAddress ifaceAddr =
631  interface->AddAddress(ifaceAddr);
632  uint32_t index = AddIpv6Interface(interface);
633  Ptr<Node> node = GetObject<Node>();
636  device);
637  interface->SetUp();
638 
639  if (m_routingProtocol)
640  {
641  m_routingProtocol->NotifyInterfaceUp(index);
642  }
643 }
644 
645 bool
647 {
648  NS_LOG_FUNCTION(this << i);
649  Ptr<Ipv6Interface> interface = GetInterface(i);
650 
651  NS_LOG_LOGIC("Forwarding state: " << interface->IsForwarding());
652  return interface->IsForwarding();
653 }
654 
655 void
656 Ipv6L3Protocol::SetForwarding(uint32_t i, bool val)
657 {
658  NS_LOG_FUNCTION(this << i << val);
659  Ptr<Ipv6Interface> interface = GetInterface(i);
660  interface->SetForwarding(val);
661 }
662 
665 {
666  NS_LOG_FUNCTION(this << interface << dest);
667  Ipv6Address ret;
668 
669  if (dest.IsLocalhost())
670  {
671  return Ipv6Address::GetLoopback();
672  }
673 
674  if (dest.IsLinkLocal() || dest.IsLinkLocalMulticast())
675  {
676  for (uint32_t i = 0; i < GetNAddresses(interface); i++)
677  {
678  Ipv6InterfaceAddress test = GetAddress(interface, i);
679  if (test.GetScope() == Ipv6InterfaceAddress::LINKLOCAL)
680  {
681  return test.GetAddress();
682  }
683  }
684  NS_ASSERT_MSG(false, "No link-local address found on interface " << interface);
685  }
686 
687  for (uint32_t i = 0; i < GetNAddresses(interface); i++)
688  {
689  Ipv6InterfaceAddress test = GetAddress(interface, i);
690 
691  if (test.GetScope() == Ipv6InterfaceAddress::GLOBAL)
692  {
693  if (test.IsInSameSubnet(dest))
694  {
695  return test.GetAddress();
696  }
697  else
698  {
699  ret = test.GetAddress();
700  }
701  }
702  }
703 
704  // no specific match found. Use a global address (any useful is fine).
705  NS_ASSERT_MSG(!ret.IsAny(),
706  "Could not find any address for " << dest << " on interface " << interface);
707  return ret;
708 }
709 
710 void
712 {
713  NS_LOG_FUNCTION(this << forward);
714  m_ipForward = forward;
715 
716  for (auto it = m_interfaces.begin(); it != m_interfaces.end(); it++)
717  {
718  (*it)->SetForwarding(forward);
719  }
720 }
721 
722 bool
724 {
725  NS_LOG_FUNCTION(this);
726  return m_ipForward;
727 }
728 
729 void
731 {
732  NS_LOG_FUNCTION(this << int(mtuDiscover));
733  m_mtuDiscover = mtuDiscover;
734 }
735 
736 bool
738 {
739  NS_LOG_FUNCTION(this);
740  return m_mtuDiscover;
741 }
742 
743 void
745 {
746  NS_LOG_FUNCTION(this << sendIcmpv6Redirect);
747  m_sendIcmpv6Redirect = sendIcmpv6Redirect;
748 }
749 
750 bool
752 {
753  NS_LOG_FUNCTION(this);
754  return m_sendIcmpv6Redirect;
755 }
756 
757 void
759 {
760  NS_LOG_FUNCTION(this);
761 
762  if (!m_node)
763  {
764  Ptr<Node> node = this->GetObject<Node>();
765  // verify that it's a valid node and that
766  // the node has not been set before
767  if (node)
768  {
769  this->SetNode(node);
770  }
771  }
772 
774 }
775 
776 void
778 {
779  NS_LOG_FUNCTION(this << node);
780  m_node = node;
781  /* add LoopbackNetDevice if needed, and an Ipv6Interface on top of it */
782  SetupLoopback();
783 }
784 
785 void
787 {
788  NS_LOG_FUNCTION(this << protocol);
789  L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), -1);
790  if (m_protocols.find(key) != m_protocols.end())
791  {
792  NS_LOG_WARN("Overwriting default protocol " << int(protocol->GetProtocolNumber()));
793  }
794  m_protocols[key] = protocol;
795 }
796 
797 void
798 Ipv6L3Protocol::Insert(Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
799 {
800  NS_LOG_FUNCTION(this << protocol << interfaceIndex);
801 
802  L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), interfaceIndex);
803  if (m_protocols.find(key) != m_protocols.end())
804  {
805  NS_LOG_WARN("Overwriting protocol " << int(protocol->GetProtocolNumber())
806  << " on interface " << int(interfaceIndex));
807  }
808  m_protocols[key] = protocol;
809 }
810 
811 void
813 {
814  NS_LOG_FUNCTION(this << protocol);
815 
816  L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), -1);
817  auto iter = m_protocols.find(key);
818  if (iter == m_protocols.end())
819  {
820  NS_LOG_WARN("Trying to remove an non-existent default protocol "
821  << int(protocol->GetProtocolNumber()));
822  }
823  else
824  {
825  m_protocols.erase(key);
826  }
827 }
828 
829 void
830 Ipv6L3Protocol::Remove(Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
831 {
832  NS_LOG_FUNCTION(this << protocol << interfaceIndex);
833 
834  L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), interfaceIndex);
835  auto iter = m_protocols.find(key);
836  if (iter == m_protocols.end())
837  {
838  NS_LOG_WARN("Trying to remove an non-existent protocol "
839  << int(protocol->GetProtocolNumber()) << " on interface "
840  << int(interfaceIndex));
841  }
842  else
843  {
844  m_protocols.erase(key);
845  }
846 }
847 
849 Ipv6L3Protocol::GetProtocol(int protocolNumber) const
850 {
851  NS_LOG_FUNCTION(this << protocolNumber);
852 
853  return GetProtocol(protocolNumber, -1);
854 }
855 
857 Ipv6L3Protocol::GetProtocol(int protocolNumber, int32_t interfaceIndex) const
858 {
859  NS_LOG_FUNCTION(this << protocolNumber << interfaceIndex);
860 
861  if (interfaceIndex >= 0)
862  {
863  // try the interface-specific protocol.
864  auto key = std::make_pair(protocolNumber, interfaceIndex);
865  auto i = m_protocols.find(key);
866  if (i != m_protocols.end())
867  {
868  return i->second;
869  }
870  }
871  // try the generic protocol.
872  auto key = std::make_pair(protocolNumber, -1);
873  auto i = m_protocols.find(key);
874  if (i != m_protocols.end())
875  {
876  return i->second;
877  }
878 
879  return nullptr;
880 }
881 
884 {
885  NS_LOG_FUNCTION(this);
886  Ptr<Ipv6RawSocketImpl> sock = CreateObject<Ipv6RawSocketImpl>();
887  sock->SetNode(m_node);
888  m_sockets.push_back(sock);
889  return sock;
890 }
891 
892 void
894 {
895  NS_LOG_FUNCTION(this << socket);
896 
897  for (auto it = m_sockets.begin(); it != m_sockets.end(); ++it)
898  {
899  if ((*it) == socket)
900  {
901  m_sockets.erase(it);
902  return;
903  }
904  }
905 }
906 
909 {
910  NS_LOG_FUNCTION(this);
912 
913  if (protocol)
914  {
915  return protocol->GetObject<Icmpv6L4Protocol>();
916  }
917  else
918  {
919  return nullptr;
920  }
921 }
922 
923 void
925 {
926  NS_LOG_FUNCTION(this << ttl);
927  m_defaultTtl = ttl;
928 }
929 
930 void
932 {
933  NS_LOG_FUNCTION(this << tclass);
934  m_defaultTclass = tclass;
935 }
936 
937 void
939  Ipv6Address source,
940  Ipv6Address destination,
941  uint8_t protocol,
942  Ptr<Ipv6Route> route)
943 {
944  NS_LOG_FUNCTION(this << packet << source << destination << (uint32_t)protocol << route);
945  Ipv6Header hdr;
946  uint8_t ttl = m_defaultTtl;
948  bool found = packet->RemovePacketTag(tag);
949 
950  if (found)
951  {
952  ttl = tag.GetHopLimit();
953  }
954 
955  SocketIpv6TclassTag tclassTag;
956  uint8_t tclass = m_defaultTclass;
957  found = packet->RemovePacketTag(tclassTag);
958 
959  if (found)
960  {
961  tclass = tclassTag.GetTclass();
962  }
963 
964  /* Handle 3 cases:
965  * 1) Packet is passed in with a route entry
966  * 2) Packet is passed in with a route entry but route->GetGateway is not set (e.g., same
967  * network) 3) route is NULL (e.g., a raw socket call or ICMPv6)
968  */
969 
970  /* 1) */
971  if (route && route->GetGateway() != Ipv6Address::GetZero())
972  {
973  NS_LOG_LOGIC("Ipv6L3Protocol::Send case 1: passed in with a route");
974  hdr = BuildHeader(source, destination, protocol, packet->GetSize(), ttl, tclass);
975  int32_t interface = GetInterfaceForDevice(route->GetOutputDevice());
976  m_sendOutgoingTrace(hdr, packet, interface);
977  SendRealOut(route, packet, hdr);
978  return;
979  }
980 
981  /* 2) */
982  if (route && route->GetGateway() == Ipv6Address::GetZero())
983  {
984  NS_LOG_LOGIC("Ipv6L3Protocol::Send case 2: probably sent to machine on same IPv6 network");
985  hdr = BuildHeader(source, destination, protocol, packet->GetSize(), ttl, tclass);
986  int32_t interface = GetInterfaceForDevice(route->GetOutputDevice());
987  m_sendOutgoingTrace(hdr, packet, interface);
988  SendRealOut(route, packet, hdr);
989  return;
990  }
991 
992  /* 3) */
993  NS_LOG_LOGIC("Ipv6L3Protocol::Send case 3: passed in with no route " << destination);
995  Ptr<NetDevice> oif(nullptr);
996  Ptr<Ipv6Route> newRoute = nullptr;
997 
998  hdr = BuildHeader(source, destination, protocol, packet->GetSize(), ttl, tclass);
999 
1000  // for link-local traffic, we need to determine the interface
1001  if (source.IsLinkLocal() || destination.IsLinkLocal() || destination.IsLinkLocalMulticast())
1002  {
1003  int32_t index = GetInterfaceForAddress(source);
1004  NS_ASSERT_MSG(index >= 0,
1005  "Can not find an outgoing interface for a packet with src "
1006  << source << " and dst " << destination);
1007  oif = GetNetDevice(index);
1008  }
1009 
1010  newRoute = m_routingProtocol->RouteOutput(packet, hdr, oif, err);
1011 
1012  if (newRoute)
1013  {
1014  int32_t interface = GetInterfaceForDevice(newRoute->GetOutputDevice());
1015  m_sendOutgoingTrace(hdr, packet, interface);
1016  SendRealOut(newRoute, packet, hdr);
1017  }
1018  else
1019  {
1020  NS_LOG_WARN("No route to host, drop!");
1021  m_dropTrace(hdr, packet, DROP_NO_ROUTE, this, GetInterfaceForDevice(oif));
1022  }
1023 }
1024 
1025 void
1028  uint16_t protocol,
1029  const Address& from,
1030  const Address& to,
1031  NetDevice::PacketType packetType)
1032 {
1033  NS_LOG_FUNCTION(this << device << p << protocol << from << to << packetType);
1034  NS_LOG_LOGIC("Packet from " << from << " received on node " << m_node->GetId());
1035 
1036  NS_ASSERT_MSG(GetInterfaceForDevice(device) != -1,
1037  "Received a packet from an interface that is not known to IPv6");
1038  uint32_t interface = GetInterfaceForDevice(device);
1039 
1040  Ptr<Ipv6Interface> ipv6Interface = m_interfaces[interface];
1041  Ptr<Packet> packet = p->Copy();
1042 
1043  if (ipv6Interface->IsUp())
1044  {
1045  m_rxTrace(packet, this, interface);
1046  }
1047  else
1048  {
1049  NS_LOG_LOGIC("Dropping received packet-- interface is down");
1050  Ipv6Header hdr;
1051  packet->RemoveHeader(hdr);
1052  m_dropTrace(hdr, packet, DROP_INTERFACE_DOWN, this, interface);
1053  return;
1054  }
1055 
1056  Ipv6Header hdr;
1057  packet->RemoveHeader(hdr);
1058 
1059  // Trim any residual frame padding from underlying devices
1060  if (hdr.GetPayloadLength() < packet->GetSize())
1061  {
1062  packet->RemoveAtEnd(packet->GetSize() - hdr.GetPayloadLength());
1063  }
1064 
1065  // the packet is valid, we update the NDISC cache entry (if present)
1066  Ptr<NdiscCache> ndiscCache = ipv6Interface->GetNdiscCache();
1067  if (ndiscCache)
1068  {
1069  // case one, it's a a direct routing.
1070  NdiscCache::Entry* entry = ndiscCache->Lookup(hdr.GetSource());
1071  if (entry)
1072  {
1073  entry->UpdateReachableTimer();
1074  }
1075  else
1076  {
1077  // It's not in the direct routing, so it's the router, and it could have multiple IP
1078  // addresses. In doubt, update all of them. Note: it's a confirmed behavior for Linux
1079  // routers.
1080  std::list<NdiscCache::Entry*> entryList = ndiscCache->LookupInverse(from);
1081  for (auto iter = entryList.begin(); iter != entryList.end(); iter++)
1082  {
1083  (*iter)->UpdateReachableTimer();
1084  }
1085  }
1086  }
1087 
1088  /* forward up to IPv6 raw sockets */
1089  for (auto it = m_sockets.begin(); it != m_sockets.end(); ++it)
1090  {
1091  Ptr<Ipv6RawSocketImpl> socket = *it;
1092  socket->ForwardUp(packet, hdr, device);
1093  }
1094 
1096  Ptr<Ipv6Extension> ipv6Extension = nullptr;
1097  uint8_t nextHeader = hdr.GetNextHeader();
1098  bool stopProcessing = false;
1099  bool isDropped = false;
1100  DropReason dropReason;
1101 
1102  if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1103  {
1104  ipv6Extension = ipv6ExtensionDemux->GetExtension(nextHeader);
1105 
1106  if (ipv6Extension)
1107  {
1108  ipv6Extension->Process(packet,
1109  0,
1110  hdr,
1111  hdr.GetDestination(),
1112  (uint8_t*)nullptr,
1113  stopProcessing,
1114  isDropped,
1115  dropReason);
1116  }
1117 
1118  if (isDropped)
1119  {
1120  m_dropTrace(hdr, packet, dropReason, this, interface);
1121  }
1122 
1123  if (stopProcessing)
1124  {
1125  return;
1126  }
1127  }
1128 
1129  if (hdr.GetDestination().IsAllNodesMulticast())
1130  {
1131  LocalDeliver(packet, hdr, interface);
1132  return;
1133  }
1134  else if (hdr.GetDestination().IsAllRoutersMulticast() && ipv6Interface->IsForwarding())
1135  {
1136  LocalDeliver(packet, hdr, interface);
1137  return;
1138  }
1139  else if (hdr.GetDestination().IsMulticast())
1140  {
1141  bool isSolicited = ipv6Interface->IsSolicitedMulticastAddress(hdr.GetDestination());
1142  bool isRegisteredOnInterface =
1143  IsRegisteredMulticastAddress(hdr.GetDestination(), interface);
1144  bool isRegisteredGlobally = IsRegisteredMulticastAddress(hdr.GetDestination());
1145  if (isSolicited || isRegisteredGlobally || isRegisteredOnInterface)
1146  {
1147  LocalDeliver(packet, hdr, interface);
1148  // do not return, the packet could be handled by a routing protocol
1149  }
1150  }
1151 
1152  for (uint32_t j = 0; j < GetNInterfaces(); j++)
1153  {
1154  for (uint32_t i = 0; i < GetNAddresses(j); i++)
1155  {
1156  Ipv6InterfaceAddress iaddr = GetAddress(j, i);
1157  Ipv6Address addr = iaddr.GetAddress();
1158  if (addr == hdr.GetDestination())
1159  {
1160  if (j == interface)
1161  {
1162  NS_LOG_LOGIC("For me (destination " << addr << " match)");
1163  LocalDeliver(packet, hdr, interface);
1164  return;
1165  }
1166  else if (!GetStrongEndSystemModel())
1167  {
1168  NS_LOG_LOGIC("For me (destination "
1169  << addr
1170  << " match) on another interface with Weak End System Model"
1171  << hdr.GetDestination());
1172  LocalDeliver(packet, hdr, interface);
1173  return;
1174  }
1175  else
1176  {
1177  NS_LOG_LOGIC(
1178  "For me (destination "
1179  << addr
1180  << " match) on another interface with Strong End System Model - discarding"
1181  << hdr.GetDestination());
1182  m_dropTrace(hdr, packet, DROP_NO_ROUTE, this, interface);
1183  return;
1184  }
1185  }
1186  NS_LOG_LOGIC("Address " << addr << " not a match");
1187  }
1188  }
1189 
1190  if (!m_routingProtocol->RouteInput(packet, hdr, device, m_ucb, m_mcb, m_lcb, m_ecb))
1191  {
1192  NS_LOG_WARN("No route found for forwarding packet. Drop.");
1193  // Drop trace and ICMPs are courtesy of RouteInputError
1194  }
1195 }
1196 
1197 void
1199  Ptr<Packet> packet,
1200  Ptr<Ipv6> ipv6,
1201  uint32_t interface)
1202 {
1203  if (!m_txTrace.IsEmpty())
1204  {
1205  Ptr<Packet> packetCopy = packet->Copy();
1206  packetCopy->AddHeader(ipHeader);
1207  m_txTrace(packetCopy, ipv6, interface);
1208  }
1209 }
1210 
1211 void
1213 {
1214  NS_LOG_FUNCTION(this << route << packet << ipHeader);
1215 
1216  if (!route)
1217  {
1218  NS_LOG_LOGIC("No route to host, drop!.");
1219  return;
1220  }
1221 
1222  Ptr<NetDevice> dev = route->GetOutputDevice();
1223  int32_t interface = GetInterfaceForDevice(dev);
1224  NS_ASSERT(interface >= 0);
1225 
1226  Ptr<Ipv6Interface> outInterface = GetInterface(interface);
1227  NS_LOG_LOGIC("Send via NetDevice ifIndex " << dev->GetIfIndex() << " Ipv6InterfaceIndex "
1228  << interface);
1229 
1230  // Check packet size
1231  std::list<Ipv6ExtensionFragment::Ipv6PayloadHeaderPair> fragments;
1232 
1233  // Check if this is the source of the packet
1234  bool fromMe = false;
1235  for (uint32_t i = 0; i < GetNInterfaces(); i++)
1236  {
1237  for (uint32_t j = 0; j < GetNAddresses(i); j++)
1238  {
1239  if (GetAddress(i, j).GetAddress() == ipHeader.GetSource())
1240  {
1241  fromMe = true;
1242  break;
1243  }
1244  }
1245  }
1246 
1247  size_t targetMtu = 0;
1248 
1249  // Check if we have a Path MTU stored. If so, use it. Else, use the link MTU.
1250  // Note: PMTU must not be cached in intermediate nodes, and must be checked only by the source
1251  // node
1252  if (fromMe)
1253  {
1254  targetMtu = (size_t)(m_pmtuCache->GetPmtu(ipHeader.GetDestination()));
1255  }
1256  if (targetMtu == 0)
1257  {
1258  targetMtu = dev->GetMtu();
1259  }
1260 
1261  if (packet->GetSize() + ipHeader.GetSerializedSize() > targetMtu)
1262  {
1263  // Router => drop
1264  if (!fromMe)
1265  {
1266  Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6();
1267  if (icmpv6)
1268  {
1269  packet->AddHeader(ipHeader);
1270  icmpv6->SendErrorTooBig(packet, ipHeader.GetSource(), dev->GetMtu());
1271  }
1272  return;
1273  }
1274 
1276 
1277  // To get specific method GetFragments from Ipv6ExtensionFragmentation
1278  Ipv6ExtensionFragment* ipv6Fragment = dynamic_cast<Ipv6ExtensionFragment*>(
1279  PeekPointer(ipv6ExtensionDemux->GetExtension(Ipv6Header::IPV6_EXT_FRAGMENTATION)));
1280  NS_ASSERT(ipv6Fragment != nullptr);
1281  ipv6Fragment->GetFragments(packet, ipHeader, targetMtu, fragments);
1282  }
1283 
1284  if (route->GetGateway() != Ipv6Address::GetAny())
1285  {
1286  if (outInterface->IsUp())
1287  {
1288  NS_LOG_LOGIC("Send to gateway " << route->GetGateway());
1289 
1290  if (!fragments.empty())
1291  {
1292  std::ostringstream oss;
1293 
1294  for (auto it = fragments.begin(); it != fragments.end(); it++)
1295  {
1296  CallTxTrace(it->second, it->first, this, interface);
1297  outInterface->Send(it->first, it->second, route->GetGateway());
1298  }
1299  }
1300  else
1301  {
1302  CallTxTrace(ipHeader, packet, this, interface);
1303  outInterface->Send(packet, ipHeader, route->GetGateway());
1304  }
1305  }
1306  else
1307  {
1308  NS_LOG_LOGIC("Dropping-- outgoing interface is down: " << route->GetGateway());
1309  m_dropTrace(ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
1310  }
1311  }
1312  else
1313  {
1314  if (outInterface->IsUp())
1315  {
1316  NS_LOG_LOGIC("Send to destination " << ipHeader.GetDestination());
1317 
1318  if (!fragments.empty())
1319  {
1320  std::ostringstream oss;
1321 
1322  for (auto it = fragments.begin(); it != fragments.end(); it++)
1323  {
1324  CallTxTrace(it->second, it->first, this, interface);
1325  outInterface->Send(it->first, it->second, ipHeader.GetDestination());
1326  }
1327  }
1328  else
1329  {
1330  CallTxTrace(ipHeader, packet, this, interface);
1331  outInterface->Send(packet, ipHeader, ipHeader.GetDestination());
1332  }
1333  }
1334  else
1335  {
1336  NS_LOG_LOGIC("Dropping-- outgoing interface is down: " << ipHeader.GetDestination());
1337  m_dropTrace(ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
1338  }
1339  }
1340 }
1341 
1342 void
1344  Ptr<Ipv6Route> rtentry,
1346  const Ipv6Header& header)
1347 {
1348  NS_LOG_FUNCTION(this << rtentry << p << header);
1349  NS_LOG_LOGIC("Forwarding logic for node: " << m_node->GetId());
1350 
1351  // Drop RFC 3849 packets: 2001:db8::/32
1352  if (header.GetDestination().IsDocumentation())
1353  {
1354  NS_LOG_WARN("Received a packet for 2001:db8::/32 (documentation class). Drop.");
1355  m_dropTrace(header, p, DROP_ROUTE_ERROR, this, 0);
1356  return;
1357  }
1358 
1359  // Forwarding
1360  Ipv6Header ipHeader = header;
1361  Ptr<Packet> packet = p->Copy();
1362  ipHeader.SetHopLimit(ipHeader.GetHopLimit() - 1);
1363 
1364  if (ipHeader.GetSource().IsLinkLocal())
1365  {
1366  /* no forward for link-local address */
1367  return;
1368  }
1369 
1370  if (ipHeader.GetHopLimit() == 0)
1371  {
1372  NS_LOG_WARN("TTL exceeded. Drop.");
1373  m_dropTrace(ipHeader, packet, DROP_TTL_EXPIRED, this, 0);
1374  // Do not reply to multicast IPv6 address
1375  if (!ipHeader.GetDestination().IsMulticast())
1376  {
1377  packet->AddHeader(ipHeader);
1378  GetIcmpv6()->SendErrorTimeExceeded(packet,
1379  ipHeader.GetSource(),
1381  }
1382  return;
1383  }
1384 
1385  /* ICMPv6 Redirect */
1386 
1387  /* if we forward to a machine on the same network as the source,
1388  * we send him an ICMPv6 redirect message to notify him that a short route
1389  * exists.
1390  */
1391 
1392  /* Theoretically we should also check if the redirect target is on the same network
1393  * as the source node. On the other hand, we are sure that the router we're redirecting to
1394  * used a link-local address. As a consequence, they MUST be on the same network, the link-local
1395  * net.
1396  */
1397 
1398  if (m_sendIcmpv6Redirect && (rtentry->GetOutputDevice() == idev))
1399  {
1400  NS_LOG_LOGIC("ICMPv6 redirect!");
1401  Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6();
1402  Address hardwareTarget;
1403  Ipv6Address dst = header.GetDestination();
1404  Ipv6Address src = header.GetSource();
1405  Ipv6Address target = rtentry->GetGateway();
1406  Ptr<Packet> copy = p->Copy();
1407 
1408  if (target.IsAny())
1409  {
1410  target = dst;
1411  }
1412 
1413  copy->AddHeader(header);
1414  Ipv6Address linkLocal = GetInterface(GetInterfaceForDevice(rtentry->GetOutputDevice()))
1416  .GetAddress();
1417 
1418  if (icmpv6->Lookup(target, rtentry->GetOutputDevice(), nullptr, &hardwareTarget))
1419  {
1420  icmpv6->SendRedirection(copy, linkLocal, src, target, dst, hardwareTarget);
1421  }
1422  else
1423  {
1424  icmpv6->SendRedirection(copy, linkLocal, src, target, dst, Address());
1425  }
1426  }
1427  // in case the packet still has a priority tag attached, remove it
1428  SocketPriorityTag priorityTag;
1429  packet->RemovePacketTag(priorityTag);
1430  int32_t interface = GetInterfaceForDevice(rtentry->GetOutputDevice());
1431  m_unicastForwardTrace(ipHeader, packet, interface);
1432  SendRealOut(rtentry, packet, ipHeader);
1433 }
1434 
1435 void
1437  Ptr<Ipv6MulticastRoute> mrtentry,
1439  const Ipv6Header& header)
1440 {
1441  NS_LOG_FUNCTION(this << mrtentry << p << header);
1442  NS_LOG_LOGIC("Multicast forwarding logic for node: " << m_node->GetId());
1443 
1444  std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap();
1445 
1446  for (auto mapIter = ttlMap.begin(); mapIter != ttlMap.end(); mapIter++)
1447  {
1448  uint32_t interfaceId = mapIter->first;
1449  // uint32_t outputTtl = mapIter->second; // Unused for now
1450  Ptr<Packet> packet = p->Copy();
1451  Ipv6Header h = header;
1452  h.SetHopLimit(header.GetHopLimit() - 1);
1453  if (h.GetHopLimit() == 0)
1454  {
1455  NS_LOG_WARN("TTL exceeded. Drop.");
1456  m_dropTrace(header, packet, DROP_TTL_EXPIRED, this, interfaceId);
1457  return;
1458  }
1459  NS_LOG_LOGIC("Forward multicast via interface " << interfaceId);
1460  Ptr<Ipv6Route> rtentry = Create<Ipv6Route>();
1461  rtentry->SetSource(h.GetSource());
1462  rtentry->SetDestination(h.GetDestination());
1463  rtentry->SetGateway(Ipv6Address::GetAny());
1464  rtentry->SetOutputDevice(GetNetDevice(interfaceId));
1465  SendRealOut(rtentry, packet, h);
1466  }
1467 }
1468 
1469 void
1471 {
1472  NS_LOG_FUNCTION(this << packet << ip << iif);
1473  Ptr<Packet> p = packet->Copy();
1474  Ptr<IpL4Protocol> protocol = nullptr;
1476  Ptr<Ipv6Extension> ipv6Extension = nullptr;
1477  Ipv6Address src = ip.GetSource();
1478  Ipv6Address dst = ip.GetDestination();
1479  uint8_t nextHeader = ip.GetNextHeader();
1480  uint8_t nextHeaderPosition = 0;
1481  bool isDropped = false;
1482  bool stopProcessing = false;
1483  DropReason dropReason;
1484 
1485  // check for a malformed hop-by-hop extension
1486  // this is a common case when forging IPv6 raw packets
1487  if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1488  {
1489  uint8_t buf;
1490  p->CopyData(&buf, 1);
1492  {
1493  NS_LOG_WARN("Double Ipv6Header::IPV6_EXT_HOP_BY_HOP in packet, dropping packet");
1494  return;
1495  }
1496  }
1497 
1498  /* process all the extensions found and the layer 4 protocol */
1499  do
1500  {
1501  /* it return 0 for non-extension (i.e. layer 4 protocol) */
1502  ipv6Extension = ipv6ExtensionDemux->GetExtension(nextHeader);
1503 
1504  if (ipv6Extension)
1505  {
1506  uint8_t nextHeaderStep = 0;
1507  uint8_t curHeader = nextHeader;
1508  nextHeaderStep = ipv6Extension->Process(p,
1509  nextHeaderPosition,
1510  ip,
1511  dst,
1512  &nextHeader,
1513  stopProcessing,
1514  isDropped,
1515  dropReason);
1516  nextHeaderPosition += nextHeaderStep;
1517 
1518  if (isDropped)
1519  {
1520  m_dropTrace(ip, packet, dropReason, this, iif);
1521  }
1522 
1523  if (stopProcessing)
1524  {
1525  return;
1526  }
1527  NS_ASSERT_MSG(nextHeaderStep != 0 || curHeader == Ipv6Header::IPV6_EXT_FRAGMENTATION,
1528  "Zero-size IPv6 Option Header, aborting" << *packet);
1529  }
1530  else
1531  {
1532  protocol = GetProtocol(nextHeader, iif);
1533 
1534  if (!protocol)
1535  {
1536  NS_LOG_LOGIC("Unknown Next Header. Drop!");
1537 
1538  // For ICMPv6 Error packets
1539  Ptr<Packet> malformedPacket = packet->Copy();
1540  malformedPacket->AddHeader(ip);
1541 
1542  if (nextHeaderPosition == 0)
1543  {
1544  GetIcmpv6()->SendErrorParameterError(malformedPacket,
1545  dst,
1547  40);
1548  }
1549  else
1550  {
1551  GetIcmpv6()->SendErrorParameterError(malformedPacket,
1552  dst,
1554  ip.GetSerializedSize() +
1555  nextHeaderPosition);
1556  }
1557  m_dropTrace(ip, p, DROP_UNKNOWN_PROTOCOL, this, iif);
1558  break;
1559  }
1560  else
1561  {
1562  p->RemoveAtStart(nextHeaderPosition);
1563  /* protocol->Receive (p, src, dst, incomingInterface); */
1564 
1565  /* L4 protocol */
1566  Ptr<Packet> copy = p->Copy();
1567 
1568  m_localDeliverTrace(ip, p, iif);
1569 
1570  IpL4Protocol::RxStatus status = protocol->Receive(p, ip, GetInterface(iif));
1571 
1572  switch (status)
1573  {
1574  case IpL4Protocol::RX_OK:
1575  break;
1577  break;
1579  break;
1581  if (ip.GetDestination().IsMulticast())
1582  {
1583  /* do not rely on multicast address */
1584  break;
1585  }
1586 
1587  copy->AddHeader(ip);
1588  GetIcmpv6()->SendErrorDestinationUnreachable(
1589  copy,
1590  ip.GetSource(),
1592  }
1593  }
1594  }
1595  } while (ipv6Extension);
1596 }
1597 
1598 void
1600  const Ipv6Header& ipHeader,
1601  Socket::SocketErrno sockErrno)
1602 {
1603  NS_LOG_FUNCTION(this << p << ipHeader << sockErrno);
1604  NS_LOG_LOGIC("Route input failure-- dropping packet to " << ipHeader << " with errno "
1605  << sockErrno);
1606 
1607  m_dropTrace(ipHeader, p, DROP_ROUTE_ERROR, this, 0);
1608 
1609  if (!ipHeader.GetDestination().IsMulticast())
1610  {
1611  Ptr<Packet> packet = p->Copy();
1612  packet->AddHeader(ipHeader);
1613  GetIcmpv6()->SendErrorDestinationUnreachable(packet,
1614  ipHeader.GetSource(),
1616  }
1617 }
1618 
1619 Ipv6Header
1621  Ipv6Address dst,
1622  uint8_t protocol,
1623  uint16_t payloadSize,
1624  uint8_t ttl,
1625  uint8_t tclass)
1626 {
1627  NS_LOG_FUNCTION(this << src << dst << (uint32_t)protocol << (uint32_t)payloadSize
1628  << (uint32_t)ttl << (uint32_t)tclass);
1629  Ipv6Header hdr;
1630 
1631  hdr.SetSource(src);
1632  hdr.SetDestination(dst);
1633  hdr.SetNextHeader(protocol);
1634  hdr.SetPayloadLength(payloadSize);
1635  hdr.SetHopLimit(ttl);
1636  hdr.SetTrafficClass(tclass);
1637  return hdr;
1638 }
1639 
1640 void
1642 {
1644  {
1645  return;
1646  }
1647  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = CreateObject<Ipv6ExtensionDemux>();
1648  ipv6ExtensionDemux->SetNode(m_node);
1649 
1650  Ptr<Ipv6ExtensionHopByHop> hopbyhopExtension = CreateObject<Ipv6ExtensionHopByHop>();
1651  hopbyhopExtension->SetNode(m_node);
1652  Ptr<Ipv6ExtensionDestination> destinationExtension = CreateObject<Ipv6ExtensionDestination>();
1653  destinationExtension->SetNode(m_node);
1654  Ptr<Ipv6ExtensionFragment> fragmentExtension = CreateObject<Ipv6ExtensionFragment>();
1655  fragmentExtension->SetNode(m_node);
1656  Ptr<Ipv6ExtensionRouting> routingExtension = CreateObject<Ipv6ExtensionRouting>();
1657  routingExtension->SetNode(m_node);
1658  // Ptr<Ipv6ExtensionESP> espExtension = CreateObject<Ipv6ExtensionESP> ();
1659  // Ptr<Ipv6ExtensionAH> ahExtension = CreateObject<Ipv6ExtensionAH> ();
1660 
1661  ipv6ExtensionDemux->Insert(hopbyhopExtension);
1662  ipv6ExtensionDemux->Insert(destinationExtension);
1663  ipv6ExtensionDemux->Insert(fragmentExtension);
1664  ipv6ExtensionDemux->Insert(routingExtension);
1665  // ipv6ExtensionDemux->Insert (espExtension);
1666  // ipv6ExtensionDemux->Insert (ahExtension);
1667 
1668  Ptr<Ipv6ExtensionRoutingDemux> routingExtensionDemux =
1669  CreateObject<Ipv6ExtensionRoutingDemux>();
1670  routingExtensionDemux->SetNode(m_node);
1671  Ptr<Ipv6ExtensionLooseRouting> looseRoutingExtension =
1672  CreateObject<Ipv6ExtensionLooseRouting>();
1673  looseRoutingExtension->SetNode(m_node);
1674  routingExtensionDemux->Insert(looseRoutingExtension);
1675 
1676  m_node->AggregateObject(routingExtensionDemux);
1677  m_node->AggregateObject(ipv6ExtensionDemux);
1678 }
1679 
1680 void
1682 {
1684  {
1685  return;
1686  }
1687  Ptr<Ipv6OptionDemux> ipv6OptionDemux = CreateObject<Ipv6OptionDemux>();
1688  ipv6OptionDemux->SetNode(m_node);
1689 
1690  Ptr<Ipv6OptionPad1> pad1Option = CreateObject<Ipv6OptionPad1>();
1691  pad1Option->SetNode(m_node);
1692  Ptr<Ipv6OptionPadn> padnOption = CreateObject<Ipv6OptionPadn>();
1693  padnOption->SetNode(m_node);
1694  Ptr<Ipv6OptionJumbogram> jumbogramOption = CreateObject<Ipv6OptionJumbogram>();
1695  jumbogramOption->SetNode(m_node);
1696  Ptr<Ipv6OptionRouterAlert> routerAlertOption = CreateObject<Ipv6OptionRouterAlert>();
1697  routerAlertOption->SetNode(m_node);
1698 
1699  ipv6OptionDemux->Insert(pad1Option);
1700  ipv6OptionDemux->Insert(padnOption);
1701  ipv6OptionDemux->Insert(jumbogramOption);
1702  ipv6OptionDemux->Insert(routerAlertOption);
1703 
1704  m_node->AggregateObject(ipv6OptionDemux);
1705 }
1706 
1707 void
1709 {
1710  m_dropTrace(ipHeader, p, dropReason, this, 0);
1711 }
1712 
1713 void
1715 {
1716  NS_LOG_FUNCTION(address << interface);
1717 
1718  if (!address.IsMulticast())
1719  {
1720  NS_LOG_WARN("Not adding a non-multicast address " << address);
1721  return;
1722  }
1723 
1724  Ipv6RegisteredMulticastAddressKey_t key = std::make_pair(address, interface);
1725  m_multicastAddresses[key]++;
1726 }
1727 
1728 void
1730 {
1732 
1733  if (!address.IsMulticast())
1734  {
1735  NS_LOG_WARN("Not adding a non-multicast address " << address);
1736  return;
1737  }
1738 
1740 }
1741 
1742 void
1744 {
1745  NS_LOG_FUNCTION(address << interface);
1746 
1747  Ipv6RegisteredMulticastAddressKey_t key = std::make_pair(address, interface);
1748 
1749  m_multicastAddresses[key]--;
1750  if (m_multicastAddresses[key] == 0)
1751  {
1752  m_multicastAddresses.erase(key);
1753  }
1754 }
1755 
1756 void
1758 {
1760 
1763  {
1765  }
1766 }
1767 
1768 bool
1770 {
1771  NS_LOG_FUNCTION(address << interface);
1772 
1773  Ipv6RegisteredMulticastAddressKey_t key = std::make_pair(address, interface);
1774  auto iter = m_multicastAddresses.find(key);
1775 
1776  return iter != m_multicastAddresses.end();
1777 }
1778 
1779 bool
1781 {
1783 
1784  auto iter = m_multicastAddressesNoInterface.find(address);
1785 
1786  return iter != m_multicastAddressesNoInterface.end();
1787 }
1788 
1789 bool
1791 {
1792  if (ipInterfaceIndex >= m_interfaces.size())
1793  {
1794  return false;
1795  }
1796 
1797  Ptr<NdiscCache> ndiscCache = m_interfaces[ipInterfaceIndex]->GetNdiscCache();
1798  if (!ndiscCache)
1799  {
1800  return false;
1801  }
1802 
1803  NdiscCache::Entry* entry = ndiscCache->Lookup(address);
1804  if (!entry || entry->IsIncomplete())
1805  {
1806  return false;
1807  }
1808 
1809  if (entry->IsReachable())
1810  {
1811  entry->UpdateReachableTimer();
1812  }
1813  else if (entry->IsPermanent() || entry->IsAutoGenerated())
1814  {
1815  return true;
1816  }
1817  else if (entry->IsProbe())
1818  {
1819  // we just confirm the entry's MAC address to get the waiting packets (if any)
1820  std::list<NdiscCache::Ipv6PayloadHeaderPair> waiting =
1821  entry->MarkReachable(entry->GetMacAddress());
1822  for (auto it = waiting.begin(); it != waiting.end(); it++)
1823  {
1824  ndiscCache->GetInterface()->Send(it->first, it->second, it->second.GetSource());
1825  }
1826  entry->ClearWaitingPacket();
1827  entry->StartReachableTimer();
1828  }
1829  else // STALE OR DELAY
1830  {
1831  entry->MarkReachable();
1832  entry->StartReachableTimer();
1833  }
1834 
1835  return true;
1836 }
1837 
1838 void
1840 {
1841  NS_LOG_FUNCTION(this << model);
1842  m_strongEndSystemModel = model;
1843 }
1844 
1845 bool
1847 {
1848  NS_LOG_FUNCTION(this);
1849  return m_strongEndSystemModel;
1850 }
1851 
1852 } /* namespace ns3 */
#define max(a, b)
Definition: 80211b.c:42
a polymophic address class
Definition: address.h:101
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:49
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:35
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.
Ipv6RoutingProtocol::MulticastForwardCallback m_mcb
Multicast forward callback.
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.
Ipv6RoutingProtocol::UnicastForwardCallback m_ucb
Unicast forward callback.
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 ?
void SetStrongEndSystemModel(bool model) override
Set or unset the Strong End System Model.
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.
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.
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.
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.
Ipv6RoutingProtocol::ErrorCallback m_ecb
Error callback.
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.
Ipv6RoutingProtocol::LocalDeliverCallback m_lcb
Local delivery callback.
std::pair< int, int32_t > L4ListKey_t
Container of the IPv6 L4 keys: protocol number, interface index.
bool GetStrongEndSystemModel() const override
Get the Strong End System Model status.
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.
IPv6 Option Demux.
Describes an IPv6 prefix.
Definition: ipv6-address.h:455
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:238
virtual void NotifyNewAggregate()
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:331
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:352
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:967
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:861
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:77
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:674
indicates whether the socket has IPV6_TCLASS set.
Definition: socket.h:1364
uint8_t GetTclass() const
Get the tag's Tclass.
Definition: socket.cc:916
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:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
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
#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:47
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
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:704
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 > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:449