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