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