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 * 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
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
52namespace ns3
53{
54
55NS_LOG_COMPONENT_DEFINE("AodvRoutingProtocol");
56
57namespace aodv
58{
59NS_OBJECT_ENSURE_REGISTERED(RoutingProtocol);
60
63
69{
70 public:
76 : Tag(),
77 m_oif(o)
78 {
79 }
80
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
104 {
105 return m_oif;
106 }
107
113 {
114 m_oif = oif;
115 }
116
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:
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
186TypeId
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)),
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.",
243 .AddAttribute(
244 "NextHopWait",
245 "Period of our waiting for the neighbour's RREP_ACK = 10 ms + NodeTraversalTime",
249 .AddAttribute("ActiveRouteTimeout",
250 "Period of time during which the route is considered to be valid",
251 TimeValue(Seconds(3)),
254 .AddAttribute("MyRouteTimeout",
255 "Value of lifetime field in RREP generating by this node = 2 * "
256 "max(ActiveRouteTimeout, PathDiscoveryTime)",
257 TimeValue(Seconds(11.2)),
260 .AddAttribute("BlackListTimeout",
261 "Time for which the node is put into the blacklist = RreqRetries * "
262 "NetTraversalTime",
263 TimeValue(Seconds(5.6)),
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)),
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)),
287 .AddAttribute(
288 "PathDiscoveryTime",
289 "Estimate of maximum time needed to find route in network = 2 * NetTraversalTime",
290 TimeValue(Seconds(5.6)),
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)),
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
343void
345{
346 m_maxQueueLen = len;
348}
349
350void
352{
353 m_maxQueueTime = t;
355}
356
358{
359}
360
361void
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 =
375 iter++)
376 {
377 iter->first->Close();
378 }
381}
382
383void
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
395int64_t
397{
398 NS_LOG_FUNCTION(this << stream);
400 return 1;
401}
402
403void
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 {
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.");
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
471void
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
496bool
498 const Ipv4Header& header,
500 const UnicastForwardCallback& ucb,
501 const MulticastForwardCallback& mcb,
502 const LocalDeliverCallback& lcb,
503 const 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 }
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())
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 }
574 {
575 return true;
576 }
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())
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))
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
646bool
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
706void
708{
709 NS_ASSERT(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);
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(),
730
732}
733
734void
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);
752 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvAodv, this));
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);
762 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvAodv, this));
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(),
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
802void
804{
805 m_nb.GetTxErrorCallback()(mpdu->GetHeader());
806}
807
808void
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();
839
840 if (m_socketAddresses.empty())
841 {
842 NS_LOG_LOGIC("No aodv interfaces");
844 m_nb.Clear();
846 return;
847 }
849}
850
851void
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);
874 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvAodv, this));
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);
883 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvAodv, this));
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(),
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
911void
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);
937 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvAodv, this));
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);
948 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvAodv, this));
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(),
967 }
968 if (m_socketAddresses.empty())
969 {
970 NS_LOG_LOGIC("No aodv interfaces");
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
983bool
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
1048void
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
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);
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
1125 {
1126 rreqHeader.SetGratuitousRrep(true);
1127 }
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
1178void
1180{
1181 socket->SendTo(packet, 0, InetSocketAddress(destination, AODV_PORT));
1182}
1183
1184void
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);
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
1214void
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
1270bool
1272{
1273 NS_LOG_FUNCTION(this << addr << lifetime);
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()));
1283 return true;
1284 }
1285 }
1286 return false;
1287}
1288
1289void
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
1332void
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);
1412 toOrigin.SetLifeTime(std::max(Time(2 * m_netTraversalTime - 2 * hop * m_nodeTraversalTime),
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 {
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
1541void
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
1572void
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);
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
1635void
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
1654void
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
1803void
1805{
1806 NS_LOG_FUNCTION(this);
1808 if (m_routingTable.LookupRoute(neighbor, rt))
1809 {
1810 rt.m_ackTimer.Cancel();
1811 rt.SetFlag(VALID);
1813 }
1814}
1815
1816void
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(
1843 std::max(Time(m_allowedHelloLoss * m_helloInterval), toNeighbor.GetLifeTime()));
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
1859void
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
1920void
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
1963void
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
1983void
1985{
1986 NS_LOG_FUNCTION(this);
1987 m_rreqCount = 0;
1989}
1990
1991void
1993{
1994 NS_LOG_FUNCTION(this);
1995 m_rerrCount = 0;
1997}
1998
1999void
2001{
2002 NS_LOG_FUNCTION(this);
2003 m_routingTable.MarkLinkAsUnidirectional(neighbor, blacklistTimeout);
2004}
2005
2006void
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
2050void
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
2074void
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
2129void
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);
2154 packet->AddHeader(TypeHeader(AODVTYPE_RERR));
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
2188void
2189RoutingProtocol::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
2311void
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:42
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
bool IsNull() const
Check for null implementation.
Definition: callback.h:567
an Inet address class
Ipv4Address GetIpv4() const
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
static Ipv4Address GetLoopback()
bool IsMulticast() const
static Ipv4Address GetBroadcast()
bool IsBroadcast() const
Packet header for IPv4.
Definition: ipv4-header.h:34
Ipv4Address GetSource() const
Definition: ipv4-header.cc:302
uint8_t GetProtocol() const
Definition: ipv4-header.cc:281
void SetTtl(uint8_t ttl)
Definition: ipv4-header.cc:267
Ipv4Address GetDestination() const
Definition: ipv4-header.cc:316
uint8_t GetTtl() const
Definition: ipv4-header.cc:274
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:295
a class to store IPv4 address information on an interface
Ipv4Mask GetMask() const
Get the network mask.
Ipv4Address GetLocal() const
Get the local address.
Ipv4Address GetBroadcast() const
Get the broadcast address.
Implement the IPv4 layer.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:257
static Ipv4Mask GetOnes()
Abstract base class for IPv4 routing protocols.
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
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
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
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
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
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:275
Time GetDelayLeft() const
Definition: timer.cc:90
void SetArguments(Ts... args)
Definition: timer.h:291
@ CANCEL_ON_DESTROY
This policy cancels the event from the destructor of the Timer or from Suspend().
Definition: timer.h:93
void Cancel()
Cancel the currently-running event if there is one.
Definition: timer.cc:108
void Schedule()
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:162
bool IsRunning() const
Definition: timer.cc:129
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
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.
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:45
Ipv4Header GetIpv4Header() const
Get IPv4 header.
Definition: aodv-rqueue.h:145
Ptr< const Packet > GetPacket() const
Get packet from entry.
Definition: aodv-rqueue.h:127
UnicastForwardCallback GetUnicastForwardCallback() const
Get unicast forward callback.
Definition: aodv-rqueue.h:91
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.
void UpdateRouteToNeighbor(Ipv4Address sender, Ipv4Address receiver)
Update neighbor record.
Timer m_rerrRateLimitTimer
RERR rate limit timer.
Time m_lastBcastTime
Keep track of the last bcast time.
void RecvReply(Ptr< Packet > p, Ipv4Address my, Ipv4Address src)
Receive RREP.
bool m_enableBroadcast
Indicates whether a a broadcast data packets forwarding enable.
bool GetBroadcastEnable() const
Get broadcast enable flag.
bool UpdateRouteLifeTime(Ipv4Address addr, Time lt)
Set lifetime field in routing table entry to the maximum of existing lifetime and lt,...
void RerrRateLimitTimerExpire()
Reset RERR count and schedule RERR rate limit timer with delay 1 sec.
Time m_blackListTimeout
Time for which the node is put into the blacklist.
void RecvReplyAck(Ipv4Address neighbor)
Receive RREP_ACK.
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketSubnetBroadcastAddresses
Raw subnet directed broadcast socket per each IP interface, map socket -> iface address (IP.
Time m_maxQueueTime
The maximum period of time that a routing protocol is allowed to buffer a packet for.
Time m_activeRouteTimeout
Period of time during which the route is considered to be valid.
std::map< Ipv4Address, Timer > m_addressReqTimer
Map IP address + RREQ timer.
uint32_t GetMaxQueueLen() const
Get the maximum queue length.
void DeferredRouteOutput(Ptr< const Packet > p, const Ipv4Header &header, UnicastForwardCallback ucb, ErrorCallback ecb)
Queue packet and send route request.
void SendTo(Ptr< Socket > socket, Ptr< Packet > packet, Ipv4Address destination)
Send packet to destination socket.
DuplicatePacketDetection m_dpd
Handle duplicated broadcast/multicast packets.
Time m_netTraversalTime
Estimate of the average net traversal time.
void DoDispose() override
Destructor implementation.
void SendRequest(Ipv4Address dst)
Send RREQ.
Time m_pathDiscoveryTime
Estimate of maximum time needed to find route in network.
bool m_gratuitousReply
Indicates whether a gratuitous RREP should be unicast to the node originated route discovery.
uint16_t m_rerrCount
Number of RERRs used for RERR rate control.
void HelloTimerExpire()
Schedule next send of hello message.
void NotifyTxError(WifiMacDropReason reason, Ptr< const WifiMpdu > mpdu)
Notify that an MPDU was dropped.
RoutingTable m_routingTable
Routing table.
uint16_t m_rreqRateLimit
Maximum number of RREQ per second.
Ptr< NetDevice > m_lo
Loopback device used to defer RREQ until packet will be fully formed.
uint32_t m_netDiameter
Net diameter measures the maximum possible number of hops between two nodes in the network.
uint32_t m_maxQueueLen
The maximum number of packets that we allow a routing protocol to buffer.
uint16_t m_ttlThreshold
Maximum TTL value for expanding ring search, TTL = NetDiameter is used beyond this value.
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
void SetMaxQueueTime(Time t)
Set the maximum queue time.
uint16_t m_ttlIncrement
TTL increment for each attempt using the expanding ring search for RREQ dissemination.
Time m_myRouteTimeout
Value of lifetime field in RREP generating by this node.
uint16_t m_timeoutBuffer
Provide a buffer for the timeout.
void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const override
Print the Routing Table entries.
Ptr< Socket > FindSocketWithInterfaceAddress(Ipv4InterfaceAddress iface) const
Find unicast socket with local interface address iface.
void NotifyInterfaceDown(uint32_t interface) override
void SetBroadcastEnable(bool f)
Set broadcast enable flag.
void SendPacketFromQueue(Ipv4Address dst, Ptr< Ipv4Route > route)
Forward packet from route request queue.
uint32_t m_allowedHelloLoss
Number of hello messages which may be loss for valid link.
bool IsMyOwnAddress(Ipv4Address src)
Test whether the provided address is assigned to an interface on this node.
void SetMaxQueueLen(uint32_t len)
Set the maximum queue length.
void ScheduleRreqRetry(Ipv4Address dst)
Repeated attempts by a source node at route discovery for a single destination use the expanding ring...
void SendReplyByIntermediateNode(RoutingTableEntry &toDst, RoutingTableEntry &toOrigin, bool gratRep)
Send RREP by intermediate node.
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketAddresses
Raw unicast socket per each IP interface, map socket -> iface address (IP + mask)
void SetGratuitousReplyFlag(bool f)
Set gratuitous reply flag.
bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, const UnicastForwardCallback &ucb, const MulticastForwardCallback &mcb, const LocalDeliverCallback &lcb, const ErrorCallback &ecb) override
Route an input packet (to be forwarded or locally delivered)
void Start()
Start protocol operation.
uint16_t m_rreqCount
Number of RREQs used for RREQ rate control.
IdCache m_rreqIdCache
Handle duplicated RREQ.
Time m_deletePeriod
DeletePeriod is intended to provide an upper bound on the time for which an upstream node A can have ...
void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address) override
void SendRerrWhenNoRouteToForward(Ipv4Address dst, uint32_t dstSeqNo, Ipv4Address origin)
Send RERR message when no route to forward input packet.
Time m_helloInterval
Every HelloInterval the node checks whether it has sent a broadcast within the last HelloInterval.
void AckTimerExpire(Ipv4Address neighbor, Time blacklistTimeout)
Mark link to neighbor node as unidirectional for blacklistTimeout.
void SetHelloEnable(bool f)
Set hello enable.
bool m_destinationOnly
Indicates only the destination may respond to this RREQ.
void SetIpv4(Ptr< Ipv4 > ipv4) override
static TypeId GetTypeId()
Get the type ID.
void SetDestinationOnlyFlag(bool f)
Set destination only flag.
bool GetDestinationOnlyFlag() const
Get destination only flag.
void SendRerrMessage(Ptr< Packet > packet, std::vector< Ipv4Address > precursors)
Forward RERR.
uint16_t m_ttlStart
Initial TTL value for RREQ.
uint32_t m_rreqRetries
Maximum number of retransmissions of RREQ with TTL = NetDiameter to discover a route.
uint32_t m_seqNo
Request sequence number.
bool m_enableHello
Indicates whether a hello messages enable.
Neighbors m_nb
Handle neighbors.
bool Forwarding(Ptr< const Packet > p, const Ipv4Header &header, UnicastForwardCallback ucb, ErrorCallback ecb)
If route exists and is valid, forward packet.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
static const uint32_t AODV_PORT
UDP Port for AODV control traffic.
Timer m_rreqRateLimitTimer
RREQ rate limit timer.
Time GetMaxQueueTime() const
Get maximum queue time.
void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address) override
Time m_nodeTraversalTime
NodeTraversalTime is a conservative estimate of the average one hop traversal time for packets and sh...
uint16_t m_rerrRateLimit
Maximum number of REER per second.
void RecvRequest(Ptr< Packet > p, Ipv4Address receiver, Ipv4Address src)
Receive RREQ.
Ptr< Socket > FindSubnetBroadcastSocketWithInterfaceAddress(Ipv4InterfaceAddress iface) const
Find subnet directed broadcast socket with local interface address iface.
void DoInitialize() override
Initialize() implementation.
bool GetHelloEnable() const
Get hello enable flag.
void SendRerrWhenBreaksLinkToNextHop(Ipv4Address nextHop)
Initiate RERR.
void RouteRequestTimerExpire(Ipv4Address dst)
Handle route discovery process.
void NotifyInterfaceUp(uint32_t interface) override
bool GetGratuitousReplyFlag() const
Get gratuitous reply flag.
void RecvError(Ptr< Packet > p, Ipv4Address src)
Receive RERR.
Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr) override
Query routing cache for an existing route, for an outbound packet.
Time m_nextHopWait
Period of our waiting for the neighbour's RREP_ACK.
void SendReplyAck(Ipv4Address neighbor)
Send RREP_ACK.
Ptr< Ipv4 > m_ipv4
IP protocol.
void RreqRateLimitTimerExpire()
Reset RREQ count and schedule RREQ rate limit timer with delay 1 sec.
void ProcessHello(const RrepHeader &rrepHeader, Ipv4Address receiverIfaceAddr)
Process hello message.
void SendReply(const RreqHeader &rreqHeader, const RoutingTableEntry &toOrigin)
Send RREP.
RequestQueue m_queue
A "drop-front" queue used by the routing layer to buffer packets to which it does not have a route.
Routing table entry.
Definition: aodv-rtable.h:62
Timer m_ackTimer
RREP_ACK timer.
Definition: aodv-rtable.h:362
void SetHop(uint16_t hop)
Set the number of hops.
Definition: aodv-rtable.h:249
bool InsertPrecursor(Ipv4Address id)
Insert precursor in precursor list if it doesn't yet exist in the list.
Definition: aodv-rtable.cc:79
Ptr< NetDevice > GetOutputDevice() const
Get output device.
Definition: aodv-rtable.h:186
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
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
Ptr< Ipv4Route > GetRoute() const
Get route function.
Definition: aodv-rtable.h:141
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)
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1444
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1424
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
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
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:702
STL namespace.