A Discrete-Event Network Simulator
API
ping-test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022 Chandrakant Jena
3  * Copyright (c) 2022 Universita' di Firenze, Italy
4  * Copyright (c) 2022 Tom Henderson
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Authors: Chandrakant Jena <chandrakant.barcelona@gmail.com>
20  * Tommaso Pecorella <tommaso.pecorella@unifi.it>
21  * Tom Henderson <tomh@tomh.org>
22  */
23 
24 // This test suite performs regression tests on the ns-3 Ping application.
25 //
26 // A simple topology is used:
27 //
28 // Node 0 Node 1
29 // +----SimpleChannel---+
30 //
31 // - the SimpleChannel implements a one-way delay of 10 ms
32 // - each node has a SimpleNetDevice with a DataRate of 1 Gb/s
33 // - a ReceiveErrorModel can be configured to force packet drops
34 //
35 // The following are described in more detail below, inline with the test cases.
36 // Most tests listed below will test both IPv4 and IPv6 operation.
37 //
38 // 1. Unlimited pings, no losses, StopApplication () with no packets in flight
39 // 2. Unlimited pings, no losses, StopApplication () with 1 packet in flight
40 // 3. Test for operation of count attribute and exit time after all pings were received
41 // 4. Test the operation of the interval attribute
42 // 5. Test for behavior of pinging an unreachable host when the
43 // network does not send an ICMP unreachable message.
44 // 6. Test pinging to IPv4 broadcast address and IPv6 all nodes multicast address
45 // 7. Test behavior of first reply lost in a count-limited configuration
46 // 8. Test behavior of second reply lost in a count-limited configuration
47 // 9. Test behavior of last reply lost in a count-limited configuration.
48 
49 #include "ns3/boolean.h"
50 #include "ns3/data-rate.h"
51 #include "ns3/error-model.h"
52 #include "ns3/internet-stack-helper.h"
53 #include "ns3/ipv4-address-helper.h"
54 #include "ns3/ipv4-interface-container.h"
55 #include "ns3/ipv6-address-helper.h"
56 #include "ns3/ipv6-interface-container.h"
57 #include "ns3/log.h"
58 #include "ns3/neighbor-cache-helper.h"
59 #include "ns3/node-container.h"
60 #include "ns3/nstime.h"
61 #include "ns3/ping.h"
62 #include "ns3/simple-net-device-helper.h"
63 #include "ns3/simple-net-device.h"
64 #include "ns3/simulator.h"
65 #include "ns3/test.h"
66 #include "ns3/uinteger.h"
67 
68 #include <list>
69 
70 using namespace ns3;
71 
72 NS_LOG_COMPONENT_DEFINE("PingTestSuite");
73 
74 constexpr bool USEIPV6_FALSE = false;
75 constexpr bool USEIPV6_TRUE = true;
76 
88 class PingTestCase : public TestCase
89 {
90  public:
96  PingTestCase(std::string name, bool useIpv6);
97 
102  void SetSimulatorStopTime(Time stopTime);
103 
108  void SetDestinationAddress(Address address);
109 
114  void SetStartTime(Time startTime)
115  {
116  m_startTime = startTime;
117  }
118 
124  {
125  m_stopTime = stopTime;
126  }
127 
132  void SetCount(uint32_t count)
133  {
134  m_countAttribute = count;
135  }
136 
141  void SetSize(uint32_t size)
142  {
143  m_sizeAttribute = size;
144  }
145 
150  void SetInterval(Time interval)
151  {
152  m_interpacketInterval = interval;
153  }
154 
159  void SetDropList(const std::list<uint32_t>& dropList)
160  {
161  m_dropList = dropList;
162  }
163 
168  void CheckTraceTx(uint32_t expectedTx);
169 
174  void CheckTraceRtt(uint32_t expectedRtt);
175 
180  void CheckReportTransmitted(uint32_t expectedReportTx);
181 
186  void CheckReportReceived(uint32_t expectedReportRx);
187 
192  void CheckReportLoss(uint16_t expectedReportLoss);
193 
198  void CheckReportTime(Time expectedTime);
199 
200  private:
201  void DoSetup() override;
202  void DoTeardown() override;
203  void DoRun() override;
204 
210  void TxTraceSink(uint16_t seq, Ptr<Packet> p);
211 
217  void RttTraceSink(uint16_t seq, Time rttSample);
218 
224  void DropTraceSink(uint16_t seq, Ping::DropReason reason);
225 
230  void ReportTraceSink(const Ping::PingReport& report);
231 
232  Address m_destination{Ipv4Address("10.0.0.2")};
233  uint32_t m_mtu{1500};
234  uint32_t m_countAttribute{0};
235  uint32_t m_sizeAttribute{56};
236  // The following are for setting expected counts for traced events
237  uint32_t m_expectedTraceTx{0};
238  uint32_t m_expectedTraceRtt{0};
239  // The following are counters for traced events
240  uint32_t m_countTraceTx{0};
241  uint32_t m_countTraceRtt{0};
242  // The following indicate whether trace counters should be checked
243  bool m_checkTraceTx{false};
244  bool m_checkTraceRtt{false};
245  // The following are for reported values in the final report
246  uint32_t m_expectedReportTx{0};
247  uint32_t m_expectedReportRx{0};
248  uint16_t m_expectedReportLoss{0};
250  // The following indicate whether report quantities should be checked
251  bool m_checkReportTransmitted{false};
252  bool m_checkReportReceived{false};
253  bool m_checkReportLoss{false};
254  bool m_checkReportTime{false};
255 
256  Time m_startTime{Seconds(1)};
257  Time m_stopTime{Seconds(5)};
258  Time m_simulatorStopTime{Seconds(6)};
259  bool m_useIpv6{false};
260  Time m_interpacketInterval{Seconds(1.0)};
262  std::list<uint32_t> m_dropList;
263 
268 };
269 
270 PingTestCase::PingTestCase(std::string name, bool useIpv6)
271  : TestCase(name),
272  m_useIpv6(useIpv6)
273 {
274 }
275 
276 void
278 {
279  NS_LOG_FUNCTION(this);
280  m_nodes.Create(2);
281  SimpleNetDeviceHelper deviceHelper;
282  deviceHelper.SetChannel("ns3::SimpleChannel", "Delay", TimeValue(MilliSeconds(10)));
283  deviceHelper.SetDeviceAttribute("DataRate", DataRateValue(DataRate("1Gbps")));
284  deviceHelper.SetNetDevicePointToPointMode(true);
285  m_devices = deviceHelper.Install(m_nodes);
286  // MTU is not an attribute, so set it directly
287  Ptr<SimpleNetDevice> device0 = DynamicCast<SimpleNetDevice>(m_devices.Get(0));
288  device0->SetMtu(m_mtu);
289  Ptr<SimpleNetDevice> device1 = DynamicCast<SimpleNetDevice>(m_devices.Get(1));
290  device1->SetMtu(m_mtu);
291 
292  InternetStackHelper internetHelper;
293  if (!m_useIpv6)
294  {
295  internetHelper.SetIpv6StackInstall(false);
296  }
297  else
298  {
299  internetHelper.SetIpv4StackInstall(false);
300  }
301  internetHelper.Install(m_nodes);
302 
303  if (!m_useIpv6)
304  {
305  Ipv4AddressHelper ipv4AddrHelper;
306  ipv4AddrHelper.SetBase("10.0.0.0", "255.255.255.0");
307  m_ipv4Interfaces = ipv4AddrHelper.Assign(m_devices);
308  }
309  else
310  {
311  // This is to disable DAD, to simplify the drop testcase.
312  m_nodes.Get(0)->GetObject<Icmpv6L4Protocol>()->SetAttribute("DAD", BooleanValue(false));
313  m_nodes.Get(1)->GetObject<Icmpv6L4Protocol>()->SetAttribute("DAD", BooleanValue(false));
314 
315  Ipv6AddressHelper ipv6AddrHelper;
316  ipv6AddrHelper.SetBase(Ipv6Address("2001:1::"), Ipv6Prefix(64));
317  m_ipv6Interfaces = ipv6AddrHelper.Assign(m_devices);
318 
319  // This is a dirty trick to disable RS/RA, to simplify the drop testcase.
320  // Forwarding interfaces do not send RS.
321  m_nodes.Get(0)->GetObject<Ipv6L3Protocol>()->SetForwarding(1, true);
322  m_nodes.Get(1)->GetObject<Ipv6L3Protocol>()->SetForwarding(1, true);
323  }
324 }
325 
326 void
328 {
329  Simulator::Destroy();
330 }
331 
332 void
333 PingTestCase::CheckReportTransmitted(uint32_t expectedReportTx)
334 {
336  m_expectedReportTx = expectedReportTx;
337 }
338 
339 void
340 PingTestCase::CheckReportReceived(uint32_t expectedReportRx)
341 {
342  m_checkReportReceived = true;
343  m_expectedReportRx = expectedReportRx;
344 }
345 
346 void
347 PingTestCase::CheckReportLoss(uint16_t expectedReportLoss)
348 {
349  m_checkReportLoss = true;
350  m_expectedReportLoss = expectedReportLoss;
351 }
352 
353 void
355 {
356  m_checkReportTime = true;
357  m_expectedReportTime = expectedTime;
358 }
359 
360 void
361 PingTestCase::RttTraceSink(uint16_t seq, Time rttSample)
362 {
363  NS_LOG_FUNCTION(this << seq << rttSample.As(Time::MS));
364  m_countTraceRtt++;
365  if (m_sizeAttribute == 56)
366  {
367  if (!m_useIpv6)
368  {
369  // Each ping should be received with RTT of 20.0013 ms in this configuration
370  // Check that each ping is within 20.0012 ms <= rttSample <= 20.0014 ms
372  rttSample.GetSeconds() * 1000,
373  20.0013,
374  0.0001,
375  "Rtt sample not within 0.0001 ms of expected value of 20.0013 ms");
376  }
377  else
378  {
379  // Each ping should be received with RTT of 20.0017 ms in this configuration
380  // Check that each ping is within 20.0016 ms <= rttSample <= 20.0018 ms
382  rttSample.GetSeconds() * 1000,
383  20.0017,
384  0.0001,
385  "Rtt sample not within 0.0001 ms of expected value of 20.0017 ms");
386  }
387  }
388 }
389 
390 void
392 {
393  NS_LOG_FUNCTION(this << seq << p);
394  m_countTraceTx++;
395  if (m_lastTx == Seconds(0))
396  {
398  }
399  else
400  {
403  "configured interval didn't match the observed interval");
405  }
406 }
407 
408 void
410 {
411  NS_LOG_FUNCTION(this << static_cast<uint16_t>(reason));
412  if (reason == Ping::DropReason::DROP_TIMEOUT)
413  {
414  NS_LOG_DEBUG("Drop due to timeout " << seq);
415  }
416  else if (reason == Ping::DROP_HOST_UNREACHABLE)
417  {
418  NS_LOG_DEBUG("Destination host is unreachable " << seq);
419  }
420  else if (reason == Ping::DROP_NET_UNREACHABLE)
421  {
422  NS_LOG_DEBUG("Destination network not reachable " << seq);
423  }
424 }
425 
426 void
428 {
429  NS_LOG_FUNCTION(this << report.m_transmitted << report.m_received << report.m_loss
430  << report.m_rttMin << report.m_rttMax);
432  {
435  "Report transmit count does not equal expected");
436  }
438  {
441  "Report receive count does not equal expected");
442  }
443  if (m_checkReportLoss)
444  {
447  "Report lost count does not equal expected");
448  }
449  if (m_checkReportTime)
450  {
451  NS_TEST_ASSERT_MSG_EQ_TOL(Simulator::Now().GetMicroSeconds(),
453  1, // tolerance of 1 us
454  "Report application not stopped at expected time");
455  }
456  NS_TEST_ASSERT_MSG_GT_OR_EQ(report.m_rttMin, 0, "minimum rtt should be greater than 0");
457  NS_TEST_ASSERT_MSG_GT_OR_EQ(report.m_rttMax, 0, "maximum rtt should be greater than 0");
458 }
459 
460 void
461 PingTestCase::CheckTraceTx(uint32_t expectedTx)
462 {
463  m_checkTraceTx = true;
464  m_expectedTraceTx = expectedTx;
465 }
466 
467 void
468 PingTestCase::CheckTraceRtt(uint32_t expectedRtt)
469 {
470  m_checkTraceRtt = true;
471  m_expectedTraceRtt = expectedRtt;
472 }
473 
474 void
476 {
478 }
479 
480 void
482 {
484 }
485 
486 void
488 {
489  NS_LOG_FUNCTION(this);
490  Ptr<Ping> ping = CreateObject<Ping>();
491 
492  if (m_useIpv6)
493  {
494  Ipv6Address dst = Ipv6Address::ConvertFrom(m_destination);
495  if (dst.IsLinkLocal() || dst.IsLinkLocalMulticast())
496  {
497  NS_LOG_LOGIC("Setting local interface address to "
498  << m_ipv6Interfaces.GetAddress(0, 0));
499  ping->SetAttribute("InterfaceAddress", AddressValue(m_ipv6Interfaces.GetAddress(0, 0)));
500  }
501  else
502  {
503  NS_LOG_LOGIC("Setting local interface address to "
504  << m_ipv6Interfaces.GetAddress(0, 1));
505  ping->SetAttribute("InterfaceAddress", AddressValue(m_ipv6Interfaces.GetAddress(0, 1)));
506  }
507  NS_LOG_LOGIC("Setting destination address to " << Ipv6Address::ConvertFrom(m_destination));
508  ping->SetAttribute("Destination", AddressValue(m_destination));
509  }
510  else
511  {
512  NS_LOG_LOGIC("Setting destination address to " << Ipv4Address::ConvertFrom(m_destination));
513  ping->SetAttribute("InterfaceAddress", AddressValue(m_ipv4Interfaces.GetAddress(0)));
514  ping->SetAttribute("Destination", AddressValue(m_destination));
515  }
516 
517  if (!m_dropList.empty())
518  {
519  NS_LOG_LOGIC("Setting drop list to list of size " << m_dropList.size());
520  Ptr<ReceiveListErrorModel> errorModel = CreateObject<ReceiveListErrorModel>();
521  Ptr<SimpleNetDevice> netDev = DynamicCast<SimpleNetDevice>(m_devices.Get(0));
522  netDev->SetReceiveErrorModel(errorModel);
523  errorModel->SetList(m_dropList);
524  }
525 
526  ping->SetAttribute("Count", UintegerValue(m_countAttribute));
527  ping->SetAttribute("Size", UintegerValue(m_sizeAttribute));
528  ping->SetAttribute("Interval", TimeValue(m_interpacketInterval));
529  ping->SetStartTime(m_startTime);
530  ping->SetStopTime(m_stopTime);
531  m_nodes.Get(0)->AddApplication(ping);
532  ping->TraceConnectWithoutContext("Tx", MakeCallback(&PingTestCase::TxTraceSink, this));
533  ping->TraceConnectWithoutContext("Rtt", MakeCallback(&PingTestCase::RttTraceSink, this));
534  ping->TraceConnectWithoutContext("Drop", MakeCallback(&PingTestCase::DropTraceSink, this));
535  ping->TraceConnectWithoutContext("Report", MakeCallback(&PingTestCase::ReportTraceSink, this));
536 
537  NeighborCacheHelper neighborCacheHelper;
538  neighborCacheHelper.PopulateNeighborCache();
539 
540  Simulator::Stop(m_simulatorStopTime);
541  Simulator::Run();
542 
543  if (m_checkTraceTx)
544  {
547  "Traced Tx events do not equal expected");
548  }
549  if (m_checkTraceRtt)
550  {
553  "Traced Rtt events do not equal expected");
554  }
555 }
556 
563 class PingTestSuite : public TestSuite
564 {
565  public:
566  PingTestSuite();
567 };
568 
570  : TestSuite("ping", UNIT)
571 {
572  // 1. Unlimited pings, no losses, StopApplication () with no packets in flight
573  // Configuration: Ping::Count = 0, Ping::Interval = 1s, Ping start
574  // time = 1s, Ping stop time = 5.5s
575  // Expected behavior: Pings are sent at times 1, 2, 3, 4, 5 sec. The
576  // number sent equals number received, which equals 5.
577  // How validated: PingReport trace is checked for number of packets
578  // transmitted and received (5), and number of drops (0).
579  PingTestCase* testcase1v4 = new PingTestCase(
580  "1. Unlimited pings, no losses, StopApplication () with no packets in flight IPv4",
581  USEIPV6_FALSE);
582  testcase1v4->SetStartTime(Seconds(1));
583  testcase1v4->SetStopTime(Seconds(5.5));
584  testcase1v4->SetCount(0);
585  testcase1v4->CheckReportTransmitted(5);
586  testcase1v4->CheckReportReceived(5);
587  testcase1v4->CheckTraceTx(5);
588  testcase1v4->SetDestinationAddress(Ipv4Address("10.0.0.2"));
589  AddTestCase(testcase1v4, TestCase::QUICK);
590 
591  PingTestCase* testcase1v6 = new PingTestCase(
592  "1. Unlimited pings, no losses, StopApplication () with no packets in flight IPv6",
593  USEIPV6_TRUE);
594  testcase1v6->SetStartTime(Seconds(1));
595  testcase1v6->SetStopTime(Seconds(5.5));
596  testcase1v6->SetCount(0);
597  testcase1v6->CheckReportTransmitted(5);
598  testcase1v6->CheckReportReceived(5);
599  testcase1v6->CheckTraceTx(5);
600  testcase1v6->SetDestinationAddress(Ipv6Address("2001:1::200:ff:fe00:2"));
601  AddTestCase(testcase1v6, TestCase::QUICK);
602 
603  // 2. Unlimited pings, no losses, StopApplication () with 1 packet in flight
604  // Configuration: Ping::Count = 0, Ping::Interval = 1s, Ping start time =
605  // 1s, Ping stop time = 1.0001s
606  // Expected behavior: The application is stopped immediately after the
607  // only ping is sent, and this ping will be reported
608  // to be lost
609  // How validated: PingReport trace is checked for number of packets
610  // transmitted (1) and received (0), and number of drops (0)
611  PingTestCase* testcase2v4 = new PingTestCase(
612  "2. Unlimited pings, no losses, StopApplication () with 1 packet in flight IPv4",
613  USEIPV6_FALSE);
614  testcase2v4->SetStartTime(Seconds(1));
615  testcase2v4->SetStopTime(Seconds(1.0001));
616  testcase2v4->SetSimulatorStopTime(Seconds(5));
617  testcase2v4->CheckReportTransmitted(1);
618  testcase2v4->CheckReportReceived(0);
619  testcase1v4->SetDestinationAddress(Ipv4Address("10.0.0.2"));
620  AddTestCase(testcase2v4, TestCase::QUICK);
621 
622  PingTestCase* testcase2v6 = new PingTestCase(
623  "2. Unlimited pings, no losses, StopApplication () with 1 packet in flight IPv6",
624  USEIPV6_TRUE);
625  testcase2v6->SetStartTime(Seconds(1));
626  testcase2v6->SetStopTime(Seconds(1.0001));
627  testcase2v6->SetSimulatorStopTime(Seconds(5));
628  testcase2v6->CheckReportTransmitted(1);
629  testcase2v6->CheckReportReceived(0);
630  testcase2v6->SetDestinationAddress(Ipv6Address("2001:1::200:ff:fe00:2"));
631  AddTestCase(testcase2v6, TestCase::QUICK);
632 
633  // 3. Test for operation of count attribute and the resulting StopApplication time after all
634  // pings were received. Limited pings, no losses, StopApplication () with no packet in flight
635  // Configuration: Ping::Count = 2, Ping::Interval = 1s, Ping start time =
636  // 1s, Ping stop time = 5s
637  // Expected behavior: Pings are sent at 1 second intervals. The
638  // number sent (2) is equal to number received (2).
639  // After receiving all pings, despite configuring
640  // the StopApplication time to 5 seconds, the
641  // application will immediately stop and generate
642  // the report (at 2020001 us)
643  // How validated: PingReport trace is checked for number of packets
644  // transmitted (2) and received (2),number of drops (0),
645  // Report time will be MicroSeconds (2020001).
646  uint32_t count = 2;
647  uint32_t expectedTx = 2;
648  PingTestCase* testcase3v4 =
649  new PingTestCase("3. Test for operation of count attribute and exit "
650  "time after all pings were received, IPv4",
651  USEIPV6_FALSE);
652  testcase3v4->SetStartTime(Seconds(1));
653  testcase3v4->SetStopTime(Seconds(5));
654  testcase3v4->SetCount(count);
655  testcase3v4->SetSimulatorStopTime(Seconds(6));
656  testcase3v4->CheckReportTransmitted(2);
657  testcase3v4->CheckReportReceived(2);
658  testcase3v4->CheckReportTime(MicroSeconds(2020001));
659  testcase3v4->CheckTraceTx(expectedTx);
660  testcase3v4->SetDestinationAddress(Ipv4Address("10.0.0.2"));
661  AddTestCase(testcase3v4, TestCase::QUICK);
662 
663  PingTestCase* testcase3v6 =
664  new PingTestCase("3. Test for operation of count attribute and exit "
665  "time after all pings were received, IPv6",
666  USEIPV6_TRUE);
667  testcase3v6->SetStartTime(Seconds(1));
668  testcase3v6->SetStopTime(Seconds(5));
669  testcase3v6->SetCount(count);
670  testcase3v6->SetSimulatorStopTime(Seconds(6));
671  testcase3v6->CheckReportTransmitted(2);
672  testcase3v6->CheckReportReceived(2);
673  testcase3v6->CheckReportTime(MicroSeconds(2020001));
674  testcase3v6->CheckTraceTx(expectedTx);
675  testcase3v6->SetDestinationAddress(Ipv6Address("2001:1::200:ff:fe00:2"));
676  AddTestCase(testcase3v6, TestCase::QUICK);
677 
678  // 4. Test for the operation of interval attribute for IPv4
679  // Unlimited pings, no losses, StopApplication () with no packet in flight
680  // Configuration: Ping::Count = 0, Ping::Interval = 3s, Ping start
681  // time = 1s, Ping stop time = 6s
682  // Expected behavior: Pings are sent at the interval of 3 sec.
683  // 1st packet is sent at 1sec and 2nd packet at 4sec.
684  // The number sent (2) is equal to number received (2)
685  // How validated: PingReport trace is checked for number of packets
686  // transmitted (2) and received (2), and number of drops (0)
687  Time interval = Seconds(3.0);
688  PingTestCase* testcase4v4 =
689  new PingTestCase("4. Test for the operation of interval attribute for IPv4", USEIPV6_FALSE);
690  testcase4v4->SetStartTime(Seconds(1));
691  testcase4v4->SetStopTime(Seconds(5));
692  testcase4v4->SetInterval(interval);
693  testcase4v4->SetSimulatorStopTime(Seconds(6));
694  testcase4v4->CheckReportTransmitted(2);
695  testcase4v4->CheckReportReceived(2);
696  testcase4v4->SetDestinationAddress(Ipv4Address("10.0.0.2"));
697  AddTestCase(testcase4v4, TestCase::QUICK);
698 
699  PingTestCase* testcase4v6 =
700  new PingTestCase("4. Test for the operation of interval attribute for IPv6", USEIPV6_TRUE);
701  testcase4v6->SetStartTime(Seconds(1));
702  testcase4v6->SetStopTime(Seconds(5));
703  testcase4v6->SetInterval(interval);
704  testcase4v6->SetSimulatorStopTime(Seconds(6));
705  testcase4v6->CheckReportTransmitted(2);
706  testcase4v6->CheckReportReceived(2);
707  testcase4v6->SetDestinationAddress(Ipv6Address("2001:1::200:ff:fe00:2"));
708  AddTestCase(testcase4v6, TestCase::QUICK);
709 
710  // 5. Test for behavior of pinging an unreachable host when the
711  // network does not send an ICMP unreachable message.
712  // Unlimited pings, StopApplication () with no packet in flight
713  // Configuration: Ping::Count = 0, Ping start time = 1s
714  // Ping stop time = 5.5s. Ping to unknown destination.
715  // Expected behavior: By default, the timeout value is 1 second. Ping
716  // sends first packet at time 1 second, and does not
717  // receive a response. At the timeout (simulation time
718  // 2 seconds), ping should print out that there was
719  // a timeout, and the drop trace should be fired.
720  // At stop time, there should be three drops recorded
721  // of type DROP_TIMEOUT, and not four,
722  // because the packet sent at time 5 seconds has not
723  // had enough time elapsed to timeout.
724  // How validated: PingReport trace is checked for number of packets
725  // transmitted (5) and received (0).
726  // The packet loss rate should be checked to be 100 percent
727  PingTestCase* testcase5v4 =
728  new PingTestCase("5. Test for behavior of ping to unreachable IPv4 address", USEIPV6_FALSE);
729  testcase5v4->SetStartTime(Seconds(1));
730  testcase5v4->SetStopTime(Seconds(5.5));
731  testcase5v4->SetDestinationAddress(Ipv4Address("1.2.3.4"));
732  testcase5v4->CheckReportTransmitted(5);
733  testcase5v4->CheckReportReceived(0);
734  testcase5v4->CheckReportLoss(100);
735  AddTestCase(testcase5v4, TestCase::QUICK);
736 
737  PingTestCase* testcase5v6 =
738  new PingTestCase("5. Test for behavior of ping to unreachable IPv6 address", USEIPV6_TRUE);
739  testcase5v6->SetStartTime(Seconds(1));
740  testcase5v6->SetStopTime(Seconds(5.5));
741  testcase5v6->SetDestinationAddress(Ipv6Address("2001:1::200:ff:fe00:3"));
742  testcase5v6->CheckReportTransmitted(5);
743  testcase5v6->CheckReportReceived(0);
744  testcase5v6->CheckReportLoss(100);
745  AddTestCase(testcase5v6, TestCase::QUICK);
746 
747  // 6. Test for behavior of pinging an broadcast (or multicast) address.
748  // Limited pings, no losses, StopApplication () with no packet in flight
749  // Configuration: Ping::Count = 2, Ping::Interval = 1s, Ping start time =
750  // 1s, Ping stop time = 5s
751  // Expected behavior: Pings are sent at 1 second intervals. The
752  // number sent (2) is equal to number received (2).
753  // After receiving all pings, despite configuring
754  // the StopApplication time to 5 seconds, the
755  // application will immediately stop and generate
756  // the report (at 2020001 us)
757  // How validated: PingReport trace is checked for number of packets
758  // transmitted (2) and received (2),number of drops (0),
759  // Report time will be MicroSeconds (2020001).
760  PingTestCase* testcase6v4 =
761  new PingTestCase("6. Test for behavior of ping to broadcast IPv4 address", USEIPV6_FALSE);
762  testcase6v4->SetStartTime(Seconds(1));
763  testcase6v4->SetStopTime(Seconds(5.5));
764  testcase6v4->SetDestinationAddress(Ipv4Address::GetBroadcast());
765  testcase6v4->CheckReportTransmitted(5);
766  testcase6v4->CheckReportReceived(5);
767  testcase6v4->CheckReportLoss(0);
768  AddTestCase(testcase6v4, TestCase::QUICK);
769 
770  PingTestCase* testcase6v6 =
771  new PingTestCase("6. Test for behavior of ping to all-nodes multicast IPv6 address",
772  USEIPV6_TRUE);
773  testcase6v6->SetStartTime(Seconds(1));
774  testcase6v6->SetStopTime(Seconds(5.5));
775  testcase6v6->SetDestinationAddress(Ipv6Address::GetAllNodesMulticast());
776  testcase6v6->CheckReportTransmitted(5);
777  testcase6v6->CheckReportReceived(5);
778  testcase6v6->CheckReportLoss(0);
779  AddTestCase(testcase6v6, TestCase::QUICK);
780 
781  // 7. Test behavior of first reply lost in a count-limited configuration.
782  // Limited pings, no losses, StopApplication () with no packet in flight
783  // Configuration: Ping::Count = 3, Ping::Interval = 1s, Ping start time =
784  // 1s, Ping stop time = 5s. Loss of first reply is forced.
785  // Expected behavior: Pings are sent at 1 second intervals at times
786  // 1s, 2s, 3s. The ping Tx trace will record 3 sends,
787  // but the RTT trace will record 2 receptions.
788  // The application will stop after the third send
789  // after waiting for 2*RttMax (40 ms).
790  // How validated: PingReport trace is checked for number of packets
791  // transmitted (3) and received (2), loss percentage (33).
792  // Ping Tx trace (3) and Rtt trace (2) are also checked.
793  // Report time will be MicroSeconds (3040000).
794  PingTestCase* testcase7v4 = new PingTestCase(
795  "7. Test behavior of first reply lost in a count-limited configuration, IPv4",
796  USEIPV6_FALSE);
797  std::list<uint32_t> dropList{0};
798  testcase7v4->SetDropList(dropList);
799  testcase7v4->SetStartTime(Seconds(1));
800  testcase7v4->SetCount(3);
801  testcase7v4->SetStopTime(Seconds(5));
802  testcase7v4->CheckTraceTx(3);
803  testcase7v4->CheckTraceRtt(2);
804  testcase7v4->CheckReportTransmitted(3);
805  testcase7v4->CheckReportReceived(2);
806  testcase7v4->CheckReportLoss(33); // 33%
807  testcase7v4->CheckReportTime(MicroSeconds(3040000));
808  AddTestCase(testcase7v4, TestCase::QUICK);
809 
810  PingTestCase* testcase7v6 = new PingTestCase(
811  "7. Test behavior of first reply lost in a count-limited configuration, IPv6",
812  USEIPV6_TRUE);
813  testcase7v6->SetDropList(dropList);
814  testcase7v6->SetStartTime(Seconds(1));
815  testcase7v6->SetCount(3);
816  testcase7v6->SetStopTime(Seconds(5));
817  testcase7v6->SetDestinationAddress(Ipv6Address("2001:1::200:ff:fe00:2"));
818  testcase7v6->CheckTraceTx(3);
819  testcase7v6->CheckTraceRtt(2);
820  testcase7v6->CheckReportTransmitted(3);
821  testcase7v6->CheckReportReceived(2);
822  testcase7v6->CheckReportLoss(33); // 33%
823  testcase7v6->CheckReportTime(MicroSeconds(3040000));
824  AddTestCase(testcase7v6, TestCase::QUICK);
825 
826  // 8. Test behavior of second reply lost in a count-limited configuration.
827  // Limited pings, no losses, StopApplication () with no packet in flight
828  // Configuration: Ping::Count = 3, Ping::Interval = 1s, Ping start time =
829  // 1s, Ping stop time = 5s. Loss of second reply is forced.
830  // Expected behavior: Pings are sent at 1 second intervals at times
831  // 1s, 2s, 3s. The ping Tx trace will record 3 sends,
832  // but the RTT trace will record 2 receptions.
833  // The application will stop after the third send
834  // after waiting for 2*RttMax (40 ms).
835  // How validated: PingReport trace is checked for number of packets
836  // transmitted (3) and received (2), loss percentage (33).
837  // Ping Tx trace (3) and Rtt trace (2) are also checked.
838  // Report time will be MicroSeconds (3040000).
839  PingTestCase* testcase8v4 = new PingTestCase(
840  "8. Test behavior of second reply lost in a count-limited configuration, IPv4",
841  USEIPV6_FALSE);
842  std::list<uint32_t> dropList2{1};
843  testcase8v4->SetDropList(dropList2);
844  testcase8v4->SetStartTime(Seconds(1));
845  testcase8v4->SetCount(3);
846  testcase8v4->SetStopTime(Seconds(5));
847  testcase8v4->CheckTraceTx(3);
848  testcase8v4->CheckTraceRtt(2);
849  testcase8v4->CheckReportTransmitted(3);
850  testcase8v4->CheckReportReceived(2);
851  testcase8v4->CheckReportLoss(33); // 33%
852  testcase8v4->CheckReportTime(MicroSeconds(3040000));
853  AddTestCase(testcase8v4, TestCase::QUICK);
854 
855  PingTestCase* testcase8v6 = new PingTestCase(
856  "8. Test behavior of second reply lost in a count-limited configuration, IPv6",
857  USEIPV6_TRUE);
858  testcase8v6->SetDropList(dropList2);
859  testcase8v6->SetStartTime(Seconds(1));
860  testcase8v6->SetCount(3);
861  testcase8v6->SetStopTime(Seconds(5));
862  testcase8v6->SetDestinationAddress(Ipv6Address("2001:1::200:ff:fe00:2"));
863  testcase8v6->CheckTraceTx(3);
864  testcase8v6->CheckTraceRtt(2);
865  testcase8v6->CheckReportTransmitted(3);
866  testcase8v6->CheckReportReceived(2);
867  testcase8v6->CheckReportLoss(33); // 33%
868  testcase8v6->CheckReportTime(MicroSeconds(3040000));
869  AddTestCase(testcase8v6, TestCase::QUICK);
870 
871  // 9. Test behavior of last reply lost in a count-limited configuration.
872  // Limited pings, no losses, StopApplication () with no packet in flight
873  // Configuration: Ping::Count = 3, Ping::Interval = 1s, Ping start time =
874  // 1s, Ping stop time = 5s. Loss of last reply is forced.
875  // Expected behavior: Pings are sent at 1 second intervals at times
876  // 1s, 2s, 3s. The ping Tx trace will record 3 sends,
877  // but the RTT trace will record 2 receptions.
878  // The application will stop after the third send
879  // after waiting for 2*RttMax (40 ms).
880  // How validated: PingReport trace is checked for number of packets
881  // transmitted (3) and received (2), loss percentage (33).
882  // Ping Tx trace (3) and Rtt trace (2) are also checked.
883  // Report time will be MicroSeconds (3040000).
884  PingTestCase* testcase9v4 = new PingTestCase(
885  "9. Test behavior of last reply lost in a count-limited configuration, IPv4",
886  USEIPV6_FALSE);
887  std::list<uint32_t> dropList3{2};
888  testcase9v4->SetDropList(dropList3);
889  testcase9v4->SetStartTime(Seconds(1));
890  testcase9v4->SetCount(3);
891  testcase9v4->SetStopTime(Seconds(5));
892  testcase9v4->CheckTraceTx(3);
893  testcase9v4->CheckTraceRtt(2);
894  testcase9v4->CheckReportTransmitted(3);
895  testcase9v4->CheckReportReceived(2);
896  testcase9v4->CheckReportLoss(33); // 33%
897  testcase9v4->CheckReportTime(MicroSeconds(3040000));
898  AddTestCase(testcase9v4, TestCase::QUICK);
899 
900  PingTestCase* testcase9v6 = new PingTestCase(
901  "9. Test behavior of last reply lost in a count-limited configuration, IPv6",
902  USEIPV6_TRUE);
903  testcase9v6->SetDropList(dropList3);
904  testcase9v6->SetStartTime(Seconds(1));
905  testcase9v6->SetCount(3);
906  testcase9v6->SetStopTime(Seconds(5));
907  testcase9v6->SetDestinationAddress(Ipv6Address("2001:1::200:ff:fe00:2"));
908  testcase9v6->CheckTraceTx(3);
909  testcase9v6->CheckTraceRtt(2);
910  testcase9v6->CheckReportTransmitted(3);
911  testcase9v6->CheckReportReceived(2);
912  testcase9v6->CheckReportLoss(33); // 33%
913  testcase9v6->CheckReportTime(MicroSeconds(3040000));
914  AddTestCase(testcase9v6, TestCase::QUICK);
915 
916 #ifdef NOTYET
917  //
918  // 10. Test for behavior of pinging on a link that causes IPv4 fragmentation
919  // Configuration: Ping::Count = 1, Ping start time = 1s
920  // Ping stop time = 2.5s. Ping to Node 1
921  // Ping size set to 2000 bytes.
922  // Expected behavior: At shortly after time 1 seconds, Ping should
923  // successfully exit by recording the successful
924  // exchange of one echo request and reply.
925  // How validated: PingReport trace is checked for number of packets
926  // transmitted (5) and received (0).
927  // PingReport time is checked for an explicit time
928  // (1.020028s) corresponding to 2000 bytes
929  // The packet loss rate should be checked to be 100 percent
930  PingTestCase* testcase10v4 = new PingTestCase("10. Test for IPv4 fragmentation", USEIPV6_FALSE);
931  testcase10v4->SetStartTime(Seconds(1));
932  testcase10v4->SetStopTime(Seconds(2.5));
933  testcase10v4->SetCount(1);
934  testcase10v4->SetSize(2000);
935  testcase10v4->CheckReportTransmitted(1);
936  testcase10v4->CheckReportReceived(1);
937  testcase10v4->CheckReportTime(MicroSeconds(1020028));
938  AddTestCase(testcase10v4, TestCase::QUICK);
939 #endif
940 }
941 
ping basic tests
Definition: ping-test.cc:89
Time m_interpacketInterval
Time between pings.
Definition: ping-test.cc:260
bool m_checkReportTime
Set to true to check the Time.
Definition: ping-test.cc:254
Time m_simulatorStopTime
Simulator stop time.
Definition: ping-test.cc:258
void RttTraceSink(uint16_t seq, Time rttSample)
Trace RTT events.
Definition: ping-test.cc:361
uint32_t m_sizeAttribute
Size of pings.
Definition: ping-test.cc:235
uint16_t m_expectedReportLoss
Expected reported Loss.
Definition: ping-test.cc:248
uint32_t m_countTraceRtt
Rtt trace counter.
Definition: ping-test.cc:241
uint32_t m_expectedReportTx
Expected reported Tx.
Definition: ping-test.cc:246
void SetStartTime(Time startTime)
Set the PING start time.
Definition: ping-test.cc:114
void SetStopTime(Time stopTime)
Set the PING stop time.
Definition: ping-test.cc:123
PingTestCase(std::string name, bool useIpv6)
Constructor.
Definition: ping-test.cc:270
uint32_t m_expectedTraceRtt
Expected Rtt trace sink calls.
Definition: ping-test.cc:238
void CheckReportTime(Time expectedTime)
Enable the check on average RTT.
Definition: ping-test.cc:354
void SetSimulatorStopTime(Time stopTime)
Set the Simulation stop time.
Definition: ping-test.cc:475
bool m_checkTraceTx
Set to true to check the Tx number.
Definition: ping-test.cc:243
void TxTraceSink(uint16_t seq, Ptr< Packet > p)
Trace TX events.
Definition: ping-test.cc:391
Ipv6InterfaceContainer m_ipv6Interfaces
The IPv6 interfaces.
Definition: ping-test.cc:266
uint32_t m_countTraceTx
Tx trace counter.
Definition: ping-test.cc:240
Time m_lastTx
Last ping Tx time.
Definition: ping-test.cc:261
void SetCount(uint32_t count)
Set the number of pings to send.
Definition: ping-test.cc:132
bool m_checkReportTransmitted
Set to true to check the Tx number.
Definition: ping-test.cc:251
uint32_t m_mtu
Link MTU.
Definition: ping-test.cc:233
Time m_expectedReportTime
Expected reported time.
Definition: ping-test.cc:249
void CheckReportTransmitted(uint32_t expectedReportTx)
Enable the check on Tx pings.
Definition: ping-test.cc:333
NodeContainer m_nodes
The simulation nodes.
Definition: ping-test.cc:264
bool m_checkReportLoss
Set to true to check the Loss number.
Definition: ping-test.cc:253
bool m_useIpv6
Use IPv6 (true) or IPv4 (false)
Definition: ping-test.cc:259
void ReportTraceSink(const Ping::PingReport &report)
Trace Report generation events.
Definition: ping-test.cc:427
void CheckReportLoss(uint16_t expectedReportLoss)
Enable the check on Lost pings.
Definition: ping-test.cc:347
bool m_checkReportReceived
Set to true to check the Rx number.
Definition: ping-test.cc:252
void DoRun() override
Implementation to actually run this TestCase.
Definition: ping-test.cc:487
Address m_destination
Destination address.
Definition: ping-test.cc:232
Time m_stopTime
Stop time.
Definition: ping-test.cc:257
void CheckTraceRtt(uint32_t expectedRtt)
Enable the check on Rtt event count in Rtt trace source.
Definition: ping-test.cc:468
uint32_t m_expectedTraceTx
Expected Tx trace sink calls.
Definition: ping-test.cc:237
bool m_checkTraceRtt
Set to true to check the Rtt number.
Definition: ping-test.cc:244
void SetInterval(Time interval)
Set the interval of pings.
Definition: ping-test.cc:150
void CheckReportReceived(uint32_t expectedReportRx)
Enable the check on Rx pings.
Definition: ping-test.cc:340
void DropTraceSink(uint16_t seq, Ping::DropReason reason)
Trace Drop events.
Definition: ping-test.cc:409
NetDeviceContainer m_devices
The NetDevices.
Definition: ping-test.cc:267
Ipv4InterfaceContainer m_ipv4Interfaces
The IPv4 interfaces.
Definition: ping-test.cc:265
uint32_t m_expectedReportRx
Expected reported Rx.
Definition: ping-test.cc:247
Time m_startTime
Start time.
Definition: ping-test.cc:256
void SetDestinationAddress(Address address)
Set the destination address (either IPv4 or IPv6).
Definition: ping-test.cc:481
void DoSetup() override
Implementation to do any local setup required for this TestCase.
Definition: ping-test.cc:277
std::list< uint32_t > m_dropList
Drop first reply (true)
Definition: ping-test.cc:262
uint32_t m_countAttribute
Number of pings to send.
Definition: ping-test.cc:234
void SetSize(uint32_t size)
Set the size of pings.
Definition: ping-test.cc:141
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
Definition: ping-test.cc:327
void SetDropList(const std::list< uint32_t > &dropList)
Set the packet drop list on the Ping node's interface.
Definition: ping-test.cc:159
void CheckTraceTx(uint32_t expectedTx)
Enable the check on Tx pings counted in Tx trace source.
Definition: ping-test.cc:461
ping TestSuite
Definition: ping-test.cc:564
a polymophic address class
Definition: address.h:100
AttributeValue implementation for Address.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
AttributeValue implementation for DataRate.
An implementation of the ICMPv6 protocol.
aggregate IP/TCP/UDP functionality to existing Nodes.
void SetIpv4StackInstall(bool enable)
Enable/disable IPv4 stack install.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
void SetIpv6StackInstall(bool enable)
Enable/disable IPv6 stack install.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
Helper class to auto-assign global IPv6 unicast addresses.
void SetBase(Ipv6Address network, Ipv6Prefix prefix, Ipv6Address base=Ipv6Address("::1"))
Set the base network number, network prefix, and base interface ID.
Describes an IPv6 address.
Definition: ipv6-address.h:50
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
bool IsLinkLocalMulticast() const
If the IPv6 address is link-local multicast (ff02::/16).
Keep track of a set of IPv6 interfaces.
Ipv6Address GetAddress(uint32_t i, uint32_t j) const
Get the address for the specified index.
IPv6 layer implementation.
Describes an IPv6 prefix.
Definition: ipv6-address.h:456
A helper class to populate neighbor cache.
void PopulateNeighborCache()
Populate neighbor ARP and NDISC caches for all devices.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:169
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
DropReason
Reason why a ping was dropped.
Definition: ping.h:80
build a set of SimpleNetDevice objects
void SetNetDevicePointToPointMode(bool pointToPointMode)
SimpleNetDevice is Broadcast capable and ARP needing.
void SetDeviceAttribute(std::string n1, const AttributeValue &v1)
void SetChannel(std::string type, Ts &&... args)
Each net device must have a channel to pass packets through.
NetDeviceContainer Install(Ptr< Node > node) const
This method creates an ns3::SimpleChannel with the attributes configured by SimpleNetDeviceHelper::Se...
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:305
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:417
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:402
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:412
AttributeValue implementation for Time.
Definition: nstime.h:1423
Hold an unsigned integer type.
Definition: uinteger.h:45
Time stopTime
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Definition: data-rate.h:328
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:296
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition: test.h:337
#define NS_TEST_ASSERT_MSG_GT_OR_EQ(actual, limit, msg)
Test that an actual value is greater than or equal to a limit and report and abort if not.
Definition: test.h:915
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1360
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
address
Definition: first.py:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:707
static PingTestSuite pingTestSuite
Static variable for test initialization.
Definition: ping-test.cc:942
constexpr bool USEIPV6_TRUE
Definition: ping-test.cc:75
constexpr bool USEIPV6_FALSE
Definition: ping-test.cc:74
A ping report provides all of the data that is typically output to the terminal when the application ...
Definition: ping.h:92
uint16_t m_loss
Percentage of lost packets (decimal value 0-100)
Definition: ping.h:95
uint32_t m_received
Number of echo replies received.
Definition: ping.h:94
double m_rttMin
rtt min value
Definition: ping.h:97
uint32_t m_transmitted
Number of echo requests sent.
Definition: ping.h:93
double m_rttMax
rtt max value
Definition: ping.h:99