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 true;
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  Address sender;
715  Ptr<Packet> packet = socket->RecvFrom (sender);
717  NS_LOG_INFO ("Received " << *packet << " from " << senderAddr);
718 
719  Ipv4Address senderAddress = senderAddr.GetIpv4 ();
720  uint16_t senderPort = senderAddr.GetPort ();
721 
722  Ipv4PacketInfoTag interfaceInfo;
723  if (!packet->RemovePacketTag (interfaceInfo))
724  {
725  NS_ABORT_MSG ("No incoming interface on RIP message, aborting.");
726  }
727  uint32_t incomingIf = interfaceInfo.GetRecvIf ();
728  Ptr<Node> node = this->GetObject<Node> ();
729  Ptr<NetDevice> dev = node->GetDevice (incomingIf);
730  uint32_t ipInterfaceIndex = m_ipv4->GetInterfaceForDevice (dev);
731 
732  SocketIpTtlTag hoplimitTag;
733  if (!packet->RemovePacketTag (hoplimitTag))
734  {
735  NS_ABORT_MSG ("No incoming Hop Count on RIP message, aborting.");
736  }
737  uint8_t hopLimit = hoplimitTag.GetTtl ();
738 
739  int32_t interfaceForAddress = m_ipv4->GetInterfaceForAddress (senderAddress);
740  if (interfaceForAddress != -1)
741  {
742  NS_LOG_LOGIC ("Ignoring a packet sent by myself.");
743  return;
744  }
745 
746  RipHeader hdr;
747  packet->RemoveHeader (hdr);
748 
749  if (hdr.GetCommand () == RipHeader::RESPONSE)
750  {
751  HandleResponses (hdr, senderAddress, ipInterfaceIndex, hopLimit);
752  }
753  else if (hdr.GetCommand () == RipHeader::REQUEST)
754  {
755  HandleRequests (hdr, senderAddress, senderPort, ipInterfaceIndex, hopLimit);
756  }
757  else
758  {
759  NS_LOG_LOGIC ("Ignoring message with unknown command: " << int (hdr.GetCommand ()));
760  }
761  return;
762 }
763 
764 void Rip::HandleRequests (RipHeader requestHdr, Ipv4Address senderAddress, uint16_t senderPort, uint32_t incomingInterface, uint8_t hopLimit)
765 {
766  NS_LOG_FUNCTION (this << senderAddress << int (senderPort) << incomingInterface << int (hopLimit) << requestHdr);
767 
768  std::list<RipRte> rtes = requestHdr.GetRteList ();
769 
770  if (rtes.empty ())
771  {
772  return;
773  }
774 
775  // check if it's a request for the full table from a neighbor
776  if (rtes.size () == 1)
777  {
778  if (rtes.begin ()->GetPrefix () == Ipv4Address::GetAny () &&
779  rtes.begin ()->GetSubnetMask ().GetPrefixLength () == 0 &&
780  rtes.begin ()->GetRouteMetric () == m_linkDown)
781  {
782  // Output whole thing. Use Split Horizon
783  if (m_interfaceExclusions.find (incomingInterface) == m_interfaceExclusions.end ())
784  {
785  // we use one of the sending sockets, as they're bound to the right interface
786  // and the local address might be used on different interfaces.
787  Ptr<Socket> sendingSoket;
788  for (SocketListI iter = m_sendSocketList.begin (); iter != m_sendSocketList.end (); iter++ )
789  {
790  if (iter->second == incomingInterface)
791  {
792  sendingSoket = iter->first;
793  }
794  }
795  NS_ASSERT_MSG (sendingSoket, "HandleRequest - Impossible to find a socket to send the reply");
796 
797  uint16_t mtu = m_ipv4->GetMtu (incomingInterface);
798  uint16_t maxRte = (mtu - Ipv4Header ().GetSerializedSize () - UdpHeader ().GetSerializedSize () - RipHeader ().GetSerializedSize ()) / RipRte ().GetSerializedSize ();
799 
800  Ptr<Packet> p = Create<Packet> ();
801  SocketIpTtlTag tag;
802  p->RemovePacketTag (tag);
803  if (senderAddress == Ipv4Address(RIP_ALL_NODE))
804  {
805  tag.SetTtl (1);
806  }
807  else
808  {
809  tag.SetTtl (255);
810  }
811  p->AddPacketTag (tag);
812 
813  RipHeader hdr;
815 
816  for (RoutesI rtIter = m_routes.begin (); rtIter != m_routes.end (); rtIter++)
817  {
818  bool splitHorizoning = (rtIter->first->GetInterface () == incomingInterface);
819 
820  Ipv4InterfaceAddress rtDestAddr = Ipv4InterfaceAddress(rtIter->first->GetDestNetwork (), rtIter->first->GetDestNetworkMask ());
821 
822  bool isGlobal = (rtDestAddr.GetScope () == Ipv4InterfaceAddress::GLOBAL);
823  bool isDefaultRoute = ((rtIter->first->GetDestNetwork () == Ipv4Address::GetAny ()) &&
824  (rtIter->first->GetDestNetworkMask () == Ipv4Mask::GetZero ()) &&
825  (rtIter->first->GetInterface () != incomingInterface));
826 
827  if ((isGlobal || isDefaultRoute) &&
828  (rtIter->first->GetRouteStatus () == RipRoutingTableEntry::RIP_VALID) )
829  {
830  RipRte rte;
831  rte.SetPrefix (rtIter->first->GetDestNetwork ());
832  rte.SetSubnetMask (rtIter->first->GetDestNetworkMask ());
833  if (m_splitHorizonStrategy == POISON_REVERSE && splitHorizoning)
834  {
836  }
837  else
838  {
839  rte.SetRouteMetric (rtIter->first->GetRouteMetric ());
840  }
841  rte.SetRouteTag (rtIter->first->GetRouteTag ());
843  (m_splitHorizonStrategy == SPLIT_HORIZON && !splitHorizoning))
844  {
845  hdr.AddRte (rte);
846  }
847  }
848  if (hdr.GetRteNumber () == maxRte)
849  {
850  p->AddHeader (hdr);
851  NS_LOG_DEBUG ("SendTo: " << *p);
852  sendingSoket->SendTo (p, 0, InetSocketAddress (senderAddress, RIP_PORT));
853  p->RemoveHeader (hdr);
854  hdr.ClearRtes ();
855  }
856  }
857  if (hdr.GetRteNumber () > 0)
858  {
859  p->AddHeader (hdr);
860  NS_LOG_DEBUG ("SendTo: " << *p);
861  sendingSoket->SendTo (p, 0, InetSocketAddress (senderAddress, RIP_PORT));
862  }
863  }
864  }
865  }
866  else
867  {
868  // note: we got the request as a single packet, so no check is necessary for MTU limit
869 
870  Ptr<Packet> p = Create<Packet> ();
871  SocketIpTtlTag tag;
872  p->RemovePacketTag (tag);
873  if (senderAddress == Ipv4Address(RIP_ALL_NODE))
874  {
875  tag.SetTtl (1);
876  }
877  else
878  {
879  tag.SetTtl (255);
880  }
881  p->AddPacketTag (tag);
882 
883  RipHeader hdr;
885 
886  for (std::list<RipRte>::iterator iter = rtes.begin ();
887  iter != rtes.end (); iter++)
888  {
889  bool found = false;
890  for (RoutesI rtIter = m_routes.begin (); rtIter != m_routes.end (); rtIter++)
891  {
892 
893  Ipv4InterfaceAddress rtDestAddr = Ipv4InterfaceAddress (rtIter->first->GetDestNetwork (), rtIter->first->GetDestNetworkMask ());
894  if ((rtDestAddr.GetScope () == Ipv4InterfaceAddress::GLOBAL) &&
895  (rtIter->first->GetRouteStatus () == RipRoutingTableEntry::RIP_VALID))
896  {
897  Ipv4Address requestedAddress = iter->GetPrefix ();
898  requestedAddress.CombineMask (iter->GetSubnetMask ());
899  Ipv4Address rtAddress = rtIter->first->GetDestNetwork ();
900  rtAddress.CombineMask (rtIter->first->GetDestNetworkMask ());
901 
902  if (requestedAddress == rtAddress)
903  {
904  iter->SetRouteMetric (rtIter->first->GetRouteMetric ());
905  iter->SetRouteTag (rtIter->first->GetRouteTag ());
906  hdr.AddRte (*iter);
907  found = true;
908  break;
909  }
910  }
911  }
912  if (!found)
913  {
914  iter->SetRouteMetric (m_linkDown);
915  iter->SetRouteTag (0);
916  hdr.AddRte (*iter);
917  }
918  }
919  p->AddHeader (hdr);
920  NS_LOG_DEBUG ("SendTo: " << *p);
921  m_recvSocket->SendTo (p, 0, InetSocketAddress (senderAddress, senderPort));
922  }
923 
924 }
925 
926 void Rip::HandleResponses (RipHeader hdr, Ipv4Address senderAddress, uint32_t incomingInterface, uint8_t hopLimit)
927 {
928  NS_LOG_FUNCTION (this << senderAddress << incomingInterface << int (hopLimit) << hdr);
929 
930  if (m_interfaceExclusions.find (incomingInterface) != m_interfaceExclusions.end ())
931  {
932  NS_LOG_LOGIC ("Ignoring an update message from an excluded interface: " << incomingInterface);
933  return;
934  }
935 
936  std::list<RipRte> rtes = hdr.GetRteList ();
937 
938  // validate the RTEs before processing
939  for (std::list<RipRte>::iterator iter = rtes.begin ();
940  iter != rtes.end (); iter++)
941  {
942  if (iter->GetRouteMetric () == 0 || iter->GetRouteMetric () > m_linkDown)
943  {
944  NS_LOG_LOGIC ("Ignoring an update message with malformed metric: " << int (iter->GetRouteMetric ()));
945  return;
946  }
947  if (iter->GetPrefix ().IsLocalhost () ||
948  iter->GetPrefix ().IsBroadcast () ||
949  iter->GetPrefix ().IsMulticast ())
950  {
951  NS_LOG_LOGIC ("Ignoring an update message with wrong prefixes: " << iter->GetPrefix ());
952  return;
953  }
954  }
955 
956  bool changed = false;
957 
958  for (std::list<RipRte>::iterator iter = rtes.begin ();
959  iter != rtes.end (); iter++)
960  {
961  Ipv4Mask rtePrefixMask = iter->GetSubnetMask ();
962  Ipv4Address rteAddr = iter->GetPrefix ().CombineMask (rtePrefixMask);
963 
964  NS_LOG_LOGIC ("Processing RTE " << *iter);
965 
966  uint32_t interfaceMetric = 1;
967  if (m_interfaceMetrics.find (incomingInterface) != m_interfaceMetrics.end ())
968  {
969  interfaceMetric = m_interfaceMetrics[incomingInterface];
970  }
971  uint64_t rteMetric = iter->GetRouteMetric () + interfaceMetric;
972  if (rteMetric > m_linkDown)
973  {
974  rteMetric = m_linkDown;
975  }
976 
977  RoutesI it;
978  bool found = false;
979  for (it = m_routes.begin (); it != m_routes.end (); it++)
980  {
981  if (it->first->GetDestNetwork () == rteAddr &&
982  it->first->GetDestNetworkMask () == rtePrefixMask)
983  {
984  found = true;
985  if (rteMetric < it->first->GetRouteMetric ())
986  {
987  if (senderAddress != it->first->GetGateway ())
988  {
989  RipRoutingTableEntry* route = new RipRoutingTableEntry (rteAddr, rtePrefixMask, senderAddress, incomingInterface);
990  delete it->first;
991  it->first = route;
992  }
993  it->first->SetRouteMetric (rteMetric);
994  it->first->SetRouteStatus (RipRoutingTableEntry::RIP_VALID);
995  it->first->SetRouteTag (iter->GetRouteTag ());
996  it->first->SetRouteChanged (true);
997  it->second.Cancel ();
998  it->second = Simulator::Schedule (m_timeoutDelay, &Rip::InvalidateRoute, this, it->first);
999  changed = true;
1000  }
1001  else if (rteMetric == it->first->GetRouteMetric ())
1002  {
1003  if (senderAddress == it->first->GetGateway ())
1004  {
1005  it->second.Cancel ();
1006  it->second = Simulator::Schedule (m_timeoutDelay, &Rip::InvalidateRoute, this, it->first);
1007  }
1008  else
1009  {
1010  if (Simulator::GetDelayLeft (it->second) < m_timeoutDelay/2)
1011  {
1012  RipRoutingTableEntry* route = new RipRoutingTableEntry (rteAddr, rtePrefixMask, senderAddress, incomingInterface);
1013  route->SetRouteMetric (rteMetric);
1015  route->SetRouteTag (iter->GetRouteTag ());
1016  route->SetRouteChanged (true);
1017  delete it->first;
1018  it->first = route;
1019  it->second.Cancel ();
1020  it->second = Simulator::Schedule (m_timeoutDelay, &Rip::InvalidateRoute, this, route);
1021  changed = true;
1022  }
1023  }
1024  }
1025  else if (rteMetric > it->first->GetRouteMetric () && senderAddress == it->first->GetGateway ())
1026  {
1027  it->second.Cancel ();
1028  if (rteMetric < m_linkDown)
1029  {
1030  it->first->SetRouteMetric (rteMetric);
1031  it->first->SetRouteStatus (RipRoutingTableEntry::RIP_VALID);
1032  it->first->SetRouteTag (iter->GetRouteTag ());
1033  it->first->SetRouteChanged (true);
1034  it->second.Cancel ();
1035  it->second = Simulator::Schedule (m_timeoutDelay, &Rip::InvalidateRoute, this, it->first);
1036  }
1037  else
1038  {
1039  InvalidateRoute (it->first);
1040  }
1041  changed = true;
1042  }
1043  }
1044  }
1045  if (!found && rteMetric != m_linkDown)
1046  {
1047  NS_LOG_LOGIC ("Received a RTE with new route, adding.");
1048 
1049  RipRoutingTableEntry* route = new RipRoutingTableEntry (rteAddr, rtePrefixMask, senderAddress, incomingInterface);
1050  route->SetRouteMetric (rteMetric);
1052  route->SetRouteChanged (true);
1053  m_routes.push_front (std::make_pair (route, EventId ()));
1054  EventId invalidateEvent = Simulator::Schedule (m_timeoutDelay, &Rip::InvalidateRoute, this, route);
1055  (m_routes.begin ())->second = invalidateEvent;
1056  changed = true;
1057  }
1058  }
1059 
1060  if (changed)
1061  {
1063  }
1064 }
1065 
1066 void Rip::DoSendRouteUpdate (bool periodic)
1067 {
1068  NS_LOG_FUNCTION (this << (periodic ? " periodic" : " triggered"));
1069 
1070  for (SocketListI iter = m_sendSocketList.begin (); iter != m_sendSocketList.end (); iter++ )
1071  {
1072  uint32_t interface = iter->second;
1073 
1074  if (m_interfaceExclusions.find (interface) == m_interfaceExclusions.end ())
1075  {
1076  uint16_t mtu = m_ipv4->GetMtu (interface);
1077  uint16_t maxRte = (mtu - Ipv4Header ().GetSerializedSize () - UdpHeader ().GetSerializedSize () - RipHeader ().GetSerializedSize ()) / RipRte ().GetSerializedSize ();
1078 
1079  Ptr<Packet> p = Create<Packet> ();
1080  SocketIpTtlTag tag;
1081  tag.SetTtl (1);
1082  p->AddPacketTag (tag);
1083 
1084  RipHeader hdr;
1086 
1087  for (RoutesI rtIter = m_routes.begin (); rtIter != m_routes.end (); rtIter++)
1088  {
1089  bool splitHorizoning = (rtIter->first->GetInterface () == interface);
1090  Ipv4InterfaceAddress rtDestAddr = Ipv4InterfaceAddress(rtIter->first->GetDestNetwork (), rtIter->first->GetDestNetworkMask ());
1091 
1092  NS_LOG_DEBUG ("Processing RT " << rtDestAddr << " " << int(rtIter->first->IsRouteChanged ()));
1093 
1094  bool isGlobal = (rtDestAddr.GetScope () == Ipv4InterfaceAddress::GLOBAL);
1095  bool isDefaultRoute = ((rtIter->first->GetDestNetwork () == Ipv4Address::GetAny ()) &&
1096  (rtIter->first->GetDestNetworkMask () == Ipv4Mask::GetZero ()) &&
1097  (rtIter->first->GetInterface () != interface));
1098 
1099  bool sameNetwork = false;
1100  for (uint32_t index = 0; index < m_ipv4->GetNAddresses (interface); index++)
1101  {
1102  Ipv4InterfaceAddress addr = m_ipv4->GetAddress (interface, index);
1103  if (addr.GetLocal ().CombineMask (addr.GetMask ()) == rtIter->first->GetDestNetwork ())
1104  {
1105  sameNetwork = true;
1106  }
1107  }
1108 
1109  if ((isGlobal || isDefaultRoute) &&
1110  (periodic || rtIter->first->IsRouteChanged ()) &&
1111  !sameNetwork)
1112  {
1113  RipRte rte;
1114  rte.SetPrefix (rtIter->first->GetDestNetwork ());
1115  rte.SetSubnetMask (rtIter->first->GetDestNetworkMask ());
1116  if (m_splitHorizonStrategy == POISON_REVERSE && splitHorizoning)
1117  {
1118  rte.SetRouteMetric (m_linkDown);
1119  }
1120  else
1121  {
1122  rte.SetRouteMetric (rtIter->first->GetRouteMetric ());
1123  }
1124  rte.SetRouteTag (rtIter->first->GetRouteTag ());
1125  if (m_splitHorizonStrategy == SPLIT_HORIZON && !splitHorizoning)
1126  {
1127  hdr.AddRte (rte);
1128  }
1130  {
1131  hdr.AddRte (rte);
1132  }
1133  }
1134  if (hdr.GetRteNumber () == maxRte)
1135  {
1136  p->AddHeader (hdr);
1137  NS_LOG_DEBUG ("SendTo: " << *p);
1138  iter->first->SendTo (p, 0, InetSocketAddress (RIP_ALL_NODE, RIP_PORT));
1139  p->RemoveHeader (hdr);
1140  hdr.ClearRtes ();
1141  }
1142  }
1143  if (hdr.GetRteNumber () > 0)
1144  {
1145  p->AddHeader (hdr);
1146  NS_LOG_DEBUG ("SendTo: " << *p);
1147  iter->first->SendTo (p, 0, InetSocketAddress (RIP_ALL_NODE, RIP_PORT));
1148  }
1149  }
1150  }
1151  for (RoutesI rtIter = m_routes.begin (); rtIter != m_routes.end (); rtIter++)
1152  {
1153  rtIter->first->SetRouteChanged (false);
1154  }
1155 }
1156 
1158 {
1159  NS_LOG_FUNCTION (this);
1160 
1162  {
1163  NS_LOG_LOGIC ("Skipping Triggered Update due to cooldown");
1164  return;
1165  }
1166 
1167  // DoSendRouteUpdate (false);
1168 
1169  // note: The RFC states:
1170  // After a triggered
1171  // update is sent, a timer should be set for a random interval between 1
1172  // and 5 seconds. If other changes that would trigger updates occur
1173  // before the timer expires, a single update is triggered when the timer
1174  // expires. The timer is then reset to another random value between 1
1175  // and 5 seconds. Triggered updates may be suppressed if a regular
1176  // update is due by the time the triggered update would be sent.
1177  // Here we rely on this:
1178  // When an update occurs (either Triggered or Periodic) the "IsChanged ()"
1179  // route field will be cleared.
1180  // Hence, the following Triggered Update will be fired, but will not send
1181  // any route update.
1182 
1185 }
1186 
1188 {
1189  NS_LOG_FUNCTION (this);
1190 
1192  {
1194  }
1195 
1196  DoSendRouteUpdate (true);
1197 
1200 }
1201 
1202 std::set<uint32_t> Rip::GetInterfaceExclusions () const
1203 {
1204  return m_interfaceExclusions;
1205 }
1206 
1207 void Rip::SetInterfaceExclusions (std::set<uint32_t> exceptions)
1208 {
1209  NS_LOG_FUNCTION (this);
1210 
1211  m_interfaceExclusions = exceptions;
1212 }
1213 
1214 uint8_t Rip::GetInterfaceMetric (uint32_t interface) const
1215 {
1216  NS_LOG_FUNCTION (this << interface);
1217 
1218  std::map<uint32_t, uint8_t>::const_iterator iter = m_interfaceMetrics.find (interface);
1219  if (iter != m_interfaceMetrics.end ())
1220  {
1221  return iter->second;
1222  }
1223  return 1;
1224 }
1225 
1226 void Rip::SetInterfaceMetric (uint32_t interface, uint8_t metric)
1227 {
1228  NS_LOG_FUNCTION (this << interface << int (metric));
1229 
1230  if (metric < m_linkDown)
1231  {
1232  m_interfaceMetrics[interface] = metric;
1233  }
1234 }
1235 
1237 {
1238  NS_LOG_FUNCTION (this);
1239 
1240  Ptr<Packet> p = Create<Packet> ();
1241  SocketIpTtlTag tag;
1242  p->RemovePacketTag (tag);
1243  tag.SetTtl (1);
1244  p->AddPacketTag (tag);
1245 
1246  RipHeader hdr;
1248 
1249  RipRte rte;
1250  rte.SetPrefix (Ipv4Address::GetAny ());
1252  rte.SetRouteMetric (m_linkDown);
1253 
1254  hdr.AddRte (rte);
1255  p->AddHeader (hdr);
1256 
1257  for (SocketListI iter = m_sendSocketList.begin (); iter != m_sendSocketList.end (); iter++ )
1258  {
1259  uint32_t interface = iter->second;
1260 
1261  if (m_interfaceExclusions.find (interface) == m_interfaceExclusions.end ())
1262  {
1263  NS_LOG_DEBUG ("SendTo: " << *p);
1264  iter->first->SendTo (p, 0, InetSocketAddress (RIP_ALL_NODE, RIP_PORT));
1265  }
1266  }
1267 }
1268 
1269 void Rip::AddDefaultRouteTo (Ipv4Address nextHop, uint32_t interface)
1270 {
1271  NS_LOG_FUNCTION (this << interface);
1272 
1273  AddNetworkRouteTo (Ipv4Address ("0.0.0.0"), Ipv4Mask::GetZero (), nextHop, interface);
1274 }
1275 
1276 
1277 /*
1278  * RipRoutingTableEntry
1279  */
1280 
1282  : m_tag (0), m_metric (0), m_status (RIP_INVALID), m_changed (false)
1283 {
1284 }
1285 
1286 RipRoutingTableEntry::RipRoutingTableEntry (Ipv4Address network, Ipv4Mask networkPrefix, Ipv4Address nextHop, uint32_t interface)
1287  : Ipv4RoutingTableEntry ( Ipv4RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface) ),
1288  m_tag (0), m_metric (0), m_status (RIP_INVALID), m_changed (false)
1289 {
1290 }
1291 
1292 RipRoutingTableEntry::RipRoutingTableEntry (Ipv4Address network, Ipv4Mask networkPrefix, uint32_t interface)
1293  : Ipv4RoutingTableEntry ( Ipv4RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, interface) ),
1294  m_tag (0), m_metric (0), m_status (RIP_INVALID), m_changed (false)
1295 {
1296 }
1297 
1299 {
1300 }
1301 
1302 
1303 void RipRoutingTableEntry::SetRouteTag (uint16_t routeTag)
1304 {
1305  if (m_tag != routeTag)
1306  {
1307  m_tag = routeTag;
1308  m_changed = true;
1309  }
1310 }
1311 
1313 {
1314  return m_tag;
1315 }
1316 
1317 void RipRoutingTableEntry::SetRouteMetric (uint8_t routeMetric)
1318 {
1319  if (m_metric != routeMetric)
1320  {
1321  m_metric = routeMetric;
1322  m_changed = true;
1323  }
1324 }
1325 
1327 {
1328  return m_metric;
1329 }
1330 
1332 {
1333  if (m_status != status)
1334  {
1335  m_status = status;
1336  m_changed = true;
1337  }
1338 }
1339 
1341 {
1342  return m_status;
1343 }
1344 
1346 {
1347  m_changed = changed;
1348 }
1349 
1351 {
1352  return m_changed;
1353 }
1354 
1355 
1356 std::ostream & operator << (std::ostream& os, const RipRoutingTableEntry& rte)
1357 {
1358  os << static_cast<const Ipv4RoutingTableEntry &>(rte);
1359  os << ", metric: " << int (rte.GetRouteMetric ()) << ", tag: " << int (rte.GetRouteTag ());
1360 
1361  return os;
1362 }
1363 
1364 
1365 }
1366 
void SetInterfaceExclusions(std::set< uint32_t > exceptions)
Set the set of interface excluded from the protocol.
Definition: rip.cc:1207
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:233
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:374
void HandleRequests(RipHeader hdr, Ipv4Address senderAddress, uint16_t senderPort, uint32_t incomingInterface, uint8_t hopLimit)
Handle RIP requests.
Definition: rip.cc:764
void HandleResponses(RipHeader hdr, Ipv4Address senderAddress, uint32_t incomingInterface, uint8_t hopLimit)
Handle RIP responses.
Definition: rip.cc:926
bool m_initialized
flag to allow socket's late-creation.
Definition: rip.h:404
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:1157
virtual void DoInitialize(void)
Initialize() implementation.
Definition: object.cc:353
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
Ipv4Address GetIpv4(void) const
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:1176
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:380
void SendUnsolicitedRouteUpdate(void)
Send Unsolicited Routing Updates on all interfaces.
Definition: rip.cc:1187
#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:1298
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:257
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:375
uint32_t m_linkDown
Link down value.
Definition: rip.h:405
std::list< std::pair< RipRoutingTableEntry *, EventId > >::iterator RoutesI
Iterator for container for the network routes.
Definition: rip.h:274
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:400
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:1270
Status_e GetRouteStatus(void) const
Get the route status.
Definition: rip.cc:1340
#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:346
RipRoutingTableEntry(void)
Definition: rip.cc:1281
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer...
Definition: socket.h:1112
Poison Reverse Split Horizon.
Definition: rip.h:205
Command_e GetCommand(void) const
Get the command.
Definition: rip-header.cc:244
No Split Horizon.
Definition: rip.h:203
a polymophic address class
Definition: address.h:90
void SetRouteChanged(bool changed)
Set the route as changed.
Definition: rip.cc:1345
EventId m_nextUnsolicitedUpdate
Next Unsolicited Update event.
Definition: rip.h:394
bool IsRouteChanged(void) const
Get the route changed status.
Definition: rip.cc:1350
void DoSendRouteUpdate(bool periodic)
Send Routing Updates on all interfaces.
Definition: rip.cc:1066
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:33
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:373
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:1238
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition: socket.cc:610
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:1214
RIP Routing Protocol, defined in RFC 2453.
Definition: rip.h:173
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:1303
Split Horizon.
Definition: rip.h:204
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:271
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:142
std::set< uint32_t > m_interfaceExclusions
Set of excluded interfaces.
Definition: rip.h:399
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
std::map< Ptr< Socket >, uint32_t >::iterator SocketListI
Socket list type iterator.
Definition: rip.h:387
#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:154
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:1312
#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:151
Ipv4Address GetGateway(void) const
Definition: ipv4-route.cc:70
Status_e
Route status.
Definition: rip.h:70
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:1317
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:1331
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
Definition: rip.cc:427
void SendRouteRequest()
Send Routing Request on all interfaces.
Definition: rip.cc:1236
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:153
virtual void NotifyInterfaceUp(uint32_t interface)
Definition: rip.cc:290
Ipv4Address GetDest(void) const
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:958
void DoInitialize()
Start protocol operation.
Definition: rip.cc:110
Time m_unsolicitedUpdate
time between two Unsolicited Routing Updates
Definition: rip.h:378
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:395
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:402
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:1269
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
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:831
Ptr< Socket > m_recvSocket
receive socket
Definition: rip.h:392
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:1326
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:1226
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:340
uint16_t GetPort(void) const
tuple address
Definition: first.py:37
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:371
Rip Routing Table Entry.
Definition: rip.h:63
uint8_t GetTtl(void) const
Get the tag's TTL.
Definition: socket.cc:617
Time m_minTriggeredUpdateDelay
Min cooldown delay after a Triggered Update.
Definition: rip.h:376
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:397
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:904
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:377
SocketList m_sendSocketList
list of sockets for sending (socket, interface index)
Definition: rip.h:391
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:813
Time m_timeoutDelay
Delay before invalidating a route.
Definition: rip.h:379
std::set< uint32_t > GetInterfaceExclusions() const
Get the set of interface excluded from the protocol.
Definition: rip.cc:1202