src/test/csma-system-test-suite.cc
changeset 6624 a071889af159
child 6775 0783f42a364b
equal deleted inserted replaced
6623:616d42c69f05 6624:a071889af159
       
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
       
     2 /*
       
     3  * This program is free software; you can redistribute it and/or modify
       
     4  * it under the terms of the GNU General Public License version 2 as
       
     5  * published by the Free Software Foundation;
       
     6  *
       
     7  * This program is distributed in the hope that it will be useful,
       
     8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
     9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    10  * GNU General Public License for more details.
       
    11  *
       
    12  * You should have received a copy of the GNU General Public License
       
    13  * along with this program; if not, write to the Free Software
       
    14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    15  */
       
    16 
       
    17 // This is not a test of CsmaNetDevice model behavior per-se, but
       
    18 // instead is a roll up of several end-to-end examples in examples/csma
       
    19 // directory, converted into system tests.  Writing a test suite
       
    20 // to test Csma itself is for further study.
       
    21 
       
    22 #include <string>
       
    23 
       
    24 #include "ns3/address.h"
       
    25 #include "ns3/application-container.h"
       
    26 #include "ns3/bridge-helper.h"
       
    27 #include "ns3/callback.h"
       
    28 #include "ns3/config.h"
       
    29 #include "ns3/csma-helper.h"
       
    30 #include "ns3/csma-star-helper.h"
       
    31 #include "ns3/inet-socket-address.h"
       
    32 #include "ns3/internet-stack-helper.h"
       
    33 #include "ns3/ipv4-address-helper.h"
       
    34 #include "ns3/ipv4-global-routing-helper.h"
       
    35 #include "ns3/ipv4-static-routing-helper.h"
       
    36 #include "ns3/node.h"
       
    37 #include "ns3/node-container.h"
       
    38 #include "ns3/on-off-helper.h"
       
    39 #include "ns3/packet.h"
       
    40 #include "ns3/packet-sink-helper.h"
       
    41 #include "ns3/packet-socket-helper.h"
       
    42 #include "ns3/packet-socket-address.h"
       
    43 #include "ns3/pointer.h"
       
    44 #include "ns3/random-variable.h"
       
    45 #include "ns3/simple-channel.h"
       
    46 #include "ns3/simulator.h"
       
    47 #include "ns3/string.h"
       
    48 #include "ns3/test.h"
       
    49 #include "ns3/uinteger.h"
       
    50 #include "ns3/v4ping-helper.h"
       
    51 
       
    52 using namespace ns3;
       
    53 
       
    54 class CsmaBridgeTestCase : public TestCase
       
    55 {
       
    56 public:
       
    57   CsmaBridgeTestCase ();
       
    58   virtual ~CsmaBridgeTestCase ();
       
    59 
       
    60 private:
       
    61   virtual bool DoRun (void);
       
    62   void SinkRx (Ptr<const Packet> p, const Address &ad);
       
    63   uint32_t m_count;
       
    64 };
       
    65 
       
    66 // Add some help text to this case to describe what it is intended to test
       
    67 CsmaBridgeTestCase::CsmaBridgeTestCase ()
       
    68   : TestCase ("Bridge example for Carrier Sense Multiple Access (CSMA) networks"), m_count (0)
       
    69 {
       
    70 }
       
    71 
       
    72 CsmaBridgeTestCase::~CsmaBridgeTestCase ()
       
    73 {
       
    74 }
       
    75 
       
    76 void 
       
    77 CsmaBridgeTestCase::SinkRx (Ptr<const Packet> p, const Address &ad)
       
    78 {
       
    79   m_count++;
       
    80 }
       
    81 
       
    82 // Network topology
       
    83 //
       
    84 //        n0     n1  
       
    85 //        |      | 
       
    86 //       ----------
       
    87 //       | Switch |
       
    88 //       ----------
       
    89 //        |      | 
       
    90 //        n2     n3  
       
    91 //
       
    92 // - CBR/UDP test flow from n0 to n1; test that packets received on n1 
       
    93 //
       
    94 bool
       
    95 CsmaBridgeTestCase::DoRun (void)
       
    96 {
       
    97   NodeContainer terminals;
       
    98   terminals.Create (4);
       
    99 
       
   100   NodeContainer csmaSwitch;
       
   101   csmaSwitch.Create (1);
       
   102 
       
   103   CsmaHelper csma;
       
   104   csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
       
   105   csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
       
   106 
       
   107   NetDeviceContainer terminalDevices;
       
   108   NetDeviceContainer switchDevices;
       
   109 
       
   110   for (int i = 0; i < 4; i++)
       
   111     {
       
   112       NetDeviceContainer link = csma.Install (NodeContainer (terminals.Get (i), csmaSwitch));
       
   113       terminalDevices.Add (link.Get (0));
       
   114       switchDevices.Add (link.Get (1));
       
   115     }
       
   116 
       
   117   // Create the bridge netdevice, which will do the packet switching
       
   118   Ptr<Node> switchNode = csmaSwitch.Get (0);
       
   119   BridgeHelper bridge;
       
   120   bridge.Install (switchNode, switchDevices);
       
   121 
       
   122   InternetStackHelper internet;
       
   123   internet.Install (terminals);
       
   124 
       
   125   Ipv4AddressHelper ipv4;
       
   126   ipv4.SetBase ("10.1.1.0", "255.255.255.0");
       
   127   ipv4.Assign (terminalDevices);
       
   128 
       
   129   uint16_t port = 9;   // Discard port (RFC 863)
       
   130 
       
   131   // Create the OnOff application to send UDP datagrams from n0 to n1.
       
   132   //
       
   133   // Make packets be sent about every DefaultPacketSize / DataRate = 
       
   134   // 4096 bits / (5000 bits/second) = 0.82 second.
       
   135   OnOffHelper onoff ("ns3::UdpSocketFactory", 
       
   136                      Address (InetSocketAddress (Ipv4Address ("10.1.1.2"), port)));
       
   137   onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
       
   138   onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
       
   139   onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000)));
       
   140 
       
   141   ApplicationContainer app = onoff.Install (terminals.Get (0));
       
   142   app.Start (Seconds (1.0));
       
   143   app.Stop (Seconds (10.0));
       
   144 
       
   145   PacketSinkHelper sink ("ns3::UdpSocketFactory",
       
   146                          Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
       
   147   app = sink.Install (terminals.Get (1));
       
   148   app.Start (Seconds (0.0));
       
   149 
       
   150   // Trace receptions
       
   151   Config::ConnectWithoutContext ("/NodeList/1/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&CsmaBridgeTestCase::SinkRx, this));
       
   152 
       
   153   Simulator::Run ();
       
   154   Simulator::Destroy ();
       
   155 
       
   156   // We should have sent and received 10 packets
       
   157   NS_TEST_ASSERT_MSG_EQ (m_count, 10, "Bridge should have passed 10 packets");
       
   158 
       
   159   return GetErrorStatus ();
       
   160 }
       
   161 
       
   162 class CsmaBroadcastTestCase : public TestCase
       
   163 {
       
   164 public:
       
   165   CsmaBroadcastTestCase ();
       
   166   virtual ~CsmaBroadcastTestCase ();
       
   167 
       
   168 private:
       
   169   virtual bool DoRun (void);
       
   170   void SinkRxNode1 (Ptr<const Packet> p, const Address &ad);
       
   171   void SinkRxNode2 (Ptr<const Packet> p, const Address &ad);
       
   172   void DropEvent (Ptr<const Packet> p);
       
   173   uint32_t m_countNode1;
       
   174   uint32_t m_countNode2;
       
   175   uint32_t m_drops;
       
   176 };
       
   177 
       
   178 // Add some help text to this case to describe what it is intended to test
       
   179 CsmaBroadcastTestCase::CsmaBroadcastTestCase ()
       
   180   : TestCase ("Broadcast example for Carrier Sense Multiple Access (CSMA) networks"), m_countNode1 (0), m_countNode2 (0), m_drops (0)
       
   181 {
       
   182 }
       
   183 
       
   184 CsmaBroadcastTestCase::~CsmaBroadcastTestCase ()
       
   185 {
       
   186 }
       
   187 
       
   188 void 
       
   189 CsmaBroadcastTestCase::SinkRxNode1 (Ptr<const Packet> p, const Address &ad)
       
   190 {
       
   191   m_countNode1++;
       
   192 }
       
   193 
       
   194 void 
       
   195 CsmaBroadcastTestCase::SinkRxNode2 (Ptr<const Packet> p, const Address &ad)
       
   196 {
       
   197   m_countNode2++;
       
   198 }
       
   199 
       
   200 void 
       
   201 CsmaBroadcastTestCase::DropEvent (Ptr<const Packet> p)
       
   202 {
       
   203   m_drops++;
       
   204 }
       
   205 
       
   206 //
       
   207 // Example of the sending of a datagram to a broadcast address
       
   208 //
       
   209 // Network topology
       
   210 //     ==============
       
   211 //       |          |
       
   212 //       n0    n1   n2   
       
   213 //       |     |       
       
   214 //     ==========
       
   215 //
       
   216 //   n0 originates UDP broadcast to 255.255.255.255/discard port, which 
       
   217 //   is replicated and received on both n1 and n2
       
   218 //
       
   219 bool
       
   220 CsmaBroadcastTestCase::DoRun (void)
       
   221 {
       
   222   NodeContainer c;
       
   223   c.Create (3);
       
   224   NodeContainer c0 = NodeContainer (c.Get (0), c.Get (1));
       
   225   NodeContainer c1 = NodeContainer (c.Get (0), c.Get (2));
       
   226 
       
   227   CsmaHelper csma;
       
   228   csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate(5000000)));
       
   229   csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds(2)));
       
   230 
       
   231   NetDeviceContainer n0 = csma.Install (c0);
       
   232   NetDeviceContainer n1 = csma.Install (c1);
       
   233 
       
   234   InternetStackHelper internet;
       
   235   internet.Install (c);
       
   236 
       
   237   Ipv4AddressHelper ipv4;
       
   238   ipv4.SetBase ("10.1.0.0", "255.255.255.0");
       
   239   ipv4.Assign (n0);
       
   240   ipv4.SetBase ("192.168.1.0", "255.255.255.0");
       
   241   ipv4.Assign (n1);
       
   242 
       
   243 
       
   244   // RFC 863 discard port ("9") indicates packet should be thrown away
       
   245   // by the system.  We allow this silent discard to be overridden
       
   246   // by the PacketSink application.
       
   247   uint16_t port = 9;
       
   248 
       
   249   // Create the OnOff application to send UDP datagrams from n0.
       
   250   //
       
   251   // Make packets be sent about every DefaultPacketSize / DataRate = 
       
   252   // 4096 bits / (5000 bits/second) = 0.82 second.
       
   253   OnOffHelper onoff ("ns3::UdpSocketFactory", 
       
   254     Address (InetSocketAddress (Ipv4Address ("255.255.255.255"), port)));
       
   255   onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
       
   256   onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
       
   257   onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000)));
       
   258 
       
   259   ApplicationContainer app = onoff.Install (c0.Get (0));
       
   260   // Start the application
       
   261   app.Start (Seconds (1.0));
       
   262   app.Stop (Seconds (10.0));
       
   263 
       
   264   // Create an optional packet sink to receive these packets
       
   265   PacketSinkHelper sink ("ns3::UdpSocketFactory",
       
   266     Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
       
   267   app = sink.Install (c0.Get (1));
       
   268   app.Add (sink.Install (c1.Get (1)));
       
   269   app.Start (Seconds (1.0));
       
   270   app.Stop (Seconds (10.0));
       
   271 
       
   272   // Trace receptions
       
   273   Config::ConnectWithoutContext ("/NodeList/1/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&CsmaBroadcastTestCase::SinkRxNode1, this));
       
   274   Config::ConnectWithoutContext ("/NodeList/2/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&CsmaBroadcastTestCase::SinkRxNode2, this));
       
   275 
       
   276   Simulator::Run ();    
       
   277   Simulator::Destroy ();
       
   278 
       
   279   // We should have sent and received 10 packets
       
   280   NS_TEST_ASSERT_MSG_EQ (m_countNode1, 10, "Node 1 should have received 10 packets");
       
   281   NS_TEST_ASSERT_MSG_EQ (m_countNode2, 10, "Node 2 should have received 10 packets");
       
   282 
       
   283   return GetErrorStatus ();
       
   284 }
       
   285 
       
   286 class CsmaMulticastTestCase : public TestCase
       
   287 {
       
   288 public:
       
   289   CsmaMulticastTestCase ();
       
   290   virtual ~CsmaMulticastTestCase ();
       
   291 
       
   292 private:
       
   293   virtual bool DoRun (void);
       
   294   void SinkRx (Ptr<const Packet> p, const Address &ad);
       
   295   void DropEvent (Ptr<const Packet> p);
       
   296   uint32_t m_count;
       
   297   uint32_t m_drops;
       
   298 };
       
   299 
       
   300 // Add some help text to this case to describe what it is intended to test
       
   301 CsmaMulticastTestCase::CsmaMulticastTestCase ()
       
   302   : TestCase ("Multicast example for Carrier Sense Multiple Access (CSMA) networks"), m_count (0), m_drops (0)
       
   303 {
       
   304 }
       
   305 
       
   306 CsmaMulticastTestCase::~CsmaMulticastTestCase ()
       
   307 {
       
   308 }
       
   309 
       
   310 void 
       
   311 CsmaMulticastTestCase::SinkRx (Ptr<const Packet> p, const Address& ad)
       
   312 {
       
   313   m_count++;
       
   314 }
       
   315 
       
   316 void 
       
   317 CsmaMulticastTestCase::DropEvent (Ptr<const Packet> p)
       
   318 {
       
   319   m_drops++;
       
   320 }
       
   321 
       
   322 // Network topology
       
   323 //
       
   324 //                     Lan1
       
   325 //                 ===========
       
   326 //                 |    |    | 
       
   327 //       n0   n1   n2   n3   n4
       
   328 //       |    |    |
       
   329 //       ===========
       
   330 //           Lan0
       
   331 //
       
   332 // - Multicast source is at node n0;
       
   333 // - Multicast forwarded by node n2 onto LAN1;
       
   334 // - Nodes n0, n1, n2, n3, and n4 receive the multicast frame.
       
   335 // - Node n4 listens for the data 
       
   336 //
       
   337 bool
       
   338 CsmaMulticastTestCase::DoRun (void)
       
   339 {
       
   340   //
       
   341   // Set up default values for the simulation.  
       
   342   //
       
   343   // Select DIX/Ethernet II-style encapsulation (no LLC/Snap header)
       
   344   Config::SetDefault ("ns3::CsmaNetDevice::EncapsulationMode", StringValue ("Dix"));  
       
   345 
       
   346   NodeContainer c;
       
   347   c.Create (5);
       
   348   // We will later want two subcontainers of these nodes, for the two LANs
       
   349   NodeContainer c0 = NodeContainer (c.Get (0), c.Get (1), c.Get (2));
       
   350   NodeContainer c1 = NodeContainer (c.Get (2), c.Get (3), c.Get (4));
       
   351   
       
   352   CsmaHelper csma;
       
   353   csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
       
   354   csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
       
   355  
       
   356   // We will use these NetDevice containers later, for IP addressing
       
   357   NetDeviceContainer nd0 = csma.Install (c0);  // First LAN
       
   358   NetDeviceContainer nd1 = csma.Install (c1);  // Second LAN
       
   359 
       
   360   InternetStackHelper internet;
       
   361   internet.Install (c);
       
   362 
       
   363   Ipv4AddressHelper ipv4Addr;
       
   364   ipv4Addr.SetBase ("10.1.1.0", "255.255.255.0");
       
   365   ipv4Addr.Assign (nd0);
       
   366   ipv4Addr.SetBase ("10.1.2.0", "255.255.255.0");
       
   367   ipv4Addr.Assign (nd1);
       
   368 
       
   369   //
       
   370   // Now we can configure multicasting.  As described above, the multicast 
       
   371   // source is at node zero, which we assigned the IP address of 10.1.1.1 
       
   372   // earlier.  We need to define a multicast group to send packets to.  This
       
   373   // can be any multicast address from 224.0.0.0 through 239.255.255.255
       
   374   // (avoiding the reserved routing protocol addresses).  
       
   375   //
       
   376 
       
   377   Ipv4Address multicastSource ("10.1.1.1");
       
   378   Ipv4Address multicastGroup ("225.1.2.4");
       
   379 
       
   380   // Now, we will set up multicast routing.  We need to do three things:
       
   381   // 1) Configure a (static) multicast route on node n2
       
   382   // 2) Set up a default multicast route on the sender n0 
       
   383   // 3) Have node n4 join the multicast group
       
   384   // We have a helper that can help us with static multicast
       
   385   Ipv4StaticRoutingHelper multicast;
       
   386 
       
   387   // 1) Configure a (static) multicast route on node n2 (multicastRouter)
       
   388   Ptr<Node> multicastRouter = c.Get (2);  // The node in question
       
   389   Ptr<NetDevice> inputIf = nd0.Get (2);  // The input NetDevice
       
   390   NetDeviceContainer outputDevices;  // A container of output NetDevices
       
   391   outputDevices.Add (nd1.Get (0));  // (we only need one NetDevice here)
       
   392 
       
   393   multicast.AddMulticastRoute (multicastRouter, multicastSource, 
       
   394     multicastGroup, inputIf, outputDevices);
       
   395   
       
   396   // 2) Set up a default multicast route on the sender n0 
       
   397   Ptr<Node> sender = c.Get (0);
       
   398   Ptr<NetDevice> senderIf = nd0.Get(0);
       
   399   multicast.SetDefaultMulticastRoute (sender, senderIf);
       
   400 
       
   401   //
       
   402   // Create an OnOff application to send UDP datagrams from node zero to the
       
   403   // multicast group (node four will be listening).
       
   404   //
       
   405 
       
   406   uint16_t multicastPort = 9;   // Discard port (RFC 863)
       
   407 
       
   408   // Configure a multicast packet generator.
       
   409   //
       
   410   // Make packets be sent about every defaultPacketSize / dataRate = 
       
   411   // 4096 bits / (5000 bits/second) = 0.82 second.
       
   412   OnOffHelper onoff ("ns3::UdpSocketFactory", 
       
   413     Address (InetSocketAddress (multicastGroup, multicastPort)));
       
   414   onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
       
   415   onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
       
   416   onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000)));
       
   417 
       
   418   ApplicationContainer srcC = onoff.Install (c0.Get (0));
       
   419 
       
   420   //
       
   421   // Tell the application when to start and stop.
       
   422   //
       
   423   srcC.Start(Seconds(1.));
       
   424   srcC.Stop (Seconds(10.));
       
   425 
       
   426   // Create an optional packet sink to receive these packets
       
   427   PacketSinkHelper sink ("ns3::UdpSocketFactory",
       
   428                          InetSocketAddress (Ipv4Address::GetAny(), multicastPort));
       
   429 
       
   430   ApplicationContainer sinkC = sink.Install (c1.Get (2)); // Node n4 
       
   431   // Start the sink
       
   432   sinkC.Start (Seconds (1.0));
       
   433   sinkC.Stop (Seconds (10.0));
       
   434 
       
   435   // Trace receptions
       
   436   Config::ConnectWithoutContext ("/NodeList/4/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&CsmaMulticastTestCase::SinkRx, this));
       
   437 
       
   438   //
       
   439   // Now, do the actual simulation.
       
   440   //
       
   441   Simulator::Run ();
       
   442   Simulator::Destroy ();
       
   443 
       
   444   // We should have sent and received 10 packets
       
   445   NS_TEST_ASSERT_MSG_EQ (m_count, 10, "Node 4 should have received 10 packets");
       
   446 
       
   447   return GetErrorStatus ();
       
   448 }
       
   449 
       
   450 class CsmaOneSubnetTestCase : public TestCase
       
   451 {
       
   452 public:
       
   453   CsmaOneSubnetTestCase ();
       
   454   virtual ~CsmaOneSubnetTestCase ();
       
   455 
       
   456 private:
       
   457   virtual bool DoRun (void);
       
   458   void SinkRxNode0 (Ptr<const Packet> p, const Address &ad);
       
   459   void SinkRxNode1 (Ptr<const Packet> p, const Address &ad);
       
   460   void DropEvent (Ptr<const Packet> p);
       
   461   uint32_t m_countNode0;
       
   462   uint32_t m_countNode1;
       
   463   uint32_t m_drops;
       
   464 };
       
   465 
       
   466 // Add some help text to this case to describe what it is intended to test
       
   467 CsmaOneSubnetTestCase::CsmaOneSubnetTestCase ()
       
   468   : TestCase ("One subnet example for Carrier Sense Multiple Access (CSMA) networks"), m_countNode0 (0), m_countNode1 (0), m_drops (0)
       
   469 {
       
   470 }
       
   471 
       
   472 CsmaOneSubnetTestCase::~CsmaOneSubnetTestCase ()
       
   473 {
       
   474 }
       
   475 
       
   476 void 
       
   477 CsmaOneSubnetTestCase::SinkRxNode0 (Ptr<const Packet> p, const Address &ad)
       
   478 {
       
   479   m_countNode0++;
       
   480 }
       
   481 
       
   482 void 
       
   483 CsmaOneSubnetTestCase::SinkRxNode1 (Ptr<const Packet> p, const Address &ad)
       
   484 {
       
   485   m_countNode1++;
       
   486 }
       
   487 
       
   488 void 
       
   489 CsmaOneSubnetTestCase::DropEvent (Ptr<const Packet> p)
       
   490 {
       
   491   m_drops++;
       
   492 }
       
   493 
       
   494 // Network topology
       
   495 //
       
   496 //       n0    n1   n2   n3
       
   497 //       |     |    |    |
       
   498 //       =================
       
   499 //              LAN
       
   500 //
       
   501 // - CBR/UDP flows from n0 to n1 and from n3 to n0
       
   502 // - DropTail queues 
       
   503 //
       
   504 bool
       
   505 CsmaOneSubnetTestCase::DoRun (void)
       
   506 {
       
   507   NodeContainer nodes;
       
   508   nodes.Create (4);
       
   509 
       
   510   CsmaHelper csma;
       
   511   csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
       
   512   csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
       
   513   //
       
   514   // Now fill out the topology by creating the net devices required to connect
       
   515   // the nodes to the channels and hooking them up.
       
   516   //
       
   517   NetDeviceContainer devices = csma.Install (nodes);
       
   518 
       
   519   InternetStackHelper internet;
       
   520   internet.Install (nodes);
       
   521 
       
   522   // We've got the "hardware" in place.  Now we need to add IP addresses.
       
   523   //
       
   524   Ipv4AddressHelper ipv4;
       
   525   ipv4.SetBase ("10.1.1.0", "255.255.255.0");
       
   526   Ipv4InterfaceContainer interfaces = ipv4.Assign (devices);
       
   527 
       
   528   uint16_t port = 9;   // Discard port (RFC 863)
       
   529 
       
   530   //
       
   531   // Create an OnOff application to send UDP datagrams from node zero
       
   532   // to node 1.
       
   533   //
       
   534   // Make packets be sent about every defaultPacketSize / dataRate = 
       
   535   // 4096 bits / (5000 bits/second) = 0.82 second.
       
   536   OnOffHelper onoff ("ns3::UdpSocketFactory", 
       
   537                      Address (InetSocketAddress (interfaces.GetAddress (1), port)));
       
   538   onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
       
   539   onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
       
   540   onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000)));
       
   541 
       
   542   ApplicationContainer app = onoff.Install (nodes.Get (0));
       
   543   // Start the application
       
   544   app.Start (Seconds (1.0));
       
   545   app.Stop (Seconds (10.0));
       
   546 
       
   547   // Create an optional packet sink to receive these packets
       
   548   PacketSinkHelper sink ("ns3::UdpSocketFactory",
       
   549     Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
       
   550   app = sink.Install (nodes.Get (1));
       
   551   app.Start (Seconds (0.0));
       
   552 
       
   553   // 
       
   554   // Create a similar flow from n3 to n0, starting at time 1.1 seconds
       
   555   //
       
   556   onoff.SetAttribute ("Remote", 
       
   557                       AddressValue (InetSocketAddress (interfaces.GetAddress (0), port)));
       
   558   app = onoff.Install (nodes.Get (3));
       
   559   app.Start(Seconds (1.1));
       
   560   app.Stop (Seconds (10.0));
       
   561 
       
   562   app = sink.Install (nodes.Get (0));
       
   563   app.Start (Seconds (0.0));
       
   564 
       
   565   // Trace receptions
       
   566   Config::ConnectWithoutContext ("/NodeList/0/ApplicationList/1/$ns3::PacketSink/Rx", MakeCallback (&CsmaOneSubnetTestCase::SinkRxNode0, this));
       
   567   Config::ConnectWithoutContext ("/NodeList/1/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&CsmaOneSubnetTestCase::SinkRxNode1, this));
       
   568 
       
   569   //
       
   570   // Now, do the actual simulation.
       
   571   //
       
   572   Simulator::Run ();
       
   573   Simulator::Destroy ();
       
   574 
       
   575   // We should have sent and received 10 packets
       
   576   NS_TEST_ASSERT_MSG_EQ (m_countNode0, 10, "Node 0 should have received 10 packets");
       
   577   NS_TEST_ASSERT_MSG_EQ (m_countNode1, 10, "Node 1 should have received 10 packets");
       
   578 
       
   579   return GetErrorStatus ();
       
   580 }
       
   581 
       
   582 class CsmaPacketSocketTestCase : public TestCase
       
   583 {
       
   584 public:
       
   585   CsmaPacketSocketTestCase ();
       
   586   virtual ~CsmaPacketSocketTestCase ();
       
   587 
       
   588 private:
       
   589   virtual bool DoRun (void);
       
   590   void SinkRx (std::string path, Ptr<const Packet> p, const Address &address);
       
   591   void DropEvent (Ptr<const Packet> p);
       
   592   uint32_t m_count;
       
   593   uint32_t m_drops;
       
   594 };
       
   595 
       
   596 // Add some help text to this case to describe what it is intended to test
       
   597 CsmaPacketSocketTestCase::CsmaPacketSocketTestCase ()
       
   598   : TestCase ("Packet socket example for Carrier Sense Multiple Access (CSMA) networks"), m_count (0), m_drops (0)
       
   599 {
       
   600 }
       
   601 
       
   602 CsmaPacketSocketTestCase::~CsmaPacketSocketTestCase ()
       
   603 {
       
   604 }
       
   605 
       
   606 void 
       
   607 CsmaPacketSocketTestCase::SinkRx (std::string path, Ptr<const Packet> p, const Address& address)
       
   608 {
       
   609   m_count++;
       
   610 }
       
   611 
       
   612 void 
       
   613 CsmaPacketSocketTestCase::DropEvent (Ptr<const Packet> p)
       
   614 {
       
   615   m_drops++;
       
   616 }
       
   617 
       
   618 //
       
   619 // Network topology
       
   620 //
       
   621 //       n0    n1   n2   n3
       
   622 //       |     |    |    |
       
   623 //     =====================
       
   624 //
       
   625 // - Packet socket flow from n0 to n1 and from node n3 to n0
       
   626 // -- We will test reception at node n0
       
   627 // - Default 512 byte packets generated by traffic generator
       
   628 //
       
   629 bool
       
   630 CsmaPacketSocketTestCase::DoRun (void)
       
   631 {
       
   632   // Here, we will explicitly create four nodes.
       
   633   NodeContainer nodes;
       
   634   nodes.Create (4);
       
   635 
       
   636   PacketSocketHelper packetSocket;
       
   637   packetSocket.Install (nodes);
       
   638 
       
   639   // create the shared medium used by all csma devices.
       
   640   Ptr<CsmaChannel> channel = CreateObjectWithAttributes<CsmaChannel> (
       
   641     "DataRate", DataRateValue (DataRate(5000000)), 
       
   642     "Delay", TimeValue (MilliSeconds(2)));
       
   643 
       
   644   // use a helper function to connect our nodes to the shared channel.
       
   645   CsmaHelper csma;
       
   646   csma.SetDeviceAttribute ("EncapsulationMode", StringValue ("Llc"));
       
   647   NetDeviceContainer devs = csma.Install (nodes, channel);
       
   648 
       
   649   // Create the OnOff application to send raw datagrams
       
   650   //
       
   651   // Make packets be sent about every DefaultPacketSize / DataRate = 
       
   652   // 4096 bits / (5000 bits/second) = 0.82 second.
       
   653   PacketSocketAddress socket;
       
   654   socket.SetSingleDevice(devs.Get (0)->GetIfIndex ());
       
   655   socket.SetPhysicalAddress (devs.Get (1)->GetAddress ());
       
   656   socket.SetProtocol (2);
       
   657   OnOffHelper onoff ("ns3::PacketSocketFactory", Address (socket));
       
   658   onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1.0)));
       
   659   onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0)));
       
   660   onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000)));
       
   661   ApplicationContainer apps = onoff.Install (nodes.Get (0));
       
   662   apps.Start (Seconds (1.0));
       
   663   apps.Stop (Seconds (10.0));
       
   664 
       
   665   socket.SetSingleDevice (devs.Get (3)->GetIfIndex ());
       
   666   socket.SetPhysicalAddress (devs.Get (0)->GetAddress ());
       
   667   socket.SetProtocol (3);
       
   668   onoff.SetAttribute ("Remote", AddressValue (socket));
       
   669   onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0)));
       
   670   apps = onoff.Install (nodes.Get (3));
       
   671   apps.Start (Seconds (1.0));
       
   672   apps.Stop (Seconds (10.0));
       
   673 
       
   674   PacketSinkHelper sink = PacketSinkHelper ("ns3::PacketSocketFactory",
       
   675                                             socket);
       
   676   apps = sink.Install (nodes.Get (0));
       
   677   apps.Start (Seconds (0.0));
       
   678   apps.Stop (Seconds (20.0));
       
   679 
       
   680   // Trace receptions
       
   681   Config::Connect ("/NodeList/0/ApplicationList/*/$ns3::PacketSink/Rx",
       
   682                    MakeCallback (&CsmaPacketSocketTestCase::SinkRx, this));
       
   683  
       
   684   Simulator::Run ();
       
   685   Simulator::Destroy ();
       
   686 
       
   687   // We should have received 10 packets on node 0
       
   688   NS_TEST_ASSERT_MSG_EQ (m_count, 10, "Node 0 should have received 10 packets");
       
   689 
       
   690   return GetErrorStatus ();
       
   691 }
       
   692 
       
   693 class CsmaPingTestCase : public TestCase
       
   694 {
       
   695 public:
       
   696   CsmaPingTestCase ();
       
   697   virtual ~CsmaPingTestCase ();
       
   698 
       
   699 private:
       
   700   virtual bool DoRun (void);
       
   701   void SinkRx (Ptr<const Packet> p, const Address &ad);
       
   702   void PingRtt (std::string context, Time rtt);
       
   703   void DropEvent (Ptr<const Packet> p);
       
   704   uint32_t m_countSinkRx;
       
   705   uint32_t m_countPingRtt;
       
   706   uint32_t m_drops;
       
   707 };
       
   708 
       
   709 // Add some help text to this case to describe what it is intended to test
       
   710 CsmaPingTestCase::CsmaPingTestCase ()
       
   711   : TestCase ("Ping example for Carrier Sense Multiple Access (CSMA) networks"), m_countSinkRx (0), m_countPingRtt (0), m_drops (0)
       
   712 {
       
   713 }
       
   714 
       
   715 CsmaPingTestCase::~CsmaPingTestCase ()
       
   716 {
       
   717 }
       
   718 
       
   719 void 
       
   720 CsmaPingTestCase::SinkRx (Ptr<const Packet> p, const Address &ad)
       
   721 {
       
   722   m_countSinkRx++;
       
   723 }
       
   724 
       
   725 void 
       
   726 CsmaPingTestCase::PingRtt (std::string context, Time rtt)
       
   727 {
       
   728   m_countPingRtt++;
       
   729 }
       
   730 
       
   731 void 
       
   732 CsmaPingTestCase::DropEvent (Ptr<const Packet> p)
       
   733 {
       
   734   m_drops++;
       
   735 }
       
   736 
       
   737 // Network topology
       
   738 //
       
   739 //       n0    n1   n2   n3
       
   740 //       |     |    |    |
       
   741 //     =====================
       
   742 //
       
   743 //  node n0,n1,n3 pings to node n2
       
   744 //  node n0 generates protocol 2 (IGMP) to node n3
       
   745 //
       
   746 bool
       
   747 CsmaPingTestCase::DoRun (void)
       
   748 {
       
   749   // Here, we will explicitly create four nodes.
       
   750   NodeContainer c;
       
   751   c.Create (4);
       
   752 
       
   753   // connect all our nodes to a shared channel.
       
   754   CsmaHelper csma;
       
   755   csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
       
   756   csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
       
   757   csma.SetDeviceAttribute ("EncapsulationMode", StringValue ("Llc"));
       
   758   NetDeviceContainer devs = csma.Install (c);
       
   759 
       
   760   // add an ip stack to all nodes.
       
   761   InternetStackHelper ipStack;
       
   762   ipStack.Install (c);
       
   763 
       
   764   // assign ip addresses
       
   765   Ipv4AddressHelper ip;
       
   766   ip.SetBase ("192.168.1.0", "255.255.255.0");
       
   767   Ipv4InterfaceContainer addresses = ip.Assign (devs);
       
   768 
       
   769   // Create the OnOff application to send UDP datagrams from n0 to n1.
       
   770   //
       
   771   // Make packets be sent about every DefaultPacketSize / DataRate = 
       
   772   // 4096 bits / (5000 bits/second) = 0.82 second.
       
   773   Config::SetDefault ("ns3::Ipv4RawSocketImpl::Protocol", StringValue ("2"));
       
   774   InetSocketAddress dst = InetSocketAddress (addresses.GetAddress (3));
       
   775   OnOffHelper onoff = OnOffHelper ("ns3::Ipv4RawSocketFactory", dst);
       
   776   onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1.0)));
       
   777   onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0)));
       
   778   onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000)));
       
   779 
       
   780   ApplicationContainer apps = onoff.Install (c.Get (0));
       
   781   apps.Start (Seconds (1.0));
       
   782   apps.Stop (Seconds (10.0));
       
   783 
       
   784   PacketSinkHelper sink = PacketSinkHelper ("ns3::Ipv4RawSocketFactory", dst);
       
   785   apps = sink.Install (c.Get (3));
       
   786   apps.Start (Seconds (0.0));
       
   787   apps.Stop (Seconds (11.0));
       
   788 
       
   789   V4PingHelper ping = V4PingHelper (addresses.GetAddress (2));
       
   790   NodeContainer pingers;
       
   791   pingers.Add (c.Get (0));
       
   792   pingers.Add (c.Get (1));
       
   793   pingers.Add (c.Get (3));
       
   794   apps = ping.Install (pingers);
       
   795   apps.Start (Seconds (2.0));
       
   796   apps.Stop (Seconds (5.0));
       
   797 
       
   798   // Trace receptions
       
   799   Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx", 
       
   800                                  MakeCallback (&CsmaPingTestCase::SinkRx, this));
       
   801 
       
   802   // Trace pings
       
   803   Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::V4Ping/Rtt",
       
   804                    MakeCallback (&CsmaPingTestCase::PingRtt, this));
       
   805 
       
   806   Simulator::Run ();
       
   807   Simulator::Destroy ();
       
   808 
       
   809   // We should have sent and received 10 packets
       
   810   NS_TEST_ASSERT_MSG_EQ (m_countSinkRx, 10, "Node 3 should have received 10 packets");
       
   811 
       
   812   // We should have 3 pingers that ping every second for 3 seconds.
       
   813   NS_TEST_ASSERT_MSG_EQ (m_countPingRtt, 9, "Node 2 should have been pinged 9 times");
       
   814 
       
   815   return GetErrorStatus ();
       
   816 }
       
   817 
       
   818 class CsmaRawIpSocketTestCase : public TestCase
       
   819 {
       
   820 public:
       
   821   CsmaRawIpSocketTestCase ();
       
   822   virtual ~CsmaRawIpSocketTestCase ();
       
   823 
       
   824 private:
       
   825   virtual bool DoRun (void);
       
   826   void SinkRx (Ptr<const Packet> p, const Address &ad);
       
   827   void DropEvent (Ptr<const Packet> p);
       
   828   uint32_t m_count;
       
   829   uint32_t m_drops;
       
   830 };
       
   831 
       
   832 // Add some help text to this case to describe what it is intended to test
       
   833 CsmaRawIpSocketTestCase::CsmaRawIpSocketTestCase ()
       
   834   : TestCase ("Raw internet protocol socket example for Carrier Sense Multiple Access (CSMA) networks"), m_count (0), m_drops (0)
       
   835 {
       
   836 }
       
   837 
       
   838 CsmaRawIpSocketTestCase::~CsmaRawIpSocketTestCase ()
       
   839 {
       
   840 }
       
   841 
       
   842 void 
       
   843 CsmaRawIpSocketTestCase::SinkRx (Ptr<const Packet> p, const Address &ad)
       
   844 {
       
   845   m_count++;
       
   846 }
       
   847 
       
   848 void 
       
   849 CsmaRawIpSocketTestCase::DropEvent (Ptr<const Packet> p)
       
   850 {
       
   851   m_drops++;
       
   852 }
       
   853 
       
   854 //
       
   855 // Network topology
       
   856 //    (sender)         (receiver)
       
   857 //       n0    n1   n2   n3
       
   858 //       |     |    |    |
       
   859 //     =====================
       
   860 //
       
   861 // Node n0 sends data to node n3 over a raw IP socket.  The protocol
       
   862 // number used is 2.
       
   863 //
       
   864 bool
       
   865 CsmaRawIpSocketTestCase::DoRun (void)
       
   866 {
       
   867   // Here, we will explicitly create four nodes.
       
   868   NodeContainer c;
       
   869   c.Create (4);
       
   870 
       
   871   // connect all our nodes to a shared channel.
       
   872   CsmaHelper csma;
       
   873   csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
       
   874   csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
       
   875   csma.SetDeviceAttribute ("EncapsulationMode", StringValue ("Llc"));
       
   876   NetDeviceContainer devs = csma.Install (c);
       
   877 
       
   878   // add an ip stack to all nodes.
       
   879   InternetStackHelper ipStack;
       
   880   ipStack.Install (c);
       
   881 
       
   882   // assign ip addresses
       
   883   Ipv4AddressHelper ip;
       
   884   ip.SetBase ("192.168.1.0", "255.255.255.0");
       
   885   Ipv4InterfaceContainer addresses = ip.Assign (devs);
       
   886 
       
   887   // IP protocol configuration
       
   888   //
       
   889   // Make packets be sent about every DefaultPacketSize / DataRate = 
       
   890   // 4096 bits / (5000 bits/second) = 0.82 second.
       
   891   Config::SetDefault ("ns3::Ipv4RawSocketImpl::Protocol", StringValue ("2"));
       
   892   InetSocketAddress dst = InetSocketAddress (addresses.GetAddress (3));
       
   893   OnOffHelper onoff = OnOffHelper ("ns3::Ipv4RawSocketFactory", dst);
       
   894   onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1.0)));
       
   895   onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0)));
       
   896   onoff.SetAttribute ("DataRate", DataRateValue (DataRate (5000)));
       
   897 
       
   898   ApplicationContainer apps = onoff.Install (c.Get (0));
       
   899   apps.Start (Seconds (1.0));
       
   900   apps.Stop (Seconds (10.0));
       
   901 
       
   902   PacketSinkHelper sink = PacketSinkHelper ("ns3::Ipv4RawSocketFactory", dst);
       
   903   apps = sink.Install (c.Get (3));
       
   904   apps.Start (Seconds (0.0));
       
   905   apps.Stop (Seconds (12.0));
       
   906 
       
   907   // Trace receptions
       
   908   Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx", 
       
   909                                  MakeCallback (&CsmaRawIpSocketTestCase::SinkRx, this));
       
   910 
       
   911   Simulator::Run ();
       
   912   Simulator::Destroy ();
       
   913 
       
   914   // We should have sent and received 10 packets
       
   915   NS_TEST_ASSERT_MSG_EQ (m_count, 10, "Node 3 should have received 10 packets");
       
   916 
       
   917   return GetErrorStatus ();
       
   918 }
       
   919 
       
   920 class CsmaStarTestCase : public TestCase
       
   921 {
       
   922 public:
       
   923   CsmaStarTestCase ();
       
   924   virtual ~CsmaStarTestCase ();
       
   925 
       
   926 private:
       
   927   virtual bool DoRun (void);
       
   928   void SinkRx (Ptr<const Packet> p, const Address &ad);
       
   929   void DropEvent (Ptr<const Packet> p);
       
   930   uint32_t m_count;
       
   931   uint32_t m_drops;
       
   932 };
       
   933 
       
   934 // Add some help text to this case to describe what it is intended to test
       
   935 CsmaStarTestCase::CsmaStarTestCase ()
       
   936   : TestCase ("Star example for Carrier Sense Multiple Access (CSMA) networks"), m_count (0), m_drops (0)
       
   937 {
       
   938 }
       
   939 
       
   940 CsmaStarTestCase::~CsmaStarTestCase ()
       
   941 {
       
   942 }
       
   943 
       
   944 void 
       
   945 CsmaStarTestCase::SinkRx (Ptr<const Packet> p, const Address& ad)
       
   946 {
       
   947   m_count++;
       
   948 }
       
   949 
       
   950 void 
       
   951 CsmaStarTestCase::DropEvent (Ptr<const Packet> p)
       
   952 {
       
   953   m_drops++;
       
   954 }
       
   955 
       
   956 // Network topology (default)
       
   957 //
       
   958 //            n2     +          +     n3          .
       
   959 //             | ... |\        /| ... |           .
       
   960 //             ======= \      / =======           .
       
   961 //              CSMA    \    /   CSMA             .
       
   962 //                       \  /                     .
       
   963 //            n1     +--- n0 ---+     n4          .
       
   964 //             | ... |   /  \   | ... |           .
       
   965 //             =======  /    \  =======           .
       
   966 //              CSMA   /      \  CSMA             .
       
   967 //                    /        \                  .
       
   968 //            n6     +          +     n5          .
       
   969 //             | ... |          | ... |           .
       
   970 //             =======          =======           .
       
   971 //              CSMA             CSMA             .
       
   972 //
       
   973 bool
       
   974 CsmaStarTestCase::DoRun (void)
       
   975 {
       
   976   //
       
   977   // Default number of nodes in the star.
       
   978   //
       
   979   uint32_t nSpokes = 7;
       
   980 
       
   981   CsmaHelper csma;
       
   982   csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
       
   983   csma.SetChannelAttribute ("Delay", StringValue ("1ms"));
       
   984   CsmaStarHelper star (nSpokes, csma);
       
   985 
       
   986   NodeContainer fillNodes;
       
   987 
       
   988   //
       
   989   // Just to be nasy, hang some more nodes off of the CSMA channel for each
       
   990   // spoke, so that there are a total of 16 nodes on each channel.  Stash
       
   991   // all of these new devices into a container.
       
   992   //
       
   993   NetDeviceContainer fillDevices;
       
   994 
       
   995   uint32_t nFill = 14;
       
   996   for (uint32_t i = 0; i < star.GetSpokeDevices ().GetN (); ++i)
       
   997     {
       
   998       Ptr<Channel> channel = star.GetSpokeDevices ().Get (i)->GetChannel ();
       
   999       Ptr<CsmaChannel> csmaChannel = channel->GetObject<CsmaChannel> ();
       
  1000       NodeContainer newNodes;
       
  1001       newNodes.Create (nFill);
       
  1002       fillNodes.Add (newNodes);
       
  1003       fillDevices.Add (csma.Install (newNodes, csmaChannel));
       
  1004     }
       
  1005 
       
  1006   InternetStackHelper internet;
       
  1007   star.InstallStack (internet);
       
  1008   internet.Install (fillNodes);
       
  1009 
       
  1010   star.AssignIpv4Addresses (Ipv4AddressHelper ("10.1.0.0", "255.255.255.0"));
       
  1011 
       
  1012   //
       
  1013   // We assigned addresses to the logical hub and the first "drop" of the 
       
  1014   // CSMA network that acts as the spoke, but we also have a number of fill
       
  1015   // devices (nFill) also hanging off the CSMA network.  We have got to 
       
  1016   // assign addresses to them as well.  We put all of the fill devices into
       
  1017   // a single device container, so the first nFill devices are associated
       
  1018   // with the channel connected to spokeDevices.Get (0), the second nFill
       
  1019   // devices afe associated with the channel connected to spokeDevices.Get (1)
       
  1020   // etc.
       
  1021   //
       
  1022   Ipv4AddressHelper address;
       
  1023   for(uint32_t i = 0; i < star.SpokeCount (); ++i)
       
  1024   {
       
  1025     std::ostringstream subnet;
       
  1026     subnet << "10.1." << i << ".0";
       
  1027       address.SetBase (subnet.str ().c_str (), "255.255.255.0", "0.0.0.3");
       
  1028 
       
  1029     for (uint32_t j = 0; j < nFill; ++j)
       
  1030       {
       
  1031         address.Assign (fillDevices.Get (i * nFill + j));
       
  1032       }
       
  1033   }
       
  1034 
       
  1035   //
       
  1036   // Create a packet sink on the star "hub" to receive packets.  
       
  1037   // 
       
  1038   uint16_t port = 50000;
       
  1039   Address hubLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
       
  1040   PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", hubLocalAddress);
       
  1041   ApplicationContainer hubApp = packetSinkHelper.Install (star.GetHub ());
       
  1042   hubApp.Start (Seconds (1.0));
       
  1043   hubApp.Stop (Seconds (10.0));
       
  1044 
       
  1045   //
       
  1046   // Create OnOff applications to send TCP to the hub, one on each spoke node.
       
  1047   //
       
  1048   // Make packets be sent about every DefaultPacketSize / DataRate = 
       
  1049   // 4096 bits / (5000 bits/second) = 0.82 second.
       
  1050   OnOffHelper onOffHelper ("ns3::TcpSocketFactory", Address ());
       
  1051   onOffHelper.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
       
  1052   onOffHelper.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
       
  1053   onOffHelper.SetAttribute ("DataRate", DataRateValue (DataRate (5000)));
       
  1054 
       
  1055   ApplicationContainer spokeApps;
       
  1056 
       
  1057   for (uint32_t i = 0; i < star.SpokeCount (); ++i)
       
  1058     {
       
  1059       AddressValue remoteAddress (InetSocketAddress (star.GetHubIpv4Address (i), port));
       
  1060       onOffHelper.SetAttribute ("Remote", remoteAddress);
       
  1061       spokeApps.Add (onOffHelper.Install (star.GetSpokeNode (i)));
       
  1062     }
       
  1063 
       
  1064   spokeApps.Start (Seconds (1.0));
       
  1065   spokeApps.Stop (Seconds (10.0));
       
  1066 
       
  1067   //
       
  1068   // Because we are evil, we also add OnOff applications to send TCP to the hub 
       
  1069   // from the fill devices on each CSMA link.  The first nFill nodes in the 
       
  1070   // fillNodes container are on the CSMA network talking to the zeroth device
       
  1071   // on the hub node.  The next nFill nodes are on the CSMA network talking to
       
  1072   // the first device on the hub node, etc.  So the ith fillNode is associated
       
  1073   // with the hub address found on the (i / nFill)th device on the hub node.
       
  1074   //
       
  1075   ApplicationContainer fillApps;
       
  1076 
       
  1077   for (uint32_t i = 0; i < fillNodes.GetN (); ++i)
       
  1078     {
       
  1079       AddressValue remoteAddress (InetSocketAddress (star.GetHubIpv4Address (i / nFill), port));
       
  1080       onOffHelper.SetAttribute ("Remote", remoteAddress);
       
  1081       fillApps.Add (onOffHelper.Install (fillNodes.Get (i)));
       
  1082     }
       
  1083 
       
  1084   fillApps.Start (Seconds (1.0));
       
  1085   fillApps.Stop (Seconds (10.0));
       
  1086 
       
  1087   //
       
  1088   // Turn on global static routing so we can actually be routed across the star.
       
  1089   //
       
  1090   Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
       
  1091 
       
  1092   // Trace receptions
       
  1093   Config::ConnectWithoutContext ("/NodeList/0/ApplicationList/*/$ns3::PacketSink/Rx", 
       
  1094                                  MakeCallback (&CsmaStarTestCase::SinkRx, this));
       
  1095 
       
  1096   Simulator::Run ();
       
  1097   Simulator::Destroy ();
       
  1098 
       
  1099   // The hub node should have received 10 packets from the nFill + 1
       
  1100   // nodes on each spoke.
       
  1101   NS_TEST_ASSERT_MSG_EQ (m_count, 10 * ( nSpokes * (nFill + 1)), "Hub node did not receive the proper number of packets");
       
  1102 
       
  1103   return GetErrorStatus ();
       
  1104 }
       
  1105 
       
  1106 class CsmaSystemTestSuite : public TestSuite
       
  1107 {
       
  1108 public:
       
  1109   CsmaSystemTestSuite ();
       
  1110 };
       
  1111 
       
  1112 CsmaSystemTestSuite::CsmaSystemTestSuite ()
       
  1113   : TestSuite ("csma-system", BVT)
       
  1114 {
       
  1115   AddTestCase (new CsmaBridgeTestCase);
       
  1116   AddTestCase (new CsmaBroadcastTestCase);
       
  1117   AddTestCase (new CsmaMulticastTestCase);
       
  1118   AddTestCase (new CsmaOneSubnetTestCase);
       
  1119   AddTestCase (new CsmaPacketSocketTestCase);
       
  1120   AddTestCase (new CsmaPingTestCase);
       
  1121   AddTestCase (new CsmaRawIpSocketTestCase);
       
  1122   AddTestCase (new CsmaStarTestCase);
       
  1123 }
       
  1124 
       
  1125 // Do not forget to allocate an instance of this TestSuite
       
  1126 static CsmaSystemTestSuite csmaSystemTestSuite;