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