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