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