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 namespace ns3
46 {
47 
48 NS_LOG_COMPONENT_DEFINE ("AodvRoutingProtocol");
49 
50 namespace aodv
51 {
52 NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
53 
55 const uint32_t RoutingProtocol::AODV_PORT = 654;
56 
57 //-----------------------------------------------------------------------------
59 
61 {
62 
63 public:
64  DeferredRouteOutputTag (int32_t o = -1) : Tag (), m_oif (o) {}
65 
66  static TypeId GetTypeId ()
67  {
68  static TypeId tid = TypeId ("ns3::aodv::DeferredRouteOutputTag")
69  .SetParent<Tag> ()
70  .SetGroupName("Aodv")
71  .AddConstructor<DeferredRouteOutputTag> ()
72  ;
73  return tid;
74  }
75 
77  {
78  return GetTypeId ();
79  }
80 
81  int32_t GetInterface() const
82  {
83  return m_oif;
84  }
85 
86  void SetInterface(int32_t oif)
87  {
88  m_oif = oif;
89  }
90 
91  uint32_t GetSerializedSize () const
92  {
93  return sizeof(int32_t);
94  }
95 
96  void Serialize (TagBuffer i) const
97  {
98  i.WriteU32 (m_oif);
99  }
100 
102  {
103  m_oif = i.ReadU32 ();
104  }
105 
106  void Print (std::ostream &os) const
107  {
108  os << "DeferredRouteOutputTag: output interface = " << m_oif;
109  }
110 
111 private:
113  int32_t m_oif;
114 };
115 
117 
118 
119 //-----------------------------------------------------------------------------
121  RreqRetries (2),
122  RreqRateLimit (10),
123  RerrRateLimit (10),
124  ActiveRouteTimeout (Seconds (3)),
125  NetDiameter (35),
126  NodeTraversalTime (MilliSeconds (40)),
127  NetTraversalTime (Time ((2 * NetDiameter) * NodeTraversalTime)),
128  PathDiscoveryTime ( Time (2 * NetTraversalTime)),
129  MyRouteTimeout (Time (2 * std::max (PathDiscoveryTime, ActiveRouteTimeout))),
130  HelloInterval (Seconds (1)),
131  AllowedHelloLoss (2),
132  DeletePeriod (Time (5 * std::max (ActiveRouteTimeout, HelloInterval))),
133  NextHopWait (NodeTraversalTime + MilliSeconds (10)),
134  BlackListTimeout (Time (RreqRetries * NetTraversalTime)),
135  MaxQueueLen (64),
136  MaxQueueTime (Seconds (30)),
137  DestinationOnly (false),
138  GratuitousReply (true),
139  EnableHello (false),
140  m_routingTable (DeletePeriod),
141  m_queue (MaxQueueLen, MaxQueueTime),
142  m_requestId (0),
143  m_seqNo (0),
144  m_rreqIdCache (PathDiscoveryTime),
145  m_dpd (PathDiscoveryTime),
146  m_nb (HelloInterval),
147  m_rreqCount (0),
148  m_rerrCount (0),
149  m_htimer (Timer::CANCEL_ON_DESTROY),
150  m_rreqRateLimitTimer (Timer::CANCEL_ON_DESTROY),
151  m_rerrRateLimitTimer (Timer::CANCEL_ON_DESTROY),
152  m_lastBcastTime (Seconds (0))
153 {
155 }
156 
157 TypeId
159 {
160  static TypeId tid = TypeId ("ns3::aodv::RoutingProtocol")
162  .SetGroupName("Aodv")
163  .AddConstructor<RoutingProtocol> ()
164  .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
165  TimeValue (Seconds (1)),
167  MakeTimeChecker ())
168  .AddAttribute ("RreqRetries", "Maximum number of retransmissions of RREQ to discover a route",
169  UintegerValue (2),
171  MakeUintegerChecker<uint32_t> ())
172  .AddAttribute ("RreqRateLimit", "Maximum number of RREQ per second.",
173  UintegerValue (10),
175  MakeUintegerChecker<uint32_t> ())
176  .AddAttribute ("RerrRateLimit", "Maximum number of RERR per second.",
177  UintegerValue (10),
179  MakeUintegerChecker<uint32_t> ())
180  .AddAttribute ("NodeTraversalTime", "Conservative estimate of the average one hop traversal time for packets and should include "
181  "queuing delays, interrupt processing times and transfer times.",
182  TimeValue (MilliSeconds (40)),
184  MakeTimeChecker ())
185  .AddAttribute ("NextHopWait", "Period of our waiting for the neighbour's RREP_ACK = 10 ms + NodeTraversalTime",
186  TimeValue (MilliSeconds (50)),
188  MakeTimeChecker ())
189  .AddAttribute ("ActiveRouteTimeout", "Period of time during which the route is considered to be valid",
190  TimeValue (Seconds (3)),
192  MakeTimeChecker ())
193  .AddAttribute ("MyRouteTimeout", "Value of lifetime field in RREP generating by this node = 2 * max(ActiveRouteTimeout, PathDiscoveryTime)",
194  TimeValue (Seconds (11.2)),
196  MakeTimeChecker ())
197  .AddAttribute ("BlackListTimeout", "Time for which the node is put into the blacklist = RreqRetries * NetTraversalTime",
198  TimeValue (Seconds (5.6)),
200  MakeTimeChecker ())
201  .AddAttribute ("DeletePeriod", "DeletePeriod is intended to provide an upper bound on the time for which an upstream node A "
202  "can have a neighbor B as an active next hop for destination D, while B has invalidated the route to D."
203  " = 5 * max (HelloInterval, ActiveRouteTimeout)",
204  TimeValue (Seconds (15)),
206  MakeTimeChecker ())
207  .AddAttribute ("NetDiameter", "Net diameter measures the maximum possible number of hops between two nodes in the network",
208  UintegerValue (35),
210  MakeUintegerChecker<uint32_t> ())
211  .AddAttribute ("NetTraversalTime", "Estimate of the average net traversal time = 2 * NodeTraversalTime * NetDiameter",
212  TimeValue (Seconds (2.8)),
214  MakeTimeChecker ())
215  .AddAttribute ("PathDiscoveryTime", "Estimate of maximum time needed to find route in network = 2 * NetTraversalTime",
216  TimeValue (Seconds (5.6)),
218  MakeTimeChecker ())
219  .AddAttribute ("MaxQueueLen", "Maximum number of packets that we allow a routing protocol to buffer.",
220  UintegerValue (64),
223  MakeUintegerChecker<uint32_t> ())
224  .AddAttribute ("MaxQueueTime", "Maximum time packets can be queued (in seconds)",
225  TimeValue (Seconds (30)),
228  MakeTimeChecker ())
229  .AddAttribute ("AllowedHelloLoss", "Number of hello messages which may be loss for valid link.",
230  UintegerValue (2),
232  MakeUintegerChecker<uint16_t> ())
233  .AddAttribute ("GratuitousReply", "Indicates whether a gratuitous RREP should be unicast to the node originated route discovery.",
234  BooleanValue (true),
238  .AddAttribute ("DestinationOnly", "Indicates only the destination may respond to this RREQ.",
239  BooleanValue (false),
243  .AddAttribute ("EnableHello", "Indicates whether a hello messages enable.",
244  BooleanValue (true),
248  .AddAttribute ("EnableBroadcast", "Indicates whether a broadcast data packets forwarding enable.",
249  BooleanValue (true),
253  .AddAttribute ("UniformRv",
254  "Access to the underlying UniformRandomVariable",
255  StringValue ("ns3::UniformRandomVariable"),
257  MakePointerChecker<UniformRandomVariable> ())
258  ;
259  return tid;
260 }
261 
262 void
264 {
265  MaxQueueLen = len;
266  m_queue.SetMaxQueueLen (len);
267 }
268 void
270 {
271  MaxQueueTime = t;
273 }
274 
276 {
277 }
278 
279 void
281 {
282  m_ipv4 = 0;
283  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::iterator iter =
284  m_socketAddresses.begin (); iter != m_socketAddresses.end (); iter++)
285  {
286  iter->first->Close ();
287  }
288  m_socketAddresses.clear ();
289  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::iterator iter =
291  {
292  iter->first->Close ();
293  }
296 }
297 
298 void
300 {
301  *stream->GetStream () << "Node: " << m_ipv4->GetObject<Node> ()->GetId ()
302  << "; Time: " << Now().As (Time::S)
303  << ", Local time: " << GetObject<Node> ()->GetLocalTime ().As (Time::S)
304  << ", AODV Routing table" << std::endl;
305 
306  m_routingTable.Print (stream);
307  *stream->GetStream () << std::endl;
308 }
309 
310 int64_t
312 {
313  NS_LOG_FUNCTION (this << stream);
315  return 1;
316 }
317 
318 void
320 {
321  NS_LOG_FUNCTION (this);
322  if (EnableHello)
323  {
324  m_nb.ScheduleTimer ();
325  }
327  this);
329 
331  this);
333 
334 }
335 
338  Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
339 {
340  NS_LOG_FUNCTION (this << header << (oif ? oif->GetIfIndex () : 0));
341  if (!p)
342  {
343  NS_LOG_DEBUG("Packet is == 0");
344  return LoopbackRoute (header, oif); // later
345  }
346  if (m_socketAddresses.empty ())
347  {
348  sockerr = Socket::ERROR_NOROUTETOHOST;
349  NS_LOG_LOGIC ("No aodv interfaces");
350  Ptr<Ipv4Route> route;
351  return route;
352  }
353  sockerr = Socket::ERROR_NOTERROR;
354  Ptr<Ipv4Route> route;
355  Ipv4Address dst = header.GetDestination ();
357  if (m_routingTable.LookupValidRoute (dst, rt))
358  {
359  route = rt.GetRoute ();
360  NS_ASSERT (route != 0);
361  NS_LOG_DEBUG ("Exist route to " << route->GetDestination () << " from interface " << route->GetSource ());
362  if (oif != 0 && route->GetOutputDevice () != oif)
363  {
364  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
365  sockerr = Socket::ERROR_NOROUTETOHOST;
366  return Ptr<Ipv4Route> ();
367  }
370  return route;
371  }
372 
373  // Valid route not found, in this case we return loopback.
374  // Actual route request will be deferred until packet will be fully formed,
375  // routed to loopback, received from loopback and passed to RouteInput (see below)
376  uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice (oif) : -1);
377  DeferredRouteOutputTag tag (iif);
378  NS_LOG_DEBUG ("Valid Route not found");
379  if (!p->PeekPacketTag (tag))
380  {
381  p->AddPacketTag (tag);
382  }
383  return LoopbackRoute (header, oif);
384 }
385 
386 void
389 {
390  NS_LOG_FUNCTION (this << p << header);
391  NS_ASSERT (p != 0 && p != Ptr<Packet> ());
392 
393  QueueEntry newEntry (p, header, ucb, ecb);
394  bool result = m_queue.Enqueue (newEntry);
395  if (result)
396  {
397  NS_LOG_LOGIC ("Add packet " << p->GetUid () << " to queue. Protocol " << (uint16_t) header.GetProtocol ());
399  bool result = m_routingTable.LookupRoute (header.GetDestination (), rt);
400  if(!result || ((rt.GetFlag () != IN_SEARCH) && result))
401  {
402  NS_LOG_LOGIC ("Send new RREQ for outbound packet to " <<header.GetDestination ());
403  SendRequest (header.GetDestination ());
404  }
405  }
406 }
407 
408 bool
412 {
413  NS_LOG_FUNCTION (this << p->GetUid () << header.GetDestination () << idev->GetAddress ());
414  if (m_socketAddresses.empty ())
415  {
416  NS_LOG_LOGIC ("No aodv interfaces");
417  return false;
418  }
419  NS_ASSERT (m_ipv4 != 0);
420  NS_ASSERT (p != 0);
421  // Check if input device supports IP
422  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
423  int32_t iif = m_ipv4->GetInterfaceForDevice (idev);
424 
425  Ipv4Address dst = header.GetDestination ();
426  Ipv4Address origin = header.GetSource ();
427 
428  // Deferred route request
429  if (idev == m_lo)
430  {
432  if (p->PeekPacketTag (tag))
433  {
434  DeferredRouteOutput (p, header, ucb, ecb);
435  return true;
436  }
437  }
438 
439  // Duplicate of own packet
440  if (IsMyOwnAddress (origin))
441  return true;
442 
443  // AODV is not a multicast routing protocol
444  if (dst.IsMulticast ())
445  {
446  return false;
447  }
448 
449  // Broadcast local delivery/forwarding
450  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
451  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
452  {
453  Ipv4InterfaceAddress iface = j->second;
454  if (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()) == iif)
455  if (dst == iface.GetBroadcast () || dst.IsBroadcast ())
456  {
457  if (m_dpd.IsDuplicate (p, header))
458  {
459  NS_LOG_DEBUG ("Duplicated packet " << p->GetUid () << " from " << origin << ". Drop.");
460  return true;
461  }
463  Ptr<Packet> packet = p->Copy ();
464  if (lcb.IsNull () == false)
465  {
466  NS_LOG_LOGIC ("Broadcast local delivery to " << iface.GetLocal ());
467  lcb (p, header, iif);
468  // Fall through to additional processing
469  }
470  else
471  {
472  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
473  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
474  }
475  if (!EnableBroadcast)
476  {
477  return true;
478  }
479  if (header.GetTtl () > 1)
480  {
481  NS_LOG_LOGIC ("Forward broadcast. TTL " << (uint16_t) header.GetTtl ());
482  RoutingTableEntry toBroadcast;
483  if (m_routingTable.LookupRoute (dst, toBroadcast))
484  {
485  Ptr<Ipv4Route> route = toBroadcast.GetRoute ();
486  ucb (route, packet, header);
487  }
488  else
489  {
490  NS_LOG_DEBUG ("No route to forward broadcast. Drop packet " << p->GetUid ());
491  }
492  }
493  else
494  {
495  NS_LOG_DEBUG ("TTL exceeded. Drop packet " << p->GetUid ());
496  }
497  return true;
498  }
499  }
500 
501  // Unicast local delivery
502  if (m_ipv4->IsDestinationAddress (dst, iif))
503  {
505  RoutingTableEntry toOrigin;
506  if (m_routingTable.LookupValidRoute (origin, toOrigin))
507  {
509  m_nb.Update (toOrigin.GetNextHop (), ActiveRouteTimeout);
510  }
511  if (lcb.IsNull () == false)
512  {
513  NS_LOG_LOGIC ("Unicast local delivery to " << dst);
514  lcb (p, header, iif);
515  }
516  else
517  {
518  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
519  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
520  }
521  return true;
522  }
523 
524  // Check if input device supports IP forwarding
525  if (m_ipv4->IsForwarding (iif) == false)
526  {
527  NS_LOG_LOGIC ("Forwarding disabled for this interface");
528  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
529  return true;
530  }
531 
532  // Forwarding
533  return Forwarding (p, header, ucb, ecb);
534 }
535 
536 bool
539 {
540  NS_LOG_FUNCTION (this);
541  Ipv4Address dst = header.GetDestination ();
542  Ipv4Address origin = header.GetSource ();
544  RoutingTableEntry toDst;
545  if (m_routingTable.LookupRoute (dst, toDst))
546  {
547  if (toDst.GetFlag () == VALID)
548  {
549  Ptr<Ipv4Route> route = toDst.GetRoute ();
550  NS_LOG_LOGIC (route->GetSource ()<<" forwarding to " << dst << " from " << origin << " packet " << p->GetUid ());
551 
552  /*
553  * Each time a route is used to forward a data packet, its Active Route
554  * Lifetime field of the source, destination and the next hop on the
555  * path to the destination is updated to be no less than the current
556  * time plus ActiveRouteTimeout.
557  */
561  /*
562  * Since the route between each originator and destination pair is expected to be symmetric, the
563  * Active Route Lifetime for the previous hop, along the reverse path back to the IP source, is also updated
564  * to be no less than the current time plus ActiveRouteTimeout
565  */
566  RoutingTableEntry toOrigin;
567  m_routingTable.LookupRoute (origin, toOrigin);
568  UpdateRouteLifeTime (toOrigin.GetNextHop (), ActiveRouteTimeout);
569 
571  m_nb.Update (toOrigin.GetNextHop (), ActiveRouteTimeout);
572 
573  ucb (route, p, header);
574  return true;
575  }
576  else
577  {
578  if (toDst.GetValidSeqNo ())
579  {
580  SendRerrWhenNoRouteToForward (dst, toDst.GetSeqNo (), origin);
581  NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
582  return false;
583  }
584  }
585  }
586  NS_LOG_LOGIC ("route not found to "<< dst << ". Send RERR message.");
587  NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
588  SendRerrWhenNoRouteToForward (dst, 0, origin);
589  return false;
590 }
591 
592 void
594 {
595  NS_ASSERT (ipv4 != 0);
596  NS_ASSERT (m_ipv4 == 0);
597 
598  m_ipv4 = ipv4;
599 
600  // Create lo route. It is asserted that the only one interface up for now is loopback
601  NS_ASSERT (m_ipv4->GetNInterfaces () == 1 && m_ipv4->GetAddress (0, 0).GetLocal () == Ipv4Address ("127.0.0.1"));
602  m_lo = m_ipv4->GetNetDevice (0);
603  NS_ASSERT (m_lo != 0);
604  // Remember lo route
605  RoutingTableEntry rt (/*device=*/ m_lo, /*dst=*/ Ipv4Address::GetLoopback (), /*know seqno=*/ true, /*seqno=*/ 0,
606  /*iface=*/ Ipv4InterfaceAddress (Ipv4Address::GetLoopback (), Ipv4Mask ("255.0.0.0")),
607  /*hops=*/ 1, /*next hop=*/ Ipv4Address::GetLoopback (),
608  /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
610 
612 }
613 
614 void
616 {
617  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
618  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
619  if (l3->GetNAddresses (i) > 1)
620  {
621  NS_LOG_WARN ("AODV does not work with more then one address per each interface.");
622  }
623  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
624  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
625  return;
626 
627  // Create a socket to listen only on this interface
628  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
630  NS_ASSERT (socket != 0);
632  socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
633  socket->BindToNetDevice (l3->GetNetDevice (i));
634  socket->SetAllowBroadcast (true);
635  socket->SetAttribute ("IpTtl", UintegerValue (1));
636  m_socketAddresses.insert (std::make_pair (socket, iface));
637 
638  // create also a subnet broadcast socket
639  socket = Socket::CreateSocket (GetObject<Node> (),
641  NS_ASSERT (socket != 0);
643  socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
644  socket->BindToNetDevice (l3->GetNetDevice (i));
645  socket->SetAllowBroadcast (true);
646  socket->SetAttribute ("IpTtl", UintegerValue (1));
647  m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
648 
649  // Add local broadcast record to the routing table
650  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
651  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
652  /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
654 
655  if (l3->GetInterface (i)->GetArpCache ())
656  {
657  m_nb.AddArpCache (l3->GetInterface (i)->GetArpCache ());
658  }
659 
660  // Allow neighbor manager use this interface for layer 2 feedback if possible
661  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
662  if (wifi == 0)
663  return;
664  Ptr<WifiMac> mac = wifi->GetMac ();
665  if (mac == 0)
666  return;
667 
668  mac->TraceConnectWithoutContext ("TxErrHeader", m_nb.GetTxErrorCallback ());
669 }
670 
671 void
673 {
674  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
675 
676  // Disable layer 2 link state monitoring (if possible)
677  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
678  Ptr<NetDevice> dev = l3->GetNetDevice (i);
679  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
680  if (wifi != 0)
681  {
682  Ptr<WifiMac> mac = wifi->GetMac ()->GetObject<AdhocWifiMac> ();
683  if (mac != 0)
684  {
685  mac->TraceDisconnectWithoutContext ("TxErrHeader",
687  m_nb.DelArpCache (l3->GetInterface (i)->GetArpCache ());
688  }
689  }
690 
691  // Close socket
692  Ptr<Socket> socket = FindSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0));
693  NS_ASSERT (socket);
694  socket->Close ();
695  m_socketAddresses.erase (socket);
696 
697  // Close socket
698  socket = FindSubnetBroadcastSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0));
699  NS_ASSERT (socket);
700  socket->Close ();
701  m_socketSubnetBroadcastAddresses.erase (socket);
702 
703  if (m_socketAddresses.empty ())
704  {
705  NS_LOG_LOGIC ("No aodv interfaces");
706  m_htimer.Cancel ();
707  m_nb.Clear ();
709  return;
710  }
712 }
713 
714 void
716 {
717  NS_LOG_FUNCTION (this << " interface " << i << " address " << address);
718  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
719  if (!l3->IsUp (i))
720  return;
721  if (l3->GetNAddresses (i) == 1)
722  {
723  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
725  if (!socket)
726  {
727  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
728  return;
729  // Create a socket to listen only on this interface
730  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
732  NS_ASSERT (socket != 0);
734  socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
735  socket->BindToNetDevice (l3->GetNetDevice (i));
736  socket->SetAllowBroadcast (true);
737  m_socketAddresses.insert (std::make_pair (socket, iface));
738 
739  // create also a subnet directed broadcast socket
740  socket = Socket::CreateSocket (GetObject<Node> (),
742  NS_ASSERT (socket != 0);
744  socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
745  socket->BindToNetDevice (l3->GetNetDevice (i));
746  socket->SetAllowBroadcast (true);
747  socket->SetAttribute ("IpTtl", UintegerValue (1));
748  m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
749 
750  // Add local broadcast record to the routing table
751  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (
752  m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
753  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true,
754  /*seqno=*/ 0, /*iface=*/ iface, /*hops=*/ 1,
755  /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
757  }
758  }
759  else
760  {
761  NS_LOG_LOGIC ("AODV does not work with more then one address per each interface. Ignore added address");
762  }
763 }
764 
765 void
767 {
768  NS_LOG_FUNCTION (this);
769  Ptr<Socket> socket = FindSocketWithInterfaceAddress (address);
770  if (socket)
771  {
773  socket->Close ();
774  m_socketAddresses.erase (socket);
775 
777  if (unicastSocket)
778  {
779  unicastSocket->Close ();
780  m_socketAddresses.erase (unicastSocket);
781  }
782 
783  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
784  if (l3->GetNAddresses (i))
785  {
786  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
787  // Create a socket to listen only on this interface
788  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
790  NS_ASSERT (socket != 0);
792  // Bind to any IP address so that broadcasts can be received
793  socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
794  socket->BindToNetDevice (l3->GetNetDevice (i));
795  socket->SetAllowBroadcast (true);
796  socket->SetAttribute ("IpTtl", UintegerValue (1));
797  m_socketAddresses.insert (std::make_pair (socket, iface));
798 
799  // create also a unicast socket
800  socket = Socket::CreateSocket (GetObject<Node> (),
802  NS_ASSERT (socket != 0);
804  socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
805  socket->BindToNetDevice (l3->GetNetDevice (i));
806  socket->SetAllowBroadcast (true);
807  socket->SetAttribute ("IpTtl", UintegerValue (1));
808  m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
809 
810  // Add local broadcast record to the routing table
811  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
812  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
813  /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
815  }
816  if (m_socketAddresses.empty ())
817  {
818  NS_LOG_LOGIC ("No aodv interfaces");
819  m_htimer.Cancel ();
820  m_nb.Clear ();
822  return;
823  }
824  }
825  else
826  {
827  NS_LOG_LOGIC ("Remove address not participating in AODV operation");
828  }
829 }
830 
831 bool
833 {
834  NS_LOG_FUNCTION (this << src);
835  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
836  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
837  {
838  Ipv4InterfaceAddress iface = j->second;
839  if (src == iface.GetLocal ())
840  {
841  return true;
842  }
843  }
844  return false;
845 }
846 
849 {
850  NS_LOG_FUNCTION (this << hdr);
851  NS_ASSERT (m_lo != 0);
852  Ptr<Ipv4Route> rt = Create<Ipv4Route> ();
853  rt->SetDestination (hdr.GetDestination ());
854  //
855  // Source address selection here is tricky. The loopback route is
856  // returned when AODV does not have a route; this causes the packet
857  // to be looped back and handled (cached) in RouteInput() method
858  // while a route is found. However, connection-oriented protocols
859  // like TCP need to create an endpoint four-tuple (src, src port,
860  // dst, dst port) and create a pseudo-header for checksumming. So,
861  // AODV needs to guess correctly what the eventual source address
862  // will be.
863  //
864  // For single interface, single address nodes, this is not a problem.
865  // When there are possibly multiple outgoing interfaces, the policy
866  // implemented here is to pick the first available AODV interface.
867  // If RouteOutput() caller specified an outgoing interface, that
868  // further constrains the selection of source address
869  //
870  std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin ();
871  if (oif)
872  {
873  // Iterate to find an address on the oif device
874  for (j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
875  {
876  Ipv4Address addr = j->second.GetLocal ();
877  int32_t interface = m_ipv4->GetInterfaceForAddress (addr);
878  if (oif == m_ipv4->GetNetDevice (static_cast<uint32_t> (interface)))
879  {
880  rt->SetSource (addr);
881  break;
882  }
883  }
884  }
885  else
886  {
887  rt->SetSource (j->second.GetLocal ());
888  }
889  NS_ASSERT_MSG (rt->GetSource () != Ipv4Address (), "Valid AODV source address not found");
890  rt->SetGateway (Ipv4Address ("127.0.0.1"));
891  rt->SetOutputDevice (m_lo);
892  return rt;
893 }
894 
895 void
897 {
898  NS_LOG_FUNCTION ( this << dst);
899  // A node SHOULD NOT originate more than RREQ_RATELIMIT RREQ messages per second.
900  if (m_rreqCount == RreqRateLimit)
901  {
903  &RoutingProtocol::SendRequest, this, dst);
904  return;
905  }
906  else
907  m_rreqCount++;
908  // Create RREQ header
909  RreqHeader rreqHeader;
910  rreqHeader.SetDst (dst);
911 
913  if (m_routingTable.LookupRoute (dst, rt))
914  {
915  rreqHeader.SetHopCount (rt.GetHop ());
916  if (rt.GetValidSeqNo ())
917  rreqHeader.SetDstSeqno (rt.GetSeqNo ());
918  else
919  rreqHeader.SetUnknownSeqno (true);
920  rt.SetFlag (IN_SEARCH);
921  m_routingTable.Update (rt);
922  }
923  else
924  {
925  rreqHeader.SetUnknownSeqno (true);
926  Ptr<NetDevice> dev = 0;
927  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ dst, /*validSeqNo=*/ false, /*seqno=*/ 0,
928  /*iface=*/ Ipv4InterfaceAddress (),/*hop=*/ 0,
929  /*nextHop=*/ Ipv4Address (), /*lifeTime=*/ Seconds (0));
930  newEntry.SetFlag (IN_SEARCH);
931  m_routingTable.AddRoute (newEntry);
932  }
933 
934  if (GratuitousReply)
935  rreqHeader.SetGratiousRrep (true);
936  if (DestinationOnly)
937  rreqHeader.SetDestinationOnly (true);
938 
939  m_seqNo++;
940  rreqHeader.SetOriginSeqno (m_seqNo);
941  m_requestId++;
942  rreqHeader.SetId (m_requestId);
943  rreqHeader.SetHopCount (0);
944 
945  // Send RREQ as subnet directed broadcast from each interface used by aodv
946  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
947  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
948  {
949  Ptr<Socket> socket = j->first;
950  Ipv4InterfaceAddress iface = j->second;
951 
952  rreqHeader.SetOrigin (iface.GetLocal ());
954 
955  Ptr<Packet> packet = Create<Packet> ();
956  packet->AddHeader (rreqHeader);
957  TypeHeader tHeader (AODVTYPE_RREQ);
958  packet->AddHeader (tHeader);
959  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
960  Ipv4Address destination;
961  if (iface.GetMask () == Ipv4Mask::GetOnes ())
962  {
963  destination = Ipv4Address ("255.255.255.255");
964  }
965  else
966  {
967  destination = iface.GetBroadcast ();
968  }
969  NS_LOG_DEBUG ("Send RREQ with id " << rreqHeader.GetId () << " to socket");
971  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, destination);
972  }
973  ScheduleRreqRetry (dst);
974 }
975 
976 void
978 {
979  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
980 
981 }
982 void
984 {
985  NS_LOG_FUNCTION (this << dst);
986  if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
987  {
989  m_addressReqTimer[dst] = timer;
990  }
992  m_addressReqTimer[dst].Remove ();
993  m_addressReqTimer[dst].SetArguments (dst);
995  m_routingTable.LookupRoute (dst, rt);
996  rt.IncrementRreqCnt ();
997  m_routingTable.Update (rt);
998  m_addressReqTimer[dst].Schedule (Time (rt.GetRreqCnt () * NetTraversalTime));
999  NS_LOG_LOGIC ("Scheduled RREQ retry in " << Time (rt.GetRreqCnt () * NetTraversalTime).GetSeconds () << " seconds");
1000 }
1001 
1002 void
1004 {
1005  NS_LOG_FUNCTION (this << socket);
1006  Address sourceAddress;
1007  Ptr<Packet> packet = socket->RecvFrom (sourceAddress);
1008  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
1009  Ipv4Address sender = inetSourceAddr.GetIpv4 ();
1010  Ipv4Address receiver;
1011 
1012  if (m_socketAddresses.find (socket) != m_socketAddresses.end ())
1013  {
1014  receiver = m_socketAddresses[socket].GetLocal ();
1015  }
1017  {
1018  receiver = m_socketSubnetBroadcastAddresses[socket].GetLocal ();
1019  }
1020  else
1021  {
1022  NS_ASSERT_MSG (false, "Received a packet from an unknown socket");
1023  }
1024  NS_LOG_DEBUG ("AODV node " << this << " received a AODV packet from " << sender << " to " << receiver);
1025 
1026  UpdateRouteToNeighbor (sender, receiver);
1027  TypeHeader tHeader (AODVTYPE_RREQ);
1028  packet->RemoveHeader (tHeader);
1029  if (!tHeader.IsValid ())
1030  {
1031  NS_LOG_DEBUG ("AODV message " << packet->GetUid () << " with unknown type received: " << tHeader.Get () << ". Drop");
1032  return; // drop
1033  }
1034  switch (tHeader.Get ())
1035  {
1036  case AODVTYPE_RREQ:
1037  {
1038  RecvRequest (packet, receiver, sender);
1039  break;
1040  }
1041  case AODVTYPE_RREP:
1042  {
1043  RecvReply (packet, receiver, sender);
1044  break;
1045  }
1046  case AODVTYPE_RERR:
1047  {
1048  RecvError (packet, sender);
1049  break;
1050  }
1051  case AODVTYPE_RREP_ACK:
1052  {
1053  RecvReplyAck (sender);
1054  break;
1055  }
1056  }
1057 }
1058 
1059 bool
1061 {
1062  NS_LOG_FUNCTION (this << addr << lifetime);
1063  RoutingTableEntry rt;
1064  if (m_routingTable.LookupRoute (addr, rt))
1065  {
1066  if (rt.GetFlag () == VALID)
1067  {
1068  NS_LOG_DEBUG ("Updating VALID route");
1069  rt.SetRreqCnt (0);
1070  rt.SetLifeTime (std::max (lifetime, rt.GetLifeTime ()));
1071  m_routingTable.Update (rt);
1072  return true;
1073  }
1074  }
1075  return false;
1076 }
1077 
1078 void
1080 {
1081  NS_LOG_FUNCTION (this << "sender " << sender << " receiver " << receiver);
1082  RoutingTableEntry toNeighbor;
1083  if (!m_routingTable.LookupRoute (sender, toNeighbor))
1084  {
1085  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1086  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1087  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1088  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ ActiveRouteTimeout);
1089  m_routingTable.AddRoute (newEntry);
1090  }
1091  else
1092  {
1093  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1094  if (toNeighbor.GetValidSeqNo () && (toNeighbor.GetHop () == 1) && (toNeighbor.GetOutputDevice () == dev))
1095  {
1096  toNeighbor.SetLifeTime (std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()));
1097  }
1098  else
1099  {
1100  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1101  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1102  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()));
1103  m_routingTable.Update (newEntry);
1104  }
1105  }
1106 
1107 }
1108 
1109 void
1111 {
1112  NS_LOG_FUNCTION (this);
1113  RreqHeader rreqHeader;
1114  p->RemoveHeader (rreqHeader);
1115 
1116  // A node ignores all RREQs received from any node in its blacklist
1117  RoutingTableEntry toPrev;
1118  if (m_routingTable.LookupRoute (src, toPrev))
1119  {
1120  if (toPrev.IsUnidirectional ())
1121  {
1122  NS_LOG_DEBUG ("Ignoring RREQ from node in blacklist");
1123  return;
1124  }
1125  }
1126 
1127  uint32_t id = rreqHeader.GetId ();
1128  Ipv4Address origin = rreqHeader.GetOrigin ();
1129 
1130  /*
1131  * Node checks to determine whether it has received a RREQ with the same Originator IP Address and RREQ ID.
1132  * If such a RREQ has been received, the node silently discards the newly received RREQ.
1133  */
1134  if (m_rreqIdCache.IsDuplicate (origin, id))
1135  {
1136  NS_LOG_DEBUG ("Ignoring RREQ due to duplicate");
1137  return;
1138  }
1139 
1140  // Increment RREQ hop count
1141  uint8_t hop = rreqHeader.GetHopCount () + 1;
1142  rreqHeader.SetHopCount (hop);
1143 
1144  /*
1145  * When the reverse route is created or updated, the following actions on the route are also carried out:
1146  * 1. the Originator Sequence Number from the RREQ is compared to the corresponding destination sequence number
1147  * in the route table entry and copied if greater than the existing value there
1148  * 2. the valid sequence number field is set to true;
1149  * 3. the next hop in the routing table becomes the node from which the RREQ was received
1150  * 4. the hop count is copied from the Hop Count in the RREQ message;
1151  * 5. the Lifetime is set to be the maximum of (ExistingLifetime, MinimalLifetime), where
1152  * MinimalLifetime = current time + 2*NetTraversalTime - 2*HopCount*NodeTraversalTime
1153  */
1154  RoutingTableEntry toOrigin;
1155  if (!m_routingTable.LookupRoute (origin, toOrigin))
1156  {
1157  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1158  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ origin, /*validSeno=*/ true, /*seqNo=*/ rreqHeader.GetOriginSeqno (),
1159  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0), /*hops=*/ hop,
1160  /*nextHop*/ src, /*timeLife=*/ Time ((2 * NetTraversalTime - 2 * hop * NodeTraversalTime)));
1161  m_routingTable.AddRoute (newEntry);
1162  }
1163  else
1164  {
1165  if (toOrigin.GetValidSeqNo ())
1166  {
1167  if (int32_t (rreqHeader.GetOriginSeqno ()) - int32_t (toOrigin.GetSeqNo ()) > 0)
1168  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1169  }
1170  else
1171  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1172  toOrigin.SetValidSeqNo (true);
1173  toOrigin.SetNextHop (src);
1174  toOrigin.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1175  toOrigin.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1176  toOrigin.SetHop (hop);
1177  toOrigin.SetLifeTime (std::max (Time (2 * NetTraversalTime - 2 * hop * NodeTraversalTime),
1178  toOrigin.GetLifeTime ()));
1179  m_routingTable.Update (toOrigin);
1180  //m_nb.Update (src, Time (AllowedHelloLoss * HelloInterval));
1181  }
1182 
1183 
1184  RoutingTableEntry toNeighbor;
1185  if (!m_routingTable.LookupRoute (src, toNeighbor))
1186  {
1187  NS_LOG_DEBUG ("Neighbor:" << src << " not found in routing table. Creating an entry");
1188  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1189  RoutingTableEntry newEntry (dev, src, false, rreqHeader.GetOriginSeqno (),
1190  m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1191  1, src, ActiveRouteTimeout);
1192  m_routingTable.AddRoute (newEntry);
1193  }
1194  else
1195  {
1196  toNeighbor.SetLifeTime (ActiveRouteTimeout);
1197  toNeighbor.SetValidSeqNo (false);
1198  toNeighbor.SetSeqNo (rreqHeader.GetOriginSeqno ());
1199  toNeighbor.SetFlag (VALID);
1200  toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1201  toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1202  toNeighbor.SetHop (1);
1203  toNeighbor.SetNextHop (src);
1204  m_routingTable.Update (toNeighbor);
1205  }
1207 
1208  NS_LOG_LOGIC (receiver << " receive RREQ with hop count " << static_cast<uint32_t>(rreqHeader.GetHopCount ())
1209  << " ID " << rreqHeader.GetId ()
1210  << " to destination " << rreqHeader.GetDst ());
1211 
1212  // A node generates a RREP if either:
1213  // (i) it is itself the destination,
1214  if (IsMyOwnAddress (rreqHeader.GetDst ()))
1215  {
1216  m_routingTable.LookupRoute (origin, toOrigin);
1217  NS_LOG_DEBUG ("Send reply since I am the destination");
1218  SendReply (rreqHeader, toOrigin);
1219  return;
1220  }
1221  /*
1222  * (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
1223  * is valid and greater than or equal to the Destination Sequence Number of the RREQ, and the "destination only" flag is NOT set.
1224  */
1225  RoutingTableEntry toDst;
1226  Ipv4Address dst = rreqHeader.GetDst ();
1227  if (m_routingTable.LookupRoute (dst, toDst))
1228  {
1229  /*
1230  * Drop RREQ, This node RREP wil make a loop.
1231  */
1232  if (toDst.GetNextHop () == src)
1233  {
1234  NS_LOG_DEBUG ("Drop RREQ from " << src << ", dest next hop " << toDst.GetNextHop ());
1235  return;
1236  }
1237  /*
1238  * The Destination Sequence number for the requested destination is set to the maximum of the corresponding value
1239  * received in the RREQ message, and the destination sequence value currently maintained by the node for the requested destination.
1240  * However, the forwarding node MUST NOT modify its maintained value for the destination sequence number, even if the value
1241  * received in the incoming RREQ is larger than the value currently maintained by the forwarding node.
1242  */
1243  if ((rreqHeader.GetUnknownSeqno () || (int32_t (toDst.GetSeqNo ()) - int32_t (rreqHeader.GetDstSeqno ()) >= 0))
1244  && toDst.GetValidSeqNo () )
1245  {
1246  if (!rreqHeader.GetDestinationOnly () && toDst.GetFlag () == VALID)
1247  {
1248  m_routingTable.LookupRoute (origin, toOrigin);
1249  SendReplyByIntermediateNode (toDst, toOrigin, rreqHeader.GetGratiousRrep ());
1250  return;
1251  }
1252  rreqHeader.SetDstSeqno (toDst.GetSeqNo ());
1253  rreqHeader.SetUnknownSeqno (false);
1254  }
1255  }
1256 
1257  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1258  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1259  {
1260  Ptr<Socket> socket = j->first;
1261  Ipv4InterfaceAddress iface = j->second;
1262  Ptr<Packet> packet = Create<Packet> ();
1263  packet->AddHeader (rreqHeader);
1264  TypeHeader tHeader (AODVTYPE_RREQ);
1265  packet->AddHeader (tHeader);
1266  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1267  Ipv4Address destination;
1268  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1269  {
1270  destination = Ipv4Address ("255.255.255.255");
1271  }
1272  else
1273  {
1274  destination = iface.GetBroadcast ();
1275  }
1277  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, destination);
1278 
1279  }
1280 }
1281 
1282 void
1283 RoutingProtocol::SendReply (RreqHeader const & rreqHeader, RoutingTableEntry const & toOrigin)
1284 {
1285  NS_LOG_FUNCTION (this << toOrigin.GetDestination ());
1286  /*
1287  * Destination node MUST increment its own sequence number by one if the sequence number in the RREQ packet is equal to that
1288  * incremented value. Otherwise, the destination does not change its sequence number before generating the RREP message.
1289  */
1290  if (!rreqHeader.GetUnknownSeqno () && (rreqHeader.GetDstSeqno () == m_seqNo + 1))
1291  m_seqNo++;
1292  RrepHeader rrepHeader ( /*prefixSize=*/ 0, /*hops=*/ 0, /*dst=*/ rreqHeader.GetDst (),
1293  /*dstSeqNo=*/ m_seqNo, /*origin=*/ toOrigin.GetDestination (), /*lifeTime=*/ MyRouteTimeout);
1294  Ptr<Packet> packet = Create<Packet> ();
1295  packet->AddHeader (rrepHeader);
1296  TypeHeader tHeader (AODVTYPE_RREP);
1297  packet->AddHeader (tHeader);
1299  NS_ASSERT (socket);
1300  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1301 }
1302 
1303 void
1305 {
1306  NS_LOG_FUNCTION (this);
1307  RrepHeader rrepHeader (/*prefix size=*/ 0, /*hops=*/ toDst.GetHop (), /*dst=*/ toDst.GetDestination (), /*dst seqno=*/ toDst.GetSeqNo (),
1308  /*origin=*/ toOrigin.GetDestination (), /*lifetime=*/ toDst.GetLifeTime ());
1309  /* If the node we received a RREQ for is a neighbor we are
1310  * probably facing a unidirectional link... Better request a RREP-ack
1311  */
1312  if (toDst.GetHop () == 1)
1313  {
1314  rrepHeader.SetAckRequired (true);
1315  RoutingTableEntry toNextHop;
1316  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHop);
1318  toNextHop.m_ackTimer.SetArguments (toNextHop.GetDestination (), BlackListTimeout);
1319  toNextHop.m_ackTimer.SetDelay (NextHopWait);
1320  }
1321  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1322  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1323  m_routingTable.Update (toDst);
1324  m_routingTable.Update (toOrigin);
1325 
1326  Ptr<Packet> packet = Create<Packet> ();
1327  packet->AddHeader (rrepHeader);
1328  TypeHeader tHeader (AODVTYPE_RREP);
1329  packet->AddHeader (tHeader);
1331  NS_ASSERT (socket);
1332  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1333 
1334  // Generating gratuitous RREPs
1335  if (gratRep)
1336  {
1337  RrepHeader gratRepHeader (/*prefix size=*/ 0, /*hops=*/ toOrigin.GetHop (), /*dst=*/ toOrigin.GetDestination (),
1338  /*dst seqno=*/ toOrigin.GetSeqNo (), /*origin=*/ toDst.GetDestination (),
1339  /*lifetime=*/ toOrigin.GetLifeTime ());
1340  Ptr<Packet> packetToDst = Create<Packet> ();
1341  packetToDst->AddHeader (gratRepHeader);
1342  TypeHeader type (AODVTYPE_RREP);
1343  packetToDst->AddHeader (type);
1345  NS_ASSERT (socket);
1346  NS_LOG_LOGIC ("Send gratuitous RREP " << packet->GetUid ());
1347  socket->SendTo (packetToDst, 0, InetSocketAddress (toDst.GetNextHop (), AODV_PORT));
1348  }
1349 }
1350 
1351 void
1353 {
1354  NS_LOG_FUNCTION (this << " to " << neighbor);
1355  RrepAckHeader h;
1356  TypeHeader typeHeader (AODVTYPE_RREP_ACK);
1357  Ptr<Packet> packet = Create<Packet> ();
1358  packet->AddHeader (h);
1359  packet->AddHeader (typeHeader);
1360  RoutingTableEntry toNeighbor;
1361  m_routingTable.LookupRoute (neighbor, toNeighbor);
1362  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toNeighbor.GetInterface ());
1363  NS_ASSERT (socket);
1364  socket->SendTo (packet, 0, InetSocketAddress (neighbor, AODV_PORT));
1365 }
1366 
1367 void
1369 {
1370  NS_LOG_FUNCTION (this << " src " << sender);
1371  RrepHeader rrepHeader;
1372  p->RemoveHeader (rrepHeader);
1373  Ipv4Address dst = rrepHeader.GetDst ();
1374  NS_LOG_LOGIC ("RREP destination " << dst << " RREP origin " << rrepHeader.GetOrigin ());
1375 
1376  uint8_t hop = rrepHeader.GetHopCount () + 1;
1377  rrepHeader.SetHopCount (hop);
1378 
1379  // If RREP is Hello message
1380  if (dst == rrepHeader.GetOrigin ())
1381  {
1382  ProcessHello (rrepHeader, receiver);
1383  return;
1384  }
1385 
1386  /*
1387  * If the route table entry to the destination is created or updated, then the following actions occur:
1388  * - the route is marked as active,
1389  * - the destination sequence number is marked as valid,
1390  * - the next hop in the route entry is assigned to be the node from which the RREP is received,
1391  * which is indicated by the source IP address field in the IP header,
1392  * - the hop count is set to the value of the hop count from RREP message + 1
1393  * - the expiry time is set to the current time plus the value of the Lifetime in the RREP message,
1394  * - and the destination sequence number is the Destination Sequence Number in the RREP message.
1395  */
1396  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1397  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ dst, /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1398  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),/*hop=*/ hop,
1399  /*nextHop=*/ sender, /*lifeTime=*/ rrepHeader.GetLifeTime ());
1400  RoutingTableEntry toDst;
1401  if (m_routingTable.LookupRoute (dst, toDst))
1402  {
1403  /*
1404  * The existing entry is updated only in the following circumstances:
1405  * (i) the sequence number in the routing table is marked as invalid in route table entry.
1406  */
1407  if (!toDst.GetValidSeqNo ())
1408  {
1409  m_routingTable.Update (newEntry);
1410  }
1411  // (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,
1412  else if ((int32_t (rrepHeader.GetDstSeqno ()) - int32_t (toDst.GetSeqNo ())) > 0)
1413  {
1414  m_routingTable.Update (newEntry);
1415  }
1416  else
1417  {
1418  // (iii) the sequence numbers are the same, but the route is marked as inactive.
1419  if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (toDst.GetFlag () != VALID))
1420  {
1421  m_routingTable.Update (newEntry);
1422  }
1423  // (iv) the sequence numbers are the same, and the New Hop Count is smaller than the hop count in route table entry.
1424  else if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (hop < toDst.GetHop ()))
1425  {
1426  m_routingTable.Update (newEntry);
1427  }
1428  }
1429  }
1430  else
1431  {
1432  // The forward route for this destination is created if it does not already exist.
1433  NS_LOG_LOGIC ("add new route");
1434  m_routingTable.AddRoute (newEntry);
1435  }
1436  // Acknowledge receipt of the RREP by sending a RREP-ACK message back
1437  if (rrepHeader.GetAckRequired ())
1438  {
1439  SendReplyAck (sender);
1440  rrepHeader.SetAckRequired (false);
1441  }
1442  NS_LOG_LOGIC ("receiver " << receiver << " origin " << rrepHeader.GetOrigin ());
1443  if (IsMyOwnAddress (rrepHeader.GetOrigin ()))
1444  {
1445  if (toDst.GetFlag () == IN_SEARCH)
1446  {
1447  m_routingTable.Update (newEntry);
1448  m_addressReqTimer[dst].Remove ();
1449  m_addressReqTimer.erase (dst);
1450  }
1451  m_routingTable.LookupRoute (dst, toDst);
1452  SendPacketFromQueue (dst, toDst.GetRoute ());
1453  return;
1454  }
1455 
1456  RoutingTableEntry toOrigin;
1457  if (!m_routingTable.LookupRoute (rrepHeader.GetOrigin (), toOrigin) || toOrigin.GetFlag () == IN_SEARCH)
1458  {
1459  return; // Impossible! drop.
1460  }
1461  toOrigin.SetLifeTime (std::max (ActiveRouteTimeout, toOrigin.GetLifeTime ()));
1462  m_routingTable.Update (toOrigin);
1463 
1464  // Update information about precursors
1465  if (m_routingTable.LookupValidRoute (rrepHeader.GetDst (), toDst))
1466  {
1467  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1468  m_routingTable.Update (toDst);
1469 
1470  RoutingTableEntry toNextHopToDst;
1471  m_routingTable.LookupRoute (toDst.GetNextHop (), toNextHopToDst);
1472  toNextHopToDst.InsertPrecursor (toOrigin.GetNextHop ());
1473  m_routingTable.Update (toNextHopToDst);
1474 
1475  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1476  m_routingTable.Update (toOrigin);
1477 
1478  RoutingTableEntry toNextHopToOrigin;
1479  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHopToOrigin);
1480  toNextHopToOrigin.InsertPrecursor (toDst.GetNextHop ());
1481  m_routingTable.Update (toNextHopToOrigin);
1482  }
1483 
1484  Ptr<Packet> packet = Create<Packet> ();
1485  packet->AddHeader (rrepHeader);
1486  TypeHeader tHeader (AODVTYPE_RREP);
1487  packet->AddHeader (tHeader);
1489  NS_ASSERT (socket);
1490  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1491 }
1492 
1493 void
1495 {
1496  NS_LOG_FUNCTION (this);
1497  RoutingTableEntry rt;
1498  if(m_routingTable.LookupRoute (neighbor, rt))
1499  {
1500  rt.m_ackTimer.Cancel ();
1501  rt.SetFlag (VALID);
1502  m_routingTable.Update (rt);
1503  }
1504 }
1505 
1506 void
1508 {
1509  NS_LOG_FUNCTION (this << "from " << rrepHeader.GetDst ());
1510  /*
1511  * Whenever a node receives a Hello message from a neighbor, the node
1512  * SHOULD make sure that it has an active route to the neighbor, and
1513  * create one if necessary.
1514  */
1515  RoutingTableEntry toNeighbor;
1516  if (!m_routingTable.LookupRoute (rrepHeader.GetDst (), toNeighbor))
1517  {
1518  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1519  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ rrepHeader.GetDst (), /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1520  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1521  /*hop=*/ 1, /*nextHop=*/ rrepHeader.GetDst (), /*lifeTime=*/ rrepHeader.GetLifeTime ());
1522  m_routingTable.AddRoute (newEntry);
1523  }
1524  else
1525  {
1526  toNeighbor.SetLifeTime (std::max (Time (AllowedHelloLoss * HelloInterval), toNeighbor.GetLifeTime ()));
1527  toNeighbor.SetSeqNo (rrepHeader.GetDstSeqno ());
1528  toNeighbor.SetValidSeqNo (true);
1529  toNeighbor.SetFlag (VALID);
1530  toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1531  toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1532  toNeighbor.SetHop (1);
1533  toNeighbor.SetNextHop (rrepHeader.GetDst ());
1534  m_routingTable.Update (toNeighbor);
1535  }
1536  if (EnableHello)
1537  {
1538  m_nb.Update (rrepHeader.GetDst (), Time (AllowedHelloLoss * HelloInterval));
1539  }
1540 }
1541 
1542 void
1544 {
1545  NS_LOG_FUNCTION (this << " from " << src);
1546  RerrHeader rerrHeader;
1547  p->RemoveHeader (rerrHeader);
1548  std::map<Ipv4Address, uint32_t> dstWithNextHopSrc;
1549  std::map<Ipv4Address, uint32_t> unreachable;
1550  m_routingTable.GetListOfDestinationWithNextHop (src, dstWithNextHopSrc);
1551  std::pair<Ipv4Address, uint32_t> un;
1552  while (rerrHeader.RemoveUnDestination (un))
1553  {
1554  for (std::map<Ipv4Address, uint32_t>::const_iterator i =
1555  dstWithNextHopSrc.begin (); i != dstWithNextHopSrc.end (); ++i)
1556  {
1557  if (i->first == un.first)
1558  {
1559  unreachable.insert (un);
1560  }
1561  }
1562  }
1563 
1564  std::vector<Ipv4Address> precursors;
1565  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin ();
1566  i != unreachable.end ();)
1567  {
1568  if (!rerrHeader.AddUnDestination (i->first, i->second))
1569  {
1570  TypeHeader typeHeader (AODVTYPE_RERR);
1571  Ptr<Packet> packet = Create<Packet> ();
1572  packet->AddHeader (rerrHeader);
1573  packet->AddHeader (typeHeader);
1574  SendRerrMessage (packet, precursors);
1575  rerrHeader.Clear ();
1576  }
1577  else
1578  {
1579  RoutingTableEntry toDst;
1580  m_routingTable.LookupRoute (i->first, toDst);
1581  toDst.GetPrecursors (precursors);
1582  ++i;
1583  }
1584  }
1585  if (rerrHeader.GetDestCount () != 0)
1586  {
1587  TypeHeader typeHeader (AODVTYPE_RERR);
1588  Ptr<Packet> packet = Create<Packet> ();
1589  packet->AddHeader (rerrHeader);
1590  packet->AddHeader (typeHeader);
1591  SendRerrMessage (packet, precursors);
1592  }
1594 }
1595 
1596 void
1598 {
1599  NS_LOG_LOGIC (this);
1600  RoutingTableEntry toDst;
1601  if (m_routingTable.LookupValidRoute (dst, toDst))
1602  {
1603  SendPacketFromQueue (dst, toDst.GetRoute ());
1604  NS_LOG_LOGIC ("route to " << dst << " found");
1605  return;
1606  }
1607  /*
1608  * If a route discovery has been attempted RreqRetries times at the maximum TTL without
1609  * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
1610  * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the application.
1611  */
1612  if (toDst.GetRreqCnt () == RreqRetries)
1613  {
1614  NS_LOG_LOGIC ("route discovery to " << dst << " has been attempted RreqRetries (" << RreqRetries << ") times");
1615  m_addressReqTimer.erase (dst);
1617  NS_LOG_DEBUG ("Route not found. Drop all packets with dst " << dst);
1618  m_queue.DropPacketWithDst (dst);
1619  return;
1620  }
1621 
1622  if (toDst.GetFlag () == IN_SEARCH)
1623  {
1624  NS_LOG_LOGIC ("Resend RREQ to " << dst << " ttl " << NetDiameter);
1625  SendRequest (dst);
1626  }
1627  else
1628  {
1629  NS_LOG_DEBUG ("Route down. Stop search. Drop packet with destination " << dst);
1630  m_addressReqTimer.erase (dst);
1632  m_queue.DropPacketWithDst (dst);
1633  }
1634 }
1635 
1636 void
1638 {
1639  NS_LOG_FUNCTION (this);
1640  Time offset = Time (Seconds (0));
1641  if (m_lastBcastTime > Time (Seconds (0)))
1642  {
1643  offset = Simulator::Now () - m_lastBcastTime;
1644  NS_LOG_DEBUG ("Hello deferred due to last bcast at:" << m_lastBcastTime);
1645  }
1646  else
1647  {
1648  SendHello ();
1649  }
1650  m_htimer.Cancel ();
1651  Time diff = HelloInterval - offset;
1652  m_htimer.Schedule (std::max (Time (Seconds (0)), diff));
1653  m_lastBcastTime = Time (Seconds (0));
1654 }
1655 
1656 void
1658 {
1659  NS_LOG_FUNCTION (this);
1660  m_rreqCount = 0;
1662 }
1663 
1664 void
1666 {
1667  NS_LOG_FUNCTION (this);
1668  m_rerrCount = 0;
1670 }
1671 
1672 void
1674 {
1675  NS_LOG_FUNCTION (this);
1676  m_routingTable.MarkLinkAsUnidirectional (neighbor, blacklistTimeout);
1677 }
1678 
1679 void
1681 {
1682  NS_LOG_FUNCTION (this);
1683  /* Broadcast a RREP with TTL = 1 with the RREP message fields set as follows:
1684  * Destination IP Address The node's IP address.
1685  * Destination Sequence Number The node's latest sequence number.
1686  * Hop Count 0
1687  * Lifetime AllowedHelloLoss * HelloInterval
1688  */
1689  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1690  {
1691  Ptr<Socket> socket = j->first;
1692  Ipv4InterfaceAddress iface = j->second;
1693  RrepHeader helloHeader (/*prefix size=*/ 0, /*hops=*/ 0, /*dst=*/ iface.GetLocal (), /*dst seqno=*/ m_seqNo,
1694  /*origin=*/ iface.GetLocal (),/*lifetime=*/ Time (AllowedHelloLoss * HelloInterval));
1695  Ptr<Packet> packet = Create<Packet> ();
1696  packet->AddHeader (helloHeader);
1697  TypeHeader tHeader (AODVTYPE_RREP);
1698  packet->AddHeader (tHeader);
1699  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1700  Ipv4Address destination;
1701  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1702  {
1703  destination = Ipv4Address ("255.255.255.255");
1704  }
1705  else
1706  {
1707  destination = iface.GetBroadcast ();
1708  }
1710  Simulator::Schedule (jitter, &RoutingProtocol::SendTo, this , socket, packet, destination);
1711  }
1712 }
1713 
1714 void
1716 {
1717  NS_LOG_FUNCTION (this);
1718  QueueEntry queueEntry;
1719  while (m_queue.Dequeue (dst, queueEntry))
1720  {
1722  Ptr<Packet> p = ConstCast<Packet> (queueEntry.GetPacket ());
1723  if (p->RemovePacketTag (tag) &&
1724  tag.GetInterface() != -1 &&
1725  tag.GetInterface() != m_ipv4->GetInterfaceForDevice (route->GetOutputDevice ()))
1726  {
1727  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
1728  return;
1729  }
1731  Ipv4Header header = queueEntry.GetIpv4Header ();
1732  header.SetSource (route->GetSource ());
1733  header.SetTtl (header.GetTtl () + 1); // compensate extra TTL decrement by fake loopback routing
1734  ucb (route, p, header);
1735  }
1736 }
1737 
1738 void
1740 {
1741  NS_LOG_FUNCTION (this << nextHop);
1742  RerrHeader rerrHeader;
1743  std::vector<Ipv4Address> precursors;
1744  std::map<Ipv4Address, uint32_t> unreachable;
1745 
1746  RoutingTableEntry toNextHop;
1747  if (!m_routingTable.LookupRoute (nextHop, toNextHop))
1748  return;
1749  toNextHop.GetPrecursors (precursors);
1750  rerrHeader.AddUnDestination (nextHop, toNextHop.GetSeqNo ());
1751  m_routingTable.GetListOfDestinationWithNextHop (nextHop, unreachable);
1752  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin (); i
1753  != unreachable.end ();)
1754  {
1755  if (!rerrHeader.AddUnDestination (i->first, i->second))
1756  {
1757  NS_LOG_LOGIC ("Send RERR message with maximum size.");
1758  TypeHeader typeHeader (AODVTYPE_RERR);
1759  Ptr<Packet> packet = Create<Packet> ();
1760  packet->AddHeader (rerrHeader);
1761  packet->AddHeader (typeHeader);
1762  SendRerrMessage (packet, precursors);
1763  rerrHeader.Clear ();
1764  }
1765  else
1766  {
1767  RoutingTableEntry toDst;
1768  m_routingTable.LookupRoute (i->first, toDst);
1769  toDst.GetPrecursors (precursors);
1770  ++i;
1771  }
1772  }
1773  if (rerrHeader.GetDestCount () != 0)
1774  {
1775  TypeHeader typeHeader (AODVTYPE_RERR);
1776  Ptr<Packet> packet = Create<Packet> ();
1777  packet->AddHeader (rerrHeader);
1778  packet->AddHeader (typeHeader);
1779  SendRerrMessage (packet, precursors);
1780  }
1781  unreachable.insert (std::make_pair (nextHop, toNextHop.GetSeqNo ()));
1783 }
1784 
1785 void
1787  uint32_t dstSeqNo, Ipv4Address origin)
1788 {
1789  NS_LOG_FUNCTION (this);
1790  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
1791  if (m_rerrCount == RerrRateLimit)
1792  {
1793  // Just make sure that the RerrRateLimit timer is running and will expire
1795  // discard the packet and return
1796  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
1798  << "; suppressing RERR");
1799  return;
1800  }
1801  RerrHeader rerrHeader;
1802  rerrHeader.AddUnDestination (dst, dstSeqNo);
1803  RoutingTableEntry toOrigin;
1804  Ptr<Packet> packet = Create<Packet> ();
1805  packet->AddHeader (rerrHeader);
1806  packet->AddHeader (TypeHeader (AODVTYPE_RERR));
1807  if (m_routingTable.LookupValidRoute (origin, toOrigin))
1808  {
1810  toOrigin.GetInterface ());
1811  NS_ASSERT (socket);
1812  NS_LOG_LOGIC ("Unicast RERR to the source of the data transmission");
1813  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1814  }
1815  else
1816  {
1817  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
1818  m_socketAddresses.begin (); i != m_socketAddresses.end (); ++i)
1819  {
1820  Ptr<Socket> socket = i->first;
1821  Ipv4InterfaceAddress iface = i->second;
1822  NS_ASSERT (socket);
1823  NS_LOG_LOGIC ("Broadcast RERR message from interface " << iface.GetLocal ());
1824  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1825  Ipv4Address destination;
1826  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1827  {
1828  destination = Ipv4Address ("255.255.255.255");
1829  }
1830  else
1831  {
1832  destination = iface.GetBroadcast ();
1833  }
1834  socket->SendTo (packet->Copy (), 0, InetSocketAddress (destination, AODV_PORT));
1835  }
1836  }
1837 }
1838 
1839 void
1840 RoutingProtocol::SendRerrMessage (Ptr<Packet> packet, std::vector<Ipv4Address> precursors)
1841 {
1842  NS_LOG_FUNCTION (this);
1843 
1844  if (precursors.empty ())
1845  {
1846  NS_LOG_LOGIC ("No precursors");
1847  return;
1848  }
1849  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
1850  if (m_rerrCount == RerrRateLimit)
1851  {
1852  // Just make sure that the RerrRateLimit timer is running and will expire
1854  // discard the packet and return
1855  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
1857  << "; suppressing RERR");
1858  return;
1859  }
1860  // If there is only one precursor, RERR SHOULD be unicast toward that precursor
1861  if (precursors.size () == 1)
1862  {
1863  RoutingTableEntry toPrecursor;
1864  if (m_routingTable.LookupValidRoute (precursors.front (), toPrecursor))
1865  {
1866  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toPrecursor.GetInterface ());
1867  NS_ASSERT (socket);
1868  NS_LOG_LOGIC ("one precursor => unicast RERR to " << toPrecursor.GetDestination () << " from " << toPrecursor.GetInterface ().GetLocal ());
1869  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, precursors.front ());
1870  m_rerrCount++;
1871  }
1872  return;
1873  }
1874 
1875  // Should only transmit RERR on those interfaces which have precursor nodes for the broken route
1876  std::vector<Ipv4InterfaceAddress> ifaces;
1877  RoutingTableEntry toPrecursor;
1878  for (std::vector<Ipv4Address>::const_iterator i = precursors.begin (); i != precursors.end (); ++i)
1879  {
1880  if (m_routingTable.LookupValidRoute (*i, toPrecursor) &&
1881  std::find (ifaces.begin (), ifaces.end (), toPrecursor.GetInterface ()) == ifaces.end ())
1882  {
1883  ifaces.push_back (toPrecursor.GetInterface ());
1884  }
1885  }
1886 
1887  for (std::vector<Ipv4InterfaceAddress>::const_iterator i = ifaces.begin (); i != ifaces.end (); ++i)
1888  {
1890  NS_ASSERT (socket);
1891  NS_LOG_LOGIC ("Broadcast RERR message from interface " << i->GetLocal ());
1892  // std::cout << "Broadcast RERR message from interface " << i->GetLocal () << std::endl;
1893  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1894  Ptr<Packet> p = packet->Copy ();
1895  Ipv4Address destination;
1896  if (i->GetMask () == Ipv4Mask::GetOnes ())
1897  {
1898  destination = Ipv4Address ("255.255.255.255");
1899  }
1900  else
1901  {
1902  destination = i->GetBroadcast ();
1903  }
1904  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, p, destination);
1905  }
1906 }
1907 
1910 {
1911  NS_LOG_FUNCTION (this << addr);
1912  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1913  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1914  {
1915  Ptr<Socket> socket = j->first;
1916  Ipv4InterfaceAddress iface = j->second;
1917  if (iface == addr)
1918  return socket;
1919  }
1920  Ptr<Socket> socket;
1921  return socket;
1922 }
1923 
1926 {
1927  NS_LOG_FUNCTION (this << addr);
1928  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1930  {
1931  Ptr<Socket> socket = j->first;
1932  Ipv4InterfaceAddress iface = j->second;
1933  if (iface == addr)
1934  return socket;
1935  }
1936  Ptr<Socket> socket;
1937  return socket;
1938 }
1939 
1940 void
1942 {
1943  NS_LOG_FUNCTION (this);
1944  uint32_t startTime;
1945  if (EnableHello)
1946  {
1948  startTime = m_uniformRandomVariable->GetInteger (0, 100);
1949  NS_LOG_DEBUG ("Starting at time " << startTime << "ms");
1950  m_htimer.Schedule (MilliSeconds (startTime));
1951  }
1953 }
1954 
1955 } //namespace aodv
1956 } //namespace ns3
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:285
UnicastForwardCallback GetUnicastForwardCallback() const
Definition: aodv-rqueue.h:66
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
static TypeId GetTypeId(void)
Get the type ID.
void SendReplyAck(Ipv4Address neighbor)
Send RREP_ACK.
static Ipv4Mask GetOnes(void)
void InvalidateRoutesWithDst(std::map< Ipv4Address, uint32_t > const &unreachable)
Update routing entries with this destinations as follows:
Definition: aodv-rtable.cc:315
virtual void DoInitialize(void)
Initialize() implementation.
Definition: object.cc:347
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
bool MarkLinkAsUnidirectional(Ipv4Address neighbor, Time blacklistTimeout)
Mark entry as unidirectional (e.g.
Definition: aodv-rtable.cc:421
an Inet address class
Ipv4Address GetIpv4(void) const
void SetOutputDevice(Ptr< NetDevice > dev)
Definition: aodv-rtable.h:111
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
uint16_t m_rreqCount
Number of RREQs used for RREQ rate control.
AttributeValue implementation for Boolean.
Definition: boolean.h:34
Ipv4Mask GetMask(void) const
Get the network mask.
Callback template class.
Definition: callback.h:1176
Time MaxQueueTime
The maximum period of time that a routing protocol is allowed to buffer a packet for.
bool GetUnknownSeqno() const
Definition: aodv-packet.cc:264
bool LookupRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup routing table entry with destination address dst.
Definition: aodv-rtable.cc:200
void Clear()
Delete all entries from routing table.
Definition: aodv-rtable.h:235
void SendTo(Ptr< Socket > socket, Ptr< Packet > packet, Ipv4Address destination)
RoutingTable m_routingTable
Routing table.
A simple Timer class.
Definition: timer.h:73
Ipv4Header GetIpv4Header() const
Definition: aodv-rqueue.h:72
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
void SetId(uint32_t id)
Definition: aodv-packet.h:120
bool GetAckRequired() const
Definition: aodv-packet.cc:380
Ipv4Address GetLocal(void) const
Get the local address.
Hold variables of type string.
Definition: string.h:41
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
Route Error (RERR) Message Format.
Definition: aodv-packet.h:272
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:257
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:81
Routing table entry.
Definition: aodv-rtable.h:59
Tag used by AODV implementation.
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:824
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:261
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the Routing Table entries.
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:368
Timer m_ackTimer
RREP_ACK timer.
Definition: aodv-rtable.h:133
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
void IncrementRreqCnt()
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
Check for null implementation.
Definition: callback.h:1270
void SetMaxQueueLen(uint32_t len)
Definition: aodv-rqueue.h:117
#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
void SetDst(Ipv4Address a)
Definition: aodv-packet.h:122
void DelArpCache(Ptr< ArpCache >)
Don't use given ARP cache any more (interface is down)
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:272
uint32_t GetDstSeqno() const
Definition: aodv-packet.h:193
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:903
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
virtual void DoDispose()
Destructor implementation.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
Timer m_rreqRateLimitTimer
RREQ rate limit timer.
bool IsMulticast(void) const
Ptr< NetDevice > GetOutputDevice() const
Definition: aodv-rtable.h:112
Time NetTraversalTime
Estimate of the average net traversal time.
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
Neighbors m_nb
Handle neighbors.
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:340
void GetPrecursors(std::vector< Ipv4Address > &prec) const
Inserts precursors in vector prec if they does not yet exist in vector.
Definition: aodv-rtable.cc:128
TAG_BUFFER_INLINE uint32_t ReadU32(void)
Definition: tag-buffer.h:215
void SetLifeTime(Time lt)
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:100
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
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:50
uint32_t m_seqNo
Request sequence number.
void ScheduleRreqRetry(Ipv4Address dst)
To reduce congestion in a network, repeated attempts by a source node at route discovery for a single...
Ptr< Socket > FindSocketWithInterfaceAddress(Ipv4InterfaceAddress iface) const
Find unicast socket with local interface address iface.
a polymophic address class
Definition: address.h:90
bool IsRunning(void) const
Definition: timer.cc:127
Ptr< Ipv4Route > LoopbackRoute(const Ipv4Header &header, Ptr< NetDevice > oif) const
Create loopback route for given header.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
bool IsValid() const
Check that type if valid.
Definition: aodv-packet.h:70
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:611
bool InsertPrecursor(Ipv4Address id)
Insert precursor in precursor list if it doesn't yet exist in the list.
Definition: aodv-rtable.cc:66
Packet header for IPv4.
Definition: ipv4-header.h:31
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
void Print(Ptr< OutputStreamWrapper > stream) const
Print routing table.
Definition: aodv-rtable.cc:439
Time GetLifeTime() const
Definition: aodv-rtable.h:122
bool DestinationOnly
Indicates only the destination may respond to this RREQ.
void SetRreqCnt(uint8_t n)
Definition: aodv-rtable.h:125
void RecvReplyAck(Ipv4Address neighbor)
Receive RREP_ACK.
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:846
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:188
bool IsMyOwnAddress(Ipv4Address src)
Check that packet is send from own interface.
virtual uint32_t GetInteger(void)=0
Get the next random value as an integer drawn from the distribution.
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
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)
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1221
void RecvReply(Ptr< Packet > p, Ipv4Address my, Ipv4Address src)
Receive RREP.
#define max(a, b)
Definition: 80211b.c:45
bool GetGratiousRrep() const
Definition: aodv-packet.cc:234
void DeleteAllRoutesFromInterface(Ipv4InterfaceAddress iface)
Delete all route from interface with address iface.
Definition: aodv-rtable.cc:335
void HelloTimerExpire()
Schedule next send of hello message.
AttributeValue implementation for Time.
Definition: nstime.h:957
void Schedule(void)
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:158
uint8_t GetDestCount() const
Return number of unreachable destinations in RERR message.
Definition: aodv-packet.h:302
Ipv4Address GetNextHop() const
Definition: aodv-rtable.h:110
bool AddUnDestination(Ipv4Address dst, uint32_t seqNo)
Add unreachable node address and its sequence number in RERR header.
Definition: aodv-packet.cc:589
void SetGateway(Ipv4Address gw)
Definition: ipv4-route.cc:63
void SetFunction(FN fn)
Definition: timer.h:309
bool UpdateRouteLifeTime(Ipv4Address addr, Time lt)
Set lifetime field in routing table entry to the maximum of existing lifetime and lt...
Hold an unsigned integer type.
Definition: uinteger.h:44
void UpdateRouteToNeighbor(Ipv4Address sender, Ipv4Address receiver)
Update neighbor record.
Ipv4Address GetDst() const
Definition: aodv-packet.h:123
double startTime
Time HelloInterval
Every HelloInterval the node checks whether it has sent a broadcast within the last HelloInterval...
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
Definition: tag-buffer.h:186
AODV routing protocol.
bool IsBroadcast(void) const
void SetSeqNo(uint32_t sn)
Definition: aodv-rtable.h:117
uint16_t RreqRateLimit
Maximum number of RREQ per second.
void SetValidSeqNo(bool s)
Definition: aodv-rtable.h:115
void SetOriginSeqno(uint32_t s)
Definition: aodv-packet.h:128
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.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
uint8_t GetHopCount() const
Definition: aodv-packet.h:119
void SetDestinationOnly(bool f)
Definition: aodv-packet.cc:240
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:128
virtual void DoInitialize(void)
Initialize() implementation.
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:71
void SendReplyByIntermediateNode(RoutingTableEntry &toDst, RoutingTableEntry &toOrigin, bool gratRep)
Send RREP by intermediate node.
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
tuple mac
Definition: third.py:92
Ptr< const Packet > GetPacket() const
Definition: aodv-rqueue.h:70
Ipv4InterfaceAddress GetInterface() const
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:75
void DropPacketWithDst(Ipv4Address dst)
Remove all packets with destination IP address dst.
Definition: aodv-rqueue.cc:72
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
uint16_t m_rerrCount
Number of RERRs used for RERR rate control.
Ipv4Address GetGateway(void) const
Definition: ipv4-route.cc:70
static Ipv4Address GetBroadcast(void)
void SetDstSeqno(uint32_t s)
Definition: aodv-packet.h:124
Route Reply (RREP) Message Format.
Definition: aodv-packet.h:172
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:298
void SetInterface(Ipv4InterfaceAddress iface)
Definition: aodv-rtable.h:114
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
AODV Queue Entry.
Definition: aodv-rqueue.h:43
void SendRerrWhenNoRouteToForward(Ipv4Address dst, uint32_t dstSeqNo, Ipv4Address origin)
Send RERR message when no route to forward input packet.
This policy cancels the event from the destructor of the Timer to verify that the event has already e...
Definition: timer.h:86
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.
Time NodeTraversalTime
NodeTraversalTime is a conservative estimate of the average one hop traversal time for packets and sh...
void SetArguments(T1 a1)
Definition: timer.h:324
Implement the Ipv4 layer.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketSubnetBroadcastAddresses
Raw subnet directed broadcast socket per each IP interface, map socket -> iface address (IP + mask) ...
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
void SetFlag(RouteFlags flag)
Definition: aodv-rtable.h:123
Ipv4Address GetOrigin() const
Definition: aodv-packet.h:195
uint16_t GetHop() const
Definition: aodv-rtable.h:120
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
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)
Delete pair (address + sequence number) from REER header, if the number of unreachable destinations >...
Definition: aodv-packet.cc:600
Ptr< Socket > FindSubnetBroadcastSocketWithInterfaceAddress(Ipv4InterfaceAddress iface) const
Find subnet directed broadcast socket with local interface address iface.
void RecvRequest(Ptr< Packet > p, Ipv4Address receiver, Ipv4Address src)
Receive RREQ.
void SetOrigin(Ipv4Address a)
Definition: aodv-packet.h:126
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketAddresses
Raw unicast socket per each IP interface, map socket -> iface address (IP + mask) ...
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Schedule an event to expire Now.
Definition: simulator.h:1384
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:958
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)
Return the current simulation virtual time.
Definition: simulator.cc:223
void SetOutputDevice(Ptr< NetDevice > outputDevice)
Equivalent in Linux to dst_entry.dev.
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:364
AODVTYPE_RREQ.
Definition: aodv-packet.h:43
Ipv4Address GetDst() const
Definition: aodv-packet.h:191
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:330
Route Reply Acknowledgment (RREP-ACK) Message Format.
Definition: aodv-packet.h:232
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)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:90
uint32_t GetDstSeqno() const
Definition: aodv-packet.h:125
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)
Definition: aodv-rtable.h:119
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
Time NextHopWait
Period of our waiting for the neighbour's RREP_ACK.
Time DeletePeriod
DeletePeriod is intended to provide an upper bound on the time for which an upstream node A can have ...
read and write tag data
Definition: tag-buffer.h:51
Ipv4Address GetBroadcast(void) const
Get the broadcast address.
virtual void NotifyInterfaceDown(uint32_t interface)
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:388
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)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
uint32_t GetSeqNo() const
Definition: aodv-rtable.h:118
void SetQueueTimeout(Time t)
Definition: aodv-rqueue.h:119
bool AddRoute(RoutingTableEntry &r)
Add routing table entry if it doesn't yet exist in routing table.
Definition: aodv-rtable.cc:249
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:831
A network Node.
Definition: node.h:56
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
void Cancel(void)
Cancel the currently-running event if there is one.
Definition: timer.cc:109
uint32_t AllowedHelloLoss
Number of hello messages which may be loss for valid link.
Ipv4Address GetOrigin() const
Definition: aodv-packet.h:127
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:259
void SetCallback(Callback< void, Ipv4Address > cb)
Handle link failure callback.
Definition: aodv-neighbor.h:89
void SetAckRequired(bool f)
Definition: aodv-packet.cc:371
void Print(std::ostream &os) const
void SendReply(RreqHeader const &rreqHeader, RoutingTableEntry const &toOrigin)
Send RREP.
uint32_t GetOriginSeqno() const
Definition: aodv-packet.h:129
Abstract base class for IPv4 routing protocols.
void SetNextHop(Ipv4Address nextHop)
Definition: aodv-rtable.h:109
bool GetDestinationOnly() const
Definition: aodv-packet.cc:249
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.
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
Definition: aodv-rtable.h:107
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:911
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:330
bool GratuitousReply
Indicates whether a gratuitous RREP should be unicast to the node originated route discovery...
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:220
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:265
uint16_t RerrRateLimit
Maximum number of REER per second.
tuple wifi
Definition: third.py:89
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
second
Definition: nstime.h:114
void SetGratiousRrep(bool f)
Definition: aodv-packet.cc:225
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:89
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.
TypeId GetInstanceTypeId() const
Get the most derived TypeId for this Object.
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:222
Time GetDelayLeft(void) const
Definition: timer.cc:87
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:191
bool IsUnidirectional() const
Definition: aodv-rtable.h:129
uint32_t GetId() const
Definition: aodv-packet.h:121
bool DeleteRoute(Ipv4Address dst)
Delete routing table entry with destination address dst, if it exists.
Definition: aodv-rtable.cc:235
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
void Purge()
Delete all outdated entries and invalidate valid entry if Lifetime is expired.
Definition: aodv-rtable.cc:355
a unique identifier for an interface.
Definition: type-id.h:58
Ptr< NetDevice > m_lo
Loopback device used to defer RREQ until packet will be fully formed.
RouteFlags GetFlag() const
Definition: aodv-rtable.h:124
uint32_t m_requestId
Broadcast ID.
Ipv4Address GetDestination() const
Definition: aodv-rtable.h:106
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:827
MessageType Get() const
Return type.
Definition: aodv-packet.h:68
uint8_t GetHopCount() const
Definition: aodv-packet.h:189
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
Definition: aodv-rtable.h:126
static Time GetMaximumSimulationTime(void)
Get the maximum representable simulation time.
Definition: simulator.cc:336
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:719
void SetUnknownSeqno(bool f)
Definition: aodv-packet.cc:255
virtual Address GetAddress(void) const =0
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:257
void SetDestination(Ipv4Address dest)
Definition: ipv4-route.cc:35
void ScheduleTimer()
Schedule m_ntimer.
bool GetValidSeqNo() const
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:118
bool EnableHello
Indicates whether a hello messages enable.