examples/csma-multicast.cc
changeset 2798 143e2e1c5167
parent 2602 d9262bff6df2
child 2800 b3e87b8fa9d2
equal deleted inserted replaced
2797:41489a849fc3 2798:143e2e1c5167
    25 //           Lan0
    25 //           Lan0
    26 //
    26 //
    27 // - Multicast source is at node n0;
    27 // - Multicast source is at node n0;
    28 // - Multicast forwarded by node n2 onto LAN1;
    28 // - Multicast forwarded by node n2 onto LAN1;
    29 // - Nodes n0, n1, n2, n3, and n4 receive the multicast frame.
    29 // - Nodes n0, n1, n2, n3, and n4 receive the multicast frame.
    30 // - Node n4 listens for the data (actual listener not yet implementted)
    30 // - Node n4 listens for the data 
    31 
    31 
    32 #include "ns3/command-line.h"
    32 #include "ns3/core-module.h"
    33 #include "ns3/ptr.h"
    33 #include "ns3/helper-module.h"
    34 #include "ns3/random-variable.h"
    34 #include "ns3/simulator-module.h"
    35 #include "ns3/log.h"
       
    36 #include "ns3/simulator.h"
       
    37 #include "ns3/nstime.h"
       
    38 #include "ns3/data-rate.h"
       
    39 #include "ns3/ascii-trace.h"
    35 #include "ns3/ascii-trace.h"
    40 #include "ns3/pcap-trace.h"
    36 #include "ns3/pcap-trace.h"
    41 #include "ns3/internet-node.h"
    37 
    42 #include "ns3/csma-channel.h"
       
    43 #include "ns3/csma-net-device.h"
       
    44 #include "ns3/csma-topology.h"
       
    45 #include "ns3/csma-ipv4-topology.h"
       
    46 #include "ns3/mac48-address.h"
       
    47 #include "ns3/ipv4-address.h"
       
    48 #include "ns3/inet-socket-address.h"
       
    49 #include "ns3/ipv4.h"
       
    50 #include "ns3/socket.h"
       
    51 #include "ns3/ipv4-route.h"
       
    52 #include "ns3/onoff-application.h"
       
    53 #include "ns3/packet-sink.h"
       
    54 #include "ns3/uinteger.h"
       
    55 
    38 
    56 using namespace ns3;
    39 using namespace ns3;
    57 
    40 
    58 NS_LOG_COMPONENT_DEFINE ("CsmaMulticastExample");
    41 NS_LOG_COMPONENT_DEFINE ("CsmaMulticastExample");
    59 
    42 
    60 int 
    43 int 
    61 main (int argc, char *argv[])
    44 main (int argc, char *argv[])
    62 {
    45 {
    63 //
    46   //
    64 // Users may find it convenient to turn on explicit debugging
    47   // Users may find it convenient to turn on explicit debugging
    65 // for selected modules; the below lines suggest how to do this
    48   // for selected modules; the below lines suggest how to do this
    66 //
    49   //
    67 #if 0
    50   // LogComponentEnable ("CsmaMulticastExample", LOG_LEVEL_INFO);
    68   LogComponentEnable ("CsmaMulticastExample", LOG_LEVEL_INFO);
       
    69 
    51 
    70   LogComponentEnable("Object", LOG_LEVEL_ALL);
    52   //
    71   LogComponentEnable("Queue", LOG_LEVEL_ALL);
    53   // Set up default values for the simulation.  
    72   LogComponentEnable("DropTailQueue", LOG_LEVEL_ALL);
    54   //
    73   LogComponentEnable("Channel", LOG_LEVEL_ALL);
    55   // Select Ethernet II-style encapsulation (no LLC/Snap header)
    74   LogComponentEnable("CsmaChannel", LOG_LEVEL_ALL);
    56   Config::SetDefault ("ns3::CsmaNetDevice::EncapsulationMode", String ("IpArp"));  
    75   LogComponentEnable("NetDevice", LOG_LEVEL_ALL);
       
    76   LogComponentEnable("CsmaNetDevice", LOG_LEVEL_ALL);
       
    77   LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL);
       
    78   LogComponentEnable("PacketSocket", LOG_LEVEL_ALL);
       
    79   LogComponentEnable("Socket", LOG_LEVEL_ALL);
       
    80   LogComponentEnable("UdpSocket", LOG_LEVEL_ALL);
       
    81   LogComponentEnable("UdpL4Protocol", LOG_LEVEL_ALL);
       
    82   LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL);
       
    83   LogComponentEnable("Ipv4StaticRouting", LOG_LEVEL_ALL);
       
    84   LogComponentEnable("Ipv4Interface", LOG_LEVEL_ALL);
       
    85   LogComponentEnable("ArpIpv4Interface", LOG_LEVEL_ALL);
       
    86   LogComponentEnable("Ipv4LoopbackInterface", LOG_LEVEL_ALL);
       
    87   LogComponentEnable("OnOffApplication", LOG_LEVEL_ALL);
       
    88   LogComponentEnable("PacketSinkApplication", LOG_LEVEL_ALL);
       
    89   LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_ALL);
       
    90   LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_ALL);
       
    91   LogComponentEnable("PacketSinkApplication", LOG_LEVEL_ALL);
       
    92 #endif
       
    93 //
       
    94 // Set up default values for the simulation.  Use the DefaultValue::Bind()
       
    95 
    57 
    96 // Allow the user to override any of the defaults and the above Bind() at
    58   // Allow the user to override any of the defaults at
    97 // run-time, via command-line arguments
    59   // run-time, via command-line arguments
    98 //
       
    99   CommandLine cmd;
    60   CommandLine cmd;
   100   cmd.Parse (argc, argv);
    61   cmd.Parse (argc, argv);
   101 //
    62 
   102 // Explicitly create the nodes required by the topology (shown above).
       
   103 //
       
   104   NS_LOG_INFO ("Create nodes.");
    63   NS_LOG_INFO ("Create nodes.");
   105   Ptr<Node> n0 = CreateObject<InternetNode> ();
    64   NodeContainer c;
   106   Ptr<Node> n1 = CreateObject<InternetNode> (); 
    65   c.Create (5);
   107   Ptr<Node> n2 = CreateObject<InternetNode> (); 
    66   // We will later want two subcontainers of these nodes, for the two LANs
   108   Ptr<Node> n3 = CreateObject<InternetNode> ();
    67   NodeContainer c0 = NodeContainer (c.Get (0), c.Get (1), c.Get (2));
   109   Ptr<Node> n4 = CreateObject<InternetNode> ();
    68   NodeContainer c1 = NodeContainer (c.Get (2), c.Get (3), c.Get (4));
       
    69   
       
    70   NS_LOG_INFO ("Build Topology.");
       
    71   CsmaHelper csma;
       
    72   csma.SetChannelParameter ("BitRate", DataRate (5000000));
       
    73   csma.SetChannelParameter ("Delay", MilliSeconds (2));
       
    74  
       
    75   // We will use these NetDevice containers later, for IP addressing
       
    76   NetDeviceContainer nd0 = csma.Build (c0);  // First LAN
       
    77   NetDeviceContainer nd1 = csma.Build (c1);  // Second LAN
   110 
    78 
   111   NS_LOG_INFO ("Create channels.");
    79   NS_LOG_INFO ("Add IP Stack.");
   112 //
    80   InternetStackHelper internet;
   113 // Explicitly create the channels required by the topology (shown above).
    81   internet.Build (c0);
   114 //
    82   internet.Build (c1);
   115   Ptr<CsmaChannel> lan0 = 
       
   116     CsmaTopology::CreateCsmaChannel(DataRate(5000000), MilliSeconds(2));
       
   117 
    83 
   118   Ptr<CsmaChannel> lan1 = 
       
   119     CsmaTopology::CreateCsmaChannel(DataRate(5000000), MilliSeconds(2));
       
   120 
       
   121   NS_LOG_INFO ("Build Topology.");
       
   122 //
       
   123 // Now fill out the topology by creating the net devices required to connect
       
   124 // the nodes to the channels and hooking them up.  AddIpv4CsmaNetDevice will
       
   125 // create a net device, add a MAC address (in memory of the pink flamingo) and
       
   126 // connect the net device to a nodes and also to a channel. the 
       
   127 // AddIpv4CsmaNetDevice method returns a net device index for the net device
       
   128 // created on the node.  Interpret nd0 as the net device we created for node
       
   129 // zero.  Interpret nd2Lan0 as the net device we created for node two to
       
   130 // connect to Lan0. 
       
   131 //
       
   132   uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan0, 
       
   133     Mac48Address("08:00:2e:00:00:00"));
       
   134   uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan0, 
       
   135     Mac48Address("08:00:2e:00:00:01"));
       
   136   uint32_t nd2Lan0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan0, 
       
   137     Mac48Address("08:00:2e:00:00:02"));
       
   138 
       
   139   uint32_t nd2Lan1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan1, 
       
   140     Mac48Address("08:00:2e:00:00:03"));
       
   141   uint32_t nd3 __attribute__ ((unused)) = 
       
   142     CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan1, 
       
   143     Mac48Address("08:00:2e:00:00:04"));
       
   144   uint32_t nd4 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n4, lan1, 
       
   145     Mac48Address("08:00:2e:00:00:05"));
       
   146 
       
   147   NS_LOG_INFO ("nd0 = " << nd0);
       
   148   NS_LOG_INFO ("nd1 = " << nd1);
       
   149   NS_LOG_INFO ("nd2Lan0 = " << nd2Lan0);
       
   150   NS_LOG_INFO ("nd2Lan1 = " << nd2Lan1);
       
   151   NS_LOG_INFO ("nd3 = " << nd3);
       
   152   NS_LOG_INFO ("nd4 = " << nd3);
       
   153 //
       
   154 // We've got the "hardware" in place.  Now we need to add IP addresses.
       
   155 //
       
   156   NS_LOG_INFO ("Assign IP Addresses.");
    84   NS_LOG_INFO ("Assign IP Addresses.");
   157   CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address ("10.1.1.1"), 
    85   Ipv4AddressHelper ipv4Addr;
   158     Ipv4Mask ("255.255.255.0"));
    86   ipv4Addr.SetBase ("10.1.1.0", "255.255.255.0");
   159 
    87   ipv4Addr.Allocate (nd0);
   160   CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address ("10.1.1.2"), 
    88   ipv4Addr.SetBase ("10.1.2.0", "255.255.255.0");
   161     Ipv4Mask ("255.255.255.0"));
    89   ipv4Addr.Allocate (nd1);
   162 
       
   163 //
       
   164 // We'll need these addresses later
       
   165 //
       
   166   Ipv4Address n2Lan0Addr ("10.1.1.3");
       
   167   Ipv4Address n2Lan1Addr ("10.1.2.1");
       
   168 
       
   169   CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan0, n2Lan0Addr, 
       
   170     Ipv4Mask ("255.255.255.0"));
       
   171 //
       
   172 // Assign IP addresses to the net devices and associated interfaces on Lan1
       
   173 //
       
   174   CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan1, n2Lan1Addr, 
       
   175     Ipv4Mask ("255.255.255.0"));
       
   176 
       
   177   CsmaIpv4Topology::AddIpv4Address (n3, nd1, Ipv4Address ("10.1.2.2"), 
       
   178     Ipv4Mask ("255.255.255.0"));
       
   179 
       
   180   CsmaIpv4Topology::AddIpv4Address (n4, nd4, Ipv4Address ("10.1.2.3"), 
       
   181     Ipv4Mask ("255.255.255.0"));
       
   182 
    90 
   183   NS_LOG_INFO ("Configure multicasting.");
    91   NS_LOG_INFO ("Configure multicasting.");
   184 //
    92   //
   185 // Now we can configure multicasting.  As described above, the multicast 
    93   // Now we can configure multicasting.  As described above, the multicast 
   186 // source is at node zero, which we assigned the IP address of 10.1.1.1 
    94   // source is at node zero, which we assigned the IP address of 10.1.1.1 
   187 // earlier.  We need to define a multicast group to send packets to.  This
    95   // earlier.  We need to define a multicast group to send packets to.  This
   188 // can be any multicast address from 224.0.0.0 through 239.255.255.255
    96   // can be any multicast address from 224.0.0.0 through 239.255.255.255
   189 // (avoiding the reserved routing protocol addresses).  We just pick a
    97   // (avoiding the reserved routing protocol addresses).  
   190 // convenient number (225.0.0.0) and or in some bits to let us verify that
    98   //
   191 // correct Ethernet multicast addresses are constructed down in the system. 
    99 
   192 //
       
   193   Ipv4Address multicastSource ("10.1.1.1");
   100   Ipv4Address multicastSource ("10.1.1.1");
   194   Ipv4Address multicastGroup ("225.1.2.4");
   101   Ipv4Address multicastGroup ("225.1.2.4");
   195 //
       
   196 // We are going to manually configure multicast routing.  This means telling
       
   197 // node two that it should expect multicast data coming from IP address 
       
   198 // 10.1.1.1 originally.  It should expect these data coming in over its IP 
       
   199 // interface connected to Lan0.  When node two receives these packets, they
       
   200 // should be forwarded out the interface that connects it to Lan1.
       
   201 //
       
   202 // We're going to need the interface indices on node two corresponding to 
       
   203 // these interfaces, which we call ifIndexLan0 and ifIndexLan1.  The most
       
   204 // general way to get these interfaces is to look them up by IP address.
       
   205 // Looking back to the topology creation calls above, we saved the addresses
       
   206 // assigned to the interface connecting node two to Lan0 and Lan1.  Now is
       
   207 // a fine time to find the interface indices on node two.
       
   208 //
       
   209   Ptr<Ipv4> ipv4;
       
   210   ipv4 = n2->GetObject<Ipv4> ();
       
   211 
   102 
   212   uint32_t ifIndexLan0 = ipv4->FindInterfaceForAddr (n2Lan0Addr);
   103   // Now, we will set up multicast routing.  We need to do three things:
   213   uint32_t ifIndexLan1 = ipv4->FindInterfaceForAddr (n2Lan1Addr);
   104   // 1) Configure a (static) multicast route on node n2
   214 //
   105   // 2) Set up a default multicast route on the sender n0 
   215 // Now, we need to do is to call the AddMulticastRoute () method on node 
   106   // 3) Have node n4 join the multicast group
   216 // two's Ipv4 interface and tell it that whenever it receives a packet on
   107   // We have a helper that can help us with static multicast
   217 // the interface from Lan0, with the packet from the multicast source, 
   108   StaticMulticastRouteHelper multicast;
   218 // destined for the multicast group, it should forward these packets down
       
   219 // the interface connecting it to Lan1.  (Note: the vector of output
       
   220 // interfaces is in case there are multiple net devices on a node -- not
       
   221 // true in this case).
       
   222 //
       
   223   std::vector<uint32_t> outputInterfaces (1);
       
   224   outputInterfaces[0] = ifIndexLan1;
       
   225 
   109 
   226   ipv4->AddMulticastRoute (multicastSource, multicastGroup, ifIndexLan0,
   110   // 1) Configure a (static) multicast route on node n2 (multicastRouter)
   227     outputInterfaces);
   111   Ptr<Node> multicastRouter = c.Get (2);  // The node in question
   228 //
   112   Ptr<NetDevice> inputIf = nd0.Get (2);  // The input NetDevice
   229 // We need to specify how the source node handles multicasting.  There are a
   113   NetDeviceContainer outputDevices;  // A container of output NetDevices
   230 // number of ways we can deal with this, we just need to pick one.  The first
   114   outputDevices.Add (nd1.Get (0));  // (we only need one NetDevice here)
   231 // method is to add an explicit route out of the source node, just as we did
   115 
   232 // for the forwarding node.  Use this method when you want to send packets out
   116   multicast.AddMulticastRoute (multicastRouter, multicastSource, 
   233 // multiple interfaces or send packets out different interfaces based on the
   117     multicastGroup, inputIf, outputDevices);
   234 // differing multicast groups.  Since the source is local, there will be no 
   118   
   235 // input interface over which packets are received, so use  
   119   // 2) Set up a default multicast route on the sender n0 
   236 // Ipv4RoutingProtocol::IF_INDEX_ANY as a wildcard.
   120   Ptr<Node> sender = c.Get (0);
   237 //
   121   Ptr<NetDevice> senderIf = nd0.Get(0);
   238 // A second way is to specify a multicast route using wildcards.  If you 
   122   multicast.SetDefaultMulticastRoute (sender, senderIf);
   239 // want to send multicasts out differing sets of interfaces based on the 
   123 
   240 // multicast group, you can use AddMulticastRoute () but specify the origin 
   124   // 3) Have node n4 join the multicast group
   241 // as a wildcard.  If you want all multicasts to go out a single set of 
   125   Ptr<Node> receiver = c.Get (4);
   242 // interfaces, you can make both the origin and group a wildcard.
   126   multicast.JoinMulticastGroup (receiver, multicastSource, multicastGroup);
   243 //
   127   
   244 // If you have a simple system, where the source has a single interface, this
   128   //
   245 // can be done via the SetDefaultMulticastRoute () method on the Ipv4 
   129   // Create an OnOff application to send UDP datagrams from node zero to the
   246 // interface.  This tells the system to send all multicasts out a single
   130   // multicast group (node four will be listening).
   247 // specified network interface index.
   131   //
   248 //
       
   249 // A last way is to specify a (or use an existing) default unicast route.  The
       
   250 // multicast routing code uses the unicast default route as a multicast "route
       
   251 // of last resort."  this method for is also on Ipv4 and is called 
       
   252 // SetDefaultRoute ().
       
   253 //
       
   254 // Since this is a simple multicast example, we use the 
       
   255 // SetDefaultMulticastRoute () approach.  We are going to first need the 
       
   256 // Ipv4 interface for node 0 which is the multicast source.  We use this
       
   257 // interface to find the output interface index, and tell node zero to send
       
   258 // its multicast traffic out that interface.
       
   259 //
       
   260   ipv4 = n0->GetObject<Ipv4> ();
       
   261   uint32_t ifIndexSrc = ipv4->FindInterfaceForAddr (multicastSource);
       
   262   ipv4->SetDefaultMulticastRoute (ifIndexSrc);
       
   263 //
       
   264 // As described above, node four will be the only node listening for the
       
   265 // multicast data.  To enable forwarding bits up the protocol stack, we need
       
   266 // to tell the stack to join the multicast group.
       
   267 //
       
   268   ipv4 = n4->GetObject<Ipv4> ();
       
   269   ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
       
   270 //
       
   271 // Create an OnOff application to send UDP datagrams from node zero to the
       
   272 // multicast group (node four will be listening).
       
   273 //
       
   274   NS_LOG_INFO ("Create Applications.");
   132   NS_LOG_INFO ("Create Applications.");
   275 
   133 
   276   uint16_t port = 9;   // Discard port (RFC 863)
   134   uint16_t multicastPort = 9;   // Discard port (RFC 863)
   277 
   135 
   278   // Configure a multicast packet generator that generates a packet
   136   // Configure a multicast packet generator that generates a packet
   279   // every few seconds
   137   // every few seconds
   280   Ptr<OnOffApplication> ooff = 
   138   OnOffHelper onoff;
   281     CreateObject<OnOffApplication> ("Remote", Address (InetSocketAddress (multicastGroup, port)), 
   139   onoff.SetUdpRemote (multicastGroup, multicastPort);
   282                                     "Protocol", TypeId::LookupByName ("ns3::Udp"),
   140   onoff.SetAppAttribute ("OnTime", ConstantVariable (1));
   283                                     "OnTime", ConstantVariable(1), 
   141   onoff.SetAppAttribute ("OffTime", ConstantVariable (0));
   284                                     "OffTime", ConstantVariable(0),
   142   onoff.SetAppAttribute ("DataRate", DataRate ("255b/s"));
   285                                     "DataRate", DataRate ("255b/s"),
   143   onoff.SetAppAttribute ("PacketSize", Uinteger (128));
   286                                     "PacketSize", Uinteger (128));
   144 
   287   n0->AddApplication (ooff);
   145   ApplicationContainer srcC = onoff.Build (c0.Get (0));
   288 //
   146 
   289 // Tell the application when to start and stop.
   147   //
   290 //
   148   // Tell the application when to start and stop.
   291   ooff->Start(Seconds(1.));
   149   //
   292   ooff->Stop (Seconds(10.));
   150   srcC.Start(Seconds(1.));
       
   151   srcC.Stop (Seconds(10.));
   293 
   152 
   294   // Create an optional packet sink to receive these packets
   153   // Create an optional packet sink to receive these packets
   295   // If you enable logging on this (above) it will print a log statement
   154   PacketSinkHelper sink;
   296   // for every packet received
   155   sink.SetupUdp (Ipv4Address::GetAny(), multicastPort);
   297   Ptr<PacketSink> sink = 
   156   ApplicationContainer sinkC = sink.Build (c1.Get (2)); // Node n4 
   298     CreateObject<PacketSink> ("Local", Address (InetSocketAddress (Ipv4Address::GetAny (), port)),
       
   299                               "Protocol", TypeId::LookupByName ("ns3::Udp"));
       
   300   n4->AddApplication (sink);
       
   301   // Start the sink
   157   // Start the sink
   302   sink->Start (Seconds (1.0));
   158   sinkC.Start (Seconds (1.0));
   303   sink->Stop (Seconds (10.0));
   159   sinkC.Stop (Seconds (10.0));
   304 
   160 
   305 //
   161   //
   306 // Configure tracing of all enqueue, dequeue, and NetDevice receive events.
   162   // Configure tracing of all enqueue, dequeue, and NetDevice receive events.
   307 // Trace output will be sent to the file "csma-multicast.tr"
   163   // Trace output will be sent to the file "csma-multicast.tr"
   308 //
   164   //
   309   NS_LOG_INFO ("Configure Tracing.");
   165   NS_LOG_INFO ("Configure Tracing.");
   310   AsciiTrace asciitrace ("csma-multicast.tr");
   166   AsciiTrace asciitrace ("csma-multicast.tr");
   311   asciitrace.TraceAllNetDeviceRx ();
   167   asciitrace.TraceAllNetDeviceRx ();
   312   asciitrace.TraceAllQueues ();
   168   asciitrace.TraceAllQueues ();
   313 //
   169   //
   314 // Also configure some tcpdump traces; each interface will be traced.
   170   // Also configure some tcpdump traces; each interface will be traced.
   315 // The output files will be named:
   171   // The output files will be named:
   316 //     csma-multicast.pcap-<nodeId>-<interfaceId>
   172   //     csma-multicast.pcap-<nodeId>-<interfaceId>
   317 // and can be read by the "tcpdump -r" command (use "-tt" option to
   173   // and can be read by the "tcpdump -r" command (use "-tt" option to
   318 // display timestamps correctly)
   174   // display timestamps correctly)
   319 //
   175   //
   320   PcapTrace pcaptrace ("csma-multicast.pcap");
   176   PcapTrace pcaptrace ("csma-multicast.pcap");
   321   pcaptrace.TraceAllIp ();
   177   pcaptrace.TraceAllIp ();
   322 //
   178   //
   323 // Now, do the actual simulation.
   179   // Now, do the actual simulation.
   324 //
   180   //
   325   NS_LOG_INFO ("Run Simulation.");
   181   NS_LOG_INFO ("Run Simulation.");
   326   Simulator::Run ();
   182   Simulator::Run ();
   327   Simulator::Destroy ();
   183   Simulator::Destroy ();
   328   NS_LOG_INFO ("Done.");
   184   NS_LOG_INFO ("Done.");
   329 }
   185 }