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.",
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 (SocketListI 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 (RoutesI 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 (SocketListI 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 (RoutesI 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 (RoutesCI 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 (RoutesI 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 (SocketListI 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 (RoutesI 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 RipRoutingTableEntry* route =
712 new RipRoutingTableEntry(network, networkPrefix, nextHop, interface);
713 route->SetRouteMetric(1);
715 route->SetRouteChanged(true);
716
717 m_routes.emplace_back(route, EventId());
718}
719
720void
721Rip::AddNetworkRouteTo(Ipv4Address network, Ipv4Mask networkPrefix, uint32_t interface)
722{
723 NS_LOG_FUNCTION(this << network << networkPrefix << interface);
724
725 RipRoutingTableEntry* route = new RipRoutingTableEntry(network, networkPrefix, interface);
726 route->SetRouteMetric(1);
728 route->SetRouteChanged(true);
729
730 m_routes.emplace_back(route, EventId());
731}
732
733void
735{
736 NS_LOG_FUNCTION(this << *route);
737
738 for (RoutesI it = m_routes.begin(); it != m_routes.end(); it++)
739 {
740 if (it->first == route)
741 {
744 route->SetRouteChanged(true);
745 if (it->second.IsRunning())
746 {
747 it->second.Cancel();
748 }
749 it->second =
751 return;
752 }
753 }
754 NS_ABORT_MSG("RIP::InvalidateRoute - cannot find the route to update");
755}
756
757void
759{
760 NS_LOG_FUNCTION(this << *route);
761
762 for (RoutesI it = m_routes.begin(); it != m_routes.end(); it++)
763 {
764 if (it->first == route)
765 {
766 delete route;
767 m_routes.erase(it);
768 return;
769 }
770 }
771 NS_ABORT_MSG("RIP::DeleteRoute - cannot find the route to delete");
772}
773
774void
776{
777 NS_LOG_FUNCTION(this << socket);
778
779 Address sender;
780 Ptr<Packet> packet = socket->RecvFrom(sender);
782 NS_LOG_INFO("Received " << *packet << " from " << senderAddr.GetIpv4() << ":"
783 << senderAddr.GetPort());
784
785 Ipv4Address senderAddress = senderAddr.GetIpv4();
786 uint16_t senderPort = senderAddr.GetPort();
787
788 if (socket == m_multicastRecvSocket)
789 {
790 NS_LOG_LOGIC("Received a packet from the multicast socket");
791 }
792 else
793 {
794 NS_LOG_LOGIC("Received a packet from one of the unicast sockets");
795 }
796
797 Ipv4PacketInfoTag interfaceInfo;
798 if (!packet->RemovePacketTag(interfaceInfo))
799 {
800 NS_ABORT_MSG("No incoming interface on RIP message, aborting.");
801 }
802 uint32_t incomingIf = interfaceInfo.GetRecvIf();
803 Ptr<Node> node = this->GetObject<Node>();
804 Ptr<NetDevice> dev = node->GetDevice(incomingIf);
805 uint32_t ipInterfaceIndex = m_ipv4->GetInterfaceForDevice(dev);
806
807 SocketIpTtlTag hoplimitTag;
808 if (!packet->RemovePacketTag(hoplimitTag))
809 {
810 NS_ABORT_MSG("No incoming Hop Count on RIP message, aborting.");
811 }
812 uint8_t hopLimit = hoplimitTag.GetTtl();
813
814 int32_t interfaceForAddress = m_ipv4->GetInterfaceForAddress(senderAddress);
815 if (interfaceForAddress != -1)
816 {
817 NS_LOG_LOGIC("Ignoring a packet sent by myself.");
818 return;
819 }
820
821 RipHeader hdr;
822 packet->RemoveHeader(hdr);
823
824 if (hdr.GetCommand() == RipHeader::RESPONSE)
825 {
826 NS_LOG_LOGIC("The message is a Response from " << senderAddr.GetIpv4() << ":"
827 << senderAddr.GetPort());
828 HandleResponses(hdr, senderAddress, ipInterfaceIndex, hopLimit);
829 }
830 else if (hdr.GetCommand() == RipHeader::REQUEST)
831 {
832 NS_LOG_LOGIC("The message is a Request from " << senderAddr.GetIpv4() << ":"
833 << senderAddr.GetPort());
834 HandleRequests(hdr, senderAddress, senderPort, ipInterfaceIndex, hopLimit);
835 }
836 else
837 {
838 NS_LOG_LOGIC("Ignoring message with unknown command: " << int(hdr.GetCommand()));
839 }
840}
841
842void
844 Ipv4Address senderAddress,
845 uint16_t senderPort,
846 uint32_t incomingInterface,
847 uint8_t hopLimit)
848{
849 NS_LOG_FUNCTION(this << senderAddress << int(senderPort) << incomingInterface << int(hopLimit)
850 << requestHdr);
851
852 std::list<RipRte> rtes = requestHdr.GetRteList();
853
854 if (rtes.empty())
855 {
856 return;
857 }
858
859 // check if it's a request for the full table from a neighbor
860 if (rtes.size() == 1)
861 {
862 if (rtes.begin()->GetPrefix() == Ipv4Address::GetAny() &&
863 rtes.begin()->GetSubnetMask().GetPrefixLength() == 0 &&
864 rtes.begin()->GetRouteMetric() == m_linkDown)
865 {
866 // Output whole thing. Use Split Horizon
867 if (m_interfaceExclusions.find(incomingInterface) == m_interfaceExclusions.end())
868 {
869 // we use one of the sending sockets, as they're bound to the right interface
870 // and the local address might be used on different interfaces.
871 Ptr<Socket> sendingSocket;
872 for (SocketListI iter = m_unicastSocketList.begin();
873 iter != m_unicastSocketList.end();
874 iter++)
875 {
876 if (iter->second == incomingInterface)
877 {
878 sendingSocket = iter->first;
879 }
880 }
881 NS_ASSERT_MSG(sendingSocket,
882 "HandleRequest - Impossible to find a socket to send the reply");
883
884 uint16_t mtu = m_ipv4->GetMtu(incomingInterface);
885 uint16_t maxRte =
889
890 Ptr<Packet> p = Create<Packet>();
891 SocketIpTtlTag tag;
892 p->RemovePacketTag(tag);
893 if (senderAddress == Ipv4Address(RIP_ALL_NODE))
894 {
895 tag.SetTtl(1);
896 }
897 else
898 {
899 tag.SetTtl(255);
900 }
901 p->AddPacketTag(tag);
902
903 RipHeader hdr;
905
906 for (RoutesI rtIter = m_routes.begin(); rtIter != m_routes.end(); rtIter++)
907 {
908 bool splitHorizoning = (rtIter->first->GetInterface() == incomingInterface);
909
910 Ipv4InterfaceAddress rtDestAddr =
911 Ipv4InterfaceAddress(rtIter->first->GetDestNetwork(),
912 rtIter->first->GetDestNetworkMask());
913
914 bool isGlobal = (rtDestAddr.GetScope() == Ipv4InterfaceAddress::GLOBAL);
915 bool isDefaultRoute =
916 ((rtIter->first->GetDestNetwork() == Ipv4Address::GetAny()) &&
917 (rtIter->first->GetDestNetworkMask() == Ipv4Mask::GetZero()) &&
918 (rtIter->first->GetInterface() != incomingInterface));
919
920 if ((isGlobal || isDefaultRoute) &&
921 (rtIter->first->GetRouteStatus() == RipRoutingTableEntry::RIP_VALID))
922 {
923 RipRte rte;
924 rte.SetPrefix(rtIter->first->GetDestNetwork());
925 rte.SetSubnetMask(rtIter->first->GetDestNetworkMask());
926 if (m_splitHorizonStrategy == POISON_REVERSE && splitHorizoning)
927 {
929 }
930 else
931 {
932 rte.SetRouteMetric(rtIter->first->GetRouteMetric());
933 }
934 rte.SetRouteTag(rtIter->first->GetRouteTag());
936 (m_splitHorizonStrategy == SPLIT_HORIZON && !splitHorizoning))
937 {
938 hdr.AddRte(rte);
939 }
940 }
941 if (hdr.GetRteNumber() == maxRte)
942 {
943 p->AddHeader(hdr);
944 NS_LOG_DEBUG("SendTo: " << *p);
945 sendingSocket->SendTo(p, 0, InetSocketAddress(senderAddress, RIP_PORT));
946 p->RemoveHeader(hdr);
947 hdr.ClearRtes();
948 }
949 }
950 if (hdr.GetRteNumber() > 0)
951 {
952 p->AddHeader(hdr);
953 NS_LOG_DEBUG("SendTo: " << *p);
954 sendingSocket->SendTo(p, 0, InetSocketAddress(senderAddress, RIP_PORT));
955 }
956 }
957 }
958 }
959 else
960 {
961 // note: we got the request as a single packet, so no check is necessary for MTU limit
962
963 Ptr<Packet> p = Create<Packet>();
964 SocketIpTtlTag tag;
965 p->RemovePacketTag(tag);
966 if (senderAddress == Ipv4Address(RIP_ALL_NODE))
967 {
968 tag.SetTtl(1);
969 }
970 else
971 {
972 tag.SetTtl(255);
973 }
974 p->AddPacketTag(tag);
975
976 RipHeader hdr;
978
979 for (std::list<RipRte>::iterator iter = rtes.begin(); iter != rtes.end(); iter++)
980 {
981 bool found = false;
982 for (RoutesI rtIter = m_routes.begin(); rtIter != m_routes.end(); rtIter++)
983 {
984 Ipv4InterfaceAddress rtDestAddr =
985 Ipv4InterfaceAddress(rtIter->first->GetDestNetwork(),
986 rtIter->first->GetDestNetworkMask());
987 if ((rtDestAddr.GetScope() == Ipv4InterfaceAddress::GLOBAL) &&
988 (rtIter->first->GetRouteStatus() == RipRoutingTableEntry::RIP_VALID))
989 {
990 Ipv4Address requestedAddress = iter->GetPrefix();
991 requestedAddress.CombineMask(iter->GetSubnetMask());
992 Ipv4Address rtAddress = rtIter->first->GetDestNetwork();
993 rtAddress.CombineMask(rtIter->first->GetDestNetworkMask());
994
995 if (requestedAddress == rtAddress)
996 {
997 iter->SetRouteMetric(rtIter->first->GetRouteMetric());
998 iter->SetRouteTag(rtIter->first->GetRouteTag());
999 hdr.AddRte(*iter);
1000 found = true;
1001 break;
1002 }
1003 }
1004 }
1005 if (!found)
1006 {
1007 iter->SetRouteMetric(m_linkDown);
1008 iter->SetRouteTag(0);
1009 hdr.AddRte(*iter);
1010 }
1011 }
1012 p->AddHeader(hdr);
1013 NS_LOG_DEBUG("SendTo: " << *p);
1014 m_multicastRecvSocket->SendTo(p, 0, InetSocketAddress(senderAddress, senderPort));
1015 }
1016}
1017
1018void
1020 Ipv4Address senderAddress,
1021 uint32_t incomingInterface,
1022 uint8_t hopLimit)
1023{
1024 NS_LOG_FUNCTION(this << senderAddress << incomingInterface << int(hopLimit) << hdr);
1025
1026 if (m_interfaceExclusions.find(incomingInterface) != m_interfaceExclusions.end())
1027 {
1029 "Ignoring an update message from an excluded interface: " << incomingInterface);
1030 return;
1031 }
1032
1033 std::list<RipRte> rtes = hdr.GetRteList();
1034
1035 // validate the RTEs before processing
1036 for (std::list<RipRte>::iterator iter = rtes.begin(); iter != rtes.end(); iter++)
1037 {
1038 if (iter->GetRouteMetric() == 0 || iter->GetRouteMetric() > m_linkDown)
1039 {
1040 NS_LOG_LOGIC("Ignoring an update message with malformed metric: "
1041 << int(iter->GetRouteMetric()));
1042 return;
1043 }
1044 if (iter->GetPrefix().IsLocalhost() || iter->GetPrefix().IsBroadcast() ||
1045 iter->GetPrefix().IsMulticast())
1046 {
1047 NS_LOG_LOGIC("Ignoring an update message with wrong prefixes: " << iter->GetPrefix());
1048 return;
1049 }
1050 }
1051
1052 bool changed = false;
1053
1054 for (std::list<RipRte>::iterator iter = rtes.begin(); iter != rtes.end(); iter++)
1055 {
1056 Ipv4Mask rtePrefixMask = iter->GetSubnetMask();
1057 Ipv4Address rteAddr = iter->GetPrefix().CombineMask(rtePrefixMask);
1058
1059 NS_LOG_LOGIC("Processing RTE " << *iter);
1060
1061 uint32_t interfaceMetric = 1;
1062 if (m_interfaceMetrics.find(incomingInterface) != m_interfaceMetrics.end())
1063 {
1064 interfaceMetric = m_interfaceMetrics[incomingInterface];
1065 }
1066 uint64_t rteMetric = iter->GetRouteMetric() + interfaceMetric;
1067 if (rteMetric > m_linkDown)
1068 {
1069 rteMetric = m_linkDown;
1070 }
1071
1072 RoutesI it;
1073 bool found = false;
1074 for (it = m_routes.begin(); it != m_routes.end(); it++)
1075 {
1076 if (it->first->GetDestNetwork() == rteAddr &&
1077 it->first->GetDestNetworkMask() == rtePrefixMask)
1078 {
1079 found = true;
1080 if (rteMetric < it->first->GetRouteMetric())
1081 {
1082 if (senderAddress != it->first->GetGateway())
1083 {
1084 RipRoutingTableEntry* route = new RipRoutingTableEntry(rteAddr,
1085 rtePrefixMask,
1086 senderAddress,
1087 incomingInterface);
1088 delete it->first;
1089 it->first = route;
1090 }
1091 it->first->SetRouteMetric(rteMetric);
1092 it->first->SetRouteStatus(RipRoutingTableEntry::RIP_VALID);
1093 it->first->SetRouteTag(iter->GetRouteTag());
1094 it->first->SetRouteChanged(true);
1095 it->second.Cancel();
1096 it->second =
1098 changed = true;
1099 }
1100 else if (rteMetric == it->first->GetRouteMetric())
1101 {
1102 if (senderAddress == it->first->GetGateway())
1103 {
1104 it->second.Cancel();
1107 this,
1108 it->first);
1109 }
1110 else
1111 {
1112 if (Simulator::GetDelayLeft(it->second) < m_timeoutDelay / 2)
1113 {
1114 RipRoutingTableEntry* route =
1115 new RipRoutingTableEntry(rteAddr,
1116 rtePrefixMask,
1117 senderAddress,
1118 incomingInterface);
1119 route->SetRouteMetric(rteMetric);
1121 route->SetRouteTag(iter->GetRouteTag());
1122 route->SetRouteChanged(true);
1123 delete it->first;
1124 it->first = route;
1125 it->second.Cancel();
1128 this,
1129 route);
1130 changed = true;
1131 }
1132 }
1133 }
1134 else if (rteMetric > it->first->GetRouteMetric() &&
1135 senderAddress == it->first->GetGateway())
1136 {
1137 it->second.Cancel();
1138 if (rteMetric < m_linkDown)
1139 {
1140 it->first->SetRouteMetric(rteMetric);
1141 it->first->SetRouteStatus(RipRoutingTableEntry::RIP_VALID);
1142 it->first->SetRouteTag(iter->GetRouteTag());
1143 it->first->SetRouteChanged(true);
1144 it->second.Cancel();
1147 this,
1148 it->first);
1149 }
1150 else
1151 {
1152 InvalidateRoute(it->first);
1153 }
1154 changed = true;
1155 }
1156 }
1157 }
1158 if (!found && rteMetric != m_linkDown)
1159 {
1160 NS_LOG_LOGIC("Received a RTE with new route, adding.");
1161
1162 RipRoutingTableEntry* route =
1163 new RipRoutingTableEntry(rteAddr, rtePrefixMask, senderAddress, incomingInterface);
1164 route->SetRouteMetric(rteMetric);
1166 route->SetRouteChanged(true);
1167 m_routes.emplace_front(route, EventId());
1168 EventId invalidateEvent =
1170 (m_routes.begin())->second = invalidateEvent;
1171 changed = true;
1172 }
1173 }
1174
1175 if (changed)
1176 {
1178 }
1179}
1180
1181void
1183{
1184 NS_LOG_FUNCTION(this << (periodic ? " periodic" : " triggered"));
1185
1186 for (SocketListI iter = m_unicastSocketList.begin(); iter != m_unicastSocketList.end(); iter++)
1187 {
1188 uint32_t interface = iter->second;
1189
1190 if (m_interfaceExclusions.find(interface) == m_interfaceExclusions.end())
1191 {
1192 uint16_t mtu = m_ipv4->GetMtu(interface);
1193 uint16_t maxRte = (mtu - Ipv4Header().GetSerializedSize() -
1196
1197 Ptr<Packet> p = Create<Packet>();
1198 SocketIpTtlTag tag;
1199 tag.SetTtl(1);
1200 p->AddPacketTag(tag);
1201
1202 RipHeader hdr;
1204
1205 for (RoutesI rtIter = m_routes.begin(); rtIter != m_routes.end(); rtIter++)
1206 {
1207 bool splitHorizoning = (rtIter->first->GetInterface() == interface);
1208 Ipv4InterfaceAddress rtDestAddr =
1209 Ipv4InterfaceAddress(rtIter->first->GetDestNetwork(),
1210 rtIter->first->GetDestNetworkMask());
1211
1212 NS_LOG_DEBUG("Processing RT " << rtDestAddr << " "
1213 << int(rtIter->first->IsRouteChanged()));
1214
1215 bool isGlobal = (rtDestAddr.GetScope() == Ipv4InterfaceAddress::GLOBAL);
1216 bool isDefaultRoute =
1217 ((rtIter->first->GetDestNetwork() == Ipv4Address::GetAny()) &&
1218 (rtIter->first->GetDestNetworkMask() == Ipv4Mask::GetZero()) &&
1219 (rtIter->first->GetInterface() != interface));
1220
1221 bool sameNetwork = false;
1222 for (uint32_t index = 0; index < m_ipv4->GetNAddresses(interface); index++)
1223 {
1224 Ipv4InterfaceAddress addr = m_ipv4->GetAddress(interface, index);
1225 if (addr.GetLocal().CombineMask(addr.GetMask()) ==
1226 rtIter->first->GetDestNetwork())
1227 {
1228 sameNetwork = true;
1229 }
1230 }
1231
1232 if ((isGlobal || isDefaultRoute) && (periodic || rtIter->first->IsRouteChanged()) &&
1233 !sameNetwork)
1234 {
1235 RipRte rte;
1236 rte.SetPrefix(rtIter->first->GetDestNetwork());
1237 rte.SetSubnetMask(rtIter->first->GetDestNetworkMask());
1238 if (m_splitHorizonStrategy == POISON_REVERSE && splitHorizoning)
1239 {
1241 }
1242 else
1243 {
1244 rte.SetRouteMetric(rtIter->first->GetRouteMetric());
1245 }
1246 rte.SetRouteTag(rtIter->first->GetRouteTag());
1247 if (m_splitHorizonStrategy == SPLIT_HORIZON && !splitHorizoning)
1248 {
1249 hdr.AddRte(rte);
1250 }
1252 {
1253 hdr.AddRte(rte);
1254 }
1255 }
1256 if (hdr.GetRteNumber() == maxRte)
1257 {
1258 p->AddHeader(hdr);
1259 NS_LOG_DEBUG("SendTo: " << *p);
1260 iter->first->SendTo(p, 0, InetSocketAddress(RIP_ALL_NODE, RIP_PORT));
1261 p->RemoveHeader(hdr);
1262 hdr.ClearRtes();
1263 }
1264 }
1265 if (hdr.GetRteNumber() > 0)
1266 {
1267 p->AddHeader(hdr);
1268 NS_LOG_DEBUG("SendTo: " << *p);
1269 iter->first->SendTo(p, 0, InetSocketAddress(RIP_ALL_NODE, RIP_PORT));
1270 }
1271 }
1272 }
1273 for (RoutesI rtIter = m_routes.begin(); rtIter != m_routes.end(); rtIter++)
1274 {
1275 rtIter->first->SetRouteChanged(false);
1276 }
1277}
1278
1279void
1281{
1282 NS_LOG_FUNCTION(this);
1283
1285 {
1286 NS_LOG_LOGIC("Skipping Triggered Update due to cooldown");
1287 return;
1288 }
1289
1290 // DoSendRouteUpdate (false);
1291
1292 // note: The RFC states:
1293 // After a triggered
1294 // update is sent, a timer should be set for a random interval between 1
1295 // and 5 seconds. If other changes that would trigger updates occur
1296 // before the timer expires, a single update is triggered when the timer
1297 // expires. The timer is then reset to another random value between 1
1298 // and 5 seconds. Triggered updates may be suppressed if a regular
1299 // update is due by the time the triggered update would be sent.
1300 // Here we rely on this:
1301 // When an update occurs (either Triggered or Periodic) the "IsChanged ()"
1302 // route field will be cleared.
1303 // Hence, the following Triggered Update will be fired, but will not send
1304 // any route update.
1305
1309}
1310
1311void
1313{
1314 NS_LOG_FUNCTION(this);
1315
1317 {
1319 }
1320
1321 DoSendRouteUpdate(true);
1322
1323 Time delay =
1326}
1327
1328std::set<uint32_t>
1330{
1331 return m_interfaceExclusions;
1332}
1333
1334void
1335Rip::SetInterfaceExclusions(std::set<uint32_t> exceptions)
1336{
1337 NS_LOG_FUNCTION(this);
1338
1339 m_interfaceExclusions = exceptions;
1340}
1341
1342uint8_t
1344{
1345 NS_LOG_FUNCTION(this << interface);
1346
1347 std::map<uint32_t, uint8_t>::const_iterator iter = m_interfaceMetrics.find(interface);
1348 if (iter != m_interfaceMetrics.end())
1349 {
1350 return iter->second;
1351 }
1352 return 1;
1353}
1354
1355void
1356Rip::SetInterfaceMetric(uint32_t interface, uint8_t metric)
1357{
1358 NS_LOG_FUNCTION(this << interface << int(metric));
1359
1360 if (metric < m_linkDown)
1361 {
1362 m_interfaceMetrics[interface] = metric;
1363 }
1364}
1365
1366void
1368{
1369 NS_LOG_FUNCTION(this);
1370
1371 Ptr<Packet> p = Create<Packet>();
1372 SocketIpTtlTag tag;
1373 p->RemovePacketTag(tag);
1374 tag.SetTtl(1);
1375 p->AddPacketTag(tag);
1376
1377 RipHeader hdr;
1379
1380 RipRte rte;
1384
1385 hdr.AddRte(rte);
1386 p->AddHeader(hdr);
1387
1388 for (SocketListI iter = m_unicastSocketList.begin(); iter != m_unicastSocketList.end(); iter++)
1389 {
1390 uint32_t interface = iter->second;
1391
1392 if (m_interfaceExclusions.find(interface) == m_interfaceExclusions.end())
1393 {
1394 NS_LOG_DEBUG("SendTo: " << *p);
1395 iter->first->SendTo(p, 0, InetSocketAddress(RIP_ALL_NODE, RIP_PORT));
1396 }
1397 }
1398}
1399
1400void
1402{
1403 NS_LOG_FUNCTION(this << interface);
1404
1405 AddNetworkRouteTo(Ipv4Address("0.0.0.0"), Ipv4Mask::GetZero(), nextHop, interface);
1406}
1407
1408/*
1409 * RipRoutingTableEntry
1410 */
1411
1413 : m_tag(0),
1414 m_metric(0),
1415 m_status(RIP_INVALID),
1416 m_changed(false)
1417{
1418}
1419
1421 Ipv4Mask networkPrefix,
1422 Ipv4Address nextHop,
1423 uint32_t interface)
1425 Ipv4RoutingTableEntry::CreateNetworkRouteTo(network, networkPrefix, nextHop, interface)),
1426 m_tag(0),
1427 m_metric(0),
1428 m_status(RIP_INVALID),
1429 m_changed(false)
1430{
1431}
1432
1434 Ipv4Mask networkPrefix,
1435 uint32_t interface)
1437 Ipv4RoutingTableEntry::CreateNetworkRouteTo(network, networkPrefix, interface)),
1438 m_tag(0),
1439 m_metric(0),
1440 m_status(RIP_INVALID),
1441 m_changed(false)
1442{
1443}
1444
1446{
1447}
1448
1449void
1451{
1452 if (m_tag != routeTag)
1453 {
1454 m_tag = routeTag;
1455 m_changed = true;
1456 }
1457}
1458
1459uint16_t
1461{
1462 return m_tag;
1463}
1464
1465void
1467{
1468 if (m_metric != routeMetric)
1469 {
1470 m_metric = routeMetric;
1471 m_changed = true;
1472 }
1473}
1474
1475uint8_t
1477{
1478 return m_metric;
1479}
1480
1481void
1483{
1484 if (m_status != status)
1485 {
1486 m_status = status;
1487 m_changed = true;
1488 }
1489}
1490
1493{
1494 return m_status;
1495}
1496
1497void
1499{
1500 m_changed = changed;
1501}
1502
1503bool
1505{
1506 return m_changed;
1507}
1508
1509std::ostream&
1510operator<<(std::ostream& os, const RipRoutingTableEntry& rte)
1511{
1512 os << static_cast<const Ipv4RoutingTableEntry&>(rte);
1513 os << ", metric: " << int(rte.GetRouteMetric()) << ", tag: " << int(rte.GetRouteTag());
1514
1515 return os;
1516}
1517
1518} // namespace ns3
a polymophic address class
Definition: address.h:100
bool IsNull() const
Check for null implementation.
Definition: callback.h:567
Hold variables of type enum.
Definition: enum.h:56
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:830
A network Node.
Definition: node.h:56
virtual void DoInitialize()
Initialize() implementation.
Definition: object.cc:360
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
RipHeader - see RFC 2453
Definition: rip-header.h:157
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
Definition: rip-header.cc:209
uint16_t GetRteNumber() const
Get the number of RTE included in the message.
Definition: rip-header.cc:296
void AddRte(RipRte rte)
Add a RTE to the message.
Definition: rip-header.cc:284
void SetCommand(Command_e command)
Set the command.
Definition: rip-header.cc:272
void ClearRtes()
Clear all the RTEs from the header.
Definition: rip-header.cc:290
std::list< RipRte > GetRteList() const
Get the list of the RTEs included in the message.
Definition: rip-header.cc:302
Command_e GetCommand() const
Get the command.
Definition: rip-header.cc:278
RIP Routing Protocol, defined in RFC 2453.
Definition: rip.h:175
void SetInterfaceMetric(uint32_t interface, uint8_t metric)
Set the metric for an interface.
Definition: rip.cc:1356
void DoSendRouteUpdate(bool periodic)
Send Routing Updates on all interfaces.
Definition: rip.cc:1182
void DoDispose() override
Dispose this object.
Definition: rip.cc:591
SplitHorizonType_e m_splitHorizonStrategy
Split Horizon strategy.
Definition: rip.h:423
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:395
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:421
std::set< uint32_t > m_interfaceExclusions
Set of excluded interfaces.
Definition: rip.h:420
std::list< std::pair< RipRoutingTableEntry *, EventId > >::iterator RoutesI
Iterator for container for the network routes.
Definition: rip.h:283
uint32_t m_linkDown
Link down value.
Definition: rip.h:426
void HandleRequests(RipHeader hdr, Ipv4Address senderAddress, uint16_t senderPort, uint32_t incomingInterface, uint8_t hopLimit)
Handle RIP requests.
Definition: rip.cc:843
void DeleteRoute(RipRoutingTableEntry *route)
Delete a route.
Definition: rip.cc:758
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:734
void Receive(Ptr< Socket > socket)
Receive RIP packets.
Definition: rip.cc:775
void NotifyInterfaceUp(uint32_t interface) override
Definition: rip.cc:321
EventId m_nextUnsolicitedUpdate
Next Unsolicited Update event.
Definition: rip.h:415
std::list< std::pair< RipRoutingTableEntry *, EventId > >::const_iterator RoutesCI
Const Iterator for container for the network routes.
Definition: rip.h:280
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:416
Ptr< Ipv4 > m_ipv4
IPv4 reference.
Definition: rip.h:394
void DoInitialize() override
Start protocol operation.
Definition: rip.cc:127
void SendRouteRequest()
Send Routing Request on all interfaces.
Definition: rip.cc:1367
Time m_timeoutDelay
Delay before invalidating a route.
Definition: rip.h:399
void AddNetworkRouteTo(Ipv4Address network, Ipv4Mask networkPrefix, Ipv4Address nextHop, uint32_t interface)
Add route to network.
Definition: rip.cc:704
std::map< Ptr< Socket >, uint32_t >::iterator SocketListI
Socket list type iterator.
Definition: rip.h:407
Ptr< Socket > m_multicastRecvSocket
multicast receive socket
Definition: rip.h:413
Time m_minTriggeredUpdateDelay
Min cooldown delay after a Triggered Update.
Definition: rip.h:396
@ SPLIT_HORIZON
Split Horizon.
Definition: rip.h:213
@ NO_SPLIT_HORIZON
No Split Horizon.
Definition: rip.h:212
@ POISON_REVERSE
Poison Reverse Split Horizon.
Definition: rip.h:214
Time m_unsolicitedUpdate
time between two Unsolicited Routing Updates
Definition: rip.h:398
std::set< uint32_t > GetInterfaceExclusions() const
Get the set of interface excluded from the protocol.
Definition: rip.cc:1329
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:1343
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:412
Time m_garbageCollectionDelay
Delay before deleting an INVALID route.
Definition: rip.h:400
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:425
void SetInterfaceExclusions(std::set< uint32_t > exceptions)
Set the set of interface excluded from the protocol.
Definition: rip.cc:1335
void AddDefaultRouteTo(Ipv4Address nextHop, uint32_t interface)
Add a default route to the router through the nextHop located on interface.
Definition: rip.cc:1401
Routes m_routes
the forwarding table for network.
Definition: rip.h:393
Time m_maxTriggeredUpdateDelay
Max cooldown delay after a Triggered Update.
Definition: rip.h:397
void SendTriggeredRouteUpdate()
Send Triggered Routing Updates on all interfaces.
Definition: rip.cc:1280
void SendUnsolicitedRouteUpdate()
Send Unsolicited Routing Updates on all interfaces.
Definition: rip.cc:1312
void HandleResponses(RipHeader hdr, Ipv4Address senderAddress, uint32_t incomingInterface, uint8_t hopLimit)
Handle RIP responses.
Definition: rip.cc:1019
Ptr< UniformRandomVariable > m_rng
Rng stream.
Definition: rip.h:418
Rip Routing Table Entry.
Definition: rip.h:64
void SetRouteMetric(uint8_t routeMetric)
Set the route metric.
Definition: rip.cc:1466
Status_e m_status
route status
Definition: rip.h:156
RipRoutingTableEntry()
Definition: rip.cc:1412
bool m_changed
route has been updated
Definition: rip.h:157
void SetRouteStatus(Status_e status)
Set the route status.
Definition: rip.cc:1482
Status_e
Route status.
Definition: rip.h:70
@ RIP_INVALID
Definition: rip.h:72
@ RIP_VALID
Definition: rip.h:71
bool IsRouteChanged() const
Get the route changed status.
Definition: rip.cc:1504
Status_e GetRouteStatus() const
Get the route status.
Definition: rip.cc:1492
uint8_t GetRouteMetric() const
Get the route metric.
Definition: rip.cc:1476
void SetRouteTag(uint16_t routeTag)
Set the route tag.
Definition: rip.cc:1450
uint16_t GetRouteTag() const
Get the route tag.
Definition: rip.cc:1460
void SetRouteChanged(bool changed)
Set the route as changed.
Definition: rip.cc:1498
uint8_t m_metric
route metric
Definition: rip.h:155
virtual ~RipRoutingTableEntry()
Definition: rip.cc:1445
uint16_t m_tag
route tag
Definition: rip.h:154
Rip v2 Routing Table Entry (RTE) - see RFC 2453.
Definition: rip-header.h:38
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:568
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:208
void SetRecvPktInfo(bool flag)
Enable/Disable receive packet information to socket.
Definition: socket.cc:352
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:126
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:521
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:1122
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition: socket.cc:602
uint8_t GetTtl() const
Get the tag's TTL.
Definition: socket.cc:609
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:417
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:402
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:111
AttributeValue implementation for Time.
Definition: nstime.h:1423
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:840
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
Packet header for UDP packets.
Definition: udp-header.h:41
uint32_t GetSerializedSize() const override
Definition: udp-header.cc:180
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 AttributeAccessor > MakeEnumAccessor(T1 a1)
Definition: enum.h:205
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1444
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1424
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_ABORT_MSG(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:296
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
-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:702
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
Ptr< const AttributeChecker > MakeEnumChecker(int v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:163
Definition: second.py:1
#define RIP_ALL_NODE
Definition: rip.cc:39
#define RIP_PORT
Definition: rip.cc:40