A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
aodv-routing-protocol.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 IITP RAS
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  * Based on
19  * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
20  * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
21  *
22  * AODV-UU implementation by Erik Nordström of Uppsala University
23  * http://core.it.uu.se/core/index.php/AODV-UU
24  *
25  * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
26  * Pavel Boyko <boyko@iitp.ru>
27  */
28 #define NS_LOG_APPEND_CONTEXT \
29  if (m_ipv4) { std::clog << "[node " << m_ipv4->GetObject<Node> ()->GetId () << "] "; }
30 
31 #include "aodv-routing-protocol.h"
32 #include "ns3/log.h"
33 #include "ns3/boolean.h"
34 #include "ns3/random-variable-stream.h"
35 #include "ns3/inet-socket-address.h"
36 #include "ns3/trace-source-accessor.h"
37 #include "ns3/udp-socket-factory.h"
38 #include "ns3/wifi-net-device.h"
39 #include "ns3/adhoc-wifi-mac.h"
40 #include "ns3/string.h"
41 #include "ns3/pointer.h"
42 #include <algorithm>
43 #include <limits>
44 
45 NS_LOG_COMPONENT_DEFINE ("AodvRoutingProtocol");
46 
47 namespace ns3
48 {
49 namespace aodv
50 {
51 NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
52 
54 const uint32_t RoutingProtocol::AODV_PORT = 654;
55 
56 //-----------------------------------------------------------------------------
58 
60 {
61 
62 public:
63  DeferredRouteOutputTag (int32_t o = -1) : Tag (), m_oif (o) {}
64 
65  static TypeId GetTypeId ()
66  {
67  static TypeId tid = TypeId ("ns3::aodv::DeferredRouteOutputTag").SetParent<Tag> ()
68  .SetParent<Tag> ()
69  .AddConstructor<DeferredRouteOutputTag> ()
70  ;
71  return tid;
72  }
73 
75  {
76  return GetTypeId ();
77  }
78 
79  int32_t GetInterface() const
80  {
81  return m_oif;
82  }
83 
84  void SetInterface(int32_t oif)
85  {
86  m_oif = oif;
87  }
88 
89  uint32_t GetSerializedSize () const
90  {
91  return sizeof(int32_t);
92  }
93 
94  void Serialize (TagBuffer i) const
95  {
96  i.WriteU32 (m_oif);
97  }
98 
100  {
101  m_oif = i.ReadU32 ();
102  }
103 
104  void Print (std::ostream &os) const
105  {
106  os << "DeferredRouteOutputTag: output interface = " << m_oif;
107  }
108 
109 private:
111  int32_t m_oif;
112 };
113 
115 
116 
117 //-----------------------------------------------------------------------------
119  RreqRetries (2),
120  RreqRateLimit (10),
121  RerrRateLimit (10),
122  ActiveRouteTimeout (Seconds (3)),
123  NetDiameter (35),
124  NodeTraversalTime (MilliSeconds (40)),
125  NetTraversalTime (Time ((2 * NetDiameter) * NodeTraversalTime)),
126  PathDiscoveryTime ( Time (2 * NetTraversalTime)),
127  MyRouteTimeout (Time (2 * std::max (PathDiscoveryTime, ActiveRouteTimeout))),
128  HelloInterval (Seconds (1)),
129  AllowedHelloLoss (2),
130  DeletePeriod (Time (5 * std::max (ActiveRouteTimeout, HelloInterval))),
131  NextHopWait (NodeTraversalTime + MilliSeconds (10)),
132  BlackListTimeout (Time (RreqRetries * NetTraversalTime)),
133  MaxQueueLen (64),
134  MaxQueueTime (Seconds (30)),
135  DestinationOnly (false),
136  GratuitousReply (true),
137  EnableHello (false),
138  m_routingTable (DeletePeriod),
139  m_queue (MaxQueueLen, MaxQueueTime),
140  m_requestId (0),
141  m_seqNo (0),
142  m_rreqIdCache (PathDiscoveryTime),
143  m_dpd (PathDiscoveryTime),
144  m_nb (HelloInterval),
145  m_rreqCount (0),
146  m_rerrCount (0),
147  m_htimer (Timer::CANCEL_ON_DESTROY),
148  m_rreqRateLimitTimer (Timer::CANCEL_ON_DESTROY),
149  m_rerrRateLimitTimer (Timer::CANCEL_ON_DESTROY),
150  m_lastBcastTime (Seconds (0))
151 {
153 }
154 
155 TypeId
157 {
158  static TypeId tid = TypeId ("ns3::aodv::RoutingProtocol")
160  .AddConstructor<RoutingProtocol> ()
161  .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
162  TimeValue (Seconds (1)),
163  MakeTimeAccessor (&RoutingProtocol::HelloInterval),
164  MakeTimeChecker ())
165  .AddAttribute ("RreqRetries", "Maximum number of retransmissions of RREQ to discover a route",
166  UintegerValue (2),
167  MakeUintegerAccessor (&RoutingProtocol::RreqRetries),
168  MakeUintegerChecker<uint32_t> ())
169  .AddAttribute ("RreqRateLimit", "Maximum number of RREQ per second.",
170  UintegerValue (10),
171  MakeUintegerAccessor (&RoutingProtocol::RreqRateLimit),
172  MakeUintegerChecker<uint32_t> ())
173  .AddAttribute ("RerrRateLimit", "Maximum number of RERR per second.",
174  UintegerValue (10),
175  MakeUintegerAccessor (&RoutingProtocol::RerrRateLimit),
176  MakeUintegerChecker<uint32_t> ())
177  .AddAttribute ("NodeTraversalTime", "Conservative estimate of the average one hop traversal time for packets and should include "
178  "queuing delays, interrupt processing times and transfer times.",
179  TimeValue (MilliSeconds (40)),
180  MakeTimeAccessor (&RoutingProtocol::NodeTraversalTime),
181  MakeTimeChecker ())
182  .AddAttribute ("NextHopWait", "Period of our waiting for the neighbour's RREP_ACK = 10 ms + NodeTraversalTime",
183  TimeValue (MilliSeconds (50)),
184  MakeTimeAccessor (&RoutingProtocol::NextHopWait),
185  MakeTimeChecker ())
186  .AddAttribute ("ActiveRouteTimeout", "Period of time during which the route is considered to be valid",
187  TimeValue (Seconds (3)),
188  MakeTimeAccessor (&RoutingProtocol::ActiveRouteTimeout),
189  MakeTimeChecker ())
190  .AddAttribute ("MyRouteTimeout", "Value of lifetime field in RREP generating by this node = 2 * max(ActiveRouteTimeout, PathDiscoveryTime)",
191  TimeValue (Seconds (11.2)),
192  MakeTimeAccessor (&RoutingProtocol::MyRouteTimeout),
193  MakeTimeChecker ())
194  .AddAttribute ("BlackListTimeout", "Time for which the node is put into the blacklist = RreqRetries * NetTraversalTime",
195  TimeValue (Seconds (5.6)),
196  MakeTimeAccessor (&RoutingProtocol::BlackListTimeout),
197  MakeTimeChecker ())
198  .AddAttribute ("DeletePeriod", "DeletePeriod is intended to provide an upper bound on the time for which an upstream node A "
199  "can have a neighbor B as an active next hop for destination D, while B has invalidated the route to D."
200  " = 5 * max (HelloInterval, ActiveRouteTimeout)",
201  TimeValue (Seconds (15)),
202  MakeTimeAccessor (&RoutingProtocol::DeletePeriod),
203  MakeTimeChecker ())
204  .AddAttribute ("NetDiameter", "Net diameter measures the maximum possible number of hops between two nodes in the network",
205  UintegerValue (35),
206  MakeUintegerAccessor (&RoutingProtocol::NetDiameter),
207  MakeUintegerChecker<uint32_t> ())
208  .AddAttribute ("NetTraversalTime", "Estimate of the average net traversal time = 2 * NodeTraversalTime * NetDiameter",
209  TimeValue (Seconds (2.8)),
210  MakeTimeAccessor (&RoutingProtocol::NetTraversalTime),
211  MakeTimeChecker ())
212  .AddAttribute ("PathDiscoveryTime", "Estimate of maximum time needed to find route in network = 2 * NetTraversalTime",
213  TimeValue (Seconds (5.6)),
214  MakeTimeAccessor (&RoutingProtocol::PathDiscoveryTime),
215  MakeTimeChecker ())
216  .AddAttribute ("MaxQueueLen", "Maximum number of packets that we allow a routing protocol to buffer.",
217  UintegerValue (64),
218  MakeUintegerAccessor (&RoutingProtocol::SetMaxQueueLen,
220  MakeUintegerChecker<uint32_t> ())
221  .AddAttribute ("MaxQueueTime", "Maximum time packets can be queued (in seconds)",
222  TimeValue (Seconds (30)),
223  MakeTimeAccessor (&RoutingProtocol::SetMaxQueueTime,
225  MakeTimeChecker ())
226  .AddAttribute ("AllowedHelloLoss", "Number of hello messages which may be loss for valid link.",
227  UintegerValue (2),
228  MakeUintegerAccessor (&RoutingProtocol::AllowedHelloLoss),
229  MakeUintegerChecker<uint16_t> ())
230  .AddAttribute ("GratuitousReply", "Indicates whether a gratuitous RREP should be unicast to the node originated route discovery.",
231  BooleanValue (true),
232  MakeBooleanAccessor (&RoutingProtocol::SetGratuitousReplyFlag,
234  MakeBooleanChecker ())
235  .AddAttribute ("DestinationOnly", "Indicates only the destination may respond to this RREQ.",
236  BooleanValue (false),
237  MakeBooleanAccessor (&RoutingProtocol::SetDesinationOnlyFlag,
239  MakeBooleanChecker ())
240  .AddAttribute ("EnableHello", "Indicates whether a hello messages enable.",
241  BooleanValue (true),
242  MakeBooleanAccessor (&RoutingProtocol::SetHelloEnable,
244  MakeBooleanChecker ())
245  .AddAttribute ("EnableBroadcast", "Indicates whether a broadcast data packets forwarding enable.",
246  BooleanValue (true),
247  MakeBooleanAccessor (&RoutingProtocol::SetBroadcastEnable,
249  MakeBooleanChecker ())
250  .AddAttribute ("UniformRv",
251  "Access to the underlying UniformRandomVariable",
252  StringValue ("ns3::UniformRandomVariable"),
253  MakePointerAccessor (&RoutingProtocol::m_uniformRandomVariable),
254  MakePointerChecker<UniformRandomVariable> ())
255  ;
256  return tid;
257 }
258 
259 void
261 {
262  MaxQueueLen = len;
263  m_queue.SetMaxQueueLen (len);
264 }
265 void
267 {
268  MaxQueueTime = t;
270 }
271 
273 {
274 }
275 
276 void
278 {
279  m_ipv4 = 0;
280  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::iterator iter =
281  m_socketAddresses.begin (); iter != m_socketAddresses.end (); iter++)
282  {
283  iter->first->Close ();
284  }
285  m_socketAddresses.clear ();
287 }
288 
289 void
291 {
292  *stream->GetStream () << "Node: " << m_ipv4->GetObject<Node> ()->GetId () << " Time: " << Simulator::Now ().GetSeconds () << "s ";
293  m_routingTable.Print (stream);
294 }
295 
296 int64_t
298 {
299  NS_LOG_FUNCTION (this << stream);
301  return 1;
302 }
303 
304 void
306 {
307  NS_LOG_FUNCTION (this);
308  if (EnableHello)
309  {
310  m_nb.ScheduleTimer ();
311  }
313  this);
314  m_rreqRateLimitTimer.Schedule (Seconds (1));
315 
317  this);
318  m_rerrRateLimitTimer.Schedule (Seconds (1));
319 
320 }
321 
324  Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
325 {
326  NS_LOG_FUNCTION (this << header << (oif ? oif->GetIfIndex () : 0));
327  if (!p)
328  {
329  NS_LOG_DEBUG("Packet is == 0");
330  return LoopbackRoute (header, oif); // later
331  }
332  if (m_socketAddresses.empty ())
333  {
334  sockerr = Socket::ERROR_NOROUTETOHOST;
335  NS_LOG_LOGIC ("No aodv interfaces");
336  Ptr<Ipv4Route> route;
337  return route;
338  }
339  sockerr = Socket::ERROR_NOTERROR;
340  Ptr<Ipv4Route> route;
341  Ipv4Address dst = header.GetDestination ();
343  if (m_routingTable.LookupValidRoute (dst, rt))
344  {
345  route = rt.GetRoute ();
346  NS_ASSERT (route != 0);
347  NS_LOG_DEBUG ("Exist route to " << route->GetDestination () << " from interface " << route->GetSource ());
348  if (oif != 0 && route->GetOutputDevice () != oif)
349  {
350  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
351  sockerr = Socket::ERROR_NOROUTETOHOST;
352  return Ptr<Ipv4Route> ();
353  }
356  return route;
357  }
358 
359  // Valid route not found, in this case we return loopback.
360  // Actual route request will be deferred until packet will be fully formed,
361  // routed to loopback, received from loopback and passed to RouteInput (see below)
362  uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice (oif) : -1);
363  DeferredRouteOutputTag tag (iif);
364  NS_LOG_DEBUG ("Valid Route not found");
365  if (!p->PeekPacketTag (tag))
366  {
367  p->AddPacketTag (tag);
368  }
369  return LoopbackRoute (header, oif);
370 }
371 
372 void
375 {
376  NS_LOG_FUNCTION (this << p << header);
377  NS_ASSERT (p != 0 && p != Ptr<Packet> ());
378 
379  QueueEntry newEntry (p, header, ucb, ecb);
380  bool result = m_queue.Enqueue (newEntry);
381  if (result)
382  {
383  NS_LOG_LOGIC ("Add packet " << p->GetUid () << " to queue. Protocol " << (uint16_t) header.GetProtocol ());
385  bool result = m_routingTable.LookupRoute (header.GetDestination (), rt);
386  if(!result || ((rt.GetFlag () != IN_SEARCH) && result))
387  {
388  NS_LOG_LOGIC ("Send new RREQ for outbound packet to " <<header.GetDestination ());
389  SendRequest (header.GetDestination ());
390  }
391  }
392 }
393 
394 bool
398 {
399  NS_LOG_FUNCTION (this << p->GetUid () << header.GetDestination () << idev->GetAddress ());
400  if (m_socketAddresses.empty ())
401  {
402  NS_LOG_LOGIC ("No aodv interfaces");
403  return false;
404  }
405  NS_ASSERT (m_ipv4 != 0);
406  NS_ASSERT (p != 0);
407  // Check if input device supports IP
408  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
409  int32_t iif = m_ipv4->GetInterfaceForDevice (idev);
410 
411  Ipv4Address dst = header.GetDestination ();
412  Ipv4Address origin = header.GetSource ();
413 
414  // Deferred route request
415  if (idev == m_lo)
416  {
418  if (p->PeekPacketTag (tag))
419  {
420  DeferredRouteOutput (p, header, ucb, ecb);
421  return true;
422  }
423  }
424 
425  // Duplicate of own packet
426  if (IsMyOwnAddress (origin))
427  return true;
428 
429  // AODV is not a multicast routing protocol
430  if (dst.IsMulticast ())
431  {
432  return false;
433  }
434 
435  // Broadcast local delivery/forwarding
436  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
437  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
438  {
439  Ipv4InterfaceAddress iface = j->second;
440  if (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()) == iif)
441  if (dst == iface.GetBroadcast () || dst.IsBroadcast ())
442  {
443  if (m_dpd.IsDuplicate (p, header))
444  {
445  NS_LOG_DEBUG ("Duplicated packet " << p->GetUid () << " from " << origin << ". Drop.");
446  return true;
447  }
449  Ptr<Packet> packet = p->Copy ();
450  if (lcb.IsNull () == false)
451  {
452  NS_LOG_LOGIC ("Broadcast local delivery to " << iface.GetLocal ());
453  lcb (p, header, iif);
454  // Fall through to additional processing
455  }
456  else
457  {
458  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
459  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
460  }
461  if (!EnableBroadcast)
462  {
463  return true;
464  }
465  if (header.GetTtl () > 1)
466  {
467  NS_LOG_LOGIC ("Forward broadcast. TTL " << (uint16_t) header.GetTtl ());
468  RoutingTableEntry toBroadcast;
469  if (m_routingTable.LookupRoute (dst, toBroadcast))
470  {
471  Ptr<Ipv4Route> route = toBroadcast.GetRoute ();
472  ucb (route, packet, header);
473  }
474  else
475  {
476  NS_LOG_DEBUG ("No route to forward broadcast. Drop packet " << p->GetUid ());
477  }
478  }
479  else
480  {
481  NS_LOG_DEBUG ("TTL exceeded. Drop packet " << p->GetUid ());
482  }
483  return true;
484  }
485  }
486 
487  // Unicast local delivery
488  if (m_ipv4->IsDestinationAddress (dst, iif))
489  {
491  RoutingTableEntry toOrigin;
492  if (m_routingTable.LookupValidRoute (origin, toOrigin))
493  {
495  m_nb.Update (toOrigin.GetNextHop (), ActiveRouteTimeout);
496  }
497  if (lcb.IsNull () == false)
498  {
499  NS_LOG_LOGIC ("Unicast local delivery to " << dst);
500  lcb (p, header, iif);
501  }
502  else
503  {
504  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
505  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
506  }
507  return true;
508  }
509 
510  // Forwarding
511  return Forwarding (p, header, ucb, ecb);
512 }
513 
514 bool
517 {
518  NS_LOG_FUNCTION (this);
519  Ipv4Address dst = header.GetDestination ();
520  Ipv4Address origin = header.GetSource ();
522  RoutingTableEntry toDst;
523  if (m_routingTable.LookupRoute (dst, toDst))
524  {
525  if (toDst.GetFlag () == VALID)
526  {
527  Ptr<Ipv4Route> route = toDst.GetRoute ();
528  NS_LOG_LOGIC (route->GetSource ()<<" forwarding to " << dst << " from " << origin << " packet " << p->GetUid ());
529 
530  /*
531  * Each time a route is used to forward a data packet, its Active Route
532  * Lifetime field of the source, destination and the next hop on the
533  * path to the destination is updated to be no less than the current
534  * time plus ActiveRouteTimeout.
535  */
539  /*
540  * Since the route between each originator and destination pair is expected to be symmetric, the
541  * Active Route Lifetime for the previous hop, along the reverse path back to the IP source, is also updated
542  * to be no less than the current time plus ActiveRouteTimeout
543  */
544  RoutingTableEntry toOrigin;
545  m_routingTable.LookupRoute (origin, toOrigin);
546  UpdateRouteLifeTime (toOrigin.GetNextHop (), ActiveRouteTimeout);
547 
549  m_nb.Update (toOrigin.GetNextHop (), ActiveRouteTimeout);
550 
551  ucb (route, p, header);
552  return true;
553  }
554  else
555  {
556  if (toDst.GetValidSeqNo ())
557  {
558  SendRerrWhenNoRouteToForward (dst, toDst.GetSeqNo (), origin);
559  NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
560  return false;
561  }
562  }
563  }
564  NS_LOG_LOGIC ("route not found to "<< dst << ". Send RERR message.");
565  NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
566  SendRerrWhenNoRouteToForward (dst, 0, origin);
567  return false;
568 }
569 
570 void
572 {
573  NS_ASSERT (ipv4 != 0);
574  NS_ASSERT (m_ipv4 == 0);
575 
576  if (EnableHello)
577  {
579  m_htimer.Schedule (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 100)));
580  }
581 
582  m_ipv4 = ipv4;
583 
584  // Create lo route. It is asserted that the only one interface up for now is loopback
585  NS_ASSERT (m_ipv4->GetNInterfaces () == 1 && m_ipv4->GetAddress (0, 0).GetLocal () == Ipv4Address ("127.0.0.1"));
586  m_lo = m_ipv4->GetNetDevice (0);
587  NS_ASSERT (m_lo != 0);
588  // Remember lo route
589  RoutingTableEntry rt (/*device=*/ m_lo, /*dst=*/ Ipv4Address::GetLoopback (), /*know seqno=*/ true, /*seqno=*/ 0,
590  /*iface=*/ Ipv4InterfaceAddress (Ipv4Address::GetLoopback (), Ipv4Mask ("255.0.0.0")),
591  /*hops=*/ 1, /*next hop=*/ Ipv4Address::GetLoopback (),
592  /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
594 
596 }
597 
598 void
600 {
601  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
602  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
603  if (l3->GetNAddresses (i) > 1)
604  {
605  NS_LOG_WARN ("AODV does not work with more then one address per each interface.");
606  }
607  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
608  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
609  return;
610 
611  // Create a socket to listen only on this interface
612  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
614  NS_ASSERT (socket != 0);
616  socket->BindToNetDevice (l3->GetNetDevice (i));
618  socket->SetAllowBroadcast (true);
619  socket->SetAttribute ("IpTtl", UintegerValue (1));
620  m_socketAddresses.insert (std::make_pair (socket, iface));
621 
622  // Add local broadcast record to the routing table
623  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
624  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
625  /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
627 
628  // Allow neighbor manager use this interface for layer 2 feedback if possible
629  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
630  if (wifi == 0)
631  return;
632  Ptr<WifiMac> mac = wifi->GetMac ();
633  if (mac == 0)
634  return;
635 
636  mac->TraceConnectWithoutContext ("TxErrHeader", m_nb.GetTxErrorCallback ());
637  m_nb.AddArpCache (l3->GetInterface (i)->GetArpCache ());
638 }
639 
640 void
642 {
643  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
644 
645  // Disable layer 2 link state monitoring (if possible)
646  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
647  Ptr<NetDevice> dev = l3->GetNetDevice (i);
648  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
649  if (wifi != 0)
650  {
651  Ptr<WifiMac> mac = wifi->GetMac ()->GetObject<AdhocWifiMac> ();
652  if (mac != 0)
653  {
654  mac->TraceDisconnectWithoutContext ("TxErrHeader",
656  m_nb.DelArpCache (l3->GetInterface (i)->GetArpCache ());
657  }
658  }
659 
660  // Close socket
661  Ptr<Socket> socket = FindSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0));
662  NS_ASSERT (socket);
663  socket->Close ();
664  m_socketAddresses.erase (socket);
665  if (m_socketAddresses.empty ())
666  {
667  NS_LOG_LOGIC ("No aodv interfaces");
668  m_htimer.Cancel ();
669  m_nb.Clear ();
671  return;
672  }
674 }
675 
676 void
678 {
679  NS_LOG_FUNCTION (this << " interface " << i << " address " << address);
680  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
681  if (!l3->IsUp (i))
682  return;
683  if (l3->GetNAddresses (i) == 1)
684  {
685  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
687  if (!socket)
688  {
689  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
690  return;
691  // Create a socket to listen only on this interface
692  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
694  NS_ASSERT (socket != 0);
696  socket->BindToNetDevice (l3->GetNetDevice (i));
697  // Bind to any IP address so that broadcasts can be received
699  socket->SetAllowBroadcast (true);
700  m_socketAddresses.insert (std::make_pair (socket, iface));
701 
702  // Add local broadcast record to the routing table
703  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (
704  m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
705  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true,
706  /*seqno=*/ 0, /*iface=*/ iface, /*hops=*/ 1,
707  /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
709  }
710  }
711  else
712  {
713  NS_LOG_LOGIC ("AODV does not work with more then one address per each interface. Ignore added address");
714  }
715 }
716 
717 void
719 {
720  NS_LOG_FUNCTION (this);
721  Ptr<Socket> socket = FindSocketWithInterfaceAddress (address);
722  if (socket)
723  {
725  m_socketAddresses.erase (socket);
726  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
727  if (l3->GetNAddresses (i))
728  {
729  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
730  // Create a socket to listen only on this interface
731  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
733  NS_ASSERT (socket != 0);
735  // Bind to any IP address so that broadcasts can be received
737  socket->SetAllowBroadcast (true);
738  m_socketAddresses.insert (std::make_pair (socket, iface));
739 
740  // Add local broadcast record to the routing table
741  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
742  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
743  /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
745  }
746  if (m_socketAddresses.empty ())
747  {
748  NS_LOG_LOGIC ("No aodv interfaces");
749  m_htimer.Cancel ();
750  m_nb.Clear ();
752  return;
753  }
754  }
755  else
756  {
757  NS_LOG_LOGIC ("Remove address not participating in AODV operation");
758  }
759 }
760 
761 bool
763 {
764  NS_LOG_FUNCTION (this << src);
765  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
766  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
767  {
768  Ipv4InterfaceAddress iface = j->second;
769  if (src == iface.GetLocal ())
770  {
771  return true;
772  }
773  }
774  return false;
775 }
776 
779 {
780  NS_LOG_FUNCTION (this << hdr);
781  NS_ASSERT (m_lo != 0);
782  Ptr<Ipv4Route> rt = Create<Ipv4Route> ();
783  rt->SetDestination (hdr.GetDestination ());
784  //
785  // Source address selection here is tricky. The loopback route is
786  // returned when AODV does not have a route; this causes the packet
787  // to be looped back and handled (cached) in RouteInput() method
788  // while a route is found. However, connection-oriented protocols
789  // like TCP need to create an endpoint four-tuple (src, src port,
790  // dst, dst port) and create a pseudo-header for checksumming. So,
791  // AODV needs to guess correctly what the eventual source address
792  // will be.
793  //
794  // For single interface, single address nodes, this is not a problem.
795  // When there are possibly multiple outgoing interfaces, the policy
796  // implemented here is to pick the first available AODV interface.
797  // If RouteOutput() caller specified an outgoing interface, that
798  // further constrains the selection of source address
799  //
800  std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin ();
801  if (oif)
802  {
803  // Iterate to find an address on the oif device
804  for (j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
805  {
806  Ipv4Address addr = j->second.GetLocal ();
807  int32_t interface = m_ipv4->GetInterfaceForAddress (addr);
808  if (oif == m_ipv4->GetNetDevice (static_cast<uint32_t> (interface)))
809  {
810  rt->SetSource (addr);
811  break;
812  }
813  }
814  }
815  else
816  {
817  rt->SetSource (j->second.GetLocal ());
818  }
819  NS_ASSERT_MSG (rt->GetSource () != Ipv4Address (), "Valid AODV source address not found");
820  rt->SetGateway (Ipv4Address ("127.0.0.1"));
821  rt->SetOutputDevice (m_lo);
822  return rt;
823 }
824 
825 void
827 {
828  NS_LOG_FUNCTION ( this << dst);
829  // A node SHOULD NOT originate more than RREQ_RATELIMIT RREQ messages per second.
830  if (m_rreqCount == RreqRateLimit)
831  {
832  Simulator::Schedule (m_rreqRateLimitTimer.GetDelayLeft () + MicroSeconds (100),
833  &RoutingProtocol::SendRequest, this, dst);
834  return;
835  }
836  else
837  m_rreqCount++;
838  // Create RREQ header
839  RreqHeader rreqHeader;
840  rreqHeader.SetDst (dst);
841 
843  if (m_routingTable.LookupRoute (dst, rt))
844  {
845  rreqHeader.SetHopCount (rt.GetHop ());
846  if (rt.GetValidSeqNo ())
847  rreqHeader.SetDstSeqno (rt.GetSeqNo ());
848  else
849  rreqHeader.SetUnknownSeqno (true);
850  rt.SetFlag (IN_SEARCH);
851  m_routingTable.Update (rt);
852  }
853  else
854  {
855  rreqHeader.SetUnknownSeqno (true);
856  Ptr<NetDevice> dev = 0;
857  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ dst, /*validSeqNo=*/ false, /*seqno=*/ 0,
858  /*iface=*/ Ipv4InterfaceAddress (),/*hop=*/ 0,
859  /*nextHop=*/ Ipv4Address (), /*lifeTime=*/ Seconds (0));
860  newEntry.SetFlag (IN_SEARCH);
861  m_routingTable.AddRoute (newEntry);
862  }
863 
864  if (GratuitousReply)
865  rreqHeader.SetGratiousRrep (true);
866  if (DestinationOnly)
867  rreqHeader.SetDestinationOnly (true);
868 
869  m_seqNo++;
870  rreqHeader.SetOriginSeqno (m_seqNo);
871  m_requestId++;
872  rreqHeader.SetId (m_requestId);
873  rreqHeader.SetHopCount (0);
874 
875  // Send RREQ as subnet directed broadcast from each interface used by aodv
876  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
877  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
878  {
879  Ptr<Socket> socket = j->first;
880  Ipv4InterfaceAddress iface = j->second;
881 
882  rreqHeader.SetOrigin (iface.GetLocal ());
884 
885  Ptr<Packet> packet = Create<Packet> ();
886  packet->AddHeader (rreqHeader);
887  TypeHeader tHeader (AODVTYPE_RREQ);
888  packet->AddHeader (tHeader);
889  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
890  Ipv4Address destination;
891  if (iface.GetMask () == Ipv4Mask::GetOnes ())
892  {
893  destination = Ipv4Address ("255.255.255.255");
894  }
895  else
896  {
897  destination = iface.GetBroadcast ();
898  }
899  NS_LOG_DEBUG ("Send RREQ with id " << rreqHeader.GetId () << " to socket");
901  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, destination);
902  }
903  ScheduleRreqRetry (dst);
904 }
905 
906 void
908 {
909  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
910 
911 }
912 void
914 {
915  NS_LOG_FUNCTION (this << dst);
916  if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
917  {
919  m_addressReqTimer[dst] = timer;
920  }
922  m_addressReqTimer[dst].Remove ();
923  m_addressReqTimer[dst].SetArguments (dst);
925  m_routingTable.LookupRoute (dst, rt);
926  rt.IncrementRreqCnt ();
927  m_routingTable.Update (rt);
928  m_addressReqTimer[dst].Schedule (Time (rt.GetRreqCnt () * NetTraversalTime));
929  NS_LOG_LOGIC ("Scheduled RREQ retry in " << Time (rt.GetRreqCnt () * NetTraversalTime).GetSeconds () << " seconds");
930 }
931 
932 void
934 {
935  NS_LOG_FUNCTION (this << socket);
936  Address sourceAddress;
937  Ptr<Packet> packet = socket->RecvFrom (sourceAddress);
938  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
939  Ipv4Address sender = inetSourceAddr.GetIpv4 ();
940  Ipv4Address receiver = m_socketAddresses[socket].GetLocal ();
941  NS_LOG_DEBUG ("AODV node " << this << " received a AODV packet from " << sender << " to " << receiver);
942 
943  UpdateRouteToNeighbor (sender, receiver);
944  TypeHeader tHeader (AODVTYPE_RREQ);
945  packet->RemoveHeader (tHeader);
946  if (!tHeader.IsValid ())
947  {
948  NS_LOG_DEBUG ("AODV message " << packet->GetUid () << " with unknown type received: " << tHeader.Get () << ". Drop");
949  return; // drop
950  }
951  switch (tHeader.Get ())
952  {
953  case AODVTYPE_RREQ:
954  {
955  RecvRequest (packet, receiver, sender);
956  break;
957  }
958  case AODVTYPE_RREP:
959  {
960  RecvReply (packet, receiver, sender);
961  break;
962  }
963  case AODVTYPE_RERR:
964  {
965  RecvError (packet, sender);
966  break;
967  }
968  case AODVTYPE_RREP_ACK:
969  {
970  RecvReplyAck (sender);
971  break;
972  }
973  }
974 }
975 
976 bool
978 {
979  NS_LOG_FUNCTION (this << addr << lifetime);
981  if (m_routingTable.LookupRoute (addr, rt))
982  {
983  if (rt.GetFlag () == VALID)
984  {
985  NS_LOG_DEBUG ("Updating VALID route");
986  rt.SetRreqCnt (0);
987  rt.SetLifeTime (std::max (lifetime, rt.GetLifeTime ()));
988  m_routingTable.Update (rt);
989  return true;
990  }
991  }
992  return false;
993 }
994 
995 void
997 {
998  NS_LOG_FUNCTION (this << "sender " << sender << " receiver " << receiver);
999  RoutingTableEntry toNeighbor;
1000  if (!m_routingTable.LookupRoute (sender, toNeighbor))
1001  {
1002  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1003  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1004  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1005  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ ActiveRouteTimeout);
1006  m_routingTable.AddRoute (newEntry);
1007  }
1008  else
1009  {
1010  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1011  if (toNeighbor.GetValidSeqNo () && (toNeighbor.GetHop () == 1) && (toNeighbor.GetOutputDevice () == dev))
1012  {
1013  toNeighbor.SetLifeTime (std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()));
1014  }
1015  else
1016  {
1017  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1018  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1019  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()));
1020  m_routingTable.Update (newEntry);
1021  }
1022  }
1023 
1024 }
1025 
1026 void
1028 {
1029  NS_LOG_FUNCTION (this);
1030  RreqHeader rreqHeader;
1031  p->RemoveHeader (rreqHeader);
1032 
1033  // A node ignores all RREQs received from any node in its blacklist
1034  RoutingTableEntry toPrev;
1035  if (m_routingTable.LookupRoute (src, toPrev))
1036  {
1037  if (toPrev.IsUnidirectional ())
1038  {
1039  NS_LOG_DEBUG ("Ignoring RREQ from node in blacklist");
1040  return;
1041  }
1042  }
1043 
1044  uint32_t id = rreqHeader.GetId ();
1045  Ipv4Address origin = rreqHeader.GetOrigin ();
1046 
1047  /*
1048  * Node checks to determine whether it has received a RREQ with the same Originator IP Address and RREQ ID.
1049  * If such a RREQ has been received, the node silently discards the newly received RREQ.
1050  */
1051  if (m_rreqIdCache.IsDuplicate (origin, id))
1052  {
1053  NS_LOG_DEBUG ("Ignoring RREQ due to duplicate");
1054  return;
1055  }
1056 
1057  // Increment RREQ hop count
1058  uint8_t hop = rreqHeader.GetHopCount () + 1;
1059  rreqHeader.SetHopCount (hop);
1060 
1061  /*
1062  * When the reverse route is created or updated, the following actions on the route are also carried out:
1063  * 1. the Originator Sequence Number from the RREQ is compared to the corresponding destination sequence number
1064  * in the route table entry and copied if greater than the existing value there
1065  * 2. the valid sequence number field is set to true;
1066  * 3. the next hop in the routing table becomes the node from which the RREQ was received
1067  * 4. the hop count is copied from the Hop Count in the RREQ message;
1068  * 5. the Lifetime is set to be the maximum of (ExistingLifetime, MinimalLifetime), where
1069  * MinimalLifetime = current time + 2*NetTraversalTime - 2*HopCount*NodeTraversalTime
1070  */
1071  RoutingTableEntry toOrigin;
1072  if (!m_routingTable.LookupRoute (origin, toOrigin))
1073  {
1074  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1075  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ origin, /*validSeno=*/ true, /*seqNo=*/ rreqHeader.GetOriginSeqno (),
1076  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0), /*hops=*/ hop,
1077  /*nextHop*/ src, /*timeLife=*/ Time ((2 * NetTraversalTime - 2 * hop * NodeTraversalTime)));
1078  m_routingTable.AddRoute (newEntry);
1079  }
1080  else
1081  {
1082  if (toOrigin.GetValidSeqNo ())
1083  {
1084  if (int32_t (rreqHeader.GetOriginSeqno ()) - int32_t (toOrigin.GetSeqNo ()) > 0)
1085  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1086  }
1087  else
1088  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1089  toOrigin.SetValidSeqNo (true);
1090  toOrigin.SetNextHop (src);
1091  toOrigin.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1092  toOrigin.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1093  toOrigin.SetHop (hop);
1094  toOrigin.SetLifeTime (std::max (Time (2 * NetTraversalTime - 2 * hop * NodeTraversalTime),
1095  toOrigin.GetLifeTime ()));
1096  m_routingTable.Update (toOrigin);
1097  //m_nb.Update (src, Time (AllowedHelloLoss * HelloInterval));
1098  }
1099 
1100 
1101  RoutingTableEntry toNeighbor;
1102  if (!m_routingTable.LookupRoute (src, toNeighbor))
1103  {
1104  NS_LOG_DEBUG ("Neighbor:" << src << " not found in routing table. Creating an entry");
1105  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1106  RoutingTableEntry newEntry (dev, src, false, rreqHeader.GetOriginSeqno (),
1107  m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1108  1, src, ActiveRouteTimeout);
1109  m_routingTable.AddRoute (newEntry);
1110  }
1111  else
1112  {
1113  toNeighbor.SetLifeTime (ActiveRouteTimeout);
1114  toNeighbor.SetValidSeqNo (false);
1115  toNeighbor.SetSeqNo (rreqHeader.GetOriginSeqno ());
1116  toNeighbor.SetFlag (VALID);
1117  toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1118  toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1119  m_routingTable.Update (toNeighbor);
1120  }
1122 
1123  NS_LOG_LOGIC (receiver << " receive RREQ with hop count " << static_cast<uint32_t>(rreqHeader.GetHopCount ())
1124  << " ID " << rreqHeader.GetId ()
1125  << " to destination " << rreqHeader.GetDst ());
1126 
1127  // A node generates a RREP if either:
1128  // (i) it is itself the destination,
1129  if (IsMyOwnAddress (rreqHeader.GetDst ()))
1130  {
1131  m_routingTable.LookupRoute (origin, toOrigin);
1132  NS_LOG_DEBUG ("Send reply since I am the destination");
1133  SendReply (rreqHeader, toOrigin);
1134  return;
1135  }
1136  /*
1137  * (ii) or it has an active route to the destination, the destination sequence number in the node's existing route table entry for the destination
1138  * is valid and greater than or equal to the Destination Sequence Number of the RREQ, and the "destination only" flag is NOT set.
1139  */
1140  RoutingTableEntry toDst;
1141  Ipv4Address dst = rreqHeader.GetDst ();
1142  if (m_routingTable.LookupRoute (dst, toDst))
1143  {
1144  /*
1145  * Drop RREQ, This node RREP wil make a loop.
1146  */
1147  if (toDst.GetNextHop () == src)
1148  {
1149  NS_LOG_DEBUG ("Drop RREQ from " << src << ", dest next hop " << toDst.GetNextHop ());
1150  return;
1151  }
1152  /*
1153  * The Destination Sequence number for the requested destination is set to the maximum of the corresponding value
1154  * received in the RREQ message, and the destination sequence value currently maintained by the node for the requested destination.
1155  * However, the forwarding node MUST NOT modify its maintained value for the destination sequence number, even if the value
1156  * received in the incoming RREQ is larger than the value currently maintained by the forwarding node.
1157  */
1158  if ((rreqHeader.GetUnknownSeqno () || (int32_t (toDst.GetSeqNo ()) - int32_t (rreqHeader.GetDstSeqno ()) >= 0))
1159  && toDst.GetValidSeqNo () )
1160  {
1161  if (!rreqHeader.GetDestinationOnly () && toDst.GetFlag () == VALID)
1162  {
1163  m_routingTable.LookupRoute (origin, toOrigin);
1164  SendReplyByIntermediateNode (toDst, toOrigin, rreqHeader.GetGratiousRrep ());
1165  return;
1166  }
1167  rreqHeader.SetDstSeqno (toDst.GetSeqNo ());
1168  rreqHeader.SetUnknownSeqno (false);
1169  }
1170  }
1171 
1172  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1173  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1174  {
1175  Ptr<Socket> socket = j->first;
1176  Ipv4InterfaceAddress iface = j->second;
1177  Ptr<Packet> packet = Create<Packet> ();
1178  packet->AddHeader (rreqHeader);
1179  TypeHeader tHeader (AODVTYPE_RREQ);
1180  packet->AddHeader (tHeader);
1181  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1182  Ipv4Address destination;
1183  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1184  {
1185  destination = Ipv4Address ("255.255.255.255");
1186  }
1187  else
1188  {
1189  destination = iface.GetBroadcast ();
1190  }
1192  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, destination);
1193 
1194  }
1195 }
1196 
1197 void
1198 RoutingProtocol::SendReply (RreqHeader const & rreqHeader, RoutingTableEntry const & toOrigin)
1199 {
1200  NS_LOG_FUNCTION (this << toOrigin.GetDestination ());
1201  /*
1202  * Destination node MUST increment its own sequence number by one if the sequence number in the RREQ packet is equal to that
1203  * incremented value. Otherwise, the destination does not change its sequence number before generating the RREP message.
1204  */
1205  if (!rreqHeader.GetUnknownSeqno () && (rreqHeader.GetDstSeqno () == m_seqNo + 1))
1206  m_seqNo++;
1207  RrepHeader rrepHeader ( /*prefixSize=*/ 0, /*hops=*/ 0, /*dst=*/ rreqHeader.GetDst (),
1208  /*dstSeqNo=*/ m_seqNo, /*origin=*/ toOrigin.GetDestination (), /*lifeTime=*/ MyRouteTimeout);
1209  Ptr<Packet> packet = Create<Packet> ();
1210  packet->AddHeader (rrepHeader);
1211  TypeHeader tHeader (AODVTYPE_RREP);
1212  packet->AddHeader (tHeader);
1214  NS_ASSERT (socket);
1215  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1216 }
1217 
1218 void
1220 {
1221  NS_LOG_FUNCTION (this);
1222  RrepHeader rrepHeader (/*prefix size=*/ 0, /*hops=*/ toDst.GetHop (), /*dst=*/ toDst.GetDestination (), /*dst seqno=*/ toDst.GetSeqNo (),
1223  /*origin=*/ toOrigin.GetDestination (), /*lifetime=*/ toDst.GetLifeTime ());
1224  /* If the node we received a RREQ for is a neighbor we are
1225  * probably facing a unidirectional link... Better request a RREP-ack
1226  */
1227  if (toDst.GetHop () == 1)
1228  {
1229  rrepHeader.SetAckRequired (true);
1230  RoutingTableEntry toNextHop;
1231  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHop);
1233  toNextHop.m_ackTimer.SetArguments (toNextHop.GetDestination (), BlackListTimeout);
1234  toNextHop.m_ackTimer.SetDelay (NextHopWait);
1235  }
1236  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1237  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1238  m_routingTable.Update (toDst);
1239  m_routingTable.Update (toOrigin);
1240 
1241  Ptr<Packet> packet = Create<Packet> ();
1242  packet->AddHeader (rrepHeader);
1243  TypeHeader tHeader (AODVTYPE_RREP);
1244  packet->AddHeader (tHeader);
1246  NS_ASSERT (socket);
1247  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1248 
1249  // Generating gratuitous RREPs
1250  if (gratRep)
1251  {
1252  RrepHeader gratRepHeader (/*prefix size=*/ 0, /*hops=*/ toOrigin.GetHop (), /*dst=*/ toOrigin.GetDestination (),
1253  /*dst seqno=*/ toOrigin.GetSeqNo (), /*origin=*/ toDst.GetDestination (),
1254  /*lifetime=*/ toOrigin.GetLifeTime ());
1255  Ptr<Packet> packetToDst = Create<Packet> ();
1256  packetToDst->AddHeader (gratRepHeader);
1257  TypeHeader type (AODVTYPE_RREP);
1258  packetToDst->AddHeader (type);
1260  NS_ASSERT (socket);
1261  NS_LOG_LOGIC ("Send gratuitous RREP " << packet->GetUid ());
1262  socket->SendTo (packetToDst, 0, InetSocketAddress (toDst.GetNextHop (), AODV_PORT));
1263  }
1264 }
1265 
1266 void
1268 {
1269  NS_LOG_FUNCTION (this << " to " << neighbor);
1270  RrepAckHeader h;
1271  TypeHeader typeHeader (AODVTYPE_RREP_ACK);
1272  Ptr<Packet> packet = Create<Packet> ();
1273  packet->AddHeader (h);
1274  packet->AddHeader (typeHeader);
1275  RoutingTableEntry toNeighbor;
1276  m_routingTable.LookupRoute (neighbor, toNeighbor);
1277  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toNeighbor.GetInterface ());
1278  NS_ASSERT (socket);
1279  socket->SendTo (packet, 0, InetSocketAddress (neighbor, AODV_PORT));
1280 }
1281 
1282 void
1284 {
1285  NS_LOG_FUNCTION (this << " src " << sender);
1286  RrepHeader rrepHeader;
1287  p->RemoveHeader (rrepHeader);
1288  Ipv4Address dst = rrepHeader.GetDst ();
1289  NS_LOG_LOGIC ("RREP destination " << dst << " RREP origin " << rrepHeader.GetOrigin ());
1290 
1291  uint8_t hop = rrepHeader.GetHopCount () + 1;
1292  rrepHeader.SetHopCount (hop);
1293 
1294  // If RREP is Hello message
1295  if (dst == rrepHeader.GetOrigin ())
1296  {
1297  ProcessHello (rrepHeader, receiver);
1298  return;
1299  }
1300 
1301  /*
1302  * If the route table entry to the destination is created or updated, then the following actions occur:
1303  * - the route is marked as active,
1304  * - the destination sequence number is marked as valid,
1305  * - the next hop in the route entry is assigned to be the node from which the RREP is received,
1306  * which is indicated by the source IP address field in the IP header,
1307  * - the hop count is set to the value of the hop count from RREP message + 1
1308  * - the expiry time is set to the current time plus the value of the Lifetime in the RREP message,
1309  * - and the destination sequence number is the Destination Sequence Number in the RREP message.
1310  */
1311  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1312  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ dst, /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1313  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),/*hop=*/ hop,
1314  /*nextHop=*/ sender, /*lifeTime=*/ rrepHeader.GetLifeTime ());
1315  RoutingTableEntry toDst;
1316  if (m_routingTable.LookupRoute (dst, toDst))
1317  {
1318  /*
1319  * The existing entry is updated only in the following circumstances:
1320  * (i) the sequence number in the routing table is marked as invalid in route table entry.
1321  */
1322  if (!toDst.GetValidSeqNo ())
1323  {
1324  m_routingTable.Update (newEntry);
1325  }
1326  // (ii)the Destination Sequence Number in the RREP is greater than the node's copy of the destination sequence number and the known value is valid,
1327  else if ((int32_t (rrepHeader.GetDstSeqno ()) - int32_t (toDst.GetSeqNo ())) > 0)
1328  {
1329  m_routingTable.Update (newEntry);
1330  }
1331  else
1332  {
1333  // (iii) the sequence numbers are the same, but the route is marked as inactive.
1334  if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (toDst.GetFlag () != VALID))
1335  {
1336  m_routingTable.Update (newEntry);
1337  }
1338  // (iv) the sequence numbers are the same, and the New Hop Count is smaller than the hop count in route table entry.
1339  else if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (hop < toDst.GetHop ()))
1340  {
1341  m_routingTable.Update (newEntry);
1342  }
1343  }
1344  }
1345  else
1346  {
1347  // The forward route for this destination is created if it does not already exist.
1348  NS_LOG_LOGIC ("add new route");
1349  m_routingTable.AddRoute (newEntry);
1350  }
1351  // Acknowledge receipt of the RREP by sending a RREP-ACK message back
1352  if (rrepHeader.GetAckRequired ())
1353  {
1354  SendReplyAck (sender);
1355  rrepHeader.SetAckRequired (false);
1356  }
1357  NS_LOG_LOGIC ("receiver " << receiver << " origin " << rrepHeader.GetOrigin ());
1358  if (IsMyOwnAddress (rrepHeader.GetOrigin ()))
1359  {
1360  if (toDst.GetFlag () == IN_SEARCH)
1361  {
1362  m_routingTable.Update (newEntry);
1363  m_addressReqTimer[dst].Remove ();
1364  m_addressReqTimer.erase (dst);
1365  }
1366  m_routingTable.LookupRoute (dst, toDst);
1367  SendPacketFromQueue (dst, toDst.GetRoute ());
1368  return;
1369  }
1370 
1371  RoutingTableEntry toOrigin;
1372  if (!m_routingTable.LookupRoute (rrepHeader.GetOrigin (), toOrigin) || toOrigin.GetFlag () == IN_SEARCH)
1373  {
1374  return; // Impossible! drop.
1375  }
1376  toOrigin.SetLifeTime (std::max (ActiveRouteTimeout, toOrigin.GetLifeTime ()));
1377  m_routingTable.Update (toOrigin);
1378 
1379  // Update information about precursors
1380  if (m_routingTable.LookupValidRoute (rrepHeader.GetDst (), toDst))
1381  {
1382  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1383  m_routingTable.Update (toDst);
1384 
1385  RoutingTableEntry toNextHopToDst;
1386  m_routingTable.LookupRoute (toDst.GetNextHop (), toNextHopToDst);
1387  toNextHopToDst.InsertPrecursor (toOrigin.GetNextHop ());
1388  m_routingTable.Update (toNextHopToDst);
1389 
1390  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1391  m_routingTable.Update (toOrigin);
1392 
1393  RoutingTableEntry toNextHopToOrigin;
1394  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHopToOrigin);
1395  toNextHopToOrigin.InsertPrecursor (toDst.GetNextHop ());
1396  m_routingTable.Update (toNextHopToOrigin);
1397  }
1398 
1399  Ptr<Packet> packet = Create<Packet> ();
1400  packet->AddHeader (rrepHeader);
1401  TypeHeader tHeader (AODVTYPE_RREP);
1402  packet->AddHeader (tHeader);
1404  NS_ASSERT (socket);
1405  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1406 }
1407 
1408 void
1410 {
1411  NS_LOG_FUNCTION (this);
1412  RoutingTableEntry rt;
1413  if(m_routingTable.LookupRoute (neighbor, rt))
1414  {
1415  rt.m_ackTimer.Cancel ();
1416  rt.SetFlag (VALID);
1417  m_routingTable.Update (rt);
1418  }
1419 }
1420 
1421 void
1423 {
1424  NS_LOG_FUNCTION (this << "from " << rrepHeader.GetDst ());
1425  /*
1426  * Whenever a node receives a Hello message from a neighbor, the node
1427  * SHOULD make sure that it has an active route to the neighbor, and
1428  * create one if necessary.
1429  */
1430  RoutingTableEntry toNeighbor;
1431  if (!m_routingTable.LookupRoute (rrepHeader.GetDst (), toNeighbor))
1432  {
1433  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1434  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ rrepHeader.GetDst (), /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1435  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1436  /*hop=*/ 1, /*nextHop=*/ rrepHeader.GetDst (), /*lifeTime=*/ rrepHeader.GetLifeTime ());
1437  m_routingTable.AddRoute (newEntry);
1438  }
1439  else
1440  {
1441  toNeighbor.SetLifeTime (std::max (Time (AllowedHelloLoss * HelloInterval), toNeighbor.GetLifeTime ()));
1442  toNeighbor.SetSeqNo (rrepHeader.GetDstSeqno ());
1443  toNeighbor.SetValidSeqNo (true);
1444  toNeighbor.SetFlag (VALID);
1445  toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1446  toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1447  m_routingTable.Update (toNeighbor);
1448  }
1449  if (EnableHello)
1450  {
1451  m_nb.Update (rrepHeader.GetDst (), Time (AllowedHelloLoss * HelloInterval));
1452  }
1453 }
1454 
1455 void
1457 {
1458  NS_LOG_FUNCTION (this << " from " << src);
1459  RerrHeader rerrHeader;
1460  p->RemoveHeader (rerrHeader);
1461  std::map<Ipv4Address, uint32_t> dstWithNextHopSrc;
1462  std::map<Ipv4Address, uint32_t> unreachable;
1463  m_routingTable.GetListOfDestinationWithNextHop (src, dstWithNextHopSrc);
1464  std::pair<Ipv4Address, uint32_t> un;
1465  while (rerrHeader.RemoveUnDestination (un))
1466  {
1467  for (std::map<Ipv4Address, uint32_t>::const_iterator i =
1468  dstWithNextHopSrc.begin (); i != dstWithNextHopSrc.end (); ++i)
1469  {
1470  if (i->first == un.first)
1471  {
1472  unreachable.insert (un);
1473  }
1474  }
1475  }
1476 
1477  std::vector<Ipv4Address> precursors;
1478  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin ();
1479  i != unreachable.end ();)
1480  {
1481  if (!rerrHeader.AddUnDestination (i->first, i->second))
1482  {
1483  TypeHeader typeHeader (AODVTYPE_RERR);
1484  Ptr<Packet> packet = Create<Packet> ();
1485  packet->AddHeader (rerrHeader);
1486  packet->AddHeader (typeHeader);
1487  SendRerrMessage (packet, precursors);
1488  rerrHeader.Clear ();
1489  }
1490  else
1491  {
1492  RoutingTableEntry toDst;
1493  m_routingTable.LookupRoute (i->first, toDst);
1494  toDst.GetPrecursors (precursors);
1495  ++i;
1496  }
1497  }
1498  if (rerrHeader.GetDestCount () != 0)
1499  {
1500  TypeHeader typeHeader (AODVTYPE_RERR);
1501  Ptr<Packet> packet = Create<Packet> ();
1502  packet->AddHeader (rerrHeader);
1503  packet->AddHeader (typeHeader);
1504  SendRerrMessage (packet, precursors);
1505  }
1507 }
1508 
1509 void
1511 {
1512  NS_LOG_LOGIC (this);
1513  RoutingTableEntry toDst;
1514  if (m_routingTable.LookupValidRoute (dst, toDst))
1515  {
1516  SendPacketFromQueue (dst, toDst.GetRoute ());
1517  NS_LOG_LOGIC ("route to " << dst << " found");
1518  return;
1519  }
1520  /*
1521  * If a route discovery has been attempted RreqRetries times at the maximum TTL without
1522  * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
1523  * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the application.
1524  */
1525  if (toDst.GetRreqCnt () == RreqRetries)
1526  {
1527  NS_LOG_LOGIC ("route discovery to " << dst << " has been attempted RreqRetries (" << RreqRetries << ") times");
1528  m_addressReqTimer.erase (dst);
1530  NS_LOG_DEBUG ("Route not found. Drop all packets with dst " << dst);
1531  m_queue.DropPacketWithDst (dst);
1532  return;
1533  }
1534 
1535  if (toDst.GetFlag () == IN_SEARCH)
1536  {
1537  NS_LOG_LOGIC ("Resend RREQ to " << dst << " ttl " << NetDiameter);
1538  SendRequest (dst);
1539  }
1540  else
1541  {
1542  NS_LOG_DEBUG ("Route down. Stop search. Drop packet with destination " << dst);
1543  m_addressReqTimer.erase (dst);
1545  m_queue.DropPacketWithDst (dst);
1546  }
1547 }
1548 
1549 void
1551 {
1552  NS_LOG_FUNCTION (this);
1553  Time offset = Time (Seconds (0));
1554  if (m_lastBcastTime > Time (Seconds (0)))
1555  {
1556  offset = Simulator::Now () - m_lastBcastTime;
1557  NS_LOG_DEBUG ("Hello deferred due to last bcast at:" << m_lastBcastTime);
1558  }
1559  else
1560  {
1561  SendHello ();
1562  }
1563  m_htimer.Cancel ();
1564  Time diff = HelloInterval - offset;
1565  m_htimer.Schedule (std::max (Time (Seconds (0)), diff));
1566  m_lastBcastTime = Time (Seconds (0));
1567 }
1568 
1569 void
1571 {
1572  NS_LOG_FUNCTION (this);
1573  m_rreqCount = 0;
1574  m_rreqRateLimitTimer.Schedule (Seconds (1));
1575 }
1576 
1577 void
1579 {
1580  NS_LOG_FUNCTION (this);
1581  m_rerrCount = 0;
1582  m_rerrRateLimitTimer.Schedule (Seconds (1));
1583 }
1584 
1585 void
1587 {
1588  NS_LOG_FUNCTION (this);
1589  m_routingTable.MarkLinkAsUnidirectional (neighbor, blacklistTimeout);
1590 }
1591 
1592 void
1594 {
1595  NS_LOG_FUNCTION (this);
1596  /* Broadcast a RREP with TTL = 1 with the RREP message fields set as follows:
1597  * Destination IP Address The node's IP address.
1598  * Destination Sequence Number The node's latest sequence number.
1599  * Hop Count 0
1600  * Lifetime AllowedHelloLoss * HelloInterval
1601  */
1602  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1603  {
1604  Ptr<Socket> socket = j->first;
1605  Ipv4InterfaceAddress iface = j->second;
1606  RrepHeader helloHeader (/*prefix size=*/ 0, /*hops=*/ 0, /*dst=*/ iface.GetLocal (), /*dst seqno=*/ m_seqNo,
1607  /*origin=*/ iface.GetLocal (),/*lifetime=*/ Time (AllowedHelloLoss * HelloInterval));
1608  Ptr<Packet> packet = Create<Packet> ();
1609  packet->AddHeader (helloHeader);
1610  TypeHeader tHeader (AODVTYPE_RREP);
1611  packet->AddHeader (tHeader);
1612  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1613  Ipv4Address destination;
1614  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1615  {
1616  destination = Ipv4Address ("255.255.255.255");
1617  }
1618  else
1619  {
1620  destination = iface.GetBroadcast ();
1621  }
1622  Time jitter = Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10)));
1623  Simulator::Schedule (jitter, &RoutingProtocol::SendTo, this , socket, packet, destination);
1624  }
1625 }
1626 
1627 void
1629 {
1630  NS_LOG_FUNCTION (this);
1631  QueueEntry queueEntry;
1632  while (m_queue.Dequeue (dst, queueEntry))
1633  {
1635  Ptr<Packet> p = ConstCast<Packet> (queueEntry.GetPacket ());
1636  if (p->RemovePacketTag (tag) &&
1637  tag.GetInterface() != -1 &&
1638  tag.GetInterface() != m_ipv4->GetInterfaceForDevice (route->GetOutputDevice ()))
1639  {
1640  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
1641  return;
1642  }
1644  Ipv4Header header = queueEntry.GetIpv4Header ();
1645  header.SetSource (route->GetSource ());
1646  header.SetTtl (header.GetTtl () + 1); // compensate extra TTL decrement by fake loopback routing
1647  ucb (route, p, header);
1648  }
1649 }
1650 
1651 void
1653 {
1654  NS_LOG_FUNCTION (this << nextHop);
1655  RerrHeader rerrHeader;
1656  std::vector<Ipv4Address> precursors;
1657  std::map<Ipv4Address, uint32_t> unreachable;
1658 
1659  RoutingTableEntry toNextHop;
1660  if (!m_routingTable.LookupRoute (nextHop, toNextHop))
1661  return;
1662  toNextHop.GetPrecursors (precursors);
1663  rerrHeader.AddUnDestination (nextHop, toNextHop.GetSeqNo ());
1664  m_routingTable.GetListOfDestinationWithNextHop (nextHop, unreachable);
1665  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin (); i
1666  != unreachable.end ();)
1667  {
1668  if (!rerrHeader.AddUnDestination (i->first, i->second))
1669  {
1670  NS_LOG_LOGIC ("Send RERR message with maximum size.");
1671  TypeHeader typeHeader (AODVTYPE_RERR);
1672  Ptr<Packet> packet = Create<Packet> ();
1673  packet->AddHeader (rerrHeader);
1674  packet->AddHeader (typeHeader);
1675  SendRerrMessage (packet, precursors);
1676  rerrHeader.Clear ();
1677  }
1678  else
1679  {
1680  RoutingTableEntry toDst;
1681  m_routingTable.LookupRoute (i->first, toDst);
1682  toDst.GetPrecursors (precursors);
1683  ++i;
1684  }
1685  }
1686  if (rerrHeader.GetDestCount () != 0)
1687  {
1688  TypeHeader typeHeader (AODVTYPE_RERR);
1689  Ptr<Packet> packet = Create<Packet> ();
1690  packet->AddHeader (rerrHeader);
1691  packet->AddHeader (typeHeader);
1692  SendRerrMessage (packet, precursors);
1693  }
1694  unreachable.insert (std::make_pair (nextHop, toNextHop.GetSeqNo ()));
1696 }
1697 
1698 void
1700  uint32_t dstSeqNo, Ipv4Address origin)
1701 {
1702  NS_LOG_FUNCTION (this);
1703  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
1704  if (m_rerrCount == RerrRateLimit)
1705  {
1706  // Just make sure that the RerrRateLimit timer is running and will expire
1708  // discard the packet and return
1709  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
1711  << "; suppressing RERR");
1712  return;
1713  }
1714  RerrHeader rerrHeader;
1715  rerrHeader.AddUnDestination (dst, dstSeqNo);
1716  RoutingTableEntry toOrigin;
1717  Ptr<Packet> packet = Create<Packet> ();
1718  packet->AddHeader (rerrHeader);
1719  packet->AddHeader (TypeHeader (AODVTYPE_RERR));
1720  if (m_routingTable.LookupValidRoute (origin, toOrigin))
1721  {
1723  toOrigin.GetInterface ());
1724  NS_ASSERT (socket);
1725  NS_LOG_LOGIC ("Unicast RERR to the source of the data transmission");
1726  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1727  }
1728  else
1729  {
1730  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
1731  m_socketAddresses.begin (); i != m_socketAddresses.end (); ++i)
1732  {
1733  Ptr<Socket> socket = i->first;
1734  Ipv4InterfaceAddress iface = i->second;
1735  NS_ASSERT (socket);
1736  NS_LOG_LOGIC ("Broadcast RERR message from interface " << iface.GetLocal ());
1737  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1738  Ipv4Address destination;
1739  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1740  {
1741  destination = Ipv4Address ("255.255.255.255");
1742  }
1743  else
1744  {
1745  destination = iface.GetBroadcast ();
1746  }
1747  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
1748  }
1749  }
1750 }
1751 
1752 void
1753 RoutingProtocol::SendRerrMessage (Ptr<Packet> packet, std::vector<Ipv4Address> precursors)
1754 {
1755  NS_LOG_FUNCTION (this);
1756 
1757  if (precursors.empty ())
1758  {
1759  NS_LOG_LOGIC ("No precursors");
1760  return;
1761  }
1762  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
1763  if (m_rerrCount == RerrRateLimit)
1764  {
1765  // Just make sure that the RerrRateLimit timer is running and will expire
1767  // discard the packet and return
1768  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
1770  << "; suppressing RERR");
1771  return;
1772  }
1773  // If there is only one precursor, RERR SHOULD be unicast toward that precursor
1774  if (precursors.size () == 1)
1775  {
1776  RoutingTableEntry toPrecursor;
1777  if (m_routingTable.LookupValidRoute (precursors.front (), toPrecursor))
1778  {
1779  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toPrecursor.GetInterface ());
1780  NS_ASSERT (socket);
1781  NS_LOG_LOGIC ("one precursor => unicast RERR to " << toPrecursor.GetDestination () << " from " << toPrecursor.GetInterface ().GetLocal ());
1782  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, precursors.front ());
1783  m_rerrCount++;
1784  }
1785  return;
1786  }
1787 
1788  // Should only transmit RERR on those interfaces which have precursor nodes for the broken route
1789  std::vector<Ipv4InterfaceAddress> ifaces;
1790  RoutingTableEntry toPrecursor;
1791  for (std::vector<Ipv4Address>::const_iterator i = precursors.begin (); i != precursors.end (); ++i)
1792  {
1793  if (m_routingTable.LookupValidRoute (*i, toPrecursor) &&
1794  std::find (ifaces.begin (), ifaces.end (), toPrecursor.GetInterface ()) == ifaces.end ())
1795  {
1796  ifaces.push_back (toPrecursor.GetInterface ());
1797  }
1798  }
1799 
1800  for (std::vector<Ipv4InterfaceAddress>::const_iterator i = ifaces.begin (); i != ifaces.end (); ++i)
1801  {
1803  NS_ASSERT (socket);
1804  NS_LOG_LOGIC ("Broadcast RERR message from interface " << i->GetLocal ());
1805  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1806  Ipv4Address destination;
1807  if (i->GetMask () == Ipv4Mask::GetOnes ())
1808  {
1809  destination = Ipv4Address ("255.255.255.255");
1810  }
1811  else
1812  {
1813  destination = i->GetBroadcast ();
1814  }
1815  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, destination);
1816  }
1817 }
1818 
1821 {
1822  NS_LOG_FUNCTION (this << addr);
1823  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1824  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1825  {
1826  Ptr<Socket> socket = j->first;
1827  Ipv4InterfaceAddress iface = j->second;
1828  if (iface == addr)
1829  return socket;
1830  }
1831  Ptr<Socket> socket;
1832  return socket;
1833 }
1834 
1835 }
1836 }
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:284
UnicastForwardCallback GetUnicastForwardCallback() const
Definition: aodv-rqueue.h:66
uint32_t RemoveHeader(Header &header)
Definition: packet.cc:268
static TypeId GetTypeId(void)
void SendReplyAck(Ipv4Address neighbor)
Send RREP_ACK.
static Ipv4Mask GetOnes(void)
void InvalidateRoutesWithDst(std::map< Ipv4Address, uint32_t > const &unreachable)
Definition: aodv-rtable.cc:314
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
NS_OBJECT_ENSURE_REGISTERED(TypeHeader)
bool MarkLinkAsUnidirectional(Ipv4Address neighbor, Time blacklistTimeout)
Definition: aodv-rtable.cc:420
an Inet address class
Ipv4Address GetIpv4(void) const
static Ipv4Address GetAny(void)
void SetOutputDevice(Ptr< NetDevice > dev)
RREP_ACK timer.
Definition: aodv-rtable.h:111
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
uint16_t m_rreqCount
Number of RREQs used for RREQ rate control.
Hold a bool native type.
Definition: boolean.h:38
Callback template class.
Definition: callback.h:920
Time MaxQueueTime
The maximum period of time that a routing protocol is allowed to buffer a packet for.
NS_LOG_COMPONENT_DEFINE("AodvRoutingProtocol")
bool GetUnknownSeqno() const
Definition: aodv-packet.cc:262
bool LookupRoute(Ipv4Address dst, RoutingTableEntry &rt)
Definition: aodv-rtable.cc:199
void Clear()
Delete all entries from routing table.
Definition: aodv-rtable.h:236
void SendTo(Ptr< Socket > socket, Ptr< Packet > packet, Ipv4Address destination)
RoutingTable m_routingTable
Routing table.
uint32_t GetInteger(uint32_t min, uint32_t max)
Returns a random unsigned integer from a uniform distribution over the interval [min,max] including both ends.
a simple Timer class
Definition: timer.h:45
Ipv4Header GetIpv4Header() const
Definition: aodv-rqueue.h:72
void SetId(uint32_t id)
Definition: aodv-packet.h:125
bool GetAckRequired() const
Definition: aodv-packet.cc:377
Ipv4Address GetLocal(void) const
hold variables of type string
Definition: string.h:19
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
Route Error (RERR) Message Format.
Definition: aodv-packet.h:288
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:210
Routing table entry.
Definition: aodv-rtable.h:59
Tag used by AODV implementation.
void AddPacketTag(const Tag &tag) const
Definition: packet.cc:841
uint32_t MaxQueueLen
The maximum number of packets that we allow a routing protocol to buffer.
Ptr< Ipv4 > m_ipv4
IP protocol.
bool Update(RoutingTableEntry &rt)
Update routing table.
Definition: aodv-rtable.cc:260
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the Routing Table entries.
uint64_t GetUid(void) const
Definition: packet.cc:393
Timer m_ackTimer
RREP_ACK timer.
Definition: aodv-rtable.h:133
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:303
void IncrementRreqCnt()
RREP_ACK timer.
Definition: aodv-rtable.h:127
bool Forwarding(Ptr< const Packet > p, const Ipv4Header &header, UnicastForwardCallback ucb, ErrorCallback ecb)
If route exists and valid, forward packet.
bool IsNull(void) const
Definition: callback.h:1014
void SetMaxQueueLen(uint32_t len)
Definition: aodv-rqueue.h:116
#define NS_ASSERT(condition)
Definition: assert.h:64
void SetDst(Ipv4Address a)
Definition: aodv-packet.h:127
void DelArpCache(Ptr< ArpCache >)
Don't use given ARP cache any more (interface is down)
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:271
uint32_t GetDstSeqno() const
Definition: aodv-packet.h:204
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
int64_t AssignStreams(int64_t stream)
Timer m_rreqRateLimitTimer
RREQ rate limit timer.
bool IsMulticast(void) const
virtual void DoDispose(void)
Definition: object.cc:335
Ptr< NetDevice > GetOutputDevice() const
RREP_ACK timer.
Definition: aodv-rtable.h:112
Time NetTraversalTime
Estimate of the average net traversal time.
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:290
Neighbors m_nb
Handle neighbors.
void GetPrecursors(std::vector< Ipv4Address > &prec) const
Definition: aodv-rtable.cc:127
TAG_BUFFER_INLINE uint32_t ReadU32(void)
Definition: tag-buffer.h:199
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:824
void SetLifeTime(Time lt)
RREP_ACK timer.
Definition: aodv-rtable.h:121
uint32_t RreqRetries
Maximum number of retransmissions of RREQ with TTL = NetDiameter to discover a route.
Route Request (RREQ) Message Format.
Definition: aodv-packet.h:102
Time m_lastBcastTime
Keep track of the last bcast time.
AODVTYPE_RERR.
Definition: aodv-packet.h:45
RequestQueue m_queue
A "drop-front" queue used by the routing layer to buffer packets to which it does not have a route...
bool Enqueue(QueueEntry &entry)
Push entry in queue, if there is no entry with the same packet and destination address in queue...
Definition: aodv-rqueue.cc:49
uint32_t m_seqNo
Request sequence number.
void ScheduleRreqRetry(Ipv4Address dst)
Ptr< Socket > FindSocketWithInterfaceAddress(Ipv4InterfaceAddress iface) const
Find socket with local interface address iface.
a polymophic address class
Definition: address.h:86
bool IsRunning(void) const
Definition: timer.cc:121
Ptr< Ipv4Route > LoopbackRoute(const Ipv4Header &header, Ptr< NetDevice > oif) const
Create loopback route for given header.
bool IsValid() const
Check that type if valid.
Definition: aodv-packet.h:72
void SetSource(Ipv4Address src)
Definition: ipv4-route.cc:49
void RecvAodv(Ptr< Socket > socket)
Receive and process control packet.
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
Ptr< NetDevice > GetOutputDevice(void) const
Definition: ipv4-route.cc:84
void Clear()
Clear header.
Definition: aodv-packet.cc:605
bool InsertPrecursor(Ipv4Address id)
Definition: aodv-rtable.cc:65
Packet header for IPv4.
Definition: ipv4-header.h:31
double GetSeconds(void) const
Definition: nstime.h:266
void Print(Ptr< OutputStreamWrapper > stream) const
Print routing table.
Definition: aodv-rtable.cc:438
Time GetLifeTime() const
RREP_ACK timer.
Definition: aodv-rtable.h:122
bool DestinationOnly
Indicates only the destination may respond to this RREQ.
void SetRreqCnt(uint8_t n)
RREP_ACK timer.
Definition: aodv-rtable.h:125
void RecvReplyAck(Ipv4Address neighbor)
Receive RREP_ACK.
bool PeekPacketTag(Tag &tag) const
Definition: packet.cc:863
bool IsDuplicate(Ptr< const Packet > p, const Ipv4Header &header)
Check that the packet is duplicated. If not, save information about this packet.
Definition: aodv-dpd.cc:31
void SendPacketFromQueue(Ipv4Address dst, Ptr< Ipv4Route > route)
Forward packet from route request queue.
void DeferredRouteOutput(Ptr< const Packet > p, const Ipv4Header &header, UnicastForwardCallback ucb, ErrorCallback ecb)
Queue packet and send route request.
void SetHopCount(uint8_t count)
Definition: aodv-packet.h:199
bool IsMyOwnAddress(Ipv4Address src)
Check that packet is send from own interface.
bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
Route an input packet (to be forwarded or locally delivered)
void RecvReply(Ptr< Packet > p, Ipv4Address my, Ipv4Address src)
Receive RREP.
bool GetGratiousRrep() const
Definition: aodv-packet.cc:232
void DeleteAllRoutesFromInterface(Ipv4InterfaceAddress iface)
Delete all route from interface with address iface.
Definition: aodv-rtable.cc:334
void HelloTimerExpire()
Schedule next send of hello message.
hold objects of type ns3::Time
Definition: nstime.h:828
void Schedule(void)
Definition: timer.cc:152
uint8_t GetDestCount() const
Return number of unreachable destinations in RERR message.
Definition: aodv-packet.h:322
Ipv4Address GetNextHop() const
RREP_ACK timer.
Definition: aodv-rtable.h:110
bool AddUnDestination(Ipv4Address dst, uint32_t seqNo)
Definition: aodv-packet.cc:583
void SetGateway(Ipv4Address gw)
Definition: ipv4-route.cc:63
void SetFunction(FN fn)
Definition: timer.h:254
bool UpdateRouteLifeTime(Ipv4Address addr, Time lt)
Hold an unsigned integer type.
Definition: uinteger.h:46
void UpdateRouteToNeighbor(Ipv4Address sender, Ipv4Address receiver)
Ipv4Address GetDst() const
Definition: aodv-packet.h:128
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
Definition: tag-buffer.h:170
bool IsBroadcast(void) const
void SetSeqNo(uint32_t sn)
RREP_ACK timer.
Definition: aodv-rtable.h:117
uint16_t RreqRateLimit
Maximum number of RREQ per second.
void SetValidSeqNo(bool s)
RREP_ACK timer.
Definition: aodv-rtable.h:115
void SetOriginSeqno(uint32_t s)
Definition: aodv-packet.h:133
int32_t m_oif
Positive if output device is fixed in RouteOutput.
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)
Hold together all Wifi-related objects.This class holds together ns3::WifiChannel, ns3::WifiPhy, ns3::WifiMac, and, ns3::WifiRemoteStationManager.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
uint8_t GetHopCount() const
Definition: aodv-packet.h:124
void SetDestinationOnly(bool f)
Definition: aodv-packet.cc:238
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:127
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
Definition: socket.cc:70
void SendReplyByIntermediateNode(RoutingTableEntry &toDst, RoutingTableEntry &toOrigin, bool gratRep)
Ipv4Address GetSource(void) const
Definition: ipv4-route.cc:56
void AddArpCache(Ptr< ArpCache >)
Add ARP cache to be used to allow layer 2 notifications processing.
AODVTYPE_RREP.
Definition: aodv-packet.h:44
Ptr< const Packet > GetPacket() const
Definition: aodv-rqueue.h:70
Ipv4InterfaceAddress GetInterface() const
RREP_ACK timer.
Definition: aodv-rtable.h:113
Callback< void, WifiMacHeader const & > GetTxErrorCallback() const
Get callback to ProcessTxError.
Definition: aodv-neighbor.h:86
void SetDelay(const Time &delay)
Definition: timer.cc:69
void DropPacketWithDst(Ipv4Address dst)
Remove all packets with destination IP address dst.
Definition: aodv-rqueue.cc:71
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
uint16_t m_rerrCount
Number of RERRs used for RERR rate control.
Ipv4Address GetGateway(void) const
Definition: ipv4-route.cc:70
void SetDstSeqno(uint32_t s)
Definition: aodv-packet.h:129
Route Reply (RREP) Message Format.
Definition: aodv-packet.h:180
void GetListOfDestinationWithNextHop(Ipv4Address nextHop, std::map< Ipv4Address, uint32_t > &unreachable)
Lookup routing entries with next hop Address dst and not empty list of precursors.
Definition: aodv-rtable.cc:297
void SetInterface(Ipv4InterfaceAddress iface)
RREP_ACK timer.
Definition: aodv-rtable.h:114
Ptr< Packet > Copy(void) const
Definition: packet.cc:122
AODV Queue Entry.
Definition: aodv-rqueue.h:43
void SendRerrWhenNoRouteToForward(Ipv4Address dst, uint32_t dstSeqNo, Ipv4Address origin)
tag a set of bytes in a packet
Definition: tag.h:36
void Clear()
Remove all entries.
Definition: aodv-neighbor.h:79
void SendRerrWhenBreaksLinkToNextHop(Ipv4Address nextHop)
Initiate RERR.
void SetArguments(T1 a1)
Definition: timer.h:269
Implement the Ipv4 layer.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
static InetSocketAddress ConvertFrom(const Address &address)
void SetFlag(RouteFlags flag)
RREP_ACK timer.
Definition: aodv-rtable.h:123
Ipv4Address GetOrigin() const
Definition: aodv-packet.h:206
uint16_t GetHop() const
RREP_ACK timer.
Definition: aodv-rtable.h:120
Time ActiveRouteTimeout
Period of time during which the route is considered to be valid.
AODVTYPE_RREP_ACK.
Definition: aodv-packet.h:46
bool RemoveUnDestination(std::pair< Ipv4Address, uint32_t > &un)
Definition: aodv-packet.cc:594
void RecvRequest(Ptr< Packet > p, Ipv4Address receiver, Ipv4Address src)
Receive RREQ.
void SetOrigin(Ipv4Address a)
Definition: aodv-packet.h:131
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketAddresses
Raw socket per each IP interface, map socket -> iface address (IP + mask)
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Definition: simulator.h:985
void Update(Ipv4Address addr, Time expire)
Update expire time for entry with address addr, if it exists, else add new entry. ...
static Time Now(void)
Definition: simulator.cc:180
void SetOutputDevice(Ptr< NetDevice > outputDevice)
Definition: ipv4-route.cc:77
void ProcessHello(RrepHeader const &rrepHeader, Ipv4Address receiverIfaceAddr)
Process hello message.
static Ipv4Address GetLoopback(void)
virtual void NotifyInterfaceUp(uint32_t interface)
Time GetLifeTime() const
Definition: aodv-packet.cc:361
AODVTYPE_RREQ.
Definition: aodv-packet.h:43
Ipv4Address GetDst() const
Definition: aodv-packet.h:202
DuplicatePacketDetection m_dpd
Handle duplicated broadcast/multicast packets.
bool EnableBroadcast
Indicates whether a a broadcast data packets forwarding enable.
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:329
Route Reply Acknowledgment (RREP-ACK) Message Format.
Definition: aodv-packet.h:246
void RecvError(Ptr< Packet > p, Ipv4Address src)
Receive RERR from node with address src.
void RreqRateLimitTimerExpire()
Reset RREQ count and schedule RREQ rate limit timer with delay 1 sec.
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
uint32_t GetDstSeqno() const
Definition: aodv-packet.h:130
Time PathDiscoveryTime
Estimate of maximum time needed to find route in network.
Ipv4Address GetDestination(void) const
Definition: ipv4-route.cc:42
Time BlackListTimeout
Time for which the node is put into the blacklist.
void SetHop(uint16_t hop)
RREP_ACK timer.
Definition: aodv-rtable.h:119
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
Time NextHopWait
Period of our waiting for the neighbour's RREP_ACK.
read and write tag data
Definition: tag-buffer.h:51
Ipv4Address GetBroadcast(void) const
virtual void NotifyInterfaceDown(uint32_t interface)
Time MyRouteTimeout
Value of lifetime field in RREP generating by this node.
a class to store IPv4 address information on an interface
#define NS_LOG_WARN(msg)
Definition: log.h:246
uint32_t GetSeqNo() const
RREP_ACK timer.
Definition: aodv-rtable.h:118
void SetQueueTimeout(Time t)
Definition: aodv-rqueue.h:118
bool AddRoute(RoutingTableEntry &r)
Definition: aodv-rtable.cc:248
bool RemovePacketTag(Tag &tag)
Definition: packet.cc:848
A network Node.
Definition: node.h:55
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
void Cancel(void)
Definition: timer.cc:103
uint32_t AllowedHelloLoss
Number of hello messages which may be loss for valid link.
Ipv4Address GetOrigin() const
Definition: aodv-packet.h:132
void SendRerrMessage(Ptr< Packet > packet, std::vector< Ipv4Address > precursors)
Forward RERR.
bool IsDuplicate(Ipv4Address addr, uint32_t id)
Check that entry (addr, id) exists in cache. Add entry, if it doesn't exist.
void SetTtl(uint8_t ttl)
Definition: ipv4-header.cc:258
void SetCallback(Callback< void, Ipv4Address > cb)
Definition: aodv-neighbor.h:90
void SetAckRequired(bool f)
Definition: aodv-packet.cc:368
void Print(std::ostream &os) const
void SendReply(RreqHeader const &rreqHeader, RoutingTableEntry const &toOrigin)
Send RREP.
uint32_t GetOriginSeqno() const
Definition: aodv-packet.h:134
Abstract base class for IPv4 routing protocols.
void SetNextHop(Ipv4Address nextHop)
RREP_ACK timer.
Definition: aodv-rtable.h:109
bool GetDestinationOnly() const
Definition: aodv-packet.cc:247
uint32_t NetDiameter
Net diameter measures the maximum possible number of hops between two nodes in the network...
Timer m_rerrRateLimitTimer
RERR rate limit timer.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range. Both limits are inclusive.
Definition: time.cc:404
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
void AckTimerExpire(Ipv4Address neighbor, Time blacklistTimeout)
Mark link to neighbor node as unidirectional for blacklistTimeout.
std::map< Ipv4Address, Timer > m_addressReqTimer
Map IP address + RREQ timer.
Ptr< Ipv4Route > GetRoute() const
RREP_ACK timer.
Definition: aodv-rtable.h:107
bool GratuitousReply
Indicates whether a gratuitous RREP should be unicast to the node originated route discovery...
#define NS_LOG_ERROR(msg)
Definition: log.h:237
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:264
uint16_t RerrRateLimit
Maximum number of REER per second.
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
void SetGratiousRrep(bool f)
Definition: aodv-packet.cc:223
void SendRequest(Ipv4Address dst)
Send RREQ.
bool Dequeue(Ipv4Address dst, QueueEntry &entry)
Return first found (the earliest) entry for given destination.
Definition: aodv-rqueue.cc:88
void RerrRateLimitTimerExpire()
Reset RERR count and schedule RERR rate limit timer with delay 1 sec.
tuple address
Definition: first.py:37
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
IdCache m_rreqIdCache
Handle duplicated RREQ.
void RouteRequestTimerExpire(Ipv4Address dst)
Handle route discovery process.
void Start()
Start protocol operation.
virtual int Close(void)=0
Close a socket.
bool LookupValidRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup route in VALID state.
Definition: aodv-rtable.cc:221
Time GetDelayLeft(void) const
Definition: timer.cc:81
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:160
bool IsUnidirectional() const
RREP_ACK timer.
Definition: aodv-rtable.h:129
uint32_t GetId() const
Definition: aodv-packet.h:126
bool DeleteRoute(Ipv4Address dst)
Definition: aodv-rtable.cc:234
void Purge()
Delete all outdated entries and invalidate valid entry if Lifetime is expired.
Definition: aodv-rtable.cc:354
a unique identifier for an interface.
Definition: type-id.h:49
Ptr< NetDevice > m_lo
Loopback device used to defer RREQ until packet will be fully formed.
RouteFlags GetFlag() const
RREP_ACK timer.
Definition: aodv-rtable.h:124
uint32_t m_requestId
Broadcast ID.
Ipv4Address GetDestination() const
RREP_ACK timer.
Definition: aodv-rtable.h:106
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
MessageType Get() const
Return type.
Definition: aodv-packet.h:70
uint8_t GetHopCount() const
Definition: aodv-packet.h:200
Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr)
Query routing cache for an existing route, for an outbound packet.
uint8_t GetRreqCnt() const
RREP_ACK timer.
Definition: aodv-rtable.h:126
static Time GetMaximumSimulationTime(void)
Definition: simulator.cc:293
std::ostream * GetStream(void)
void SetUnknownSeqno(bool f)
Definition: aodv-packet.cc:253
void AddHeader(const Header &header)
Definition: packet.cc:253
void SetDestination(Ipv4Address dest)
Definition: ipv4-route.cc:35
void ScheduleTimer()
Schedule m_ntimer.
bool GetValidSeqNo() const
RREP_ACK timer.
Definition: aodv-rtable.h:116
static const uint32_t AODV_PORT
UDP Port for AODV control traffic.
void SetHopCount(uint8_t count)
Definition: aodv-packet.h:123
bool EnableHello
Indicates whether a hello messages enable.