A Discrete-Event Network Simulator
API
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
22#include "ns3/abort.h"
23#include "ns3/assert.h"
24#include "ns3/enum.h"
25#include "ns3/ipv4-packet-info-tag.h"
26#include "ns3/ipv4-route.h"
27#include "ns3/log.h"
28#include "ns3/loopback-net-device.h"
29#include "ns3/names.h"
30#include "ns3/node.h"
31#include "ns3/random-variable-stream.h"
32#include "ns3/rip-header.h"
33#include "ns3/udp-header.h"
34#include "ns3/uinteger.h"
35
36#include <iomanip>
37
38#define RIP_ALL_NODE "224.0.0.9"
39#define RIP_PORT 520
40
41namespace ns3
42{
43
45
47
49 : m_ipv4(nullptr),
50 m_splitHorizonStrategy(Rip::POISON_REVERSE),
51 m_initialized(false)
52{
53 m_rng = CreateObject<UniformRandomVariable>();
54}
55
57{
58}
59
62{
63 static TypeId tid =
64 TypeId("ns3::Rip")
66 .SetGroupName("Internet")
67 .AddConstructor<Rip>()
68 .AddAttribute("UnsolicitedRoutingUpdate",
69 "The time between two Unsolicited Routing Updates.",
70 TimeValue(Seconds(30)),
73 .AddAttribute("StartupDelay",
74 "Maximum random delay for protocol startup (send route requests).",
78 .AddAttribute("TimeoutDelay",
79 "The delay to invalidate a route.",
80 TimeValue(Seconds(180)),
83 .AddAttribute("GarbageCollectionDelay",
84 "The delay to delete an expired route.",
85 TimeValue(Seconds(120)),
88 .AddAttribute("MinTriggeredCooldown",
89 "Min cooldown delay after a Triggered Update.",
93 .AddAttribute("MaxTriggeredCooldown",
94 "Max cooldown delay after a Triggered Update.",
98 .AddAttribute("SplitHorizon",
99 "Split Horizon strategy.",
103 "NoSplitHorizon",
105 "SplitHorizon",
107 "PoisonReverse"))
108 .AddAttribute("LinkDownValue",
109 "Value for link down in count to infinity.",
110 UintegerValue(16),
112 MakeUintegerChecker<uint32_t>());
113 return tid;
114}
115
116int64_t
117Rip::AssignStreams(int64_t stream)
118{
119 NS_LOG_FUNCTION(this << stream);
120
121 m_rng->SetStream(stream);
122 return 1;
123}
124
125void
127{
128 NS_LOG_FUNCTION(this);
129
130 bool addedGlobal = false;
131
132 m_initialized = true;
133
134 Time delay =
137
138 for (uint32_t i = 0; i < m_ipv4->GetNInterfaces(); i++)
139 {
140 Ptr<LoopbackNetDevice> check = DynamicCast<LoopbackNetDevice>(m_ipv4->GetNetDevice(i));
141 if (check)
142 {
143 continue;
144 }
145
146 bool activeInterface = false;
147 if (m_interfaceExclusions.find(i) == m_interfaceExclusions.end())
148 {
149 activeInterface = true;
150 m_ipv4->SetForwarding(i, true);
151 }
152
153 for (uint32_t j = 0; j < m_ipv4->GetNAddresses(i); j++)
154 {
155 Ipv4InterfaceAddress address = m_ipv4->GetAddress(i, j);
156 if (address.GetScope() != Ipv4InterfaceAddress::HOST && activeInterface == true)
157 {
158 NS_LOG_LOGIC("RIP: adding socket to " << address.GetLocal());
159 TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
160 Ptr<Node> theNode = GetObject<Node>();
161 Ptr<Socket> socket = Socket::CreateSocket(theNode, tid);
163 socket->BindToNetDevice(m_ipv4->GetNetDevice(i));
164 int ret = socket->Bind(local);
165 NS_ASSERT_MSG(ret == 0, "Bind unsuccessful");
166
168 socket->SetIpRecvTtl(true);
169 socket->SetRecvPktInfo(true);
170
171 m_unicastSocketList[socket] = i;
172 }
173 else if (m_ipv4->GetAddress(i, j).GetScope() == Ipv4InterfaceAddress::GLOBAL)
174 {
175 addedGlobal = true;
176 }
177 }
178 }
179
181 {
182 NS_LOG_LOGIC("RIP: adding receiving socket");
183 TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
184 Ptr<Node> theNode = GetObject<Node>();
191 }
192
193 if (addedGlobal)
194 {
198 }
199
202
204}
205
208 const Ipv4Header& header,
209 Ptr<NetDevice> oif,
210 Socket::SocketErrno& sockerr)
211{
212 NS_LOG_FUNCTION(this << header << oif);
213
214 Ipv4Address destination = header.GetDestination();
215 Ptr<Ipv4Route> rtentry = nullptr;
216
217 if (destination.IsMulticast())
218 {
219 // Note: Multicast routes for outbound packets are stored in the
220 // normal unicast table. An implication of this is that it is not
221 // possible to source multicast datagrams on multiple interfaces.
222 // This is a well-known property of sockets implementation on
223 // many Unix variants.
224 // So, we just log it and fall through to LookupStatic ()
225 NS_LOG_LOGIC("RouteOutput (): Multicast destination");
226 }
227
228 rtentry = Lookup(destination, true, oif);
229 if (rtentry)
230 {
231 sockerr = Socket::ERROR_NOTERROR;
232 }
233 else
234 {
236 }
237 return rtentry;
238}
239
240bool
242 const Ipv4Header& header,
247 ErrorCallback ecb)
248{
249 NS_LOG_FUNCTION(this << p << header << header.GetSource() << header.GetDestination() << idev);
250
252 // Check if input device supports IP
253 NS_ASSERT(m_ipv4->GetInterfaceForDevice(idev) >= 0);
254 uint32_t iif = m_ipv4->GetInterfaceForDevice(idev);
255 Ipv4Address dst = header.GetDestination();
256
257 if (m_ipv4->IsDestinationAddress(header.GetDestination(), iif))
258 {
259 if (!lcb.IsNull())
260 {
261 NS_LOG_LOGIC("Local delivery to " << header.GetDestination());
262 lcb(p, header, iif);
263 return true;
264 }
265 else
266 {
267 // The local delivery callback is null. This may be a multicast
268 // or broadcast packet, so return false so that another
269 // multicast routing protocol can handle it. It should be possible
270 // to extend this to explicitly check whether it is a unicast
271 // packet, and invoke the error callback if so
272 return false;
273 }
274 }
275
276 if (dst.IsMulticast())
277 {
278 NS_LOG_LOGIC("Multicast route not supported by RIP");
279 return false; // Let other routing protocols try to handle this
280 }
281
282 if (header.GetDestination().IsBroadcast())
283 {
284 NS_LOG_LOGIC("Dropping packet not for me and with dst Broadcast");
285 if (!ecb.IsNull())
286 {
287 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
288 }
289 return false;
290 }
291
292 // Check if input device supports IP forwarding
293 if (m_ipv4->IsForwarding(iif) == false)
294 {
295 NS_LOG_LOGIC("Forwarding disabled for this interface");
296 if (!ecb.IsNull())
297 {
298 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
299 }
300 return true;
301 }
302 // Next, try to find a route
303 NS_LOG_LOGIC("Unicast destination");
304 Ptr<Ipv4Route> rtentry = Lookup(header.GetDestination(), false);
305
306 if (rtentry)
307 {
308 NS_LOG_LOGIC("Found unicast destination - calling unicast callback");
309 ucb(rtentry, p, header); // unicast forwarding callback
310 return true;
311 }
312 else
313 {
314 NS_LOG_LOGIC("Did not find unicast destination - returning false");
315 return false; // Let other routing protocols try to handle this
316 }
317}
318
319void
321{
322 NS_LOG_FUNCTION(this << i);
323
324 Ptr<LoopbackNetDevice> check = DynamicCast<LoopbackNetDevice>(m_ipv4->GetNetDevice(i));
325 if (check)
326 {
327 return;
328 }
329
330 for (uint32_t j = 0; j < m_ipv4->GetNAddresses(i); j++)
331 {
332 Ipv4InterfaceAddress address = m_ipv4->GetAddress(i, j);
333 Ipv4Mask networkMask = address.GetMask();
334 Ipv4Address networkAddress = address.GetLocal().CombineMask(networkMask);
335
336 if (address.GetScope() == Ipv4InterfaceAddress::GLOBAL)
337 {
338 AddNetworkRouteTo(networkAddress, networkMask, i);
339 }
340 }
341
342 if (!m_initialized)
343 {
344 return;
345 }
346
347 bool sendSocketFound = false;
348 for (SocketListI iter = m_unicastSocketList.begin(); iter != m_unicastSocketList.end(); iter++)
349 {
350 if (iter->second == i)
351 {
352 sendSocketFound = true;
353 break;
354 }
355 }
356
357 bool activeInterface = false;
358 if (m_interfaceExclusions.find(i) == m_interfaceExclusions.end())
359 {
360 activeInterface = true;
361 m_ipv4->SetForwarding(i, true);
362 }
363
364 for (uint32_t j = 0; j < m_ipv4->GetNAddresses(i); j++)
365 {
366 Ipv4InterfaceAddress address = m_ipv4->GetAddress(i, j);
367
368 if (address.GetScope() != Ipv4InterfaceAddress::HOST && sendSocketFound == false &&
369 activeInterface == true)
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);
376 socket->BindToNetDevice(m_ipv4->GetNetDevice(i));
377 socket->Bind(local);
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())) != "")
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:92
Callback template class.
Definition: callback.h:443
bool IsNull() const
Check for null implementation.
Definition: callback.h:556
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:43
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:258
uint16_t GetPrefixLength() const
bool IsMatch(Ipv4Address a, Ipv4Address b) const
static Ipv4Mask GetZero()
This class implements Linux struct pktinfo in order to deliver ancillary information to the socket in...
uint32_t GetRecvIf() const
Get the tag's receiving interface.
Abstract base class for IPv4 routing protocols.
A record of an IPv4 routing table entry for Ipv4GlobalRouting and Ipv4StaticRouting.
Ipv4Address GetDest() const
Ipv4Address GetGateway() const
bool IsHost() const
bool IsGateway() const
Ipv4Address GetDestNetwork() const
uint32_t GetInterface() const
Ipv4Mask GetDestNetworkMask() const
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and,...
Definition: names.cc:830
A network Node.
Definition: node.h:56
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:152
virtual void DoInitialize()
Initialize() implementation.
Definition: object.cc:360
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
std::ostream * GetStream()
Return a pointer to an ostream previously set in the wrapper.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:986
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:979
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
bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb) override
Route an input packet (to be forwarded or locally delivered)
Definition: rip.cc:241
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:48
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
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:320
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:117
~Rip() override
Definition: rip.cc:56
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:126
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:207
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:61
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
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
void SetRecvPktInfo(bool flag)
Enable/Disable receive packet information to socket.
Definition: socket.cc:352
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:325
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
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
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:417
AttributeValue implementation for Time.
Definition: nstime.h:1425
a unique identifier for an interface.
Definition: type-id.h:60
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:839
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
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, as a double in the specified range .
#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 AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1426
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:45
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:1338
Definition: first.py:1
address
Definition: first.py:40
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:691
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:535
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:38
#define RIP_PORT
Definition: rip.cc:39