internet-apps: add TracerouteV4 application
This commit is contained in:
248
src/internet-apps/examples/traceroute-example.cc
Normal file
248
src/internet-apps/examples/traceroute-example.cc
Normal file
@@ -0,0 +1,248 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2019 Ritsumeikan University, Shiga, Japan
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
|
||||
*
|
||||
*
|
||||
* TraceRoute application example using AODV routing protocol.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ns3/aodv-module.h"
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/network-module.h"
|
||||
#include "ns3/internet-module.h"
|
||||
#include "ns3/mobility-module.h"
|
||||
#include "ns3/point-to-point-module.h"
|
||||
#include "ns3/wifi-module.h"
|
||||
#include "ns3/v4traceroute-helper.h"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
/**
|
||||
* \ingroup aodv-examples
|
||||
* \ingroup examples
|
||||
* \brief Test script.
|
||||
*
|
||||
* This script creates 1-dimensional grid topology and Traceroute the last node from the first one:
|
||||
*
|
||||
* [10.0.0.1] <-- step --> [10.0.0.2] <-- step --> [10.0.0.3] <-- step --> [10.0.0.4]
|
||||
*
|
||||
* The results should be all the intermediate hops all the way to 10.0.0.10
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* traceroute 10.0.0.10
|
||||
*/
|
||||
class TracerouteExample
|
||||
{
|
||||
public:
|
||||
TracerouteExample ();
|
||||
/**
|
||||
* \brief Configure script parameters
|
||||
* \param argc is the command line argument count
|
||||
* \param argv is the command line arguments
|
||||
* \return true on successful configuration
|
||||
*/
|
||||
bool Configure (int argc, char **argv);
|
||||
/// Run simulation
|
||||
void Run ();
|
||||
/**
|
||||
* Report results
|
||||
* \param os the output stream
|
||||
*/
|
||||
void Report (std::ostream & os);
|
||||
|
||||
private:
|
||||
// parameters
|
||||
/// Number of nodes
|
||||
uint32_t size;
|
||||
/// Distance between nodes, meters
|
||||
double step;
|
||||
/// Simulation time, seconds
|
||||
double totalTime;
|
||||
/// Write per-device PCAP traces if true
|
||||
bool pcap;
|
||||
/// Print aodv routes if true
|
||||
bool printRoutes;
|
||||
/// nodes used in the example
|
||||
NodeContainer nodes;
|
||||
/// devices used in the example
|
||||
NetDeviceContainer devices;
|
||||
/// interfaces used in the example
|
||||
Ipv4InterfaceContainer interfaces;
|
||||
|
||||
private:
|
||||
/// Create the nodes
|
||||
void CreateNodes ();
|
||||
/// Create the devices
|
||||
void CreateDevices ();
|
||||
/// Create the network
|
||||
void InstallInternetStack ();
|
||||
/// Create the simulation applications
|
||||
|
||||
void InstallApplications ();
|
||||
};
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
TracerouteExample test;
|
||||
if (!test.Configure (argc, argv))
|
||||
{
|
||||
NS_FATAL_ERROR ("Configuration failed. Aborted.");
|
||||
}
|
||||
|
||||
test.Run ();
|
||||
test.Report (std::cout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
TracerouteExample::TracerouteExample ()
|
||||
: size (10),
|
||||
step (50),
|
||||
totalTime (100),
|
||||
pcap (false),
|
||||
printRoutes (false)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
TracerouteExample::Configure (int argc, char **argv)
|
||||
{
|
||||
// Enable AODV logs by default. Comment this if too noisy
|
||||
// LogComponentEnable("AodvRoutingProtocol", LOG_LEVEL_ALL);
|
||||
|
||||
SeedManager::SetSeed (12345);
|
||||
CommandLine cmd;
|
||||
|
||||
cmd.AddValue ("pcap", "Write PCAP traces.", pcap);
|
||||
cmd.AddValue ("printRoutes", "Print routing table dumps.", printRoutes);
|
||||
cmd.AddValue ("size", "Number of nodes.", size);
|
||||
cmd.AddValue ("time", "Simulation time, s.", totalTime);
|
||||
cmd.AddValue ("step", "Grid step, m", step);
|
||||
|
||||
cmd.Parse (argc, argv);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TracerouteExample::Run ()
|
||||
{
|
||||
CreateNodes ();
|
||||
|
||||
CreateDevices ();
|
||||
|
||||
InstallInternetStack ();
|
||||
|
||||
InstallApplications ();
|
||||
|
||||
std::cout << "Starting simulation for " << totalTime << " s ...\n";
|
||||
|
||||
Simulator::Stop (Seconds (totalTime));
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
}
|
||||
|
||||
void
|
||||
TracerouteExample::Report (std::ostream &)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
TracerouteExample::CreateNodes ()
|
||||
{
|
||||
std::cout << "Creating " << (unsigned)size << " nodes " << step << " m apart.\n";
|
||||
nodes.Create (size);
|
||||
// Name nodes
|
||||
for (uint32_t i = 0; i < size; ++i)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "node-" << i;
|
||||
Names::Add (os.str (), nodes.Get (i));
|
||||
}
|
||||
// Create static grid
|
||||
MobilityHelper mobility;
|
||||
mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
|
||||
"MinX", DoubleValue (0.0),
|
||||
"MinY", DoubleValue (0.0),
|
||||
"DeltaX", DoubleValue (step),
|
||||
"DeltaY", DoubleValue (0),
|
||||
"GridWidth", UintegerValue (size),
|
||||
"LayoutType", StringValue ("RowFirst"));
|
||||
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
|
||||
mobility.Install (nodes);
|
||||
}
|
||||
|
||||
void
|
||||
TracerouteExample::CreateDevices ()
|
||||
{
|
||||
WifiMacHelper wifiMac;
|
||||
wifiMac.SetType ("ns3::AdhocWifiMac");
|
||||
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
|
||||
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
|
||||
wifiPhy.SetChannel (wifiChannel.Create ());
|
||||
WifiHelper wifi;
|
||||
wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue ("OfdmRate6Mbps"), "RtsCtsThreshold", UintegerValue (0));
|
||||
devices = wifi.Install (wifiPhy, wifiMac, nodes);
|
||||
|
||||
if (pcap)
|
||||
{
|
||||
wifiPhy.EnablePcapAll (std::string ("aodv"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TracerouteExample::InstallInternetStack ()
|
||||
{
|
||||
AodvHelper aodv;
|
||||
// you can configure AODV attributes here using aodv.Set(name, value)
|
||||
InternetStackHelper stack;
|
||||
stack.SetRoutingHelper (aodv); // has effect on the next Install ()
|
||||
stack.Install (nodes);
|
||||
Ipv4AddressHelper address;
|
||||
address.SetBase ("10.0.0.0", "255.0.0.0");
|
||||
interfaces = address.Assign (devices);
|
||||
|
||||
if (printRoutes)
|
||||
{
|
||||
Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("aodv.routes", std::ios::out);
|
||||
aodv.PrintRoutingTableAllAt (Seconds (8), routingStream);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TracerouteExample::InstallApplications ()
|
||||
{
|
||||
V4TraceRouteHelper traceroute (Ipv4Address ("10.0.0.10")); //size - 1
|
||||
traceroute.SetAttribute ("Verbose", BooleanValue (true));
|
||||
ApplicationContainer p = traceroute.Install (nodes.Get (0));
|
||||
|
||||
// Used when we wish to dump the traceroute results into a file
|
||||
|
||||
//Ptr<OutputStreamWrapper> printstrm = Create<OutputStreamWrapper> ("mytrace", std::ios::out);
|
||||
//traceroute.PrintTraceRouteAt(nodes.Get(0),printstrm);
|
||||
|
||||
p.Start (Seconds (0));
|
||||
p.Stop (Seconds (totalTime) - Seconds (0.001));
|
||||
|
||||
}
|
||||
|
||||
@@ -5,4 +5,7 @@ def build(bld):
|
||||
return;
|
||||
|
||||
obj = bld.create_ns3_program('dhcp-example', ['internet', 'internet-apps', 'csma', 'point-to-point', 'applications'])
|
||||
obj.source = 'dhcp-example.cc'
|
||||
obj.source = 'dhcp-example.cc'
|
||||
|
||||
obj = bld.create_ns3_program('traceroute-example', ['aodv', 'core', 'network', 'internet', 'point-to-point', 'wifi','internet-apps'])
|
||||
obj.source = 'traceroute-example.cc'
|
||||
94
src/internet-apps/helper/v4traceroute-helper.cc
Normal file
94
src/internet-apps/helper/v4traceroute-helper.cc
Normal file
@@ -0,0 +1,94 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2019 Ritsumeikan University, Shiga, Japan
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*
|
||||
* Author: Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "v4traceroute-helper.h"
|
||||
#include "ns3/v4traceroute.h"
|
||||
#include "ns3/names.h"
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
V4TraceRouteHelper::V4TraceRouteHelper (Ipv4Address remote)
|
||||
{
|
||||
m_factory.SetTypeId ("ns3::V4TraceRoute");
|
||||
m_factory.Set ("Remote", Ipv4AddressValue (remote));
|
||||
}
|
||||
|
||||
void
|
||||
V4TraceRouteHelper::SetAttribute (std::string name, const AttributeValue &value)
|
||||
{
|
||||
m_factory.Set (name, value);
|
||||
}
|
||||
|
||||
ApplicationContainer
|
||||
V4TraceRouteHelper::Install (Ptr<Node> node) const
|
||||
{
|
||||
return ApplicationContainer (InstallPriv (node));
|
||||
}
|
||||
|
||||
ApplicationContainer
|
||||
V4TraceRouteHelper::Install (std::string nodeName) const
|
||||
{
|
||||
Ptr<Node> node = Names::Find<Node> (nodeName);
|
||||
return ApplicationContainer (InstallPriv (node));
|
||||
}
|
||||
|
||||
ApplicationContainer
|
||||
V4TraceRouteHelper::Install (NodeContainer c) const
|
||||
{
|
||||
ApplicationContainer apps;
|
||||
for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
|
||||
{
|
||||
apps.Add (InstallPriv (*i));
|
||||
}
|
||||
|
||||
return apps;
|
||||
}
|
||||
|
||||
Ptr<Application>
|
||||
V4TraceRouteHelper::InstallPriv (Ptr<Node> node) const
|
||||
{
|
||||
Ptr<V4TraceRoute> app = m_factory.Create<V4TraceRoute> ();
|
||||
node->AddApplication (app);
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
void
|
||||
V4TraceRouteHelper::PrintTraceRouteAt (Ptr<Node> node, Ptr<OutputStreamWrapper> stream)
|
||||
{
|
||||
Ptr<V4TraceRoute> trace;
|
||||
|
||||
for (uint32_t i = 0; i < node->GetNApplications (); ++i)
|
||||
{
|
||||
trace = node->GetApplication (i)->GetObject <V4TraceRoute> ();
|
||||
if (trace != NULL)
|
||||
{
|
||||
*stream->GetStream () << "Tracing Route from Node " << node->GetId () << "\n";
|
||||
trace->Print (stream);
|
||||
return;
|
||||
}
|
||||
}
|
||||
NS_ASSERT_MSG (false, "No V4TraceRoute application found in node " << node->GetId ());
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
109
src/internet-apps/helper/v4traceroute-helper.h
Normal file
109
src/internet-apps/helper/v4traceroute-helper.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2019 Ritsumeikan University, Shiga, Japan
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*
|
||||
* Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef V4TRACEROUTE_HELPER_H
|
||||
#define V4TRACEROUTE_HELPER_H
|
||||
|
||||
#include "ns3/node-container.h"
|
||||
#include "ns3/application-container.h"
|
||||
#include "ns3/object-factory.h"
|
||||
#include "ns3/output-stream-wrapper.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \ingroup v4traceroute
|
||||
* \brief Create a IPv4 traceroute application and associate it to a node
|
||||
*
|
||||
* This class creates one or multiple instances of ns3::V4TraceRoute and associates
|
||||
* it/them to one/multiple node(s).
|
||||
*/
|
||||
class V4TraceRouteHelper
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a V4TraceRouteHelper which is used to make life easier for people wanting
|
||||
* to use TraceRoute
|
||||
*
|
||||
* \param remote The address which should be traced
|
||||
*/
|
||||
V4TraceRouteHelper (Ipv4Address remote);
|
||||
|
||||
/**
|
||||
* Install a TraceRoute application on each Node in the provided NodeContainer.
|
||||
*
|
||||
* \param nodes The NodeContainer containing all of the nodes to get a V4TraceRoute
|
||||
* application.
|
||||
*
|
||||
* \returns A list of TraceRoute applications, one for each input node
|
||||
*/
|
||||
ApplicationContainer Install (NodeContainer nodes) const;
|
||||
|
||||
/**
|
||||
* Install a TraceRoute application on the provided Node. The Node is specified
|
||||
* directly by a Ptr<Node>
|
||||
*
|
||||
* \param node The node to install the V4TraceRouteApplication on.
|
||||
*
|
||||
* \returns An ApplicationContainer holding the TraceRoute application created.
|
||||
*/
|
||||
ApplicationContainer Install (Ptr<Node> node) const;
|
||||
|
||||
/**
|
||||
* Install a TraceRoute application on the provided Node. The Node is specified
|
||||
* by a string that must have previously been associated with a Node using the
|
||||
* Object Name Service.
|
||||
*
|
||||
* \param nodeName The node to install the V4TraceRouteApplication on.
|
||||
*
|
||||
* \returns An ApplicationContainer holding the TraceRoute application created.
|
||||
*/
|
||||
ApplicationContainer Install (std::string nodeName) const;
|
||||
|
||||
/**
|
||||
* \brief Configure traceRoute applications attribute
|
||||
* \param name attribute's name
|
||||
* \param value attribute's value
|
||||
*/
|
||||
void SetAttribute (std::string name, const AttributeValue &value);
|
||||
/**
|
||||
* \brief Print the resulting trace routes from given node.
|
||||
* \param node The origin node where the traceroute is initiated.
|
||||
* \param stream The outputstream used to print the resulting traced routes.
|
||||
*/
|
||||
static void PrintTraceRouteAt (Ptr<Node> node, Ptr<OutputStreamWrapper> stream);
|
||||
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Do the actual application installation in the node
|
||||
* \param node the node
|
||||
* \returns a Smart pointer to the installed application
|
||||
*/
|
||||
Ptr<Application> InstallPriv (Ptr<Node> node) const;
|
||||
/// Object factory
|
||||
ObjectFactory m_factory;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* V4TRACEROUTE_HELPER_H */
|
||||
469
src/internet-apps/model/v4traceroute.cc
Normal file
469
src/internet-apps/model/v4traceroute.cc
Normal file
@@ -0,0 +1,469 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2019 Ritsumeikan University, Shiga, Japan
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Alberto Gallegos Ramonet
|
||||
*
|
||||
* Traceroute uses ICMPV4 echo messages to trace all the middle hops to a given destination.
|
||||
* It also shows the delay time it takes for a round trip to complete for each
|
||||
* set probe (default 3).
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "v4traceroute.h"
|
||||
#include "ns3/icmpv4.h"
|
||||
#include "ns3/icmpv4-l4-protocol.h"
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ns3/socket.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "ns3/boolean.h"
|
||||
#include "ns3/inet-socket-address.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/trace-source-accessor.h"
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("V4TraceRoute");
|
||||
NS_OBJECT_ENSURE_REGISTERED (V4TraceRoute);
|
||||
|
||||
TypeId
|
||||
V4TraceRoute::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::V4TraceRoute")
|
||||
.SetParent<Application> ()
|
||||
.SetGroupName ("Internet-Apps")
|
||||
.AddConstructor<V4TraceRoute> ()
|
||||
.AddAttribute ("Remote",
|
||||
"The address of the machine we want to trace.",
|
||||
Ipv4AddressValue (),
|
||||
MakeIpv4AddressAccessor (&V4TraceRoute::m_remote),
|
||||
MakeIpv4AddressChecker ())
|
||||
.AddAttribute ("Verbose",
|
||||
"Produce usual output.",
|
||||
BooleanValue (true),
|
||||
MakeBooleanAccessor (&V4TraceRoute::m_verbose),
|
||||
MakeBooleanChecker ())
|
||||
.AddAttribute ("Interval", "Wait interval between sent packets.",
|
||||
TimeValue (Seconds (0)),
|
||||
MakeTimeAccessor (&V4TraceRoute::m_interval),
|
||||
MakeTimeChecker ())
|
||||
.AddAttribute ("Size", "The number of data bytes to be sent, real packet will be 8 (ICMP) + 20 (IP) bytes longer.",
|
||||
UintegerValue (56),
|
||||
MakeUintegerAccessor (&V4TraceRoute::m_size),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.AddAttribute ("MaxHop", "The maximum number of hops to trace.",
|
||||
UintegerValue (30),
|
||||
MakeUintegerAccessor (&V4TraceRoute::m_maxTtl),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.AddAttribute ("ProbeNum", "The number of packets send to each hop.",
|
||||
UintegerValue (3),
|
||||
MakeUintegerAccessor (&V4TraceRoute::m_maxProbes),
|
||||
MakeUintegerChecker<uint16_t> ())
|
||||
.AddAttribute ("Timeout", "The waiting time for a route response before a timeout.",
|
||||
TimeValue (Seconds (5)),
|
||||
MakeTimeAccessor (&V4TraceRoute::m_waitIcmpReplyTimeout),
|
||||
MakeTimeChecker ())
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
|
||||
V4TraceRoute::V4TraceRoute ()
|
||||
: m_interval (Seconds (0)),
|
||||
m_size (56),
|
||||
m_socket (0),
|
||||
m_seq (0),
|
||||
m_verbose (true),
|
||||
m_probeCount (0),
|
||||
m_maxProbes (3),
|
||||
m_ttl (1),
|
||||
m_maxTtl (30),
|
||||
m_waitIcmpReplyTimeout (Seconds (5))
|
||||
{
|
||||
osRoute.clear ();
|
||||
routeIpv4.clear ();
|
||||
|
||||
}
|
||||
|
||||
V4TraceRoute::~V4TraceRoute ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
V4TraceRoute::Print (Ptr<OutputStreamWrapper> stream)
|
||||
{
|
||||
printStream = stream;
|
||||
}
|
||||
|
||||
void
|
||||
V4TraceRoute::StartApplication (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_LOG_LOGIC ("Application started");
|
||||
m_started = Simulator::Now ();
|
||||
|
||||
if (m_verbose)
|
||||
{
|
||||
NS_LOG_UNCOND("Traceroute to " << m_remote << ", "
|
||||
<< m_maxTtl << " hops Max, "
|
||||
<< m_size << " bytes of data.");
|
||||
}
|
||||
|
||||
if (printStream != NULL)
|
||||
{
|
||||
*printStream->GetStream () << "Traceroute to " << m_remote << ", "
|
||||
<< m_maxTtl << " hops Max, "
|
||||
<< m_size << " bytes of data.\n";
|
||||
}
|
||||
|
||||
|
||||
m_socket = Socket::CreateSocket (GetNode (), TypeId::LookupByName ("ns3::Ipv4RawSocketFactory"));
|
||||
m_socket->SetAttribute ("Protocol", UintegerValue (Icmpv4L4Protocol::PROT_NUMBER));
|
||||
|
||||
|
||||
NS_ASSERT (m_socket != 0);
|
||||
m_socket->SetRecvCallback (MakeCallback (&V4TraceRoute::Receive, this));
|
||||
|
||||
InetSocketAddress src = InetSocketAddress (Ipv4Address::GetAny (), 0);
|
||||
int status;
|
||||
status = m_socket->Bind (src);
|
||||
NS_ASSERT (status != -1);
|
||||
|
||||
m_next = Simulator::ScheduleNow (&V4TraceRoute::StartWaitReplyTimer, this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
V4TraceRoute::StopApplication (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
if (m_next.IsRunning ())
|
||||
{
|
||||
m_next.Cancel ();
|
||||
}
|
||||
|
||||
if (m_waitIcmpReplyTimer.IsRunning ())
|
||||
{
|
||||
m_waitIcmpReplyTimer.Cancel ();
|
||||
}
|
||||
|
||||
if (m_socket)
|
||||
{
|
||||
m_socket->Close ();
|
||||
}
|
||||
|
||||
if (m_verbose)
|
||||
{
|
||||
NS_LOG_UNCOND("\nTrace Complete");
|
||||
}
|
||||
|
||||
if (printStream != NULL)
|
||||
{
|
||||
*printStream->GetStream () << "Trace Complete\n" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
V4TraceRoute::DoDispose (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
if (m_next.IsRunning () || m_waitIcmpReplyTimer.IsRunning ())
|
||||
{
|
||||
StopApplication ();
|
||||
}
|
||||
|
||||
m_socket = 0;
|
||||
Application::DoDispose ();
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
V4TraceRoute::GetApplicationId (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
Ptr<Node> node = GetNode ();
|
||||
for (uint32_t i = 0; i < node->GetNApplications (); ++i)
|
||||
{
|
||||
if (node->GetApplication (i) == this)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
NS_ASSERT_MSG (false, "forgot to add application to node");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
V4TraceRoute::Receive (Ptr<Socket> socket)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << socket);
|
||||
|
||||
while (m_socket->GetRxAvailable () > 0)
|
||||
{
|
||||
Address from;
|
||||
Ptr<Packet> p = m_socket->RecvFrom (0xffffffff, 0, from);
|
||||
NS_LOG_DEBUG ("recv " << p->GetSize () << " bytes");
|
||||
NS_ASSERT (InetSocketAddress::IsMatchingType (from));
|
||||
InetSocketAddress realFrom = InetSocketAddress::ConvertFrom (from);
|
||||
NS_ASSERT (realFrom.GetPort () == 1);
|
||||
Ipv4Header ipv4;
|
||||
p->RemoveHeader (ipv4);
|
||||
NS_ASSERT (ipv4.GetProtocol () == Icmpv4L4Protocol::PROT_NUMBER);
|
||||
Icmpv4Header icmp;
|
||||
p->RemoveHeader (icmp);
|
||||
|
||||
|
||||
|
||||
if (icmp.GetType () == Icmpv4Header::ICMPV4_TIME_EXCEEDED)
|
||||
{
|
||||
|
||||
Icmpv4TimeExceeded timeoutResp;
|
||||
p->RemoveHeader (timeoutResp);
|
||||
|
||||
// GetData () gets 64 bits of data, but the received packet
|
||||
// only contains 32 bits of data.
|
||||
uint8_t data [8];
|
||||
timeoutResp.GetData (data);
|
||||
|
||||
// Get the 7th and 8th Octect to obtain the Sequence number from
|
||||
// the original packet.
|
||||
uint16_t recvSeq;
|
||||
recvSeq = (uint16_t) data[7] << 0;
|
||||
recvSeq |= (uint16_t) data [6] << 8;
|
||||
|
||||
|
||||
std::map<uint16_t, Time>::iterator i = m_sent.find (recvSeq);
|
||||
if (i != m_sent.end ())
|
||||
{
|
||||
Time sendTime = i->second;
|
||||
NS_ASSERT (Simulator::Now () >= sendTime);
|
||||
Time delta = Simulator::Now () - sendTime;
|
||||
|
||||
routeIpv4.str ("");
|
||||
routeIpv4.clear ();
|
||||
routeIpv4 << realFrom.GetIpv4 ();
|
||||
osRoute << delta.GetMilliSeconds () << " ms ";
|
||||
if (m_probeCount == m_maxProbes)
|
||||
{
|
||||
if (m_verbose)
|
||||
{
|
||||
NS_LOG_UNCOND(m_ttl << " " << routeIpv4.str () << " " << osRoute.str ());
|
||||
}
|
||||
|
||||
if (printStream != NULL)
|
||||
{
|
||||
*printStream->GetStream () << m_ttl << " "
|
||||
<< routeIpv4.str () << " "
|
||||
<< osRoute.str () << "\n";
|
||||
}
|
||||
osRoute.str ("");
|
||||
osRoute.clear ();
|
||||
routeIpv4.str ("");
|
||||
routeIpv4.clear ();
|
||||
|
||||
}
|
||||
|
||||
m_waitIcmpReplyTimer.Cancel ();
|
||||
|
||||
if (m_ttl < m_maxTtl + 1)
|
||||
{
|
||||
m_next = Simulator::Schedule (m_interval, &V4TraceRoute::StartWaitReplyTimer, this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (icmp.GetType () == Icmpv4Header::ICMPV4_ECHO_REPLY && m_remote == realFrom.GetIpv4 ())
|
||||
{
|
||||
// When UDP is used, TraceRoute should stop until ICMPV4_DEST_UNREACH
|
||||
// (with code (3) PORT_UNREACH) is received, however, the current
|
||||
// ns-3 implementation does not include the UDP version of traceroute.
|
||||
// The traceroute ICMP version (the current version) stops until max_ttl is reached
|
||||
// or until an ICMP ECHO REPLY is received m_maxProbes times.
|
||||
|
||||
Icmpv4Echo echo;
|
||||
p->RemoveHeader (echo);
|
||||
std::map<uint16_t, Time>::iterator i = m_sent.find (echo.GetSequenceNumber ());
|
||||
|
||||
if (i != m_sent.end () && echo.GetIdentifier () == 0)
|
||||
{
|
||||
uint32_t * buf = new uint32_t [m_size];
|
||||
uint32_t dataSize = echo.GetDataSize ();
|
||||
|
||||
if (dataSize == m_size)
|
||||
{
|
||||
echo.GetData ((uint8_t *)buf);
|
||||
|
||||
Time sendTime = i->second;
|
||||
NS_ASSERT (Simulator::Now () >= sendTime);
|
||||
Time delta = Simulator::Now () - sendTime;
|
||||
|
||||
m_sent.erase (i);
|
||||
|
||||
if (m_verbose)
|
||||
{
|
||||
routeIpv4.str ("");
|
||||
routeIpv4.clear ();
|
||||
routeIpv4 << realFrom.GetIpv4 ();
|
||||
osRoute << delta.GetMilliSeconds () << " ms ";
|
||||
|
||||
if (m_probeCount == m_maxProbes)
|
||||
{
|
||||
NS_LOG_UNCOND(m_ttl << " " << routeIpv4.str () << " " << osRoute.str ());
|
||||
if (printStream != NULL)
|
||||
{
|
||||
*printStream->GetStream () << m_ttl << " "
|
||||
<< routeIpv4.str () << " "
|
||||
<< osRoute.str () << "\n";
|
||||
}
|
||||
|
||||
osRoute.clear ();
|
||||
routeIpv4.clear ();
|
||||
}
|
||||
}
|
||||
}
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
m_waitIcmpReplyTimer.Cancel ();
|
||||
if (m_probeCount == m_maxProbes)
|
||||
{
|
||||
StopApplication ();
|
||||
}
|
||||
else if (m_ttl < m_maxTtl + 1)
|
||||
{
|
||||
m_next = Simulator::Schedule (m_interval, &V4TraceRoute::StartWaitReplyTimer, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
V4TraceRoute::Send ()
|
||||
{
|
||||
NS_LOG_INFO ("m_seq=" << m_seq);
|
||||
Ptr<Packet> p = Create<Packet> ();
|
||||
Icmpv4Echo echo;
|
||||
echo.SetSequenceNumber (m_seq);
|
||||
m_seq++;
|
||||
echo.SetIdentifier (0);
|
||||
|
||||
//
|
||||
// We must write quantities out in some form of network order. Since there
|
||||
// isn't an htonl to work with we just follow the convention in pcap traces
|
||||
// (where any difference would show up anyway) and borrow that code. Don't
|
||||
// be too surprised when you see that this is a little endian convention.
|
||||
//
|
||||
uint8_t* data = new uint8_t[m_size];
|
||||
for (uint32_t i = 0; i < m_size; ++i)
|
||||
{
|
||||
data[i] = 0;
|
||||
}
|
||||
NS_ASSERT (m_size >= 16);
|
||||
|
||||
Ptr<Packet> dataPacket = Create<Packet> ((uint8_t *) data, m_size);
|
||||
echo.SetData (dataPacket);
|
||||
p->AddHeader (echo);
|
||||
Icmpv4Header header;
|
||||
header.SetType (Icmpv4Header::ICMPV4_ECHO);
|
||||
header.SetCode (0);
|
||||
if (Node::ChecksumEnabled ())
|
||||
{
|
||||
header.EnableChecksum ();
|
||||
}
|
||||
|
||||
p->AddHeader (header);
|
||||
|
||||
if (m_probeCount < m_maxProbes)
|
||||
{
|
||||
m_probeCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_probeCount = 1;
|
||||
m_ttl++;
|
||||
}
|
||||
|
||||
m_sent.insert (std::make_pair (m_seq - 1, Simulator::Now ()));
|
||||
m_socket->SetIpTtl (m_ttl);
|
||||
|
||||
|
||||
InetSocketAddress dst = InetSocketAddress (m_remote, 0);
|
||||
m_socket->SendTo (p, 0, dst);
|
||||
|
||||
delete[] data;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
V4TraceRoute::StartWaitReplyTimer (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
if (!m_waitIcmpReplyTimer.IsRunning ())
|
||||
{
|
||||
NS_LOG_LOGIC ("Starting WaitIcmpReplyTimer at " << Simulator::Now () << " for " <<
|
||||
m_waitIcmpReplyTimeout);
|
||||
|
||||
m_waitIcmpReplyTimer = Simulator::Schedule (m_waitIcmpReplyTimeout,
|
||||
&V4TraceRoute::HandleWaitReplyTimeout, this);
|
||||
Send ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
V4TraceRoute::HandleWaitReplyTimeout (void)
|
||||
{
|
||||
if (m_ttl < m_maxTtl + 1)
|
||||
{
|
||||
m_next = Simulator::Schedule (m_interval, &V4TraceRoute::StartWaitReplyTimer, this);
|
||||
}
|
||||
|
||||
osRoute << "* ";
|
||||
if (m_probeCount == m_maxProbes)
|
||||
{
|
||||
if (m_verbose)
|
||||
{
|
||||
NS_LOG_UNCOND(m_ttl << " " << routeIpv4.str () << " " << osRoute.str ());
|
||||
}
|
||||
|
||||
if (printStream != NULL)
|
||||
{
|
||||
*printStream->GetStream () << m_ttl
|
||||
<< " " << routeIpv4.str () << " "
|
||||
<< osRoute.str () << "\n";
|
||||
}
|
||||
osRoute.str ("");
|
||||
osRoute.clear ();
|
||||
routeIpv4.str ("");
|
||||
routeIpv4.clear ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // ns3 namespace
|
||||
142
src/internet-apps/model/v4traceroute.h
Normal file
142
src/internet-apps/model/v4traceroute.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2019 Ritsumeikan University, Shiga, Japan
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef V4TRACEROUTE_H
|
||||
#define V4TRACEROUTE_H
|
||||
|
||||
#include "ns3/application.h"
|
||||
#include "ns3/traced-callback.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/average.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/output-stream-wrapper.h"
|
||||
#include <map>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Socket;
|
||||
|
||||
/**
|
||||
* \ingroup internet-apps
|
||||
* \defgroup v4traceroute V4Traceroute
|
||||
*/
|
||||
|
||||
/**
|
||||
* \ingroup v4traceroute
|
||||
* \brief Traceroute application sends one ICMP ECHO request with TTL=1,
|
||||
* and after receiving an ICMP TIME EXCEED reply, it increases the
|
||||
* TTL and repeat the process to reveal all the intermediate hops to
|
||||
* the destination.
|
||||
*
|
||||
*/
|
||||
class V4TraceRoute : public Application
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
V4TraceRoute ();
|
||||
virtual ~V4TraceRoute ();
|
||||
/**
|
||||
* \brief Prints the application traced routes into a given OutputStream.
|
||||
*/
|
||||
void Print (Ptr<OutputStreamWrapper> stream);
|
||||
|
||||
private:
|
||||
virtual void StartApplication (void);
|
||||
virtual void StopApplication (void);
|
||||
virtual void DoDispose (void);
|
||||
/**
|
||||
* \brief Return the application ID in the node.
|
||||
* \returns the application id
|
||||
*/
|
||||
uint32_t GetApplicationId (void) const;
|
||||
/**
|
||||
* \brief Receive an ICMP Echo
|
||||
* \param socket the receiving socket
|
||||
*
|
||||
* This function is called by lower layers through a callback.
|
||||
*/
|
||||
void Receive (Ptr<Socket> socket);
|
||||
|
||||
/** \brief Send one (ICMP ECHO) to the destination.*/
|
||||
void Send ();
|
||||
|
||||
/** \brief Starts a timer after sending an ICMP ECHO.*/
|
||||
void StartWaitReplyTimer ();
|
||||
|
||||
/** \brief Triggers an action if an ICMP TIME EXCEED have not being received
|
||||
* in the time defined by StartWaitReplyTimer.
|
||||
*/
|
||||
void HandleWaitReplyTimeout ();
|
||||
|
||||
/// Remote address
|
||||
Ipv4Address m_remote;
|
||||
|
||||
/// Wait interval seconds between sending each packet
|
||||
Time m_interval;
|
||||
/**
|
||||
* Specifies the number of data bytes to be sent.
|
||||
* The default is 56, which translates into 64 ICMP data bytes when
|
||||
* combined with the 8 bytes of ICMP header data.
|
||||
*/
|
||||
uint32_t m_size;
|
||||
/// The socket we send packets from
|
||||
Ptr<Socket> m_socket;
|
||||
/// ICMP ECHO sequence number
|
||||
uint16_t m_seq;
|
||||
/// produce traceroute style output if true
|
||||
bool m_verbose;
|
||||
/// Start time to report total ping time
|
||||
Time m_started;
|
||||
/// Next packet will be sent
|
||||
EventId m_next;
|
||||
/// The Current probe value
|
||||
uint32_t m_probeCount;
|
||||
/// The maximum number of probe packets per hop
|
||||
u_int16_t m_maxProbes;
|
||||
/// The current TTL value
|
||||
uint16_t m_ttl;
|
||||
/// The maximium Ttl (Max number of hops to trace)
|
||||
uint32_t m_maxTtl;
|
||||
/// The wait time until the response is considered lost.
|
||||
Time m_waitIcmpReplyTimeout;
|
||||
/// The timer used to wait for the probes ICMP replies
|
||||
EventId m_waitIcmpReplyTimer;
|
||||
/// All sent but not answered packets. Map icmp seqno -> when sent
|
||||
std::map<uint16_t, Time> m_sent;
|
||||
/// Stream of characters used for printing the traceroute results
|
||||
std::ostringstream os;
|
||||
/// Stream of characters used for printing a single route
|
||||
std::ostringstream osRoute;
|
||||
/// The Ipv4 address of the latest hop found
|
||||
std::ostringstream routeIpv4;
|
||||
/// Stream of the traceroute used for the output file
|
||||
Ptr<OutputStreamWrapper> printStream;
|
||||
|
||||
|
||||
};
|
||||
|
||||
} //ns3 namespace
|
||||
|
||||
#endif /*V4TRACEROUTE_H*/
|
||||
@@ -14,12 +14,14 @@ def build(bld):
|
||||
'model/radvd-prefix.cc',
|
||||
'model/radvd.cc',
|
||||
'model/v4ping.cc',
|
||||
'model/v4traceroute.cc',
|
||||
'model/dhcp-header.cc',
|
||||
'model/dhcp-server.cc',
|
||||
'model/dhcp-client.cc',
|
||||
'helper/ping6-helper.cc',
|
||||
'helper/radvd-helper.cc',
|
||||
'helper/v4ping-helper.cc',
|
||||
'helper/v4traceroute-helper.cc',
|
||||
'helper/dhcp-helper.cc',
|
||||
]
|
||||
|
||||
@@ -36,11 +38,13 @@ def build(bld):
|
||||
'model/radvd-interface.h',
|
||||
'model/radvd-prefix.h',
|
||||
'model/v4ping.h',
|
||||
'model/v4traceroute.h',
|
||||
'model/dhcp-header.h',
|
||||
'model/dhcp-server.h',
|
||||
'model/dhcp-client.h',
|
||||
'helper/ping6-helper.h',
|
||||
'helper/v4ping-helper.h',
|
||||
'helper/v4traceroute-helper.h',
|
||||
'helper/radvd-helper.h',
|
||||
'helper/dhcp-helper.h',
|
||||
]
|
||||
@@ -49,4 +53,3 @@ def build(bld):
|
||||
bld.recurse('examples')
|
||||
|
||||
bld.ns3_python_bindings()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user