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  // Copy the current ostream state
497  std::ios oldState (nullptr);
498  oldState.copyfmt (*os);
499 
500  *os << std::resetiosflags (std::ios::adjustfield) << std::setiosflags (std::ios::left);
501 
502  *os << "Node: " << m_ipv4->GetObject<Node> ()->GetId ()
503  << ", Time: " << Now().As (unit)
504  << ", Local time: " << m_ipv4->GetObject<Node> ()->GetLocalTime ().As (unit)
505  << ", IPv4 RIP table" << std::endl;
506 
507  if (!m_routes.empty ())
508  {
509  *os << "Destination Gateway Genmask Flags Metric Ref Use Iface" << std::endl;
510  for (RoutesCI it = m_routes.begin (); it != m_routes.end (); it++)
511  {
512  RipRoutingTableEntry* route = it->first;
514 
515  if (status == RipRoutingTableEntry::RIP_VALID)
516  {
517  std::ostringstream dest, gw, mask, flags;
518  dest << route->GetDest ();
519  *os << std::setw (16) << dest.str ();
520  gw << route->GetGateway ();
521  *os << std::setw (16) << gw.str ();
522  mask << route->GetDestNetworkMask ();
523  *os << std::setw (16) << mask.str ();
524  flags << "U";
525  if (route->IsHost ())
526  {
527  flags << "HS";
528  }
529  else if (route->IsGateway ())
530  {
531  flags << "GS";
532  }
533  *os << std::setw (6) << flags.str ();
534  *os << std::setw (7) << int(route->GetRouteMetric ());
535  // Ref ct not implemented
536  *os << "-" << " ";
537  // Use not implemented
538  *os << "-" << " ";
539  if (Names::FindName (m_ipv4->GetNetDevice (route->GetInterface ())) != "")
540  {
541  *os << Names::FindName (m_ipv4->GetNetDevice (route->GetInterface ()));
542  }
543  else
544  {
545  *os << route->GetInterface ();
546  }
547  *os << std::endl;
548  }
549  }
550  }
551  *os << std::endl;
552  // Restore the previous ostream state
553  (*os).copyfmt (oldState);
554 }
555 
557 {
558  NS_LOG_FUNCTION (this);
559 
560  for (RoutesI j = m_routes.begin (); j != m_routes.end (); j = m_routes.erase (j))
561  {
562  delete j->first;
563  }
564  m_routes.clear ();
565 
570 
571  for (SocketListI iter = m_unicastSocketList.begin (); iter != m_unicastSocketList.end (); iter++ )
572  {
573  iter->first->Close ();
574  }
575  m_unicastSocketList.clear ();
576 
579 
580  m_ipv4 = 0;
581 
583 }
584 
585 
587 {
588  NS_LOG_FUNCTION (this << dst << interface);
589 
590  Ptr<Ipv4Route> rtentry = 0;
591  uint16_t longestMask = 0;
592 
593  /* when sending on local multicast, there have to be interface specified */
594  if (dst.IsLocalMulticast ())
595  {
596  NS_ASSERT_MSG (interface, "Try to send on local multicast address, and no interface index is given!");
597  rtentry = Create<Ipv4Route> ();
598  rtentry->SetSource (m_ipv4->SourceAddressSelection (m_ipv4->GetInterfaceForDevice (interface), dst));
599  rtentry->SetDestination (dst);
600  rtentry->SetGateway (Ipv4Address::GetZero ());
601  rtentry->SetOutputDevice (interface);
602  return rtentry;
603  }
604 
605  for (RoutesI it = m_routes.begin (); it != m_routes.end (); it++)
606  {
607  RipRoutingTableEntry* j = it->first;
608 
610  {
611  Ipv4Mask mask = j->GetDestNetworkMask ();
612  uint16_t maskLen = mask.GetPrefixLength ();
613  Ipv4Address entry = j->GetDestNetwork ();
614 
615  NS_LOG_LOGIC ("Searching for route to " << dst << ", mask length " << maskLen);
616 
617  if (mask.IsMatch (dst, entry))
618  {
619  NS_LOG_LOGIC ("Found global network route " << j << ", mask length " << maskLen);
620 
621  /* if interface is given, check the route will output on this interface */
622  if (!interface || interface == m_ipv4->GetNetDevice (j->GetInterface ()))
623  {
624  if (maskLen < longestMask)
625  {
626  NS_LOG_LOGIC ("Previous match longer, skipping");
627  continue;
628  }
629 
630  longestMask = maskLen;
631 
632  Ipv4RoutingTableEntry* route = j;
633  uint32_t interfaceIdx = route->GetInterface ();
634  rtentry = Create<Ipv4Route> ();
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  rtentry->SetDestination (route->GetDest ());
646  rtentry->SetGateway (route->GetGateway ());
647  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
648  }
649  }
650  }
651  }
652 
653  if (rtentry)
654  {
655  NS_LOG_LOGIC ("Matching route via " << rtentry->GetDestination () << " (through " << rtentry->GetGateway () << ") at the end");
656  }
657  return rtentry;
658 }
659 
660 void Rip::AddNetworkRouteTo (Ipv4Address network, Ipv4Mask networkPrefix, Ipv4Address nextHop, uint32_t interface)
661 {
662  NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface);
663 
664  RipRoutingTableEntry* route = new RipRoutingTableEntry (network, networkPrefix, nextHop, interface);
665  route->SetRouteMetric (1);
667  route->SetRouteChanged (true);
668 
669  m_routes.push_back (std::make_pair (route, EventId ()));
670 }
671 
672 void Rip::AddNetworkRouteTo (Ipv4Address network, Ipv4Mask networkPrefix, uint32_t interface)
673 {
674  NS_LOG_FUNCTION (this << network << networkPrefix << interface);
675 
676  RipRoutingTableEntry* route = new RipRoutingTableEntry (network, networkPrefix, interface);
677  route->SetRouteMetric (1);
679  route->SetRouteChanged (true);
680 
681  m_routes.push_back (std::make_pair (route, EventId ()));
682 }
683 
685 {
686  NS_LOG_FUNCTION (this << *route);
687 
688  for (RoutesI it = m_routes.begin (); it != m_routes.end (); it++)
689  {
690  if (it->first == route)
691  {
693  route->SetRouteMetric (m_linkDown);
694  route->SetRouteChanged (true);
695  if (it->second.IsRunning ())
696  {
697  it->second.Cancel ();
698  }
699  it->second = Simulator::Schedule (m_garbageCollectionDelay, &Rip::DeleteRoute, this, route);
700  return;
701  }
702  }
703  NS_ABORT_MSG ("RIP::InvalidateRoute - cannot find the route to update");
704 }
705 
707 {
708  NS_LOG_FUNCTION (this << *route);
709 
710  for (RoutesI it = m_routes.begin (); it != m_routes.end (); it++)
711  {
712  if (it->first == route)
713  {
714  delete route;
715  m_routes.erase (it);
716  return;
717  }
718  }
719  NS_ABORT_MSG ("RIP::DeleteRoute - cannot find the route to delete");
720 }
721 
722 
724 {
725  NS_LOG_FUNCTION (this << socket);
726 
727  Address sender;
728  Ptr<Packet> packet = socket->RecvFrom (sender);
730  NS_LOG_INFO ("Received " << *packet << " from " << senderAddr.GetIpv4 () << ":" << senderAddr.GetPort ());
731 
732  Ipv4Address senderAddress = senderAddr.GetIpv4 ();
733  uint16_t senderPort = senderAddr.GetPort ();
734 
735  if (socket == m_multicastRecvSocket)
736  {
737  NS_LOG_LOGIC ("Received a packet from the multicast socket");
738  }
739  else
740  {
741  NS_LOG_LOGIC ("Received a packet from one of the unicast sockets");
742  }
743 
744  Ipv4PacketInfoTag interfaceInfo;
745  if (!packet->RemovePacketTag (interfaceInfo))
746  {
747  NS_ABORT_MSG ("No incoming interface on RIP message, aborting.");
748  }
749  uint32_t incomingIf = interfaceInfo.GetRecvIf ();
750  Ptr<Node> node = this->GetObject<Node> ();
751  Ptr<NetDevice> dev = node->GetDevice (incomingIf);
752  uint32_t ipInterfaceIndex = m_ipv4->GetInterfaceForDevice (dev);
753 
754  SocketIpTtlTag hoplimitTag;
755  if (!packet->RemovePacketTag (hoplimitTag))
756  {
757  NS_ABORT_MSG ("No incoming Hop Count on RIP message, aborting.");
758  }
759  uint8_t hopLimit = hoplimitTag.GetTtl ();
760 
761  int32_t interfaceForAddress = m_ipv4->GetInterfaceForAddress (senderAddress);
762  if (interfaceForAddress != -1)
763  {
764  NS_LOG_LOGIC ("Ignoring a packet sent by myself.");
765  return;
766  }
767 
768  RipHeader hdr;
769  packet->RemoveHeader (hdr);
770 
771  if (hdr.GetCommand () == RipHeader::RESPONSE)
772  {
773  NS_LOG_LOGIC ("The message is a Response from " << senderAddr.GetIpv4 () << ":" << senderAddr.GetPort ());
774  HandleResponses (hdr, senderAddress, ipInterfaceIndex, hopLimit);
775  }
776  else if (hdr.GetCommand () == RipHeader::REQUEST)
777  {
778  NS_LOG_LOGIC ("The message is a Request from " << senderAddr.GetIpv4 () << ":" << senderAddr.GetPort ());
779  HandleRequests (hdr, senderAddress, senderPort, ipInterfaceIndex, hopLimit);
780  }
781  else
782  {
783  NS_LOG_LOGIC ("Ignoring message with unknown command: " << int (hdr.GetCommand ()));
784  }
785  return;
786 }
787 
788 void Rip::HandleRequests (RipHeader requestHdr, Ipv4Address senderAddress, uint16_t senderPort, uint32_t incomingInterface, uint8_t hopLimit)
789 {
790  NS_LOG_FUNCTION (this << senderAddress << int (senderPort) << incomingInterface << int (hopLimit) << requestHdr);
791 
792  std::list<RipRte> rtes = requestHdr.GetRteList ();
793 
794  if (rtes.empty ())
795  {
796  return;
797  }
798 
799  // check if it's a request for the full table from a neighbor
800  if (rtes.size () == 1)
801  {
802  if (rtes.begin ()->GetPrefix () == Ipv4Address::GetAny () &&
803  rtes.begin ()->GetSubnetMask ().GetPrefixLength () == 0 &&
804  rtes.begin ()->GetRouteMetric () == m_linkDown)
805  {
806  // Output whole thing. Use Split Horizon
807  if (m_interfaceExclusions.find (incomingInterface) == m_interfaceExclusions.end ())
808  {
809  // we use one of the sending sockets, as they're bound to the right interface
810  // and the local address might be used on different interfaces.
811  Ptr<Socket> sendingSocket;
812  for (SocketListI iter = m_unicastSocketList.begin (); iter != m_unicastSocketList.end (); iter++ )
813  {
814  if (iter->second == incomingInterface)
815  {
816  sendingSocket = iter->first;
817  }
818  }
819  NS_ASSERT_MSG (sendingSocket, "HandleRequest - Impossible to find a socket to send the reply");
820 
821  uint16_t mtu = m_ipv4->GetMtu (incomingInterface);
822  uint16_t maxRte = (mtu - Ipv4Header ().GetSerializedSize () - UdpHeader ().GetSerializedSize () - RipHeader ().GetSerializedSize ()) / RipRte ().GetSerializedSize ();
823 
824  Ptr<Packet> p = Create<Packet> ();
825  SocketIpTtlTag tag;
826  p->RemovePacketTag (tag);
827  if (senderAddress == Ipv4Address(RIP_ALL_NODE))
828  {
829  tag.SetTtl (1);
830  }
831  else
832  {
833  tag.SetTtl (255);
834  }
835  p->AddPacketTag (tag);
836 
837  RipHeader hdr;
839 
840  for (RoutesI rtIter = m_routes.begin (); rtIter != m_routes.end (); rtIter++)
841  {
842  bool splitHorizoning = (rtIter->first->GetInterface () == incomingInterface);
843 
844  Ipv4InterfaceAddress rtDestAddr = Ipv4InterfaceAddress(rtIter->first->GetDestNetwork (), rtIter->first->GetDestNetworkMask ());
845 
846  bool isGlobal = (rtDestAddr.GetScope () == Ipv4InterfaceAddress::GLOBAL);
847  bool isDefaultRoute = ((rtIter->first->GetDestNetwork () == Ipv4Address::GetAny ()) &&
848  (rtIter->first->GetDestNetworkMask () == Ipv4Mask::GetZero ()) &&
849  (rtIter->first->GetInterface () != incomingInterface));
850 
851  if ((isGlobal || isDefaultRoute) &&
852  (rtIter->first->GetRouteStatus () == RipRoutingTableEntry::RIP_VALID) )
853  {
854  RipRte rte;
855  rte.SetPrefix (rtIter->first->GetDestNetwork ());
856  rte.SetSubnetMask (rtIter->first->GetDestNetworkMask ());
857  if (m_splitHorizonStrategy == POISON_REVERSE && splitHorizoning)
858  {
860  }
861  else
862  {
863  rte.SetRouteMetric (rtIter->first->GetRouteMetric ());
864  }
865  rte.SetRouteTag (rtIter->first->GetRouteTag ());
867  (m_splitHorizonStrategy == SPLIT_HORIZON && !splitHorizoning))
868  {
869  hdr.AddRte (rte);
870  }
871  }
872  if (hdr.GetRteNumber () == maxRte)
873  {
874  p->AddHeader (hdr);
875  NS_LOG_DEBUG ("SendTo: " << *p);
876  sendingSocket->SendTo (p, 0, InetSocketAddress (senderAddress, RIP_PORT));
877  p->RemoveHeader (hdr);
878  hdr.ClearRtes ();
879  }
880  }
881  if (hdr.GetRteNumber () > 0)
882  {
883  p->AddHeader (hdr);
884  NS_LOG_DEBUG ("SendTo: " << *p);
885  sendingSocket->SendTo (p, 0, InetSocketAddress (senderAddress, RIP_PORT));
886  }
887  }
888  }
889  }
890  else
891  {
892  // note: we got the request as a single packet, so no check is necessary for MTU limit
893 
894  Ptr<Packet> p = Create<Packet> ();
895  SocketIpTtlTag tag;
896  p->RemovePacketTag (tag);
897  if (senderAddress == Ipv4Address(RIP_ALL_NODE))
898  {
899  tag.SetTtl (1);
900  }
901  else
902  {
903  tag.SetTtl (255);
904  }
905  p->AddPacketTag (tag);
906 
907  RipHeader hdr;
909 
910  for (std::list<RipRte>::iterator iter = rtes.begin ();
911  iter != rtes.end (); iter++)
912  {
913  bool found = false;
914  for (RoutesI rtIter = m_routes.begin (); rtIter != m_routes.end (); rtIter++)
915  {
916 
917  Ipv4InterfaceAddress rtDestAddr = Ipv4InterfaceAddress (rtIter->first->GetDestNetwork (), rtIter->first->GetDestNetworkMask ());
918  if ((rtDestAddr.GetScope () == Ipv4InterfaceAddress::GLOBAL) &&
919  (rtIter->first->GetRouteStatus () == RipRoutingTableEntry::RIP_VALID))
920  {
921  Ipv4Address requestedAddress = iter->GetPrefix ();
922  requestedAddress.CombineMask (iter->GetSubnetMask ());
923  Ipv4Address rtAddress = rtIter->first->GetDestNetwork ();
924  rtAddress.CombineMask (rtIter->first->GetDestNetworkMask ());
925 
926  if (requestedAddress == rtAddress)
927  {
928  iter->SetRouteMetric (rtIter->first->GetRouteMetric ());
929  iter->SetRouteTag (rtIter->first->GetRouteTag ());
930  hdr.AddRte (*iter);
931  found = true;
932  break;
933  }
934  }
935  }
936  if (!found)
937  {
938  iter->SetRouteMetric (m_linkDown);
939  iter->SetRouteTag (0);
940  hdr.AddRte (*iter);
941  }
942  }
943  p->AddHeader (hdr);
944  NS_LOG_DEBUG ("SendTo: " << *p);
945  m_multicastRecvSocket->SendTo (p, 0, InetSocketAddress (senderAddress, senderPort));
946  }
947 
948 }
949 
950 void Rip::HandleResponses (RipHeader hdr, Ipv4Address senderAddress, uint32_t incomingInterface, uint8_t hopLimit)
951 {
952  NS_LOG_FUNCTION (this << senderAddress << incomingInterface << int (hopLimit) << hdr);
953 
954  if (m_interfaceExclusions.find (incomingInterface) != m_interfaceExclusions.end ())
955  {
956  NS_LOG_LOGIC ("Ignoring an update message from an excluded interface: " << incomingInterface);
957  return;
958  }
959 
960  std::list<RipRte> rtes = hdr.GetRteList ();
961 
962  // validate the RTEs before processing
963  for (std::list<RipRte>::iterator iter = rtes.begin ();
964  iter != rtes.end (); iter++)
965  {
966  if (iter->GetRouteMetric () == 0 || iter->GetRouteMetric () > m_linkDown)
967  {
968  NS_LOG_LOGIC ("Ignoring an update message with malformed metric: " << int (iter->GetRouteMetric ()));
969  return;
970  }
971  if (iter->GetPrefix ().IsLocalhost () ||
972  iter->GetPrefix ().IsBroadcast () ||
973  iter->GetPrefix ().IsMulticast ())
974  {
975  NS_LOG_LOGIC ("Ignoring an update message with wrong prefixes: " << iter->GetPrefix ());
976  return;
977  }
978  }
979 
980  bool changed = false;
981 
982  for (std::list<RipRte>::iterator iter = rtes.begin ();
983  iter != rtes.end (); iter++)
984  {
985  Ipv4Mask rtePrefixMask = iter->GetSubnetMask ();
986  Ipv4Address rteAddr = iter->GetPrefix ().CombineMask (rtePrefixMask);
987 
988  NS_LOG_LOGIC ("Processing RTE " << *iter);
989 
990  uint32_t interfaceMetric = 1;
991  if (m_interfaceMetrics.find (incomingInterface) != m_interfaceMetrics.end ())
992  {
993  interfaceMetric = m_interfaceMetrics[incomingInterface];
994  }
995  uint64_t rteMetric = iter->GetRouteMetric () + interfaceMetric;
996  if (rteMetric > m_linkDown)
997  {
998  rteMetric = m_linkDown;
999  }
1000 
1001  RoutesI it;
1002  bool found = false;
1003  for (it = m_routes.begin (); it != m_routes.end (); it++)
1004  {
1005  if (it->first->GetDestNetwork () == rteAddr &&
1006  it->first->GetDestNetworkMask () == rtePrefixMask)
1007  {
1008  found = true;
1009  if (rteMetric < it->first->GetRouteMetric ())
1010  {
1011  if (senderAddress != it->first->GetGateway ())
1012  {
1013  RipRoutingTableEntry* route = new RipRoutingTableEntry (rteAddr, rtePrefixMask, senderAddress, incomingInterface);
1014  delete it->first;
1015  it->first = route;
1016  }
1017  it->first->SetRouteMetric (rteMetric);
1018  it->first->SetRouteStatus (RipRoutingTableEntry::RIP_VALID);
1019  it->first->SetRouteTag (iter->GetRouteTag ());
1020  it->first->SetRouteChanged (true);
1021  it->second.Cancel ();
1022  it->second = Simulator::Schedule (m_timeoutDelay, &Rip::InvalidateRoute, this, it->first);
1023  changed = true;
1024  }
1025  else if (rteMetric == it->first->GetRouteMetric ())
1026  {
1027  if (senderAddress == it->first->GetGateway ())
1028  {
1029  it->second.Cancel ();
1030  it->second = Simulator::Schedule (m_timeoutDelay, &Rip::InvalidateRoute, this, it->first);
1031  }
1032  else
1033  {
1034  if (Simulator::GetDelayLeft (it->second) < m_timeoutDelay/2)
1035  {
1036  RipRoutingTableEntry* route = new RipRoutingTableEntry (rteAddr, rtePrefixMask, senderAddress, incomingInterface);
1037  route->SetRouteMetric (rteMetric);
1039  route->SetRouteTag (iter->GetRouteTag ());
1040  route->SetRouteChanged (true);
1041  delete it->first;
1042  it->first = route;
1043  it->second.Cancel ();
1044  it->second = Simulator::Schedule (m_timeoutDelay, &Rip::InvalidateRoute, this, route);
1045  changed = true;
1046  }
1047  }
1048  }
1049  else if (rteMetric > it->first->GetRouteMetric () && senderAddress == it->first->GetGateway ())
1050  {
1051  it->second.Cancel ();
1052  if (rteMetric < m_linkDown)
1053  {
1054  it->first->SetRouteMetric (rteMetric);
1055  it->first->SetRouteStatus (RipRoutingTableEntry::RIP_VALID);
1056  it->first->SetRouteTag (iter->GetRouteTag ());
1057  it->first->SetRouteChanged (true);
1058  it->second.Cancel ();
1059  it->second = Simulator::Schedule (m_timeoutDelay, &Rip::InvalidateRoute, this, it->first);
1060  }
1061  else
1062  {
1063  InvalidateRoute (it->first);
1064  }
1065  changed = true;
1066  }
1067  }
1068  }
1069  if (!found && rteMetric != m_linkDown)
1070  {
1071  NS_LOG_LOGIC ("Received a RTE with new route, adding.");
1072 
1073  RipRoutingTableEntry* route = new RipRoutingTableEntry (rteAddr, rtePrefixMask, senderAddress, incomingInterface);
1074  route->SetRouteMetric (rteMetric);
1076  route->SetRouteChanged (true);
1077  m_routes.push_front (std::make_pair (route, EventId ()));
1078  EventId invalidateEvent = Simulator::Schedule (m_timeoutDelay, &Rip::InvalidateRoute, this, route);
1079  (m_routes.begin ())->second = invalidateEvent;
1080  changed = true;
1081  }
1082  }
1083 
1084  if (changed)
1085  {
1087  }
1088 }
1089 
1090 void Rip::DoSendRouteUpdate (bool periodic)
1091 {
1092  NS_LOG_FUNCTION (this << (periodic ? " periodic" : " triggered"));
1093 
1094  for (SocketListI iter = m_unicastSocketList.begin (); iter != m_unicastSocketList.end (); iter++ )
1095  {
1096  uint32_t interface = iter->second;
1097 
1098  if (m_interfaceExclusions.find (interface) == m_interfaceExclusions.end ())
1099  {
1100  uint16_t mtu = m_ipv4->GetMtu (interface);
1101  uint16_t maxRte = (mtu - Ipv4Header ().GetSerializedSize () - UdpHeader ().GetSerializedSize () - RipHeader ().GetSerializedSize ()) / RipRte ().GetSerializedSize ();
1102 
1103  Ptr<Packet> p = Create<Packet> ();
1104  SocketIpTtlTag tag;
1105  tag.SetTtl (1);
1106  p->AddPacketTag (tag);
1107 
1108  RipHeader hdr;
1110 
1111  for (RoutesI rtIter = m_routes.begin (); rtIter != m_routes.end (); rtIter++)
1112  {
1113  bool splitHorizoning = (rtIter->first->GetInterface () == interface);
1114  Ipv4InterfaceAddress rtDestAddr = Ipv4InterfaceAddress(rtIter->first->GetDestNetwork (), rtIter->first->GetDestNetworkMask ());
1115 
1116  NS_LOG_DEBUG ("Processing RT " << rtDestAddr << " " << int(rtIter->first->IsRouteChanged ()));
1117 
1118  bool isGlobal = (rtDestAddr.GetScope () == Ipv4InterfaceAddress::GLOBAL);
1119  bool isDefaultRoute = ((rtIter->first->GetDestNetwork () == Ipv4Address::GetAny ()) &&
1120  (rtIter->first->GetDestNetworkMask () == Ipv4Mask::GetZero ()) &&
1121  (rtIter->first->GetInterface () != interface));
1122 
1123  bool sameNetwork = false;
1124  for (uint32_t index = 0; index < m_ipv4->GetNAddresses (interface); index++)
1125  {
1126  Ipv4InterfaceAddress addr = m_ipv4->GetAddress (interface, index);
1127  if (addr.GetLocal ().CombineMask (addr.GetMask ()) == rtIter->first->GetDestNetwork ())
1128  {
1129  sameNetwork = true;
1130  }
1131  }
1132 
1133  if ((isGlobal || isDefaultRoute) &&
1134  (periodic || rtIter->first->IsRouteChanged ()) &&
1135  !sameNetwork)
1136  {
1137  RipRte rte;
1138  rte.SetPrefix (rtIter->first->GetDestNetwork ());
1139  rte.SetSubnetMask (rtIter->first->GetDestNetworkMask ());
1140  if (m_splitHorizonStrategy == POISON_REVERSE && splitHorizoning)
1141  {
1142  rte.SetRouteMetric (m_linkDown);
1143  }
1144  else
1145  {
1146  rte.SetRouteMetric (rtIter->first->GetRouteMetric ());
1147  }
1148  rte.SetRouteTag (rtIter->first->GetRouteTag ());
1149  if (m_splitHorizonStrategy == SPLIT_HORIZON && !splitHorizoning)
1150  {
1151  hdr.AddRte (rte);
1152  }
1154  {
1155  hdr.AddRte (rte);
1156  }
1157  }
1158  if (hdr.GetRteNumber () == maxRte)
1159  {
1160  p->AddHeader (hdr);
1161  NS_LOG_DEBUG ("SendTo: " << *p);
1162  iter->first->SendTo (p, 0, InetSocketAddress (RIP_ALL_NODE, RIP_PORT));
1163  p->RemoveHeader (hdr);
1164  hdr.ClearRtes ();
1165  }
1166  }
1167  if (hdr.GetRteNumber () > 0)
1168  {
1169  p->AddHeader (hdr);
1170  NS_LOG_DEBUG ("SendTo: " << *p);
1171  iter->first->SendTo (p, 0, InetSocketAddress (RIP_ALL_NODE, RIP_PORT));
1172  }
1173  }
1174  }
1175  for (RoutesI rtIter = m_routes.begin (); rtIter != m_routes.end (); rtIter++)
1176  {
1177  rtIter->first->SetRouteChanged (false);
1178  }
1179 }
1180 
1182 {
1183  NS_LOG_FUNCTION (this);
1184 
1186  {
1187  NS_LOG_LOGIC ("Skipping Triggered Update due to cooldown");
1188  return;
1189  }
1190 
1191  // DoSendRouteUpdate (false);
1192 
1193  // note: The RFC states:
1194  // After a triggered
1195  // update is sent, a timer should be set for a random interval between 1
1196  // and 5 seconds. If other changes that would trigger updates occur
1197  // before the timer expires, a single update is triggered when the timer
1198  // expires. The timer is then reset to another random value between 1
1199  // and 5 seconds. Triggered updates may be suppressed if a regular
1200  // update is due by the time the triggered update would be sent.
1201  // Here we rely on this:
1202  // When an update occurs (either Triggered or Periodic) the "IsChanged ()"
1203  // route field will be cleared.
1204  // Hence, the following Triggered Update will be fired, but will not send
1205  // any route update.
1206 
1209 }
1210 
1212 {
1213  NS_LOG_FUNCTION (this);
1214 
1216  {
1218  }
1219 
1220  DoSendRouteUpdate (true);
1221 
1224 }
1225 
1226 std::set<uint32_t> Rip::GetInterfaceExclusions () const
1227 {
1228  return m_interfaceExclusions;
1229 }
1230 
1231 void Rip::SetInterfaceExclusions (std::set<uint32_t> exceptions)
1232 {
1233  NS_LOG_FUNCTION (this);
1234 
1235  m_interfaceExclusions = exceptions;
1236 }
1237 
1238 uint8_t Rip::GetInterfaceMetric (uint32_t interface) const
1239 {
1240  NS_LOG_FUNCTION (this << interface);
1241 
1242  std::map<uint32_t, uint8_t>::const_iterator iter = m_interfaceMetrics.find (interface);
1243  if (iter != m_interfaceMetrics.end ())
1244  {
1245  return iter->second;
1246  }
1247  return 1;
1248 }
1249 
1250 void Rip::SetInterfaceMetric (uint32_t interface, uint8_t metric)
1251 {
1252  NS_LOG_FUNCTION (this << interface << int (metric));
1253 
1254  if (metric < m_linkDown)
1255  {
1256  m_interfaceMetrics[interface] = metric;
1257  }
1258 }
1259 
1261 {
1262  NS_LOG_FUNCTION (this);
1263 
1264  Ptr<Packet> p = Create<Packet> ();
1265  SocketIpTtlTag tag;
1266  p->RemovePacketTag (tag);
1267  tag.SetTtl (1);
1268  p->AddPacketTag (tag);
1269 
1270  RipHeader hdr;
1272 
1273  RipRte rte;
1274  rte.SetPrefix (Ipv4Address::GetAny ());
1276  rte.SetRouteMetric (m_linkDown);
1277 
1278  hdr.AddRte (rte);
1279  p->AddHeader (hdr);
1280 
1281  for (SocketListI iter = m_unicastSocketList.begin (); iter != m_unicastSocketList.end (); iter++ )
1282  {
1283  uint32_t interface = iter->second;
1284 
1285  if (m_interfaceExclusions.find (interface) == m_interfaceExclusions.end ())
1286  {
1287  NS_LOG_DEBUG ("SendTo: " << *p);
1288  iter->first->SendTo (p, 0, InetSocketAddress (RIP_ALL_NODE, RIP_PORT));
1289  }
1290  }
1291 }
1292 
1293 void Rip::AddDefaultRouteTo (Ipv4Address nextHop, uint32_t interface)
1294 {
1295  NS_LOG_FUNCTION (this << interface);
1296 
1297  AddNetworkRouteTo (Ipv4Address ("0.0.0.0"), Ipv4Mask::GetZero (), nextHop, interface);
1298 }
1299 
1300 
1301 /*
1302  * RipRoutingTableEntry
1303  */
1304 
1306  : m_tag (0), m_metric (0), m_status (RIP_INVALID), m_changed (false)
1307 {
1308 }
1309 
1310 RipRoutingTableEntry::RipRoutingTableEntry (Ipv4Address network, Ipv4Mask networkPrefix, Ipv4Address nextHop, uint32_t interface)
1311  : Ipv4RoutingTableEntry ( Ipv4RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface) ),
1312  m_tag (0), m_metric (0), m_status (RIP_INVALID), m_changed (false)
1313 {
1314 }
1315 
1316 RipRoutingTableEntry::RipRoutingTableEntry (Ipv4Address network, Ipv4Mask networkPrefix, uint32_t interface)
1317  : Ipv4RoutingTableEntry ( Ipv4RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, interface) ),
1318  m_tag (0), m_metric (0), m_status (RIP_INVALID), m_changed (false)
1319 {
1320 }
1321 
1323 {
1324 }
1325 
1326 
1327 void RipRoutingTableEntry::SetRouteTag (uint16_t routeTag)
1328 {
1329  if (m_tag != routeTag)
1330  {
1331  m_tag = routeTag;
1332  m_changed = true;
1333  }
1334 }
1335 
1337 {
1338  return m_tag;
1339 }
1340 
1341 void RipRoutingTableEntry::SetRouteMetric (uint8_t routeMetric)
1342 {
1343  if (m_metric != routeMetric)
1344  {
1345  m_metric = routeMetric;
1346  m_changed = true;
1347  }
1348 }
1349 
1351 {
1352  return m_metric;
1353 }
1354 
1356 {
1357  if (m_status != status)
1358  {
1359  m_status = status;
1360  m_changed = true;
1361  }
1362 }
1363 
1365 {
1366  return m_status;
1367 }
1368 
1370 {
1371  m_changed = changed;
1372 }
1373 
1375 {
1376  return m_changed;
1377 }
1378 
1379 
1380 std::ostream & operator << (std::ostream& os, const RipRoutingTableEntry& rte)
1381 {
1382  os << static_cast<const Ipv4RoutingTableEntry &>(rte);
1383  os << ", metric: " << int (rte.GetRouteMetric ()) << ", tag: " << int (rte.GetRouteTag ());
1384 
1385  return os;
1386 }
1387 
1388 
1389 }
1390 
void SetInterfaceExclusions(std::set< uint32_t > exceptions)
Set the set of interface excluded from the protocol.
Definition: rip.cc:1231
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:788
void HandleResponses(RipHeader hdr, Ipv4Address senderAddress, uint32_t incomingInterface, uint8_t hopLimit)
Handle RIP responses.
Definition: rip.cc:950
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
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:429
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:1181
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:1211
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:586
virtual ~RipRoutingTableEntry()
Definition: rip.cc:1322
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:380
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:1305
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:1369
EventId m_nextUnsolicitedUpdate
Next Unsolicited Update event.
Definition: rip.h:395
void DoSendRouteUpdate(bool periodic)
Send Routing Updates on all interfaces.
Definition: rip.cc:1090
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
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:137
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:684
virtual void DoDispose()
Dispose this object.
Definition: rip.cc:556
void DeleteRoute(RipRoutingTableEntry *route)
Delete a route.
Definition: rip.cc:706
uint8_t GetInterfaceMetric(uint32_t interface) const
Get the metric for an interface.
Definition: rip.cc:1238
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:1353
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:1327
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:660
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
void SetRouteMetric(uint8_t routeMetric)
Set the route metric.
Definition: rip.cc:1341
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:1355
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:1260
uint16_t GetPort(void) const
void Receive(Ptr< Socket > socket)
Receive RIP packets.
Definition: rip.cc:723
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:1226
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:1354
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:1336
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:1293
Status_e GetRouteStatus(void) const
Get the route status.
Definition: rip.cc:1364
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:1289
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:1374
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:1250
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:533
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:1350
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