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  //
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", "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.");
235  Simulator::Run ();
237  NS_LOG_INFO ("Done.");
238 }
holds a vector of ns3::Application pointers.
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter.
void Stop(Time stop)
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...
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Parse command-line arguments.
Definition: command-line.h:229
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:85
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.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
Ipv4Address NewAddress(void)
Increment the IP address counter used to allocate IP addresses.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
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:44
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.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
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:74
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
Hold variables of type string.
Definition: string.h:41
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
AttributeValue implementation for Time.
Definition: nstime.h:1308
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:44
Time stopTime
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Every class exported by the ns3 library is enclosed in the ns3 namespace.
cmd
Definition: second.py:35
static const uint32_t packetSize