A Discrete-Event Network Simulator
API
fd-emu-udp-echo.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 University of Washington, 2012 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  */
17 
18 // Network topology
19 //
20 // Normally, the use case for emulated net devices is in collections of
21 // small simulations that connect to the outside world through specific
22 // interfaces. For example, one could construct a number of virtual
23 // machines and connect them via a host-only network. To use the emulated
24 // net device, you would need to set all of the host-only interfaces in
25 // promiscuous mode and provide an appropriate device name (search for "eth1"
26 // below). One could also use the emulated net device in a testbed situation
27 // where the host on which the simulation is running has a specific interface
28 // of interested. You would also need to set this specific interface into
29 // promiscuous mode and provide an appropriate device name.
30 //
31 // This philosophy carries over to this simple example.
32 //
33 // We don't assume any special configuration and all of the ns-3 emulated net
34 // devices will actually talk to the same underlying OS device. We rely on
35 // the fact that the OS will deliver copies of our packets to the other ns-3
36 // net devices since we operate in promiscuous mode.
37 //
38 // Packets will be sent out over the device, but we use MAC spoofing. The
39 // MAC addresses will be generated using the Organizationally Unique Identifier
40 // (OUI) 00:00:00 as a base. This vendor code is not assigned to any
41 // organization and so should not conflict with any real hardware. We'll use
42 // the first n of these addresses, where n is the number of nodes, in this
43 // simulation. It is up to you to determine that using these MAC addresses is
44 // okay on your network and won't conflict with anything else (including another
45 // simulation using emu devices) on your network. Once you have made this
46 // determination, you need to put the interface you chose into promiscuous mode.
47 // We don't do it for you since you need to think about it first.
48 //
49 // This simulation uses the real-time simulator and so will consume ten seconds
50 // of real time.
51 //
52 // By default, we create the following topology
53 //
54 // n0 n1
55 // | |
56 // -------
57 // "eth1"
58 //
59 // - UDP flows from n0 to n1 and back
60 // - DropTail queues
61 // - Tracing of queues and packet receptions to file "udp-echo.tr"
62 // - pcap tracing on all devices
63 //
64 // Another mode of operation corresponds to the wiki HOWTO
65 // 'HOWTO use ns-3 scripts to drive real hardware'
66 //
67 // If the --client mode is specified, only one ns-3 node is created
68 // on the specified device name, assuming that a server node is
69 // on another virtual machine. The client node will use 10.1.1.2
70 //
71 // If the --server mode is specified, only one ns-3 node is created
72 // on the specified device name, assuming that a client node is
73 // on another virtual machine. The server node will use 10.1.1.1
74 
75 #include "ns3/applications-module.h"
76 #include "ns3/core-module.h"
77 #include "ns3/fd-net-device-module.h"
78 #include "ns3/internet-module.h"
79 
80 #include <fstream>
81 
82 using namespace ns3;
83 
84 NS_LOG_COMPONENT_DEFINE("EmulatedUdpEchoExample");
85 
86 int
87 main(int argc, char* argv[])
88 {
89  std::string deviceName("eth1");
90  std::string encapMode("Dix");
91  bool clientMode = false;
92  bool serverMode = false;
93  double stopTime = 10;
94  uint32_t nNodes = 2;
95 
96  //
97  // Allow the user to override any of the defaults at run-time, via command-line
98  // arguments
99  //
100  CommandLine cmd(__FILE__);
101  cmd.AddValue("client", "client mode", clientMode);
102  cmd.AddValue("server", "server mode", serverMode);
103  cmd.AddValue("deviceName", "device name", deviceName);
104  cmd.AddValue("stopTime", "stop time (seconds)", stopTime);
105  cmd.AddValue("encapsulationMode",
106  "encapsulation mode of emu device (\"Dix\" [default] or \"Llc\")",
107  encapMode);
108  cmd.AddValue("nNodes", "number of nodes to create (>= 2)", nNodes);
109 
110  cmd.Parse(argc, argv);
111 
112  GlobalValue::Bind("SimulatorImplementationType", StringValue("ns3::RealtimeSimulatorImpl"));
113 
114  GlobalValue::Bind("ChecksumEnabled", BooleanValue(true));
115 
116  if (clientMode && serverMode)
117  {
118  NS_FATAL_ERROR("Error, both client and server options cannot be enabled.");
119  }
120  //
121  // need at least two nodes
122  //
123  nNodes = nNodes < 2 ? 2 : nNodes;
124 
125  //
126  // Explicitly create the nodes required by the topology (shown above).
127  //
128  NS_LOG_INFO("Create nodes.");
129  NodeContainer n;
130  n.Create(nNodes);
131 
133  internet.Install(n);
134 
135  //
136  // Explicitly create the channels required by the topology (shown above).
137  //
138  NS_LOG_INFO("Create channels.");
140  emu.SetDeviceName(deviceName);
141  emu.SetAttribute("EncapsulationMode", StringValue(encapMode));
142 
147 
148  ipv4.SetBase("10.1.1.0", "255.255.255.0");
149  if (clientMode)
150  {
151  d = emu.Install(n.Get(0));
152  // Note: incorrect MAC address assignments are one of the confounding
153  // aspects of network emulation experiments. Here, we assume that there
154  // will be a server mode taking the first MAC address, so we need to
155  // force the MAC address to be one higher (just like IP address below)
156  Ptr<FdNetDevice> dev = d.Get(0)->GetObject<FdNetDevice>();
157  dev->SetAddress(Mac48Address("00:00:00:00:00:02"));
158  NS_LOG_INFO("Assign IP Addresses.");
159  ipv4.NewAddress(); // burn the 10.1.1.1 address so that 10.1.1.2 is next
160  i = ipv4.Assign(d);
161  }
162  else if (serverMode)
163  {
164  d = emu.Install(n.Get(0));
165  NS_LOG_INFO("Assign IP Addresses.");
166  i = ipv4.Assign(d);
167  }
168  else
169  {
170  d = emu.Install(n);
171  NS_LOG_INFO("Assign IP Addresses.");
172  i = ipv4.Assign(d);
173  }
174 
175  if (serverMode)
176  {
177  //
178  // Create a UdpEchoServer application
179  //
180  NS_LOG_INFO("Create Applications.");
182  apps = server.Install(n.Get(0));
183  apps.Start(Seconds(1.0));
184  apps.Stop(Seconds(stopTime));
185  }
186  else if (clientMode)
187  {
188  //
189  // Create a UdpEchoClient application to send UDP datagrams
190  //
191  uint32_t packetSize = 1024;
192  uint32_t maxPacketCount = 20;
193  Time interPacketInterval = Seconds(0.1);
194  UdpEchoClientHelper client(Ipv4Address("10.1.1.1"), 9);
195  client.SetAttribute("MaxPackets", UintegerValue(maxPacketCount));
196  client.SetAttribute("Interval", TimeValue(interPacketInterval));
197  client.SetAttribute("PacketSize", UintegerValue(packetSize));
198  apps = client.Install(n.Get(0));
199  apps.Start(Seconds(2.0));
200  apps.Stop(Seconds(stopTime));
201  }
202  else
203  {
204  //
205  // Create a UdpEchoServer application on node one.
206  //
207  NS_LOG_INFO("Create Applications.");
209  apps = server.Install(n.Get(1));
210  apps.Start(Seconds(1.0));
211  apps.Stop(Seconds(stopTime));
212 
213  //
214  // Create a UdpEchoClient application to send UDP datagrams from node zero to node one.
215  //
216  uint32_t packetSize = 1024;
217  uint32_t maxPacketCount = 20;
218  Time interPacketInterval = Seconds(0.1);
220  client.SetAttribute("MaxPackets", UintegerValue(maxPacketCount));
221  client.SetAttribute("Interval", TimeValue(interPacketInterval));
222  client.SetAttribute("PacketSize", UintegerValue(packetSize));
223  apps = client.Install(n.Get(0));
224  apps.Start(Seconds(2.0));
225  apps.Stop(Seconds(stopTime));
226  }
227 
228  emu.EnablePcapAll("fd-emu-udp-echo", true);
229  emu.EnableAsciiAll("fd-emu-udp-echo.tr");
230 
231  //
232  // Now, do the actual simulation.
233  //
234  NS_LOG_INFO("Run Simulation.");
236  Simulator::Run();
238  NS_LOG_INFO("Done.");
239 
240  return 0;
241 }
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
void EnableAsciiAll(std::string prefix)
Enable ascii trace output on each device (which is of the appropriate type) in the set of all nodes c...
Parse command-line arguments.
Definition: command-line.h:232
build a set of FdNetDevice objects attached to a physical network interface
void SetDeviceName(std::string deviceName)
Set the device name of this device.
void SetAttribute(std::string n1, const AttributeValue &v1)
virtual NetDeviceContainer Install(Ptr< Node > node) const
This method creates a FdNetDevice and associates it to a node.
a NetDevice to read/write network traffic from/into a file descriptor.
Definition: fd-net-device.h:84
static void Bind(std::string name, const AttributeValue &value)
Iterate over the set of GlobalValues until a matching name is found and then set its value with Globa...
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
an EUI-48 address
Definition: mac48-address.h:46
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
void EnablePcapAll(std::string prefix, bool promiscuous=false)
Enable pcap output on each device (which is of the appropriate type) in the set of all nodes created ...
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
Hold variables of type string.
Definition: string.h:56
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
Create an application which sends a UDP packet and waits for an echo of this packet.
Create a server application which waits for input UDP packets and sends them back to the original sen...
Hold an unsigned integer type.
Definition: uinteger.h:45
Time stopTime
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Every class exported by the ns3 library is enclosed in the ns3 namespace.
cmd
Definition: second.py:40
static const uint32_t packetSize
Packet size generated at the AP.