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