A Discrete-Event Network Simulator
API
fd-emu-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 * 2017 Università' degli Studi di Napoli Federico II
5 * 2019 NITK Surathkal
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation;
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21// Allow ns-3 to ping a real host somewhere, using emulation mode
22//
23// +--------------------------+
24// | host |
25// +--------------------------+
26// | ns-3 simulation |
27// +--------------------------+
28// | ns-3 Node |
29// | +--------------------+ |
30// | | ns-3 TCP | |
31// | +--------------------+ |
32// | | ns-3 IPv4 | |
33// | +--------------------+ |
34// | | FdNetDevice or | |
35// | | NetmapNetDevice or | |
36// | | DpdkNetDevice | |
37// |--+--------------------+--+
38// | | eth0 | |
39// | +------+ |
40// | | |
41// +------------|-------------+
42// |
43// | +---------+
44// .-------| GW host |--- (Internet) -----
45// +---------+
46//
48// 1) You need to decide on a physical device on your real system, and either
49// overwrite the hard-configured device name below (eth0) or pass this
50// device name in as a command-line argument
51// 1') If you run emulation in dpdk mode, use device address (eg. 0000:00.1f.6)
52// as device name. This address can be obtained by running `lspci`
53// 2) The host device must be set to promiscuous mode
54// (e.g. "sudo ifconfig eth0 promisc")
55// 2') If you run emulation in netmap or dpdk mode, you need before to load
56// the netmap.ko or dpdk modules. The user is in charge to configure and
57// build netmap/dpdk separately.
58// 3) Be aware that ns-3 will generate a fake mac address, and that in
59// some enterprise networks, this may be considered bad form to be
60// sending packets out of your device with "unauthorized" mac addresses
61// 4) You will need to assign an IP address to the ns-3 simulation node that
62// is consistent with the subnet that is active on the host device's link.
63// That is, you will have to assign an IP address to the ns-3 node as if
64// it were on your real subnet. Search for "Ipv4Address localIp" and
65// replace the string "1.2.3.4" with a valid IP address.
66// 5) You will need to configure a default route in the ns-3 node to tell it
67// how to get off of your subnet. One thing you could do is a
68// 'netstat -rn' command and find the IP address of the default gateway
69// on your host. Search for "Ipv4Address gateway" and replace the string
70// "1.2.3.4" string with the gateway IP address.
71// 6) Give root suid to the raw or netmap socket creator binary.
72// If the --enable-sudo option was used to configure ns-3 with ns3, then the following
73// step will not be necessary.
74//
75// $ sudo chown root.root build/src/fd-net-device/ns3-dev-raw-sock-creator
76// $ sudo chmod 4755 build/src/fd-net-device/ns3-dev-raw-sock-creator
77//
78// or (if you run emulation in netmap mode):
79// $ sudo chown root.root build/src/fd-net-device/ns3-dev-netmap-device-creator
80// $ sudo chmod 4755 build/src/fd-net-device/ns3-dev-netmap-device-creator
81// 6') If you run emulation in dpdk mode, you will need to run example as root.
82//
83
84#include "ns3/abort.h"
85#include "ns3/core-module.h"
86#include "ns3/internet-module.h"
87#include "ns3/network-module.h"
88#include "ns3/fd-net-device-module.h"
89#include "ns3/internet-apps-module.h"
90#include "ns3/ipv4-static-routing-helper.h"
91#include "ns3/ipv4-list-routing-helper.h"
92
93using namespace ns3;
94
95NS_LOG_COMPONENT_DEFINE ("PingEmulationExample");
96
97static void
98PingRtt (std::string context, Time rtt)
99{
100 NS_LOG_UNCOND ("Received Response with RTT = " << rtt);
101}
102
103int
104main (int argc, char *argv[])
105{
106 NS_LOG_INFO ("Ping Emulation Example");
107
108 std::string deviceName ("eth0");
109 std::string remote ("8.8.8.8");
110 std::string localAddress ("1.2.3.4");
111 std::string localGateway ("1.2.3.4");
112#ifdef HAVE_PACKET_H
113 std::string emuMode ("raw");
114#elif HAVE_NETMAP_USER_H
115 std::string emuMode ("netmap");
116#else // HAVE_DPDK_USER_H is true (otherwise this example is not compiled)
117 std::string emuMode ("dpdk");
118#endif
119
120 //
121 // Allow the user to override any of the defaults at run-time, via
122 // command-line arguments
123 //
124 CommandLine cmd (__FILE__);
125 cmd.AddValue ("deviceName", "Device name (in raw, netmap mode) or Device address (in dpdk mode, eg: 0000:00:1f.6). Use `lspci` to find device address.", deviceName);
126 cmd.AddValue ("remote", "Remote IP address (dotted decimal only please)", remote);
127 cmd.AddValue ("localIp", "Local IP address (dotted decimal only please)", localAddress);
128 cmd.AddValue ("gateway", "Gateway address (dotted decimal only please)", localGateway);
129 cmd.AddValue ("emuMode", "Emulation mode in {raw, netmap, dpdk}", emuMode);
130 cmd.Parse (argc, argv);
131
132 Ipv4Address remoteIp (remote.c_str ());
133 Ipv4Address localIp (localAddress.c_str ());
134 NS_ABORT_MSG_IF (localIp == "1.2.3.4", "You must change the local IP address before running this example");
135
136 Ipv4Mask localMask ("255.255.255.0");
137
138 //
139 // Since we are using a real piece of hardware we need to use the realtime
140 // simulator.
141 //
142 GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));
143
144 //
145 // Since we are going to be talking to real-world machines, we need to enable
146 // calculation of checksums in our protocols.
147 //
148 GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
149
150 //
151 // In such a simple topology, the use of the helper API can be a hindrance
152 // so we drop down into the low level API and do it manually.
153 //
154 // First we need a single node.
155 //
156 NS_LOG_INFO ("Create Node");
157 Ptr<Node> node = CreateObject<Node> ();
158
159 //
160 // Create an emu device, allocate a MAC address and point the device to the
161 // Linux device name. The device needs a transmit queueing discipline so
162 // create a droptail queue and give it to the device. Finally, "install"
163 // the device into the node.
164 //
165 // Do understand that the ns-3 allocated MAC address will be sent out over
166 // your network since the emu net device will spoof it. By default, this
167 // address will have an Organizationally Unique Identifier (OUI) of zero.
168 // The Internet Assigned Number Authority IANA
169 //
170 // http://www.iana.org/assignments/ethernet-numbers
171 //
172 // reports that this OUI is unassigned, and so should not conflict with
173 // real hardware on your net. It may raise all kinds of red flags in a
174 // real environment to have packets from a device with an obviously bogus
175 // OUI flying around. Be aware.
176 //
177 NS_LOG_INFO ("Create Device");
178
179 FdNetDeviceHelper* helper = nullptr;
180
181#ifdef HAVE_PACKET_H
182 if (emuMode == "raw")
183 {
185 raw->SetDeviceName (deviceName);
186 helper = raw;
187 }
188#endif
189#ifdef HAVE_NETMAP_USER_H
190 if (emuMode == "netmap")
191 {
193 netmap->SetDeviceName (deviceName);
194 helper = netmap;
195 }
196#endif
197#ifdef HAVE_DPDK_USER_H
198 if (emuMode == "dpdk")
199 {
201 // Use e1000 driver library (this is for IGb PMD supproting Intel 1GbE NIC)
202 // NOTE: DPDK supports multiple Poll Mode Drivers (PMDs) and you can use it
203 // based on your NIC. You just need to set pmd library as follows:
204 dpdk->SetPmdLibrary ("librte_pmd_e1000.so");
205 // Set dpdk driver to use for the NIC. `uio_pci_generic` supports most NICs.
206 dpdk->SetDpdkDriver ("uio_pci_generic");
207 // Set device name
208 dpdk->SetDeviceName (deviceName);
209 helper = dpdk;
210 }
211#endif
212
213 if (helper == nullptr)
214 {
215 NS_ABORT_MSG (emuMode << " not supported.");
216 }
217
218 NetDeviceContainer devices = helper->Install (node);
219 Ptr<NetDevice> device = devices.Get (0);
220 device->SetAttribute ("Address", Mac48AddressValue (Mac48Address::Allocate ()));
221
222 //Ptr<Queue> queue = CreateObject<DropTailQueue> ();
223 //device->SetQueue (queue);
224 //node->AddDevice (device);
225
226 //
227 // Add a default internet stack to the node. This gets us the ns-3 versions
228 // of ARP, IPv4, ICMP, UDP and TCP.
229 //
230 NS_LOG_INFO ("Add Internet Stack");
231 InternetStackHelper internetStackHelper;
232 internetStackHelper.Install (node);
233
234 NS_LOG_INFO ("Create IPv4 Interface");
235 Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
236 uint32_t interface = ipv4->AddInterface (device);
238 ipv4->AddAddress (interface, address);
239 ipv4->SetMetric (interface, 1);
240 ipv4->SetUp (interface);
241
242 //
243 // When the ping application sends its ICMP packet, it will happily send it
244 // down the ns-3 protocol stack. We set the IP address of the destination
245 // to the address corresponding to example.com above. This address is off
246 // our local network so we have got to provide some kind of default route
247 // to ns-3 to be able to get that ICMP packet forwarded off of our network.
248 //
249 // You have got to provide an IP address of a real host that you can send
250 // real packets to and have them forwarded off of your local network. One
251 // thing you could do is a 'netstat -rn' command and find the IP address of
252 // the default gateway on your host and add it below, replacing the
253 // "1.2.3.4" string.
254 //
255 Ipv4Address gateway (localGateway.c_str ());
256 NS_ABORT_MSG_IF (gateway == "1.2.3.4", "You must change the gateway IP address before running this example");
257
258 Ipv4StaticRoutingHelper ipv4RoutingHelper;
259 Ptr<Ipv4StaticRouting> staticRouting = ipv4RoutingHelper.GetStaticRouting (ipv4);
260 staticRouting->SetDefaultRoute (gateway, interface);
261
262 //
263 // Create the ping application. This application knows how to send
264 // ICMP echo requests. Setting up the packet sink manually is a bit
265 // of a hassle and since there is no law that says we cannot mix the
266 // helper API with the low level API, let's just use the helper.
267 //
268 NS_LOG_INFO ("Create V4Ping Appliation");
269 Ptr<V4Ping> app = CreateObject<V4Ping> ();
270 app->SetAttribute ("Remote", Ipv4AddressValue (remoteIp));
271 app->SetAttribute ("Verbose", BooleanValue (true) );
272 node->AddApplication (app);
273 app->SetStartTime (Seconds (1.0));
274 app->SetStopTime (Seconds (22.0));
275
276 //
277 // Give the application a name. This makes life much easier when constructing
278 // config paths.
279 //
280 Names::Add ("app", app);
281
282 //
283 // Hook a trace to print something when the response comes back.
284 //
285 Config::Connect ("/Names/app/Rtt", MakeCallback (&PingRtt));
286
287 //
288 // Enable a promiscuous pcap trace to see what is coming and going on our device.
289 //
290 helper->EnablePcap (emuMode + "-emu-ping", device, true);
291
292 //
293 // Now, do the actual emulation.
294 //
295 NS_LOG_INFO ("Run Emulation in " << emuMode << " mode.");
296 Simulator::Stop (Seconds (23.0));
297 Simulator::Run ();
298 Simulator::Destroy ();
299 delete helper;
300 NS_LOG_INFO ("Done.");
301}
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Parse command-line arguments.
Definition: command-line.h:229
build a DpdkNetDevice object attached to a physical network interface
void SetPmdLibrary(std::string pmdLibrary)
Sets PMD Library to be used for the NIC.
void SetDpdkDriver(std::string dpdkDriver)
Sets DPDK Driver to bind NIC to.
build a set of FdNetDevice objects attached to a physical network interface
void SetDeviceName(std::string deviceName)
Set the device name of this device.
build a set of FdNetDevice objects Normally we eschew multiple inheritance, however,...
virtual NetDeviceContainer Install(Ptr< Node > node) const
This method creates a FdNetDevice and associates it to a node.
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...
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
AttributeValue implementation for Ipv4Address.
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:77
a class to store IPv4 address information on an interface
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:256
Helper class that adds ns3::Ipv4StaticRouting objects.
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...
AttributeValue implementation for Mac48Address.
holds a vector of ns3::NetDevice pointers
build a set of FdNetDevice objects attached to a physical network interface
void SetDeviceName(std::string deviceName)
Set the device name of this device.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:159
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:256
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
void EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
Hold variables of type string.
Definition: string.h:41
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
static void PingRtt(std::string context, Time rtt)
Definition: fd-emu-ping.cc:98
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_UNCOND(msg)
Output the requested message unconditionally.
#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
address
Definition: first.py:44
devices
Definition: first.py:39
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
cmd
Definition: second.py:35