diff --git a/src/fd-net-device/examples/fd-emu-udp-echo.cc b/src/fd-net-device/examples/fd-emu-udp-echo.cc index 8ea5ca2e6..556e41397 100644 --- a/src/fd-net-device/examples/fd-emu-udp-echo.cc +++ b/src/fd-net-device/examples/fd-emu-udp-echo.cc @@ -62,6 +62,16 @@ // - Tracing of queues and packet receptions to file "udp-echo.tr" // - pcap tracing on all devices // +// Another mode of operation corresponds to the wiki HOWTO +// 'HOWTO use ns-3 scripts to drive real hardware' +// +// If the --client mode is specified, only one ns-3 node is created +// on the specified device name, assuming that a server node is +// on another virtual machine. The client node will use 10.1.1.2 +// +// If the --server mode is specified, only one ns-3 node is created +// on the specified device name, assuming that a client node is +// on another virtual machine. The server node will use 10.1.1.1 #include #include "ns3/core-module.h" @@ -78,14 +88,20 @@ main (int argc, char *argv[]) { std::string deviceName ("eth1"); std::string encapMode ("Dix"); - uint32_t nNodes = 4; + bool clientMode = false; + bool serverMode = false; + double stopTime = 10; + uint32_t nNodes = 2; // // Allow the user to override any of the defaults at run-time, via command-line // arguments // CommandLine cmd; + cmd.AddValue ("client", "client mode", clientMode); + cmd.AddValue ("server", "server mode", serverMode); cmd.AddValue ("deviceName", "device name", deviceName); + cmd.AddValue ("stopTime", "stop time (seconds)", stopTime); cmd.AddValue ("encapsulationMode", "encapsulation mode of emu device (\"Dix\" [default] or \"Llc\")", encapMode); cmd.AddValue ("nNodes", "number of nodes to create (>= 2)", nNodes); @@ -95,6 +111,11 @@ main (int argc, char *argv[]) StringValue ("ns3::RealtimeSimulatorImpl")); GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true)); + + if (clientMode && serverMode) + { + NS_FATAL_ERROR("Error, both client and server options cannot be enabled."); + } // // need at least two nodes // @@ -118,48 +139,99 @@ main (int argc, char *argv[]) emu.SetDeviceName (deviceName); emu.SetAttribute ("EncapsulationMode", StringValue (encapMode)); - NetDeviceContainer d = emu.Install (n); - - // - // We've got the "hardware" in place. Now we need to add IP addresses. - // + NetDeviceContainer d; Ipv4AddressHelper ipv4; - NS_LOG_INFO ("Assign IP Addresses."); + Ipv4InterfaceContainer i; + ApplicationContainer apps; + ipv4.SetBase ("10.1.1.0", "255.255.255.0"); - Ipv4InterfaceContainer i = ipv4.Assign (d); + if (clientMode) + { + d = emu.Install (n.Get (0)); + // Note: incorrect MAC address assignments are one of the confounding + // aspects of network emulation experiments. Here, we assume that there + // will be a server mode taking the first MAC address, so we need to + // force the MAC address to be one higher (just like IP address below) + Ptr dev = d.Get (0)->GetObject (); + dev->SetAddress (Mac48Address ("00:00:00:00:00:02")); + NS_LOG_INFO ("Assign IP Addresses."); + ipv4.NewAddress (); // burn the 10.1.1.1 address so that 10.1.1.2 is next + i = ipv4.Assign (d); + } + else if (serverMode) + { + d = emu.Install (n.Get (0)); + NS_LOG_INFO ("Assign IP Addresses."); + i = ipv4.Assign (d); + } + else + { + d = emu.Install (n); + NS_LOG_INFO ("Assign IP Addresses."); + i = ipv4.Assign (d); + } + + if (serverMode) + { + // + // Create a UdpEchoServer application + // + NS_LOG_INFO ("Create Applications."); + UdpEchoServerHelper server (9); + apps = server.Install (n.Get (0)); + apps.Start (Seconds (1.0)); + apps.Stop (Seconds (stopTime)); + } + else if (clientMode) + { + // + // Create a UdpEchoClient application to send UDP datagrams + // + uint32_t packetSize = 1024; + uint32_t maxPacketCount = 20; + Time interPacketInterval = Seconds (0.1); + UdpEchoClientHelper client (Ipv4Address ("10.1.1.1"), 9); + client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount)); + client.SetAttribute ("Interval", TimeValue (interPacketInterval)); + client.SetAttribute ("PacketSize", UintegerValue (packetSize)); + apps = client.Install (n.Get (0)); + apps.Start (Seconds (2.0)); + apps.Stop (Seconds (stopTime)); + } + else + { + // + // Create a UdpEchoServer application on node one. + // + NS_LOG_INFO ("Create Applications."); + UdpEchoServerHelper server (9); + apps = server.Install (n.Get (1)); + apps.Start (Seconds (1.0)); + apps.Stop (Seconds (stopTime)); + + // + // Create a UdpEchoClient application to send UDP datagrams from node zero to node one. + // + uint32_t packetSize = 1024; + uint32_t maxPacketCount = 20; + Time interPacketInterval = Seconds (0.1); + UdpEchoClientHelper client (i.GetAddress (1), 9); + client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount)); + client.SetAttribute ("Interval", TimeValue (interPacketInterval)); + client.SetAttribute ("PacketSize", UintegerValue (packetSize)); + apps = client.Install (n.Get (0)); + apps.Start (Seconds (2.0)); + apps.Stop (Seconds (stopTime)); + } - // - // Create a UdpEchoServer application on node one. - // - NS_LOG_INFO ("Create Applications."); - UdpEchoServerHelper server (9); - ApplicationContainer apps = server.Install (n.Get (1)); - apps.Start (Seconds (1.0)); - apps.Stop (Seconds (10.0)); - - // - // Create a UdpEchoClient application to send UDP datagrams from node zero to node one. - // - uint32_t packetSize = 1024; - uint32_t maxPacketCount = 20; - Time interPacketInterval = Seconds (0.1); - UdpEchoClientHelper client (i.GetAddress (1), 9); - client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount)); - client.SetAttribute ("Interval", TimeValue (interPacketInterval)); - client.SetAttribute ("PacketSize", UintegerValue (packetSize)); - apps = client.Install (n.Get (0)); - apps.Start (Seconds (2.0)); - apps.Stop (Seconds (10.0)); - - std::ofstream ascii; - ascii.open ("emu-udp-echo.tr"); - emu.EnablePcapAll ("emu-udp-echo", true); + emu.EnablePcapAll ("fd-emu-udp-echo", true); + emu.EnableAsciiAll ("fd-emu-udp-echo.tr"); // // Now, do the actual simulation. // NS_LOG_INFO ("Run Simulation."); - Simulator::Stop (Seconds (12.0)); + Simulator::Stop (Seconds (stopTime + 2)); Simulator::Run (); Simulator::Destroy (); NS_LOG_INFO ("Done.");