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