A Discrete-Event Network Simulator
API
csma-system-test-suite.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License version 2 as
4  * published by the Free Software Foundation;
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program; if not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14  */
15 
16 // This is not a test of CsmaNetDevice model behavior per-se, but
17 // instead is a roll up of several end-to-end examples in examples/csma
18 // directory, converted into system tests. Writing a test suite
19 // to test Csma itself is for further study.
20 
21 #include "ns3/address.h"
22 #include "ns3/application-container.h"
23 #include "ns3/bridge-helper.h"
24 #include "ns3/callback.h"
25 #include "ns3/config.h"
26 #include "ns3/csma-helper.h"
27 #include "ns3/csma-star-helper.h"
28 #include "ns3/data-rate.h"
29 #include "ns3/inet-socket-address.h"
30 #include "ns3/internet-stack-helper.h"
31 #include "ns3/ipv4-address-helper.h"
32 #include "ns3/ipv4-global-routing-helper.h"
33 #include "ns3/ipv4-static-routing-helper.h"
34 #include "ns3/node-container.h"
35 #include "ns3/node.h"
36 #include "ns3/on-off-helper.h"
37 #include "ns3/packet-sink-helper.h"
38 #include "ns3/packet-socket-address.h"
39 #include "ns3/packet-socket-helper.h"
40 #include "ns3/packet.h"
41 #include "ns3/ping-helper.h"
42 #include "ns3/pointer.h"
43 #include "ns3/simple-channel.h"
44 #include "ns3/simulator.h"
45 #include "ns3/string.h"
46 #include "ns3/test.h"
47 #include "ns3/uinteger.h"
48 
49 #include <string>
50 
51 using namespace ns3;
52 
59 {
60  public:
62  ~CsmaBridgeTestCase() override;
63 
64  private:
65  void DoRun() override;
66 
72  void SinkRx(Ptr<const Packet> p, const Address& ad);
73  uint32_t m_count;
74 };
75 
76 // Add some help text to this case to describe what it is intended to test
78  : TestCase("Bridge example for Carrier Sense Multiple Access (CSMA) networks"),
79  m_count(0)
80 {
81 }
82 
84 {
85 }
86 
87 void
89 {
90  m_count++;
91 }
92 
93 // Network topology
94 //
95 // n0 n1
96 // | |
97 // ----------
98 // | Switch |
99 // ----------
100 // | |
101 // n2 n3
102 //
103 // - CBR/UDP test flow from n0 to n1; test that packets received on n1
104 //
105 void
107 {
109  terminals.Create(4);
110 
112  csmaSwitch.Create(1);
113 
115  csma.SetChannelAttribute("DataRate", DataRateValue(5000000));
116  csma.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
117 
120 
121  for (int i = 0; i < 4; i++)
122  {
124  terminalDevices.Add(link.Get(0));
125  switchDevices.Add(link.Get(1));
126  }
127 
128  // Create the bridge netdevice, which will do the packet switching
130  BridgeHelper bridge;
132 
134  internet.Install(terminals);
135 
137  ipv4.SetBase("10.1.1.0", "255.255.255.0");
138  ipv4.Assign(terminalDevices);
139 
140  uint16_t port = 9; // Discard port (RFC 863)
141 
142  // Create the OnOff application to send UDP datagrams from n0 to n1.
143  //
144  // Make packets be sent about every DefaultPacketSize / DataRate =
145  // 4096 bits / (5000 bits/second) = 0.82 second.
146  OnOffHelper onoff("ns3::UdpSocketFactory",
147  Address(InetSocketAddress(Ipv4Address("10.1.1.2"), port)));
148  onoff.SetConstantRate(DataRate(5000));
149 
150  ApplicationContainer app = onoff.Install(terminals.Get(0));
151  app.Start(Seconds(1.0));
152  app.Stop(Seconds(10.0));
153 
154  PacketSinkHelper sink("ns3::UdpSocketFactory",
155  Address(InetSocketAddress(Ipv4Address::GetAny(), port)));
156  app = sink.Install(terminals.Get(1));
157  app.Start(Seconds(0.0));
158 
159  // Trace receptions
160  Config::ConnectWithoutContext("/NodeList/1/ApplicationList/0/$ns3::PacketSink/Rx",
162 
163  Simulator::Run();
164  Simulator::Destroy();
165 
166  // We should have sent and received 10 packets
167  NS_TEST_ASSERT_MSG_EQ(m_count, 10, "Bridge should have passed 10 packets");
168 }
169 
176 {
177  public:
179  ~CsmaBroadcastTestCase() override;
180 
181  private:
182  void DoRun() override;
183 
190  void SinkRxNode1(Ptr<const Packet> p, const Address& ad);
191  void SinkRxNode2(Ptr<const Packet> p, const Address& ad);
199 
200  uint32_t m_countNode1;
201  uint32_t m_countNode2;
202  uint32_t m_drops;
203 };
204 
205 // Add some help text to this case to describe what it is intended to test
207  : TestCase("Broadcast example for Carrier Sense Multiple Access (CSMA) networks"),
208  m_countNode1(0),
209  m_countNode2(0),
210  m_drops(0)
211 {
212 }
213 
215 {
216 }
217 
218 void
220 {
221  m_countNode1++;
222 }
223 
224 void
226 {
227  m_countNode2++;
228 }
229 
230 void
232 {
233  m_drops++;
234 }
235 
236 //
237 // Example of the sending of a datagram to a broadcast address
238 //
239 // Network topology
240 // ==============
241 // | |
242 // n0 n1 n2
243 // | |
244 // ==========
245 //
246 // n0 originates UDP broadcast to 255.255.255.255/discard port, which
247 // is replicated and received on both n1 and n2
248 //
249 void
251 {
252  NodeContainer c;
253  c.Create(3);
254  NodeContainer c0 = NodeContainer(c.Get(0), c.Get(1));
255  NodeContainer c1 = NodeContainer(c.Get(0), c.Get(2));
256 
258  csma.SetChannelAttribute("DataRate", DataRateValue(DataRate(5000000)));
259  csma.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
260 
261  NetDeviceContainer n0 = csma.Install(c0);
262  NetDeviceContainer n1 = csma.Install(c1);
263 
265  internet.Install(c);
266 
268  ipv4.SetBase("10.1.0.0", "255.255.255.0");
269  ipv4.Assign(n0);
270  ipv4.SetBase("192.168.1.0", "255.255.255.0");
271  ipv4.Assign(n1);
272 
273  // RFC 863 discard port ("9") indicates packet should be thrown away
274  // by the system. We allow this silent discard to be overridden
275  // by the PacketSink application.
276  uint16_t port = 9;
277 
278  // Create the OnOff application to send UDP datagrams from n0.
279  //
280  // Make packets be sent about every DefaultPacketSize / DataRate =
281  // 4096 bits / (5000 bits/second) = 0.82 second.
282  OnOffHelper onoff("ns3::UdpSocketFactory",
283  Address(InetSocketAddress(Ipv4Address("255.255.255.255"), port)));
284  onoff.SetConstantRate(DataRate(5000));
285 
286  ApplicationContainer app = onoff.Install(c0.Get(0));
287  // Start the application
288  app.Start(Seconds(1.0));
289  app.Stop(Seconds(10.0));
290 
291  // Create an optional packet sink to receive these packets
292  PacketSinkHelper sink("ns3::UdpSocketFactory",
293  Address(InetSocketAddress(Ipv4Address::GetAny(), port)));
294  app = sink.Install(c0.Get(1));
295  app.Add(sink.Install(c1.Get(1)));
296  app.Start(Seconds(1.0));
297  app.Stop(Seconds(10.0));
298 
299  // Trace receptions
300  Config::ConnectWithoutContext("/NodeList/1/ApplicationList/0/$ns3::PacketSink/Rx",
302  Config::ConnectWithoutContext("/NodeList/2/ApplicationList/0/$ns3::PacketSink/Rx",
304 
305  Simulator::Run();
306  Simulator::Destroy();
307 
308  // We should have sent and received 10 packets
309  NS_TEST_ASSERT_MSG_EQ(m_countNode1, 10, "Node 1 should have received 10 packets");
310  NS_TEST_ASSERT_MSG_EQ(m_countNode2, 10, "Node 2 should have received 10 packets");
311 }
312 
319 {
320  public:
322  ~CsmaMulticastTestCase() override;
323 
324  private:
325  void DoRun() override;
326 
332  void SinkRx(Ptr<const Packet> p, const Address& ad);
333 
339 
340  uint32_t m_count;
341  uint32_t m_drops;
342 };
343 
344 // Add some help text to this case to describe what it is intended to test
346  : TestCase("Multicast example for Carrier Sense Multiple Access (CSMA) networks"),
347  m_count(0),
348  m_drops(0)
349 {
350 }
351 
353 {
354 }
355 
356 void
358 {
359  m_count++;
360 }
361 
362 void
364 {
365  m_drops++;
366 }
367 
368 // Network topology
369 //
370 // Lan1
371 // ===========
372 // | | |
373 // n0 n1 n2 n3 n4
374 // | | |
375 // ===========
376 // Lan0
377 //
378 // - Multicast source is at node n0;
379 // - Multicast forwarded by node n2 onto LAN1;
380 // - Nodes n0, n1, n2, n3, and n4 receive the multicast frame.
381 // - Node n4 listens for the data
382 //
383 void
385 {
386  //
387  // Set up default values for the simulation.
388  //
389  // Select DIX/Ethernet II-style encapsulation (no LLC/Snap header)
390  Config::SetDefault("ns3::CsmaNetDevice::EncapsulationMode", StringValue("Dix"));
391 
392  NodeContainer c;
393  c.Create(5);
394  // We will later want two subcontainers of these nodes, for the two LANs
395  NodeContainer c0 = NodeContainer(c.Get(0), c.Get(1), c.Get(2));
396  NodeContainer c1 = NodeContainer(c.Get(2), c.Get(3), c.Get(4));
397 
399  csma.SetChannelAttribute("DataRate", DataRateValue(DataRate(5000000)));
400  csma.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
401 
402  // We will use these NetDevice containers later, for IP addressing
403  NetDeviceContainer nd0 = csma.Install(c0); // First LAN
404  NetDeviceContainer nd1 = csma.Install(c1); // Second LAN
405 
407  internet.Install(c);
408 
409  Ipv4AddressHelper ipv4Addr;
410  ipv4Addr.SetBase("10.1.1.0", "255.255.255.0");
411  ipv4Addr.Assign(nd0);
412  ipv4Addr.SetBase("10.1.2.0", "255.255.255.0");
413  ipv4Addr.Assign(nd1);
414 
415  //
416  // Now we can configure multicasting. As described above, the multicast
417  // source is at node zero, which we assigned the IP address of 10.1.1.1
418  // earlier. We need to define a multicast group to send packets to. This
419  // can be any multicast address from 224.0.0.0 through 239.255.255.255
420  // (avoiding the reserved routing protocol addresses).
421  //
422 
423  Ipv4Address multicastSource("10.1.1.1");
424  Ipv4Address multicastGroup("225.1.2.4");
425 
426  // Now, we will set up multicast routing. We need to do three things:
427  // 1) Configure a (static) multicast route on node n2
428  // 2) Set up a default multicast route on the sender n0
429  // 3) Have node n4 join the multicast group
430  // We have a helper that can help us with static multicast
431  Ipv4StaticRoutingHelper multicast;
432 
433  // 1) Configure a (static) multicast route on node n2 (multicastRouter)
434  Ptr<Node> multicastRouter = c.Get(2); // The node in question
435  Ptr<NetDevice> inputIf = nd0.Get(2); // The input NetDevice
436  NetDeviceContainer outputDevices; // A container of output NetDevices
437  outputDevices.Add(nd1.Get(0)); // (we only need one NetDevice here)
438 
439  multicast.AddMulticastRoute(multicastRouter,
440  multicastSource,
441  multicastGroup,
442  inputIf,
443  outputDevices);
444 
445  // 2) Set up a default multicast route on the sender n0
446  Ptr<Node> sender = c.Get(0);
447  Ptr<NetDevice> senderIf = nd0.Get(0);
448  multicast.SetDefaultMulticastRoute(sender, senderIf);
449 
450  //
451  // Create an OnOff application to send UDP datagrams from node zero to the
452  // multicast group (node four will be listening).
453  //
454 
455  uint16_t multicastPort = 9; // Discard port (RFC 863)
456 
457  // Configure a multicast packet generator.
458  //
459  // Make packets be sent about every defaultPacketSize / dataRate =
460  // 4096 bits / (5000 bits/second) = 0.82 second.
461  OnOffHelper onoff("ns3::UdpSocketFactory",
462  Address(InetSocketAddress(multicastGroup, multicastPort)));
463  onoff.SetConstantRate(DataRate(5000));
464 
465  ApplicationContainer srcC = onoff.Install(c0.Get(0));
466 
467  //
468  // Tell the application when to start and stop.
469  //
470  srcC.Start(Seconds(1.));
471  srcC.Stop(Seconds(10.));
472 
473  // Create an optional packet sink to receive these packets
474  PacketSinkHelper sink("ns3::UdpSocketFactory",
475  InetSocketAddress(Ipv4Address::GetAny(), multicastPort));
476 
477  ApplicationContainer sinkC = sink.Install(c1.Get(2)); // Node n4
478  // Start the sink
479  sinkC.Start(Seconds(1.0));
480  sinkC.Stop(Seconds(10.0));
481 
482  // Trace receptions
483  Config::ConnectWithoutContext("/NodeList/4/ApplicationList/0/$ns3::PacketSink/Rx",
485 
486  //
487  // Now, do the actual simulation.
488  //
489  Simulator::Run();
490  Simulator::Destroy();
491 
492  // We should have sent and received 10 packets
493  NS_TEST_ASSERT_MSG_EQ(m_count, 10, "Node 4 should have received 10 packets");
494 }
495 
502 {
503  public:
505  ~CsmaOneSubnetTestCase() override;
506 
507  private:
508  void DoRun() override;
509 
516  void SinkRxNode0(Ptr<const Packet> p, const Address& ad);
517  void SinkRxNode1(Ptr<const Packet> p, const Address& ad);
525  uint32_t m_countNode0;
526  uint32_t m_countNode1;
527  uint32_t m_drops;
528 };
529 
530 // Add some help text to this case to describe what it is intended to test
532  : TestCase("One subnet example for Carrier Sense Multiple Access (CSMA) networks"),
533  m_countNode0(0),
534  m_countNode1(0),
535  m_drops(0)
536 {
537 }
538 
540 {
541 }
542 
543 void
545 {
546  m_countNode0++;
547 }
548 
549 void
551 {
552  m_countNode1++;
553 }
554 
555 void
557 {
558  m_drops++;
559 }
560 
561 // Network topology
562 //
563 // n0 n1 n2 n3
564 // | | | |
565 // =================
566 // LAN
567 //
568 // - CBR/UDP flows from n0 to n1 and from n3 to n0
569 // - DropTail queues
570 //
571 void
573 {
575  nodes.Create(4);
576 
578  csma.SetChannelAttribute("DataRate", DataRateValue(5000000));
579  csma.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
580  //
581  // Now fill out the topology by creating the net devices required to connect
582  // the nodes to the channels and hooking them up.
583  //
585 
587  internet.Install(nodes);
588 
589  // We've got the "hardware" in place. Now we need to add IP addresses.
590  //
592  ipv4.SetBase("10.1.1.0", "255.255.255.0");
594 
595  uint16_t port = 9; // Discard port (RFC 863)
596 
597  //
598  // Create an OnOff application to send UDP datagrams from node zero
599  // to node 1.
600  //
601  // Make packets be sent about every defaultPacketSize / dataRate =
602  // 4096 bits / (5000 bits/second) = 0.82 second.
603  OnOffHelper onoff("ns3::UdpSocketFactory",
604  Address(InetSocketAddress(interfaces.GetAddress(1), port)));
605  onoff.SetConstantRate(DataRate(5000));
606 
607  ApplicationContainer app = onoff.Install(nodes.Get(0));
608  // Start the application
609  app.Start(Seconds(1.0));
610  app.Stop(Seconds(10.0));
611 
612  // Create an optional packet sink to receive these packets
613  PacketSinkHelper sink("ns3::UdpSocketFactory",
614  Address(InetSocketAddress(Ipv4Address::GetAny(), port)));
615  app = sink.Install(nodes.Get(1));
616  app.Start(Seconds(0.0));
617 
618  //
619  // Create a similar flow from n3 to n0, starting at time 1.1 seconds
620  //
621  onoff.SetAttribute("Remote", AddressValue(InetSocketAddress(interfaces.GetAddress(0), port)));
622  app = onoff.Install(nodes.Get(3));
623  app.Start(Seconds(1.1));
624  app.Stop(Seconds(10.0));
625 
626  app = sink.Install(nodes.Get(0));
627  app.Start(Seconds(0.0));
628 
629  // Trace receptions
630  Config::ConnectWithoutContext("/NodeList/0/ApplicationList/1/$ns3::PacketSink/Rx",
632  Config::ConnectWithoutContext("/NodeList/1/ApplicationList/0/$ns3::PacketSink/Rx",
634 
635  //
636  // Now, do the actual simulation.
637  //
638  Simulator::Run();
639  Simulator::Destroy();
640 
641  // We should have sent and received 10 packets
642  NS_TEST_ASSERT_MSG_EQ(m_countNode0, 10, "Node 0 should have received 10 packets");
643  NS_TEST_ASSERT_MSG_EQ(m_countNode1, 10, "Node 1 should have received 10 packets");
644 }
645 
652 {
653  public:
655  ~CsmaPacketSocketTestCase() override;
656 
657  private:
658  void DoRun() override;
665  void SinkRx(std::string path, Ptr<const Packet> p, const Address& ad);
666 
672 
673  uint32_t m_count;
674  uint32_t m_drops;
675 };
676 
677 // Add some help text to this case to describe what it is intended to test
679  : TestCase("Packet socket example for Carrier Sense Multiple Access (CSMA) networks"),
680  m_count(0),
681  m_drops(0)
682 {
683 }
684 
686 {
687 }
688 
689 void
691 {
692  m_count++;
693 }
694 
695 void
697 {
698  m_drops++;
699 }
700 
701 //
702 // Network topology
703 //
704 // n0 n1 n2 n3
705 // | | | |
706 // =====================
707 //
708 // - Packet socket flow from n0 to n1 and from node n3 to n0
709 // -- We will test reception at node n0
710 // - Default 512 byte packets generated by traffic generator
711 //
712 void
714 {
715  // Here, we will explicitly create four nodes.
717  nodes.Create(4);
718 
719  PacketSocketHelper packetSocket;
720  packetSocket.Install(nodes);
721 
722  // create the shared medium used by all csma devices.
724  CreateObjectWithAttributes<CsmaChannel>("DataRate",
725  DataRateValue(DataRate(5000000)),
726  "Delay",
727  TimeValue(MilliSeconds(2)));
728 
729  // use a helper function to connect our nodes to the shared channel.
731  csma.SetDeviceAttribute("EncapsulationMode", StringValue("Llc"));
732  NetDeviceContainer devs = csma.Install(nodes, channel);
733 
734  // Create the OnOff application to send raw datagrams
735  //
736  // Make packets be sent about every DefaultPacketSize / DataRate =
737  // 4096 bits / (5000 bits/second) = 0.82 second.
738  PacketSocketAddress socket;
739  socket.SetSingleDevice(devs.Get(0)->GetIfIndex());
740  socket.SetPhysicalAddress(devs.Get(1)->GetAddress());
741  socket.SetProtocol(2);
742  OnOffHelper onoff("ns3::PacketSocketFactory", Address(socket));
743  onoff.SetConstantRate(DataRate(5000));
744  ApplicationContainer apps = onoff.Install(nodes.Get(0));
745  apps.Start(Seconds(1.0));
746  apps.Stop(Seconds(10.0));
747 
748  socket.SetSingleDevice(devs.Get(3)->GetIfIndex());
749  socket.SetPhysicalAddress(devs.Get(0)->GetAddress());
750  socket.SetProtocol(3);
751  onoff.SetAttribute("Remote", AddressValue(socket));
752  apps = onoff.Install(nodes.Get(3));
753  apps.Start(Seconds(1.0));
754  apps.Stop(Seconds(10.0));
755 
756  PacketSinkHelper sink = PacketSinkHelper("ns3::PacketSocketFactory", socket);
757  apps = sink.Install(nodes.Get(0));
758  apps.Start(Seconds(0.0));
759  apps.Stop(Seconds(20.0));
760 
761  // Trace receptions
762  Config::Connect("/NodeList/0/ApplicationList/*/$ns3::PacketSink/Rx",
764 
765  Simulator::Run();
766  Simulator::Destroy();
767 
768  // We should have received 10 packets on node 0
769  NS_TEST_ASSERT_MSG_EQ(m_count, 10, "Node 0 should have received 10 packets");
770 }
771 
778 {
779  public:
781  ~CsmaPingTestCase() override;
782 
783  private:
784  void DoRun() override;
788  void SinkRx(Ptr<const Packet>, const Address&);
789 
793  void PingRtt(std::string, uint16_t, Time);
794 
799 
800  uint32_t m_countSinkRx;
801  uint32_t m_countPingRtt;
802  uint32_t m_drops;
803 };
804 
805 // Add some help text to this case to describe what it is intended to test
807  : TestCase("Ping example for Carrier Sense Multiple Access (CSMA) networks"),
808  m_countSinkRx(0),
809  m_countPingRtt(0),
810  m_drops(0)
811 {
812 }
813 
815 {
816 }
817 
818 void
820 {
821  m_countSinkRx++;
822 }
823 
824 void
825 CsmaPingTestCase::PingRtt(std::string, uint16_t, Time)
826 {
827  m_countPingRtt++;
828 }
829 
830 void
832 {
833  m_drops++;
834 }
835 
836 // Network topology
837 //
838 // n0 n1 n2 n3
839 // | | | |
840 // =====================
841 //
842 // node n0,n1,n3 pings to node n2
843 // node n0 generates protocol 2 (IGMP) to node n3
844 //
845 void
847 {
848  // Here, we will explicitly create four nodes.
849  NodeContainer c;
850  c.Create(4);
851 
852  // connect all our nodes to a shared channel.
854  csma.SetChannelAttribute("DataRate", DataRateValue(DataRate(5000000)));
855  csma.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
856  csma.SetDeviceAttribute("EncapsulationMode", StringValue("Llc"));
857  NetDeviceContainer devs = csma.Install(c);
858 
859  // add an ip stack to all nodes.
860  InternetStackHelper ipStack;
861  ipStack.Install(c);
862 
863  // assign ip addresses
865  ip.SetBase("192.168.1.0", "255.255.255.0");
866  Ipv4InterfaceContainer addresses = ip.Assign(devs);
867 
868  // Create the OnOff application to send UDP datagrams from n0 to n1.
869  //
870  // Make packets be sent about every DefaultPacketSize / DataRate =
871  // 4096 bits / (5000 bits/second) = 0.82 second.
872  Config::SetDefault("ns3::Ipv4RawSocketImpl::Protocol", StringValue("2"));
873  InetSocketAddress dst(addresses.GetAddress(3));
874  OnOffHelper onoff = OnOffHelper("ns3::Ipv4RawSocketFactory", dst);
875  onoff.SetConstantRate(DataRate(5000));
876 
877  ApplicationContainer apps = onoff.Install(c.Get(0));
878  apps.Start(Seconds(1.0));
879  apps.Stop(Seconds(10.0));
880 
881  PacketSinkHelper sink = PacketSinkHelper("ns3::Ipv4RawSocketFactory", dst);
882  apps = sink.Install(c.Get(3));
883  apps.Start(Seconds(0.0));
884  apps.Stop(Seconds(11.0));
885 
886  PingHelper ping(addresses.GetAddress(2));
887  NodeContainer pingers;
888  pingers.Add(c.Get(0));
889  pingers.Add(c.Get(1));
890  pingers.Add(c.Get(3));
891  apps = ping.Install(pingers);
892  apps.Start(Seconds(2.0));
893  apps.Stop(Seconds(5.0));
894 
895  // Trace receptions
896  Config::ConnectWithoutContext("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx",
898 
899  // Trace pings
900  Config::Connect("/NodeList/*/ApplicationList/*/$ns3::Ping/Rtt",
902 
903  Simulator::Run();
904  Simulator::Destroy();
905 
906  // We should have sent and received 10 packets
907  NS_TEST_ASSERT_MSG_EQ(m_countSinkRx, 10, "Node 3 should have received 10 packets");
908 
909  // We should have 3 pingers that ping every second for 3 seconds.
910  NS_TEST_ASSERT_MSG_EQ(m_countPingRtt, 9, "Node 2 should have been pinged 9 times");
911 }
912 
919 {
920  public:
922  ~CsmaRawIpSocketTestCase() override;
923 
924  private:
925  void DoRun() override;
926 
932  void SinkRx(Ptr<const Packet> p, const Address& ad);
933 
939 
940  uint32_t m_count;
941  uint32_t m_drops;
942 };
943 
944 // Add some help text to this case to describe what it is intended to test
946  : TestCase(
947  "Raw internet protocol socket example for Carrier Sense Multiple Access (CSMA) networks"),
948  m_count(0),
949  m_drops(0)
950 {
951 }
952 
954 {
955 }
956 
957 void
959 {
960  m_count++;
961 }
962 
963 void
965 {
966  m_drops++;
967 }
968 
969 //
970 // Network topology
971 // (sender) (receiver)
972 // n0 n1 n2 n3
973 // | | | |
974 // =====================
975 //
976 // Node n0 sends data to node n3 over a raw IP socket. The protocol
977 // number used is 2.
978 //
979 void
981 {
982  // Here, we will explicitly create four nodes.
983  NodeContainer c;
984  c.Create(4);
985 
986  // connect all our nodes to a shared channel.
988  csma.SetChannelAttribute("DataRate", DataRateValue(DataRate(5000000)));
989  csma.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
990  csma.SetDeviceAttribute("EncapsulationMode", StringValue("Llc"));
991  NetDeviceContainer devs = csma.Install(c);
992 
993  // add an ip stack to all nodes.
994  InternetStackHelper ipStack;
995  ipStack.Install(c);
996 
997  // assign ip addresses
999  ip.SetBase("192.168.1.0", "255.255.255.0");
1000  Ipv4InterfaceContainer addresses = ip.Assign(devs);
1001 
1002  // IP protocol configuration
1003  //
1004  // Make packets be sent about every DefaultPacketSize / DataRate =
1005  // 4096 bits / (5000 bits/second) = 0.82 second.
1006  Config::SetDefault("ns3::Ipv4RawSocketImpl::Protocol", StringValue("2"));
1007  InetSocketAddress dst(addresses.GetAddress(3));
1008  OnOffHelper onoff = OnOffHelper("ns3::Ipv4RawSocketFactory", dst);
1009  onoff.SetConstantRate(DataRate(5000));
1010 
1011  ApplicationContainer apps = onoff.Install(c.Get(0));
1012  apps.Start(Seconds(1.0));
1013  apps.Stop(Seconds(10.0));
1014 
1015  PacketSinkHelper sink = PacketSinkHelper("ns3::Ipv4RawSocketFactory", dst);
1016  apps = sink.Install(c.Get(3));
1017  apps.Start(Seconds(0.0));
1018  apps.Stop(Seconds(12.0));
1019 
1020  // Trace receptions
1021  Config::ConnectWithoutContext("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx",
1023 
1024  Simulator::Run();
1025  Simulator::Destroy();
1026 
1027  // We should have sent and received 10 packets
1028  NS_TEST_ASSERT_MSG_EQ(m_count, 10, "Node 3 should have received 10 packets");
1029 }
1030 
1037 {
1038  public:
1039  CsmaStarTestCase();
1040  ~CsmaStarTestCase() override;
1041 
1042  private:
1043  void DoRun() override;
1044 
1050  void SinkRx(Ptr<const Packet> p, const Address& ad);
1051 
1056  void DropEvent(Ptr<const Packet> p);
1057 
1058  uint32_t m_count;
1059  uint32_t m_drops;
1060 };
1061 
1062 // Add some help text to this case to describe what it is intended to test
1064  : TestCase("Star example for Carrier Sense Multiple Access (CSMA) networks"),
1065  m_count(0),
1066  m_drops(0)
1067 {
1068 }
1069 
1071 {
1072 }
1073 
1074 void
1076 {
1077  m_count++;
1078 }
1079 
1080 void
1082 {
1083  m_drops++;
1084 }
1085 
1086 // Network topology (default)
1087 //
1088 // n2 + + n3 .
1089 // | ... |\ /| ... | .
1090 // ======= \ / ======= .
1091 // CSMA \ / CSMA .
1092 // \ / .
1093 // n1 +--- n0 ---+ n4 .
1094 // | ... | / \ | ... | .
1095 // ======= / \ ======= .
1096 // CSMA / \ CSMA .
1097 // / \ .
1098 // n6 + + n5 .
1099 // | ... | | ... | .
1100 // ======= ======= .
1101 // CSMA CSMA .
1102 //
1103 void
1105 {
1106  //
1107  // Default number of nodes in the star.
1108  //
1109  uint32_t nSpokes = 7;
1110 
1111  CsmaHelper csma;
1112  csma.SetChannelAttribute("DataRate", StringValue("100Mbps"));
1113  csma.SetChannelAttribute("Delay", StringValue("1ms"));
1114  CsmaStarHelper star(nSpokes, csma);
1115 
1116  NodeContainer fillNodes;
1117 
1118  //
1119  // Just to be nasy, hang some more nodes off of the CSMA channel for each
1120  // spoke, so that there are a total of 16 nodes on each channel. Stash
1121  // all of these new devices into a container.
1122  //
1123  NetDeviceContainer fillDevices;
1124 
1125  uint32_t nFill = 14;
1126  for (uint32_t i = 0; i < star.GetSpokeDevices().GetN(); ++i)
1127  {
1128  Ptr<Channel> channel = star.GetSpokeDevices().Get(i)->GetChannel();
1129  Ptr<CsmaChannel> csmaChannel = channel->GetObject<CsmaChannel>();
1130  NodeContainer newNodes;
1131  newNodes.Create(nFill);
1132  fillNodes.Add(newNodes);
1133  fillDevices.Add(csma.Install(newNodes, csmaChannel));
1134  }
1135 
1137  star.InstallStack(internet);
1138  internet.Install(fillNodes);
1139 
1140  star.AssignIpv4Addresses(Ipv4AddressHelper("10.1.0.0", "255.255.255.0"));
1141 
1142  //
1143  // We assigned addresses to the logical hub and the first "drop" of the
1144  // CSMA network that acts as the spoke, but we also have a number of fill
1145  // devices (nFill) also hanging off the CSMA network. We have got to
1146  // assign addresses to them as well. We put all of the fill devices into
1147  // a single device container, so the first nFill devices are associated
1148  // with the channel connected to spokeDevices.Get (0), the second nFill
1149  // devices are associated with the channel connected to spokeDevices.Get (1)
1150  // etc.
1151  //
1153  for (uint32_t i = 0; i < star.SpokeCount(); ++i)
1154  {
1155  std::ostringstream subnet;
1156  subnet << "10.1." << i << ".0";
1157  address.SetBase(subnet.str().c_str(), "255.255.255.0", "0.0.0.3");
1158 
1159  for (uint32_t j = 0; j < nFill; ++j)
1160  {
1161  address.Assign(fillDevices.Get(i * nFill + j));
1162  }
1163  }
1164 
1165  //
1166  // Create a packet sink on the star "hub" to receive packets.
1167  //
1168  uint16_t port = 50000;
1169  Address hubLocalAddress(InetSocketAddress(Ipv4Address::GetAny(), port));
1170  PacketSinkHelper packetSinkHelper("ns3::TcpSocketFactory", hubLocalAddress);
1171  ApplicationContainer hubApp = packetSinkHelper.Install(star.GetHub());
1172  hubApp.Start(Seconds(1.0));
1173  hubApp.Stop(Seconds(10.0));
1174 
1175  //
1176  // Create OnOff applications to send TCP to the hub, one on each spoke node.
1177  //
1178  // Make packets be sent about every DefaultPacketSize / DataRate =
1179  // 4096 bits / (5000 bits/second) = 0.82 second.
1180  OnOffHelper onOffHelper("ns3::TcpSocketFactory", Address());
1181  onOffHelper.SetConstantRate(DataRate(5000));
1182 
1183  ApplicationContainer spokeApps;
1184 
1185  for (uint32_t i = 0; i < star.SpokeCount(); ++i)
1186  {
1187  AddressValue remoteAddress(InetSocketAddress(star.GetHubIpv4Address(i), port));
1188  onOffHelper.SetAttribute("Remote", remoteAddress);
1189  spokeApps.Add(onOffHelper.Install(star.GetSpokeNode(i)));
1190  }
1191 
1192  spokeApps.Start(Seconds(1.0));
1193  spokeApps.Stop(Seconds(10.0));
1194 
1195  //
1196  // Because we are evil, we also add OnOff applications to send TCP to the hub
1197  // from the fill devices on each CSMA link. The first nFill nodes in the
1198  // fillNodes container are on the CSMA network talking to the zeroth device
1199  // on the hub node. The next nFill nodes are on the CSMA network talking to
1200  // the first device on the hub node, etc. So the ith fillNode is associated
1201  // with the hub address found on the (i / nFill)th device on the hub node.
1202  //
1203  ApplicationContainer fillApps;
1204 
1205  for (uint32_t i = 0; i < fillNodes.GetN(); ++i)
1206  {
1207  AddressValue remoteAddress(InetSocketAddress(star.GetHubIpv4Address(i / nFill), port));
1208  onOffHelper.SetAttribute("Remote", remoteAddress);
1209  fillApps.Add(onOffHelper.Install(fillNodes.Get(i)));
1210  }
1211 
1212  fillApps.Start(Seconds(1.0));
1213  fillApps.Stop(Seconds(10.0));
1214 
1215  //
1216  // Turn on global static routing so we can actually be routed across the star.
1217  //
1218  Ipv4GlobalRoutingHelper::PopulateRoutingTables();
1219 
1220  // Trace receptions
1221  Config::ConnectWithoutContext("/NodeList/0/ApplicationList/*/$ns3::PacketSink/Rx",
1223 
1224  Simulator::Run();
1225  Simulator::Destroy();
1226 
1227  // The hub node should have received 10 packets from the nFill + 1
1228  // nodes on each spoke.
1230  10 * (nSpokes * (nFill + 1)),
1231  "Hub node did not receive the proper number of packets");
1232 }
1233 
1240 {
1241  public:
1243 };
1244 
1246  : TestSuite("csma-system", UNIT)
1247 {
1248  AddTestCase(new CsmaBridgeTestCase, TestCase::QUICK);
1249  AddTestCase(new CsmaBroadcastTestCase, TestCase::QUICK);
1250  AddTestCase(new CsmaMulticastTestCase, TestCase::QUICK);
1251  AddTestCase(new CsmaOneSubnetTestCase, TestCase::QUICK);
1252  AddTestCase(new CsmaPacketSocketTestCase, TestCase::QUICK);
1253  AddTestCase(new CsmaPingTestCase, TestCase::QUICK);
1254  AddTestCase(new CsmaRawIpSocketTestCase, TestCase::QUICK);
1255  AddTestCase(new CsmaStarTestCase, TestCase::QUICK);
1256 }
1257 
CSMA Bridge mode test.
uint32_t m_count
Counter of received packets.
void DoRun() override
Implementation to actually run this TestCase.
void SinkRx(Ptr< const Packet > p, const Address &ad)
Sink called when a packet is received.
CSMA Broadcast mode test.
void DoRun() override
Implementation to actually run this TestCase.
uint32_t m_countNode2
Counter of received packets on node 2.
void DropEvent(Ptr< const Packet > p)
Sink called when a packet is dropped.
void SinkRxNode1(Ptr< const Packet > p, const Address &ad)
Sink called when a packet is received by a node.
void SinkRxNode2(Ptr< const Packet > p, const Address &ad)
Sink called when a packet is received by a node.
uint32_t m_countNode1
Counter of received packets on node 1.
uint32_t m_drops
Counter of dropped packets.
CSMA Multicast mode test.
void SinkRx(Ptr< const Packet > p, const Address &ad)
Sink called when a packet is received by a node.
void DropEvent(Ptr< const Packet > p)
Sink called when a packet is dropped.
void DoRun() override
Implementation to actually run this TestCase.
uint32_t m_count
Counter of received packets.
uint32_t m_drops
Counter of dropped packets.
CSMA One Subnet mode test.
uint32_t m_countNode1
Counter of received packets on node 1.
void SinkRxNode0(Ptr< const Packet > p, const Address &ad)
Sink called when a packet is received by a node.
uint32_t m_countNode0
Counter of received packets on node 0.
void SinkRxNode1(Ptr< const Packet > p, const Address &ad)
Sink called when a packet is received by a node.
void DropEvent(Ptr< const Packet > p)
Sink called when a packet is dropped.
void DoRun() override
Implementation to actually run this TestCase.
uint32_t m_drops
Counter of dropped packets.
uint32_t m_count
Counter of received packets.
void SinkRx(std::string path, Ptr< const Packet > p, const Address &ad)
Sink called when a packet is received by a node.
uint32_t m_drops
Counter of dropped packets.
void DropEvent(Ptr< const Packet > p)
Sink called when a packet is dropped.
void DoRun() override
Implementation to actually run this TestCase.
void DropEvent(Ptr< const Packet >)
Sink called when a packet is dropped.
void DoRun() override
Implementation to actually run this TestCase.
void PingRtt(std::string, uint16_t, Time)
Sink called when a PING is received.
void SinkRx(Ptr< const Packet >, const Address &)
Sink called when a packet is received by a node.
uint32_t m_drops
Counter of dropped packets.
uint32_t m_countSinkRx
Counter of received packets.
uint32_t m_countPingRtt
Counter of PING received.
void DropEvent(Ptr< const Packet > p)
Sink called when a packet is dropped.
void SinkRx(Ptr< const Packet > p, const Address &ad)
Sink called when a packet is received by a node.
void DoRun() override
Implementation to actually run this TestCase.
uint32_t m_drops
Counter of dropped packets.
uint32_t m_count
Counter of received packets.
CSMA star mode test.
void DropEvent(Ptr< const Packet > p)
Sink called when a packet is dropped.
uint32_t m_count
Counter of received packets.
uint32_t m_drops
Counter of dropped packets.
void DoRun() override
Implementation to actually run this TestCase.
void SinkRx(Ptr< const Packet > p, const Address &ad)
Sink called when a packet is received by a node.
a polymophic address class
Definition: address.h:101
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
void Add(ApplicationContainer other)
Append the contents of another ApplicationContainer to the end of this container.
Add capability to bridge multiple LAN segments (IEEE 802.1D bridging)
Definition: bridge-helper.h:45
NetDeviceContainer Install(Ptr< Node > node, NetDeviceContainer c)
This method creates an ns3::BridgeNetDevice with the attributes configured by BridgeHelper::SetDevice...
Csma Channel.
Definition: csma-channel.h:92
build a set of CsmaNetDevice objects
Definition: csma-helper.h:48
A helper to make it easier to create a star topology with Csma links.
void InstallStack(InternetStackHelper stack)
Ipv4Address GetHubIpv4Address(uint32_t i) const
void AssignIpv4Addresses(Ipv4AddressHelper address)
Ptr< Node > GetSpokeNode(uint32_t i) const
Ptr< Node > GetHub() const
NetDeviceContainer GetSpokeDevices() const
uint32_t SpokeCount() const
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
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:42
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
Helper class that adds ns3::Ipv4StaticRouting objects.
void AddMulticastRoute(Ptr< Node > n, Ipv4Address source, Ipv4Address group, Ptr< NetDevice > input, NetDeviceContainer output)
Add a multicast route to a node and net device using explicit Ptr<Node> and Ptr<NetDevice>
void SetDefaultMulticastRoute(Ptr< Node > n, Ptr< NetDevice > nd)
Add a default route to the static routing protocol to forward packets out a particular interface.
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
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.
uint32_t GetN() const
Get the number of Ptr<Node> stored in this container.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void Add(const NodeContainer &nc)
Append the contents of another NodeContainer to the end of this container.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:44
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
Create a ping application and associate it to a node.
Definition: ping-helper.h:48
ApplicationContainer Install(NodeContainer nodes) const
Install a Ping application on each Node in the provided NodeContainer.
Definition: ping-helper.cc:65
Hold variables of type string.
Definition: string.h:56
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:301
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
static void SinkRx(std::string path, Ptr< const Packet > p, const Address &address)
Rx sink.
static CsmaSystemTestSuite csmaSystemTestSuite
Do not forget to allocate an instance of this TestSuite.
uint16_t port
Definition: dsdv-manet.cc:44
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:974
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:950
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Definition: data-rate.h:327
#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
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
NodeContainer nodes
address
Definition: first.py:47
devices
Definition: first.py:42
interfaces
Definition: first.py:50
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:704
csma
Definition: second.py:63
channel
Definition: third.py:88
Ptr< PacketSink > sink
Pointer to the packet sink application.
Definition: wifi-tcp.cc:55