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