examples/csma-multicast.cc
changeset 1433 a6fb891b59fd
parent 1432 3aef7d7a71c2
child 1434 2b63aafb050b
equal deleted inserted replaced
1432:3aef7d7a71c2 1433:a6fb891b59fd
    14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    15  */
    15  */
    16 
    16 
    17 // Network topology
    17 // Network topology
    18 //
    18 //
    19 //       n0    n1   n2   n3
    19 //                     Lan1
    20 //       |     |    |    |
    20 //                 ===========
    21 //     =====================
    21 //                 |    |    | 
    22 //
    22 //       n0   n1   n2   n3   n4
    23 // - CBR/UDP flows from n0 to n1, and from n3 to n0
    23 //       |    |    |
    24 // - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
    24 //       ===========
    25 //   (i.e., DataRate of 448,000 bps)
    25 //           Lan0
    26 // - DropTail queues 
    26 //
    27 // - Tracing of queues and packet receptions to file "csma-one-subnet.tr"
    27 // - Multicast source is at node n0;
    28 
    28 // - Multicast forwarded by node n2 onto LAN1;
    29 #include <iostream>
    29 // - Nodes n0, n1, n2, n3, and n4 receive the multicast frame.
    30 #include <fstream>
    30 // - Node n4 listens for the data (actual listener not yet implementted)
    31 #include <string>
       
    32 #include <cassert>
       
    33 
    31 
    34 #include "ns3/command-line.h"
    32 #include "ns3/command-line.h"
    35 #include "ns3/default-value.h"
    33 #include "ns3/default-value.h"
    36 #include "ns3/ptr.h"
    34 #include "ns3/ptr.h"
    37 #include "ns3/random-variable.h"
    35 #include "ns3/random-variable.h"
    38 #include "ns3/debug.h"
    36 #include "ns3/debug.h"
    39 
       
    40 #include "ns3/simulator.h"
    37 #include "ns3/simulator.h"
    41 #include "ns3/nstime.h"
    38 #include "ns3/nstime.h"
    42 #include "ns3/data-rate.h"
    39 #include "ns3/data-rate.h"
    43 
       
    44 #include "ns3/ascii-trace.h"
    40 #include "ns3/ascii-trace.h"
    45 #include "ns3/pcap-trace.h"
    41 #include "ns3/pcap-trace.h"
    46 #include "ns3/internet-node.h"
    42 #include "ns3/internet-node.h"
    47 #include "ns3/csma-channel.h"
    43 #include "ns3/csma-channel.h"
    48 #include "ns3/csma-net-device.h"
    44 #include "ns3/csma-net-device.h"
    56 #include "ns3/ipv4-route.h"
    52 #include "ns3/ipv4-route.h"
    57 #include "ns3/onoff-application.h"
    53 #include "ns3/onoff-application.h"
    58 
    54 
    59 using namespace ns3;
    55 using namespace ns3;
    60 
    56 
    61 NS_DEBUG_COMPONENT_DEFINE ("Me");
    57 NS_DEBUG_COMPONENT_DEFINE ("CsmaMulticast");
    62 
    58 
    63 int 
    59 int 
    64 main (int argc, char *argv[])
    60 main (int argc, char *argv[])
    65 {
    61 {
    66   // Users may find it convenient to turn on explicit debugging
    62 //
    67   // for selected modules; the below lines suggest how to do this
    63 // Users may find it convenient to turn on explicit debugging
       
    64 // for selected modules; the below lines suggest how to do this
       
    65 //
    68 #if 0
    66 #if 0
    69   DebugComponentEnable("Me");
    67   DebugComponentEnable("CsmaMulticast");
       
    68 
    70   DebugComponentEnable("Object");
    69   DebugComponentEnable("Object");
    71   DebugComponentEnable("Queue");
    70   DebugComponentEnable("Queue");
    72   DebugComponentEnable("DropTailQueue");
    71   DebugComponentEnable("DropTailQueue");
    73   DebugComponentEnable("Channel");
    72   DebugComponentEnable("Channel");
    74   DebugComponentEnable("CsmaChannel");
    73   DebugComponentEnable("CsmaChannel");
    84   DebugComponentEnable("Ipv4Interface");
    83   DebugComponentEnable("Ipv4Interface");
    85   DebugComponentEnable("ArpIpv4Interface");
    84   DebugComponentEnable("ArpIpv4Interface");
    86   DebugComponentEnable("Ipv4LoopbackInterface");
    85   DebugComponentEnable("Ipv4LoopbackInterface");
    87 #endif
    86 #endif
    88 
    87 
    89   DebugComponentEnable("Me");
    88   DebugComponentEnable("UdpSocket");
       
    89   DebugComponentEnable("UdpL4Protocol");
       
    90   DebugComponentEnable("Ipv4L3Protocol");
       
    91   DebugComponentEnable("Ipv4StaticRouting");
       
    92   DebugComponentEnable("Ipv4Interface");
       
    93   DebugComponentEnable("ArpIpv4Interface");
       
    94   DebugComponentEnable("Ipv4LoopbackInterface");
       
    95 
       
    96   DebugComponentEnable("CsmaMulticast");
    90   DebugComponentEnable("CsmaChannel");
    97   DebugComponentEnable("CsmaChannel");
    91   DebugComponentEnable("CsmaNetDevice");
    98   DebugComponentEnable("CsmaNetDevice");
    92   DebugComponentEnable("UdpL4Protocol");
    99 //
    93 
   100 // Set up default values for the simulation.  Use the DefaultValue::Bind()
    94   // Set up some default values for the simulation.  Use the Bind()
   101 // technique to tell the system what subclass of Queue to use.  The Bind
    95   // technique to tell the system what subclass of Queue to use,
   102 // command command tells the queue factory which class to instantiate when the
    96   // and what the queue limit is
   103 // queue factory is invoked in the topology code
    97 
   104 //
    98   // The below Bind command tells the queue factory which class to
       
    99   // instantiate, when the queue factory is invoked in the topology code
       
   100   DefaultValue::Bind ("Queue", "DropTailQueue");
   105   DefaultValue::Bind ("Queue", "DropTailQueue");
   101 
   106 //
   102   // Allow the user to override any of the defaults and the above
   107 // Allow the user to override any of the defaults and the above Bind() at
   103   // Bind()s at run-time, via command-line arguments
   108 // run-time, via command-line arguments
       
   109 //
   104   CommandLine::Parse (argc, argv);
   110   CommandLine::Parse (argc, argv);
   105 
   111 //
   106   // Here, we will explicitly create four nodes.  In more sophisticated
   112 // Explicitly create the nodes required by the topology (shown above).
   107   // topologies, we could configure a node factory.
   113 //
   108   NS_DEBUG("Create nodes.");
   114   NS_DEBUG("Create nodes.");
   109   Ptr<Node> n0 = Create<InternetNode> ();
   115   Ptr<Node> n0 = Create<InternetNode> ();
   110   Ptr<Node> n1 = Create<InternetNode> (); 
   116   Ptr<Node> n1 = Create<InternetNode> (); 
   111   Ptr<Node> n2 = Create<InternetNode> (); 
   117   Ptr<Node> n2 = Create<InternetNode> (); 
   112   Ptr<Node> n3 = Create<InternetNode> ();
   118   Ptr<Node> n3 = Create<InternetNode> ();
       
   119   Ptr<Node> n4 = Create<InternetNode> ();
   113 
   120 
   114   NS_DEBUG("Create channels.");
   121   NS_DEBUG("Create channels.");
   115   // We create the channels first without any IP addressing information
   122 //
   116   Ptr<CsmaChannel> channel0 = 
   123 // Explicitly create the channels required by the topology (shown above).
       
   124 //
       
   125   Ptr<CsmaChannel> lan0 = 
   117     CsmaTopology::CreateCsmaChannel(
   126     CsmaTopology::CreateCsmaChannel(
   118       DataRate(5000000), MilliSeconds(2));
   127       DataRate(5000000), MilliSeconds(2));
   119 
   128 
       
   129   Ptr<CsmaChannel> lan1 = 
       
   130     CsmaTopology::CreateCsmaChannel(
       
   131       DataRate(5000000), MilliSeconds(2));
       
   132 
   120   NS_DEBUG("Build Topology.");
   133   NS_DEBUG("Build Topology.");
   121   uint32_t netDeviceNumberNode0 = CsmaIpv4Topology::AddIpv4CsmaNode (n0, 
   134 //
   122     channel0, Eui48Address("10:54:23:54:23:50"));
   135 // Now fill out the topology by creating the net devices required to connect
   123   uint32_t netDeviceNumberNode1 = CsmaIpv4Topology::AddIpv4CsmaNode (n1, 
   136 // the nodes to the channels and hooking them up.  AddIpv4CsmaNetDevice will
   124     channel0, Eui48Address("10:54:23:54:23:51"));
   137 // create a net device, add a MAC address (in memory of the pink flamingo) and
   125   uint32_t netDeviceNumberNode2 = CsmaIpv4Topology::AddIpv4CsmaNode (n2, 
   138 // connect the net device to a nodes and also to a channel. the 
   126     channel0, Eui48Address("10:54:23:54:23:52"));
   139 // AddIpv4CsmaNetDevice method returns a net device index for the net device
   127   uint32_t netDeviceNumberNode3 = CsmaIpv4Topology::AddIpv4CsmaNode (n3, 
   140 // created on the node.  Interpret nd0 as the net device we created for node
   128     channel0, Eui48Address("10:54:23:54:23:53"));
   141 // zero.  Interpret nd2Lan0 as the net device we created for node two to
   129 
   142 // connect to Lan0. 
   130   NS_DEBUG ("netDeviceNumberNode0 = " << netDeviceNumberNode0);
   143 //
   131   NS_DEBUG ("netDeviceNumberNode1 = " << netDeviceNumberNode1);
   144   uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan0, 
   132   NS_DEBUG ("netDeviceNumberNode2 = " << netDeviceNumberNode2);
   145     Eui48Address("08:00:2e:00:00:00"));
   133   NS_DEBUG ("netDeviceNumberNode3 = " << netDeviceNumberNode3);
   146   uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan0, 
   134 
   147     Eui48Address("08:00:2e:00:00:01"));
   135   // Later, we add IP addresses.  
   148   uint32_t nd2Lan0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan0, 
       
   149     Eui48Address("08:00:2e:00:00:02"));
       
   150 
       
   151   uint32_t nd2Lan1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan1, 
       
   152     Eui48Address("08:00:2e:00:00:00"));
       
   153   uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan1, 
       
   154     Eui48Address("08:00:2e:00:00:01"));
       
   155   uint32_t nd4 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n4, lan1, 
       
   156     Eui48Address("08:00:2e:00:00:02"));
       
   157 
       
   158   NS_DEBUG ("nd0 = " << nd0);
       
   159   NS_DEBUG ("nd1 = " << nd1);
       
   160   NS_DEBUG ("nd2Lan0 = " << nd2Lan0);
       
   161   NS_DEBUG ("nd2Lan1 = " << nd2Lan1);
       
   162   NS_DEBUG ("nd3 = " << nd3);
       
   163   NS_DEBUG ("nd4 = " << nd3);
       
   164 //
       
   165 // We've got the "hardware" in place.  Now we need to add IP addresses.
       
   166 //
   136   NS_DEBUG("Assign IP Addresses.");
   167   NS_DEBUG("Assign IP Addresses.");
   137   // XXX BUGBUG
   168 //
   138   // Need a better way to get the interface index.  The point-to-point topology
   169 // XXX BUGBUG
   139   // as implemented can't return the index since it creates interfaces on both
   170 // Need a better way to get the interface index.  The point-to-point topology
   140   // sides (i.e., AddIpv4Addresses, not AddIpv4Address).  Need a method on
   171 // as implemented can't return the index since it creates interfaces on both
   141   // Ipv4 to find the interface index corresponding to a given ipv4 address.
   172 // sides (i.e., it does AddIpv4Addresses, not AddIpv4Address).  We need a
   142   uint32_t ifIndexNode0 = CsmaIpv4Topology::AddIpv4Address (n0, 
   173 // method on Ipv4 to find the interface index corresponding to a given ipv4 
   143     netDeviceNumberNode0, Ipv4Address ("10.1.1.1"), 
   174 // address.
   144     Ipv4Mask ("255.255.255.0"));
   175 //
   145 
   176 // First, assign IP addresses to the net devices and associated interfaces
   146   uint32_t ifIndexNode1 = CsmaIpv4Topology::AddIpv4Address (n1, 
   177 // on Lan0.  The AddIpv4Address method returns an Ipv4 interface index.
   147     netDeviceNumberNode1, Ipv4Address ("10.1.1.2"), 
   178 // Interpret ifIndexNd0 as the interface index to use to reference the
   148     Ipv4Mask ("255.255.255.0"));
   179 // net device we created on node zero when coming in from the Ipv4 interface.
   149 
   180 // Net device numbers and interface indices are distinct.  Interpret
   150   uint32_t ifIndexNode2 = CsmaIpv4Topology::AddIpv4Address (n2, 
   181 // ifIndexNd2Lan0 as the interface index to use to reference the
   151     netDeviceNumberNode2, Ipv4Address ("10.1.1.3"), 
   182 // net device we created that connects node two to lan zero.
   152     Ipv4Mask ("255.255.255.0"));
   183 //
   153   
   184   uint32_t ifIndexNd0 = CsmaIpv4Topology::AddIpv4Address (n0, nd0, 
   154   uint32_t ifIndexNode3 = CsmaIpv4Topology::AddIpv4Address (n3, 
   185     Ipv4Address ("10.1.1.1"), Ipv4Mask ("255.255.255.0"));
   155     netDeviceNumberNode3, Ipv4Address ("10.1.1.4"), 
   186 
   156     Ipv4Mask ("255.255.255.0"));
   187   uint32_t ifIndexNd1 = CsmaIpv4Topology::AddIpv4Address (n1, nd1, 
   157 
   188     Ipv4Address ("10.1.1.2"), Ipv4Mask ("255.255.255.0"));
   158   NS_DEBUG ("ifIndexNode0 = " << ifIndexNode0);
   189 
   159   NS_DEBUG ("ifIndexNode1 = " << ifIndexNode1);
   190   uint32_t ifIndexNd2Lan0 = CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan0,
   160   NS_DEBUG ("ifIndexNode2 = " << ifIndexNode2);
   191     Ipv4Address ("10.1.1.3"), Ipv4Mask ("255.255.255.0"));
   161   NS_DEBUG ("ifIndexNode3 = " << ifIndexNode3);
   192 //
   162 
   193 // Assign IP addresses to the net devices and associated interfaces on Lan1
   163   // Configure multicasting
   194 //
       
   195   uint32_t ifIndexNd2Lan1 = CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan1, 
       
   196     Ipv4Address ("10.1.2.1"), Ipv4Mask ("255.255.255.0"));
       
   197 
       
   198   uint32_t ifIndexNd3 = CsmaIpv4Topology::AddIpv4Address (n3, nd1, 
       
   199     Ipv4Address ("10.1.2.2"), Ipv4Mask ("255.255.255.0"));
       
   200 
       
   201   uint32_t ifIndexNd4 = CsmaIpv4Topology::AddIpv4Address (n4, nd4,
       
   202     Ipv4Address ("10.1.2.3"), Ipv4Mask ("255.255.255.0"));
       
   203 
       
   204   NS_DEBUG ("ifIndexNd0 = " << ifIndexNd0);
       
   205   NS_DEBUG ("ifIndexNd1 = " << ifIndexNd1);
       
   206   NS_DEBUG ("ifIndexNd2Lan0 = " << ifIndexNd2Lan0);
       
   207   NS_DEBUG ("ifIndexNd2Lan1 = " << ifIndexNd2Lan1);
       
   208   NS_DEBUG ("ifIndexNd3 = " << ifIndexNd3);
       
   209   NS_DEBUG ("ifIndexNd4 = " << ifIndexNd4);
   164   NS_DEBUG("Configure multicasting.");
   210   NS_DEBUG("Configure multicasting.");
       
   211 //
       
   212 // Now we can configure multicasting.  As described above, the multicast 
       
   213 // source is at node zero, which we assigned the IP address of 10.1.1.1 
       
   214 // earlier.  We need to define a multicast group to send packets to.  This
       
   215 // can be any multicast address from 224.0.0.0 through 239.255.255.255
       
   216 // (avoiding the reserved routing protocol addresses).  We just pick a
       
   217 // convenient number.
       
   218 //
   165   Ipv4Address multicastSource ("10.1.1.1");
   219   Ipv4Address multicastSource ("10.1.1.1");
   166   Ipv4Address multicastGroup ("225.0.0.0");
   220   Ipv4Address multicastGroup ("225.0.0.0");
   167 
   221 //
       
   222 // We are going to manually configure multicast routing.  This means telling
       
   223 // node two that it should expect multicast data coming from IP address 
       
   224 // 10.1.1.1 over its IP interface connected to Lan0.  These are called
       
   225 // multicastSource and ifIndexNd2Lan0 respectively.  When node two receives
       
   226 // these packets, they should be forwarded out the interface that connects it
       
   227 // to Lan1 which is called ifIndexNd2Lan1.  All we need to do is to call the
       
   228 // AddMulticastRoute method on node two's Ipv4 interface and provide this
       
   229 // information.  (Note: the vector of output interfaces is in case there are
       
   230 // multiple net devices on a node).
       
   231 //
   168   Ptr<Ipv4> ipv4;
   232   Ptr<Ipv4> ipv4;
       
   233   ipv4 = n2->QueryInterface<Ipv4> (Ipv4::iid);
       
   234 
       
   235   std::vector<uint32_t> outputInterfaces (1);
       
   236   outputInterfaces[0] = ifIndexNd2Lan1;
       
   237 
       
   238   ipv4->AddMulticastRoute (multicastSource, multicastGroup, ifIndexNd2Lan0,
       
   239     outputInterfaces);
       
   240 //
       
   241 // We also need to explain to the node zero forwarding code that when it sees
       
   242 // a packet destined for the multicast group it needs to send it out its
       
   243 // one and only interface.  The 0xffffffff in the call means that the input
       
   244 // interface qualification is not applicable in this case (the packet has
       
   245 // not been received over an interface, it has been created locally).
       
   246 //
   169   ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
   247   ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
   170 
   248 
   171   std::vector<uint32_t> outputInterfaces (1);
   249   outputInterfaces[0] = ifIndexNd0;;
   172   outputInterfaces[0] = ifIndexNode0;
   250 
   173 
   251   ipv4->AddMulticastRoute (multicastSource, multicastGroup, 0xffffffff,
   174   ipv4->AddMulticastRoute (multicastSource, multicastGroup, 0, 
       
   175     outputInterfaces);
   252     outputInterfaces);
   176 
   253 //
   177   ipv4 = n1->QueryInterface<Ipv4> (Ipv4::iid);
   254 // As described above, node four will be the only node listening for the
   178   //  ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
   255 // multicast data.  To enable forwarding bits up the protocol stack, we need
   179 
   256 // to tell the stack to join the multicast group.
   180   ipv4 = n2->QueryInterface<Ipv4> (Ipv4::iid);
   257 //
   181   //  ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
   258   ipv4 = n4->QueryInterface<Ipv4> (Ipv4::iid);
   182 
   259   ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
   183   ipv4 = n3->QueryInterface<Ipv4> (Ipv4::iid);
   260 //
   184   //  ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
   261 // Create an OnOff application to send UDP datagrams from node zero to the
   185 
   262 // multicast group (node four will be listening).
   186   // Create the OnOff application to send UDP datagrams
   263 //
   187   // from n0 to the multicast group
       
   188   NS_DEBUG("Create Applications.");
   264   NS_DEBUG("Create Applications.");
   189   Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
   265   Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
   190     n0, 
   266     n0, 
   191     InetSocketAddress (multicastGroup, 80), 
   267     InetSocketAddress (multicastGroup, 80), 
   192     "Udp",
   268     "Udp",
   193     ConstantVariable(1), 
   269     ConstantVariable(1), 
   194     ConstantVariable(0),
   270     ConstantVariable(0),
   195     DataRate ("128b/s"),
   271     DataRate ("255b/s"),
   196     128);
   272     128);
   197   // Start the application
   273 //
       
   274 // Tell the application when to start and stop.
       
   275 //
   198   ooff->Start(Seconds(1.));
   276   ooff->Start(Seconds(1.));
   199   ooff->Stop (Seconds(10.));
   277   ooff->Stop (Seconds(10.));
   200 
   278 //
   201   // Configure tracing of all enqueue, dequeue, and NetDevice receive events
   279 // Configure tracing of all enqueue, dequeue, and NetDevice receive events.
   202   // Trace output will be sent to the csma-one-subnet.tr file
   280 // Trace output will be sent to the file "csma-multicast.tr"
       
   281 //
   203   NS_DEBUG("Configure Tracing.");
   282   NS_DEBUG("Configure Tracing.");
   204   AsciiTrace asciitrace ("csma-multicast.tr");
   283   AsciiTrace asciitrace ("csma-multicast.tr");
   205   asciitrace.TraceAllNetDeviceRx ();
   284   asciitrace.TraceAllNetDeviceRx ();
   206   asciitrace.TraceAllQueues ();
   285   asciitrace.TraceAllQueues ();
   207 
   286 //
   208   // Also configure some tcpdump traces; each interface will be traced
   287 // Also configure some tcpdump traces; each interface will be traced.
   209   // The output files will be named 
   288 // The output files will be named:
   210   // simple-point-to-point.pcap-<nodeId>-<interfaceId>
   289 //     csma-multicast.pcap-<nodeId>-<interfaceId>
   211   // and can be read by the "tcpdump -r" command (use "-tt" option to
   290 // and can be read by the "tcpdump -r" command (use "-tt" option to
   212   // display timestamps correctly)
   291 // display timestamps correctly)
       
   292 //
   213   PcapTrace pcaptrace ("csma-multicast.pcap");
   293   PcapTrace pcaptrace ("csma-multicast.pcap");
   214   pcaptrace.TraceAllIp ();
   294   pcaptrace.TraceAllIp ();
   215 
   295 //
       
   296 // Now, do the actual simulation.
       
   297 //
   216   NS_DEBUG("Run Simulation.");
   298   NS_DEBUG("Run Simulation.");
   217   Simulator::Run ();
   299   Simulator::Run ();
   218   Simulator::Destroy ();
   300   Simulator::Destroy ();
   219   NS_DEBUG("Done.");
   301   NS_DEBUG("Done.");
   220 }
   302 }