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