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, unit);
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);
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].Cancel ();
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  NS_ABORT_MSG_UNLESS (rt.GetRreqCnt () > 0, "Unexpected value for GetRreqCount ()");
1104  uint16_t backoffFactor = rt.GetRreqCnt () - 1;
1105  NS_LOG_LOGIC ("Applying binary exponential backoff factor " << backoffFactor);
1106  retry = m_netTraversalTime * (1 << backoffFactor);
1107  }
1108  m_addressReqTimer[dst].Schedule (retry);
1109  NS_LOG_LOGIC ("Scheduled RREQ retry in " << retry.As (Time::S));
1110 }
1111 
1112 void
1114 {
1115  NS_LOG_FUNCTION (this << socket);
1116  Address sourceAddress;
1117  Ptr<Packet> packet = socket->RecvFrom (sourceAddress);
1118  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
1119  Ipv4Address sender = inetSourceAddr.GetIpv4 ();
1120  Ipv4Address receiver;
1121 
1122  if (m_socketAddresses.find (socket) != m_socketAddresses.end ())
1123  {
1124  receiver = m_socketAddresses[socket].GetLocal ();
1125  }
1126  else if (m_socketSubnetBroadcastAddresses.find (socket) != m_socketSubnetBroadcastAddresses.end ())
1127  {
1128  receiver = m_socketSubnetBroadcastAddresses[socket].GetLocal ();
1129  }
1130  else
1131  {
1132  NS_ASSERT_MSG (false, "Received a packet from an unknown socket");
1133  }
1134  NS_LOG_DEBUG ("AODV node " << this << " received a AODV packet from " << sender << " to " << receiver);
1135 
1136  UpdateRouteToNeighbor (sender, receiver);
1137  TypeHeader tHeader (AODVTYPE_RREQ);
1138  packet->RemoveHeader (tHeader);
1139  if (!tHeader.IsValid ())
1140  {
1141  NS_LOG_DEBUG ("AODV message " << packet->GetUid () << " with unknown type received: " << tHeader.Get () << ". Drop");
1142  return; // drop
1143  }
1144  switch (tHeader.Get ())
1145  {
1146  case AODVTYPE_RREQ:
1147  {
1148  RecvRequest (packet, receiver, sender);
1149  break;
1150  }
1151  case AODVTYPE_RREP:
1152  {
1153  RecvReply (packet, receiver, sender);
1154  break;
1155  }
1156  case AODVTYPE_RERR:
1157  {
1158  RecvError (packet, sender);
1159  break;
1160  }
1161  case AODVTYPE_RREP_ACK:
1162  {
1163  RecvReplyAck (sender);
1164  break;
1165  }
1166  }
1167 }
1168 
1169 bool
1171 {
1172  NS_LOG_FUNCTION (this << addr << lifetime);
1173  RoutingTableEntry rt;
1174  if (m_routingTable.LookupRoute (addr, rt))
1175  {
1176  if (rt.GetFlag () == VALID)
1177  {
1178  NS_LOG_DEBUG ("Updating VALID route");
1179  rt.SetRreqCnt (0);
1180  rt.SetLifeTime (std::max (lifetime, rt.GetLifeTime ()));
1181  m_routingTable.Update (rt);
1182  return true;
1183  }
1184  }
1185  return false;
1186 }
1187 
1188 void
1190 {
1191  NS_LOG_FUNCTION (this << "sender " << sender << " receiver " << receiver);
1192  RoutingTableEntry toNeighbor;
1193  if (!m_routingTable.LookupRoute (sender, toNeighbor))
1194  {
1195  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1196  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1197  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1198  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ m_activeRouteTimeout);
1199  m_routingTable.AddRoute (newEntry);
1200  }
1201  else
1202  {
1203  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1204  if (toNeighbor.GetValidSeqNo () && (toNeighbor.GetHop () == 1) && (toNeighbor.GetOutputDevice () == dev))
1205  {
1206  toNeighbor.SetLifeTime (std::max (m_activeRouteTimeout, toNeighbor.GetLifeTime ()));
1207  }
1208  else
1209  {
1210  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1211  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1212  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ std::max (m_activeRouteTimeout, toNeighbor.GetLifeTime ()));
1213  m_routingTable.Update (newEntry);
1214  }
1215  }
1216 
1217 }
1218 
1219 void
1221 {
1222  NS_LOG_FUNCTION (this);
1223  RreqHeader rreqHeader;
1224  p->RemoveHeader (rreqHeader);
1225 
1226  // A node ignores all RREQs received from any node in its blacklist
1227  RoutingTableEntry toPrev;
1228  if (m_routingTable.LookupRoute (src, toPrev))
1229  {
1230  if (toPrev.IsUnidirectional ())
1231  {
1232  NS_LOG_DEBUG ("Ignoring RREQ from node in blacklist");
1233  return;
1234  }
1235  }
1236 
1237  uint32_t id = rreqHeader.GetId ();
1238  Ipv4Address origin = rreqHeader.GetOrigin ();
1239 
1240  /*
1241  * Node checks to determine whether it has received a RREQ with the same Originator IP Address and RREQ ID.
1242  * If such a RREQ has been received, the node silently discards the newly received RREQ.
1243  */
1244  if (m_rreqIdCache.IsDuplicate (origin, id))
1245  {
1246  NS_LOG_DEBUG ("Ignoring RREQ due to duplicate");
1247  return;
1248  }
1249 
1250  // Increment RREQ hop count
1251  uint8_t hop = rreqHeader.GetHopCount () + 1;
1252  rreqHeader.SetHopCount (hop);
1253 
1254  /*
1255  * When the reverse route is created or updated, the following actions on the route are also carried out:
1256  * 1. the Originator Sequence Number from the RREQ is compared to the corresponding destination sequence number
1257  * in the route table entry and copied if greater than the existing value there
1258  * 2. the valid sequence number field is set to true;
1259  * 3. the next hop in the routing table becomes the node from which the RREQ was received
1260  * 4. the hop count is copied from the Hop Count in the RREQ message;
1261  * 5. the Lifetime is set to be the maximum of (ExistingLifetime, MinimalLifetime), where
1262  * MinimalLifetime = current time + 2*NetTraversalTime - 2*HopCount*NodeTraversalTime
1263  */
1264  RoutingTableEntry toOrigin;
1265  if (!m_routingTable.LookupRoute (origin, toOrigin))
1266  {
1267  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1268  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ origin, /*validSeno=*/ true, /*seqNo=*/ rreqHeader.GetOriginSeqno (),
1269  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0), /*hops=*/ hop,
1270  /*nextHop*/ src, /*timeLife=*/ Time ((2 * m_netTraversalTime - 2 * hop * m_nodeTraversalTime)));
1271  m_routingTable.AddRoute (newEntry);
1272  }
1273  else
1274  {
1275  if (toOrigin.GetValidSeqNo ())
1276  {
1277  if (int32_t (rreqHeader.GetOriginSeqno ()) - int32_t (toOrigin.GetSeqNo ()) > 0)
1278  {
1279  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1280  }
1281  }
1282  else
1283  {
1284  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1285  }
1286  toOrigin.SetValidSeqNo (true);
1287  toOrigin.SetNextHop (src);
1288  toOrigin.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1289  toOrigin.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1290  toOrigin.SetHop (hop);
1291  toOrigin.SetLifeTime (std::max (Time (2 * m_netTraversalTime - 2 * hop * m_nodeTraversalTime),
1292  toOrigin.GetLifeTime ()));
1293  m_routingTable.Update (toOrigin);
1294  //m_nb.Update (src, Time (AllowedHelloLoss * HelloInterval));
1295  }
1296 
1297 
1298  RoutingTableEntry toNeighbor;
1299  if (!m_routingTable.LookupRoute (src, toNeighbor))
1300  {
1301  NS_LOG_DEBUG ("Neighbor:" << src << " not found in routing table. Creating an entry");
1302  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1303  RoutingTableEntry newEntry (dev, src, false, rreqHeader.GetOriginSeqno (),
1304  m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1305  1, src, m_activeRouteTimeout);
1306  m_routingTable.AddRoute (newEntry);
1307  }
1308  else
1309  {
1310  toNeighbor.SetLifeTime (m_activeRouteTimeout);
1311  toNeighbor.SetValidSeqNo (false);
1312  toNeighbor.SetSeqNo (rreqHeader.GetOriginSeqno ());
1313  toNeighbor.SetFlag (VALID);
1314  toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1315  toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1316  toNeighbor.SetHop (1);
1317  toNeighbor.SetNextHop (src);
1318  m_routingTable.Update (toNeighbor);
1319  }
1321 
1322  NS_LOG_LOGIC (receiver << " receive RREQ with hop count " << static_cast<uint32_t> (rreqHeader.GetHopCount ())
1323  << " ID " << rreqHeader.GetId ()
1324  << " to destination " << rreqHeader.GetDst ());
1325 
1326  // A node generates a RREP if either:
1327  // (i) it is itself the destination,
1328  if (IsMyOwnAddress (rreqHeader.GetDst ()))
1329  {
1330  m_routingTable.LookupRoute (origin, toOrigin);
1331  NS_LOG_DEBUG ("Send reply since I am the destination");
1332  SendReply (rreqHeader, toOrigin);
1333  return;
1334  }
1335  /*
1336  * (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
1337  * is valid and greater than or equal to the Destination Sequence Number of the RREQ, and the "destination only" flag is NOT set.
1338  */
1339  RoutingTableEntry toDst;
1340  Ipv4Address dst = rreqHeader.GetDst ();
1341  if (m_routingTable.LookupRoute (dst, toDst))
1342  {
1343  /*
1344  * Drop RREQ, This node RREP will make a loop.
1345  */
1346  if (toDst.GetNextHop () == src)
1347  {
1348  NS_LOG_DEBUG ("Drop RREQ from " << src << ", dest next hop " << toDst.GetNextHop ());
1349  return;
1350  }
1351  /*
1352  * The Destination Sequence number for the requested destination is set to the maximum of the corresponding value
1353  * received in the RREQ message, and the destination sequence value currently maintained by the node for the requested destination.
1354  * However, the forwarding node MUST NOT modify its maintained value for the destination sequence number, even if the value
1355  * received in the incoming RREQ is larger than the value currently maintained by the forwarding node.
1356  */
1357  if ((rreqHeader.GetUnknownSeqno () || (int32_t (toDst.GetSeqNo ()) - int32_t (rreqHeader.GetDstSeqno ()) >= 0))
1358  && toDst.GetValidSeqNo () )
1359  {
1360  if (!rreqHeader.GetDestinationOnly () && toDst.GetFlag () == VALID)
1361  {
1362  m_routingTable.LookupRoute (origin, toOrigin);
1363  SendReplyByIntermediateNode (toDst, toOrigin, rreqHeader.GetGratuitousRrep ());
1364  return;
1365  }
1366  rreqHeader.SetDstSeqno (toDst.GetSeqNo ());
1367  rreqHeader.SetUnknownSeqno (false);
1368  }
1369  }
1370 
1371  SocketIpTtlTag tag;
1372  p->RemovePacketTag (tag);
1373  if (tag.GetTtl () < 2)
1374  {
1375  NS_LOG_DEBUG ("TTL exceeded. Drop RREQ origin " << src << " destination " << dst );
1376  return;
1377  }
1378 
1379  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1380  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1381  {
1382  Ptr<Socket> socket = j->first;
1383  Ipv4InterfaceAddress iface = j->second;
1384  Ptr<Packet> packet = Create<Packet> ();
1385  SocketIpTtlTag ttl;
1386  ttl.SetTtl (tag.GetTtl () - 1);
1387  packet->AddPacketTag (ttl);
1388  packet->AddHeader (rreqHeader);
1389  TypeHeader tHeader (AODVTYPE_RREQ);
1390  packet->AddHeader (tHeader);
1391  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1392  Ipv4Address destination;
1393  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1394  {
1395  destination = Ipv4Address ("255.255.255.255");
1396  }
1397  else
1398  {
1399  destination = iface.GetBroadcast ();
1400  }
1402  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, destination);
1403 
1404  }
1405 }
1406 
1407 void
1408 RoutingProtocol::SendReply (RreqHeader const & rreqHeader, RoutingTableEntry const & toOrigin)
1409 {
1410  NS_LOG_FUNCTION (this << toOrigin.GetDestination ());
1411  /*
1412  * Destination node MUST increment its own sequence number by one if the sequence number in the RREQ packet is equal to that
1413  * incremented value. Otherwise, the destination does not change its sequence number before generating the RREP message.
1414  */
1415  if (!rreqHeader.GetUnknownSeqno () && (rreqHeader.GetDstSeqno () == m_seqNo + 1))
1416  {
1417  m_seqNo++;
1418  }
1419  RrepHeader rrepHeader ( /*prefixSize=*/ 0, /*hops=*/ 0, /*dst=*/ rreqHeader.GetDst (),
1420  /*dstSeqNo=*/ m_seqNo, /*origin=*/ toOrigin.GetDestination (), /*lifeTime=*/ m_myRouteTimeout);
1421  Ptr<Packet> packet = Create<Packet> ();
1422  SocketIpTtlTag tag;
1423  tag.SetTtl (toOrigin.GetHop ());
1424  packet->AddPacketTag (tag);
1425  packet->AddHeader (rrepHeader);
1426  TypeHeader tHeader (AODVTYPE_RREP);
1427  packet->AddHeader (tHeader);
1429  NS_ASSERT (socket);
1430  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1431 }
1432 
1433 void
1435 {
1436  NS_LOG_FUNCTION (this);
1437  RrepHeader rrepHeader (/*prefix size=*/ 0, /*hops=*/ toDst.GetHop (), /*dst=*/ toDst.GetDestination (), /*dst seqno=*/ toDst.GetSeqNo (),
1438  /*origin=*/ toOrigin.GetDestination (), /*lifetime=*/ toDst.GetLifeTime ());
1439  /* If the node we received a RREQ for is a neighbor we are
1440  * probably facing a unidirectional link... Better request a RREP-ack
1441  */
1442  if (toDst.GetHop () == 1)
1443  {
1444  rrepHeader.SetAckRequired (true);
1445  RoutingTableEntry toNextHop;
1446  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHop);
1448  toNextHop.m_ackTimer.SetArguments (toNextHop.GetDestination (), m_blackListTimeout);
1449  toNextHop.m_ackTimer.SetDelay (m_nextHopWait);
1450  }
1451  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1452  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1453  m_routingTable.Update (toDst);
1454  m_routingTable.Update (toOrigin);
1455 
1456  Ptr<Packet> packet = Create<Packet> ();
1457  SocketIpTtlTag tag;
1458  tag.SetTtl (toOrigin.GetHop ());
1459  packet->AddPacketTag (tag);
1460  packet->AddHeader (rrepHeader);
1461  TypeHeader tHeader (AODVTYPE_RREP);
1462  packet->AddHeader (tHeader);
1464  NS_ASSERT (socket);
1465  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1466 
1467  // Generating gratuitous RREPs
1468  if (gratRep)
1469  {
1470  RrepHeader gratRepHeader (/*prefix size=*/ 0, /*hops=*/ toOrigin.GetHop (), /*dst=*/ toOrigin.GetDestination (),
1471  /*dst seqno=*/ toOrigin.GetSeqNo (), /*origin=*/ toDst.GetDestination (),
1472  /*lifetime=*/ toOrigin.GetLifeTime ());
1473  Ptr<Packet> packetToDst = Create<Packet> ();
1474  SocketIpTtlTag gratTag;
1475  gratTag.SetTtl (toDst.GetHop ());
1476  packetToDst->AddPacketTag (gratTag);
1477  packetToDst->AddHeader (gratRepHeader);
1478  TypeHeader type (AODVTYPE_RREP);
1479  packetToDst->AddHeader (type);
1481  NS_ASSERT (socket);
1482  NS_LOG_LOGIC ("Send gratuitous RREP " << packet->GetUid ());
1483  socket->SendTo (packetToDst, 0, InetSocketAddress (toDst.GetNextHop (), AODV_PORT));
1484  }
1485 }
1486 
1487 void
1489 {
1490  NS_LOG_FUNCTION (this << " to " << neighbor);
1491  RrepAckHeader h;
1492  TypeHeader typeHeader (AODVTYPE_RREP_ACK);
1493  Ptr<Packet> packet = Create<Packet> ();
1494  SocketIpTtlTag tag;
1495  tag.SetTtl (1);
1496  packet->AddPacketTag (tag);
1497  packet->AddHeader (h);
1498  packet->AddHeader (typeHeader);
1499  RoutingTableEntry toNeighbor;
1500  m_routingTable.LookupRoute (neighbor, toNeighbor);
1501  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toNeighbor.GetInterface ());
1502  NS_ASSERT (socket);
1503  socket->SendTo (packet, 0, InetSocketAddress (neighbor, AODV_PORT));
1504 }
1505 
1506 void
1508 {
1509  NS_LOG_FUNCTION (this << " src " << sender);
1510  RrepHeader rrepHeader;
1511  p->RemoveHeader (rrepHeader);
1512  Ipv4Address dst = rrepHeader.GetDst ();
1513  NS_LOG_LOGIC ("RREP destination " << dst << " RREP origin " << rrepHeader.GetOrigin ());
1514 
1515  uint8_t hop = rrepHeader.GetHopCount () + 1;
1516  rrepHeader.SetHopCount (hop);
1517 
1518  // If RREP is Hello message
1519  if (dst == rrepHeader.GetOrigin ())
1520  {
1521  ProcessHello (rrepHeader, receiver);
1522  return;
1523  }
1524 
1525  /*
1526  * If the route table entry to the destination is created or updated, then the following actions occur:
1527  * - the route is marked as active,
1528  * - the destination sequence number is marked as valid,
1529  * - the next hop in the route entry is assigned to be the node from which the RREP is received,
1530  * which is indicated by the source IP address field in the IP header,
1531  * - the hop count is set to the value of the hop count from RREP message + 1
1532  * - the expiry time is set to the current time plus the value of the Lifetime in the RREP message,
1533  * - and the destination sequence number is the Destination Sequence Number in the RREP message.
1534  */
1535  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1536  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ dst, /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1537  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),/*hop=*/ hop,
1538  /*nextHop=*/ sender, /*lifeTime=*/ rrepHeader.GetLifeTime ());
1539  RoutingTableEntry toDst;
1540  if (m_routingTable.LookupRoute (dst, toDst))
1541  {
1542  /*
1543  * The existing entry is updated only in the following circumstances:
1544  * (i) the sequence number in the routing table is marked as invalid in route table entry.
1545  */
1546  if (!toDst.GetValidSeqNo ())
1547  {
1548  m_routingTable.Update (newEntry);
1549  }
1550  // (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,
1551  else if ((int32_t (rrepHeader.GetDstSeqno ()) - int32_t (toDst.GetSeqNo ())) > 0)
1552  {
1553  m_routingTable.Update (newEntry);
1554  }
1555  else
1556  {
1557  // (iii) the sequence numbers are the same, but the route is marked as inactive.
1558  if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (toDst.GetFlag () != VALID))
1559  {
1560  m_routingTable.Update (newEntry);
1561  }
1562  // (iv) the sequence numbers are the same, and the New Hop Count is smaller than the hop count in route table entry.
1563  else if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (hop < toDst.GetHop ()))
1564  {
1565  m_routingTable.Update (newEntry);
1566  }
1567  }
1568  }
1569  else
1570  {
1571  // The forward route for this destination is created if it does not already exist.
1572  NS_LOG_LOGIC ("add new route");
1573  m_routingTable.AddRoute (newEntry);
1574  }
1575  // Acknowledge receipt of the RREP by sending a RREP-ACK message back
1576  if (rrepHeader.GetAckRequired ())
1577  {
1578  SendReplyAck (sender);
1579  rrepHeader.SetAckRequired (false);
1580  }
1581  NS_LOG_LOGIC ("receiver " << receiver << " origin " << rrepHeader.GetOrigin ());
1582  if (IsMyOwnAddress (rrepHeader.GetOrigin ()))
1583  {
1584  if (toDst.GetFlag () == IN_SEARCH)
1585  {
1586  m_routingTable.Update (newEntry);
1587  m_addressReqTimer[dst].Cancel ();
1588  m_addressReqTimer.erase (dst);
1589  }
1590  m_routingTable.LookupRoute (dst, toDst);
1591  SendPacketFromQueue (dst, toDst.GetRoute ());
1592  return;
1593  }
1594 
1595  RoutingTableEntry toOrigin;
1596  if (!m_routingTable.LookupRoute (rrepHeader.GetOrigin (), toOrigin) || toOrigin.GetFlag () == IN_SEARCH)
1597  {
1598  return; // Impossible! drop.
1599  }
1600  toOrigin.SetLifeTime (std::max (m_activeRouteTimeout, toOrigin.GetLifeTime ()));
1601  m_routingTable.Update (toOrigin);
1602 
1603  // Update information about precursors
1604  if (m_routingTable.LookupValidRoute (rrepHeader.GetDst (), toDst))
1605  {
1606  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1607  m_routingTable.Update (toDst);
1608 
1609  RoutingTableEntry toNextHopToDst;
1610  m_routingTable.LookupRoute (toDst.GetNextHop (), toNextHopToDst);
1611  toNextHopToDst.InsertPrecursor (toOrigin.GetNextHop ());
1612  m_routingTable.Update (toNextHopToDst);
1613 
1614  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1615  m_routingTable.Update (toOrigin);
1616 
1617  RoutingTableEntry toNextHopToOrigin;
1618  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHopToOrigin);
1619  toNextHopToOrigin.InsertPrecursor (toDst.GetNextHop ());
1620  m_routingTable.Update (toNextHopToOrigin);
1621  }
1622  SocketIpTtlTag tag;
1623  p->RemovePacketTag (tag);
1624  if (tag.GetTtl () < 2)
1625  {
1626  NS_LOG_DEBUG ("TTL exceeded. Drop RREP destination " << dst << " origin " << rrepHeader.GetOrigin ());
1627  return;
1628  }
1629 
1630  Ptr<Packet> packet = Create<Packet> ();
1631  SocketIpTtlTag ttl;
1632  ttl.SetTtl (tag.GetTtl () - 1);
1633  packet->AddPacketTag (ttl);
1634  packet->AddHeader (rrepHeader);
1635  TypeHeader tHeader (AODVTYPE_RREP);
1636  packet->AddHeader (tHeader);
1638  NS_ASSERT (socket);
1639  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1640 }
1641 
1642 void
1644 {
1645  NS_LOG_FUNCTION (this);
1646  RoutingTableEntry rt;
1647  if (m_routingTable.LookupRoute (neighbor, rt))
1648  {
1649  rt.m_ackTimer.Cancel ();
1650  rt.SetFlag (VALID);
1651  m_routingTable.Update (rt);
1652  }
1653 }
1654 
1655 void
1657 {
1658  NS_LOG_FUNCTION (this << "from " << rrepHeader.GetDst ());
1659  /*
1660  * Whenever a node receives a Hello message from a neighbor, the node
1661  * SHOULD make sure that it has an active route to the neighbor, and
1662  * create one if necessary.
1663  */
1664  RoutingTableEntry toNeighbor;
1665  if (!m_routingTable.LookupRoute (rrepHeader.GetDst (), toNeighbor))
1666  {
1667  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1668  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ rrepHeader.GetDst (), /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1669  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1670  /*hop=*/ 1, /*nextHop=*/ rrepHeader.GetDst (), /*lifeTime=*/ rrepHeader.GetLifeTime ());
1671  m_routingTable.AddRoute (newEntry);
1672  }
1673  else
1674  {
1675  toNeighbor.SetLifeTime (std::max (Time (m_allowedHelloLoss * m_helloInterval), toNeighbor.GetLifeTime ()));
1676  toNeighbor.SetSeqNo (rrepHeader.GetDstSeqno ());
1677  toNeighbor.SetValidSeqNo (true);
1678  toNeighbor.SetFlag (VALID);
1679  toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1680  toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1681  toNeighbor.SetHop (1);
1682  toNeighbor.SetNextHop (rrepHeader.GetDst ());
1683  m_routingTable.Update (toNeighbor);
1684  }
1685  if (m_enableHello)
1686  {
1688  }
1689 }
1690 
1691 void
1693 {
1694  NS_LOG_FUNCTION (this << " from " << src);
1695  RerrHeader rerrHeader;
1696  p->RemoveHeader (rerrHeader);
1697  std::map<Ipv4Address, uint32_t> dstWithNextHopSrc;
1698  std::map<Ipv4Address, uint32_t> unreachable;
1699  m_routingTable.GetListOfDestinationWithNextHop (src, dstWithNextHopSrc);
1700  std::pair<Ipv4Address, uint32_t> un;
1701  while (rerrHeader.RemoveUnDestination (un))
1702  {
1703  for (std::map<Ipv4Address, uint32_t>::const_iterator i =
1704  dstWithNextHopSrc.begin (); i != dstWithNextHopSrc.end (); ++i)
1705  {
1706  if (i->first == un.first)
1707  {
1708  unreachable.insert (un);
1709  }
1710  }
1711  }
1712 
1713  std::vector<Ipv4Address> precursors;
1714  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin ();
1715  i != unreachable.end (); )
1716  {
1717  if (!rerrHeader.AddUnDestination (i->first, i->second))
1718  {
1719  TypeHeader typeHeader (AODVTYPE_RERR);
1720  Ptr<Packet> packet = Create<Packet> ();
1721  SocketIpTtlTag tag;
1722  tag.SetTtl (1);
1723  packet->AddPacketTag (tag);
1724  packet->AddHeader (rerrHeader);
1725  packet->AddHeader (typeHeader);
1726  SendRerrMessage (packet, precursors);
1727  rerrHeader.Clear ();
1728  }
1729  else
1730  {
1731  RoutingTableEntry toDst;
1732  m_routingTable.LookupRoute (i->first, toDst);
1733  toDst.GetPrecursors (precursors);
1734  ++i;
1735  }
1736  }
1737  if (rerrHeader.GetDestCount () != 0)
1738  {
1739  TypeHeader typeHeader (AODVTYPE_RERR);
1740  Ptr<Packet> packet = Create<Packet> ();
1741  SocketIpTtlTag tag;
1742  tag.SetTtl (1);
1743  packet->AddPacketTag (tag);
1744  packet->AddHeader (rerrHeader);
1745  packet->AddHeader (typeHeader);
1746  SendRerrMessage (packet, precursors);
1747  }
1749 }
1750 
1751 void
1753 {
1754  NS_LOG_LOGIC (this);
1755  RoutingTableEntry toDst;
1756  if (m_routingTable.LookupValidRoute (dst, toDst))
1757  {
1758  SendPacketFromQueue (dst, toDst.GetRoute ());
1759  NS_LOG_LOGIC ("route to " << dst << " found");
1760  return;
1761  }
1762  /*
1763  * If a route discovery has been attempted RreqRetries times at the maximum TTL without
1764  * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
1765  * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the application.
1766  */
1767  if (toDst.GetRreqCnt () == m_rreqRetries)
1768  {
1769  NS_LOG_LOGIC ("route discovery to " << dst << " has been attempted RreqRetries (" << m_rreqRetries << ") times with ttl " << m_netDiameter);
1770  m_addressReqTimer.erase (dst);
1772  NS_LOG_DEBUG ("Route not found. Drop all packets with dst " << dst);
1773  m_queue.DropPacketWithDst (dst);
1774  return;
1775  }
1776 
1777  if (toDst.GetFlag () == IN_SEARCH)
1778  {
1779  NS_LOG_LOGIC ("Resend RREQ to " << dst << " previous ttl " << toDst.GetHop ());
1780  SendRequest (dst);
1781  }
1782  else
1783  {
1784  NS_LOG_DEBUG ("Route down. Stop search. Drop packet with destination " << dst);
1785  m_addressReqTimer.erase (dst);
1787  m_queue.DropPacketWithDst (dst);
1788  }
1789 }
1790 
1791 void
1793 {
1794  NS_LOG_FUNCTION (this);
1795  Time offset = Time (Seconds (0));
1796  if (m_lastBcastTime > Time (Seconds (0)))
1797  {
1798  offset = Simulator::Now () - m_lastBcastTime;
1799  NS_LOG_DEBUG ("Hello deferred due to last bcast at:" << m_lastBcastTime);
1800  }
1801  else
1802  {
1803  SendHello ();
1804  }
1805  m_htimer.Cancel ();
1806  Time diff = m_helloInterval - offset;
1807  m_htimer.Schedule (std::max (Time (Seconds (0)), diff));
1808  m_lastBcastTime = Time (Seconds (0));
1809 }
1810 
1811 void
1813 {
1814  NS_LOG_FUNCTION (this);
1815  m_rreqCount = 0;
1817 }
1818 
1819 void
1821 {
1822  NS_LOG_FUNCTION (this);
1823  m_rerrCount = 0;
1825 }
1826 
1827 void
1829 {
1830  NS_LOG_FUNCTION (this);
1831  m_routingTable.MarkLinkAsUnidirectional (neighbor, blacklistTimeout);
1832 }
1833 
1834 void
1836 {
1837  NS_LOG_FUNCTION (this);
1838  /* Broadcast a RREP with TTL = 1 with the RREP message fields set as follows:
1839  * Destination IP Address The node's IP address.
1840  * Destination Sequence Number The node's latest sequence number.
1841  * Hop Count 0
1842  * Lifetime AllowedHelloLoss * HelloInterval
1843  */
1844  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1845  {
1846  Ptr<Socket> socket = j->first;
1847  Ipv4InterfaceAddress iface = j->second;
1848  RrepHeader helloHeader (/*prefix size=*/ 0, /*hops=*/ 0, /*dst=*/ iface.GetLocal (), /*dst seqno=*/ m_seqNo,
1849  /*origin=*/ iface.GetLocal (),/*lifetime=*/ Time (m_allowedHelloLoss * m_helloInterval));
1850  Ptr<Packet> packet = Create<Packet> ();
1851  SocketIpTtlTag tag;
1852  tag.SetTtl (1);
1853  packet->AddPacketTag (tag);
1854  packet->AddHeader (helloHeader);
1855  TypeHeader tHeader (AODVTYPE_RREP);
1856  packet->AddHeader (tHeader);
1857  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1858  Ipv4Address destination;
1859  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1860  {
1861  destination = Ipv4Address ("255.255.255.255");
1862  }
1863  else
1864  {
1865  destination = iface.GetBroadcast ();
1866  }
1868  Simulator::Schedule (jitter, &RoutingProtocol::SendTo, this, socket, packet, destination);
1869  }
1870 }
1871 
1872 void
1874 {
1875  NS_LOG_FUNCTION (this);
1876  QueueEntry queueEntry;
1877  while (m_queue.Dequeue (dst, queueEntry))
1878  {
1880  Ptr<Packet> p = ConstCast<Packet> (queueEntry.GetPacket ());
1881  if (p->RemovePacketTag (tag)
1882  && tag.GetInterface () != -1
1883  && tag.GetInterface () != m_ipv4->GetInterfaceForDevice (route->GetOutputDevice ()))
1884  {
1885  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
1886  return;
1887  }
1889  Ipv4Header header = queueEntry.GetIpv4Header ();
1890  header.SetSource (route->GetSource ());
1891  header.SetTtl (header.GetTtl () + 1); // compensate extra TTL decrement by fake loopback routing
1892  ucb (route, p, header);
1893  }
1894 }
1895 
1896 void
1898 {
1899  NS_LOG_FUNCTION (this << nextHop);
1900  RerrHeader rerrHeader;
1901  std::vector<Ipv4Address> precursors;
1902  std::map<Ipv4Address, uint32_t> unreachable;
1903 
1904  RoutingTableEntry toNextHop;
1905  if (!m_routingTable.LookupRoute (nextHop, toNextHop))
1906  {
1907  return;
1908  }
1909  toNextHop.GetPrecursors (precursors);
1910  rerrHeader.AddUnDestination (nextHop, toNextHop.GetSeqNo ());
1911  m_routingTable.GetListOfDestinationWithNextHop (nextHop, unreachable);
1912  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin (); i
1913  != unreachable.end (); )
1914  {
1915  if (!rerrHeader.AddUnDestination (i->first, i->second))
1916  {
1917  NS_LOG_LOGIC ("Send RERR message with maximum size.");
1918  TypeHeader typeHeader (AODVTYPE_RERR);
1919  Ptr<Packet> packet = Create<Packet> ();
1920  SocketIpTtlTag tag;
1921  tag.SetTtl (1);
1922  packet->AddPacketTag (tag);
1923  packet->AddHeader (rerrHeader);
1924  packet->AddHeader (typeHeader);
1925  SendRerrMessage (packet, precursors);
1926  rerrHeader.Clear ();
1927  }
1928  else
1929  {
1930  RoutingTableEntry toDst;
1931  m_routingTable.LookupRoute (i->first, toDst);
1932  toDst.GetPrecursors (precursors);
1933  ++i;
1934  }
1935  }
1936  if (rerrHeader.GetDestCount () != 0)
1937  {
1938  TypeHeader typeHeader (AODVTYPE_RERR);
1939  Ptr<Packet> packet = Create<Packet> ();
1940  SocketIpTtlTag tag;
1941  tag.SetTtl (1);
1942  packet->AddPacketTag (tag);
1943  packet->AddHeader (rerrHeader);
1944  packet->AddHeader (typeHeader);
1945  SendRerrMessage (packet, precursors);
1946  }
1947  unreachable.insert (std::make_pair (nextHop, toNextHop.GetSeqNo ()));
1949 }
1950 
1951 void
1953  uint32_t dstSeqNo, Ipv4Address origin)
1954 {
1955  NS_LOG_FUNCTION (this);
1956  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
1958  {
1959  // Just make sure that the RerrRateLimit timer is running and will expire
1961  // discard the packet and return
1962  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().As (Time::S) << " with timer delay left "
1964  << "; suppressing RERR");
1965  return;
1966  }
1967  RerrHeader rerrHeader;
1968  rerrHeader.AddUnDestination (dst, dstSeqNo);
1969  RoutingTableEntry toOrigin;
1970  Ptr<Packet> packet = Create<Packet> ();
1971  SocketIpTtlTag tag;
1972  tag.SetTtl (1);
1973  packet->AddPacketTag (tag);
1974  packet->AddHeader (rerrHeader);
1975  packet->AddHeader (TypeHeader (AODVTYPE_RERR));
1976  if (m_routingTable.LookupValidRoute (origin, toOrigin))
1977  {
1979  toOrigin.GetInterface ());
1980  NS_ASSERT (socket);
1981  NS_LOG_LOGIC ("Unicast RERR to the source of the data transmission");
1982  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1983  }
1984  else
1985  {
1986  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
1987  m_socketAddresses.begin (); i != m_socketAddresses.end (); ++i)
1988  {
1989  Ptr<Socket> socket = i->first;
1990  Ipv4InterfaceAddress iface = i->second;
1991  NS_ASSERT (socket);
1992  NS_LOG_LOGIC ("Broadcast RERR message from interface " << iface.GetLocal ());
1993  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1994  Ipv4Address destination;
1995  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1996  {
1997  destination = Ipv4Address ("255.255.255.255");
1998  }
1999  else
2000  {
2001  destination = iface.GetBroadcast ();
2002  }
2003  socket->SendTo (packet->Copy (), 0, InetSocketAddress (destination, AODV_PORT));
2004  }
2005  }
2006 }
2007 
2008 void
2009 RoutingProtocol::SendRerrMessage (Ptr<Packet> packet, std::vector<Ipv4Address> precursors)
2010 {
2011  NS_LOG_FUNCTION (this);
2012 
2013  if (precursors.empty ())
2014  {
2015  NS_LOG_LOGIC ("No precursors");
2016  return;
2017  }
2018  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
2020  {
2021  // Just make sure that the RerrRateLimit timer is running and will expire
2023  // discard the packet and return
2024  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().As (Time::S) << " with timer delay left "
2026  << "; suppressing RERR");
2027  return;
2028  }
2029  // If there is only one precursor, RERR SHOULD be unicast toward that precursor
2030  if (precursors.size () == 1)
2031  {
2032  RoutingTableEntry toPrecursor;
2033  if (m_routingTable.LookupValidRoute (precursors.front (), toPrecursor))
2034  {
2035  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toPrecursor.GetInterface ());
2036  NS_ASSERT (socket);
2037  NS_LOG_LOGIC ("one precursor => unicast RERR to " << toPrecursor.GetDestination () << " from " << toPrecursor.GetInterface ().GetLocal ());
2038  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, precursors.front ());
2039  m_rerrCount++;
2040  }
2041  return;
2042  }
2043 
2044  // Should only transmit RERR on those interfaces which have precursor nodes for the broken route
2045  std::vector<Ipv4InterfaceAddress> ifaces;
2046  RoutingTableEntry toPrecursor;
2047  for (std::vector<Ipv4Address>::const_iterator i = precursors.begin (); i != precursors.end (); ++i)
2048  {
2049  if (m_routingTable.LookupValidRoute (*i, toPrecursor)
2050  && std::find (ifaces.begin (), ifaces.end (), toPrecursor.GetInterface ()) == ifaces.end ())
2051  {
2052  ifaces.push_back (toPrecursor.GetInterface ());
2053  }
2054  }
2055 
2056  for (std::vector<Ipv4InterfaceAddress>::const_iterator i = ifaces.begin (); i != ifaces.end (); ++i)
2057  {
2059  NS_ASSERT (socket);
2060  NS_LOG_LOGIC ("Broadcast RERR message from interface " << i->GetLocal ());
2061  // std::cout << "Broadcast RERR message from interface " << i->GetLocal () << std::endl;
2062  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
2063  Ptr<Packet> p = packet->Copy ();
2064  Ipv4Address destination;
2065  if (i->GetMask () == Ipv4Mask::GetOnes ())
2066  {
2067  destination = Ipv4Address ("255.255.255.255");
2068  }
2069  else
2070  {
2071  destination = i->GetBroadcast ();
2072  }
2073  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, p, destination);
2074  }
2075 }
2076 
2079 {
2080  NS_LOG_FUNCTION (this << addr);
2081  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
2082  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
2083  {
2084  Ptr<Socket> socket = j->first;
2085  Ipv4InterfaceAddress iface = j->second;
2086  if (iface == addr)
2087  {
2088  return socket;
2089  }
2090  }
2091  Ptr<Socket> socket;
2092  return socket;
2093 }
2094 
2097 {
2098  NS_LOG_FUNCTION (this << addr);
2099  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
2101  {
2102  Ptr<Socket> socket = j->first;
2103  Ipv4InterfaceAddress iface = j->second;
2104  if (iface == addr)
2105  {
2106  return socket;
2107  }
2108  }
2109  Ptr<Socket> socket;
2110  return socket;
2111 }
2112 
2113 void
2115 {
2116  NS_LOG_FUNCTION (this);
2117  uint32_t startTime;
2118  if (m_enableHello)
2119  {
2122  NS_LOG_DEBUG ("Starting at time " << startTime << "ms");
2124  }
2126 }
2127 
2128 } //namespace aodv
2129 } //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
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
static TypeId GetTypeId(void)
Get the type ID.
UnicastForwardCallback GetUnicastForwardCallback() const
Get unicast forward callback.
Definition: aodv-rqueue.h:85
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
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
uint64_t GetUid(void) const
Returns the packet&#39;s Uid.
Definition: packet.cc:390
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
bool MarkLinkAsUnidirectional(Ipv4Address neighbor, Time blacklistTimeout)
Mark entry as unidirectional (e.g.
Definition: aodv-rtable.cc:449
bool GetGratuitousReplyFlag() const
Get gratuitous reply flag.
an Inet address class
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.
AttributeValue implementation for Boolean.
Definition: boolean.h:36
uint8_t GetHopCount() const
Get the hop count.
Definition: aodv-packet.h:175
Callback template class.
Definition: callback.h:1278
bool m_enableBroadcast
Indicates whether a a broadcast data packets forwarding enable.
Time GetLifeTime() const
Get the lifetime.
Definition: aodv-packet.cc:385
bool LookupRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup routing table entry with destination address dst.
Definition: aodv-rtable.cc:214
int32_t GetInterface() const
Get the output interface.
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 destination scoket.
bool IsBroadcast(void) const
RoutingTable m_routingTable
Routing table.
uint32_t GetInteger(uint32_t min, uint32_t max)
Get the next random value, as an unsigned integer in the specified range .
A simple virtual Timer class.
Definition: timer.h:73
#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
uint32_t GetMaxQueueLen() const
Get the maximum queue length.
bool IsUnidirectional() const
Get the unidirectional flag.
Definition: aodv-rtable.h:308
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:269
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:85
Routing table entry.
Definition: aodv-rtable.h:59
Tag used by AODV implementation.
Ptr< Ipv4 > m_ipv4
IP protocol.
bool Update(RoutingTableEntry &rt)
Update routing table.
Definition: aodv-rtable.cc:277
Timer m_ackTimer
RREP_ACK timer.
Definition: aodv-rtable.h:329
Ipv4Address GetDestination() const
Get destination address function.
Definition: aodv-rtable.h:125
uint32_t m_maxQueueLen
The maximum number of packets that we allow a routing protocol to buffer.
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
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 GetBroadcastEnable() const
Get broadcast enable flag.
Time m_helloInterval
Every HelloInterval the node checks whether it has sent a broadcast within the last HelloInterval...
uint32_t GetDstSeqno() const
Get the destination sequence number.
Definition: aodv-packet.h:407
void SetMaxQueueLen(uint32_t len)
Set maximum queue length.
Definition: aodv-rqueue.h:238
Ipv4InterfaceAddress GetInterface() const
Get the Ipv4InterfaceAddress.
Definition: aodv-rtable.h:181
#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.
Time GetDelayLeft(void) const
Definition: timer.cc:87
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1286
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.
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...
Neighbors m_nb
Handle neighbors.
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:802
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
bool GetDestinationOnlyFlag() const
Get destination only flag.
void SetGratuitousReplyFlag(bool f)
Set gratuitous reply flag.
TAG_BUFFER_INLINE uint32_t ReadU32(void)
Definition: tag-buffer.h:215
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:389
Ptr< Socket > FindSubnetBroadcastSocketWithInterfaceAddress(Ipv4InterfaceAddress iface) const
Find subnet directed broadcast socket with local interface address iface.
Time m_nextHopWait
Period of our waiting for the neighbour&#39;s RREP_ACK.
uint8_t GetDestCount() const
Definition: aodv-packet.h:604
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:1115
STL namespace.
uint16_t m_rerrRateLimit
Maximum number of REER per second.
Route Request (RREQ) Message Format.
Definition: aodv-packet.h:131
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
Time m_lastBcastTime
Keep track of the last bcast time.
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
bool m_destinationOnly
Indicates only the destination may respond to this RREQ.
Wifi MAC high model for an ad-hoc Wifi MAC.
uint32_t m_rreqRetries
Maximum number of retransmissions of RREQ with TTL = NetDiameter to discover a route.
Ptr< Ipv4Route > GetRoute() const
Get route function.
Definition: aodv-rtable.h:133
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...
a polymophic address class
Definition: address.h:90
bool m_gratuitousReply
Indicates whether a gratuitous RREP should be unicast to the node originated route discovery...
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:272
void SetSource(Ipv4Address src)
Definition: ipv4-route.cc:49
uint32_t GetSeqNo() const
Get the sequence number.
Definition: aodv-rtable.h:221
void RecvAodv(Ptr< Socket > socket)
Receive and process control packet.
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
uint8_t GetHopCount() const
Get the hop count.
Definition: aodv-packet.h:375
void Clear()
Clear header.
Definition: aodv-packet.cc:645
void DelArpCache(Ptr< ArpCache > a)
Don&#39;t use given ARP cache any more (interface is down)
bool InsertPrecursor(Ipv4Address id)
Insert precursor in precursor list if it doesn&#39;t yet exist in the list.
Definition: aodv-rtable.cc:70
Packet header for IPv4.
Definition: ipv4-header.h:33
bool GetUnknownSeqno() const
Get the unknown sequence number flag.
Definition: aodv-packet.cc:281
bool IsMulticast(void) const
void SetRreqCnt(uint8_t n)
Set the RREQ count.
Definition: aodv-rtable.h:277
void RecvReplyAck(Ipv4Address neighbor)
Receive RREP_ACK.
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.
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:227
bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
Route an input packet (to be forwarded or locally delivered)
void RecvReply(Ptr< Packet > p, Ipv4Address my, Ipv4Address src)
Receive RREP.
#define max(a, b)
Definition: 80211b.c:43
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.
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:588
uint32_t m_allowedHelloLoss
Number of hello messages which may be loss for valid link.
void SetTtl(uint8_t ttl)
Set the tag&#39;s TTL.
Definition: socket.cc:604
AttributeValue implementation for Time.
Definition: nstime.h:1342
void Schedule(void)
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:158
bool GetValidSeqNo() const
Get the valid sequence number.
Definition: aodv-rtable.h:205
uint16_t GetDestinationPort(void) const
Definition: udp-header.cc:70
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:278
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 GetOrigin() const
Get the origin address.
Definition: aodv-packet.h:239
double startTime
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
Definition: tag-buffer.h:186
Callback< void, WifiMacHeader const & > GetTxErrorCallback() const
Get callback to ProcessTxError.
void SetArguments(Ts... args)
Definition: timer.h:293
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:109
AODV routing protocol.
Ipv4Address GetNextHop() const
Get next hop address.
Definition: aodv-rtable.h:157
mac
Definition: third.py:99
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.
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:290
Ipv4Address GetDestination(void) const
Definition: ipv4-route.cc:42
static TypeId GetTypeId(void)
Get the type ID.
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.
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 GetBroadcast(void) const
Get the broadcast address.
Ptr< Socket > FindSocketWithInterfaceAddress(Ipv4InterfaceAddress iface) const
Find unicast socket with local interface address iface.
Ipv4Mask GetMask(void) const
Get the network mask.
void SetDelay(const Time &delay)
Definition: timer.cc:75
void DropPacketWithDst(Ipv4Address dst)
Remove all packets with destination IP address dst.
Definition: aodv-rqueue.cc:72
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
uint16_t m_rerrCount
Number of RERRs used for RERR rate control.
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.
MessageType Get() const
Definition: aodv-packet.h:80
void SetInterface(Ipv4InterfaceAddress iface)
Set the Ipv4InterfaceAddress.
Definition: aodv-rtable.h:189
AODV Queue Entry.
Definition: aodv-rqueue.h:43
void SendRerrWhenNoRouteToForward(Ipv4Address dst, uint32_t dstSeqNo, Ipv4Address origin)
Send RERR message when no route to forward input packet.
This policy cancels the event from the destructor of the Timer or from Suspend(). ...
Definition: timer.h:93
bool GetDestinationOnly() const
Get the Destination only flag.
Definition: aodv-packet.cc:262
tag a set of bytes in a packet
Definition: tag.h:36
TypeId GetInstanceTypeId() const
Get the most derived TypeId for this Object.
void Clear()
Remove all entries.
void SendRerrWhenBreaksLinkToNextHop(Ipv4Address nextHop)
Initiate RERR.
Implement the IPv4 layer.
Ptr< NetDevice > GetOutputDevice(void) const
Definition: ipv4-route.cc:84
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
address
Definition: first.py:44
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.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
bool IsValid() const
Check that type if valid.
Definition: aodv-packet.h:88
Packet header for UDP packets.
Definition: udp-header.h:39
void Print(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print routing table.
Definition: aodv-rtable.cc:467
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.
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:1343
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:195
void SetOutputDevice(Ptr< NetDevice > outputDevice)
Equivalent in Linux to dst_entry.dev.
Definition: ipv4-route.cc:77
Ptr< NetDevice > GetOutputDevice() const
Get output device.
Definition: aodv-rtable.h:173
void ProcessHello(RrepHeader const &rrepHeader, Ipv4Address receiverIfaceAddr)
Process hello message.
static Ipv4Address GetLoopback(void)
virtual void NotifyInterfaceUp(uint32_t interface)
bool m_enableHello
Indicates whether a hello messages enable.
uint8_t GetRreqCnt() const
Get the RREQ count.
Definition: aodv-rtable.h:285
DuplicatePacketDetection m_dpd
Handle duplicated broadcast/multicast packets.
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:330
Ipv4Address GetGateway(void) const
Definition: ipv4-route.cc:70
Route Reply Acknowledgment (RREP-ACK) Message Format.
Definition: aodv-packet.h:503
uint32_t GetDstSeqno() const
Get the destination sequence number.
Definition: aodv-packet.h:223
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.
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:265
Time GetMaxQueueTime() const
Get maximum queue time.
bool IsRunning(void) const
Definition: timer.cc:127
Time m_myRouteTimeout
Value of lifetime field in RREP generating by this node.
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
double max(double x, double y)
wifi
Definition: third.py:96
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:41
read and write tag data
Definition: tag-buffer.h:51
virtual void NotifyInterfaceDown(uint32_t interface)
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
void SetGratuitousRrep(bool f)
Set the gratuitous RREP flag.
Definition: aodv-packet.cc:230
a class to store IPv4 address information on an interface
Ipv4Header GetIpv4Header() const
Get IPv4 header.
Definition: aodv-rqueue.h:133
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:956
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
void SetQueueTimeout(Time t)
Set queue timeout.
Definition: aodv-rqueue.h:254
Ipv4Address GetOrigin() const
Get the origin address.
Definition: aodv-packet.h:423
Ipv4Address GetDst() const
Get the destination address.
Definition: aodv-packet.h:207
bool AddRoute(RoutingTableEntry &r)
Add routing table entry if it doesn&#39;t yet exist in routing table.
Definition: aodv-rtable.cc:263
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:963
A network Node.
Definition: node.h:56
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:273
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1278
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
void Cancel(void)
Cancel the currently-running event if there is one.
Definition: timer.cc:109
AODVTYPE_RREP_ACK.
Definition: aodv-packet.h:50
Time m_blackListTimeout
Time for which the node is put into the blacklist.
void SendRerrMessage(Ptr< Packet > packet, std::vector< Ipv4Address > precursors)
Forward RERR.
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print the Routing Table entries.
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
uint16_t GetHop() const
Get the number of hops.
Definition: aodv-rtable.h:237
void SetIpRecvTtl(bool ipv4RecvTtl)
Tells a socket to pass information about IP_TTL up the stack.
Definition: socket.cc:526
void SetCallback(Callback< void, Ipv4Address > cb)
Set link failure callback.
void SetAckRequired(bool f)
Set the ack required flag.
Definition: aodv-packet.cc:392
uint32_t GetId() const
Get the request ID.
Definition: aodv-packet.h:191
void SendReply(RreqHeader const &rreqHeader, RoutingTableEntry const &toOrigin)
Send RREP.
Ipv4Address GetLocal(void) const
Get the local address.
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
Ptr< Ipv4Route > LoopbackRoute(const Ipv4Header &header, Ptr< NetDevice > oif) const
Create loopback route for given header.
Timer m_rerrRateLimitTimer
RERR rate limit timer.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:472
RouteFlags GetFlag() const
Get the route flags.
Definition: aodv-rtable.h:269
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.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1294
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:257
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
second
Definition: nstime.h:115
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:90
void RerrRateLimitTimerExpire()
Reset RERR count and schedule RERR rate limit timer with delay 1 sec.
Time GetLifeTime() const
Get the lifetime.
Definition: aodv-rtable.h:253
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.
bool GetGratuitousRrep() const
Get the gratuitous RREP flag.
Definition: aodv-packet.cc:243
DeferredRouteOutputTag(int32_t o=-1)
Constructor.
Ipv4Address GetDst() const
Get the destination address.
Definition: aodv-packet.h:391
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:978
IdCache m_rreqIdCache
Handle duplicated RREQ.
void RouteRequestTimerExpire(Ipv4Address dst)
Handle route discovery process.
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.
Ipv4Address GetSource(void) const
Definition: ipv4-route.cc:56
virtual int Close(void)=0
Close a socket.
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
bool LookupValidRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup route in VALID state.
Definition: aodv-rtable.cc:236
void Print(std::ostream &os) const
static TypeId GetTypeId()
Get the type ID.
void SetBroadcastEnable(bool f)
Set broadcast enable flag.
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
bool GetAckRequired() const
get the ack required flag
Definition: aodv-packet.cc:405
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.
uint32_t m_requestId
Broadcast ID.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
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.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
static Time GetMaximumSimulationTime(void)
Get the maximum representable simulation time.
Definition: simulator.cc:293
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
Ptr< const Packet > GetPacket() const
Get packet from entry.
Definition: aodv-rqueue.h:117
void SetUnknownSeqno(bool f)
Set the unknown sequence number flag.
Definition: aodv-packet.cc:268
virtual Address GetAddress(void) const =0
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
uint8_t GetTtl(void) const
Get the tag&#39;s TTL.
Definition: socket.cc:611
void SetDestination(Ipv4Address dest)
Definition: ipv4-route.cc:35
void ScheduleTimer()
Schedule m_ntimer.
Ipv4Address GetIpv4(void) const
uint32_t GetOriginSeqno() const
Get the origin sequence number.
Definition: aodv-packet.h:255
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