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