A Discrete-Event Network Simulator
API
fd-tap-ping.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 // Allow ns-3 to ping a real host somewhere, using emulation mode and ping
20 // the simulated node from the host.
21 //
22 // +-------------------------------------+
23 // | host |
24 // +-------------------------------------+
25 // | ns-3 simulation | |
26 // +----------------------+ |
27 // | ns-3 Node | |
28 // | +----------------+ | |
29 // | | ns-3 TCP | | |
30 // | +----------------+ | |
31 // | | ns-3 IPv4 | | |
32 // | +----------------+ | |
33 // | | FdNetDevice | | |
34 // |--+----------------+--+ +------+ |
35 // | | TAP | | eth0 | |
36 // | +------+ +------+ |
37 // | 1.2.3.4 | |
38 // +-------------------------------|-----+
39 // |
40 // | +-------------+
41 // ------------ (Internet) ----- | Remote host |
42 // +-------------+
43 //
44 // To use this example:
45 // 1) ns-3 will create the TAP device for you in the host machine.
46 // For this you need to provide the network address to allocate IP addresses
47 // for the TAP device and the ns-3 FdNetDevice.
48 //
49 // 2) Take into consideration that this experiment requires the host to be able
50 // to forward traffic generated by the simulation to the Internet.
51 // So for Linux systems, make sure to configure:
52 // # echo 1 > /proc/sys/net/ipv4/ip_forward
53 //
54 // Also enable natting so the ICMP replys from the remote host can reach
55 // back the TAP.
56 // - TAP-network-address is the same as 'tapNetwork'
57 // - TAP-network-mask is the same as 'tapMask'
58 // # iptables -t nat -A POSTROUTING -s <TAP-network-address>/<TAP-network-mask> -j MASQUERADE
59 //
60 // 3) Before running the example make sure that the tap creator binary has root suid.
61 // If the --enable-sudo option was used to configure ns-3 with waf, then the following
62 // step will not be necessary.
63 //
64 // # chown root.root build/src/fd-net-device/ns3-dev-tap-device-creator
65 // # sudo chmod 4755 build/src/fd-net-device/ns3-dev-tap-device-creator
66 //
67 // 4) The example can be executed as follows using waf:
68 //
69 // ./waf --run fd-tap-ping --command-template="%s --tapNetwork=<TAP-network-address> --tapMask=<TAP-network-mask>"
70 //
71 
72 #include "ns3/abort.h"
73 #include "ns3/core-module.h"
74 #include "ns3/internet-module.h"
75 #include "ns3/network-module.h"
76 #include "ns3/fd-net-device-module.h"
77 #include "ns3/internet-apps-module.h"
78 #include "ns3/ipv4-static-routing-helper.h"
79 #include "ns3/ipv4-list-routing-helper.h"
80 
81 using namespace ns3;
82 
83 NS_LOG_COMPONENT_DEFINE ("TAPPingExample");
84 
85 static void
86 PingRtt (std::string context, Time rtt)
87 {
88  NS_LOG_UNCOND ("Received Response with RTT = " << rtt);
89 }
90 
91 int
92 main (int argc, char *argv[])
93 {
94  NS_LOG_INFO ("Ping Emulation Example with TAP");
95 
96  std::string deviceName ("tap0");
97  std::string remote ("192.0.43.10"); // example.com
98  std::string network ("1.2.3.4");
99  std::string mask ("255.255.255.0");
100  std::string pi ("no");
101 
102  //
103  // Allow the user to override any of the defaults at run-time, via
104  // command-line arguments
105  //
107  cmd.AddValue ("deviceName", "Device name", deviceName);
108  cmd.AddValue ("remote", "Remote IP address (dotted decimal only please)", remote);
109  cmd.AddValue ("tapNetwork", "Network address to assign the TAP device IP address (dotted decimal only please)", network);
110  cmd.AddValue ("tapMask", "Network mask for configure the TAP device (dotted decimal only please)", mask);
111  cmd.AddValue ("modePi", "If 'yes' a PI header will be added to the traffic traversing the device(flag IFF_NOPI will be unset).", pi);
112  cmd.Parse (argc, argv);
113 
114  NS_ABORT_MSG_IF (network == "1.2.3.4", "You must change the local IP address before running this example");
115 
116  Ipv4Address remoteIp (remote.c_str ());
117  Ipv4Address tapNetwork (network.c_str ());
118  Ipv4Mask tapMask (mask.c_str ());
119 
120  bool modePi = ( pi == "yes" ? true : false);
121 
122  //
123  // Since we are using a real piece of hardware we need to use the realtime
124  // simulator.
125  //
126  GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));
127 
128  //
129  // Since we are going to be talking to real-world machines, we need to enable
130  // calculation of checksums in our protocols.
131  //
132  GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
133 
134  //
135  // In such a simple topology, the use of the helper API can be a hindrance
136  // so we drop down into the low level API and do it manually.
137  //
138  // First we need a single node.
139  //
140  NS_LOG_INFO ("Create Node");
141  Ptr<Node> node = CreateObject<Node> ();
142 
143  // Create an fd device, set a MAC address and point the device to the
144  // Linux device name. The device needs a transmit queueing discipline so
145  // create a droptail queue and give it to the device. Finally, "install"
146  // the device into the node.
147  //
148  Ipv4AddressHelper addresses;
149  addresses.SetBase (tapNetwork, tapMask);
150  Ipv4Address tapIp = addresses.NewAddress ();
151 
152  NS_LOG_INFO ("Create Device");
153  TapFdNetDeviceHelper helper;
154  helper.SetDeviceName (deviceName);
155  helper.SetModePi (modePi);
156  helper.SetTapIpv4Address (tapIp);
157  helper.SetTapIpv4Mask (tapMask);
158 
159  NetDeviceContainer devices = helper.Install (node);
160  Ptr<NetDevice> device = devices.Get (0);
161 
162  //
163  // Add a default internet stack to the node (ARP, IPv4, ICMP, UDP and TCP).
164  //
165  NS_LOG_INFO ("Add Internet Stack");
166  InternetStackHelper internetStackHelper;
167  internetStackHelper.Install (node);
168 
169  //
170  // Add an address to the ns-3 device in the same network than one
171  // assigned to the TAP.
172  //
173  NS_LOG_INFO ("Create IPv4 Interface");
174  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
175  uint32_t interface = ipv4->AddInterface (device);
176  Ipv4Address devIp = addresses.NewAddress ();
178  ipv4->AddAddress (interface, address);
179  ipv4->SetMetric (interface, 1);
180  ipv4->SetUp (interface);
181 
182  //
183  // Add a route to the ns-3 device so it can reach the outside world though the
184  // TAP.
185  //
186  Ipv4StaticRoutingHelper ipv4RoutingHelper;
187  Ptr<Ipv4StaticRouting> staticRouting = ipv4RoutingHelper.GetStaticRouting (ipv4);
188  staticRouting->SetDefaultRoute (tapIp, interface);
189 
190  //
191  // Create the ping application. This application knows how to send
192  // ICMP echo requests. Setting up the packet sink manually is a bit
193  // of a hassle and since there is no law that says we cannot mix the
194  // helper API with the low level API, let's just use the helper.
195  //
196  NS_LOG_INFO ("Create V4Ping Appliation");
197  Ptr<V4Ping> app = CreateObject<V4Ping> ();
198  app->SetAttribute ("Remote", Ipv4AddressValue (remoteIp));
199  app->SetAttribute ("Verbose", BooleanValue (true) );
200  node->AddApplication (app);
201  app->SetStartTime (Seconds (1.0));
202  app->SetStopTime (Seconds (21.0));
203 
204  //
205  // Give the application a name. This makes life much easier when constructing
206  // config paths.
207  //
208  Names::Add ("app", app);
209 
210  //
211  // Hook a trace to print something when the response comes back.
212  //
213  Config::Connect ("/Names/app/Rtt", MakeCallback (&PingRtt));
214 
215  //
216  // Enable a promiscuous pcap trace to see what is coming and going on our device.
217  //
218  helper.EnablePcap ("fd-tap-ping", device, true);
219 
220  //
221  // Now, do the actual emulation.
222  //
223  NS_LOG_INFO ("Run Emulation.");
224  Simulator::Stop (Seconds (25.0));
225  Simulator::Run ();
227  NS_LOG_INFO ("Done.");
228 }
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:157
void SetStopTime(Time stop)
Specify application stop time.
Definition: application.cc:75
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.
AttributeValue implementation for Boolean.
Definition: boolean.h:36
tuple devices
Definition: first.py:32
void SetDefaultRoute(Ipv4Address nextHop, uint32_t interface, uint32_t metric=0)
Add a default route to the static routing table.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:459
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.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:258
static void Run(void)
Run the simulation.
Definition: simulator.cc:226
#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:277
build a set of FdNetDevice objects attached to a virtual TAP network interface
tuple cmd
Definition: second.py:35
static void Add(std::string name, Ptr< Object > object)
Add the association between the string "name" and the Ptr obj.
Definition: names.cc:770
static void PingRtt(std::string context, Time rtt)
Definition: fd-tap-ping.cc:86
void SetTapIpv4Address(Ipv4Address address)
Set the device IPv4 address.
virtual void SetUp(uint32_t interface)=0
holds a vector of ns3::NetDevice pointers
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
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...
Parse command-line arguments.
Definition: command-line.h:205
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:843
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:190
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:76
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.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
#define NS_LOG_UNCOND(msg)
Output the requested message unconditionaly.
AttributeValue implementation for Ipv4Address.
Definition: ipv4-address.h:329
void SetTapIpv4Mask(Ipv4Mask mask)
Set the IPv4 network mask for the TAP device.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
Ptr< Ipv4StaticRouting > GetStaticRouting(Ptr< Ipv4 > ipv4) const
Try and find the static routing protocol as either the main routing protocol or in the list of routin...
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
a class to store IPv4 address information on an interface
Helper class that adds ns3::Ipv4StaticRouting objects.
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:498
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:234
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:993
virtual void SetMetric(uint32_t interface, uint16_t metric)=0
virtual bool AddAddress(uint32_t interface, Ipv4InterfaceAddress address)=0
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.
tuple address
Definition: first.py:37
void EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
void SetModePi(bool pi)
Set flag IFF_NO_PI on the device.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:69
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.