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/pointer.h"
42#include "ns3/simple-channel.h"
43#include "ns3/simulator.h"
44#include "ns3/string.h"
45#include "ns3/test.h"
46#include "ns3/uinteger.h"
47#include "ns3/v4ping-helper.h"
48
49#include <string>
50
51using 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);
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
87void
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//
105void
107{
108 NodeContainer terminals;
109 terminals.Create(4);
110
111 NodeContainer csmaSwitch;
112 csmaSwitch.Create(1);
113
115 csma.SetChannelAttribute("DataRate", DataRateValue(5000000));
116 csma.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
117
118 NetDeviceContainer terminalDevices;
119 NetDeviceContainer switchDevices;
120
121 for (int i = 0; i < 4; i++)
122 {
123 NetDeviceContainer link = csma.Install(NodeContainer(terminals.Get(i), csmaSwitch));
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
129 Ptr<Node> switchNode = csmaSwitch.Get(0);
130 BridgeHelper bridge;
131 bridge.Install(switchNode, switchDevices);
132
133 InternetStackHelper internet;
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",
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
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
218void
220{
221 m_countNode1++;
222}
223
224void
226{
227 m_countNode2++;
228}
229
230void
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//
249void
251{
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
264 InternetStackHelper internet;
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
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
356void
358{
359 m_count++;
360}
361
362void
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//
383void
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
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
406 InternetStackHelper internet;
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);
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
543void
545{
546 m_countNode0++;
547}
548
549void
551{
552 m_countNode1++;
553}
554
555void
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//
571void
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
586 InternetStackHelper internet;
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
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
689void
691{
692 m_count++;
693}
694
695void
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//
712void
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",
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;
790 void SinkRx(Ptr<const Packet> p, const Address& ad);
791
797 void PingRtt(std::string context, Time rtt);
798
804
808};
809
810// Add some help text to this case to describe what it is intended to test
812 : TestCase("Ping example for Carrier Sense Multiple Access (CSMA) networks"),
813 m_countSinkRx(0),
814 m_countPingRtt(0),
815 m_drops(0)
816{
817}
818
820{
821}
822
823void
825{
827}
828
829void
830CsmaPingTestCase::PingRtt(std::string context, Time rtt)
831{
833}
834
835void
837{
838 m_drops++;
839}
840
841// Network topology
842//
843// n0 n1 n2 n3
844// | | | |
845// =====================
846//
847// node n0,n1,n3 pings to node n2
848// node n0 generates protocol 2 (IGMP) to node n3
849//
850void
852{
853 // Here, we will explicitly create four nodes.
855 c.Create(4);
856
857 // connect all our nodes to a shared channel.
859 csma.SetChannelAttribute("DataRate", DataRateValue(DataRate(5000000)));
860 csma.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
861 csma.SetDeviceAttribute("EncapsulationMode", StringValue("Llc"));
862 NetDeviceContainer devs = csma.Install(c);
863
864 // add an ip stack to all nodes.
865 InternetStackHelper ipStack;
866 ipStack.Install(c);
867
868 // assign ip addresses
870 ip.SetBase("192.168.1.0", "255.255.255.0");
871 Ipv4InterfaceContainer addresses = ip.Assign(devs);
872
873 // Create the OnOff application to send UDP datagrams from n0 to n1.
874 //
875 // Make packets be sent about every DefaultPacketSize / DataRate =
876 // 4096 bits / (5000 bits/second) = 0.82 second.
877 Config::SetDefault("ns3::Ipv4RawSocketImpl::Protocol", StringValue("2"));
879 OnOffHelper onoff = OnOffHelper("ns3::Ipv4RawSocketFactory", dst);
880 onoff.SetConstantRate(DataRate(5000));
881
882 ApplicationContainer apps = onoff.Install(c.Get(0));
883 apps.Start(Seconds(1.0));
884 apps.Stop(Seconds(10.0));
885
886 PacketSinkHelper sink = PacketSinkHelper("ns3::Ipv4RawSocketFactory", dst);
887 apps = sink.Install(c.Get(3));
888 apps.Start(Seconds(0.0));
889 apps.Stop(Seconds(11.0));
890
891 V4PingHelper ping = V4PingHelper(addresses.GetAddress(2));
892 NodeContainer pingers;
893 pingers.Add(c.Get(0));
894 pingers.Add(c.Get(1));
895 pingers.Add(c.Get(3));
896 apps = ping.Install(pingers);
897 apps.Start(Seconds(2.0));
898 apps.Stop(Seconds(5.0));
899
900 // Trace receptions
901 Config::ConnectWithoutContext("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx",
903
904 // Trace pings
905 Config::Connect("/NodeList/*/ApplicationList/*/$ns3::V4Ping/Rtt",
907
908 Simulator::Run();
909 Simulator::Destroy();
910
911 // We should have sent and received 10 packets
912 NS_TEST_ASSERT_MSG_EQ(m_countSinkRx, 10, "Node 3 should have received 10 packets");
913
914 // We should have 3 pingers that ping every second for 3 seconds.
915 NS_TEST_ASSERT_MSG_EQ(m_countPingRtt, 9, "Node 2 should have been pinged 9 times");
916}
917
924{
925 public:
927 ~CsmaRawIpSocketTestCase() override;
928
929 private:
930 void DoRun() override;
931
937 void SinkRx(Ptr<const Packet> p, const Address& ad);
938
944
947};
948
949// Add some help text to this case to describe what it is intended to test
951 : TestCase(
952 "Raw internet protocol socket example for Carrier Sense Multiple Access (CSMA) networks"),
953 m_count(0),
954 m_drops(0)
955{
956}
957
959{
960}
961
962void
964{
965 m_count++;
966}
967
968void
970{
971 m_drops++;
972}
973
974//
975// Network topology
976// (sender) (receiver)
977// n0 n1 n2 n3
978// | | | |
979// =====================
980//
981// Node n0 sends data to node n3 over a raw IP socket. The protocol
982// number used is 2.
983//
984void
986{
987 // Here, we will explicitly create four nodes.
989 c.Create(4);
990
991 // connect all our nodes to a shared channel.
993 csma.SetChannelAttribute("DataRate", DataRateValue(DataRate(5000000)));
994 csma.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
995 csma.SetDeviceAttribute("EncapsulationMode", StringValue("Llc"));
996 NetDeviceContainer devs = csma.Install(c);
997
998 // add an ip stack to all nodes.
999 InternetStackHelper ipStack;
1000 ipStack.Install(c);
1001
1002 // assign ip addresses
1004 ip.SetBase("192.168.1.0", "255.255.255.0");
1005 Ipv4InterfaceContainer addresses = ip.Assign(devs);
1006
1007 // IP protocol configuration
1008 //
1009 // Make packets be sent about every DefaultPacketSize / DataRate =
1010 // 4096 bits / (5000 bits/second) = 0.82 second.
1011 Config::SetDefault("ns3::Ipv4RawSocketImpl::Protocol", StringValue("2"));
1013 OnOffHelper onoff = OnOffHelper("ns3::Ipv4RawSocketFactory", dst);
1014 onoff.SetConstantRate(DataRate(5000));
1015
1016 ApplicationContainer apps = onoff.Install(c.Get(0));
1017 apps.Start(Seconds(1.0));
1018 apps.Stop(Seconds(10.0));
1019
1020 PacketSinkHelper sink = PacketSinkHelper("ns3::Ipv4RawSocketFactory", dst);
1021 apps = sink.Install(c.Get(3));
1022 apps.Start(Seconds(0.0));
1023 apps.Stop(Seconds(12.0));
1024
1025 // Trace receptions
1026 Config::ConnectWithoutContext("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx",
1028
1029 Simulator::Run();
1030 Simulator::Destroy();
1031
1032 // We should have sent and received 10 packets
1033 NS_TEST_ASSERT_MSG_EQ(m_count, 10, "Node 3 should have received 10 packets");
1034}
1035
1042{
1043 public:
1045 ~CsmaStarTestCase() override;
1046
1047 private:
1048 void DoRun() override;
1049
1055 void SinkRx(Ptr<const Packet> p, const Address& ad);
1056
1062
1065};
1066
1067// Add some help text to this case to describe what it is intended to test
1069 : TestCase("Star example for Carrier Sense Multiple Access (CSMA) networks"),
1070 m_count(0),
1071 m_drops(0)
1072{
1073}
1074
1076{
1077}
1078
1079void
1081{
1082 m_count++;
1083}
1084
1085void
1087{
1088 m_drops++;
1089}
1090
1091// Network topology (default)
1092//
1093// n2 + + n3 .
1094// | ... |\ /| ... | .
1095// ======= \ / ======= .
1096// CSMA \ / CSMA .
1097// \ / .
1098// n1 +--- n0 ---+ n4 .
1099// | ... | / \ | ... | .
1100// ======= / \ ======= .
1101// CSMA / \ CSMA .
1102// / \ .
1103// n6 + + n5 .
1104// | ... | | ... | .
1105// ======= ======= .
1106// CSMA CSMA .
1107//
1108void
1110{
1111 //
1112 // Default number of nodes in the star.
1113 //
1114 uint32_t nSpokes = 7;
1115
1117 csma.SetChannelAttribute("DataRate", StringValue("100Mbps"));
1118 csma.SetChannelAttribute("Delay", StringValue("1ms"));
1119 CsmaStarHelper star(nSpokes, csma);
1120
1121 NodeContainer fillNodes;
1122
1123 //
1124 // Just to be nasy, hang some more nodes off of the CSMA channel for each
1125 // spoke, so that there are a total of 16 nodes on each channel. Stash
1126 // all of these new devices into a container.
1127 //
1128 NetDeviceContainer fillDevices;
1129
1130 uint32_t nFill = 14;
1131 for (uint32_t i = 0; i < star.GetSpokeDevices().GetN(); ++i)
1132 {
1133 Ptr<Channel> channel = star.GetSpokeDevices().Get(i)->GetChannel();
1134 Ptr<CsmaChannel> csmaChannel = channel->GetObject<CsmaChannel>();
1135 NodeContainer newNodes;
1136 newNodes.Create(nFill);
1137 fillNodes.Add(newNodes);
1138 fillDevices.Add(csma.Install(newNodes, csmaChannel));
1139 }
1140
1141 InternetStackHelper internet;
1142 star.InstallStack(internet);
1143 internet.Install(fillNodes);
1144
1145 star.AssignIpv4Addresses(Ipv4AddressHelper("10.1.0.0", "255.255.255.0"));
1146
1147 //
1148 // We assigned addresses to the logical hub and the first "drop" of the
1149 // CSMA network that acts as the spoke, but we also have a number of fill
1150 // devices (nFill) also hanging off the CSMA network. We have got to
1151 // assign addresses to them as well. We put all of the fill devices into
1152 // a single device container, so the first nFill devices are associated
1153 // with the channel connected to spokeDevices.Get (0), the second nFill
1154 // devices afe associated with the channel connected to spokeDevices.Get (1)
1155 // etc.
1156 //
1158 for (uint32_t i = 0; i < star.SpokeCount(); ++i)
1159 {
1160 std::ostringstream subnet;
1161 subnet << "10.1." << i << ".0";
1162 address.SetBase(subnet.str().c_str(), "255.255.255.0", "0.0.0.3");
1163
1164 for (uint32_t j = 0; j < nFill; ++j)
1165 {
1166 address.Assign(fillDevices.Get(i * nFill + j));
1167 }
1168 }
1169
1170 //
1171 // Create a packet sink on the star "hub" to receive packets.
1172 //
1173 uint16_t port = 50000;
1174 Address hubLocalAddress(InetSocketAddress(Ipv4Address::GetAny(), port));
1175 PacketSinkHelper packetSinkHelper("ns3::TcpSocketFactory", hubLocalAddress);
1176 ApplicationContainer hubApp = packetSinkHelper.Install(star.GetHub());
1177 hubApp.Start(Seconds(1.0));
1178 hubApp.Stop(Seconds(10.0));
1179
1180 //
1181 // Create OnOff applications to send TCP to the hub, one on each spoke node.
1182 //
1183 // Make packets be sent about every DefaultPacketSize / DataRate =
1184 // 4096 bits / (5000 bits/second) = 0.82 second.
1185 OnOffHelper onOffHelper("ns3::TcpSocketFactory", Address());
1186 onOffHelper.SetConstantRate(DataRate(5000));
1187
1188 ApplicationContainer spokeApps;
1189
1190 for (uint32_t i = 0; i < star.SpokeCount(); ++i)
1191 {
1192 AddressValue remoteAddress(InetSocketAddress(star.GetHubIpv4Address(i), port));
1193 onOffHelper.SetAttribute("Remote", remoteAddress);
1194 spokeApps.Add(onOffHelper.Install(star.GetSpokeNode(i)));
1195 }
1196
1197 spokeApps.Start(Seconds(1.0));
1198 spokeApps.Stop(Seconds(10.0));
1199
1200 //
1201 // Because we are evil, we also add OnOff applications to send TCP to the hub
1202 // from the fill devices on each CSMA link. The first nFill nodes in the
1203 // fillNodes container are on the CSMA network talking to the zeroth device
1204 // on the hub node. The next nFill nodes are on the CSMA network talking to
1205 // the first device on the hub node, etc. So the ith fillNode is associated
1206 // with the hub address found on the (i / nFill)th device on the hub node.
1207 //
1208 ApplicationContainer fillApps;
1209
1210 for (uint32_t i = 0; i < fillNodes.GetN(); ++i)
1211 {
1212 AddressValue remoteAddress(InetSocketAddress(star.GetHubIpv4Address(i / nFill), port));
1213 onOffHelper.SetAttribute("Remote", remoteAddress);
1214 fillApps.Add(onOffHelper.Install(fillNodes.Get(i)));
1215 }
1216
1217 fillApps.Start(Seconds(1.0));
1218 fillApps.Stop(Seconds(10.0));
1219
1220 //
1221 // Turn on global static routing so we can actually be routed across the star.
1222 //
1223 Ipv4GlobalRoutingHelper::PopulateRoutingTables();
1224
1225 // Trace receptions
1226 Config::ConnectWithoutContext("/NodeList/0/ApplicationList/*/$ns3::PacketSink/Rx",
1228
1229 Simulator::Run();
1230 Simulator::Destroy();
1231
1232 // The hub node should have received 10 packets from the nFill + 1
1233 // nodes on each spoke.
1235 10 * (nSpokes * (nFill + 1)),
1236 "Hub node did not receive the proper number of packets");
1237}
1238
1245{
1246 public:
1248};
1249
1251 : TestSuite("csma-system", UNIT)
1252{
1253 AddTestCase(new CsmaBridgeTestCase, TestCase::QUICK);
1254 AddTestCase(new CsmaBroadcastTestCase, TestCase::QUICK);
1255 AddTestCase(new CsmaMulticastTestCase, TestCase::QUICK);
1256 AddTestCase(new CsmaOneSubnetTestCase, TestCase::QUICK);
1257 AddTestCase(new CsmaPacketSocketTestCase, TestCase::QUICK);
1258 AddTestCase(new CsmaPingTestCase, TestCase::QUICK);
1259 AddTestCase(new CsmaRawIpSocketTestCase, TestCase::QUICK);
1260 AddTestCase(new CsmaStarTestCase, TestCase::QUICK);
1261}
1262
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 PingRtt(std::string context, Time rtt)
Sink called when a PING ois received.
void DoRun() override
Implementation to actually run this TestCase.
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 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:92
AttributeValue implementation for Address.
holds a vector of ns3::Application pointers.
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter.
void Add(ApplicationContainer other)
Append the contents of another ApplicationContainer to the end of this container.
void Stop(Time stop)
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
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
AttributeValue implementation for DataRate.
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: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 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
void SetConstantRate(DataRate dataRate, uint32_t packetSize=512)
Helper function to set a constant rate source.
ApplicationContainer Install(NodeContainer c) const
Install an ns3::OnOffApplication on each node of the input container configured with all the attribut...
void SetAttribute(std::string name, const AttributeValue &value)
Helper function used to set the underlying application attributes.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
ApplicationContainer Install(NodeContainer c) const
Install an ns3::PacketSinkApplication on each node of the input container configured with all the att...
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.
Hold variables of type string.
Definition: string.h:42
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
AttributeValue implementation for Time.
Definition: nstime.h:1425
Create a IPv4 ping application and associate it to a node.
Definition: v4ping-helper.h:38
ApplicationContainer Install(NodeContainer nodes) const
Install a Ping application on each Node in the provided NodeContainer.
static CsmaSystemTestSuite csmaSystemTestSuite
Do not forget to allocate an instance of this TestSuite.
uint16_t port
Definition: dsdv-manet.cc:45
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:891
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:975
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:951
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Definition: data-rate.h:328
#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:1338
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
NodeContainer nodes
address
Definition: first.py:40
devices
Definition: first.py:35
interfaces
Definition: first.py:44
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:691
csma
Definition: second.py:56
channel
Definition: third.py:81
Ptr< PacketSink > sink
Pointer to the packet sink application.
Definition: wifi-tcp.cc:55