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