A Discrete-Event Network Simulator
API
icmpv6-l4-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  * David Gross <gdavid.devel@gmail.com>
20  * Mehdi Benamor <benamor.mehdi@ensi.rnu.tn>
21  * Tommaso Pecorella <tommaso.pecorella@unifi.it>
22  */
23 
24 #include "ns3/log.h"
25 #include "ns3/assert.h"
26 #include "ns3/packet.h"
27 #include "ns3/node.h"
28 #include "ns3/boolean.h"
29 #include "ns3/ipv6-routing-protocol.h"
30 #include "ns3/ipv6-route.h"
31 #include "ns3/pointer.h"
32 #include "ns3/string.h"
33 
35 #include "ipv6-l3-protocol.h"
36 #include "ipv6-interface.h"
37 #include "icmpv6-l4-protocol.h"
38 
39 namespace ns3 {
40 
41 NS_LOG_COMPONENT_DEFINE ("Icmpv6L4Protocol");
42 
43 NS_OBJECT_ENSURE_REGISTERED (Icmpv6L4Protocol);
44 
45 const uint8_t Icmpv6L4Protocol::PROT_NUMBER = 58;
46 
51 const uint32_t Icmpv6L4Protocol::MAX_RA_DELAY_TIME = 500; /* millisecond */
52 
56 
61 const uint32_t Icmpv6L4Protocol::REACHABLE_TIME = 30000;
62 const uint32_t Icmpv6L4Protocol::RETRANS_TIMER = 1000;
64 const double Icmpv6L4Protocol::MIN_RANDOM_FACTOR = 0.5;
65 const double Icmpv6L4Protocol::MAX_RANDOM_FACTOR = 1.5;
66 
68 {
69  static TypeId tid = TypeId ("ns3::Icmpv6L4Protocol")
71  .SetGroupName ("Internet")
72  .AddConstructor<Icmpv6L4Protocol> ()
73  .AddAttribute ("DAD", "Always do DAD check.",
74  BooleanValue (true),
77  .AddAttribute ("SolicitationJitter", "The jitter in ms a node is allowed to wait before sending any solicitation . Some jitter aims to prevent collisions. By default, the model will wait for a duration in ms defined by a uniform random-variable between 0 and SolicitationJitter",
78  StringValue ("ns3::UniformRandomVariable[Min=0.0|Max=10.0]"),
80  MakePointerChecker<RandomVariableStream> ())
81 
82  ;
83  return tid;
84 }
85 
87  : m_node (0)
88 {
89  NS_LOG_FUNCTION (this);
90 }
91 
93 {
94  NS_LOG_FUNCTION (this);
95 }
96 
98 {
99  NS_LOG_FUNCTION (this);
100  for (CacheList::const_iterator it = m_cacheList.begin (); it != m_cacheList.end (); it++)
101  {
102  Ptr<NdiscCache> cache = *it;
103  cache->Dispose ();
104  cache = 0;
105  }
106  m_cacheList.clear ();
108 
109  m_node = 0;
111 }
112 
113 int64_t Icmpv6L4Protocol::AssignStreams (int64_t stream)
114 {
115  NS_LOG_FUNCTION (this << stream);
117  return 1;
118 }
119 
121 {
122  NS_LOG_FUNCTION (this);
123  if (m_node == 0)
124  {
125  Ptr<Node> node = this->GetObject<Node> ();
126  if (node != 0)
127  {
128  Ptr<Ipv6> ipv6 = this->GetObject<Ipv6> ();
129  if (ipv6 != 0 && m_downTarget.IsNull ())
130  {
131  SetNode (node);
132  ipv6->Insert (this);
133  Ptr<Ipv6RawSocketFactoryImpl> rawFactory = CreateObject<Ipv6RawSocketFactoryImpl> ();
134  ipv6->AggregateObject (rawFactory);
136  }
137  }
138  }
140 }
141 
143 {
144  NS_LOG_FUNCTION (this << node);
145  m_node = node;
146 }
147 
149 {
151  return PROT_NUMBER;
152 }
153 
155 {
156  NS_LOG_FUNCTION (this);
157  return PROT_NUMBER;
158 }
159 
161 {
162  NS_LOG_FUNCTION (this);
163  return 1;
164 }
165 
167 {
168  NS_LOG_FUNCTION (this);
169  return m_alwaysDad;
170 }
171 
173 {
174  NS_LOG_FUNCTION (this << target << interface);
175  Ipv6Address addr;
177 
178  NS_ASSERT (ipv6);
179 
180  if (!m_alwaysDad)
181  {
182  return;
183  }
184 
187  NdiscCache::Ipv6PayloadHeaderPair p = ForgeNS ("::",Ipv6Address::MakeSolicitedAddress (target), target, interface->GetDevice ()->GetAddress ());
188 
189  /* update last packet UID */
190  interface->SetNsDadUid (target, p.first->GetUid ());
192 }
193 
195 {
196  NS_LOG_FUNCTION (this << packet << header);
198 }
199 
201 {
202  NS_LOG_FUNCTION (this << packet << header.GetSourceAddress () << header.GetDestinationAddress () << interface);
203  Ptr<Packet> p = packet->Copy ();
204  Ptr<Ipv6> ipv6 = m_node->GetObject<Ipv6> ();
205 
206  /* very ugly! try to find something better in the future */
207  uint8_t type;
208  p->CopyData (&type, sizeof(type));
209 
210  switch (type)
211  {
213  if (ipv6->IsForwarding (ipv6->GetInterfaceForDevice (interface->GetDevice ())))
214  {
215  HandleRS (p, header.GetSourceAddress (), header.GetDestinationAddress (), interface);
216  }
217  break;
219  if (!ipv6->IsForwarding (ipv6->GetInterfaceForDevice (interface->GetDevice ())))
220  {
221  HandleRA (p, header.GetSourceAddress (), header.GetDestinationAddress (), interface);
222  }
223  break;
225  HandleNS (p, header.GetSourceAddress (), header.GetDestinationAddress (), interface);
226  break;
228  HandleNA (p, header.GetSourceAddress (), header.GetDestinationAddress (), interface);
229  break;
231  HandleRedirection (p, header.GetSourceAddress (), header.GetDestinationAddress (), interface);
232  break;
234  HandleEchoRequest (p, header.GetSourceAddress (), header.GetDestinationAddress (), interface);
235  break;
237  // EchoReply does not contain any info about L4
238  // so we can not forward it up.
240  break;
242  HandleDestinationUnreachable (p, header.GetSourceAddress (), header.GetDestinationAddress (), interface);
243  break;
245  HandlePacketTooBig (p, header.GetSourceAddress (), header.GetDestinationAddress (), interface);
246  break;
248  HandleTimeExceeded (p, header.GetSourceAddress (), header.GetDestinationAddress (), interface);
249  break;
251  HandleParameterError (p, header.GetSourceAddress (), header.GetDestinationAddress (), interface);
252  break;
253  default:
254  NS_LOG_LOGIC ("Unknown ICMPv6 message type=" << type);
255  break;
256  }
257 
258  return IpL4Protocol::RX_OK;
259 }
260 
262  uint32_t info, Ipv6Header ipHeader,
263  const uint8_t payload[8])
264 {
265  NS_LOG_FUNCTION (this << source << icmp << info << ipHeader << payload);
266 
268 
270 
271  uint8_t nextHeader = ipHeader.GetNextHeader ();
272 
273  if (nextHeader != Icmpv6L4Protocol::PROT_NUMBER)
274  {
275  Ptr<IpL4Protocol> l4 = ipv6->GetProtocol (nextHeader);
276  if (l4 != 0)
277  {
278  l4->ReceiveIcmp (source, ipHeader.GetHopLimit (), icmp.GetType (), icmp.GetCode (),
279  info, ipHeader.GetSourceAddress (), ipHeader.GetDestinationAddress (), payload);
280  }
281  }
282 }
283 
285 {
286  NS_LOG_FUNCTION (this << packet << src << dst << interface);
287  Icmpv6Echo request;
288  uint8_t* buf = new uint8_t[packet->GetSize ()];
289 
290  packet->RemoveHeader (request);
291  /* XXX IPv6 extension: obtain a fresh copy of data otherwise it crash... */
292  packet->CopyData (buf, packet->GetSize ());
293  Ptr<Packet> p = Create<Packet> (buf, packet->GetSize ());
294 
295  /* if we send message from ff02::* (link-local multicast), we use our link-local address */
296  SendEchoReply (dst.IsMulticast () ? interface->GetLinkLocalAddress ().GetAddress () : dst, src, request.GetId (), request.GetSeq (), p);
297  delete[] buf;
298 }
299 
300 void Icmpv6L4Protocol::HandleRA (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
301 {
302  NS_LOG_FUNCTION (this << packet << src << dst << interface);
303  Ptr<Packet> p = packet->Copy ();
304  Icmpv6RA raHeader;
307  Icmpv6OptionMtu mtuHdr;
309  bool next = true;
310  bool hasLla = false;
311  bool hasMtu = false;
312  Ipv6Address defaultRouter = Ipv6Address::GetZero ();
313 
314  p->RemoveHeader (raHeader);
315 
316  if (raHeader.GetLifeTime())
317  {
318  defaultRouter = src;
319  }
320 
321  while (next == true)
322  {
323  uint8_t type = 0;
324  p->CopyData (&type, sizeof(type));
325 
326  switch (type)
327  {
329  p->RemoveHeader (prefixHdr);
330  ipv6->AddAutoconfiguredAddress (ipv6->GetInterfaceForDevice (interface->GetDevice ()), prefixHdr.GetPrefix (), prefixHdr.GetPrefixLength (),
331  prefixHdr.GetFlags (), prefixHdr.GetValidTime (), prefixHdr.GetPreferredTime (), defaultRouter);
332  break;
334  /* take in account the first MTU option */
335  if (!hasMtu)
336  {
337  p->RemoveHeader (mtuHdr);
338  hasMtu = true;
340  /* interface->GetDevice ()->SetMtu (m.GetMtu ()); */
341  }
342  break;
344  /* take in account the first LLA option */
345  if (!hasLla)
346  {
347  p->RemoveHeader (llaHdr);
348  ReceiveLLA (llaHdr, src, dst, interface);
349  hasLla = true;
350  }
351  break;
352  default:
353  /* unknow option, quit */
354  next = false;
355  }
356  }
357 }
358 
360 {
361  NS_LOG_FUNCTION (this << lla << src << dst << interface);
362  Address hardwareAddress;
363  NdiscCache::Entry* entry = 0;
364  Ptr<NdiscCache> cache = FindCache (interface->GetDevice ());
365 
366  /* check if we have this address in our cache */
367  entry = cache->Lookup (src);
368 
369  if (!entry)
370  {
371  entry = cache->Add (src);
372  entry->SetRouter (true);
373  entry->SetMacAddress (lla.GetAddress ());
374  entry->MarkReachable ();
375  entry->StartReachableTimer ();
376  }
377  else
378  {
379  std::list<NdiscCache::Ipv6PayloadHeaderPair> waiting;
380  if (entry->IsIncomplete ())
381  {
382  entry->StopNudTimer ();
383  // mark it to reachable
384  waiting = entry->MarkReachable (lla.GetAddress ());
385  entry->StartReachableTimer ();
386  // send out waiting packet
387  for (std::list<NdiscCache::Ipv6PayloadHeaderPair>::const_iterator it = waiting.begin (); it != waiting.end (); it++)
388  {
389  cache->GetInterface ()->Send (it->first, it->second, src);
390  }
391  entry->ClearWaitingPacket ();
392  }
393  else
394  {
395  if (entry->GetMacAddress () != lla.GetAddress ())
396  {
397  entry->SetMacAddress (lla.GetAddress ());
398  entry->MarkStale ();
399  entry->SetRouter (true);
400  }
401  else
402  {
403  if (!entry->IsReachable () || !entry->IsPermanent ())
404  {
405  entry->StopNudTimer ();
406  waiting = entry->MarkReachable (lla.GetAddress ());
407  if (entry->IsProbe ())
408  {
409  for (std::list<NdiscCache::Ipv6PayloadHeaderPair>::const_iterator it = waiting.begin (); it != waiting.end (); it++)
410  {
411  cache->GetInterface ()->Send (it->first, it->second, src);
412  }
413  }
414  if (!entry->IsPermanent ())
415  {
416  entry->StartReachableTimer ();
417  }
418  }
419  }
420  }
421  }
422 }
423 
424 void Icmpv6L4Protocol::HandleRS (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
425 {
426  NS_LOG_FUNCTION (this << packet << src << dst << interface);
428  Icmpv6RS rsHeader;
429  packet->RemoveHeader (rsHeader);
430  Address hardwareAddress;
432  NdiscCache::Entry* entry = 0;
433  Ptr<NdiscCache> cache = FindCache (interface->GetDevice ());
434 
435  if (src != Ipv6Address::GetAny ())
436  {
437  /* XXX search all options following the RS header */
438  /* test if the next option is SourceLinkLayerAddress */
439  uint8_t type;
440  packet->CopyData (&type, sizeof(type));
441 
443  {
444  return;
445  }
446  packet->RemoveHeader (lla);
447  NS_LOG_LOGIC ("Cache updated by RS");
448 
449  entry = cache->Lookup (src);
450  if (!entry)
451  {
452  entry = cache->Add (src);
453  entry->SetRouter (false);
454  entry->MarkStale (lla.GetAddress ());
455  }
456  else if (entry->GetMacAddress () != lla.GetAddress ())
457  {
458  entry->MarkStale (lla.GetAddress ());
459  }
460  }
461 }
462 
463 void Icmpv6L4Protocol::HandleNS (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
464 {
465  NS_LOG_FUNCTION (this << packet << src << dst << interface);
466  Icmpv6NS nsHeader ("::");
467  Ipv6InterfaceAddress ifaddr;
468  uint32_t nb = interface->GetNAddresses ();
469  uint32_t i = 0;
470  bool found = false;
471 
472  packet->RemoveHeader (nsHeader);
473 
474  Ipv6Address target = nsHeader.GetIpv6Target ();
475 
476  for (i = 0; i < nb; i++)
477  {
478  ifaddr = interface->GetAddress (i);
479 
480  if (ifaddr.GetAddress () == target)
481  {
482  found = true;
483  break;
484  }
485  }
486 
487  if (!found)
488  {
489  NS_LOG_LOGIC ("Not a NS for us");
490  return;
491  }
492 
493  if (packet->GetUid () == ifaddr.GetNsDadUid ())
494  {
495  /* don't process our own DAD probe */
496  NS_LOG_LOGIC ("Hey we receive our DAD probe!");
497  return;
498  }
499 
501  Address hardwareAddress;
502  NdiscCache::Entry* entry = 0;
503  Ptr<NdiscCache> cache = FindCache (interface->GetDevice ());
504  uint8_t flags = 0;
505 
506  /* XXX search all options following the NS header */
507 
508  if (src != Ipv6Address::GetAny ())
509  {
510  uint8_t type;
511  packet->CopyData (&type, sizeof(type));
512 
514  {
515  return;
516  }
517 
518  /* Get LLA */
519  packet->RemoveHeader (lla);
520 
521  entry = cache->Lookup (src);
522  if (!entry)
523  {
524  entry = cache->Add (src);
525  entry->SetRouter (false);
526  entry->MarkStale (lla.GetAddress ());
527  }
528  else if (entry->GetMacAddress () != lla.GetAddress ())
529  {
530  entry->MarkStale (lla.GetAddress ());
531  }
532 
533  flags = 3; /* S + O flags */
534  }
535  else
536  {
537  /* it means someone do a DAD */
538  flags = 1; /* O flag */
539  }
540 
541  /* send a NA to src */
543 
544  if (ipv6->IsForwarding (ipv6->GetInterfaceForDevice (interface->GetDevice ())))
545  {
546  flags += 4; /* R flag */
547  }
548 
549  hardwareAddress = interface->GetDevice ()->GetAddress ();
550  NdiscCache::Ipv6PayloadHeaderPair p = ForgeNA (target.IsLinkLocal () ? interface->GetLinkLocalAddress ().GetAddress () : ifaddr.GetAddress (), src.IsAny () ? Ipv6Address::GetAllNodesMulticast () : src, &hardwareAddress, flags );
551  interface->Send (p.first, p.second, src.IsAny () ? Ipv6Address::GetAllNodesMulticast () : src);
552 
553  /* not a NS for us discard it */
554 }
555 
557 {
558  NS_LOG_FUNCTION (this << src << dst << hardwareAddress);
559  Ptr<Packet> p = Create<Packet> ();
560  Ipv6Header ipHeader;
561  Icmpv6RS rs;
562  Icmpv6OptionLinkLayerAddress llOption (1, hardwareAddress); /* we give our mac address in response */
563 
564  NS_LOG_LOGIC ("Send RS ( from " << src << " to " << dst << ")");
565  p->AddHeader (llOption);
566 
568  p->AddHeader (rs);
569 
570  ipHeader.SetSourceAddress (src);
571  ipHeader.SetDestinationAddress (dst);
572  ipHeader.SetNextHeader (PROT_NUMBER);
573  ipHeader.SetPayloadLength (p->GetSize ());
574  ipHeader.SetHopLimit (255);
575 
576  return NdiscCache::Ipv6PayloadHeaderPair (p, ipHeader);
577 }
578 
580 {
581  NS_LOG_FUNCTION (this << src << dst << id << seq << data);
582  Ptr<Packet> p = data->Copy ();
583  Ipv6Header ipHeader;
584  Icmpv6Echo req (1);
585 
586  req.SetId (id);
587  req.SetSeq (seq);
588 
589  req.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + req.GetSerializedSize (), PROT_NUMBER);
590  p->AddHeader (req);
591 
592  ipHeader.SetSourceAddress (src);
593  ipHeader.SetDestinationAddress (dst);
594  ipHeader.SetNextHeader (PROT_NUMBER);
595  ipHeader.SetPayloadLength (p->GetSize ());
596  ipHeader.SetHopLimit (255);
597 
598  return NdiscCache::Ipv6PayloadHeaderPair (p, ipHeader);
599 }
600 
601 void Icmpv6L4Protocol::HandleNA (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
602 {
603  NS_LOG_FUNCTION (this << packet << src << dst << interface);
604  Icmpv6NA naHeader;
606 
607  packet->RemoveHeader (naHeader);
608  Ipv6Address target = naHeader.GetIpv6Target ();
609 
610  Address hardwareAddress;
611  NdiscCache::Entry* entry = 0;
612  Ptr<NdiscCache> cache = FindCache (interface->GetDevice ());
613  std::list<NdiscCache::Ipv6PayloadHeaderPair> waiting;
614 
615  /* check if we have something in our cache */
616  entry = cache->Lookup (target);
617 
618  if (!entry)
619  {
620  /* ouch!! we might be victim of a DAD */
621 
622  Ipv6InterfaceAddress ifaddr;
623  bool found = false;
624  uint32_t i = 0;
625  uint32_t nb = interface->GetNAddresses ();
626 
627  for (i = 0; i < nb; i++)
628  {
629  ifaddr = interface->GetAddress (i);
630  if (ifaddr.GetAddress () == target)
631  {
632  found = true;
633  break;
634  }
635  }
636 
637  if (found)
638  {
640  {
641  interface->SetState (ifaddr.GetAddress (), Ipv6InterfaceAddress::INVALID);
642  }
643  }
644 
645  /* we have not initiated any communication with the target so... discard the NA */
646  return;
647  }
648 
649  /* XXX search all options following the NA header */
650  /* Get LLA */
651  uint8_t type;
652  packet->CopyData (&type, sizeof(type));
653 
655  {
656  return;
657  }
658  packet->RemoveHeader (lla);
659 
660  if (entry->IsIncomplete ())
661  {
662  /* we receive a NA so stop the retransmission timer */
663  entry->StopNudTimer ();
664 
665  if (naHeader.GetFlagS ())
666  {
667  /* mark it to reachable */
668  waiting = entry->MarkReachable (lla.GetAddress ());
669  entry->StartReachableTimer ();
670  /* send out waiting packet */
671  for (std::list<NdiscCache::Ipv6PayloadHeaderPair>::const_iterator it = waiting.begin (); it != waiting.end (); it++)
672  {
673  cache->GetInterface ()->Send (it->first, it->second, src);
674  }
675  entry->ClearWaitingPacket ();
676  }
677  else
678  {
679  entry->MarkStale (lla.GetAddress ());
680  }
681 
682  if (naHeader.GetFlagR ())
683  {
684  entry->SetRouter (true);
685  }
686  }
687  else
688  {
689  /* we receive a NA so stop the probe timer or delay timer if any */
690  entry->StopNudTimer ();
691 
692  /* if the Flag O is clear and mac address differs from the cache */
693  if (!naHeader.GetFlagO () && lla.GetAddress () != entry->GetMacAddress ())
694  {
695  if (entry->IsReachable ())
696  {
697  entry->MarkStale ();
698  }
699  return;
700  }
701  else
702  {
703  if ((!naHeader.GetFlagO () && lla.GetAddress () == entry->GetMacAddress ()) || naHeader.GetFlagO ()) /* XXX lake "no target link-layer address option supplied" */
704  {
705  entry->SetMacAddress (lla.GetAddress ());
706 
707  if (naHeader.GetFlagS ())
708  {
709  if (!entry->IsReachable () || !entry->IsPermanent ())
710  {
711  if (entry->IsProbe ())
712  {
713  waiting = entry->MarkReachable (lla.GetAddress ());
714  for (std::list<NdiscCache::Ipv6PayloadHeaderPair>::const_iterator it = waiting.begin (); it != waiting.end (); it++)
715  {
716  cache->GetInterface ()->Send (it->first, it->second, src);
717  }
718  entry->ClearWaitingPacket ();
719  }
720  else
721  {
722  entry->MarkReachable (lla.GetAddress ());
723  }
724  }
725  if (!entry->IsPermanent ())
726  {
727  entry->StartReachableTimer ();
728  }
729  }
730  else if (lla.GetAddress () != entry->GetMacAddress ())
731  {
732  entry->MarkStale ();
733  }
734  entry->SetRouter (naHeader.GetFlagR ());
735  }
736  }
737  }
738 }
739 
741 {
742  NS_LOG_FUNCTION (this << packet << src << dst << interface);
743  bool hasLla = false;
744  Ptr<Packet> p = packet->Copy ();
745  Icmpv6OptionLinkLayerAddress llOptionHeader (0);
746 
747  Icmpv6Redirection redirectionHeader;
748  p->RemoveHeader (redirectionHeader);
749 
750  /* little ugly try to find a better way */
751  uint8_t type;
752  p->CopyData (&type, sizeof(type));
754  {
755  hasLla = true;
756  p->RemoveHeader (llOptionHeader);
757  }
758 
759  Icmpv6OptionRedirected redirectedOptionHeader;
760  p->RemoveHeader (redirectedOptionHeader);
761 
762  Ipv6Address redirTarget = redirectionHeader.GetTarget ();
763  Ipv6Address redirDestination = redirectionHeader.GetDestination ();
764 
765  if (hasLla)
766  {
767  /* update the cache if needed */
768  NdiscCache::Entry* entry = 0;
769  Ptr<NdiscCache> cache = FindCache (interface->GetDevice ());
770 
771  entry = cache->Lookup (redirTarget);
772  if (!entry)
773  {
774  entry = cache->Add (redirTarget);
775  /* destination and target different => necessarily a router */
776  entry->SetRouter (!redirTarget.IsEqual (redirDestination) ? true : false);
777  entry->SetMacAddress (llOptionHeader.GetAddress ());
778  entry->MarkStale ();
779  }
780  else
781  {
782  if (entry->IsIncomplete () || entry->GetMacAddress () != llOptionHeader.GetAddress ())
783  {
784  /* update entry to STALE */
785  if (entry->GetMacAddress () != llOptionHeader.GetAddress ())
786  {
787  entry->SetMacAddress (llOptionHeader.GetAddress ());
788  entry->MarkStale ();
789  }
790  }
791  else
792  {
793  /* stay unchanged */
794  }
795  }
796  }
797 
798  /* add redirection in routing table */
799  Ptr<Ipv6> ipv6 = m_node->GetObject<Ipv6> ();
800 
801  if (redirTarget.IsEqual (redirDestination))
802  {
803  ipv6->GetRoutingProtocol ()->NotifyAddRoute (redirDestination, Ipv6Prefix (128), Ipv6Address ("::"), ipv6->GetInterfaceForAddress (dst));
804  }
805  else
806  {
807  uint32_t ifIndex = ipv6->GetInterfaceForAddress (dst);
808  ipv6->GetRoutingProtocol ()->NotifyAddRoute (redirDestination, Ipv6Prefix (128), redirTarget, ifIndex);
809  }
810 }
811 
813 {
814  NS_LOG_FUNCTION (this << *p << src << dst << interface);
815  Ptr<Packet> pkt = p->Copy ();
816 
818  pkt->RemoveHeader (unreach);
819  Ptr<Packet> origPkt = unreach.GetPacket ();
820 
821  Ipv6Header ipHeader;
822  if ( origPkt->GetSize () > ipHeader.GetSerializedSize () )
823  {
824  origPkt->RemoveHeader (ipHeader);
825  uint8_t payload[8];
826  origPkt->CopyData (payload, 8);
827  Forward (src, unreach, unreach.GetCode (), ipHeader, payload);
828  }
829 }
830 
832 {
833  NS_LOG_FUNCTION (this << *p << src << dst << interface);
834  Ptr<Packet> pkt = p->Copy ();
835 
836  Icmpv6TimeExceeded timeexceeded;
837  pkt->RemoveHeader (timeexceeded);
838  Ptr<Packet> origPkt = timeexceeded.GetPacket ();
839  Ipv6Header ipHeader;
840  uint8_t payload[8];
841  origPkt->RemoveHeader (ipHeader);
842  origPkt->CopyData (payload, 8);
843 
844  Forward (src, timeexceeded, timeexceeded.GetCode (), ipHeader, payload);
845 }
846 
848 {
849  NS_LOG_FUNCTION (this << *p << src << dst << interface);
850  Ptr<Packet> pkt = p->Copy ();
851 
852  Icmpv6TooBig tooBig;
853  pkt->RemoveHeader (tooBig);
854  Ptr<Packet> origPkt = tooBig.GetPacket ();
855 
856  Ipv6Header ipHeader;
857  origPkt->RemoveHeader (ipHeader);
858  uint8_t payload[8];
859  origPkt->CopyData (payload, 8);
860 
862  ipv6->SetPmtu(ipHeader.GetDestinationAddress(), tooBig.GetMtu ());
863 
864  Forward (src, tooBig, tooBig.GetMtu (), ipHeader, payload);
865 }
866 
868 {
869  NS_LOG_FUNCTION (this << *p << src << dst << interface);
870  Ptr<Packet> pkt = p->Copy ();
871 
872  Icmpv6ParameterError paramErr;
873  pkt->RemoveHeader (paramErr);
874  Ptr<Packet> origPkt = paramErr.GetPacket ();
875 
876  Ipv6Header ipHeader;
877  origPkt->RemoveHeader (ipHeader);
878  uint8_t payload[8];
879  origPkt->CopyData (payload, 8);
880  Forward (src, paramErr, paramErr.GetCode (), ipHeader, payload);
881 }
882 
884 {
885  NS_LOG_FUNCTION (this << packet << src << dst << (uint32_t)ttl);
887  SocketIpTtlTag tag;
888  NS_ASSERT (ipv6 != 0);
889 
890  tag.SetTtl (ttl);
891  packet->AddPacketTag (tag);
892  m_downTarget (packet, src, dst, PROT_NUMBER, 0);
893 }
894 
896 {
897  NS_LOG_FUNCTION (this << packet << src << dst << (uint32_t)ttl);
898  SendMessage (packet, src, dst, ttl);
899 }
900 
901 void Icmpv6L4Protocol::SendMessage (Ptr<Packet> packet, Ipv6Address dst, Icmpv6Header& icmpv6Hdr, uint8_t ttl)
902 {
903  NS_LOG_FUNCTION (this << packet << dst << icmpv6Hdr << (uint32_t)ttl);
905  NS_ASSERT (ipv6 != 0 && ipv6->GetRoutingProtocol () != 0);
906  Ipv6Header header;
907  SocketIpTtlTag tag;
909  Ptr<Ipv6Route> route;
910  Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
911 
912  header.SetDestinationAddress (dst);
913  route = ipv6->GetRoutingProtocol ()->RouteOutput (packet, header, oif, err);
914 
915  if (route != 0)
916  {
917  NS_LOG_LOGIC ("Route exists");
918  tag.SetTtl (ttl);
919  packet->AddPacketTag (tag);
920  Ipv6Address src = route->GetSource ();
921 
922  icmpv6Hdr.CalculatePseudoHeaderChecksum (src, dst, packet->GetSize () + icmpv6Hdr.GetSerializedSize (), PROT_NUMBER);
923  packet->AddHeader (icmpv6Hdr);
924  m_downTarget (packet, src, dst, PROT_NUMBER, route);
925  }
926  else
927  {
928  NS_LOG_WARN ("drop icmp message");
929  }
930 }
931 
932 void Icmpv6L4Protocol::SendNA (Ipv6Address src, Ipv6Address dst, Address* hardwareAddress, uint8_t flags)
933 {
934  NS_LOG_FUNCTION (this << src << dst << hardwareAddress << static_cast<uint32_t> (flags));
935  Ptr<Packet> p = Create<Packet> ();
936  Icmpv6NA na;
937  Icmpv6OptionLinkLayerAddress llOption (0, *hardwareAddress); /* not a source link layer */
938 
939  NS_LOG_LOGIC ("Send NA ( from " << src << " to " << dst << " target " << src << ")");
940  na.SetIpv6Target (src);
941 
942  if ((flags & 1))
943  {
944  na.SetFlagO (true);
945  }
946  if ((flags & 2) && src != Ipv6Address::GetAny ())
947  {
948  na.SetFlagS (true);
949  }
950  if ((flags & 4))
951  {
952  na.SetFlagR (true);
953  }
954 
955  p->AddHeader (llOption);
956  na.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + na.GetSerializedSize (), PROT_NUMBER);
957  p->AddHeader (na);
958 
959  SendMessage (p, src, dst, 255);
960 }
961 
962 void Icmpv6L4Protocol::SendEchoReply (Ipv6Address src, Ipv6Address dst, uint16_t id, uint16_t seq, Ptr<Packet> data)
963 {
964  NS_LOG_FUNCTION (this << src << dst << id << seq << data);
965  Ptr<Packet> p = data->Copy ();
966  Icmpv6Echo reply (0); /* echo reply */
967 
968  reply.SetId (id);
969  reply.SetSeq (seq);
970 
971  reply.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + reply.GetSerializedSize (), PROT_NUMBER);
972  p->AddHeader (reply);
973  SendMessage (p, src, dst, 64);
974 }
975 
976 void Icmpv6L4Protocol::SendNS (Ipv6Address src, Ipv6Address dst, Ipv6Address target, Address hardwareAddress)
977 {
978  NS_LOG_FUNCTION (this << src << dst << target << hardwareAddress);
979  Ptr<Packet> p = Create<Packet> ();
980  /* Ipv6Header ipHeader; */
981  Icmpv6NS ns (target);
982  Icmpv6OptionLinkLayerAddress llOption (1, hardwareAddress); /* we give our mac address in response */
983 
984  /* if the source is unspec, multicast the NA to all-nodes multicast */
985  if (src == Ipv6Address::GetAny ())
986  {
988  }
989 
990  NS_LOG_LOGIC ("Send NS ( from " << src << " to " << dst << " target " << target << ")");
991 
992  p->AddHeader (llOption);
993  ns.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + ns.GetSerializedSize (), PROT_NUMBER);
994  p->AddHeader (ns);
995  if (!dst.IsMulticast ())
996  {
997  SendMessage (p, src, dst, 255);
998  }
999  else
1000  {
1001  NS_LOG_LOGIC ("Destination is Multicast, using DelayedSendMessage");
1003  }
1004 }
1005 
1007 {
1008  NS_LOG_FUNCTION (this << src << dst << hardwareAddress);
1009  Ptr<Packet> p = Create<Packet> ();
1010  Icmpv6RS rs;
1011  Icmpv6OptionLinkLayerAddress llOption (1, hardwareAddress); /* we give our mac address in response */
1012 
1013  /* if the source is unspec, multicast the NA to all-nodes multicast */
1014  if (src != Ipv6Address::GetAny ())
1015  {
1016  p->AddHeader (llOption);
1017  }
1018 
1019  NS_LOG_LOGIC ("Send RS ( from " << src << " to " << dst << ")");
1020 
1021  rs.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + rs.GetSerializedSize (), PROT_NUMBER);
1022  p->AddHeader (rs);
1023  if (!dst.IsMulticast ())
1024  {
1025  SendMessage (p, src, dst, 255);
1026  }
1027  else
1028  {
1029  NS_LOG_LOGIC ("Destination is Multicast, using DelayedSendMessage");
1031  }
1032 }
1033 
1035 {
1036  NS_LOG_FUNCTION (this << malformedPacket << dst << (uint32_t)code);
1037  Ptr<Packet> p = Create<Packet> ();
1038  uint32_t malformedPacketSize = malformedPacket->GetSize ();
1040 
1041  NS_LOG_LOGIC ("Send Destination Unreachable ( to " << dst << " code " << (uint32_t)code << " )");
1042 
1043  /* 48 = sizeof IPv6 header + sizeof ICMPv6 error header */
1044  if (malformedPacketSize <= 1280 - 48)
1045  {
1046  header.SetPacket (malformedPacket);
1047  }
1048  else
1049  {
1050  Ptr<Packet> fragment = malformedPacket->CreateFragment (0, 1280 - 48);
1051  header.SetPacket (fragment);
1052  }
1053 
1054  header.SetCode (code);
1055  SendMessage (p, dst, header, 255);
1056 }
1057 
1058 void Icmpv6L4Protocol::SendErrorTooBig (Ptr<Packet> malformedPacket, Ipv6Address dst, uint32_t mtu)
1059 {
1060  NS_LOG_FUNCTION (this << malformedPacket << dst << mtu);
1061  Ptr<Packet> p = Create<Packet> ();
1062  uint32_t malformedPacketSize = malformedPacket->GetSize ();
1063  Icmpv6TooBig header;
1064 
1065  NS_LOG_LOGIC ("Send Too Big ( to " << dst << " )");
1066 
1067  /* 48 = sizeof IPv6 header + sizeof ICMPv6 error header */
1068  if (malformedPacketSize <= 1280 - 48)
1069  {
1070  header.SetPacket (malformedPacket);
1071  }
1072  else
1073  {
1074  Ptr<Packet> fragment = malformedPacket->CreateFragment (0, 1280 - 48);
1075  header.SetPacket (fragment);
1076  }
1077 
1078  header.SetCode (0);
1079  header.SetMtu (mtu);
1080  SendMessage (p, dst, header, 255);
1081 }
1082 
1083 void Icmpv6L4Protocol::SendErrorTimeExceeded (Ptr<Packet> malformedPacket, Ipv6Address dst, uint8_t code)
1084 {
1085  NS_LOG_FUNCTION (this << malformedPacket << dst << static_cast<uint32_t> (code));
1086  Ptr<Packet> p = Create<Packet> ();
1087  uint32_t malformedPacketSize = malformedPacket->GetSize ();
1088  Icmpv6TimeExceeded header;
1089 
1090  NS_LOG_LOGIC ("Send Time Exceeded ( to " << dst << " code " << (uint32_t)code << " )");
1091 
1092  /* 48 = sizeof IPv6 header + sizeof ICMPv6 error header */
1093  if (malformedPacketSize <= 1280 - 48)
1094  {
1095  header.SetPacket (malformedPacket);
1096  }
1097  else
1098  {
1099  Ptr<Packet> fragment = malformedPacket->CreateFragment (0, 1280 - 48);
1100  header.SetPacket (fragment);
1101  }
1102 
1103  header.SetCode (code);
1104  SendMessage (p, dst, header, 255);
1105 }
1106 
1107 void Icmpv6L4Protocol::SendErrorParameterError (Ptr<Packet> malformedPacket, Ipv6Address dst, uint8_t code, uint32_t ptr)
1108 {
1109  NS_LOG_FUNCTION (this << malformedPacket << dst << static_cast<uint32_t> (code) << ptr);
1110  Ptr<Packet> p = Create<Packet> ();
1111  uint32_t malformedPacketSize = malformedPacket->GetSize ();
1112  Icmpv6ParameterError header;
1113 
1114  NS_LOG_LOGIC ("Send Parameter Error ( to " << dst << " code " << (uint32_t)code << " )");
1115 
1116  /* 48 = sizeof IPv6 header + sizeof ICMPv6 error header */
1117  if (malformedPacketSize <= 1280 - 48 )
1118  {
1119  header.SetPacket (malformedPacket);
1120  }
1121  else
1122  {
1123  Ptr<Packet> fragment = malformedPacket->CreateFragment (0, 1280 - 48);
1124  header.SetPacket (fragment);
1125  }
1126 
1127  header.SetCode (code);
1128  header.SetPtr (ptr);
1129  SendMessage (p, dst, header, 255);
1130 }
1131 
1132 void Icmpv6L4Protocol::SendRedirection (Ptr<Packet> redirectedPacket, Ipv6Address src, Ipv6Address dst, Ipv6Address redirTarget, Ipv6Address redirDestination, Address redirHardwareTarget)
1133 {
1134  NS_LOG_FUNCTION (this << redirectedPacket << dst << redirTarget << redirDestination << redirHardwareTarget);
1135  uint32_t llaSize = 0;
1136  Ptr<Packet> p = Create<Packet> ();
1137  uint32_t redirectedPacketSize = redirectedPacket->GetSize ();
1138  Icmpv6OptionLinkLayerAddress llOption (0);
1139 
1140  NS_LOG_LOGIC ("Send Redirection ( to " << dst << " target " << redirTarget << " destination " << redirDestination << " )");
1141 
1142  Icmpv6OptionRedirected redirectedOptionHeader;
1143 
1144  if ((redirectedPacketSize % 8) != 0)
1145  {
1146  Ptr<Packet> pad = Create<Packet> (8 - (redirectedPacketSize % 8));
1147  redirectedPacket->AddAtEnd (pad);
1148  }
1149 
1150  if (redirHardwareTarget.GetLength ())
1151  {
1152  llOption.SetAddress (redirHardwareTarget);
1153  llaSize = llOption.GetSerializedSize ();
1154  }
1155 
1156  /* 56 = sizeof IPv6 header + sizeof ICMPv6 error header + sizeof redirected option */
1157  if (redirectedPacketSize <= (1280 - 56 - llaSize))
1158  {
1159  redirectedOptionHeader.SetPacket (redirectedPacket);
1160  }
1161  else
1162  {
1163  Ptr<Packet> fragment = redirectedPacket->CreateFragment (0, 1280 - 56 - llaSize);
1164  redirectedOptionHeader.SetPacket (fragment);
1165  }
1166 
1167  p->AddHeader (redirectedOptionHeader);
1168 
1169  if (llaSize)
1170  {
1171  p->AddHeader (llOption);
1172  }
1173 
1174  Icmpv6Redirection redirectionHeader;
1175  redirectionHeader.SetTarget (redirTarget);
1176  redirectionHeader.SetDestination (redirDestination);
1177  redirectionHeader.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + redirectionHeader.GetSerializedSize (), PROT_NUMBER);
1178  p->AddHeader (redirectionHeader);
1179 
1180  SendMessage (p, src, dst, 64);
1181 }
1182 
1184 {
1185  NS_LOG_FUNCTION (this << src << dst << hardwareAddress << (uint32_t)flags);
1186  Ptr<Packet> p = Create<Packet> ();
1187  Ipv6Header ipHeader;
1188  Icmpv6NA na;
1189  Icmpv6OptionLinkLayerAddress llOption (0, *hardwareAddress); /* we give our mac address in response */
1190 
1191  NS_LOG_LOGIC ("Send NA ( from " << src << " to " << dst << ")");
1192 
1193  /* forge the entire NA packet from IPv6 header to ICMPv6 link-layer option, so that the packet does not pass by Icmpv6L4Protocol::Lookup again */
1194 
1195  p->AddHeader (llOption);
1196  na.SetIpv6Target (src);
1197 
1198  if ((flags & 1))
1199  {
1200  na.SetFlagO (true);
1201  }
1202  if ((flags & 2) && src != Ipv6Address::GetAny ())
1203  {
1204  na.SetFlagS (true);
1205  }
1206  if ((flags & 4))
1207  {
1208  na.SetFlagR (true);
1209  }
1210 
1212  p->AddHeader (na);
1213 
1214  ipHeader.SetSourceAddress (src);
1215  ipHeader.SetDestinationAddress (dst);
1216  ipHeader.SetNextHeader (PROT_NUMBER);
1217  ipHeader.SetPayloadLength (p->GetSize ());
1218  ipHeader.SetHopLimit (255);
1219 
1220  return NdiscCache::Ipv6PayloadHeaderPair (p, ipHeader);
1221 }
1222 
1224 {
1225  NS_LOG_FUNCTION (this << src << dst << target << hardwareAddress);
1226  Ptr<Packet> p = Create<Packet> ();
1227  Ipv6Header ipHeader;
1228  Icmpv6NS ns (target);
1229  Icmpv6OptionLinkLayerAddress llOption (1, hardwareAddress); /* we give our mac address in response */
1230 
1231  /* if the source is unspec, multicast the NA to all-nodes multicast */
1232  if (src == Ipv6Address::GetAny ())
1233  {
1235  }
1236 
1237  NS_LOG_LOGIC ("Send NS ( from " << src << " to " << dst << " target " << target << ")");
1238 
1239  p->AddHeader (llOption);
1241  p->AddHeader (ns);
1242 
1243  ipHeader.SetSourceAddress (src);
1244  ipHeader.SetDestinationAddress (dst);
1245  ipHeader.SetNextHeader (PROT_NUMBER);
1246  ipHeader.SetPayloadLength (p->GetSize ());
1247  ipHeader.SetHopLimit (255);
1248 
1249  return NdiscCache::Ipv6PayloadHeaderPair (p, ipHeader);
1250 }
1251 
1253 {
1254  NS_LOG_FUNCTION (this << device);
1255 
1256  for (CacheList::const_iterator i = m_cacheList.begin (); i != m_cacheList.end (); i++)
1257  {
1258  if ((*i)->GetDevice () == device)
1259  {
1260  return *i;
1261  }
1262  }
1263 
1264  NS_ASSERT (false);
1265  /* quiet compiler */
1266  return 0;
1267 }
1268 
1270 {
1271  NS_LOG_FUNCTION (this << device << interface);
1272 
1273  Ptr<NdiscCache> cache = CreateObject<NdiscCache> ();
1274 
1275  cache->SetDevice (device, interface);
1276  device->AddLinkChangeCallback (MakeCallback (&NdiscCache::Flush, cache));
1277  m_cacheList.push_back (cache);
1278  return cache;
1279 }
1280 
1281 bool Icmpv6L4Protocol::Lookup (Ipv6Address dst, Ptr<NetDevice> device, Ptr<NdiscCache> cache, Address* hardwareDestination)
1282 {
1283  NS_LOG_FUNCTION (this << dst << device << cache << hardwareDestination);
1284 
1285  if (!cache)
1286  {
1287  /* try to find the cache */
1288  cache = FindCache (device);
1289  }
1290  if (cache)
1291  {
1292  NdiscCache::Entry* entry = cache->Lookup (dst);
1293  if (entry)
1294  {
1295  if (entry->IsReachable () || entry->IsDelay () || entry->IsPermanent ())
1296  {
1297  *hardwareDestination = entry->GetMacAddress ();
1298  return true;
1299  }
1300  else if (entry->IsStale ())
1301  {
1302  entry->StartDelayTimer ();
1303  entry->MarkDelay ();
1304  *hardwareDestination = entry->GetMacAddress ();
1305  return true;
1306  }
1307  }
1308  }
1309  return false;
1310 }
1311 
1312 bool Icmpv6L4Protocol::Lookup (Ptr<Packet> p, const Ipv6Header & ipHeader, Ipv6Address dst, Ptr<NetDevice> device, Ptr<NdiscCache> cache, Address* hardwareDestination)
1313 {
1314  NS_LOG_FUNCTION (this << p << ipHeader << dst << device << cache << hardwareDestination);
1315 
1316  if (!cache)
1317  {
1318  /* try to find the cache */
1319  cache = FindCache (device);
1320  }
1321  if (!cache)
1322  {
1323  return false;
1324  }
1325 
1326  NdiscCache::Entry* entry = cache->Lookup (dst);
1327  if (entry)
1328  {
1329  if (entry->IsReachable () || entry->IsDelay () || entry->IsPermanent ())
1330  {
1331  /* XXX check reachability time */
1332  /* send packet */
1333  *hardwareDestination = entry->GetMacAddress ();
1334  return true;
1335  }
1336  else if (entry->IsStale ())
1337  {
1338  /* start delay timer */
1339  entry->StartDelayTimer ();
1340  entry->MarkDelay ();
1341  *hardwareDestination = entry->GetMacAddress ();
1342  return true;
1343  }
1344  else /* INCOMPLETE or PROBE */
1345  {
1346  /* queue packet */
1347  entry->AddWaitingPacket (NdiscCache::Ipv6PayloadHeaderPair (p, ipHeader));
1348  return false;
1349  }
1350  }
1351  else
1352  {
1353  /* we contact this node for the first time
1354  * add it to the cache and send an NS
1355  */
1356  Ipv6Address addr;
1357  NdiscCache::Entry* entry = cache->Add (dst);
1358  entry->MarkIncomplete (NdiscCache::Ipv6PayloadHeaderPair (p, ipHeader));
1359  entry->SetRouter (false);
1360 
1361  if (dst.IsLinkLocal ())
1362  {
1363  addr = cache->GetInterface ()->GetLinkLocalAddress ().GetAddress ();
1364  }
1365  else if (cache->GetInterface ()->GetNAddresses () == 1) /* an interface have at least one address (link-local) */
1366  {
1367  /* try to resolve global address without having global address so return! */
1368  cache->Remove (entry);
1369  return false;
1370  }
1371  else
1372  {
1373  /* find source address that match destination */
1374  addr = cache->GetInterface ()->GetAddressMatchingDestination (dst).GetAddress ();
1375  }
1376 
1377  SendNS (addr, Ipv6Address::MakeSolicitedAddress (dst), dst, cache->GetDevice ()->GetAddress ());
1378 
1379  /* start retransmit timer */
1380  entry->StartRetransmitTimer ();
1381  return false;
1382  }
1383 
1384  return false;
1385 }
1386 
1388 {
1390  NS_LOG_LOGIC (interface << " " << addr);
1391  Ipv6InterfaceAddress ifaddr;
1392  bool found = false;
1393  uint32_t i = 0;
1394  uint32_t nb = interface->GetNAddresses ();
1395 
1396  for (i = 0; i < nb; i++)
1397  {
1398  ifaddr = interface->GetAddress (i);
1399 
1400  if (ifaddr.GetAddress () == addr)
1401  {
1402  found = true;
1403  break;
1404  }
1405  }
1406 
1407  /* for the moment, this function is always called, if we was victim of a DAD the address is INVALID
1408  * and we do not set it to PREFERRED
1409  */
1410  if (found && ifaddr.GetState () != Ipv6InterfaceAddress::INVALID)
1411  {
1412  interface->SetState (ifaddr.GetAddress (), Ipv6InterfaceAddress::PREFERRED);
1413  NS_LOG_LOGIC ("DAD OK, interface in state PREFERRED");
1414 
1415  /* send an RS if our interface is not forwarding (router) and if address is a link-local ones
1416  * (because we will send RS with it)
1417  */
1418  Ptr<Ipv6> ipv6 = icmpv6->m_node->GetObject<Ipv6> ();
1419 
1420  if (!ipv6->IsForwarding (ipv6->GetInterfaceForDevice (interface->GetDevice ())) && addr.IsLinkLocal ())
1421  {
1422  /* \todo Add random delays before sending RS
1423  * because all nodes start at the same time, there will be many of RS arround 1 second of simulation time
1424  */
1425  Simulator::Schedule (Seconds (0.0), &Icmpv6L4Protocol::SendRS, PeekPointer (icmpv6), ifaddr.GetAddress (), Ipv6Address::GetAllRoutersMulticast (), interface->GetDevice ()->GetAddress ());
1426  }
1427  }
1428 }
1429 
1430 void
1432 {
1433  NS_LOG_FUNCTION (this << &callback);
1434 }
1435 
1436 void
1438 {
1439  NS_LOG_FUNCTION (this << &callback);
1440  m_downTarget = callback;
1441 }
1442 
1445 {
1446  NS_LOG_FUNCTION (this);
1447  return (IpL4Protocol::DownTargetCallback)NULL;
1448 }
1449 
1452 {
1453  NS_LOG_FUNCTION (this);
1454  return m_downTarget;
1455 }
1456 
1457 } /* namespace ns3 */
1458 
void DelayedSendMessage(Ptr< Packet > packet, Ipv6Address src, Ipv6Address dst, uint8_t ttl)
Helper function used during delayed solicitation.
bool IsAny() const
If the IPv6 address is the "Any" address.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
void Dispose(void)
Dispose of this Object.
Definition: object.cc:214
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
Definition: ipv6-header.cc:143
std::list< Ipv6PayloadHeaderPair > MarkStale(Address mac)
Changes the state to this entry to STALE.
Definition: ndisc-cache.cc:526
uint8_t GetNextHeader(void) const
Get the next header.
Definition: ipv6-header.cc:80
void SetPayloadLength(uint16_t len)
Set the "Payload length" field.
Definition: ipv6-header.cc:65
void SetPacket(Ptr< Packet > packet)
Set the redirected packet.
void CalculatePseudoHeaderChecksum(Ipv6Address src, Ipv6Address dst, uint16_t length, uint8_t protocol)
Calculate pseudo header checksum for IPv6.
ICMPv6 redirected option.
uint16_t GetId() const
Get the ID of the packet.
static const uint8_t MAX_ANYCAST_DELAY_TIME
Neighbor Discovery node constants : max anycast delay.
uint32_t GetNsDadUid() const
Get the latest DAD probe packet UID.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Packet header for IPv6.
Definition: ipv6-header.h:34
bool Lookup(Ipv6Address dst, Ptr< NetDevice > device, Ptr< NdiscCache > cache, Address *hardwareDestination)
Lookup in the ND cache for the IPv6 address.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
ICMPv6 Error Parameter Error header.
void SetState(Ipv6Address address, Ipv6InterfaceAddress::State_e state)
Update state of an interface address.
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
AttributeValue implementation for Boolean.
Definition: boolean.h:34
ICMPv6 Router Advertisement header.
ICMPv6 Neighbor Advertisement header.
void SendNA(Ipv6Address src, Ipv6Address dst, Address *hardwareAddress, uint8_t flags)
Send a Neighbor Adverstisement.
void HandleNS(Ptr< Packet > p, Ipv6Address const &src, Ipv6Address const &dst, Ptr< Ipv6Interface > interface)
Receive Neighbor Solicitation method.
virtual uint32_t GetSerializedSize() const
Get the serialized size.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
Address GetMacAddress() const
Get the MAC address of this entry.
Definition: ndisc-cache.cc:583
NdiscCache::Entry * Add(Ipv6Address to)
Add an entry.
Definition: ndisc-cache.cc:120
static const uint8_t MAX_INITIAL_RTR_ADVERTISEMENTS
Neighbor Discovery router constants : max initial RA transmission.
Ptr< Packet > GetPacket() const
Get the incorrect packet.
Ipv6Address GetTarget() const
Get the IPv6 target address.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:462
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:81
Hold variables of type string.
Definition: string.h:41
void StopNudTimer()
Stop NUD timer and reset the NUD retransmission counter.
Definition: ndisc-cache.cc:482
virtual uint32_t GetSerializedSize() const
Get the serialized size.
static const uint8_t MAX_FINAL_RTR_ADVERTISEMENTS
Neighbor Discovery router constants : max final RA transmission.
ICMPv6 Error Time Exceeded header.
IPv6 layer implementation.
Ptr< Node > m_node
The node.
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:81
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:824
ICMPv6 Router Solicitation header.
void SendRS(Ipv6Address src, Ipv6Address dst, Address hardwareAddress)
Send a Router Solicitation.
ICMPv6 Neighbor Solicitation header.
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:368
uint8_t GetType() const
Get the type field.
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1270
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
virtual void ReceiveIcmp(Ipv4Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo, Ipv4Address payloadSource, Ipv4Address payloadDestination, const uint8_t payload[8])
Called from lower-level layers to send the ICMP packet up in the stack.
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:562
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
Ipv6InterfaceAddress GetAddress(uint32_t index) const
Get an address from IPv6 interface.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
IPv6 address associated with an interface.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:903
void SetPtr(uint32_t ptr)
Set the pointer field.
static const uint8_t PROT_NUMBER
ICMPv6 protocol number (58).
virtual IpL4Protocol::DownTargetCallback6 GetDownTarget6(void) const
This method allows a caller to get the current down target callback set for this L4 protocol (IPv6 ca...
bool GetFlagS() const
Get the S flag.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:792
void SetNextHeader(uint8_t next)
Set the "Next header" field.
Definition: ipv6-header.cc:75
bool IsEqual(const Ipv6Address &other) const
Comparison operation between two Ipv6Addresses.
virtual ~Icmpv6L4Protocol()
Destructor.
static const uint8_t RTR_SOLICITATION_INTERVAL
Neighbor Discovery host constants : RS interval.
std::list< Ipv6PayloadHeaderPair > MarkReachable(Address mac)
Changes the state to this entry to REACHABLE.
Definition: ndisc-cache.cc:500
static const uint8_t MAX_RTR_SOLICITATIONS
Neighbor Discovery host constants : max RS transmission.
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
void SetMtu(uint32_t mtu)
Set the MTU.
void SetNode(Ptr< Node > node)
Set the node.
void SetPacket(Ptr< Packet > p)
Set the incorrect packet.
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer...
Definition: socket.h:1112
void SetTarget(Ipv6Address target)
Set the IPv6 target address.
virtual int GetProtocolNumber() const
Get the protocol number.
RxStatus
Rx status codes.
Icmpv6L4Protocol()
Constructor.
uint16_t GetLifeTime() const
Get the node Life time (Neighbor Discovery).
virtual double GetValue(void)=0
Get the next random value as a double drawn from the distribution.
a polymophic address class
Definition: address.h:90
void SetPacket(Ptr< Packet > p)
Set the incorrect packet.
static void FunctionDadTimeout(Ptr< Icmpv6L4Protocol > icmpv6, Ipv6Interface *interface, Ipv6Address addr)
Function called when DAD timeout.
virtual enum IpL4Protocol::RxStatus Receive(Ptr< Packet > p, Ipv4Header const &header, Ptr< Ipv4Interface > interface)
Receive method.
void SendErrorTooBig(Ptr< Packet > malformedPacket, Ipv6Address dst, uint32_t mtu)
Send an error Too Big.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
Ptr< Ipv6Interface > GetInterface() const
Get the Ipv6Interface associated with this cache.
Definition: ndisc-cache.cc:79
void NotifyNewAggregate()
This method is called by AddAgregate and completes the aggregation by setting the node in the ICMPv6 ...
bool IsDelay() const
Is the entry DELAY.
Definition: ndisc-cache.cc:559
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition: packet.cc:228
Packet header for IPv4.
Definition: ipv4-header.h:33
virtual void Send(Ptr< Packet > packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr< Ipv6Route > route)=0
Higher-level layers call this method to send a packet down the stack to the MAC and PHY layers...
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:313
bool GetFlagR() const
Get the R flag.
The IPv6 representation of a network interface.
ICMPv6 Error Destination Unreachable header.
void HandleRedirection(Ptr< Packet > p, Ipv6Address const &src, Ipv6Address const &dst, Ptr< Ipv6Interface > interface)
Receive Redirection method.
Ipv6Address GetAddress() const
Get the IPv6 address.
void Send(Ptr< Packet > p, const Ipv6Header &hdr, Ipv6Address dest)
Send a packet through this interface.
Ipv6Address GetIpv6Target() const
Get the IPv6 target field.
ICMPv6 header.
Definition: icmpv6-header.h:38
uint32_t GetNAddresses(void) const
Get number of addresses on this IPv6 interface.
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: pointer.h:220
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1238
static const uint32_t MAX_RA_DELAY_TIME
Neighbor Discovery router constants : max delay between RA.
void Forward(Ipv6Address source, Icmpv6Header icmp, uint32_t info, Ipv6Header ipHeader, const uint8_t payload[8])
Notify an ICMPv6 reception to upper layers (if requested).
void SendErrorParameterError(Ptr< Packet > malformedPacket, Ipv6Address dst, uint8_t code, uint32_t ptr)
Send an error Parameter Error.
Ptr< Packet > GetPacket() const
Get the incorrect packet.
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition: socket.cc:610
void SetIpv6Target(Ipv6Address target)
Set the IPv6 target field.
void HandleTimeExceeded(Ptr< Packet > p, Ipv6Address const &src, Ipv6Address const &dst, Ptr< Ipv6Interface > interface)
Receive Time Exceeded method.
NdiscCache::Ipv6PayloadHeaderPair ForgeNS(Ipv6Address src, Ipv6Address dst, Ipv6Address target, Address hardwareAddress)
Forge a Neighbor Solicitation.
NdiscCache::Ipv6PayloadHeaderPair ForgeEchoRequest(Ipv6Address src, Ipv6Address dst, uint16_t id, uint16_t seq, Ptr< Packet > data)
Forge an Echo Request.
void Flush()
Flush the cache.
Definition: ndisc-cache.cc:147
void SendErrorTimeExceeded(Ptr< Packet > malformedPacket, Ipv6Address dst, uint8_t code)
Send an error Time Exceeded.
ICMPv6 Option Prefix Information.
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
uint8_t data[writeSize]
Address is tentative but we are optimistic so we can send packet even if DAD is not yet finished...
NdiscCache::Ipv6PayloadHeaderPair ForgeRS(Ipv6Address src, Ipv6Address dst, Address hardwareAddress)
Forge a Router Solicitation.
bool IsAlwaysDad() const
Is the node must do DAD.
uint8_t GetLength(void) const
Get the length of the underlying address.
Definition: address.cc:75
static const uint32_t REACHABLE_TIME
Neighbor Discovery node constants : reachable time.
ICMPv6 Redirection header.
Ptr< Packet > GetPacket() const
Get the incorrect packet.
static const double MIN_RANDOM_FACTOR
Neighbor Discovery node constants : min random factor.
An implementation of the ICMPv6 protocol.
Ptr< NdiscCache > FindCache(Ptr< NetDevice > device)
Get the cache corresponding to the device.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
virtual Ptr< NetDevice > GetDevice() const
Get the NetDevice.
void SetPacket(Ptr< Packet > p)
Set the incorrect packet.
Ptr< RandomVariableStream > m_solicitationJitter
Random jitter before sending solicitations.
bool GetFlagO() const
Get the O flag.
void HandleRS(Ptr< Packet > p, Ipv6Address const &src, Ipv6Address const &dst, Ptr< Ipv6Interface > interface)
Receive Router Solicitation method.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
void StartRetransmitTimer()
Start retransmit timer.
Definition: ndisc-cache.cc:470
uint16_t GetSeq() const
Get the sequence number.
void SetNsDadUid(Ipv6Address address, uint32_t uid)
Update NS DAD packet UID of an interface address.
void ClearWaitingPacket()
Clear the waiting packet list.
Definition: ndisc-cache.cc:258
virtual uint32_t GetSerializedSize() const
Get the serialized size.
void HandleEchoRequest(Ptr< Packet > p, Ipv6Address const &src, Ipv6Address const &dst, Ptr< Ipv6Interface > interface)
Receive Echo Request method.
void HandleParameterError(Ptr< Packet > p, Ipv6Address const &src, Ipv6Address const &dst, Ptr< Ipv6Interface > interface)
Receive Parameter Error method.
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
static const uint8_t MAX_MULTICAST_SOLICIT
Neighbor Discovery node constants : max multicast solicitations.
bool IsProbe() const
Is the entry PROBE.
Definition: ndisc-cache.cc:571
uint8_t GetHopLimit(void) const
Get the "Hop limit" field (TTL).
Definition: ipv6-header.cc:90
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SendErrorDestinationUnreachable(Ptr< Packet > malformedPacket, Ipv6Address dst, uint8_t code)
Send an error Destination Unreachable.
void SendEchoReply(Ipv6Address src, Ipv6Address dst, uint16_t id, uint16_t seq, Ptr< Packet > data)
Send a Echo Reply.
static TypeId GetTypeId()
Interface ID.
static const uint8_t MAX_NEIGHBOR_ADVERTISEMENT
Neighbor Discovery node constants : max NA transmission.
virtual IpL4Protocol::DownTargetCallback GetDownTarget(void) const
This method allows a caller to get the current down target callback set for this L4 protocol (IPv4 ca...
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
static uint16_t GetStaticProtocolNumber()
Get ICMPv6 protocol number.
void SetCode(uint8_t code)
Set the code field.
Ipv6InterfaceAddress::State_e GetState() const
Get the address state.
ICMPv6 MTU option.
uint8_t GetCode() const
Get the code field.
void StartDelayTimer()
Start delay timer.
Definition: ndisc-cache.cc:458
IpL4Protocol::DownTargetCallback6 m_downTarget
callback to Ipv6::Send
static const uint8_t MAX_INITIAL_RTR_ADVERT_INTERVAL
Neighbor Discovery router constants : max initial RA initial interval.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
static Ipv6Address GetAllNodesMulticast()
Get the "all nodes multicast" address.
void StartReachableTimer()
Start the reachable timer.
Definition: ndisc-cache.cc:417
bool m_alwaysDad
Always do DAD ?
bool IsIncomplete() const
Is the entry INCOMPLETE.
Definition: ndisc-cache.cc:565
L4 Protocol abstract base class.
void SendMessage(Ptr< Packet > packet, Ipv6Address src, Ipv6Address dst, uint8_t ttl)
Send a packet via ICMPv6, note that packet already contains ICMPv6 header.
virtual void SetDownTarget(IpL4Protocol::DownTargetCallback cb)
This method allows a caller to set the current down target callback set for this L4 protocol (IPv4 ca...
void Remove(NdiscCache::Entry *entry)
Delete an entry.
Definition: ndisc-cache.cc:131
static const uint8_t MIN_DELAY_BETWEEN_RAS
Neighbor Discovery router constants : min delay between RA.
void SetFlagR(bool r)
Set the R flag.
virtual uint32_t GetSerializedSize() const
Get the serialized size.
void SendRedirection(Ptr< Packet > redirectedPacket, Ipv6Address src, Ipv6Address dst, Ipv6Address redirTarget, Ipv6Address redirDestination, Address redirHardwareTarget)
Send an ICMPv6 Redirection.
void SetMacAddress(Address mac)
Set the MAC address of this entry.
Definition: ndisc-cache.cc:589
static const double MAX_RANDOM_FACTOR
Neighbor Discovery node constants : max random factor.
ICMPv6 Echo message.
void SetFlagS(bool s)
Set the S flag.
void SetSourceAddress(Ipv6Address src)
Set the "Source address" field.
Definition: ipv6-header.cc:95
CacheList m_cacheList
A list of cache by device.
void DoDAD(Ipv6Address target, Ptr< Ipv6Interface > interface)
Do the Duplication Address Detection (DAD).
virtual void SetDownTarget6(IpL4Protocol::DownTargetCallback6 cb)
This method allows a caller to set the current down target callback set for this L4 protocol (IPv6 ca...
Ipv6InterfaceAddress GetLinkLocalAddress() const
Get link-local address from IPv6 interface.
Describes an IPv6 address.
Definition: ipv6-address.h:48
Address is tentative, no packet can be sent unless DAD finished.
NdiscCache::Entry * Lookup(Ipv6Address dst)
Lookup in the cache.
Definition: ndisc-cache.cc:91
void SetHopLimit(uint8_t limit)
Set the "Hop limit" field (TTL).
Definition: ipv6-header.cc:85
void HandleRA(Ptr< Packet > p, Ipv6Address const &src, Ipv6Address const &dst, Ptr< Ipv6Interface > interface)
Receive Router Advertisement method.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
void ReceiveLLA(Icmpv6OptionLinkLayerAddress lla, Ipv6Address const &src, Ipv6Address const &dst, Ptr< Ipv6Interface > interface)
Link layer address option processing.
void MarkDelay()
Change the state to this entry to DELAY.
Definition: ndisc-cache.cc:534
virtual int GetVersion() const
Get the version of the protocol.
static const uint32_t RETRANS_TIMER
Neighbor Discovery node constants : retransmission timer.
void SetDestination(Ipv6Address destination)
Set the IPv6 destination address.
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:100
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
Invalid state (after a DAD failed)
void MarkIncomplete(Ipv6PayloadHeaderPair p)
Changes the state to this entry to INCOMPLETE.
Definition: ndisc-cache.cc:489
void SetDevice(Ptr< NetDevice > device, Ptr< Ipv6Interface > interface)
Set the device and interface.
Definition: ndisc-cache.cc:72
Describes an IPv6 prefix.
Definition: ipv6-address.h:394
virtual void DoDispose()
Dispose this object.
void Nullify(void)
Discard the implementation, set it to null.
Definition: callback.h:1274
Ipv6Address GetDestination() const
Get the IPv6 destination address.
Ipv6Address GetIpv6Target() const
Get the IPv6 target field.
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:356
bool IsPermanent() const
Is the entry PERMANENT.
Definition: ndisc-cache.cc:577
static const uint8_t MAX_RTR_SOLICITATION_DELAY
Neighbor Discovery host constants : max RS delay.
A record that holds information about a NdiscCache entry.
Definition: ndisc-cache.h:153
void HandleNA(Ptr< Packet > p, Ipv6Address const &src, Ipv6Address const &dst, Ptr< Ipv6Interface > interface)
Receive Neighbor Advertisement method.
void SetRouter(bool router)
Set the node type.
Definition: ndisc-cache.cc:233
static const uint8_t DELAY_FIRST_PROBE_TIME
Neighbor Discovery node constants : delay for the first probe.
virtual uint32_t GetSerializedSize() const
Get the serialized size.
void SetSeq(uint16_t seq)
Set the sequence number.
virtual void NotifyNewAggregate(void)
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:325
std::pair< Ptr< Packet >, Ipv6Header > Ipv6PayloadHeaderPair
Pair of a packet and an Ipv4 header.
Definition: ndisc-cache.h:146
void HandlePacketTooBig(Ptr< Packet > p, Ipv6Address const &src, Ipv6Address const &dst, Ptr< Ipv6Interface > interface)
Receive Packet Too Big method.
bool IsReachable() const
Is the entry REACHABLE.
Definition: ndisc-cache.cc:553
void SetPacket(Ptr< Packet > p)
Set the incorrect packet.
uint32_t GetMtu() const
Get the MTU field.
ICMPv6 Error Too Big header.
a unique identifier for an interface.
Definition: type-id.h:58
void AddWaitingPacket(Ipv6PayloadHeaderPair p)
Add a packet (or replace old value) in the queue.
Definition: ndisc-cache.cc:245
Ptr< Packet > GetPacket() const
Get the incorrect packet.
Ipv6InterfaceAddress GetAddressMatchingDestination(Ipv6Address dst)
Get an address which is in the same network prefix as destination.
virtual uint32_t GetSerializedSize() const
Get the serialized size.
void SetDestinationAddress(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:105
void SetFlagO(bool o)
Set the O flag.
Ptr< NetDevice > GetDevice() const
Get the NetDevice associated with this cache.
Definition: ndisc-cache.cc:85
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:904
void SendNS(Ipv6Address src, Ipv6Address dst, Ipv6Address target, Address hardwareAddress)
Send a Neighbor Solicitation.
NdiscCache::Ipv6PayloadHeaderPair ForgeNA(Ipv6Address src, Ipv6Address dst, Address *hardwareAddress, uint8_t flags)
Forge a Neighbor Advertisement.
bool IsStale() const
Is the entry STALE.
Definition: ndisc-cache.cc:547
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:257
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:110
Ptr< NdiscCache > CreateCache(Ptr< NetDevice > device, Ptr< Ipv6Interface > interface)
Create a neighbor cache.
void SetId(uint16_t id)
Set the ID of the packet.
void HandleDestinationUnreachable(Ptr< Packet > p, Ipv6Address const &src, Ipv6Address const &dst, Ptr< Ipv6Interface > interface)
Receive Destination Unreachable method.
static Ipv6Address MakeSolicitedAddress(Ipv6Address addr)
Make the solicited IPv6 address.
static Ipv6Address GetAllRoutersMulticast()
Get the "all routers multicast" address.
static const uint8_t MAX_UNICAST_SOLICIT
Neighbor Discovery node constants : max unicast solicitations.