1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2016 Universita' di Firenze
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 "ns3/test.h"
22 #include "ns3/socket-factory.h"
23 #include "ns3/udp-socket-factory.h"
24 #include "ns3/simulator.h"
25 #include "ns3/simple-channel.h"
26 #include "ns3/simple-net-device.h"
27 #include "ns3/socket.h"
28 #include "ns3/boolean.h"
29 #include "ns3/enum.h"
30 
31 #include "ns3/log.h"
32 #include "ns3/node.h"
33 #include "ns3/inet-socket-address.h"
34 
35 #include "ns3/internet-stack-helper.h"
36 #include "ns3/ipv4-address-helper.h"
37 #include "ns3/ipv4-l3-protocol.h"
38 #include "ns3/icmpv4-l4-protocol.h"
39 #include "ns3/udp-l4-protocol.h"
40 #include "ns3/rip.h"
41 #include "ns3/rip-helper.h"
42 #include "ns3/node-container.h"
43 #include "ns3/ipv4-static-routing.h"
44 
45 #include <string>
46 #include <limits>
47 
48 using namespace ns3;
49 
50 /**
51  * \ingroup internet-test
52  * \ingroup tests
53  *
54  * \brief IPv4 RIP Test
55  */
56 class Ipv4RipTest : public TestCase
57 {
58   Ptr<Packet> m_receivedPacket; //!< Received packet
59 
60   /**
61    * \brief Send data.
62    * \param socket The sending socket.
63    * \param to Destination address.
64    */
65   void DoSendData (Ptr<Socket> socket, std::string to);
66   /**
67    * \brief Send data.
68    * \param socket The sending socket.
69    * \param to Destination address.
70    */
71   void SendData (Ptr<Socket> socket, std::string to);
72 
73 public:
74   virtual void DoRun (void);
75   Ipv4RipTest ();
76 
77   /**
78    * \brief Receive data.
79    * \param socket The receiving socket.
80    */
81   void ReceivePkt (Ptr<Socket> socket);
82 };
83 
Ipv4RipTest()84 Ipv4RipTest::Ipv4RipTest ()
85   : TestCase ("RIP")
86 {
87 }
88 
ReceivePkt(Ptr<Socket> socket)89 void Ipv4RipTest::ReceivePkt (Ptr<Socket> socket)
90 {
91   uint32_t availableData;
92   availableData = socket->GetRxAvailable ();
93   m_receivedPacket = socket->Recv (std::numeric_limits<uint32_t>::max (), 0);
94   NS_ASSERT (availableData == m_receivedPacket->GetSize ());
95   //cast availableData to void, to suppress 'availableData' set but not used
96   //compiler warning
97   (void) availableData;
98 }
99 
100 void
DoSendData(Ptr<Socket> socket,std::string to)101 Ipv4RipTest::DoSendData (Ptr<Socket> socket, std::string to)
102 {
103   Address realTo = InetSocketAddress (Ipv4Address (to.c_str ()), 1234);
104   NS_TEST_EXPECT_MSG_EQ (socket->SendTo (Create<Packet> (123), 0, realTo),
105                          123, "100");
106 }
107 
108 void
SendData(Ptr<Socket> socket,std::string to)109 Ipv4RipTest::SendData (Ptr<Socket> socket, std::string to)
110 {
111   m_receivedPacket = Create<Packet> ();
112   Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), Seconds (60),
113                                   &Ipv4RipTest::DoSendData, this, socket, to);
114   Simulator::Stop (Seconds (66));
115   Simulator::Run ();
116 }
117 
118 void
DoRun(void)119 Ipv4RipTest::DoRun (void)
120 {
121   // Create topology
122 
123   Ptr<Node> txNode = CreateObject<Node> ();
124   Ptr<Node> rxNode = CreateObject<Node> ();
125   Ptr<Node> routerA = CreateObject<Node> ();
126   Ptr<Node> routerB = CreateObject<Node> ();
127   Ptr<Node> routerC = CreateObject<Node> ();
128 
129   NodeContainer nodes (txNode, rxNode);
130   NodeContainer routers (routerA, routerB, routerC);
131   NodeContainer all (nodes, routers);
132 
133   RipHelper ripRouting;
134   InternetStackHelper internetRouters;
135   internetRouters.SetRoutingHelper (ripRouting);
136   internetRouters.Install (routers);
137 
138   InternetStackHelper internetNodes;
139   internetNodes.Install (nodes);
140 
141   NetDeviceContainer net1;
142   NetDeviceContainer net2;
143   NetDeviceContainer net3;
144   NetDeviceContainer net4;
145 
146   // Sender Node
147   Ptr<SimpleNetDevice> txDev;
148   {
149     txDev = CreateObject<SimpleNetDevice> ();
150     txDev->SetAddress (Mac48Address ("00:00:00:00:00:01"));
151     txNode->AddDevice (txDev);
152   }
153   net1.Add (txDev);
154 
155   // Router A
156   Ptr<SimpleNetDevice> fwDev1routerA, fwDev2routerA;
157   { // first interface
158     fwDev1routerA = CreateObject<SimpleNetDevice> ();
159     fwDev1routerA->SetAddress (Mac48Address ("00:00:00:00:00:02"));
160     routerA->AddDevice (fwDev1routerA);
161   }
162   net1.Add (fwDev1routerA);
163 
164   { // second interface
165     fwDev2routerA = CreateObject<SimpleNetDevice> ();
166     fwDev2routerA->SetAddress (Mac48Address ("00:00:00:00:00:03"));
167     routerA->AddDevice (fwDev2routerA);
168   }
169   net2.Add (fwDev2routerA);
170 
171   // Router B
172   Ptr<SimpleNetDevice> fwDev1routerB, fwDev2routerB;
173   { // first interface
174     fwDev1routerB = CreateObject<SimpleNetDevice> ();
175     fwDev1routerB->SetAddress (Mac48Address ("00:00:00:00:00:04"));
176     routerB->AddDevice (fwDev1routerB);
177   }
178   net2.Add (fwDev1routerB);
179 
180   { // second interface
181     fwDev2routerB = CreateObject<SimpleNetDevice> ();
182     fwDev2routerB->SetAddress (Mac48Address ("00:00:00:00:00:05"));
183     routerB->AddDevice (fwDev2routerB);
184   }
185   net3.Add (fwDev2routerB);
186 
187   // Router C
188   Ptr<SimpleNetDevice> fwDev1routerC, fwDev2routerC;
189   { // first interface
190     fwDev1routerC = CreateObject<SimpleNetDevice> ();
191     fwDev1routerC->SetAddress (Mac48Address ("00:00:00:00:00:06"));
192     routerC->AddDevice (fwDev1routerC);
193   }
194   net3.Add (fwDev1routerC);
195 
196   { // second interface
197     fwDev2routerC = CreateObject<SimpleNetDevice> ();
198     fwDev2routerC->SetAddress (Mac48Address ("00:00:00:00:00:07"));
199     routerC->AddDevice (fwDev2routerC);
200   }
201   net4.Add (fwDev2routerC);
202 
203   // Rx node
204   Ptr<SimpleNetDevice> rxDev;
205   { // first interface
206     rxDev = CreateObject<SimpleNetDevice> ();
207     rxDev->SetAddress (Mac48Address ("00:00:00:00:00:08"));
208     rxNode->AddDevice (rxDev);
209   }
210   net4.Add (rxDev);
211 
212   // link the channels
213   Ptr<SimpleChannel> channel1 = CreateObject<SimpleChannel> ();
214   txDev->SetChannel (channel1);
215   fwDev1routerA->SetChannel (channel1);
216 
217   Ptr<SimpleChannel> channel2 = CreateObject<SimpleChannel> ();
218   fwDev2routerA->SetChannel (channel2);
219   fwDev1routerB->SetChannel (channel2);
220 
221   Ptr<SimpleChannel> channel3 = CreateObject<SimpleChannel> ();
222   fwDev2routerB->SetChannel (channel3);
223   fwDev1routerC->SetChannel (channel3);
224 
225   Ptr<SimpleChannel> channel4 = CreateObject<SimpleChannel> ();
226   fwDev2routerC->SetChannel (channel4);
227   rxDev->SetChannel (channel4);
228 
229   // Setup IPv4 addresses and forwarding
230   Ipv4AddressHelper ipv4;
231 
232   ipv4.SetBase (Ipv4Address ("10.0.1.0"), Ipv4Mask ("255.255.255.0"));
233   Ipv4InterfaceContainer iic1 = ipv4.Assign (net1);
234 
235   ipv4.SetBase (Ipv4Address ("192.168.0.0"), Ipv4Mask ("255.255.255.0"));
236   Ipv4InterfaceContainer iic2 = ipv4.Assign (net2);
237 
238   ipv4.SetBase (Ipv4Address ("192.168.1.0"), Ipv4Mask ("255.255.255.0"));
239   Ipv4InterfaceContainer iic3 = ipv4.Assign (net3);
240 
241   ipv4.SetBase (Ipv4Address ("10.0.2.0"), Ipv4Mask ("255.255.255.0"));
242   Ipv4InterfaceContainer iic4 = ipv4.Assign (net4);
243 
244   Ptr<Ipv4StaticRouting> staticRouting;
245   staticRouting = Ipv4RoutingHelper::GetRouting <Ipv4StaticRouting> (txNode->GetObject<Ipv4> ()->GetRoutingProtocol ());
246   staticRouting->SetDefaultRoute ("10.0.1.2", 1 );
247   staticRouting = Ipv4RoutingHelper::GetRouting <Ipv4StaticRouting> (rxNode->GetObject<Ipv4> ()->GetRoutingProtocol ());
248   staticRouting->SetDefaultRoute ("10.0.2.1", 1 );
249 
250   // Create the UDP sockets
251   Ptr<SocketFactory> rxSocketFactory = rxNode->GetObject<UdpSocketFactory> ();
252   Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket ();
253   NS_TEST_EXPECT_MSG_EQ (rxSocket->Bind (InetSocketAddress (Ipv4Address ("10.0.2.2"), 1234)), 0, "trivial");
254   rxSocket->SetRecvCallback (MakeCallback (&Ipv4RipTest::ReceivePkt, this));
255 
256   Ptr<SocketFactory> txSocketFactory = txNode->GetObject<UdpSocketFactory> ();
257   Ptr<Socket> txSocket = txSocketFactory->CreateSocket ();
258   txSocket->SetAllowBroadcast (true);
259 
260   // ------ Now the tests ------------
261 
262   // Unicast test
263   SendData (txSocket, "10.0.2.2");
264   NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 123, "IPv4 RIP should work.");
265 
266   m_receivedPacket->RemoveAllByteTags ();
267 
268   Simulator::Destroy ();
269 }
270 
271 
272 /**
273  * \ingroup internet-test
274  * \ingroup tests
275  *
276  * \brief IPv4 RIP count to infinity Test
277  */
278 class Ipv4RipCountToInfinityTest : public TestCase
279 {
280   Ptr<Packet> m_receivedPacket; //!< Received packet
281 
282   /**
283    * \brief Send data.
284    * \param socket The sending socket.
285    * \param to Destination address.
286    */
287   void DoSendData (Ptr<Socket> socket, std::string to);
288   /**
289    * \brief Send data.
290    * \param socket The sending socket.
291    * \param to Destination address.
292    */
293   void SendData (Ptr<Socket> socket, std::string to);
294 
295 public:
296   virtual void DoRun (void);
297   Ipv4RipCountToInfinityTest ();
298 
299   /**
300    * \brief Receive data.
301    * \param socket The receiving socket.
302    */
303   void ReceivePkt (Ptr<Socket> socket);
304 };
305 
Ipv4RipCountToInfinityTest()306 Ipv4RipCountToInfinityTest::Ipv4RipCountToInfinityTest ()
307   : TestCase ("RIP counting to infinity")
308 {
309 }
310 
ReceivePkt(Ptr<Socket> socket)311 void Ipv4RipCountToInfinityTest::ReceivePkt (Ptr<Socket> socket)
312 {
313   uint32_t availableData;
314   availableData = socket->GetRxAvailable ();
315   m_receivedPacket = socket->Recv (std::numeric_limits<uint32_t>::max (), 0);
316   NS_ASSERT (availableData == m_receivedPacket->GetSize ());
317   //cast availableData to void, to suppress 'availableData' set but not used
318   //compiler warning
319   (void) availableData;
320 }
321 
322 void
DoSendData(Ptr<Socket> socket,std::string to)323 Ipv4RipCountToInfinityTest::DoSendData (Ptr<Socket> socket, std::string to)
324 {
325   Address realTo = InetSocketAddress (Ipv4Address (to.c_str ()), 1234);
326   NS_TEST_EXPECT_MSG_EQ (socket->SendTo (Create<Packet> (123), 0, realTo),
327                          123, "100");
328 }
329 
330 void
SendData(Ptr<Socket> socket,std::string to)331 Ipv4RipCountToInfinityTest::SendData (Ptr<Socket> socket, std::string to)
332 {
333   m_receivedPacket = Create<Packet> ();
334   Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), Seconds (60),
335                                   &Ipv4RipCountToInfinityTest::DoSendData, this, socket, to);
336   Simulator::Stop (Seconds (66));
337   Simulator::Run ();
338 }
339 
340 void
DoRun(void)341 Ipv4RipCountToInfinityTest::DoRun (void)
342 {
343   // Create topology
344 
345   Ptr<Node> txNode = CreateObject<Node> ();
346   Ptr<Node> rxNode = CreateObject<Node> ();
347   Ptr<Node> routerA = CreateObject<Node> ();
348   Ptr<Node> routerB = CreateObject<Node> ();
349   Ptr<Node> routerC = CreateObject<Node> ();
350 
351   NodeContainer nodes (txNode, rxNode);
352   NodeContainer routers (routerA, routerB, routerC);
353   NodeContainer all (nodes, routers);
354 
355   RipHelper ripNgRouting;
356   // Change the router's interface metric to 10, must not send packets (count to infinity)
357   // note: Interface 0 is the loopback.
358   ripNgRouting.SetInterfaceMetric (routerA, 2, 10);
359   ripNgRouting.SetInterfaceMetric (routerB, 1, 10);
360   ripNgRouting.SetInterfaceMetric (routerB, 2, 10);
361   ripNgRouting.SetInterfaceMetric (routerC, 1, 10);
362 
363   InternetStackHelper internetv6routers;
364   internetv6routers.SetRoutingHelper (ripNgRouting);
365   internetv6routers.Install (routers);
366 
367   InternetStackHelper internetv6nodes;
368   internetv6nodes.Install (nodes);
369 
370   NetDeviceContainer net1;
371   NetDeviceContainer net2;
372   NetDeviceContainer net3;
373   NetDeviceContainer net4;
374 
375   // Sender Node
376   Ptr<SimpleNetDevice> txDev;
377   {
378     txDev = CreateObject<SimpleNetDevice> ();
379     txDev->SetAddress (Mac48Address ("00:00:00:00:00:01"));
380     txNode->AddDevice (txDev);
381   }
382   net1.Add (txDev);
383 
384   // Router A
385   Ptr<SimpleNetDevice> fwDev1routerA, fwDev2routerA;
386   { // first interface
387     fwDev1routerA = CreateObject<SimpleNetDevice> ();
388     fwDev1routerA->SetAddress (Mac48Address ("00:00:00:00:00:02"));
389     routerA->AddDevice (fwDev1routerA);
390   }
391   net1.Add (fwDev1routerA);
392 
393   { // second interface
394     fwDev2routerA = CreateObject<SimpleNetDevice> ();
395     fwDev2routerA->SetAddress (Mac48Address ("00:00:00:00:00:03"));
396     routerA->AddDevice (fwDev2routerA);
397   }
398   net2.Add (fwDev2routerA);
399 
400   // Router B
401   Ptr<SimpleNetDevice> fwDev1routerB, fwDev2routerB;
402   { // first interface
403     fwDev1routerB = CreateObject<SimpleNetDevice> ();
404     fwDev1routerB->SetAddress (Mac48Address ("00:00:00:00:00:04"));
405     routerB->AddDevice (fwDev1routerB);
406   }
407   net2.Add (fwDev1routerB);
408 
409   { // second interface
410     fwDev2routerB = CreateObject<SimpleNetDevice> ();
411     fwDev2routerB->SetAddress (Mac48Address ("00:00:00:00:00:05"));
412     routerB->AddDevice (fwDev2routerB);
413   }
414   net3.Add (fwDev2routerB);
415 
416   // Router C
417   Ptr<SimpleNetDevice> fwDev1routerC, fwDev2routerC;
418   { // first interface
419     fwDev1routerC = CreateObject<SimpleNetDevice> ();
420     fwDev1routerC->SetAddress (Mac48Address ("00:00:00:00:00:06"));
421     routerC->AddDevice (fwDev1routerC);
422   }
423   net3.Add (fwDev1routerC);
424 
425   { // second interface
426     fwDev2routerC = CreateObject<SimpleNetDevice> ();
427     fwDev2routerC->SetAddress (Mac48Address ("00:00:00:00:00:07"));
428     routerC->AddDevice (fwDev2routerC);
429   }
430   net4.Add (fwDev2routerC);
431 
432   // Rx node
433   Ptr<SimpleNetDevice> rxDev;
434   { // first interface
435     rxDev = CreateObject<SimpleNetDevice> ();
436     rxDev->SetAddress (Mac48Address ("00:00:00:00:00:08"));
437     rxNode->AddDevice (rxDev);
438   }
439   net4.Add (rxDev);
440 
441   // link the channels
442   Ptr<SimpleChannel> channel1 = CreateObject<SimpleChannel> ();
443   txDev->SetChannel (channel1);
444   fwDev1routerA->SetChannel (channel1);
445 
446   Ptr<SimpleChannel> channel2 = CreateObject<SimpleChannel> ();
447   fwDev2routerA->SetChannel (channel2);
448   fwDev1routerB->SetChannel (channel2);
449 
450   Ptr<SimpleChannel> channel3 = CreateObject<SimpleChannel> ();
451   fwDev2routerB->SetChannel (channel3);
452   fwDev1routerC->SetChannel (channel3);
453 
454   Ptr<SimpleChannel> channel4 = CreateObject<SimpleChannel> ();
455   fwDev2routerC->SetChannel (channel4);
456   rxDev->SetChannel (channel4);
457 
458   // Setup IPv4 addresses and forwarding
459   Ipv4AddressHelper ipv4;
460 
461   ipv4.SetBase (Ipv4Address ("10.0.1.0"), Ipv4Mask ("255.255.255.0"));
462   Ipv4InterfaceContainer iic1 = ipv4.Assign (net1);
463 
464   ipv4.SetBase (Ipv4Address ("192.168.0.0"), Ipv4Mask ("255.255.255.0"));
465   Ipv4InterfaceContainer iic2 = ipv4.Assign (net2);
466 
467   ipv4.SetBase (Ipv4Address ("192.168.1.0"), Ipv4Mask ("255.255.255.0"));
468   Ipv4InterfaceContainer iic3 = ipv4.Assign (net3);
469 
470   ipv4.SetBase (Ipv4Address ("10.0.2.0"), Ipv4Mask ("255.255.255.0"));
471   Ipv4InterfaceContainer iic4 = ipv4.Assign (net4);
472 
473   Ptr<Ipv4StaticRouting> staticRouting;
474   staticRouting = Ipv4RoutingHelper::GetRouting <Ipv4StaticRouting> (txNode->GetObject<Ipv4> ()->GetRoutingProtocol ());
475   staticRouting->SetDefaultRoute ("10.0.1.2", 1 );
476   staticRouting = Ipv4RoutingHelper::GetRouting <Ipv4StaticRouting> (rxNode->GetObject<Ipv4> ()->GetRoutingProtocol ());
477   staticRouting->SetDefaultRoute ("10.0.2.1", 1 );
478 
479 
480   // Create the UDP sockets
481   Ptr<SocketFactory> rxSocketFactory = rxNode->GetObject<UdpSocketFactory> ();
482   Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket ();
483   NS_TEST_EXPECT_MSG_EQ (rxSocket->Bind (InetSocketAddress (Ipv4Address ("10.0.2.2"), 1234)), 0, "trivial");
484   rxSocket->SetRecvCallback (MakeCallback (&Ipv4RipCountToInfinityTest::ReceivePkt, this));
485 
486   Ptr<SocketFactory> txSocketFactory = txNode->GetObject<UdpSocketFactory> ();
487   Ptr<Socket> txSocket = txSocketFactory->CreateSocket ();
488   txSocket->SetAllowBroadcast (true);
489 
490   // ------ Now the tests ------------
491 
492   SendData (txSocket, "10.0.2.2");
493   NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 0, "RIP counting to infinity.");
494 
495   Simulator::Destroy ();
496 }
497 
498 
499 /**
500  * \ingroup internet-test
501  * \ingroup tests
502  *
503  * \brief IPv4 RIP SplitHorizon strategy Test
504  */
505 class Ipv4RipSplitHorizonStrategyTest : public TestCase
506 {
507   Rip::SplitHorizonType_e m_setStrategy;      //!< Strategy set.
508   Rip::SplitHorizonType_e m_detectedStrategy; //!< Strategy detected.
509 
510 public:
511   virtual void DoRun (void);
512 
513   /**
514    * \brief Constructor.
515    * \param strategy The SplitHorizon strategy.
516    */
517   Ipv4RipSplitHorizonStrategyTest (Rip::SplitHorizonType_e strategy);
518 
519   /**
520    * \brief Receive data.
521    * \param socket The receiving socket.
522    */
523   void ReceivePktProbe (Ptr<Socket> socket);
524 };
525 
Ipv4RipSplitHorizonStrategyTest(Rip::SplitHorizonType_e strategy)526 Ipv4RipSplitHorizonStrategyTest::Ipv4RipSplitHorizonStrategyTest (Rip::SplitHorizonType_e strategy)
527   : TestCase ("RIP Split Horizon strategy")
528 {
529   m_setStrategy = strategy;
530 }
531 
ReceivePktProbe(Ptr<Socket> socket)532 void Ipv4RipSplitHorizonStrategyTest::ReceivePktProbe (Ptr<Socket> socket)
533 {
534   uint32_t availableData;
535   availableData = socket->GetRxAvailable ();
536   Address srcAddr;
537   Ptr<Packet> receivedPacketProbe = socket->RecvFrom (std::numeric_limits<uint32_t>::max (), 0, srcAddr);
538   NS_ASSERT (availableData == receivedPacketProbe->GetSize ());
539   Ipv4Address senderAddress = InetSocketAddress::ConvertFrom (srcAddr).GetIpv4 ();
540 
541   if (senderAddress == "192.168.0.2")
542     {
543       RipHeader hdr;
544       receivedPacketProbe->RemoveHeader (hdr);
545 
546       std::list<RipRte> rtes = hdr.GetRteList ();
547 
548       // validate the RTEs before processing
549       for (std::list<RipRte>::iterator iter = rtes.begin ();
550           iter != rtes.end (); iter++)
551         {
552           if (iter->GetPrefix () == "10.0.1.0")
553             {
554               bool correct = false;
555               if (iter->GetRouteMetric () == 16)
556                 {
557                   correct = true;
558                   m_detectedStrategy = Rip::POISON_REVERSE;
559                 }
560               else if (iter->GetRouteMetric () == 2)
561                 {
562                   correct = true;
563                   m_detectedStrategy = Rip::NO_SPLIT_HORIZON;
564                 }
565               NS_TEST_EXPECT_MSG_EQ (correct, true, "RIP: unexpected metric value: " << iter->GetRouteMetric ());
566             }
567         }
568     }
569 
570   //cast availableData to void, to suppress 'availableData' set but not used
571   //compiler warning
572   (void) availableData;
573 }
574 
575 void
DoRun(void)576 Ipv4RipSplitHorizonStrategyTest::DoRun (void)
577 {
578   // Create topology
579 
580   Ptr<Node> fakeNode = CreateObject<Node> ();
581   Ptr<Node> listener = CreateObject<Node> ();
582 
583   Ptr<Node> routerA = CreateObject<Node> ();
584   Ptr<Node> routerB = CreateObject<Node> ();
585 
586   NodeContainer listeners (listener, fakeNode);
587   NodeContainer routers (routerA, routerB);
588   NodeContainer all (routers, listeners);
589 
590   RipHelper ripNgRouting;
591   ripNgRouting.Set ("SplitHorizon", EnumValue (m_setStrategy));
592 
593   InternetStackHelper internetRouters;
594   internetRouters.SetRoutingHelper (ripNgRouting);
595   internetRouters.Install (routers);
596 
597   InternetStackHelper internetNodes;
598   internetNodes.Install (listeners);
599 
600   NetDeviceContainer net0;
601   NetDeviceContainer net1;
602 
603   // Fake Node
604   Ptr<SimpleNetDevice> silentDev;
605   {
606     silentDev = CreateObject<SimpleNetDevice> ();
607     silentDev->SetAddress (Mac48Address ("00:00:00:00:00:01"));
608     fakeNode->AddDevice (silentDev);
609   }
610   net0.Add (silentDev);
611 
612   // Router A
613   Ptr<SimpleNetDevice> silentDevRouterA, fwDevRouterA;
614   { // silent interface
615     silentDevRouterA = CreateObject<SimpleNetDevice> ();
616     silentDevRouterA->SetAddress (Mac48Address ("00:00:00:00:00:02"));
617     routerA->AddDevice (silentDevRouterA);
618   }
619   net0.Add (silentDevRouterA);
620 
621   { // first interface
622     fwDevRouterA = CreateObject<SimpleNetDevice> ();
623     fwDevRouterA->SetAddress (Mac48Address ("00:00:00:00:00:03"));
624     routerA->AddDevice (fwDevRouterA);
625   }
626   net1.Add (fwDevRouterA);
627 
628   // Router B
629   Ptr<SimpleNetDevice> fwDevRouterB;
630   { // first interface
631     fwDevRouterB = CreateObject<SimpleNetDevice> ();
632     fwDevRouterB->SetAddress (Mac48Address ("00:00:00:00:00:04"));
633     routerB->AddDevice (fwDevRouterB);
634   }
635   net1.Add (fwDevRouterB);
636 
637   // listener A
638   Ptr<SimpleNetDevice> listenerDev;
639   {
640     listenerDev = CreateObject<SimpleNetDevice> ();
641     listenerDev->SetAddress (Mac48Address ("00:00:00:00:00:05"));
642     listener->AddDevice (listenerDev);
643   }
644   net1.Add (listenerDev);
645 
646   // link the channels
647   Ptr<SimpleChannel> channel0 = CreateObject<SimpleChannel> ();
648   silentDev->SetChannel (channel0);
649   silentDevRouterA->SetChannel (channel0);
650 
651   Ptr<SimpleChannel> channel1 = CreateObject<SimpleChannel> ();
652   fwDevRouterA->SetChannel (channel1);
653   fwDevRouterB->SetChannel (channel1);
654   listenerDev->SetChannel (channel1);
655 
656   // Setup IPv6 addresses and forwarding
657   Ipv4AddressHelper ipv4;
658 
659   ipv4.SetBase (Ipv4Address ("10.0.1.0"), Ipv4Mask ("255.255.255.0"));
660   Ipv4InterfaceContainer iic0 = ipv4.Assign (net0);
661 
662   ipv4.SetBase (Ipv4Address ("192.168.0.0"), Ipv4Mask ("255.255.255.0"));
663   Ipv4InterfaceContainer iic1 = ipv4.Assign (net1);
664 
665   // Create the UDP sockets
666   Ptr<SocketFactory> rxSocketFactory = listener->GetObject<UdpSocketFactory> ();
667   Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket ();
668   rxSocket->BindToNetDevice (listenerDev);
669   NS_TEST_EXPECT_MSG_EQ (rxSocket->Bind (InetSocketAddress (Ipv4Address ("224.0.0.9"), 520)), 0, "trivial");
670   rxSocket->SetRecvCallback (MakeCallback (&Ipv4RipSplitHorizonStrategyTest::ReceivePktProbe, this));
671 
672   // ------ Now the tests ------------
673 
674   // If the strategy is Split Horizon, then no packet will be received.
675   m_detectedStrategy = Rip::SPLIT_HORIZON;
676 
677   Simulator::Stop (Seconds (66));
678   Simulator::Run ();
679   NS_TEST_EXPECT_MSG_EQ (m_detectedStrategy, m_setStrategy, "RIP counting to infinity.");
680 
681   Simulator::Destroy ();
682 }
683 
684 
685 /**
686  * \ingroup internet-test
687  * \ingroup tests
688  *
689  * \brief IPv4 RIP TestSuite
690  */
691 class Ipv4RipTestSuite : public TestSuite
692 {
693 public:
Ipv4RipTestSuite()694   Ipv4RipTestSuite () : TestSuite ("ipv4-rip", UNIT)
695   {
696     AddTestCase (new Ipv4RipTest, TestCase::QUICK);
697     AddTestCase (new Ipv4RipCountToInfinityTest, TestCase::QUICK);
698     AddTestCase (new Ipv4RipSplitHorizonStrategyTest (Rip::POISON_REVERSE), TestCase::QUICK);
699     AddTestCase (new Ipv4RipSplitHorizonStrategyTest (Rip::SPLIT_HORIZON), TestCase::QUICK);
700     AddTestCase (new Ipv4RipSplitHorizonStrategyTest (Rip::NO_SPLIT_HORIZON), TestCase::QUICK);
701   }
702 };
703 
704 static Ipv4RipTestSuite g_ipv4ripTestSuite; //!< Static variable for test initialization
705