1.1 --- a/examples/emu-ping.cc Fri May 01 14:34:27 2009 +0200
1.2 +++ b/examples/emu-ping.cc Fri May 01 09:07:04 2009 -0700
1.3 @@ -1,217 +1,217 @@
1.4 -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
1.5 -/*
1.6 - * This program is free software; you can redistribute it and/or modify
1.7 - * it under the terms of the GNU General Public License version 2 as
1.8 - * published by the Free Software Foundation;
1.9 - *
1.10 - * This program is distributed in the hope that it will be useful,
1.11 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.13 - * GNU General Public License for more details.
1.14 - *
1.15 - * You should have received a copy of the GNU General Public License
1.16 - * along with this program; if not, write to the Free Software
1.17 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1.18 - */
1.19 -
1.20 -// Allow ns-3 to ping a real host somewhere, using emulation mode
1.21 -//
1.22 -// ------------
1.23 -// | node n0 |
1.24 -// | |
1.25 -// | --- |
1.26 -// | | | |
1.27 -// | |emu| |
1.28 -// | | | |
1.29 -// | --- |
1.30 -// | | |
1.31 -// ----|-------
1.32 -// |
1.33 -// (device on host system, set to promiscuous mode)
1.34 -// |
1.35 -// --------- (Internet) -------
1.36 -//
1.37 -// To use this example:
1.38 -// 1) You need to decide on a physical device on your real system, and either
1.39 -// overwrite the hard-configured device name below (eth0) or pass this
1.40 -// device name in as a command-line argument
1.41 -// 2) The host device must be set to promiscuous mode
1.42 -// (e.g. "sudo ifconfig eth0 promisc")
1.43 -// 3) Be aware that ns-3 will generate a fake mac address, and that in
1.44 -// some enterprise networks, this may be considered bad form to be
1.45 -// sending packets out of your device with "unauthorized" mac addresses
1.46 -// 4) You will need to assign an IP address to the ns-3 simulation node that
1.47 -// is consistent with the subnet that is active on the host device's link.
1.48 -// That is, you will have to assign an IP address to the ns-3 node as if
1.49 -// it were on your real subnet. Search for "Ipv4Address localIp" and
1.50 -// replace the string "1.2.3.4" with a valid IP address.
1.51 -// 5) You will need to configure a default route in the ns-3 node to tell it
1.52 -// how to get off of your subnet. One thing you could do is a
1.53 -// 'netstat -rn' command and find the IP address of the default gateway
1.54 -// on your host. Search for "Ipv4Address gateway" and replace the string
1.55 -// "1.2.3.4" string with the gateway IP address.
1.56 -
1.57 -#include "ns3/abort.h"
1.58 -#include "ns3/core-module.h"
1.59 -#include "ns3/simulator-module.h"
1.60 -#include "ns3/node-module.h"
1.61 -#include "ns3/internet-stack-module.h"
1.62 -#include "ns3/emu-module.h"
1.63 -#include "ns3/v4ping-module.h"
1.64 -#include "ns3/helper-module.h"
1.65 -
1.66 -using namespace ns3;
1.67 -
1.68 -NS_LOG_COMPONENT_DEFINE ("PingEmulationExample");
1.69 -
1.70 -static void
1.71 -PingRtt (std::string context, Time rtt)
1.72 -{
1.73 - NS_LOG_UNCOND ("Received Response with RTT = " << rtt);
1.74 -}
1.75 -
1.76 -int
1.77 -main (int argc, char *argv[])
1.78 -{
1.79 - NS_LOG_INFO ("Ping Emulation Example");
1.80 -
1.81 - std::string deviceName ("eth0");
1.82 - std::string remote ("208.77.188.166"); // example.com
1.83 -
1.84 - //
1.85 - // Allow the user to override any of the defaults at run-time, via
1.86 - // command-line arguments
1.87 - //
1.88 - CommandLine cmd;
1.89 - cmd.AddValue("deviceName", "Device name", deviceName);
1.90 - cmd.AddValue("remote", "Remote IP address (dotted decimal only please)", remote);
1.91 - cmd.Parse (argc, argv);
1.92 -
1.93 - Ipv4Address remoteIp (remote.c_str ());
1.94 - Ipv4Address localIp ("1.2.3.4");
1.95 - NS_ABORT_MSG_IF (localIp == "1.2.3.4", "You must change the local IP address before running this example");
1.96 -
1.97 - Ipv4Mask localMask ("255.255.255.0");
1.98 -
1.99 - //
1.100 - // Since we are using a real piece of hardware we need to use the realtime
1.101 - // simulator.
1.102 - //
1.103 - GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));
1.104 -
1.105 - //
1.106 - // Since we are going to be talking to real-world machines, we need to enable
1.107 - // calculation of checksums in our protocols.
1.108 - //
1.109 - Config::SetDefault ("ns3::Ipv4L3Protocol::CalcChecksum", BooleanValue (true));
1.110 - Config::SetDefault ("ns3::Icmpv4L4Protocol::CalcChecksum", BooleanValue (true));
1.111 - Config::SetDefault ("ns3::TcpL4Protocol::CalcChecksum", BooleanValue (true));
1.112 - Config::SetDefault ("ns3::UdpL4Protocol::CalcChecksum", BooleanValue (true));
1.113 -
1.114 - //
1.115 - // In such a simple topology, the use of the helper API can be a hindrance
1.116 - // so we drop down into the low level API and do it manually.
1.117 - //
1.118 - // First we need a single node.
1.119 - //
1.120 - NS_LOG_INFO ("Create Node");
1.121 - Ptr<Node> node = CreateObject<Node> ();
1.122 -
1.123 - //
1.124 - // Create an emu device, allocate a MAC address and point the device to the
1.125 - // Linux device name. The device needs a transmit queueing discipline so
1.126 - // create a droptail queue and give it to the device. Finally, "install"
1.127 - // the device into the node.
1.128 - //
1.129 - // Do understand that the ns-3 allocated MAC address will be sent out over
1.130 - // your network since the emu net device will spoof it. By default, this
1.131 - // address will have an Organizationally Unique Identifier (OUI) of zero.
1.132 - // The Internet Assigned Number Authority IANA
1.133 - //
1.134 - // http://www.iana.org/assignments/ethernet-numbers
1.135 - //
1.136 - // reports that this OUI is unassigned, and so should not conflict with
1.137 - // real hardware on your net. It may raise all kinds of red flags in a
1.138 - // real environment to have packets from a device with an obviously bogus
1.139 - // OUI flying around. Be aware.
1.140 - //
1.141 - NS_LOG_INFO ("Create Device");
1.142 - Ptr<EmuNetDevice> device = CreateObject<EmuNetDevice> ();
1.143 - device->SetAttribute ("Address", Mac48AddressValue (Mac48Address::Allocate ()));
1.144 - device->SetAttribute ("DeviceName", StringValue (deviceName));
1.145 -
1.146 - Ptr<Queue> queue = CreateObject<DropTailQueue> ();
1.147 - device->SetQueue (queue);
1.148 - node->AddDevice (device);
1.149 -
1.150 - //
1.151 - // Add a default internet stack to the node. This gets us the ns-3 versions
1.152 - // of ARP, IPv4, ICMP, UDP and TCP.
1.153 - //
1.154 - NS_LOG_INFO ("Add Internet Stack");
1.155 - AddInternetStack (node);
1.156 -
1.157 - NS_LOG_INFO ("Create IPv4 Interface");
1.158 - Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
1.159 - uint32_t interface = ipv4->AddInterface (device);
1.160 - Ipv4InterfaceAddress address = Ipv4InterfaceAddress (localIp, localMask);
1.161 - ipv4->AddAddress (interface, address);
1.162 - ipv4->SetMetric (interface, 1);
1.163 - ipv4->SetUp (interface);
1.164 -
1.165 - //
1.166 - // When the ping appliation sends its ICMP packet, it will happily send it
1.167 - // down the ns-3 protocol stack. We set the IP address of the destination
1.168 - // to the address corresponding to example.com above. This address is off
1.169 - // our local network so we have got to provide some kind of default route
1.170 - // to ns-3 to be able to get that ICMP packet forwarded off of our network.
1.171 - //
1.172 - // You have got to provide an IP address of a real host that you can send
1.173 - // real packets to and have them forwarded off of your local network. One
1.174 - // thing you could do is a 'netstat -rn' command and find the IP address of
1.175 - // the default gateway on your host and add it below, replacing the
1.176 - // "1.2.3.4" string.
1.177 - //
1.178 - Ipv4Address gateway ("1.2.3.4");
1.179 - NS_ABORT_MSG_IF (gateway == "1.2.3.4", "You must change the gateway IP address before running this example");
1.180 -
1.181 - ipv4->SetDefaultRoute (gateway, interface);
1.182 -
1.183 - //
1.184 - // Create the ping application. This application knows how to send
1.185 - // ICMP echo requests. Setting up the packet sink manually is a bit
1.186 - // of a hassle and since there is no law that says we cannot mix the
1.187 - // helper API with the low level API, let's just use the helper.
1.188 - //
1.189 - NS_LOG_INFO ("Create V4Ping Appliation");
1.190 - Ptr<V4Ping> app = CreateObject<V4Ping> ();
1.191 - app->SetAttribute ("Remote", Ipv4AddressValue (remoteIp));
1.192 - node->AddApplication (app);
1.193 - app->Start (Seconds (1.0));
1.194 - app->Stop (Seconds (5.0));
1.195 -
1.196 - //
1.197 - // Give the application a name. This makes life much easier when constructing
1.198 - // config paths.
1.199 - //
1.200 - Names::Add ("app", app);
1.201 -
1.202 - //
1.203 - // Hook a trace to print something when the response comes back.
1.204 - //
1.205 - Config::Connect ("/Names/app/Rtt", MakeCallback (&PingRtt));
1.206 -
1.207 - //
1.208 - // Enable a promiscuous pcap trace to see what is coming and going on our device.
1.209 - //
1.210 - EmuHelper::EnablePcap ("emu-ping", device, true);
1.211 -
1.212 - //
1.213 - // Now, do the actual emulation.
1.214 - //
1.215 - NS_LOG_INFO ("Run Emulation.");
1.216 - Simulator::Stop (Seconds (5.0));
1.217 - Simulator::Run ();
1.218 - Simulator::Destroy ();
1.219 - NS_LOG_INFO ("Done.");
1.220 -}
1.221 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
1.222 +/*
1.223 + * This program is free software; you can redistribute it and/or modify
1.224 + * it under the terms of the GNU General Public License version 2 as
1.225 + * published by the Free Software Foundation;
1.226 + *
1.227 + * This program is distributed in the hope that it will be useful,
1.228 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.229 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.230 + * GNU General Public License for more details.
1.231 + *
1.232 + * You should have received a copy of the GNU General Public License
1.233 + * along with this program; if not, write to the Free Software
1.234 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1.235 + */
1.236 +
1.237 +// Allow ns-3 to ping a real host somewhere, using emulation mode
1.238 +//
1.239 +// ------------
1.240 +// | node n0 |
1.241 +// | |
1.242 +// | --- |
1.243 +// | | | |
1.244 +// | |emu| |
1.245 +// | | | |
1.246 +// | --- |
1.247 +// | | |
1.248 +// ----|-------
1.249 +// |
1.250 +// (device on host system, set to promiscuous mode)
1.251 +// |
1.252 +// --------- (Internet) -------
1.253 +//
1.254 +// To use this example:
1.255 +// 1) You need to decide on a physical device on your real system, and either
1.256 +// overwrite the hard-configured device name below (eth0) or pass this
1.257 +// device name in as a command-line argument
1.258 +// 2) The host device must be set to promiscuous mode
1.259 +// (e.g. "sudo ifconfig eth0 promisc")
1.260 +// 3) Be aware that ns-3 will generate a fake mac address, and that in
1.261 +// some enterprise networks, this may be considered bad form to be
1.262 +// sending packets out of your device with "unauthorized" mac addresses
1.263 +// 4) You will need to assign an IP address to the ns-3 simulation node that
1.264 +// is consistent with the subnet that is active on the host device's link.
1.265 +// That is, you will have to assign an IP address to the ns-3 node as if
1.266 +// it were on your real subnet. Search for "Ipv4Address localIp" and
1.267 +// replace the string "1.2.3.4" with a valid IP address.
1.268 +// 5) You will need to configure a default route in the ns-3 node to tell it
1.269 +// how to get off of your subnet. One thing you could do is a
1.270 +// 'netstat -rn' command and find the IP address of the default gateway
1.271 +// on your host. Search for "Ipv4Address gateway" and replace the string
1.272 +// "1.2.3.4" string with the gateway IP address.
1.273 +
1.274 +#include "ns3/abort.h"
1.275 +#include "ns3/core-module.h"
1.276 +#include "ns3/simulator-module.h"
1.277 +#include "ns3/node-module.h"
1.278 +#include "ns3/internet-stack-module.h"
1.279 +#include "ns3/emu-module.h"
1.280 +#include "ns3/v4ping-module.h"
1.281 +#include "ns3/helper-module.h"
1.282 +
1.283 +using namespace ns3;
1.284 +
1.285 +NS_LOG_COMPONENT_DEFINE ("PingEmulationExample");
1.286 +
1.287 +static void
1.288 +PingRtt (std::string context, Time rtt)
1.289 +{
1.290 + NS_LOG_UNCOND ("Received Response with RTT = " << rtt);
1.291 +}
1.292 +
1.293 +int
1.294 +main (int argc, char *argv[])
1.295 +{
1.296 + NS_LOG_INFO ("Ping Emulation Example");
1.297 +
1.298 + std::string deviceName ("eth0");
1.299 + std::string remote ("208.77.188.166"); // example.com
1.300 +
1.301 + //
1.302 + // Allow the user to override any of the defaults at run-time, via
1.303 + // command-line arguments
1.304 + //
1.305 + CommandLine cmd;
1.306 + cmd.AddValue("deviceName", "Device name", deviceName);
1.307 + cmd.AddValue("remote", "Remote IP address (dotted decimal only please)", remote);
1.308 + cmd.Parse (argc, argv);
1.309 +
1.310 + Ipv4Address remoteIp (remote.c_str ());
1.311 + Ipv4Address localIp ("1.2.3.4");
1.312 + NS_ABORT_MSG_IF (localIp == "1.2.3.4", "You must change the local IP address before running this example");
1.313 +
1.314 + Ipv4Mask localMask ("255.255.255.0");
1.315 +
1.316 + //
1.317 + // Since we are using a real piece of hardware we need to use the realtime
1.318 + // simulator.
1.319 + //
1.320 + GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));
1.321 +
1.322 + //
1.323 + // Since we are going to be talking to real-world machines, we need to enable
1.324 + // calculation of checksums in our protocols.
1.325 + //
1.326 + Config::SetDefault ("ns3::Ipv4L3Protocol::CalcChecksum", BooleanValue (true));
1.327 + Config::SetDefault ("ns3::Icmpv4L4Protocol::CalcChecksum", BooleanValue (true));
1.328 + Config::SetDefault ("ns3::TcpL4Protocol::CalcChecksum", BooleanValue (true));
1.329 + Config::SetDefault ("ns3::UdpL4Protocol::CalcChecksum", BooleanValue (true));
1.330 +
1.331 + //
1.332 + // In such a simple topology, the use of the helper API can be a hindrance
1.333 + // so we drop down into the low level API and do it manually.
1.334 + //
1.335 + // First we need a single node.
1.336 + //
1.337 + NS_LOG_INFO ("Create Node");
1.338 + Ptr<Node> node = CreateObject<Node> ();
1.339 +
1.340 + //
1.341 + // Create an emu device, allocate a MAC address and point the device to the
1.342 + // Linux device name. The device needs a transmit queueing discipline so
1.343 + // create a droptail queue and give it to the device. Finally, "install"
1.344 + // the device into the node.
1.345 + //
1.346 + // Do understand that the ns-3 allocated MAC address will be sent out over
1.347 + // your network since the emu net device will spoof it. By default, this
1.348 + // address will have an Organizationally Unique Identifier (OUI) of zero.
1.349 + // The Internet Assigned Number Authority IANA
1.350 + //
1.351 + // http://www.iana.org/assignments/ethernet-numbers
1.352 + //
1.353 + // reports that this OUI is unassigned, and so should not conflict with
1.354 + // real hardware on your net. It may raise all kinds of red flags in a
1.355 + // real environment to have packets from a device with an obviously bogus
1.356 + // OUI flying around. Be aware.
1.357 + //
1.358 + NS_LOG_INFO ("Create Device");
1.359 + Ptr<EmuNetDevice> device = CreateObject<EmuNetDevice> ();
1.360 + device->SetAttribute ("Address", Mac48AddressValue (Mac48Address::Allocate ()));
1.361 + device->SetAttribute ("DeviceName", StringValue (deviceName));
1.362 +
1.363 + Ptr<Queue> queue = CreateObject<DropTailQueue> ();
1.364 + device->SetQueue (queue);
1.365 + node->AddDevice (device);
1.366 +
1.367 + //
1.368 + // Add a default internet stack to the node. This gets us the ns-3 versions
1.369 + // of ARP, IPv4, ICMP, UDP and TCP.
1.370 + //
1.371 + NS_LOG_INFO ("Add Internet Stack");
1.372 + AddInternetStack (node);
1.373 +
1.374 + NS_LOG_INFO ("Create IPv4 Interface");
1.375 + Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
1.376 + uint32_t interface = ipv4->AddInterface (device);
1.377 + Ipv4InterfaceAddress address = Ipv4InterfaceAddress (localIp, localMask);
1.378 + ipv4->AddAddress (interface, address);
1.379 + ipv4->SetMetric (interface, 1);
1.380 + ipv4->SetUp (interface);
1.381 +
1.382 + //
1.383 + // When the ping appliation sends its ICMP packet, it will happily send it
1.384 + // down the ns-3 protocol stack. We set the IP address of the destination
1.385 + // to the address corresponding to example.com above. This address is off
1.386 + // our local network so we have got to provide some kind of default route
1.387 + // to ns-3 to be able to get that ICMP packet forwarded off of our network.
1.388 + //
1.389 + // You have got to provide an IP address of a real host that you can send
1.390 + // real packets to and have them forwarded off of your local network. One
1.391 + // thing you could do is a 'netstat -rn' command and find the IP address of
1.392 + // the default gateway on your host and add it below, replacing the
1.393 + // "1.2.3.4" string.
1.394 + //
1.395 + Ipv4Address gateway ("1.2.3.4");
1.396 + NS_ABORT_MSG_IF (gateway == "1.2.3.4", "You must change the gateway IP address before running this example");
1.397 +
1.398 + ipv4->SetDefaultRoute (gateway, interface);
1.399 +
1.400 + //
1.401 + // Create the ping application. This application knows how to send
1.402 + // ICMP echo requests. Setting up the packet sink manually is a bit
1.403 + // of a hassle and since there is no law that says we cannot mix the
1.404 + // helper API with the low level API, let's just use the helper.
1.405 + //
1.406 + NS_LOG_INFO ("Create V4Ping Appliation");
1.407 + Ptr<V4Ping> app = CreateObject<V4Ping> ();
1.408 + app->SetAttribute ("Remote", Ipv4AddressValue (remoteIp));
1.409 + node->AddApplication (app);
1.410 + app->Start (Seconds (1.0));
1.411 + app->Stop (Seconds (5.0));
1.412 +
1.413 + //
1.414 + // Give the application a name. This makes life much easier when constructing
1.415 + // config paths.
1.416 + //
1.417 + Names::Add ("app", app);
1.418 +
1.419 + //
1.420 + // Hook a trace to print something when the response comes back.
1.421 + //
1.422 + Config::Connect ("/Names/app/Rtt", MakeCallback (&PingRtt));
1.423 +
1.424 + //
1.425 + // Enable a promiscuous pcap trace to see what is coming and going on our device.
1.426 + //
1.427 + EmuHelper::EnablePcap ("emu-ping", device, true);
1.428 +
1.429 + //
1.430 + // Now, do the actual emulation.
1.431 + //
1.432 + NS_LOG_INFO ("Run Emulation.");
1.433 + Simulator::Stop (Seconds (5.0));
1.434 + Simulator::Run ();
1.435 + Simulator::Destroy ();
1.436 + NS_LOG_INFO ("Done.");
1.437 +}