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
39 : m_ipv4(nullptr),
40 m_splitHorizonStrategy(Rip::POISON_REVERSE),
41 m_initialized(false)
42{
44}
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 =
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 }
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>();
181 }
182
183 if (addedGlobal)
184 {
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
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>();
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 {
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
594
595 for (auto iter = m_unicastSocketList.begin(); iter != m_unicastSocketList.end(); iter++)
596 {
597 iter->first->Close();
598 }
599 m_unicastSocketList.clear();
600
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(
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
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
1292}
1293
1294void
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),
1398 m_status(RIP_INVALID),
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),
1411 m_status(RIP_INVALID),
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),
1423 m_status(RIP_INVALID),
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
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition event-id.cc:44
bool IsPending() const
This method is syntactic sugar for !IsExpired().
Definition event-id.cc:65
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
virtual int32_t GetInterfaceForAddress(Ipv4Address address) const =0
Return the interface number of the interface that has been assigned the specified IP address.
virtual bool IsForwarding(uint32_t interface) const =0
virtual uint32_t GetNAddresses(uint32_t interface) const =0
virtual uint16_t GetMtu(uint32_t interface) const =0
virtual Ipv4InterfaceAddress GetAddress(uint32_t interface, uint32_t addressIndex) const =0
Because addresses can be removed, the addressIndex is not guaranteed to be static across calls to thi...
virtual Ptr< NetDevice > GetNetDevice(uint32_t interface)=0
virtual bool IsDestinationAddress(Ipv4Address address, uint32_t iif) const =0
Determine whether address and interface corresponding to received packet can be accepted for local de...
virtual int32_t GetInterfaceForDevice(Ptr< const NetDevice > device) const =0
virtual Ipv4Address SourceAddressSelection(uint32_t interface, Ipv4Address dest)=0
Choose the source address to use with destination address.
virtual uint32_t GetNInterfaces() const =0
virtual void SetForwarding(uint32_t interface, bool val)=0
virtual bool IsUp(uint32_t interface) const =0
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.
A record of an IPv4 routing table entry for Ipv4GlobalRouting and Ipv4StaticRouting.
Ipv4Address GetDest() const
Ipv4Address GetGateway() const
bool IsHost() const
bool IsGateway() const
Ipv4Address GetDestNetwork() const
uint32_t GetInterface() const
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.
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.
RIP Routing Protocol, defined in RFC 2453 .
Definition rip.h:165
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:560
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition simulator.cc:206
void SetRecvPktInfo(bool flag)
Enable/Disable receive packet information to socket.
Definition socket.cc:343
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition socket.cc:117
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
virtual int Close()=0
Close a socket.
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
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
void SetIpRecvTtl(bool ipv4RecvTtl)
Tells a socket to pass information about IP_TTL up the stack.
Definition socket.cc:512
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer.
Definition socket.h: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:404
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:392
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:48
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:1308
-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:1396
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:1416
#define RIP_ALL_NODE
Definition rip.cc:28
#define RIP_PORT
Definition rip.cc:29