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