A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
rip.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016 Universita' di Firenze, Italy
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
7 */
8
9#include "rip.h"
10
12#include "ipv4-route.h"
13#include "loopback-net-device.h"
14#include "rip-header.h"
15#include "udp-header.h"
16
17#include "ns3/abort.h"
18#include "ns3/assert.h"
19#include "ns3/enum.h"
20#include "ns3/log.h"
21#include "ns3/names.h"
22#include "ns3/node.h"
23#include "ns3/random-variable-stream.h"
24#include "ns3/uinteger.h"
25
26#include <iomanip>
27
28#define RIP_ALL_NODE "224.0.0.9"
29#define RIP_PORT 520
30
31namespace ns3
32{
33
35
37
45
47{
48}
49
52{
53 static TypeId tid =
54 TypeId("ns3::Rip")
56 .SetGroupName("Internet")
57 .AddConstructor<Rip>()
58 .AddAttribute("UnsolicitedRoutingUpdate",
59 "The time between two Unsolicited Routing Updates.",
60 TimeValue(Seconds(30)),
63 .AddAttribute("StartupDelay",
64 "Maximum random delay for protocol startup (send route requests).",
68 .AddAttribute("TimeoutDelay",
69 "The delay to invalidate a route.",
70 TimeValue(Seconds(180)),
73 .AddAttribute("GarbageCollectionDelay",
74 "The delay to delete an expired route.",
75 TimeValue(Seconds(120)),
78 .AddAttribute("MinTriggeredCooldown",
79 "Min cooldown delay after a Triggered Update.",
83 .AddAttribute("MaxTriggeredCooldown",
84 "Max cooldown delay after a Triggered Update.",
88 .AddAttribute("SplitHorizon",
89 "Split Horizon strategy.",
93 "NoSplitHorizon",
95 "SplitHorizon",
97 "PoisonReverse"))
98 .AddAttribute("LinkDownValue",
99 "Value for link down in count to infinity.",
100 UintegerValue(16),
103 return tid;
104}
105
106int64_t
107Rip::AssignStreams(int64_t stream)
108{
109 NS_LOG_FUNCTION(this << stream);
110
111 m_rng->SetStream(stream);
112 return 1;
113}
114
115void
117{
118 NS_LOG_FUNCTION(this);
119
120 bool addedGlobal = false;
121
122 m_initialized = true;
123
124 Time delay =
125 m_unsolicitedUpdate + Seconds(m_rng->GetValue(0, 0.5 * m_unsolicitedUpdate.GetSeconds()));
127
128 for (uint32_t i = 0; i < m_ipv4->GetNInterfaces(); i++)
129 {
131 if (check)
132 {
133 continue;
134 }
135
136 bool activeInterface = false;
137 if (m_interfaceExclusions.find(i) == m_interfaceExclusions.end())
138 {
139 activeInterface = true;
140 m_ipv4->SetForwarding(i, true);
141 }
142
143 for (uint32_t j = 0; j < m_ipv4->GetNAddresses(i); j++)
144 {
145 Ipv4InterfaceAddress address = m_ipv4->GetAddress(i, j);
146 if (address.GetScope() != Ipv4InterfaceAddress::HOST && activeInterface)
147 {
148 NS_LOG_LOGIC("RIP: adding socket to " << address.GetLocal());
149 TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
150 Ptr<Node> theNode = GetObject<Node>();
151 Ptr<Socket> socket = Socket::CreateSocket(theNode, tid);
152 InetSocketAddress local = InetSocketAddress(address.GetLocal(), RIP_PORT);
153 socket->BindToNetDevice(m_ipv4->GetNetDevice(i));
154 int ret = socket->Bind(local);
155 NS_ASSERT_MSG(ret == 0, "Bind unsuccessful");
156
157 socket->SetRecvCallback(MakeCallback(&Rip::Receive, this));
158 socket->SetIpRecvTtl(true);
159 socket->SetRecvPktInfo(true);
160
161 m_unicastSocketList[socket] = i;
162 }
163 else if (m_ipv4->GetAddress(i, j).GetScope() == Ipv4InterfaceAddress::GLOBAL)
164 {
165 addedGlobal = true;
166 }
167 }
168 }
169
171 {
172 NS_LOG_LOGIC("RIP: adding receiving socket");
173 TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
174 Ptr<Node> theNode = GetObject<Node>();
177 m_multicastRecvSocket->Bind(local);
178 m_multicastRecvSocket->SetRecvCallback(MakeCallback(&Rip::Receive, this));
179 m_multicastRecvSocket->SetIpRecvTtl(true);
180 m_multicastRecvSocket->SetRecvPktInfo(true);
181 }
182
183 if (addedGlobal)
184 {
185 Time delay = Seconds(m_rng->GetValue(m_minTriggeredUpdateDelay.GetSeconds(),
186 m_maxTriggeredUpdateDelay.GetSeconds()));
188 }
189
190 delay = Seconds(m_rng->GetValue(0.01, m_startupDelay.GetSeconds()));
192
194}
195
198 const Ipv4Header& header,
199 Ptr<NetDevice> oif,
200 Socket::SocketErrno& sockerr)
201{
202 NS_LOG_FUNCTION(this << header << oif);
203
204 Ipv4Address destination = header.GetDestination();
205 Ptr<Ipv4Route> rtentry = nullptr;
206
207 if (destination.IsMulticast())
208 {
209 // Note: Multicast routes for outbound packets are stored in the
210 // normal unicast table. An implication of this is that it is not
211 // possible to source multicast datagrams on multiple interfaces.
212 // This is a well-known property of sockets implementation on
213 // many Unix variants.
214 // So, we just log it and fall through to LookupStatic ()
215 NS_LOG_LOGIC("RouteOutput (): Multicast destination");
216 }
217
218 rtentry = Lookup(destination, true, oif);
219 if (rtentry)
220 {
221 sockerr = Socket::ERROR_NOTERROR;
222 }
223 else
224 {
226 }
227 return rtentry;
228}
229
230bool
232 const Ipv4Header& header,
234 const UnicastForwardCallback& ucb,
235 const MulticastForwardCallback& mcb,
236 const LocalDeliverCallback& lcb,
237 const ErrorCallback& ecb)
238{
239 NS_LOG_FUNCTION(this << p << header << header.GetSource() << header.GetDestination() << idev);
240
242 // Check if input device supports IP
243 NS_ASSERT(m_ipv4->GetInterfaceForDevice(idev) >= 0);
244 uint32_t iif = m_ipv4->GetInterfaceForDevice(idev);
245 Ipv4Address dst = header.GetDestination();
246
247 if (m_ipv4->IsDestinationAddress(header.GetDestination(), iif))
248 {
249 if (!lcb.IsNull())
250 {
251 NS_LOG_LOGIC("Local delivery to " << header.GetDestination());
252 lcb(p, header, iif);
253 return true;
254 }
255 else
256 {
257 // The local delivery callback is null. This may be a multicast
258 // or broadcast packet, so return false so that another
259 // multicast routing protocol can handle it. It should be possible
260 // to extend this to explicitly check whether it is a unicast
261 // packet, and invoke the error callback if so
262 return false;
263 }
264 }
265
266 if (dst.IsMulticast())
267 {
268 NS_LOG_LOGIC("Multicast route not supported by RIP");
269 return false; // Let other routing protocols try to handle this
270 }
271
272 if (header.GetDestination().IsBroadcast())
273 {
274 NS_LOG_LOGIC("Dropping packet not for me and with dst Broadcast");
275 if (!ecb.IsNull())
276 {
277 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
278 }
279 return false;
280 }
281
282 // Check if input device supports IP forwarding
283 if (!m_ipv4->IsForwarding(iif))
284 {
285 NS_LOG_LOGIC("Forwarding disabled for this interface");
286 if (!ecb.IsNull())
287 {
288 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
289 }
290 return true;
291 }
292 // Next, try to find a route
293 NS_LOG_LOGIC("Unicast destination");
294 Ptr<Ipv4Route> rtentry = Lookup(header.GetDestination(), false);
295
296 if (rtentry)
297 {
298 NS_LOG_LOGIC("Found unicast destination - calling unicast callback");
299 ucb(rtentry, p, header); // unicast forwarding callback
300 return true;
301 }
302 else
303 {
304 NS_LOG_LOGIC("Did not find unicast destination - returning false");
305 return false; // Let other routing protocols try to handle this
306 }
307}
308
309void
311{
312 NS_LOG_FUNCTION(this << i);
313
315 if (check)
316 {
317 return;
318 }
319
320 for (uint32_t j = 0; j < m_ipv4->GetNAddresses(i); j++)
321 {
322 Ipv4InterfaceAddress address = m_ipv4->GetAddress(i, j);
323 Ipv4Mask networkMask = address.GetMask();
324 Ipv4Address networkAddress = address.GetLocal().CombineMask(networkMask);
325
326 if (address.GetScope() == Ipv4InterfaceAddress::GLOBAL)
327 {
328 AddNetworkRouteTo(networkAddress, networkMask, i);
329 }
330 }
331
332 if (!m_initialized)
333 {
334 return;
335 }
336
337 bool sendSocketFound = false;
338 for (auto iter = m_unicastSocketList.begin(); iter != m_unicastSocketList.end(); iter++)
339 {
340 if (iter->second == i)
341 {
342 sendSocketFound = true;
343 break;
344 }
345 }
346
347 bool activeInterface = false;
348 if (m_interfaceExclusions.find(i) == m_interfaceExclusions.end())
349 {
350 activeInterface = true;
351 m_ipv4->SetForwarding(i, true);
352 }
353
354 for (uint32_t j = 0; j < m_ipv4->GetNAddresses(i); j++)
355 {
356 Ipv4InterfaceAddress address = m_ipv4->GetAddress(i, j);
357
358 if (address.GetScope() != Ipv4InterfaceAddress::HOST && !sendSocketFound && activeInterface)
359 {
360 NS_LOG_LOGIC("RIP: adding sending socket to " << address.GetLocal());
361 TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
362 Ptr<Node> theNode = GetObject<Node>();
363 Ptr<Socket> socket = Socket::CreateSocket(theNode, tid);
364 InetSocketAddress local = InetSocketAddress(address.GetLocal(), RIP_PORT);
365 socket->BindToNetDevice(m_ipv4->GetNetDevice(i));
366 socket->Bind(local);
367 socket->SetRecvCallback(MakeCallback(&Rip::Receive, this));
368 socket->SetIpRecvTtl(true);
369 socket->SetRecvPktInfo(true);
370 m_unicastSocketList[socket] = i;
371 }
372 if (address.GetScope() == Ipv4InterfaceAddress::GLOBAL)
373 {
375 }
376 }
377
379 {
380 NS_LOG_LOGIC("RIP: adding receiving socket");
381 TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
382 Ptr<Node> theNode = GetObject<Node>();
385 m_multicastRecvSocket->Bind(local);
386 m_multicastRecvSocket->SetRecvCallback(MakeCallback(&Rip::Receive, this));
387 m_multicastRecvSocket->SetIpRecvTtl(true);
388 m_multicastRecvSocket->SetRecvPktInfo(true);
389 }
390}
391
392void
394{
395 NS_LOG_FUNCTION(this << interface);
396
397 /* remove all routes that are going through this interface */
398 for (auto it = m_routes.begin(); it != m_routes.end(); it++)
399 {
400 if (it->first->GetInterface() == interface)
401 {
402 InvalidateRoute(it->first);
403 }
404 }
405
406 for (auto iter = m_unicastSocketList.begin(); iter != m_unicastSocketList.end(); iter++)
407 {
408 NS_LOG_INFO("Checking socket for interface " << interface);
409 if (iter->second == interface)
410 {
411 NS_LOG_INFO("Removed socket for interface " << interface);
412 iter->first->Close();
413 m_unicastSocketList.erase(iter);
414 break;
415 }
416 }
417
418 if (m_interfaceExclusions.find(interface) == m_interfaceExclusions.end())
419 {
421 }
422}
423
424void
426{
427 NS_LOG_FUNCTION(this << interface << address);
428
429 if (!m_ipv4->IsUp(interface))
430 {
431 return;
432 }
433
434 if (m_interfaceExclusions.find(interface) != m_interfaceExclusions.end())
435 {
436 return;
437 }
438
439 Ipv4Address networkAddress = address.GetLocal().CombineMask(address.GetMask());
440 Ipv4Mask networkMask = address.GetMask();
441
442 if (address.GetScope() == Ipv4InterfaceAddress::GLOBAL)
443 {
444 AddNetworkRouteTo(networkAddress, networkMask, interface);
445 }
446
448}
449
450void
452{
453 NS_LOG_FUNCTION(this << interface << address);
454
455 if (!m_ipv4->IsUp(interface))
456 {
457 return;
458 }
459
460 if (address.GetScope() != Ipv4InterfaceAddress::GLOBAL)
461 {
462 return;
463 }
464
465 Ipv4Address networkAddress = address.GetLocal().CombineMask(address.GetMask());
466 Ipv4Mask networkMask = address.GetMask();
467
468 // Remove all routes that are going through this interface
469 // which reference this network
470 for (auto it = m_routes.begin(); it != m_routes.end(); it++)
471 {
472 if (it->first->GetInterface() == interface && it->first->IsNetwork() &&
473 it->first->GetDestNetwork() == networkAddress &&
474 it->first->GetDestNetworkMask() == networkMask)
475 {
476 InvalidateRoute(it->first);
477 }
478 }
479
480 if (m_interfaceExclusions.find(interface) == m_interfaceExclusions.end())
481 {
483 }
484}
485
486void
488{
489 NS_LOG_FUNCTION(this << ipv4);
490
491 NS_ASSERT(!m_ipv4 && ipv4);
492 uint32_t i = 0;
493 m_ipv4 = ipv4;
494
495 for (i = 0; i < m_ipv4->GetNInterfaces(); i++)
496 {
497 if (m_ipv4->IsUp(i))
498 {
500 }
501 else
502 {
504 }
505 }
506}
507
508void
510{
511 NS_LOG_FUNCTION(this << stream);
512
513 std::ostream* os = stream->GetStream();
514 // Copy the current ostream state
515 std::ios oldState(nullptr);
516 oldState.copyfmt(*os);
517
518 *os << std::resetiosflags(std::ios::adjustfield) << std::setiosflags(std::ios::left);
519
520 *os << "Node: " << m_ipv4->GetObject<Node>()->GetId() << ", Time: " << Now().As(unit)
521 << ", Local time: " << m_ipv4->GetObject<Node>()->GetLocalTime().As(unit)
522 << ", IPv4 RIP table" << std::endl;
523
524 if (!m_routes.empty())
525 {
526 *os << "Destination Gateway Genmask Flags Metric Ref Use Iface"
527 << std::endl;
528 for (auto it = m_routes.begin(); it != m_routes.end(); it++)
529 {
530 RipRoutingTableEntry* route = it->first;
532
534 {
535 std::ostringstream dest;
536 std::ostringstream gw;
537 std::ostringstream mask;
538 std::ostringstream flags;
539 dest << route->GetDest();
540 *os << std::setw(16) << dest.str();
541 gw << route->GetGateway();
542 *os << std::setw(16) << gw.str();
543 mask << route->GetDestNetworkMask();
544 *os << std::setw(16) << mask.str();
545 flags << "U";
546 if (route->IsHost())
547 {
548 flags << "HS";
549 }
550 else if (route->IsGateway())
551 {
552 flags << "GS";
553 }
554 *os << std::setw(6) << flags.str();
555 *os << std::setw(7) << int(route->GetRouteMetric());
556 // Ref ct not implemented
557 *os << "-"
558 << " ";
559 // Use not implemented
560 *os << "-"
561 << " ";
562 if (!Names::FindName(m_ipv4->GetNetDevice(route->GetInterface())).empty())
563 {
564 *os << Names::FindName(m_ipv4->GetNetDevice(route->GetInterface()));
565 }
566 else
567 {
568 *os << route->GetInterface();
569 }
570 *os << std::endl;
571 }
572 }
573 }
574 *os << std::endl;
575 // Restore the previous ostream state
576 (*os).copyfmt(oldState);
577}
578
579void
581{
582 NS_LOG_FUNCTION(this);
583
584 for (auto j = m_routes.begin(); j != m_routes.end(); j = m_routes.erase(j))
585 {
586 delete j->first;
587 }
588 m_routes.clear();
589
590 m_nextTriggeredUpdate.Cancel();
594
595 for (auto iter = m_unicastSocketList.begin(); iter != m_unicastSocketList.end(); iter++)
596 {
597 iter->first->Close();
598 }
599 m_unicastSocketList.clear();
600
601 m_multicastRecvSocket->Close();
602 m_multicastRecvSocket = nullptr;
603
604 m_ipv4 = nullptr;
605
607}
608
610Rip::Lookup(Ipv4Address dst, bool setSource, Ptr<NetDevice> interface)
611{
612 NS_LOG_FUNCTION(this << dst << interface);
613
614 Ptr<Ipv4Route> rtentry = nullptr;
615 uint16_t longestMask = 0;
616
617 /* when sending on local multicast, there have to be interface specified */
618 if (dst.IsLocalMulticast())
619 {
620 NS_ASSERT_MSG(interface,
621 "Try to send on local multicast address, and no interface index is given!");
622 rtentry = Create<Ipv4Route>();
623 rtentry->SetSource(
624 m_ipv4->SourceAddressSelection(m_ipv4->GetInterfaceForDevice(interface), dst));
625 rtentry->SetDestination(dst);
626 rtentry->SetGateway(Ipv4Address::GetZero());
627 rtentry->SetOutputDevice(interface);
628 return rtentry;
629 }
630
631 for (auto it = m_routes.begin(); it != m_routes.end(); it++)
632 {
633 RipRoutingTableEntry* j = it->first;
634
636 {
637 Ipv4Mask mask = j->GetDestNetworkMask();
638 uint16_t maskLen = mask.GetPrefixLength();
639 Ipv4Address entry = j->GetDestNetwork();
640
641 NS_LOG_LOGIC("Searching for route to " << dst << ", mask length " << maskLen);
642
643 if (mask.IsMatch(dst, entry))
644 {
645 NS_LOG_LOGIC("Found global network route " << j << ", mask length " << maskLen);
646
647 /* if interface is given, check the route will output on this interface */
648 if (!interface || interface == m_ipv4->GetNetDevice(j->GetInterface()))
649 {
650 if (maskLen < longestMask)
651 {
652 NS_LOG_LOGIC("Previous match longer, skipping");
653 continue;
654 }
655
656 longestMask = maskLen;
657
658 Ipv4RoutingTableEntry* route = j;
659 uint32_t interfaceIdx = route->GetInterface();
660 rtentry = Create<Ipv4Route>();
661
662 if (setSource)
663 {
664 if (route->GetDest().IsAny()) /* default route */
665 {
666 rtentry->SetSource(
667 m_ipv4->SourceAddressSelection(interfaceIdx, route->GetGateway()));
668 }
669 else
670 {
671 rtentry->SetSource(
672 m_ipv4->SourceAddressSelection(interfaceIdx, route->GetDest()));
673 }
674 }
675
676 rtentry->SetDestination(route->GetDest());
677 rtentry->SetGateway(route->GetGateway());
678 rtentry->SetOutputDevice(m_ipv4->GetNetDevice(interfaceIdx));
679 }
680 }
681 }
682 }
683
684 if (rtentry)
685 {
686 NS_LOG_LOGIC("Matching route via " << rtentry->GetDestination() << " (through "
687 << rtentry->GetGateway() << ") at the end");
688 }
689 return rtentry;
690}
691
692void
694 Ipv4Mask networkPrefix,
695 Ipv4Address nextHop,
696 uint32_t interface)
697{
698 NS_LOG_FUNCTION(this << network << networkPrefix << nextHop << interface);
699
700 auto route = new RipRoutingTableEntry(network, networkPrefix, nextHop, interface);
701 route->SetRouteMetric(1);
702 route->SetRouteStatus(RipRoutingTableEntry::RIP_VALID);
703 route->SetRouteChanged(true);
704
705 m_routes.emplace_back(route, EventId());
706}
707
708void
709Rip::AddNetworkRouteTo(Ipv4Address network, Ipv4Mask networkPrefix, uint32_t interface)
710{
711 NS_LOG_FUNCTION(this << network << networkPrefix << interface);
712
713 auto route = new RipRoutingTableEntry(network, networkPrefix, interface);
714 route->SetRouteMetric(1);
715 route->SetRouteStatus(RipRoutingTableEntry::RIP_VALID);
716 route->SetRouteChanged(true);
717
718 m_routes.emplace_back(route, EventId());
719}
720
721void
723{
724 NS_LOG_FUNCTION(this << *route);
725
726 for (auto it = m_routes.begin(); it != m_routes.end(); it++)
727 {
728 if (it->first == route)
729 {
732 route->SetRouteChanged(true);
733 if (it->second.IsPending())
734 {
735 it->second.Cancel();
736 }
737 it->second =
739 return;
740 }
741 }
742 NS_ABORT_MSG("RIP::InvalidateRoute - cannot find the route to update");
743}
744
745void
747{
748 NS_LOG_FUNCTION(this << *route);
749
750 for (auto it = m_routes.begin(); it != m_routes.end(); it++)
751 {
752 if (it->first == route)
753 {
754 delete route;
755 m_routes.erase(it);
756 return;
757 }
758 }
759 NS_ABORT_MSG("RIP::DeleteRoute - cannot find the route to delete");
760}
761
762void
764{
765 NS_LOG_FUNCTION(this << socket);
766
767 Address sender;
768 Ptr<Packet> packet = socket->RecvFrom(sender);
770 NS_LOG_INFO("Received " << *packet << " from " << senderAddr.GetIpv4() << ":"
771 << senderAddr.GetPort());
772
773 Ipv4Address senderAddress = senderAddr.GetIpv4();
774 uint16_t senderPort = senderAddr.GetPort();
775
776 if (socket == m_multicastRecvSocket)
777 {
778 NS_LOG_LOGIC("Received a packet from the multicast socket");
779 }
780 else
781 {
782 NS_LOG_LOGIC("Received a packet from one of the unicast sockets");
783 }
784
785 Ipv4PacketInfoTag interfaceInfo;
786 if (!packet->RemovePacketTag(interfaceInfo))
787 {
788 NS_ABORT_MSG("No incoming interface on RIP message, aborting.");
789 }
790 uint32_t incomingIf = interfaceInfo.GetRecvIf();
791 Ptr<Node> node = this->GetObject<Node>();
792 Ptr<NetDevice> dev = node->GetDevice(incomingIf);
793 uint32_t ipInterfaceIndex = m_ipv4->GetInterfaceForDevice(dev);
794
795 SocketIpTtlTag hoplimitTag;
796 if (!packet->RemovePacketTag(hoplimitTag))
797 {
798 NS_ABORT_MSG("No incoming Hop Count on RIP message, aborting.");
799 }
800 uint8_t hopLimit = hoplimitTag.GetTtl();
801
802 int32_t interfaceForAddress = m_ipv4->GetInterfaceForAddress(senderAddress);
803 if (interfaceForAddress != -1)
804 {
805 NS_LOG_LOGIC("Ignoring a packet sent by myself.");
806 return;
807 }
808
809 RipHeader hdr;
810 packet->RemoveHeader(hdr);
811
812 if (hdr.GetCommand() == RipHeader::RESPONSE)
813 {
814 NS_LOG_LOGIC("The message is a Response from " << senderAddr.GetIpv4() << ":"
815 << senderAddr.GetPort());
816 HandleResponses(hdr, senderAddress, ipInterfaceIndex, hopLimit);
817 }
818 else if (hdr.GetCommand() == RipHeader::REQUEST)
819 {
820 NS_LOG_LOGIC("The message is a Request from " << senderAddr.GetIpv4() << ":"
821 << senderAddr.GetPort());
822 HandleRequests(hdr, senderAddress, senderPort, ipInterfaceIndex, hopLimit);
823 }
824 else
825 {
826 NS_LOG_LOGIC("Ignoring message with unknown command: " << int(hdr.GetCommand()));
827 }
828}
829
830void
832 Ipv4Address senderAddress,
833 uint16_t senderPort,
834 uint32_t incomingInterface,
835 uint8_t hopLimit)
836{
837 NS_LOG_FUNCTION(this << senderAddress << int(senderPort) << incomingInterface << int(hopLimit)
838 << requestHdr);
839
840 std::list<RipRte> rtes = requestHdr.GetRteList();
841
842 if (rtes.empty())
843 {
844 return;
845 }
846
847 // check if it's a request for the full table from a neighbor
848 if (rtes.size() == 1)
849 {
850 if (rtes.begin()->GetPrefix() == Ipv4Address::GetAny() &&
851 rtes.begin()->GetSubnetMask().GetPrefixLength() == 0 &&
852 rtes.begin()->GetRouteMetric() == m_linkDown)
853 {
854 // Output whole thing. Use Split Horizon
855 if (m_interfaceExclusions.find(incomingInterface) == m_interfaceExclusions.end())
856 {
857 // we use one of the sending sockets, as they're bound to the right interface
858 // and the local address might be used on different interfaces.
859 Ptr<Socket> sendingSocket;
860 for (auto iter = m_unicastSocketList.begin(); iter != m_unicastSocketList.end();
861 iter++)
862 {
863 if (iter->second == incomingInterface)
864 {
865 sendingSocket = iter->first;
866 }
867 }
868 NS_ASSERT_MSG(sendingSocket,
869 "HandleRequest - Impossible to find a socket to send the reply");
870
871 uint16_t mtu = m_ipv4->GetMtu(incomingInterface);
872 uint16_t maxRte =
876
878 SocketIpTtlTag tag;
879 p->RemovePacketTag(tag);
880 if (senderAddress == Ipv4Address(RIP_ALL_NODE))
881 {
882 tag.SetTtl(1);
883 }
884 else
885 {
886 tag.SetTtl(255);
887 }
888 p->AddPacketTag(tag);
889
890 RipHeader hdr;
892
893 for (auto rtIter = m_routes.begin(); rtIter != m_routes.end(); rtIter++)
894 {
895 bool splitHorizoning = (rtIter->first->GetInterface() == incomingInterface);
896
897 Ipv4InterfaceAddress rtDestAddr =
898 Ipv4InterfaceAddress(rtIter->first->GetDestNetwork(),
899 rtIter->first->GetDestNetworkMask());
900
901 bool isGlobal = (rtDestAddr.GetScope() == Ipv4InterfaceAddress::GLOBAL);
902 bool isDefaultRoute =
903 ((rtIter->first->GetDestNetwork() == Ipv4Address::GetAny()) &&
904 (rtIter->first->GetDestNetworkMask() == Ipv4Mask::GetZero()) &&
905 (rtIter->first->GetInterface() != incomingInterface));
906
907 if ((isGlobal || isDefaultRoute) &&
908 (rtIter->first->GetRouteStatus() == RipRoutingTableEntry::RIP_VALID))
909 {
910 RipRte rte;
911 rte.SetPrefix(rtIter->first->GetDestNetwork());
912 rte.SetSubnetMask(rtIter->first->GetDestNetworkMask());
913 if (m_splitHorizonStrategy == POISON_REVERSE && splitHorizoning)
914 {
916 }
917 else
918 {
919 rte.SetRouteMetric(rtIter->first->GetRouteMetric());
920 }
921 rte.SetRouteTag(rtIter->first->GetRouteTag());
923 (m_splitHorizonStrategy == SPLIT_HORIZON && !splitHorizoning))
924 {
925 hdr.AddRte(rte);
926 }
927 }
928 if (hdr.GetRteNumber() == maxRte)
929 {
930 p->AddHeader(hdr);
931 NS_LOG_DEBUG("SendTo: " << *p);
932 sendingSocket->SendTo(p, 0, InetSocketAddress(senderAddress, RIP_PORT));
933 p->RemoveHeader(hdr);
934 hdr.ClearRtes();
935 }
936 }
937 if (hdr.GetRteNumber() > 0)
938 {
939 p->AddHeader(hdr);
940 NS_LOG_DEBUG("SendTo: " << *p);
941 sendingSocket->SendTo(p, 0, InetSocketAddress(senderAddress, RIP_PORT));
942 }
943 }
944 }
945 }
946 else
947 {
948 // note: we got the request as a single packet, so no check is necessary for MTU limit
949
951 SocketIpTtlTag tag;
952 p->RemovePacketTag(tag);
953 if (senderAddress == Ipv4Address(RIP_ALL_NODE))
954 {
955 tag.SetTtl(1);
956 }
957 else
958 {
959 tag.SetTtl(255);
960 }
961 p->AddPacketTag(tag);
962
963 RipHeader hdr;
965
966 for (auto iter = rtes.begin(); iter != rtes.end(); iter++)
967 {
968 bool found = false;
969 for (auto rtIter = m_routes.begin(); rtIter != m_routes.end(); rtIter++)
970 {
971 Ipv4InterfaceAddress rtDestAddr =
972 Ipv4InterfaceAddress(rtIter->first->GetDestNetwork(),
973 rtIter->first->GetDestNetworkMask());
974 if ((rtDestAddr.GetScope() == Ipv4InterfaceAddress::GLOBAL) &&
975 (rtIter->first->GetRouteStatus() == RipRoutingTableEntry::RIP_VALID))
976 {
977 Ipv4Address requestedAddress = iter->GetPrefix();
978 requestedAddress.CombineMask(iter->GetSubnetMask());
979 Ipv4Address rtAddress = rtIter->first->GetDestNetwork();
980 rtAddress.CombineMask(rtIter->first->GetDestNetworkMask());
981
982 if (requestedAddress == rtAddress)
983 {
984 iter->SetRouteMetric(rtIter->first->GetRouteMetric());
985 iter->SetRouteTag(rtIter->first->GetRouteTag());
986 hdr.AddRte(*iter);
987 found = true;
988 break;
989 }
990 }
991 }
992 if (!found)
993 {
994 iter->SetRouteMetric(m_linkDown);
995 iter->SetRouteTag(0);
996 hdr.AddRte(*iter);
997 }
998 }
999 p->AddHeader(hdr);
1000 NS_LOG_DEBUG("SendTo: " << *p);
1001 m_multicastRecvSocket->SendTo(p, 0, InetSocketAddress(senderAddress, senderPort));
1002 }
1003}
1004
1005void
1007 Ipv4Address senderAddress,
1008 uint32_t incomingInterface,
1009 uint8_t hopLimit)
1010{
1011 NS_LOG_FUNCTION(this << senderAddress << incomingInterface << int(hopLimit) << hdr);
1012
1013 if (m_interfaceExclusions.find(incomingInterface) != m_interfaceExclusions.end())
1014 {
1016 "Ignoring an update message from an excluded interface: " << incomingInterface);
1017 return;
1018 }
1019
1020 std::list<RipRte> rtes = hdr.GetRteList();
1021
1022 // validate the RTEs before processing
1023 for (auto iter = rtes.begin(); iter != rtes.end(); iter++)
1024 {
1025 if (iter->GetRouteMetric() == 0 || iter->GetRouteMetric() > m_linkDown)
1026 {
1027 NS_LOG_LOGIC("Ignoring an update message with malformed metric: "
1028 << int(iter->GetRouteMetric()));
1029 return;
1030 }
1031 if (iter->GetPrefix().IsLocalhost() || iter->GetPrefix().IsBroadcast() ||
1032 iter->GetPrefix().IsMulticast())
1033 {
1034 NS_LOG_LOGIC("Ignoring an update message with wrong prefixes: " << iter->GetPrefix());
1035 return;
1036 }
1037 }
1038
1039 bool changed = false;
1040
1041 for (auto iter = rtes.begin(); iter != rtes.end(); iter++)
1042 {
1043 Ipv4Mask rtePrefixMask = iter->GetSubnetMask();
1044 Ipv4Address rteAddr = iter->GetPrefix().CombineMask(rtePrefixMask);
1045
1046 NS_LOG_LOGIC("Processing RTE " << *iter);
1047
1048 uint32_t interfaceMetric = 1;
1049 if (m_interfaceMetrics.find(incomingInterface) != m_interfaceMetrics.end())
1050 {
1051 interfaceMetric = m_interfaceMetrics[incomingInterface];
1052 }
1053 uint64_t rteMetric = iter->GetRouteMetric() + interfaceMetric;
1054 if (rteMetric > m_linkDown)
1055 {
1056 rteMetric = m_linkDown;
1057 }
1058
1059 RoutesI it;
1060 bool found = false;
1061 for (it = m_routes.begin(); it != m_routes.end(); it++)
1062 {
1063 if (it->first->GetDestNetwork() == rteAddr &&
1064 it->first->GetDestNetworkMask() == rtePrefixMask)
1065 {
1066 found = true;
1067 if (rteMetric < it->first->GetRouteMetric())
1068 {
1069 if (senderAddress != it->first->GetGateway())
1070 {
1071 auto route = new RipRoutingTableEntry(rteAddr,
1072 rtePrefixMask,
1073 senderAddress,
1074 incomingInterface);
1075 delete it->first;
1076 it->first = route;
1077 }
1078 it->first->SetRouteMetric(rteMetric);
1079 it->first->SetRouteStatus(RipRoutingTableEntry::RIP_VALID);
1080 it->first->SetRouteTag(iter->GetRouteTag());
1081 it->first->SetRouteChanged(true);
1082 it->second.Cancel();
1083 it->second =
1085 changed = true;
1086 }
1087 else if (rteMetric == it->first->GetRouteMetric())
1088 {
1089 if (senderAddress == it->first->GetGateway())
1090 {
1091 it->second.Cancel();
1094 this,
1095 it->first);
1096 }
1097 else
1098 {
1099 if (Simulator::GetDelayLeft(it->second) < m_timeoutDelay / 2)
1100 {
1101 auto route = new RipRoutingTableEntry(rteAddr,
1102 rtePrefixMask,
1103 senderAddress,
1104 incomingInterface);
1105 route->SetRouteMetric(rteMetric);
1106 route->SetRouteStatus(RipRoutingTableEntry::RIP_VALID);
1107 route->SetRouteTag(iter->GetRouteTag());
1108 route->SetRouteChanged(true);
1109 delete it->first;
1110 it->first = route;
1111 it->second.Cancel();
1114 this,
1115 route);
1116 changed = true;
1117 }
1118 }
1119 }
1120 else if (rteMetric > it->first->GetRouteMetric() &&
1121 senderAddress == it->first->GetGateway())
1122 {
1123 it->second.Cancel();
1124 if (rteMetric < m_linkDown)
1125 {
1126 it->first->SetRouteMetric(rteMetric);
1127 it->first->SetRouteStatus(RipRoutingTableEntry::RIP_VALID);
1128 it->first->SetRouteTag(iter->GetRouteTag());
1129 it->first->SetRouteChanged(true);
1130 it->second.Cancel();
1133 this,
1134 it->first);
1135 }
1136 else
1137 {
1138 InvalidateRoute(it->first);
1139 }
1140 changed = true;
1141 }
1142 }
1143 }
1144 if (!found && rteMetric != m_linkDown)
1145 {
1146 NS_LOG_LOGIC("Received a RTE with new route, adding.");
1147
1148 auto route =
1149 new RipRoutingTableEntry(rteAddr, rtePrefixMask, senderAddress, incomingInterface);
1150 route->SetRouteMetric(rteMetric);
1151 route->SetRouteStatus(RipRoutingTableEntry::RIP_VALID);
1152 route->SetRouteChanged(true);
1153 m_routes.emplace_front(route, EventId());
1154 EventId invalidateEvent =
1156 (m_routes.begin())->second = invalidateEvent;
1157 changed = true;
1158 }
1159 }
1160
1161 if (changed)
1162 {
1164 }
1165}
1166
1167void
1169{
1170 NS_LOG_FUNCTION(this << (periodic ? " periodic" : " triggered"));
1171
1172 for (auto iter = m_unicastSocketList.begin(); iter != m_unicastSocketList.end(); iter++)
1173 {
1174 uint32_t interface = iter->second;
1175
1176 if (m_interfaceExclusions.find(interface) == m_interfaceExclusions.end())
1177 {
1178 uint16_t mtu = m_ipv4->GetMtu(interface);
1179 uint16_t maxRte = (mtu - Ipv4Header().GetSerializedSize() -
1182
1184 SocketIpTtlTag tag;
1185 tag.SetTtl(1);
1186 p->AddPacketTag(tag);
1187
1188 RipHeader hdr;
1190
1191 for (auto rtIter = m_routes.begin(); rtIter != m_routes.end(); rtIter++)
1192 {
1193 bool splitHorizoning = (rtIter->first->GetInterface() == interface);
1194 Ipv4InterfaceAddress rtDestAddr =
1195 Ipv4InterfaceAddress(rtIter->first->GetDestNetwork(),
1196 rtIter->first->GetDestNetworkMask());
1197
1198 NS_LOG_DEBUG("Processing RT " << rtDestAddr << " "
1199 << int(rtIter->first->IsRouteChanged()));
1200
1201 bool isGlobal = (rtDestAddr.GetScope() == Ipv4InterfaceAddress::GLOBAL);
1202 bool isDefaultRoute =
1203 ((rtIter->first->GetDestNetwork() == Ipv4Address::GetAny()) &&
1204 (rtIter->first->GetDestNetworkMask() == Ipv4Mask::GetZero()) &&
1205 (rtIter->first->GetInterface() != interface));
1206
1207 bool sameNetwork = false;
1208 for (uint32_t index = 0; index < m_ipv4->GetNAddresses(interface); index++)
1209 {
1210 Ipv4InterfaceAddress addr = m_ipv4->GetAddress(interface, index);
1211 if (addr.GetLocal().CombineMask(addr.GetMask()) ==
1212 rtIter->first->GetDestNetwork())
1213 {
1214 sameNetwork = true;
1215 }
1216 }
1217
1218 if ((isGlobal || isDefaultRoute) && (periodic || rtIter->first->IsRouteChanged()) &&
1219 !sameNetwork)
1220 {
1221 RipRte rte;
1222 rte.SetPrefix(rtIter->first->GetDestNetwork());
1223 rte.SetSubnetMask(rtIter->first->GetDestNetworkMask());
1224 if (m_splitHorizonStrategy == POISON_REVERSE && splitHorizoning)
1225 {
1227 }
1228 else
1229 {
1230 rte.SetRouteMetric(rtIter->first->GetRouteMetric());
1231 }
1232 rte.SetRouteTag(rtIter->first->GetRouteTag());
1233 if ((m_splitHorizonStrategy == SPLIT_HORIZON && !splitHorizoning) ||
1235 {
1236 hdr.AddRte(rte);
1237 }
1238 }
1239 if (hdr.GetRteNumber() == maxRte)
1240 {
1241 p->AddHeader(hdr);
1242 NS_LOG_DEBUG("SendTo: " << *p);
1243 iter->first->SendTo(p, 0, InetSocketAddress(RIP_ALL_NODE, RIP_PORT));
1244 p->RemoveHeader(hdr);
1245 hdr.ClearRtes();
1246 }
1247 }
1248 if (hdr.GetRteNumber() > 0)
1249 {
1250 p->AddHeader(hdr);
1251 NS_LOG_DEBUG("SendTo: " << *p);
1252 iter->first->SendTo(p, 0, InetSocketAddress(RIP_ALL_NODE, RIP_PORT));
1253 }
1254 }
1255 }
1256 for (auto rtIter = m_routes.begin(); rtIter != m_routes.end(); rtIter++)
1257 {
1258 rtIter->first->SetRouteChanged(false);
1259 }
1260}
1261
1262void
1264{
1265 NS_LOG_FUNCTION(this);
1266
1267 if (m_nextTriggeredUpdate.IsPending())
1268 {
1269 NS_LOG_LOGIC("Skipping Triggered Update due to cooldown");
1270 return;
1271 }
1272
1273 // DoSendRouteUpdate (false);
1274
1275 // note: The RFC states:
1276 // After a triggered
1277 // update is sent, a timer should be set for a random interval between 1
1278 // and 5 seconds. If other changes that would trigger updates occur
1279 // before the timer expires, a single update is triggered when the timer
1280 // expires. The timer is then reset to another random value between 1
1281 // and 5 seconds. Triggered updates may be suppressed if a regular
1282 // update is due by the time the triggered update would be sent.
1283 // Here we rely on this:
1284 // When an update occurs (either Triggered or Periodic) the "IsChanged ()"
1285 // route field will be cleared.
1286 // Hence, the following Triggered Update will be fired, but will not send
1287 // any route update.
1288
1289 Time delay = Seconds(m_rng->GetValue(m_minTriggeredUpdateDelay.GetSeconds(),
1290 m_maxTriggeredUpdateDelay.GetSeconds()));
1292}
1293
1294void
1296{
1297 NS_LOG_FUNCTION(this);
1298
1299 if (m_nextTriggeredUpdate.IsPending())
1300 {
1301 m_nextTriggeredUpdate.Cancel();
1302 }
1303
1304 DoSendRouteUpdate(true);
1305
1306 Time delay =
1307 m_unsolicitedUpdate + Seconds(m_rng->GetValue(0, 0.5 * m_unsolicitedUpdate.GetSeconds()));
1309}
1310
1311std::set<uint32_t>
1316
1317void
1318Rip::SetInterfaceExclusions(std::set<uint32_t> exceptions)
1319{
1320 NS_LOG_FUNCTION(this);
1321
1322 m_interfaceExclusions = exceptions;
1323}
1324
1325uint8_t
1327{
1328 NS_LOG_FUNCTION(this << interface);
1329
1330 auto iter = m_interfaceMetrics.find(interface);
1331 if (iter != m_interfaceMetrics.end())
1332 {
1333 return iter->second;
1334 }
1335 return 1;
1336}
1337
1338void
1339Rip::SetInterfaceMetric(uint32_t interface, uint8_t metric)
1340{
1341 NS_LOG_FUNCTION(this << interface << int(metric));
1342
1343 if (metric < m_linkDown)
1344 {
1345 m_interfaceMetrics[interface] = metric;
1346 }
1347}
1348
1349void
1351{
1352 NS_LOG_FUNCTION(this);
1353
1355 SocketIpTtlTag tag;
1356 p->RemovePacketTag(tag);
1357 tag.SetTtl(1);
1358 p->AddPacketTag(tag);
1359
1360 RipHeader hdr;
1362
1363 RipRte rte;
1367
1368 hdr.AddRte(rte);
1369 p->AddHeader(hdr);
1370
1371 for (auto iter = m_unicastSocketList.begin(); iter != m_unicastSocketList.end(); iter++)
1372 {
1373 uint32_t interface = iter->second;
1374
1375 if (m_interfaceExclusions.find(interface) == m_interfaceExclusions.end())
1376 {
1377 NS_LOG_DEBUG("SendTo: " << *p);
1378 iter->first->SendTo(p, 0, InetSocketAddress(RIP_ALL_NODE, RIP_PORT));
1379 }
1380 }
1381}
1382
1383void
1385{
1386 NS_LOG_FUNCTION(this << interface);
1387
1388 AddNetworkRouteTo(Ipv4Address("0.0.0.0"), Ipv4Mask::GetZero(), nextHop, interface);
1389}
1390
1391/*
1392 * RipRoutingTableEntry
1393 */
1394
1396 : m_tag(0),
1397 m_metric(0),
1399 m_changed(false)
1400{
1401}
1402
1404 Ipv4Mask networkPrefix,
1405 Ipv4Address nextHop,
1406 uint32_t interface)
1408 Ipv4RoutingTableEntry::CreateNetworkRouteTo(network, networkPrefix, nextHop, interface)),
1409 m_tag(0),
1410 m_metric(0),
1412 m_changed(false)
1413{
1414}
1415
1417 Ipv4Mask networkPrefix,
1418 uint32_t interface)
1420 Ipv4RoutingTableEntry::CreateNetworkRouteTo(network, networkPrefix, interface)),
1421 m_tag(0),
1422 m_metric(0),
1424 m_changed(false)
1425{
1426}
1427
1431
1432void
1434{
1435 if (m_tag != routeTag)
1436 {
1437 m_tag = routeTag;
1438 m_changed = true;
1439 }
1440}
1441
1442uint16_t
1444{
1445 return m_tag;
1446}
1447
1448void
1450{
1451 if (m_metric != routeMetric)
1452 {
1453 m_metric = routeMetric;
1454 m_changed = true;
1455 }
1456}
1457
1458uint8_t
1460{
1461 return m_metric;
1462}
1463
1464void
1466{
1467 if (m_status != status)
1468 {
1469 m_status = status;
1470 m_changed = true;
1471 }
1472}
1473
1476{
1477 return m_status;
1478}
1479
1480void
1482{
1483 m_changed = changed;
1484}
1485
1486bool
1488{
1489 return m_changed;
1490}
1491
1492std::ostream&
1493operator<<(std::ostream& os, const RipRoutingTableEntry& rte)
1494{
1495 os << static_cast<const Ipv4RoutingTableEntry&>(rte);
1496 os << ", metric: " << int(rte.GetRouteMetric()) << ", tag: " << int(rte.GetRouteTag());
1497
1498 return os;
1499}
1500
1501} // namespace ns3
a polymophic address class
Definition address.h:90
bool IsNull() const
Check for null implementation.
Definition callback.h:555
Hold variables of type enum.
Definition enum.h:52
An identifier for simulation events.
Definition event-id.h:45
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.
bool IsMulticast() const
static Ipv4Address GetZero()
Ipv4Address CombineMask(const Ipv4Mask &mask) const
Combine this address with a network mask.
bool IsAny() const
bool IsBroadcast() const
static Ipv4Address GetAny()
bool IsLocalMulticast() const
Packet header for IPv4.
Definition ipv4-header.h:23
Ipv4Address GetSource() const
Ipv4Address GetDestination() const
uint32_t GetSerializedSize() const override
a class to store IPv4 address information on an interface
Ipv4Mask GetMask() const
Get the network mask.
Ipv4InterfaceAddress::InterfaceAddressScope_e GetScope() const
Get address scope.
Ipv4Address GetLocal() const
Get the local address.
a class to represent an Ipv4 address mask
uint16_t GetPrefixLength() const
bool IsMatch(Ipv4Address a, Ipv4Address b) const
static Ipv4Mask GetZero()
This class implements Linux struct pktinfo in order to deliver ancillary information to the socket in...
uint32_t GetRecvIf() const
Get the tag's receiving interface.
Abstract base class for IPv4 routing protocols.
Callback< void, Ptr< Ipv4MulticastRoute >, Ptr< const Packet >, const Ipv4Header & > MulticastForwardCallback
Callback for multicast packets to be forwarded.
Callback< void, Ptr< const Packet >, const Ipv4Header &, uint32_t > LocalDeliverCallback
Callback for packets to be locally delivered.
Callback< void, Ptr< Ipv4Route >, Ptr< const Packet >, const Ipv4Header & > UnicastForwardCallback
Callback for unicast packets to be forwarded.
Callback< void, Ptr< const Packet >, const Ipv4Header &, Socket::SocketErrno > ErrorCallback
Callback for routing errors (e.g., no route found)
A record of an IPv4 routing table entry for Ipv4GlobalRouting and Ipv4StaticRouting.
Ipv4Address GetDest() const
Ipv4Address GetGateway() const
bool IsHost() const
Ipv4RoutingTableEntry()
This constructor does nothing.
bool IsGateway() const
Ipv4Address GetDestNetwork() const
uint32_t GetInterface() const
static Ipv4RoutingTableEntry CreateNetworkRouteTo(Ipv4Address network, Ipv4Mask networkMask, Ipv4Address nextHop, uint32_t interface)
Ipv4Mask GetDestNetworkMask() const
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and,...
Definition names.cc:818
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.
Definition ptr.h:66
RipHeader - see RFC 2453
Definition rip-header.h:147
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
uint16_t GetRteNumber() const
Get the number of RTE included in the message.
void AddRte(RipRte rte)
Add a RTE to the message.
void SetCommand(Command_e command)
Set the command.
void ClearRtes()
Clear all the RTEs from the header.
std::list< RipRte > GetRteList() const
Get the list of the RTEs included in the message.
Command_e GetCommand() const
Get the command.
void SetInterfaceMetric(uint32_t interface, uint8_t metric)
Set the metric for an interface.
Definition rip.cc:1339
void DoSendRouteUpdate(bool periodic)
Send Routing Updates on all interfaces.
Definition rip.cc:1168
void DoDispose() override
Dispose this object.
Definition rip.cc:580
SplitHorizonType_e m_splitHorizonStrategy
Split Horizon strategy.
Definition rip.h:413
Ptr< Ipv4Route > Lookup(Ipv4Address dest, bool setSource, Ptr< NetDevice >=nullptr)
Lookup in the forwarding table for destination.
Definition rip.cc:610
Rip()
Definition rip.cc:38
Time m_startupDelay
Random delay before protocol startup.
Definition rip.h:385
void NotifyInterfaceDown(uint32_t interface) override
Definition rip.cc:393
std::map< uint32_t, uint8_t > m_interfaceMetrics
Map of interface metrics.
Definition rip.h:411
std::set< uint32_t > m_interfaceExclusions
Set of excluded interfaces.
Definition rip.h:410
std::list< std::pair< RipRoutingTableEntry *, EventId > >::iterator RoutesI
Iterator for container for the network routes.
Definition rip.h:273
uint32_t m_linkDown
Link down value.
Definition rip.h:416
void HandleRequests(RipHeader hdr, Ipv4Address senderAddress, uint16_t senderPort, uint32_t incomingInterface, uint8_t hopLimit)
Handle RIP requests.
Definition rip.cc:831
void DeleteRoute(RipRoutingTableEntry *route)
Delete a route.
Definition rip.cc:746
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)
Definition rip.cc:231
void InvalidateRoute(RipRoutingTableEntry *route)
Invalidate a route.
Definition rip.cc:722
void Receive(Ptr< Socket > socket)
Receive RIP packets.
Definition rip.cc:763
void NotifyInterfaceUp(uint32_t interface) override
Definition rip.cc:310
EventId m_nextUnsolicitedUpdate
Next Unsolicited Update event.
Definition rip.h:405
void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const override
Print the Routing Table entries.
Definition rip.cc:509
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Definition rip.cc:107
~Rip() override
Definition rip.cc:46
EventId m_nextTriggeredUpdate
Next Triggered Update event.
Definition rip.h:406
Ptr< Ipv4 > m_ipv4
IPv4 reference.
Definition rip.h:384
void DoInitialize() override
Start protocol operation.
Definition rip.cc:116
void SendRouteRequest()
Send Routing Request on all interfaces.
Definition rip.cc:1350
Time m_timeoutDelay
Delay before invalidating a route.
Definition rip.h:389
void AddNetworkRouteTo(Ipv4Address network, Ipv4Mask networkPrefix, Ipv4Address nextHop, uint32_t interface)
Add route to network.
Definition rip.cc:693
Ptr< Socket > m_multicastRecvSocket
multicast receive socket
Definition rip.h:403
Time m_minTriggeredUpdateDelay
Min cooldown delay after a Triggered Update.
Definition rip.h:386
@ SPLIT_HORIZON
Split Horizon.
Definition rip.h:203
@ NO_SPLIT_HORIZON
No Split Horizon.
Definition rip.h:202
@ POISON_REVERSE
Poison Reverse Split Horizon.
Definition rip.h:204
Time m_unsolicitedUpdate
time between two Unsolicited Routing Updates
Definition rip.h:388
std::set< uint32_t > GetInterfaceExclusions() const
Get the set of interface excluded from the protocol.
Definition rip.cc:1312
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.
Definition rip.cc:197
uint8_t GetInterfaceMetric(uint32_t interface) const
Get the metric for an interface.
Definition rip.cc:1326
void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address) override
Definition rip.cc:451
void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address) override
Definition rip.cc:425
SocketList m_unicastSocketList
list of sockets for unicast messages (socket, interface index)
Definition rip.h:402
Time m_garbageCollectionDelay
Delay before deleting an INVALID route.
Definition rip.h:390
void SetIpv4(Ptr< Ipv4 > ipv4) override
Definition rip.cc:487
static TypeId GetTypeId()
Get the type ID.
Definition rip.cc:51
bool m_initialized
flag to allow socket's late-creation.
Definition rip.h:415
void SetInterfaceExclusions(std::set< uint32_t > exceptions)
Set the set of interface excluded from the protocol.
Definition rip.cc:1318
void AddDefaultRouteTo(Ipv4Address nextHop, uint32_t interface)
Add a default route to the router through the nextHop located on interface.
Definition rip.cc:1384
Routes m_routes
the forwarding table for network.
Definition rip.h:383
Time m_maxTriggeredUpdateDelay
Max cooldown delay after a Triggered Update.
Definition rip.h:387
void SendTriggeredRouteUpdate()
Send Triggered Routing Updates on all interfaces.
Definition rip.cc:1263
void SendUnsolicitedRouteUpdate()
Send Unsolicited Routing Updates on all interfaces.
Definition rip.cc:1295
void HandleResponses(RipHeader hdr, Ipv4Address senderAddress, uint32_t incomingInterface, uint8_t hopLimit)
Handle RIP responses.
Definition rip.cc:1006
Ptr< UniformRandomVariable > m_rng
Rng stream.
Definition rip.h:408
Rip Routing Table Entry.
Definition rip.h:54
void SetRouteMetric(uint8_t routeMetric)
Set the route metric.
Definition rip.cc:1449
Status_e m_status
route status
Definition rip.h:146
RipRoutingTableEntry()
Definition rip.cc:1395
bool m_changed
route has been updated
Definition rip.h:147
void SetRouteStatus(Status_e status)
Set the route status.
Definition rip.cc:1465
Status_e
Route status.
Definition rip.h:60
@ RIP_INVALID
Definition rip.h:62
@ RIP_VALID
Definition rip.h:61
bool IsRouteChanged() const
Get the route changed status.
Definition rip.cc:1487
Status_e GetRouteStatus() const
Get the route status.
Definition rip.cc:1475
uint8_t GetRouteMetric() const
Get the route metric.
Definition rip.cc:1459
void SetRouteTag(uint16_t routeTag)
Set the route tag.
Definition rip.cc:1433
uint16_t GetRouteTag() const
Get the route tag.
Definition rip.cc:1443
void SetRouteChanged(bool changed)
Set the route as changed.
Definition rip.cc:1481
uint8_t m_metric
route metric
Definition rip.h:145
virtual ~RipRoutingTableEntry()
Definition rip.cc:1428
uint16_t m_tag
route tag
Definition rip.h:144
Rip v2 Routing Table Entry (RTE) - see RFC 2453.
Definition rip-header.h:28
void SetSubnetMask(Ipv4Mask subnetMask)
Set the subnet mask.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
Definition rip-header.cc:53
void SetRouteMetric(uint32_t routeMetric)
Set the route metric.
void SetPrefix(Ipv4Address prefix)
Set the prefix.
Definition rip-header.cc:92
void SetRouteTag(uint16_t routeTag)
Set the route tag.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:561
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition simulator.cc:206
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
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:403
Unit
The unit to use to interpret a number representing time.
Definition nstime.h:100
a unique identifier for an interface.
Definition type-id.h:49
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition type-id.cc:872
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Packet header for UDP packets.
Definition udp-header.h:30
uint32_t GetSerializedSize() const override
Hold an unsigned integer type.
Definition uinteger.h:34
#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
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#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_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#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:436
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition simulator.cc:294
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1345
-style-clang-format
Definition first.py:1
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition nstime.h:1433
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< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition uinteger.h:35
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition enum.h:179
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Definition enum.h:221
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1453
#define RIP_ALL_NODE
Definition rip.cc:28
#define RIP_PORT
Definition rip.cc:29