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 (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::iterator iter = m_socketAddresses.begin();
366  iter != m_socketAddresses.end();
367  iter++)
368  {
369  iter->first->Close();
370  }
371  m_socketAddresses.clear();
372  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::iterator iter =
374  iter != m_socketSubnetBroadcastAddresses.end();
375  iter++)
376  {
377  iter->first->Close();
378  }
381 }
382 
383 void
385 {
386  *stream->GetStream() << "Node: " << m_ipv4->GetObject<Node>()->GetId()
387  << "; Time: " << Now().As(unit)
388  << ", Local time: " << m_ipv4->GetObject<Node>()->GetLocalTime().As(unit)
389  << ", AODV Routing table" << std::endl;
390 
391  m_routingTable.Print(stream, unit);
392  *stream->GetStream() << std::endl;
393 }
394 
395 int64_t
397 {
398  NS_LOG_FUNCTION(this << stream);
400  return 1;
401 }
402 
403 void
405 {
406  NS_LOG_FUNCTION(this);
407  if (m_enableHello)
408  {
410  }
413 
416 }
417 
420  const Ipv4Header& header,
421  Ptr<NetDevice> oif,
422  Socket::SocketErrno& sockerr)
423 {
424  NS_LOG_FUNCTION(this << header << (oif ? oif->GetIfIndex() : 0));
425  if (!p)
426  {
427  NS_LOG_DEBUG("Packet is == 0");
428  return LoopbackRoute(header, oif); // later
429  }
430  if (m_socketAddresses.empty())
431  {
432  sockerr = Socket::ERROR_NOROUTETOHOST;
433  NS_LOG_LOGIC("No aodv interfaces");
434  Ptr<Ipv4Route> route;
435  return route;
436  }
437  sockerr = Socket::ERROR_NOTERROR;
438  Ptr<Ipv4Route> route;
439  Ipv4Address dst = header.GetDestination();
441  if (m_routingTable.LookupValidRoute(dst, rt))
442  {
443  route = rt.GetRoute();
444  NS_ASSERT(route);
445  NS_LOG_DEBUG("Exist route to " << route->GetDestination() << " from interface "
446  << route->GetSource());
447  if (oif && route->GetOutputDevice() != oif)
448  {
449  NS_LOG_DEBUG("Output device doesn't match. Dropped.");
450  sockerr = Socket::ERROR_NOROUTETOHOST;
451  return Ptr<Ipv4Route>();
452  }
454  UpdateRouteLifeTime(route->GetGateway(), m_activeRouteTimeout);
455  return route;
456  }
457 
458  // Valid route not found, in this case we return loopback.
459  // Actual route request will be deferred until packet will be fully formed,
460  // routed to loopback, received from loopback and passed to RouteInput (see below)
461  uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice(oif) : -1);
462  DeferredRouteOutputTag tag(iif);
463  NS_LOG_DEBUG("Valid Route not found");
464  if (!p->PeekPacketTag(tag))
465  {
466  p->AddPacketTag(tag);
467  }
468  return LoopbackRoute(header, oif);
469 }
470 
471 void
473  const Ipv4Header& header,
475  ErrorCallback ecb)
476 {
477  NS_LOG_FUNCTION(this << p << header);
478  NS_ASSERT(p && p != Ptr<Packet>());
479 
480  QueueEntry newEntry(p, header, ucb, ecb);
481  bool result = m_queue.Enqueue(newEntry);
482  if (result)
483  {
484  NS_LOG_LOGIC("Add packet " << p->GetUid() << " to queue. Protocol "
485  << (uint16_t)header.GetProtocol());
487  bool result = m_routingTable.LookupRoute(header.GetDestination(), rt);
488  if (!result || ((rt.GetFlag() != IN_SEARCH) && result))
489  {
490  NS_LOG_LOGIC("Send new RREQ for outbound packet to " << header.GetDestination());
491  SendRequest(header.GetDestination());
492  }
493  }
494 }
495 
496 bool
498  const Ipv4Header& header,
503  ErrorCallback ecb)
504 {
505  NS_LOG_FUNCTION(this << p->GetUid() << header.GetDestination() << idev->GetAddress());
506  if (m_socketAddresses.empty())
507  {
508  NS_LOG_LOGIC("No aodv interfaces");
509  return false;
510  }
511  NS_ASSERT(m_ipv4);
512  NS_ASSERT(p);
513  // Check if input device supports IP
514  NS_ASSERT(m_ipv4->GetInterfaceForDevice(idev) >= 0);
515  int32_t iif = m_ipv4->GetInterfaceForDevice(idev);
516 
517  Ipv4Address dst = header.GetDestination();
518  Ipv4Address origin = header.GetSource();
519 
520  // Deferred route request
521  if (idev == m_lo)
522  {
524  if (p->PeekPacketTag(tag))
525  {
526  DeferredRouteOutput(p, header, ucb, ecb);
527  return true;
528  }
529  }
530 
531  // Duplicate of own packet
532  if (IsMyOwnAddress(origin))
533  {
534  return true;
535  }
536 
537  // AODV is not a multicast routing protocol
538  if (dst.IsMulticast())
539  {
540  return false;
541  }
542 
543  // Broadcast local delivery/forwarding
544  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin();
545  j != m_socketAddresses.end();
546  ++j)
547  {
548  Ipv4InterfaceAddress iface = j->second;
549  if (m_ipv4->GetInterfaceForAddress(iface.GetLocal()) == iif)
550  {
551  if (dst == iface.GetBroadcast() || dst.IsBroadcast())
552  {
553  if (m_dpd.IsDuplicate(p, header))
554  {
555  NS_LOG_DEBUG("Duplicated packet " << p->GetUid() << " from " << origin
556  << ". Drop.");
557  return true;
558  }
560  Ptr<Packet> packet = p->Copy();
561  if (lcb.IsNull() == false)
562  {
563  NS_LOG_LOGIC("Broadcast local delivery to " << iface.GetLocal());
564  lcb(p, header, iif);
565  // Fall through to additional processing
566  }
567  else
568  {
569  NS_LOG_ERROR("Unable to deliver packet locally due to null callback "
570  << p->GetUid() << " from " << origin);
571  ecb(p, header, Socket::ERROR_NOROUTETOHOST);
572  }
573  if (!m_enableBroadcast)
574  {
575  return true;
576  }
577  if (header.GetProtocol() == UdpL4Protocol::PROT_NUMBER)
578  {
579  UdpHeader udpHeader;
580  p->PeekHeader(udpHeader);
581  if (udpHeader.GetDestinationPort() == AODV_PORT)
582  {
583  // AODV packets sent in broadcast are already managed
584  return true;
585  }
586  }
587  if (header.GetTtl() > 1)
588  {
589  NS_LOG_LOGIC("Forward broadcast. TTL " << (uint16_t)header.GetTtl());
590  RoutingTableEntry toBroadcast;
591  if (m_routingTable.LookupRoute(dst, toBroadcast))
592  {
593  Ptr<Ipv4Route> route = toBroadcast.GetRoute();
594  ucb(route, packet, header);
595  }
596  else
597  {
598  NS_LOG_DEBUG("No route to forward broadcast. Drop packet " << p->GetUid());
599  }
600  }
601  else
602  {
603  NS_LOG_DEBUG("TTL exceeded. Drop packet " << p->GetUid());
604  }
605  return true;
606  }
607  }
608  }
609 
610  // Unicast local delivery
611  if (m_ipv4->IsDestinationAddress(dst, iif))
612  {
614  RoutingTableEntry toOrigin;
615  if (m_routingTable.LookupValidRoute(origin, toOrigin))
616  {
619  }
620  if (lcb.IsNull() == false)
621  {
622  NS_LOG_LOGIC("Unicast local delivery to " << dst);
623  lcb(p, header, iif);
624  }
625  else
626  {
627  NS_LOG_ERROR("Unable to deliver packet locally due to null callback "
628  << p->GetUid() << " from " << origin);
629  ecb(p, header, Socket::ERROR_NOROUTETOHOST);
630  }
631  return true;
632  }
633 
634  // Check if input device supports IP forwarding
635  if (m_ipv4->IsForwarding(iif) == false)
636  {
637  NS_LOG_LOGIC("Forwarding disabled for this interface");
638  ecb(p, header, Socket::ERROR_NOROUTETOHOST);
639  return true;
640  }
641 
642  // Forwarding
643  return Forwarding(p, header, ucb, ecb);
644 }
645 
646 bool
648  const Ipv4Header& header,
650  ErrorCallback ecb)
651 {
652  NS_LOG_FUNCTION(this);
653  Ipv4Address dst = header.GetDestination();
654  Ipv4Address origin = header.GetSource();
656  RoutingTableEntry toDst;
657  if (m_routingTable.LookupRoute(dst, toDst))
658  {
659  if (toDst.GetFlag() == VALID)
660  {
661  Ptr<Ipv4Route> route = toDst.GetRoute();
662  NS_LOG_LOGIC(route->GetSource() << " forwarding to " << dst << " from " << origin
663  << " packet " << p->GetUid());
664 
665  /*
666  * Each time a route is used to forward a data packet, its Active Route
667  * Lifetime field of the source, destination and the next hop on the
668  * path to the destination is updated to be no less than the current
669  * time plus ActiveRouteTimeout.
670  */
673  UpdateRouteLifeTime(route->GetGateway(), m_activeRouteTimeout);
674  /*
675  * Since the route between each originator and destination pair is expected to be
676  * symmetric, the Active Route Lifetime for the previous hop, along the reverse path
677  * back to the IP source, is also updated to be no less than the current time plus
678  * ActiveRouteTimeout
679  */
680  RoutingTableEntry toOrigin;
681  m_routingTable.LookupRoute(origin, toOrigin);
683 
684  m_nb.Update(route->GetGateway(), m_activeRouteTimeout);
686 
687  ucb(route, p, header);
688  return true;
689  }
690  else
691  {
692  if (toDst.GetValidSeqNo())
693  {
694  SendRerrWhenNoRouteToForward(dst, toDst.GetSeqNo(), origin);
695  NS_LOG_DEBUG("Drop packet " << p->GetUid() << " because no route to forward it.");
696  return false;
697  }
698  }
699  }
700  NS_LOG_LOGIC("route not found to " << dst << ". Send RERR message.");
701  NS_LOG_DEBUG("Drop packet " << p->GetUid() << " because no route to forward it.");
702  SendRerrWhenNoRouteToForward(dst, 0, origin);
703  return false;
704 }
705 
706 void
708 {
709  NS_ASSERT(ipv4);
710  NS_ASSERT(!m_ipv4);
711 
712  m_ipv4 = ipv4;
713 
714  // Create lo route. It is asserted that the only one interface up for now is loopback
715  NS_ASSERT(m_ipv4->GetNInterfaces() == 1 &&
716  m_ipv4->GetAddress(0, 0).GetLocal() == Ipv4Address("127.0.0.1"));
717  m_lo = m_ipv4->GetNetDevice(0);
718  NS_ASSERT(m_lo);
719  // Remember lo route
721  /*dev=*/m_lo,
722  /*dst=*/Ipv4Address::GetLoopback(),
723  /*vSeqNo=*/true,
724  /*seqNo=*/0,
725  /*iface=*/Ipv4InterfaceAddress(Ipv4Address::GetLoopback(), Ipv4Mask("255.0.0.0")),
726  /*hops=*/1,
727  /*nextHop=*/Ipv4Address::GetLoopback(),
728  /*lifetime=*/Simulator::GetMaximumSimulationTime());
730 
732 }
733 
734 void
736 {
737  NS_LOG_FUNCTION(this << m_ipv4->GetAddress(i, 0).GetLocal());
738  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol>();
739  if (l3->GetNAddresses(i) > 1)
740  {
741  NS_LOG_WARN("AODV does not work with more then one address per each interface.");
742  }
743  Ipv4InterfaceAddress iface = l3->GetAddress(i, 0);
744  if (iface.GetLocal() == Ipv4Address("127.0.0.1"))
745  {
746  return;
747  }
748 
749  // Create a socket to listen only on this interface
750  Ptr<Socket> socket = Socket::CreateSocket(GetObject<Node>(), UdpSocketFactory::GetTypeId());
751  NS_ASSERT(socket);
753  socket->BindToNetDevice(l3->GetNetDevice(i));
754  socket->Bind(InetSocketAddress(iface.GetLocal(), AODV_PORT));
755  socket->SetAllowBroadcast(true);
756  socket->SetIpRecvTtl(true);
757  m_socketAddresses.insert(std::make_pair(socket, iface));
758 
759  // create also a subnet broadcast socket
760  socket = Socket::CreateSocket(GetObject<Node>(), UdpSocketFactory::GetTypeId());
761  NS_ASSERT(socket);
763  socket->BindToNetDevice(l3->GetNetDevice(i));
764  socket->Bind(InetSocketAddress(iface.GetBroadcast(), AODV_PORT));
765  socket->SetAllowBroadcast(true);
766  socket->SetIpRecvTtl(true);
767  m_socketSubnetBroadcastAddresses.insert(std::make_pair(socket, iface));
768 
769  // Add local broadcast record to the routing table
770  Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(iface.GetLocal()));
771  RoutingTableEntry rt(/*dev=*/dev,
772  /*dst=*/iface.GetBroadcast(),
773  /*vSeqNo=*/true,
774  /*seqNo=*/0,
775  /*iface=*/iface,
776  /*hops=*/1,
777  /*nextHop=*/iface.GetBroadcast(),
778  /*lifetime=*/Simulator::GetMaximumSimulationTime());
780 
781  if (l3->GetInterface(i)->GetArpCache())
782  {
783  m_nb.AddArpCache(l3->GetInterface(i)->GetArpCache());
784  }
785 
786  // Allow neighbor manager use this interface for layer 2 feedback if possible
787  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice>();
788  if (!wifi)
789  {
790  return;
791  }
792  Ptr<WifiMac> mac = wifi->GetMac();
793  if (!mac)
794  {
795  return;
796  }
797 
798  mac->TraceConnectWithoutContext("DroppedMpdu",
800 }
801 
802 void
804 {
805  m_nb.GetTxErrorCallback()(mpdu->GetHeader());
806 }
807 
808 void
810 {
811  NS_LOG_FUNCTION(this << m_ipv4->GetAddress(i, 0).GetLocal());
812 
813  // Disable layer 2 link state monitoring (if possible)
814  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol>();
815  Ptr<NetDevice> dev = l3->GetNetDevice(i);
816  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice>();
817  if (wifi)
818  {
819  Ptr<WifiMac> mac = wifi->GetMac()->GetObject<AdhocWifiMac>();
820  if (mac)
821  {
822  mac->TraceDisconnectWithoutContext("DroppedMpdu",
824  m_nb.DelArpCache(l3->GetInterface(i)->GetArpCache());
825  }
826  }
827 
828  // Close socket
829  Ptr<Socket> socket = FindSocketWithInterfaceAddress(m_ipv4->GetAddress(i, 0));
830  NS_ASSERT(socket);
831  socket->Close();
832  m_socketAddresses.erase(socket);
833 
834  // Close socket
835  socket = FindSubnetBroadcastSocketWithInterfaceAddress(m_ipv4->GetAddress(i, 0));
836  NS_ASSERT(socket);
837  socket->Close();
838  m_socketSubnetBroadcastAddresses.erase(socket);
839 
840  if (m_socketAddresses.empty())
841  {
842  NS_LOG_LOGIC("No aodv interfaces");
843  m_htimer.Cancel();
844  m_nb.Clear();
846  return;
847  }
849 }
850 
851 void
853 {
854  NS_LOG_FUNCTION(this << " interface " << i << " address " << address);
855  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol>();
856  if (!l3->IsUp(i))
857  {
858  return;
859  }
860  if (l3->GetNAddresses(i) == 1)
861  {
862  Ipv4InterfaceAddress iface = l3->GetAddress(i, 0);
864  if (!socket)
865  {
866  if (iface.GetLocal() == Ipv4Address("127.0.0.1"))
867  {
868  return;
869  }
870  // Create a socket to listen only on this interface
871  Ptr<Socket> socket =
873  NS_ASSERT(socket);
875  socket->BindToNetDevice(l3->GetNetDevice(i));
876  socket->Bind(InetSocketAddress(iface.GetLocal(), AODV_PORT));
877  socket->SetAllowBroadcast(true);
878  m_socketAddresses.insert(std::make_pair(socket, iface));
879 
880  // create also a subnet directed broadcast socket
881  socket = Socket::CreateSocket(GetObject<Node>(), UdpSocketFactory::GetTypeId());
882  NS_ASSERT(socket);
884  socket->BindToNetDevice(l3->GetNetDevice(i));
885  socket->Bind(InetSocketAddress(iface.GetBroadcast(), AODV_PORT));
886  socket->SetAllowBroadcast(true);
887  socket->SetIpRecvTtl(true);
888  m_socketSubnetBroadcastAddresses.insert(std::make_pair(socket, iface));
889 
890  // Add local broadcast record to the routing table
891  Ptr<NetDevice> dev =
892  m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(iface.GetLocal()));
893  RoutingTableEntry rt(/*dev=*/dev,
894  /*dst=*/iface.GetBroadcast(),
895  /*vSeqNo=*/true,
896  /*seqNo=*/0,
897  /*iface=*/iface,
898  /*hops=*/1,
899  /*nextHop=*/iface.GetBroadcast(),
900  /*lifetime=*/Simulator::GetMaximumSimulationTime());
902  }
903  }
904  else
905  {
906  NS_LOG_LOGIC("AODV does not work with more then one address per each interface. Ignore "
907  "added address");
908  }
909 }
910 
911 void
913 {
914  NS_LOG_FUNCTION(this);
916  if (socket)
917  {
919  socket->Close();
920  m_socketAddresses.erase(socket);
921 
923  if (unicastSocket)
924  {
925  unicastSocket->Close();
926  m_socketAddresses.erase(unicastSocket);
927  }
928 
929  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol>();
930  if (l3->GetNAddresses(i))
931  {
932  Ipv4InterfaceAddress iface = l3->GetAddress(i, 0);
933  // Create a socket to listen only on this interface
934  Ptr<Socket> socket =
936  NS_ASSERT(socket);
938  // Bind to any IP address so that broadcasts can be received
939  socket->BindToNetDevice(l3->GetNetDevice(i));
940  socket->Bind(InetSocketAddress(iface.GetLocal(), AODV_PORT));
941  socket->SetAllowBroadcast(true);
942  socket->SetIpRecvTtl(true);
943  m_socketAddresses.insert(std::make_pair(socket, iface));
944 
945  // create also a unicast socket
946  socket = Socket::CreateSocket(GetObject<Node>(), UdpSocketFactory::GetTypeId());
947  NS_ASSERT(socket);
949  socket->BindToNetDevice(l3->GetNetDevice(i));
950  socket->Bind(InetSocketAddress(iface.GetBroadcast(), AODV_PORT));
951  socket->SetAllowBroadcast(true);
952  socket->SetIpRecvTtl(true);
953  m_socketSubnetBroadcastAddresses.insert(std::make_pair(socket, iface));
954 
955  // Add local broadcast record to the routing table
956  Ptr<NetDevice> dev =
957  m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(iface.GetLocal()));
958  RoutingTableEntry rt(/*dev=*/dev,
959  /*dst=*/iface.GetBroadcast(),
960  /*vSeqNo=*/true,
961  /*seqNo=*/0,
962  /*iface=*/iface,
963  /*hops=*/1,
964  /*nextHop=*/iface.GetBroadcast(),
965  /*lifetime=*/Simulator::GetMaximumSimulationTime());
967  }
968  if (m_socketAddresses.empty())
969  {
970  NS_LOG_LOGIC("No aodv interfaces");
971  m_htimer.Cancel();
972  m_nb.Clear();
974  return;
975  }
976  }
977  else
978  {
979  NS_LOG_LOGIC("Remove address not participating in AODV operation");
980  }
981 }
982 
983 bool
985 {
986  NS_LOG_FUNCTION(this << src);
987  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin();
988  j != m_socketAddresses.end();
989  ++j)
990  {
991  Ipv4InterfaceAddress iface = j->second;
992  if (src == iface.GetLocal())
993  {
994  return true;
995  }
996  }
997  return false;
998 }
999 
1002 {
1003  NS_LOG_FUNCTION(this << hdr);
1004  NS_ASSERT(m_lo);
1005  Ptr<Ipv4Route> rt = Create<Ipv4Route>();
1006  rt->SetDestination(hdr.GetDestination());
1007  //
1008  // Source address selection here is tricky. The loopback route is
1009  // returned when AODV does not have a route; this causes the packet
1010  // to be looped back and handled (cached) in RouteInput() method
1011  // while a route is found. However, connection-oriented protocols
1012  // like TCP need to create an endpoint four-tuple (src, src port,
1013  // dst, dst port) and create a pseudo-header for checksumming. So,
1014  // AODV needs to guess correctly what the eventual source address
1015  // will be.
1016  //
1017  // For single interface, single address nodes, this is not a problem.
1018  // When there are possibly multiple outgoing interfaces, the policy
1019  // implemented here is to pick the first available AODV interface.
1020  // If RouteOutput() caller specified an outgoing interface, that
1021  // further constrains the selection of source address
1022  //
1023  std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin();
1024  if (oif)
1025  {
1026  // Iterate to find an address on the oif device
1027  for (j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
1028  {
1029  Ipv4Address addr = j->second.GetLocal();
1030  int32_t interface = m_ipv4->GetInterfaceForAddress(addr);
1031  if (oif == m_ipv4->GetNetDevice(static_cast<uint32_t>(interface)))
1032  {
1033  rt->SetSource(addr);
1034  break;
1035  }
1036  }
1037  }
1038  else
1039  {
1040  rt->SetSource(j->second.GetLocal());
1041  }
1042  NS_ASSERT_MSG(rt->GetSource() != Ipv4Address(), "Valid AODV source address not found");
1043  rt->SetGateway(Ipv4Address("127.0.0.1"));
1044  rt->SetOutputDevice(m_lo);
1045  return rt;
1046 }
1047 
1048 void
1050 {
1051  NS_LOG_FUNCTION(this << dst);
1052  // A node SHOULD NOT originate more than RREQ_RATELIMIT RREQ messages per second.
1054  {
1057  this,
1058  dst);
1059  return;
1060  }
1061  else
1062  {
1063  m_rreqCount++;
1064  }
1065  // Create RREQ header
1066  RreqHeader rreqHeader;
1067  rreqHeader.SetDst(dst);
1068 
1069  RoutingTableEntry rt;
1070  // Using the Hop field in Routing Table to manage the expanding ring search
1071  uint16_t ttl = m_ttlStart;
1072  if (m_routingTable.LookupRoute(dst, rt))
1073  {
1074  if (rt.GetFlag() != IN_SEARCH)
1075  {
1076  ttl = std::min<uint16_t>(rt.GetHop() + m_ttlIncrement, m_netDiameter);
1077  }
1078  else
1079  {
1080  ttl = rt.GetHop() + m_ttlIncrement;
1081  if (ttl > m_ttlThreshold)
1082  {
1083  ttl = m_netDiameter;
1084  }
1085  }
1086  if (ttl == m_netDiameter)
1087  {
1088  rt.IncrementRreqCnt();
1089  }
1090  if (rt.GetValidSeqNo())
1091  {
1092  rreqHeader.SetDstSeqno(rt.GetSeqNo());
1093  }
1094  else
1095  {
1096  rreqHeader.SetUnknownSeqno(true);
1097  }
1098  rt.SetHop(ttl);
1099  rt.SetFlag(IN_SEARCH);
1101  m_routingTable.Update(rt);
1102  }
1103  else
1104  {
1105  rreqHeader.SetUnknownSeqno(true);
1106  Ptr<NetDevice> dev = nullptr;
1107  RoutingTableEntry newEntry(/*dev=*/dev,
1108  /*dst=*/dst,
1109  /*vSeqNo=*/false,
1110  /*seqNo=*/0,
1111  /*iface=*/Ipv4InterfaceAddress(),
1112  /*hops=*/ttl,
1113  /*nextHop=*/Ipv4Address(),
1114  /*lifetime=*/m_pathDiscoveryTime);
1115  // Check if TtlStart == NetDiameter
1116  if (ttl == m_netDiameter)
1117  {
1118  newEntry.IncrementRreqCnt();
1119  }
1120  newEntry.SetFlag(IN_SEARCH);
1121  m_routingTable.AddRoute(newEntry);
1122  }
1123 
1124  if (m_gratuitousReply)
1125  {
1126  rreqHeader.SetGratuitousRrep(true);
1127  }
1128  if (m_destinationOnly)
1129  {
1130  rreqHeader.SetDestinationOnly(true);
1131  }
1132 
1133  m_seqNo++;
1134  rreqHeader.SetOriginSeqno(m_seqNo);
1135  m_requestId++;
1136  rreqHeader.SetId(m_requestId);
1137 
1138  // Send RREQ as subnet directed broadcast from each interface used by aodv
1139  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin();
1140  j != m_socketAddresses.end();
1141  ++j)
1142  {
1143  Ptr<Socket> socket = j->first;
1144  Ipv4InterfaceAddress iface = j->second;
1145 
1146  rreqHeader.SetOrigin(iface.GetLocal());
1148 
1149  Ptr<Packet> packet = Create<Packet>();
1150  SocketIpTtlTag tag;
1151  tag.SetTtl(ttl);
1152  packet->AddPacketTag(tag);
1153  packet->AddHeader(rreqHeader);
1154  TypeHeader tHeader(AODVTYPE_RREQ);
1155  packet->AddHeader(tHeader);
1156  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1157  Ipv4Address destination;
1158  if (iface.GetMask() == Ipv4Mask::GetOnes())
1159  {
1160  destination = Ipv4Address("255.255.255.255");
1161  }
1162  else
1163  {
1164  destination = iface.GetBroadcast();
1165  }
1166  NS_LOG_DEBUG("Send RREQ with id " << rreqHeader.GetId() << " to socket");
1170  this,
1171  socket,
1172  packet,
1173  destination);
1174  }
1175  ScheduleRreqRetry(dst);
1176 }
1177 
1178 void
1180 {
1181  socket->SendTo(packet, 0, InetSocketAddress(destination, AODV_PORT));
1182 }
1183 
1184 void
1186 {
1187  NS_LOG_FUNCTION(this << dst);
1188  if (m_addressReqTimer.find(dst) == m_addressReqTimer.end())
1189  {
1191  m_addressReqTimer[dst] = timer;
1192  }
1194  m_addressReqTimer[dst].Cancel();
1195  m_addressReqTimer[dst].SetArguments(dst);
1196  RoutingTableEntry rt;
1197  m_routingTable.LookupRoute(dst, rt);
1198  Time retry;
1199  if (rt.GetHop() < m_netDiameter)
1200  {
1201  retry = 2 * m_nodeTraversalTime * (rt.GetHop() + m_timeoutBuffer);
1202  }
1203  else
1204  {
1205  NS_ABORT_MSG_UNLESS(rt.GetRreqCnt() > 0, "Unexpected value for GetRreqCount ()");
1206  uint16_t backoffFactor = rt.GetRreqCnt() - 1;
1207  NS_LOG_LOGIC("Applying binary exponential backoff factor " << backoffFactor);
1208  retry = m_netTraversalTime * (1 << backoffFactor);
1209  }
1210  m_addressReqTimer[dst].Schedule(retry);
1211  NS_LOG_LOGIC("Scheduled RREQ retry in " << retry.As(Time::S));
1212 }
1213 
1214 void
1216 {
1217  NS_LOG_FUNCTION(this << socket);
1218  Address sourceAddress;
1219  Ptr<Packet> packet = socket->RecvFrom(sourceAddress);
1220  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom(sourceAddress);
1221  Ipv4Address sender = inetSourceAddr.GetIpv4();
1222  Ipv4Address receiver;
1223 
1224  if (m_socketAddresses.find(socket) != m_socketAddresses.end())
1225  {
1226  receiver = m_socketAddresses[socket].GetLocal();
1227  }
1228  else if (m_socketSubnetBroadcastAddresses.find(socket) !=
1230  {
1231  receiver = m_socketSubnetBroadcastAddresses[socket].GetLocal();
1232  }
1233  else
1234  {
1235  NS_ASSERT_MSG(false, "Received a packet from an unknown socket");
1236  }
1237  NS_LOG_DEBUG("AODV node " << this << " received a AODV packet from " << sender << " to "
1238  << receiver);
1239 
1240  UpdateRouteToNeighbor(sender, receiver);
1241  TypeHeader tHeader(AODVTYPE_RREQ);
1242  packet->RemoveHeader(tHeader);
1243  if (!tHeader.IsValid())
1244  {
1245  NS_LOG_DEBUG("AODV message " << packet->GetUid() << " with unknown type received: "
1246  << tHeader.Get() << ". Drop");
1247  return; // drop
1248  }
1249  switch (tHeader.Get())
1250  {
1251  case AODVTYPE_RREQ: {
1252  RecvRequest(packet, receiver, sender);
1253  break;
1254  }
1255  case AODVTYPE_RREP: {
1256  RecvReply(packet, receiver, sender);
1257  break;
1258  }
1259  case AODVTYPE_RERR: {
1260  RecvError(packet, sender);
1261  break;
1262  }
1263  case AODVTYPE_RREP_ACK: {
1264  RecvReplyAck(sender);
1265  break;
1266  }
1267  }
1268 }
1269 
1270 bool
1272 {
1273  NS_LOG_FUNCTION(this << addr << lifetime);
1274  RoutingTableEntry rt;
1275  if (m_routingTable.LookupRoute(addr, rt))
1276  {
1277  if (rt.GetFlag() == VALID)
1278  {
1279  NS_LOG_DEBUG("Updating VALID route");
1280  rt.SetRreqCnt(0);
1281  rt.SetLifeTime(std::max(lifetime, rt.GetLifeTime()));
1282  m_routingTable.Update(rt);
1283  return true;
1284  }
1285  }
1286  return false;
1287 }
1288 
1289 void
1291 {
1292  NS_LOG_FUNCTION(this << "sender " << sender << " receiver " << receiver);
1293  RoutingTableEntry toNeighbor;
1294  if (!m_routingTable.LookupRoute(sender, toNeighbor))
1295  {
1296  Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver));
1297  RoutingTableEntry newEntry(
1298  /*dev=*/dev,
1299  /*dst=*/sender,
1300  /*vSeqNo=*/false,
1301  /*seqNo=*/0,
1302  /*iface=*/m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0),
1303  /*hops=*/1,
1304  /*nextHop=*/sender,
1305  /*lifetime=*/m_activeRouteTimeout);
1306  m_routingTable.AddRoute(newEntry);
1307  }
1308  else
1309  {
1310  Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver));
1311  if (toNeighbor.GetValidSeqNo() && (toNeighbor.GetHop() == 1) &&
1312  (toNeighbor.GetOutputDevice() == dev))
1313  {
1314  toNeighbor.SetLifeTime(std::max(m_activeRouteTimeout, toNeighbor.GetLifeTime()));
1315  }
1316  else
1317  {
1318  RoutingTableEntry newEntry(
1319  /*dev=*/dev,
1320  /*dst=*/sender,
1321  /*vSeqNo=*/false,
1322  /*seqNo=*/0,
1323  /*iface=*/m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0),
1324  /*hops=*/1,
1325  /*nextHop=*/sender,
1326  /*lifetime=*/std::max(m_activeRouteTimeout, toNeighbor.GetLifeTime()));
1327  m_routingTable.Update(newEntry);
1328  }
1329  }
1330 }
1331 
1332 void
1334 {
1335  NS_LOG_FUNCTION(this);
1336  RreqHeader rreqHeader;
1337  p->RemoveHeader(rreqHeader);
1338 
1339  // A node ignores all RREQs received from any node in its blacklist
1340  RoutingTableEntry toPrev;
1341  if (m_routingTable.LookupRoute(src, toPrev))
1342  {
1343  if (toPrev.IsUnidirectional())
1344  {
1345  NS_LOG_DEBUG("Ignoring RREQ from node in blacklist");
1346  return;
1347  }
1348  }
1349 
1350  uint32_t id = rreqHeader.GetId();
1351  Ipv4Address origin = rreqHeader.GetOrigin();
1352 
1353  /*
1354  * Node checks to determine whether it has received a RREQ with the same Originator IP Address
1355  * and RREQ ID. If such a RREQ has been received, the node silently discards the newly received
1356  * RREQ.
1357  */
1358  if (m_rreqIdCache.IsDuplicate(origin, id))
1359  {
1360  NS_LOG_DEBUG("Ignoring RREQ due to duplicate");
1361  return;
1362  }
1363 
1364  // Increment RREQ hop count
1365  uint8_t hop = rreqHeader.GetHopCount() + 1;
1366  rreqHeader.SetHopCount(hop);
1367 
1368  /*
1369  * When the reverse route is created or updated, the following actions on the route are also
1370  * carried out:
1371  * 1. the Originator Sequence Number from the RREQ is compared to the corresponding destination
1372  * sequence number in the route table entry and copied if greater than the existing value there
1373  * 2. the valid sequence number field is set to true;
1374  * 3. the next hop in the routing table becomes the node from which the RREQ was received
1375  * 4. the hop count is copied from the Hop Count in the RREQ message;
1376  * 5. the Lifetime is set to be the maximum of (ExistingLifetime, MinimalLifetime), where
1377  * MinimalLifetime = current time + 2*NetTraversalTime - 2*HopCount*NodeTraversalTime
1378  */
1379  RoutingTableEntry toOrigin;
1380  if (!m_routingTable.LookupRoute(origin, toOrigin))
1381  {
1382  Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver));
1383  RoutingTableEntry newEntry(
1384  /*dev=*/dev,
1385  /*dst=*/origin,
1386  /*vSeqNo=*/true,
1387  /*seqNo=*/rreqHeader.GetOriginSeqno(),
1388  /*iface=*/m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0),
1389  /*hops=*/hop,
1390  /*nextHop=*/src,
1391  /*lifetime=*/Time((2 * m_netTraversalTime - 2 * hop * m_nodeTraversalTime)));
1392  m_routingTable.AddRoute(newEntry);
1393  }
1394  else
1395  {
1396  if (toOrigin.GetValidSeqNo())
1397  {
1398  if (int32_t(rreqHeader.GetOriginSeqno()) - int32_t(toOrigin.GetSeqNo()) > 0)
1399  {
1400  toOrigin.SetSeqNo(rreqHeader.GetOriginSeqno());
1401  }
1402  }
1403  else
1404  {
1405  toOrigin.SetSeqNo(rreqHeader.GetOriginSeqno());
1406  }
1407  toOrigin.SetValidSeqNo(true);
1408  toOrigin.SetNextHop(src);
1409  toOrigin.SetOutputDevice(m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver)));
1410  toOrigin.SetInterface(m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0));
1411  toOrigin.SetHop(hop);
1413  toOrigin.GetLifeTime()));
1414  m_routingTable.Update(toOrigin);
1415  // m_nb.Update (src, Time (AllowedHelloLoss * HelloInterval));
1416  }
1417 
1418  RoutingTableEntry toNeighbor;
1419  if (!m_routingTable.LookupRoute(src, toNeighbor))
1420  {
1421  NS_LOG_DEBUG("Neighbor:" << src << " not found in routing table. Creating an entry");
1422  Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver));
1423  RoutingTableEntry newEntry(dev,
1424  src,
1425  false,
1426  rreqHeader.GetOriginSeqno(),
1427  m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0),
1428  1,
1429  src,
1431  m_routingTable.AddRoute(newEntry);
1432  }
1433  else
1434  {
1435  toNeighbor.SetLifeTime(m_activeRouteTimeout);
1436  toNeighbor.SetValidSeqNo(false);
1437  toNeighbor.SetSeqNo(rreqHeader.GetOriginSeqno());
1438  toNeighbor.SetFlag(VALID);
1439  toNeighbor.SetOutputDevice(m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver)));
1440  toNeighbor.SetInterface(m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0));
1441  toNeighbor.SetHop(1);
1442  toNeighbor.SetNextHop(src);
1443  m_routingTable.Update(toNeighbor);
1444  }
1446 
1447  NS_LOG_LOGIC(receiver << " receive RREQ with hop count "
1448  << static_cast<uint32_t>(rreqHeader.GetHopCount()) << " ID "
1449  << rreqHeader.GetId() << " to destination " << rreqHeader.GetDst());
1450 
1451  // A node generates a RREP if either:
1452  // (i) it is itself the destination,
1453  if (IsMyOwnAddress(rreqHeader.GetDst()))
1454  {
1455  m_routingTable.LookupRoute(origin, toOrigin);
1456  NS_LOG_DEBUG("Send reply since I am the destination");
1457  SendReply(rreqHeader, toOrigin);
1458  return;
1459  }
1460  /*
1461  * (ii) or it has an active route to the destination, the destination sequence number in the
1462  * node's existing route table entry for the destination is valid and greater than or equal to
1463  * the Destination Sequence Number of the RREQ, and the "destination only" flag is NOT set.
1464  */
1465  RoutingTableEntry toDst;
1466  Ipv4Address dst = rreqHeader.GetDst();
1467  if (m_routingTable.LookupRoute(dst, toDst))
1468  {
1469  /*
1470  * Drop RREQ, This node RREP will make a loop.
1471  */
1472  if (toDst.GetNextHop() == src)
1473  {
1474  NS_LOG_DEBUG("Drop RREQ from " << src << ", dest next hop " << toDst.GetNextHop());
1475  return;
1476  }
1477  /*
1478  * The Destination Sequence number for the requested destination is set to the maximum of
1479  * the corresponding value received in the RREQ message, and the destination sequence value
1480  * currently maintained by the node for the requested destination. However, the forwarding
1481  * node MUST NOT modify its maintained value for the destination sequence number, even if
1482  * the value received in the incoming RREQ is larger than the value currently maintained by
1483  * the forwarding node.
1484  */
1485  if ((rreqHeader.GetUnknownSeqno() ||
1486  (int32_t(toDst.GetSeqNo()) - int32_t(rreqHeader.GetDstSeqno()) >= 0)) &&
1487  toDst.GetValidSeqNo())
1488  {
1489  if (!rreqHeader.GetDestinationOnly() && toDst.GetFlag() == VALID)
1490  {
1491  m_routingTable.LookupRoute(origin, toOrigin);
1492  SendReplyByIntermediateNode(toDst, toOrigin, rreqHeader.GetGratuitousRrep());
1493  return;
1494  }
1495  rreqHeader.SetDstSeqno(toDst.GetSeqNo());
1496  rreqHeader.SetUnknownSeqno(false);
1497  }
1498  }
1499 
1500  SocketIpTtlTag tag;
1501  p->RemovePacketTag(tag);
1502  if (tag.GetTtl() < 2)
1503  {
1504  NS_LOG_DEBUG("TTL exceeded. Drop RREQ origin " << src << " destination " << dst);
1505  return;
1506  }
1507 
1508  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin();
1509  j != m_socketAddresses.end();
1510  ++j)
1511  {
1512  Ptr<Socket> socket = j->first;
1513  Ipv4InterfaceAddress iface = j->second;
1514  Ptr<Packet> packet = Create<Packet>();
1515  SocketIpTtlTag ttl;
1516  ttl.SetTtl(tag.GetTtl() - 1);
1517  packet->AddPacketTag(ttl);
1518  packet->AddHeader(rreqHeader);
1519  TypeHeader tHeader(AODVTYPE_RREQ);
1520  packet->AddHeader(tHeader);
1521  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1522  Ipv4Address destination;
1523  if (iface.GetMask() == Ipv4Mask::GetOnes())
1524  {
1525  destination = Ipv4Address("255.255.255.255");
1526  }
1527  else
1528  {
1529  destination = iface.GetBroadcast();
1530  }
1534  this,
1535  socket,
1536  packet,
1537  destination);
1538  }
1539 }
1540 
1541 void
1542 RoutingProtocol::SendReply(const RreqHeader& rreqHeader, const RoutingTableEntry& toOrigin)
1543 {
1544  NS_LOG_FUNCTION(this << toOrigin.GetDestination());
1545  /*
1546  * Destination node MUST increment its own sequence number by one if the sequence number in the
1547  * RREQ packet is equal to that incremented value. Otherwise, the destination does not change
1548  * its sequence number before generating the RREP message.
1549  */
1550  if (!rreqHeader.GetUnknownSeqno() && (rreqHeader.GetDstSeqno() == m_seqNo + 1))
1551  {
1552  m_seqNo++;
1553  }
1554  RrepHeader rrepHeader(/*prefixSize=*/0,
1555  /*hopCount=*/0,
1556  /*dst=*/rreqHeader.GetDst(),
1557  /*dstSeqNo=*/m_seqNo,
1558  /*origin=*/toOrigin.GetDestination(),
1559  /*lifetime=*/m_myRouteTimeout);
1560  Ptr<Packet> packet = Create<Packet>();
1561  SocketIpTtlTag tag;
1562  tag.SetTtl(toOrigin.GetHop());
1563  packet->AddPacketTag(tag);
1564  packet->AddHeader(rrepHeader);
1565  TypeHeader tHeader(AODVTYPE_RREP);
1566  packet->AddHeader(tHeader);
1568  NS_ASSERT(socket);
1569  socket->SendTo(packet, 0, InetSocketAddress(toOrigin.GetNextHop(), AODV_PORT));
1570 }
1571 
1572 void
1574  RoutingTableEntry& toOrigin,
1575  bool gratRep)
1576 {
1577  NS_LOG_FUNCTION(this);
1578  RrepHeader rrepHeader(/*prefixSize=*/0,
1579  /*hopCount=*/toDst.GetHop(),
1580  /*dst=*/toDst.GetDestination(),
1581  /*dstSeqNo=*/toDst.GetSeqNo(),
1582  /*origin=*/toOrigin.GetDestination(),
1583  /*lifetime=*/toDst.GetLifeTime());
1584  /* If the node we received a RREQ for is a neighbor we are
1585  * probably facing a unidirectional link... Better request a RREP-ack
1586  */
1587  if (toDst.GetHop() == 1)
1588  {
1589  rrepHeader.SetAckRequired(true);
1590  RoutingTableEntry toNextHop;
1591  m_routingTable.LookupRoute(toOrigin.GetNextHop(), toNextHop);
1593  toNextHop.m_ackTimer.SetArguments(toNextHop.GetDestination(), m_blackListTimeout);
1594  toNextHop.m_ackTimer.SetDelay(m_nextHopWait);
1595  }
1596  toDst.InsertPrecursor(toOrigin.GetNextHop());
1597  toOrigin.InsertPrecursor(toDst.GetNextHop());
1598  m_routingTable.Update(toDst);
1599  m_routingTable.Update(toOrigin);
1600 
1601  Ptr<Packet> packet = Create<Packet>();
1602  SocketIpTtlTag tag;
1603  tag.SetTtl(toOrigin.GetHop());
1604  packet->AddPacketTag(tag);
1605  packet->AddHeader(rrepHeader);
1606  TypeHeader tHeader(AODVTYPE_RREP);
1607  packet->AddHeader(tHeader);
1609  NS_ASSERT(socket);
1610  socket->SendTo(packet, 0, InetSocketAddress(toOrigin.GetNextHop(), AODV_PORT));
1611 
1612  // Generating gratuitous RREPs
1613  if (gratRep)
1614  {
1615  RrepHeader gratRepHeader(/*prefixSize=*/0,
1616  /*hopCount=*/toOrigin.GetHop(),
1617  /*dst=*/toOrigin.GetDestination(),
1618  /*dstSeqNo=*/toOrigin.GetSeqNo(),
1619  /*origin=*/toDst.GetDestination(),
1620  /*lifetime=*/toOrigin.GetLifeTime());
1621  Ptr<Packet> packetToDst = Create<Packet>();
1622  SocketIpTtlTag gratTag;
1623  gratTag.SetTtl(toDst.GetHop());
1624  packetToDst->AddPacketTag(gratTag);
1625  packetToDst->AddHeader(gratRepHeader);
1627  packetToDst->AddHeader(type);
1629  NS_ASSERT(socket);
1630  NS_LOG_LOGIC("Send gratuitous RREP " << packet->GetUid());
1631  socket->SendTo(packetToDst, 0, InetSocketAddress(toDst.GetNextHop(), AODV_PORT));
1632  }
1633 }
1634 
1635 void
1637 {
1638  NS_LOG_FUNCTION(this << " to " << neighbor);
1639  RrepAckHeader h;
1640  TypeHeader typeHeader(AODVTYPE_RREP_ACK);
1641  Ptr<Packet> packet = Create<Packet>();
1642  SocketIpTtlTag tag;
1643  tag.SetTtl(1);
1644  packet->AddPacketTag(tag);
1645  packet->AddHeader(h);
1646  packet->AddHeader(typeHeader);
1647  RoutingTableEntry toNeighbor;
1648  m_routingTable.LookupRoute(neighbor, toNeighbor);
1650  NS_ASSERT(socket);
1651  socket->SendTo(packet, 0, InetSocketAddress(neighbor, AODV_PORT));
1652 }
1653 
1654 void
1656 {
1657  NS_LOG_FUNCTION(this << " src " << sender);
1658  RrepHeader rrepHeader;
1659  p->RemoveHeader(rrepHeader);
1660  Ipv4Address dst = rrepHeader.GetDst();
1661  NS_LOG_LOGIC("RREP destination " << dst << " RREP origin " << rrepHeader.GetOrigin());
1662 
1663  uint8_t hop = rrepHeader.GetHopCount() + 1;
1664  rrepHeader.SetHopCount(hop);
1665 
1666  // If RREP is Hello message
1667  if (dst == rrepHeader.GetOrigin())
1668  {
1669  ProcessHello(rrepHeader, receiver);
1670  return;
1671  }
1672 
1673  /*
1674  * If the route table entry to the destination is created or updated, then the following actions
1675  * occur:
1676  * - the route is marked as active,
1677  * - the destination sequence number is marked as valid,
1678  * - the next hop in the route entry is assigned to be the node from which the RREP is
1679  * received, which is indicated by the source IP address field in the IP header,
1680  * - the hop count is set to the value of the hop count from RREP message + 1
1681  * - the expiry time is set to the current time plus the value of the Lifetime in the RREP
1682  * message,
1683  * - and the destination sequence number is the Destination Sequence Number in the RREP
1684  * message.
1685  */
1686  Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver));
1687  RoutingTableEntry newEntry(
1688  /*dev=*/dev,
1689  /*dst=*/dst,
1690  /*vSeqNo=*/true,
1691  /*seqNo=*/rrepHeader.GetDstSeqno(),
1692  /*iface=*/m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0),
1693  /*hops=*/hop,
1694  /*nextHop=*/sender,
1695  /*lifetime=*/rrepHeader.GetLifeTime());
1696  RoutingTableEntry toDst;
1697  if (m_routingTable.LookupRoute(dst, toDst))
1698  {
1699  /*
1700  * The existing entry is updated only in the following circumstances:
1701  * (i) the sequence number in the routing table is marked as invalid in route table entry.
1702  */
1703  if (!toDst.GetValidSeqNo())
1704  {
1705  m_routingTable.Update(newEntry);
1706  }
1707  // (ii)the Destination Sequence Number in the RREP is greater than the node's copy of the
1708  // destination sequence number and the known value is valid,
1709  else if ((int32_t(rrepHeader.GetDstSeqno()) - int32_t(toDst.GetSeqNo())) > 0)
1710  {
1711  m_routingTable.Update(newEntry);
1712  }
1713  else
1714  {
1715  // (iii) the sequence numbers are the same, but the route is marked as inactive.
1716  if ((rrepHeader.GetDstSeqno() == toDst.GetSeqNo()) && (toDst.GetFlag() != VALID))
1717  {
1718  m_routingTable.Update(newEntry);
1719  }
1720  // (iv) the sequence numbers are the same, and the New Hop Count is smaller than the
1721  // hop count in route table entry.
1722  else if ((rrepHeader.GetDstSeqno() == toDst.GetSeqNo()) && (hop < toDst.GetHop()))
1723  {
1724  m_routingTable.Update(newEntry);
1725  }
1726  }
1727  }
1728  else
1729  {
1730  // The forward route for this destination is created if it does not already exist.
1731  NS_LOG_LOGIC("add new route");
1732  m_routingTable.AddRoute(newEntry);
1733  }
1734  // Acknowledge receipt of the RREP by sending a RREP-ACK message back
1735  if (rrepHeader.GetAckRequired())
1736  {
1737  SendReplyAck(sender);
1738  rrepHeader.SetAckRequired(false);
1739  }
1740  NS_LOG_LOGIC("receiver " << receiver << " origin " << rrepHeader.GetOrigin());
1741  if (IsMyOwnAddress(rrepHeader.GetOrigin()))
1742  {
1743  if (toDst.GetFlag() == IN_SEARCH)
1744  {
1745  m_routingTable.Update(newEntry);
1746  m_addressReqTimer[dst].Cancel();
1747  m_addressReqTimer.erase(dst);
1748  }
1749  m_routingTable.LookupRoute(dst, toDst);
1750  SendPacketFromQueue(dst, toDst.GetRoute());
1751  return;
1752  }
1753 
1754  RoutingTableEntry toOrigin;
1755  if (!m_routingTable.LookupRoute(rrepHeader.GetOrigin(), toOrigin) ||
1756  toOrigin.GetFlag() == IN_SEARCH)
1757  {
1758  return; // Impossible! drop.
1759  }
1760  toOrigin.SetLifeTime(std::max(m_activeRouteTimeout, toOrigin.GetLifeTime()));
1761  m_routingTable.Update(toOrigin);
1762 
1763  // Update information about precursors
1764  if (m_routingTable.LookupValidRoute(rrepHeader.GetDst(), toDst))
1765  {
1766  toDst.InsertPrecursor(toOrigin.GetNextHop());
1767  m_routingTable.Update(toDst);
1768 
1769  RoutingTableEntry toNextHopToDst;
1770  m_routingTable.LookupRoute(toDst.GetNextHop(), toNextHopToDst);
1771  toNextHopToDst.InsertPrecursor(toOrigin.GetNextHop());
1772  m_routingTable.Update(toNextHopToDst);
1773 
1774  toOrigin.InsertPrecursor(toDst.GetNextHop());
1775  m_routingTable.Update(toOrigin);
1776 
1777  RoutingTableEntry toNextHopToOrigin;
1778  m_routingTable.LookupRoute(toOrigin.GetNextHop(), toNextHopToOrigin);
1779  toNextHopToOrigin.InsertPrecursor(toDst.GetNextHop());
1780  m_routingTable.Update(toNextHopToOrigin);
1781  }
1782  SocketIpTtlTag tag;
1783  p->RemovePacketTag(tag);
1784  if (tag.GetTtl() < 2)
1785  {
1786  NS_LOG_DEBUG("TTL exceeded. Drop RREP destination " << dst << " origin "
1787  << rrepHeader.GetOrigin());
1788  return;
1789  }
1790 
1791  Ptr<Packet> packet = Create<Packet>();
1792  SocketIpTtlTag ttl;
1793  ttl.SetTtl(tag.GetTtl() - 1);
1794  packet->AddPacketTag(ttl);
1795  packet->AddHeader(rrepHeader);
1796  TypeHeader tHeader(AODVTYPE_RREP);
1797  packet->AddHeader(tHeader);
1799  NS_ASSERT(socket);
1800  socket->SendTo(packet, 0, InetSocketAddress(toOrigin.GetNextHop(), AODV_PORT));
1801 }
1802 
1803 void
1805 {
1806  NS_LOG_FUNCTION(this);
1807  RoutingTableEntry rt;
1808  if (m_routingTable.LookupRoute(neighbor, rt))
1809  {
1810  rt.m_ackTimer.Cancel();
1811  rt.SetFlag(VALID);
1812  m_routingTable.Update(rt);
1813  }
1814 }
1815 
1816 void
1818 {
1819  NS_LOG_FUNCTION(this << "from " << rrepHeader.GetDst());
1820  /*
1821  * Whenever a node receives a Hello message from a neighbor, the node
1822  * SHOULD make sure that it has an active route to the neighbor, and
1823  * create one if necessary.
1824  */
1825  RoutingTableEntry toNeighbor;
1826  if (!m_routingTable.LookupRoute(rrepHeader.GetDst(), toNeighbor))
1827  {
1828  Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver));
1829  RoutingTableEntry newEntry(
1830  /*dev=*/dev,
1831  /*dst=*/rrepHeader.GetDst(),
1832  /*vSeqNo=*/true,
1833  /*seqNo=*/rrepHeader.GetDstSeqno(),
1834  /*iface=*/m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0),
1835  /*hops=*/1,
1836  /*nextHop=*/rrepHeader.GetDst(),
1837  /*lifetime=*/rrepHeader.GetLifeTime());
1838  m_routingTable.AddRoute(newEntry);
1839  }
1840  else
1841  {
1842  toNeighbor.SetLifeTime(
1844  toNeighbor.SetSeqNo(rrepHeader.GetDstSeqno());
1845  toNeighbor.SetValidSeqNo(true);
1846  toNeighbor.SetFlag(VALID);
1847  toNeighbor.SetOutputDevice(m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver)));
1848  toNeighbor.SetInterface(m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0));
1849  toNeighbor.SetHop(1);
1850  toNeighbor.SetNextHop(rrepHeader.GetDst());
1851  m_routingTable.Update(toNeighbor);
1852  }
1853  if (m_enableHello)
1854  {
1856  }
1857 }
1858 
1859 void
1861 {
1862  NS_LOG_FUNCTION(this << " from " << src);
1863  RerrHeader rerrHeader;
1864  p->RemoveHeader(rerrHeader);
1865  std::map<Ipv4Address, uint32_t> dstWithNextHopSrc;
1866  std::map<Ipv4Address, uint32_t> unreachable;
1867  m_routingTable.GetListOfDestinationWithNextHop(src, dstWithNextHopSrc);
1868  std::pair<Ipv4Address, uint32_t> un;
1869  while (rerrHeader.RemoveUnDestination(un))
1870  {
1871  for (std::map<Ipv4Address, uint32_t>::const_iterator i = dstWithNextHopSrc.begin();
1872  i != dstWithNextHopSrc.end();
1873  ++i)
1874  {
1875  if (i->first == un.first)
1876  {
1877  unreachable.insert(un);
1878  }
1879  }
1880  }
1881 
1882  std::vector<Ipv4Address> precursors;
1883  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin();
1884  i != unreachable.end();)
1885  {
1886  if (!rerrHeader.AddUnDestination(i->first, i->second))
1887  {
1888  TypeHeader typeHeader(AODVTYPE_RERR);
1889  Ptr<Packet> packet = Create<Packet>();
1890  SocketIpTtlTag tag;
1891  tag.SetTtl(1);
1892  packet->AddPacketTag(tag);
1893  packet->AddHeader(rerrHeader);
1894  packet->AddHeader(typeHeader);
1895  SendRerrMessage(packet, precursors);
1896  rerrHeader.Clear();
1897  }
1898  else
1899  {
1900  RoutingTableEntry toDst;
1901  m_routingTable.LookupRoute(i->first, toDst);
1902  toDst.GetPrecursors(precursors);
1903  ++i;
1904  }
1905  }
1906  if (rerrHeader.GetDestCount() != 0)
1907  {
1908  TypeHeader typeHeader(AODVTYPE_RERR);
1909  Ptr<Packet> packet = Create<Packet>();
1910  SocketIpTtlTag tag;
1911  tag.SetTtl(1);
1912  packet->AddPacketTag(tag);
1913  packet->AddHeader(rerrHeader);
1914  packet->AddHeader(typeHeader);
1915  SendRerrMessage(packet, precursors);
1916  }
1918 }
1919 
1920 void
1922 {
1923  NS_LOG_LOGIC(this);
1924  RoutingTableEntry toDst;
1925  if (m_routingTable.LookupValidRoute(dst, toDst))
1926  {
1927  SendPacketFromQueue(dst, toDst.GetRoute());
1928  NS_LOG_LOGIC("route to " << dst << " found");
1929  return;
1930  }
1931  /*
1932  * If a route discovery has been attempted RreqRetries times at the maximum TTL without
1933  * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
1934  * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the
1935  * application.
1936  */
1937  if (toDst.GetRreqCnt() == m_rreqRetries)
1938  {
1939  NS_LOG_LOGIC("route discovery to " << dst << " has been attempted RreqRetries ("
1940  << m_rreqRetries << ") times with ttl "
1941  << m_netDiameter);
1942  m_addressReqTimer.erase(dst);
1944  NS_LOG_DEBUG("Route not found. Drop all packets with dst " << dst);
1946  return;
1947  }
1948 
1949  if (toDst.GetFlag() == IN_SEARCH)
1950  {
1951  NS_LOG_LOGIC("Resend RREQ to " << dst << " previous ttl " << toDst.GetHop());
1952  SendRequest(dst);
1953  }
1954  else
1955  {
1956  NS_LOG_DEBUG("Route down. Stop search. Drop packet with destination " << dst);
1957  m_addressReqTimer.erase(dst);
1960  }
1961 }
1962 
1963 void
1965 {
1966  NS_LOG_FUNCTION(this);
1967  Time offset = Time(Seconds(0));
1968  if (m_lastBcastTime > Time(Seconds(0)))
1969  {
1970  offset = Simulator::Now() - m_lastBcastTime;
1971  NS_LOG_DEBUG("Hello deferred due to last bcast at:" << m_lastBcastTime);
1972  }
1973  else
1974  {
1975  SendHello();
1976  }
1977  m_htimer.Cancel();
1978  Time diff = m_helloInterval - offset;
1979  m_htimer.Schedule(std::max(Time(Seconds(0)), diff));
1981 }
1982 
1983 void
1985 {
1986  NS_LOG_FUNCTION(this);
1987  m_rreqCount = 0;
1989 }
1990 
1991 void
1993 {
1994  NS_LOG_FUNCTION(this);
1995  m_rerrCount = 0;
1997 }
1998 
1999 void
2001 {
2002  NS_LOG_FUNCTION(this);
2003  m_routingTable.MarkLinkAsUnidirectional(neighbor, blacklistTimeout);
2004 }
2005 
2006 void
2008 {
2009  NS_LOG_FUNCTION(this);
2010  /* Broadcast a RREP with TTL = 1 with the RREP message fields set as follows:
2011  * Destination IP Address The node's IP address.
2012  * Destination Sequence Number The node's latest sequence number.
2013  * Hop Count 0
2014  * Lifetime AllowedHelloLoss * HelloInterval
2015  */
2016  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin();
2017  j != m_socketAddresses.end();
2018  ++j)
2019  {
2020  Ptr<Socket> socket = j->first;
2021  Ipv4InterfaceAddress iface = j->second;
2022  RrepHeader helloHeader(/*prefixSize=*/0,
2023  /*hopCount=*/0,
2024  /*dst=*/iface.GetLocal(),
2025  /*dstSeqNo=*/m_seqNo,
2026  /*origin=*/iface.GetLocal(),
2027  /*lifetime=*/Time(m_allowedHelloLoss * m_helloInterval));
2028  Ptr<Packet> packet = Create<Packet>();
2029  SocketIpTtlTag tag;
2030  tag.SetTtl(1);
2031  packet->AddPacketTag(tag);
2032  packet->AddHeader(helloHeader);
2033  TypeHeader tHeader(AODVTYPE_RREP);
2034  packet->AddHeader(tHeader);
2035  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
2036  Ipv4Address destination;
2037  if (iface.GetMask() == Ipv4Mask::GetOnes())
2038  {
2039  destination = Ipv4Address("255.255.255.255");
2040  }
2041  else
2042  {
2043  destination = iface.GetBroadcast();
2044  }
2046  Simulator::Schedule(jitter, &RoutingProtocol::SendTo, this, socket, packet, destination);
2047  }
2048 }
2049 
2050 void
2052 {
2053  NS_LOG_FUNCTION(this);
2054  QueueEntry queueEntry;
2055  while (m_queue.Dequeue(dst, queueEntry))
2056  {
2058  Ptr<Packet> p = ConstCast<Packet>(queueEntry.GetPacket());
2059  if (p->RemovePacketTag(tag) && tag.GetInterface() != -1 &&
2060  tag.GetInterface() != m_ipv4->GetInterfaceForDevice(route->GetOutputDevice()))
2061  {
2062  NS_LOG_DEBUG("Output device doesn't match. Dropped.");
2063  return;
2064  }
2066  Ipv4Header header = queueEntry.GetIpv4Header();
2067  header.SetSource(route->GetSource());
2068  header.SetTtl(header.GetTtl() +
2069  1); // compensate extra TTL decrement by fake loopback routing
2070  ucb(route, p, header);
2071  }
2072 }
2073 
2074 void
2076 {
2077  NS_LOG_FUNCTION(this << nextHop);
2078  RerrHeader rerrHeader;
2079  std::vector<Ipv4Address> precursors;
2080  std::map<Ipv4Address, uint32_t> unreachable;
2081 
2082  RoutingTableEntry toNextHop;
2083  if (!m_routingTable.LookupRoute(nextHop, toNextHop))
2084  {
2085  return;
2086  }
2087  toNextHop.GetPrecursors(precursors);
2088  rerrHeader.AddUnDestination(nextHop, toNextHop.GetSeqNo());
2089  m_routingTable.GetListOfDestinationWithNextHop(nextHop, unreachable);
2090  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin();
2091  i != unreachable.end();)
2092  {
2093  if (!rerrHeader.AddUnDestination(i->first, i->second))
2094  {
2095  NS_LOG_LOGIC("Send RERR message with maximum size.");
2096  TypeHeader typeHeader(AODVTYPE_RERR);
2097  Ptr<Packet> packet = Create<Packet>();
2098  SocketIpTtlTag tag;
2099  tag.SetTtl(1);
2100  packet->AddPacketTag(tag);
2101  packet->AddHeader(rerrHeader);
2102  packet->AddHeader(typeHeader);
2103  SendRerrMessage(packet, precursors);
2104  rerrHeader.Clear();
2105  }
2106  else
2107  {
2108  RoutingTableEntry toDst;
2109  m_routingTable.LookupRoute(i->first, toDst);
2110  toDst.GetPrecursors(precursors);
2111  ++i;
2112  }
2113  }
2114  if (rerrHeader.GetDestCount() != 0)
2115  {
2116  TypeHeader typeHeader(AODVTYPE_RERR);
2117  Ptr<Packet> packet = Create<Packet>();
2118  SocketIpTtlTag tag;
2119  tag.SetTtl(1);
2120  packet->AddPacketTag(tag);
2121  packet->AddHeader(rerrHeader);
2122  packet->AddHeader(typeHeader);
2123  SendRerrMessage(packet, precursors);
2124  }
2125  unreachable.insert(std::make_pair(nextHop, toNextHop.GetSeqNo()));
2127 }
2128 
2129 void
2131  uint32_t dstSeqNo,
2132  Ipv4Address origin)
2133 {
2134  NS_LOG_FUNCTION(this);
2135  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
2137  {
2138  // Just make sure that the RerrRateLimit timer is running and will expire
2140  // discard the packet and return
2141  NS_LOG_LOGIC("RerrRateLimit reached at "
2142  << Simulator::Now().As(Time::S) << " with timer delay left "
2143  << m_rerrRateLimitTimer.GetDelayLeft().As(Time::S) << "; suppressing RERR");
2144  return;
2145  }
2146  RerrHeader rerrHeader;
2147  rerrHeader.AddUnDestination(dst, dstSeqNo);
2148  RoutingTableEntry toOrigin;
2149  Ptr<Packet> packet = Create<Packet>();
2150  SocketIpTtlTag tag;
2151  tag.SetTtl(1);
2152  packet->AddPacketTag(tag);
2153  packet->AddHeader(rerrHeader);
2155  if (m_routingTable.LookupValidRoute(origin, toOrigin))
2156  {
2158  NS_ASSERT(socket);
2159  NS_LOG_LOGIC("Unicast RERR to the source of the data transmission");
2160  socket->SendTo(packet, 0, InetSocketAddress(toOrigin.GetNextHop(), AODV_PORT));
2161  }
2162  else
2163  {
2164  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
2165  m_socketAddresses.begin();
2166  i != m_socketAddresses.end();
2167  ++i)
2168  {
2169  Ptr<Socket> socket = i->first;
2170  Ipv4InterfaceAddress iface = i->second;
2171  NS_ASSERT(socket);
2172  NS_LOG_LOGIC("Broadcast RERR message from interface " << iface.GetLocal());
2173  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
2174  Ipv4Address destination;
2175  if (iface.GetMask() == Ipv4Mask::GetOnes())
2176  {
2177  destination = Ipv4Address("255.255.255.255");
2178  }
2179  else
2180  {
2181  destination = iface.GetBroadcast();
2182  }
2183  socket->SendTo(packet->Copy(), 0, InetSocketAddress(destination, AODV_PORT));
2184  }
2185  }
2186 }
2187 
2188 void
2189 RoutingProtocol::SendRerrMessage(Ptr<Packet> packet, std::vector<Ipv4Address> precursors)
2190 {
2191  NS_LOG_FUNCTION(this);
2192 
2193  if (precursors.empty())
2194  {
2195  NS_LOG_LOGIC("No precursors");
2196  return;
2197  }
2198  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
2200  {
2201  // Just make sure that the RerrRateLimit timer is running and will expire
2203  // discard the packet and return
2204  NS_LOG_LOGIC("RerrRateLimit reached at "
2205  << Simulator::Now().As(Time::S) << " with timer delay left "
2206  << m_rerrRateLimitTimer.GetDelayLeft().As(Time::S) << "; suppressing RERR");
2207  return;
2208  }
2209  // If there is only one precursor, RERR SHOULD be unicast toward that precursor
2210  if (precursors.size() == 1)
2211  {
2212  RoutingTableEntry toPrecursor;
2213  if (m_routingTable.LookupValidRoute(precursors.front(), toPrecursor))
2214  {
2216  NS_ASSERT(socket);
2217  NS_LOG_LOGIC("one precursor => unicast RERR to "
2218  << toPrecursor.GetDestination() << " from "
2219  << toPrecursor.GetInterface().GetLocal());
2222  this,
2223  socket,
2224  packet,
2225  precursors.front());
2226  m_rerrCount++;
2227  }
2228  return;
2229  }
2230 
2231  // Should only transmit RERR on those interfaces which have precursor nodes for the broken
2232  // route
2233  std::vector<Ipv4InterfaceAddress> ifaces;
2234  RoutingTableEntry toPrecursor;
2235  for (std::vector<Ipv4Address>::const_iterator i = precursors.begin(); i != precursors.end();
2236  ++i)
2237  {
2238  if (m_routingTable.LookupValidRoute(*i, toPrecursor) &&
2239  std::find(ifaces.begin(), ifaces.end(), toPrecursor.GetInterface()) == ifaces.end())
2240  {
2241  ifaces.push_back(toPrecursor.GetInterface());
2242  }
2243  }
2244 
2245  for (std::vector<Ipv4InterfaceAddress>::const_iterator i = ifaces.begin(); i != ifaces.end();
2246  ++i)
2247  {
2249  NS_ASSERT(socket);
2250  NS_LOG_LOGIC("Broadcast RERR message from interface " << i->GetLocal());
2251  // std::cout << "Broadcast RERR message from interface " << i->GetLocal () << std::endl;
2252  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
2253  Ptr<Packet> p = packet->Copy();
2254  Ipv4Address destination;
2255  if (i->GetMask() == Ipv4Mask::GetOnes())
2256  {
2257  destination = Ipv4Address("255.255.255.255");
2258  }
2259  else
2260  {
2261  destination = i->GetBroadcast();
2262  }
2265  this,
2266  socket,
2267  p,
2268  destination);
2269  }
2270 }
2271 
2274 {
2275  NS_LOG_FUNCTION(this << addr);
2276  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin();
2277  j != m_socketAddresses.end();
2278  ++j)
2279  {
2280  Ptr<Socket> socket = j->first;
2281  Ipv4InterfaceAddress iface = j->second;
2282  if (iface == addr)
2283  {
2284  return socket;
2285  }
2286  }
2287  Ptr<Socket> socket;
2288  return socket;
2289 }
2290 
2293 {
2294  NS_LOG_FUNCTION(this << addr);
2295  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
2298  ++j)
2299  {
2300  Ptr<Socket> socket = j->first;
2301  Ipv4InterfaceAddress iface = j->second;
2302  if (iface == addr)
2303  {
2304  return socket;
2305  }
2306  }
2307  Ptr<Socket> socket;
2308  return socket;
2309 }
2310 
2311 void
2313 {
2314  NS_LOG_FUNCTION(this);
2315  uint32_t startTime;
2316  if (m_enableHello)
2317  {
2319  startTime = m_uniformRandomVariable->GetInteger(0, 100);
2320  NS_LOG_DEBUG("Starting at time " << startTime << "ms");
2321  m_htimer.Schedule(MilliSeconds(startTime));
2322  }
2324 }
2325 
2326 } // namespace aodv
2327 } // namespace ns3
#define max(a, b)
Definition: 80211b.c:43
a polymophic address class
Definition: address.h:100
Wifi MAC high model for an ad-hoc Wifi MAC.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Callback template class.
Definition: callback.h:443
bool IsNull() const
Check for null implementation.
Definition: callback.h:572
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:43
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:258
static Ipv4Mask GetOnes()
Abstract base class for IPv4 routing protocols.
virtual Address GetAddress() const =0
A network Node.
Definition: node.h:56
virtual void DoInitialize()
Initialize() implementation.
Definition: object.cc:360
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
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:986
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:979
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:1002
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:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:606
static Time GetMaximumSimulationTime()
Get the maximum representable simulation time.
Definition: simulator.cc:302
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:126
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:325
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:521
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:602
uint8_t GetTtl() const
Get the tag's TTL.
Definition: socket.cc:609
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:417
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:111
@ S
second
Definition: nstime.h:116
AttributeValue implementation for Time.
Definition: nstime.h:1423
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:278
Time GetDelayLeft() const
Definition: timer.cc:90
void SetArguments(Ts... args)
Definition: timer.h:294
@ 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:112
void Schedule()
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:166
bool IsRunning() const
Definition: timer.cc:133
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Packet header for UDP packets.
Definition: udp-header.h:41
uint16_t GetDestinationPort() const
Definition: udp-header.cc:75
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:645
bool AddUnDestination(Ipv4Address dst, uint32_t seqNo)
Add unreachable node address and its sequence number in RERR header.
Definition: aodv-packet.cc:619
bool RemoveUnDestination(std::pair< Ipv4Address, uint32_t > &un)
Delete pair (address + sequence number) from REER header, if the number of unreachable destinations >...
Definition: aodv-packet.cc:632
Ptr< Ipv4Route > LoopbackRoute(const Ipv4Header &header, Ptr< NetDevice > oif) const
Create loopback route for given header.
uint32_t m_requestId
Broadcast ID.
void RecvAodv(Ptr< Socket > socket)
Receive and process control packet.
bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb) override
Route an input packet (to be forwarded or locally delivered)
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.
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:144
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:336
bool LookupValidRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup route in VALID state.
Definition: aodv-rtable.cc:258
void Purge()
Delete all outdated entries and invalidate valid entry if Lifetime is expired.
Definition: aodv-rtable.cc:401
bool Update(RoutingTableEntry &rt)
Update routing table.
Definition: aodv-rtable.cc:300
bool AddRoute(RoutingTableEntry &r)
Add routing table entry if it doesn't yet exist in routing table.
Definition: aodv-rtable.cc:286
void Print(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print routing table.
Definition: aodv-rtable.cc:491
bool LookupRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup routing table entry with destination address dst.
Definition: aodv-rtable.cc:237
void DeleteAllRoutesFromInterface(Ipv4InterfaceAddress iface)
Delete all route from interface with address iface.
Definition: aodv-rtable.cc:377
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:355
bool MarkLinkAsUnidirectional(Ipv4Address neighbor, Time blacklistTimeout)
Mark entry as unidirectional (e.g.
Definition: aodv-rtable.cc:474
bool DeleteRoute(Ipv4Address dst)
Delete routing table entry with destination address dst, if it exists.
Definition: aodv-rtable.cc:272
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
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: pointer.h:231
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: nstime.h:1424
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:46
#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:296
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1360
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
WifiMacDropReason
The reason why an MPDU was dropped.
Definition: wifi-mac.h:75
address
Definition: first.py:40
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:848
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:707
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:535
mac
Definition: third.py:85
wifi
Definition: third.py:88