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