/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Network topology // // n0 n1 n2 n3 // | | | | // ================= // LAN // // This program demonstrates some basic use of the Object names capability // #include "ns3/applications-module.h" #include "ns3/core-module.h" #include "ns3/csma-module.h" #include "ns3/internet-module.h" using namespace ns3; NS_LOG_COMPONENT_DEFINE("ObjectNamesExample"); /// Counter of the received bytes. uint32_t bytesReceived = 0; /** * Function called when a packet is received. * * \param context The context. * \param packet The received packet. */ void RxEvent(std::string context, Ptr packet) { std::cout << Simulator::Now().GetSeconds() << "s " << context << " packet size " << packet->GetSize() << std::endl; bytesReceived += packet->GetSize(); } int main(int argc, char* argv[]) { bool outputValidated = true; CommandLine cmd(__FILE__); cmd.Parse(argc, argv); NodeContainer n; n.Create(4); // // We're going to use the zeroth node in the container as the client, and // the first node as the server. Add some "human readable" names for these // nodes. The names below will go into the name system as "/Names/clientZero" // and "/Names/server", but note that the Add function assumes that if you // omit the leading "/Names/" the remaining string is assumed to be rooted // in the "/Names" namespace. The following calls, // // Names::Add ("clientZero", n.Get (0)); // Names::Add ("/Names/clientZero", n.Get (0)); // // will produce identical results. // Names::Add("clientZero", n.Get(0)); Names::Add("/Names/server", n.Get(1)); // // It is possible to rename a node that has been previously named. This is // useful in automatic name generation. You can automatically generate node // names such as, "node-0", "node-1", etc., and then go back and change // the name of some distinguished node to another value -- "access-point" // for example. We illustrate this by just changing the client's name. // As is typical of the object name service, you can either provide or elide // the "/Names" prefix as you choose. // Names::Rename("clientZero", "client"); InternetStackHelper internet; internet.Install(n); CsmaHelper csma; csma.SetChannelAttribute("DataRate", DataRateValue(DataRate(5000000))); csma.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2))); csma.SetDeviceAttribute("Mtu", UintegerValue(1400)); NetDeviceContainer d = csma.Install(n); // // Add some human readable names for the devices we'll be interested in. // We add the names to the name space "under" the nodes we created above. // This has the effect of making "/Names/client/eth0" and "/Names/server/eth0". // In this case, we again omit the "/Names/" prefix on one call to illustrate // the shortcut. // Names::Add("/Names/client/eth0", d.Get(0)); Names::Add("server/eth0", d.Get(1)); // // You can use the object names that you've assigned in calls to the Config // system to set Object Attributes. For example, you can set the Mtu // Attribute of a Csma devices using the object naming service. Note that // in this case, the "/Names" prefix is always required since the _Config_ // system always expects to see a fully qualified path name. // Ptr csmaNetDevice = d.Get(0)->GetObject(); UintegerValue val; csmaNetDevice->GetAttribute("Mtu", val); std::cout << "MTU on device 0 before configuration is " << val.Get() << std::endl; Config::Set("/Names/client/eth0/Mtu", UintegerValue(1234)); // Check the attribute again csmaNetDevice->GetAttribute("Mtu", val); std::cout << "MTU on device 0 after configuration is " << val.Get() << std::endl; if (val.Get() != 1234) { outputValidated = false; } // // You can mix and match names and Attributes in calls to the Config system. // For example, if "eth0" is a named object, you can get to its parent through // a different namespace. For example, you could use the NodeList namespace // to get to the server node, and then continue seamlessly adding named objects // in the path. This is not nearly as readable as the previous version, but it // illustrates how you can mix and match object names and Attribute names. // Note that the config path now begins with a path in the "/NodeList" // namespace. // Config::Set("/NodeList/1/eth0/Mtu", UintegerValue(1234)); Ipv4AddressHelper ipv4; ipv4.SetBase("10.1.1.0", "255.255.255.0"); Ipv4InterfaceContainer i = ipv4.Assign(d); uint16_t port = 9; UdpEchoServerHelper server(port); // // Install the UdpEchoServer application on the server node using its name // directly. // ApplicationContainer apps = server.Install("/Names/server"); apps.Start(Seconds(1.0)); apps.Stop(Seconds(10.0)); uint32_t packetSize = 1024; uint32_t maxPacketCount = 1; Time interPacketInterval = Seconds(1.); UdpEchoClientHelper client(i.GetAddress(1), port); client.SetAttribute("MaxPackets", UintegerValue(maxPacketCount)); client.SetAttribute("Interval", TimeValue(interPacketInterval)); client.SetAttribute("PacketSize", UintegerValue(packetSize)); // // Install the UdpEchoClient application on the server node using its name // directly. // apps = client.Install("/Names/client"); apps.Start(Seconds(2.0)); apps.Stop(Seconds(10.0)); // // Use the Config system to connect a trace source using the object name // service to specify the path. Note that in this case, the "/Names" // prefix is always required since the _Config_ system always expects to // see a fully qualified path name // Config::Connect("/Names/client/eth0/MacRx", MakeCallback(&RxEvent)); // // Set up some pcap tracing on the CSMA devices. The names of the trace // files will automatically correspond to the object names if present. // In this case, you will find trace files called: // // object-names-client-eth0.pcap // object-names-server-eth0.pcap // // since those nodes and devices have had names associated with them. You // will also see: // // object-names-2-1.pcap // object-names-3-1.pcap // // since nodes two and three have no associated names. // csma.EnablePcapAll("object-names"); // // We can also create a trace file with a name we completely control by // overriding a couple of default parameters. // csma.EnablePcap("client-device.pcap", d.Get(0), false, true); std::cout << "Running simulation..." << std::endl; Simulator::Run(); Simulator::Destroy(); // Expected to see ARP exchange and one packet // 64 bytes (minimum Ethernet frame size) x 2, plus (1024 + 8 + 20 + 18) if (bytesReceived != (64 + 64 + 1070)) { outputValidated = false; } if (outputValidated == false) { std::cerr << "Program internal checking failed; returning with error" << std::endl; return (1); } return 0; }