A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
fd-tap-ping.cc
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) -----
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 the 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 traffic sent on the Internet are able to
55 // reach back the TAP.
56 // - TAP-network-address is the same as 'tapNetwork'
57 // - net-device-ip is be the IP address of the network device connected to the internet
58 // # iptables -t nat -A POSTROUTING -s <TAP-network-addres>/24 -j SNAT --to-source <net-device-ip>
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 
68 
69 #include "ns3/abort.h"
70 #include "ns3/core-module.h"
71 #include "ns3/internet-module.h"
72 #include "ns3/network-module.h"
73 #include "ns3/fd-net-device-module.h"
74 #include "ns3/applications-module.h"
75 #include "ns3/ipv4-static-routing-helper.h"
76 #include "ns3/ipv4-list-routing-helper.h"
77 
78 using namespace ns3;
79 
80 NS_LOG_COMPONENT_DEFINE ("TAPPingExample");
81 
82 static void
83 PingRtt (std::string context, Time rtt)
84 {
85  NS_LOG_UNCOND ("Received Response with RTT = " << rtt);
86 }
87 
88 int
89 main (int argc, char *argv[])
90 {
91  NS_LOG_INFO ("Ping Emulation Example with TAP");
92 
93  std::string deviceName ("tap0");
94  std::string remote ("192.0.43.10"); // example.com
95  std::string network ("1.2.3.4");
96  std::string mask ("255.255.255.0");
97  std::string pi ("no");
98 
99  //
100  // Allow the user to override any of the defaults at run-time, via
101  // command-line arguments
102  //
103  CommandLine cmd;
104  cmd.AddValue ("deviceName", "Device name", deviceName);
105  cmd.AddValue ("remote", "Remote IP address (dotted decimal only please)", remote);
106  cmd.AddValue ("tapNetwork", "Network address to assign the TAP device IP address (dotted decimal only please)", network);
107  cmd.AddValue ("tapMask", "Network mask for configure the TAP device (dotted decimal only please)", mask);
108  cmd.AddValue ("modePi", "If 'yes' a PI header will be added to the traffic traversing the device(flag IFF_NOPI will be unset).", pi);
109  cmd.Parse (argc, argv);
110 
111  NS_ABORT_MSG_IF (network == "1.2.3.4", "You must change the local IP address before running this example");
112 
113  Ipv4Address remoteIp (remote.c_str ());
114  Ipv4Address tapNetwork (network.c_str ());
115  Ipv4Mask tapMask (mask.c_str ());
116 
117  bool modePi = ( pi == "yes" ? true : false);
118 
119  //
120  // Since we are using a real piece of hardware we need to use the realtime
121  // simulator.
122  //
123  GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));
124 
125  //
126  // Since we are going to be talking to real-world machines, we need to enable
127  // calculation of checksums in our protocols.
128  //
129  GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
130 
131  //
132  // In such a simple topology, the use of the helper API can be a hindrance
133  // so we drop down into the low level API and do it manually.
134  //
135  // First we need a single node.
136  //
137  NS_LOG_INFO ("Create Node");
138  Ptr<Node> node = CreateObject<Node> ();
139 
140  // Create an fd device, set a MAC address and point the device to the
141  // Linux device name. The device needs a transmit queueing discipline so
142  // create a droptail queue and give it to the device. Finally, "install"
143  // the device into the node.
144  //
145  Ipv4AddressHelper addresses;
146  addresses.SetBase (tapNetwork, tapMask);
147  Ipv4Address tapIp = addresses.NewAddress ();
148 
149  NS_LOG_INFO ("Create Device");
150  TapFdNetDeviceHelper helper;
151  helper.SetDeviceName (deviceName);
152  helper.SetModePi (modePi);
153  helper.SetTapIpv4Address (tapIp);
154  helper.SetTapIpv4Mask (tapMask);
155 
156  NetDeviceContainer devices = helper.Install (node);
157  Ptr<NetDevice> device = devices.Get (0);
158 
159  //
160  // Add a default internet stack to the node (ARP, IPv4, ICMP, UDP and TCP).
161  //
162  NS_LOG_INFO ("Add Internet Stack");
163  InternetStackHelper internetStackHelper;
164  internetStackHelper.Install (node);
165 
166  //
167  // Add an address to the ns-3 device in the same network than one
168  // assigned to the TAP.
169  //
170  NS_LOG_INFO ("Create IPv4 Interface");
171  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
172  uint32_t interface = ipv4->AddInterface (device);
173  Ipv4Address devIp = addresses.NewAddress ();
174  Ipv4InterfaceAddress address = Ipv4InterfaceAddress (devIp, tapMask);
175  ipv4->AddAddress (interface, address);
176  ipv4->SetMetric (interface, 1);
177  ipv4->SetUp (interface);
178 
179  //
180  // Add a route to the ns-3 device so it can reach the outside world though the
181  // TAP.
182  //
183  Ipv4StaticRoutingHelper ipv4RoutingHelper;
184  Ptr<Ipv4StaticRouting> staticRouting = ipv4RoutingHelper.GetStaticRouting (ipv4);
185  staticRouting->SetDefaultRoute (tapIp, interface);
186 
187  //
188  // Create the ping application. This application knows how to send
189  // ICMP echo requests. Setting up the packet sink manually is a bit
190  // of a hassle and since there is no law that says we cannot mix the
191  // helper API with the low level API, let's just use the helper.
192  //
193  NS_LOG_INFO ("Create V4Ping Appliation");
194  Ptr<V4Ping> app = CreateObject<V4Ping> ();
195  app->SetAttribute ("Remote", Ipv4AddressValue (remoteIp));
196  app->SetAttribute ("Verbose", BooleanValue (true) );
197  node->AddApplication (app);
198  app->SetStartTime (Seconds (1.0));
199  app->SetStopTime (Seconds (21.0));
200 
201  //
202  // Give the application a name. This makes life much easier when constructing
203  // config paths.
204  //
205  Names::Add ("app", app);
206 
207  //
208  // Hook a trace to print something when the response comes back.
209  //
210  Config::Connect ("/Names/app/Rtt", MakeCallback (&PingRtt));
211 
212  //
213  // Enable a promiscuous pcap trace to see what is coming and going on our device.
214  //
215  helper.EnablePcap ("fd-tap-ping", device, true);
216 
217  //
218  // Now, do the actual emulation.
219  //
220  NS_LOG_INFO ("Run Emulation.");
221  Simulator::Stop (Seconds (25.0));
222  Simulator::Run ();
224  NS_LOG_INFO ("Done.");
225 }
uint32_t AddApplication(Ptr< Application > application)
Definition: node.cc:148
void SetStopTime(Time stop)
Specify application stop time.
Definition: application.cc:74
keep track of time unit.
Definition: nstime.h:149
virtual NetDeviceContainer Install(Ptr< Node > node) const
Hold a bool native type.
Definition: boolean.h:38
void SetDefaultRoute(Ipv4Address nextHop, uint32_t interface, uint32_t metric=0)
Add a default route to the static routing table.
hold variables of type string
Definition: string.h:19
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:210
static void Run(void)
Definition: simulator.cc:157
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
aggregate IP/TCP/UDP functionality to existing Nodes.
#define NS_LOG_INFO(msg)
Definition: log.h:264
build a set of FdNetDevice objects attached to a virtua TAP network interface
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:728
static void Add(std::string name, Ptr< Object > object)
Add the association between the string "name" and the Ptr<Object> obj.
Definition: names.cc:615
void SetTapIpv4Address(Ipv4Address 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:502
static void Bind(std::string name, const AttributeValue &value)
parse command-line argumentsInstances of this class can be used to parse command-line arguments: user...
Definition: command-line.h:50
static void Destroy(void)
Definition: simulator.cc:121
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:75
void SetDeviceName(std::string deviceName)
void Install(std::string nodeName) const
#define NS_LOG_UNCOND(msg)
Definition: log.h:343
hold objects of type ns3::Ipv4Address
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
Ptr< Ipv4StaticRouting > GetStaticRouting(Ptr< Ipv4 > ipv4) const
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)
Definition: command-line.h:134
static void Stop(void)
Definition: simulator.cc:164
void Parse(int argc, char *argv[]) const
Definition: command-line.cc:84
virtual void SetMetric(uint32_t interface, uint16_t metric)=0
virtual bool AddAddress(uint32_t interface, Ipv4InterfaceAddress address)=0
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if cond is true.
Definition: abort.h:98
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:160
Ptr< T > GetObject(void) const
Definition: object.h:332
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:68
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.