A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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  *
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
20 //
21 // +----------------------+
22 // | host |
23 // +----------------------+
24 // | ns-3 simulation |
25 // +----------------------+
26 // | ns-3 Node |
27 // | +----------------+ |
28 // | | ns-3 TCP | |
29 // | +----------------+ |
30 // | | ns-3 IPv4 | |
31 // | +----------------+ |
32 // | | FdNetDevice | |
33 // |--+----------------+--+
34 // | | eth0 | |
35 // | +------+ |
36 // | | |
37 // +----------|-----------+
38 // |
39 // | +---------+
40 // .---------| GW host |--- (Internet) -----
41 // +---------+
42 //
44 // 1) You need to decide on a physical device on your real system, and either
45 // overwrite the hard-configured device name below (eth0) or pass this
46 // device name in as a command-line argument
47 // 2) The host device must be set to promiscuous mode
48 // (e.g. "sudo ifconfig eth0 promisc")
49 // 3) Be aware that ns-3 will generate a fake mac address, and that in
50 // some enterprise networks, this may be considered bad form to be
51 // sending packets out of your device with "unauthorized" mac addresses
52 // 4) You will need to assign an IP address to the ns-3 simulation node that
53 // is consistent with the subnet that is active on the host device's link.
54 // That is, you will have to assign an IP address to the ns-3 node as if
55 // it were on your real subnet. Search for "Ipv4Address localIp" and
56 // replace the string "1.2.3.4" with a valid IP address.
57 // 5) You will need to configure a default route in the ns-3 node to tell it
58 // how to get off of your subnet. One thing you could do is a
59 // 'netstat -rn' command and find the IP address of the default gateway
60 // on your host. Search for "Ipv4Address gateway" and replace the string
61 // "1.2.3.4" string with the gateway IP address.
63 // If the --enable-sudo option was used to configure ns-3 with waf, then the following
64 // step will not be necessary.
65 //
66 // $ sudo chown root.root build/src/fd-net-device/ns3-dev-raw-sock-creator
67 // $ sudo chmod 4755 build/src/fd-net-device/ns3-dev-raw-sock-creator
68 //
69 
70 #include "ns3/abort.h"
71 #include "ns3/core-module.h"
72 #include "ns3/internet-module.h"
73 #include "ns3/network-module.h"
74 #include "ns3/fd-net-device-module.h"
75 #include "ns3/applications-module.h"
76 #include "ns3/ipv4-static-routing-helper.h"
77 #include "ns3/ipv4-list-routing-helper.h"
78 
79 using namespace ns3;
80 
81 NS_LOG_COMPONENT_DEFINE ("PingEmulationExample");
82 
83 static void
84 PingRtt (std::string context, Time rtt)
85 {
86  NS_LOG_UNCOND ("Received Response with RTT = " << rtt);
87 }
88 
89 int
90 main (int argc, char *argv[])
91 {
92  NS_LOG_INFO ("Ping Emulation Example");
93 
94  std::string deviceName ("eth0");
95  std::string remote ("173.194.34.51"); // example.com
96 
97  //
98  // Allow the user to override any of the defaults at run-time, via
99  // command-line arguments
100  //
101  CommandLine cmd;
102  cmd.AddValue ("deviceName", "Device name", deviceName);
103  cmd.AddValue ("remote", "Remote IP address (dotted decimal only please)", remote);
104  cmd.Parse (argc, argv);
105 
106  Ipv4Address remoteIp (remote.c_str ());
107  Ipv4Address localIp ("1.2.3.4");
108  NS_ABORT_MSG_IF (localIp == "1.2.3.4", "You must change the local IP address before running this example");
109 
110  Ipv4Mask localMask ("255.255.255.0");
111 
112  //
113  // Since we are using a real piece of hardware we need to use the realtime
114  // simulator.
115  //
116  GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));
117 
118  //
119  // Since we are going to be talking to real-world machines, we need to enable
120  // calculation of checksums in our protocols.
121  //
122  GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
123 
124  //
125  // In such a simple topology, the use of the helper API can be a hindrance
126  // so we drop down into the low level API and do it manually.
127  //
128  // First we need a single node.
129  //
130  NS_LOG_INFO ("Create Node");
131  Ptr<Node> node = CreateObject<Node> ();
132 
133  //
134  // Create an emu device, allocate a MAC address and point the device to the
135  // Linux device name. The device needs a transmit queueing discipline so
136  // create a droptail queue and give it to the device. Finally, "install"
137  // the device into the node.
138  //
139  // Do understand that the ns-3 allocated MAC address will be sent out over
140  // your network since the emu net device will spoof it. By default, this
141  // address will have an Organizationally Unique Identifier (OUI) of zero.
142  // The Internet Assigned Number Authority IANA
143  //
144  // http://www.iana.org/assignments/ethernet-numbers
145  //
146  // reports that this OUI is unassigned, and so should not conflict with
147  // real hardware on your net. It may raise all kinds of red flags in a
148  // real environment to have packets from a device with an obviously bogus
149  // OUI flying around. Be aware.
150  //
151  NS_LOG_INFO ("Create Device");
153  emu.SetDeviceName (deviceName);
154  NetDeviceContainer devices = emu.Install (node);
155  Ptr<NetDevice> device = devices.Get (0);
156  device->SetAttribute ("Address", Mac48AddressValue (Mac48Address::Allocate ()));
157 
158  //Ptr<Queue> queue = CreateObject<DropTailQueue> ();
159  //device->SetQueue (queue);
160  //node->AddDevice (device);
161 
162  //
163  // Add a default internet stack to the node. This gets us the ns-3 versions
164  // of ARP, IPv4, ICMP, UDP and TCP.
165  //
166  NS_LOG_INFO ("Add Internet Stack");
167  InternetStackHelper internetStackHelper;
168  internetStackHelper.Install (node);
169 
170  NS_LOG_INFO ("Create IPv4 Interface");
171  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
172  uint32_t interface = ipv4->AddInterface (device);
173  Ipv4InterfaceAddress address = Ipv4InterfaceAddress (localIp, localMask);
174  ipv4->AddAddress (interface, address);
175  ipv4->SetMetric (interface, 1);
176  ipv4->SetUp (interface);
177 
178  //
179  // When the ping application sends its ICMP packet, it will happily send it
180  // down the ns-3 protocol stack. We set the IP address of the destination
181  // to the address corresponding to example.com above. This address is off
182  // our local network so we have got to provide some kind of default route
183  // to ns-3 to be able to get that ICMP packet forwarded off of our network.
184  //
185  // You have got to provide an IP address of a real host that you can send
186  // real packets to and have them forwarded off of your local network. One
187  // thing you could do is a 'netstat -rn' command and find the IP address of
188  // the default gateway on your host and add it below, replacing the
189  // "1.2.3.4" string.
190  //
191  Ipv4Address gateway ("1.2.3.4");
192  NS_ABORT_MSG_IF (gateway == "1.2.3.4", "You must change the gateway IP address before running this example");
193 
194  Ipv4StaticRoutingHelper ipv4RoutingHelper;
195  Ptr<Ipv4StaticRouting> staticRouting = ipv4RoutingHelper.GetStaticRouting (ipv4);
196  staticRouting->SetDefaultRoute (gateway, interface);
197 
198  //
199  // Create the ping application. This application knows how to send
200  // ICMP echo requests. Setting up the packet sink manually is a bit
201  // of a hassle and since there is no law that says we cannot mix the
202  // helper API with the low level API, let's just use the helper.
203  //
204  NS_LOG_INFO ("Create V4Ping Appliation");
205  Ptr<V4Ping> app = CreateObject<V4Ping> ();
206  app->SetAttribute ("Remote", Ipv4AddressValue (remoteIp));
207  app->SetAttribute ("Verbose", BooleanValue (true) );
208  node->AddApplication (app);
209  app->SetStartTime (Seconds (1.0));
210  app->SetStopTime (Seconds (21.0));
211 
212  //
213  // Give the application a name. This makes life much easier when constructing
214  // config paths.
215  //
216  Names::Add ("app", app);
217 
218  //
219  // Hook a trace to print something when the response comes back.
220  //
221  Config::Connect ("/Names/app/Rtt", MakeCallback (&PingRtt));
222 
223  //
224  // Enable a promiscuous pcap trace to see what is coming and going on our device.
225  //
226  emu.EnablePcap ("emu-ping", device, true);
227 
228  //
229  // Now, do the actual emulation.
230  //
231  NS_LOG_INFO ("Run Emulation.");
232  Simulator::Stop (Seconds (22.0));
233  Simulator::Run ();
235  NS_LOG_INFO ("Done.");
236 }
uint32_t AddApplication(Ptr< Application > application)
Definition: node.cc:149
void SetStopTime(Time stop)
Specify application stop time.
Definition: application.cc:74
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:79
virtual NetDeviceContainer Install(Ptr< Node > node) const
This method creates a FdNetDevice and associates it to a node.
Hold a bool native type.
Definition: boolean.h:38
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.
hold variables of type string
Definition: string.h:18
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:222
static void Run(void)
Run the simulation until one of:
Definition: simulator.cc:157
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
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:223
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:728
static void PingRtt(std::string context, Time rtt)
Definition: fd-emu-ping.cc:84
static void Add(std::string name, Ptr< Object > object)
Add the association between the string "name" and the Ptr obj.
Definition: names.cc:615
static Mac48Address Allocate(void)
Allocate a new Mac48Address.
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:1242
static void Bind(std::string name, const AttributeValue &value)
Parse command-line arguments.
Definition: command-line.h:177
static void Destroy(void)
Every event scheduled by the Simulator::insertAtDestroy method is invoked.
Definition: simulator.cc:121
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.
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.
hold objects of type ns3::Ipv4Address
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
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 cond is true.
Definition: abort.h:101
a class to store IPv4 address information on an interface
Helper class that adds ns3::Ipv4StaticRouting objects.
hold objects of type ns3::Mac48Address
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:435
static void Stop(void)
If an event invokes this method, it will be the last event scheduled by the Simulator::run method bef...
Definition: simulator.cc:165
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.
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 SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:176
Ptr< T > GetObject(void) const
Definition: object.h:362
build a set of FdNetDevice objects attached to a physical network interface
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:68
int main(int argc, char *argv[])
Definition: fd-emu-ping.cc:90