Traceroute fixes
- Group definition in v4traceroute.h - Documentation added to V4TraceRoute class - Indentention fixed using check-style.py - Debug, commented code removed - Use of constant Icmpv4L4Protocol::PROT_NUMBER - Automatic search of Traceroute in PrintTraceRouteAt (v4traceroute-helper.cc) - Remove of the word seconds in Interval Attribute description (v4traceroute.cc) - Remove of NodeId and AppId from the packet payload. - Rephrase some comments for clarity and additional info
This commit is contained in:
@@ -29,7 +29,7 @@
|
||||
#include "ns3/internet-module.h"
|
||||
#include "ns3/mobility-module.h"
|
||||
#include "ns3/point-to-point-module.h"
|
||||
#include "ns3/wifi-module.h"
|
||||
#include "ns3/wifi-module.h"
|
||||
#include "ns3/v4traceroute-helper.h"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
@@ -40,11 +40,13 @@ 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
|
||||
@@ -69,7 +71,6 @@ public:
|
||||
void Report (std::ostream & os);
|
||||
|
||||
private:
|
||||
|
||||
// parameters
|
||||
/// Number of nodes
|
||||
uint32_t size;
|
||||
@@ -104,7 +105,9 @@ int main (int argc, char **argv)
|
||||
{
|
||||
TracerouteExample test;
|
||||
if (!test.Configure (argc, argv))
|
||||
NS_FATAL_ERROR ("Configuration failed. Aborted.");
|
||||
{
|
||||
NS_FATAL_ERROR ("Configuration failed. Aborted.");
|
||||
}
|
||||
|
||||
test.Run ();
|
||||
test.Report (std::cout);
|
||||
@@ -112,12 +115,12 @@ int main (int argc, char **argv)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
TracerouteExample::TracerouteExample () :
|
||||
size (10),
|
||||
step (50),
|
||||
totalTime (100),
|
||||
pcap (false),
|
||||
printRoutes (false)
|
||||
TracerouteExample::TracerouteExample ()
|
||||
: size (10),
|
||||
step (50),
|
||||
totalTime (100),
|
||||
pcap (false),
|
||||
printRoutes (false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -160,7 +163,7 @@ TracerouteExample::Run ()
|
||||
|
||||
void
|
||||
TracerouteExample::Report (std::ostream &)
|
||||
{
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
@@ -198,7 +201,7 @@ TracerouteExample::CreateDevices ()
|
||||
wifiPhy.SetChannel (wifiChannel.Create ());
|
||||
WifiHelper wifi;
|
||||
wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue ("OfdmRate6Mbps"), "RtsCtsThreshold", UintegerValue (0));
|
||||
devices = wifi.Install (wifiPhy, wifiMac, nodes);
|
||||
devices = wifi.Install (wifiPhy, wifiMac, nodes);
|
||||
|
||||
if (pcap)
|
||||
{
|
||||
@@ -229,14 +232,14 @@ TracerouteExample::InstallInternetStack ()
|
||||
void
|
||||
TracerouteExample::InstallApplications ()
|
||||
{
|
||||
V4TraceRouteHelper traceroute (Ipv4Address("10.0.0.10")); //size - 1
|
||||
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);
|
||||
//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));
|
||||
|
||||
@@ -33,7 +33,6 @@ V4TraceRouteHelper::V4TraceRouteHelper (Ipv4Address remote)
|
||||
m_factory.Set ("Remote", Ipv4AddressValue (remote));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
V4TraceRouteHelper::SetAttribute (std::string name, const AttributeValue &value)
|
||||
{
|
||||
@@ -77,12 +76,19 @@ V4TraceRouteHelper::InstallPriv (Ptr<Node> node) const
|
||||
void
|
||||
V4TraceRouteHelper::PrintTraceRouteAt (Ptr<Node> node, Ptr<OutputStreamWrapper> stream)
|
||||
{
|
||||
Ptr<V4TraceRoute> trace = node->GetApplication(0)->GetObject <V4TraceRoute>();
|
||||
if (trace)
|
||||
Ptr<V4TraceRoute> trace;
|
||||
|
||||
for (uint32_t i = 0; i < node->GetNApplications (); ++i)
|
||||
{
|
||||
*stream->GetStream() <<"Tracing Route from Node "<<node->GetId()<<"\n";
|
||||
trace->Print(stream);
|
||||
}
|
||||
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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2019 Ritsumeikan University
|
||||
* 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
|
||||
@@ -16,7 +16,7 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*
|
||||
* Alberto Gallegos <ramonet@fc.ritsumei.ac.jp>
|
||||
* Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2019 Ritsumeikan University
|
||||
* 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
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#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"
|
||||
@@ -47,7 +48,7 @@ V4TraceRoute::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::V4TraceRoute")
|
||||
.SetParent<Application> ()
|
||||
.SetGroupName("Internet-Apps")
|
||||
.SetGroupName ("Internet-Apps")
|
||||
.AddConstructor<V4TraceRoute> ()
|
||||
.AddAttribute ("Remote",
|
||||
"The address of the machine we want to trace.",
|
||||
@@ -56,10 +57,10 @@ V4TraceRoute::GetTypeId (void)
|
||||
MakeIpv4AddressChecker ())
|
||||
.AddAttribute ("Verbose",
|
||||
"Produce usual output.",
|
||||
BooleanValue (false),
|
||||
BooleanValue (true),
|
||||
MakeBooleanAccessor (&V4TraceRoute::m_verbose),
|
||||
MakeBooleanChecker ())
|
||||
.AddAttribute ("Interval", "Wait interval seconds between sending each packet.",
|
||||
.AddAttribute ("Interval", "Wait interval between sent packets.",
|
||||
TimeValue (Seconds (0)),
|
||||
MakeTimeAccessor (&V4TraceRoute::m_interval),
|
||||
MakeTimeChecker ())
|
||||
@@ -67,35 +68,35 @@ V4TraceRoute::GetTypeId (void)
|
||||
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 ())
|
||||
.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_recv (0),
|
||||
m_probeCount(0),
|
||||
m_maxProbes(3),
|
||||
m_ttl (1),
|
||||
m_maxTtl (30),
|
||||
m_waitIcmpReplyTimeout (Seconds (5))
|
||||
: m_interval (Seconds (0)),
|
||||
m_size (56),
|
||||
m_socket (0),
|
||||
m_seq (0),
|
||||
m_verbose (true),
|
||||
m_recv (0),
|
||||
m_probeCount (0),
|
||||
m_maxProbes (3),
|
||||
m_ttl (1),
|
||||
m_maxTtl (30),
|
||||
m_waitIcmpReplyTimeout (Seconds (5))
|
||||
{
|
||||
osRoute.clear ();
|
||||
routeIpv4.clear ();
|
||||
@@ -111,33 +112,33 @@ V4TraceRoute::~V4TraceRoute ()
|
||||
void
|
||||
V4TraceRoute::Print (Ptr<OutputStreamWrapper> stream)
|
||||
{
|
||||
printStream = stream;
|
||||
printStream = stream;
|
||||
}
|
||||
|
||||
void
|
||||
V4TraceRoute::StartApplication (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
std::cout<<"Application started\n";
|
||||
NS_LOG_LOGIC ("Application started");
|
||||
m_started = Simulator::Now ();
|
||||
|
||||
if (m_verbose)
|
||||
{
|
||||
std::cout << "Traceroute to " << m_remote <<", "
|
||||
<<m_maxTtl<<" hops Max, "
|
||||
<<m_size<<" bytes of data.\n";
|
||||
}
|
||||
|
||||
if(printStream != NULL)
|
||||
{
|
||||
*printStream->GetStream ()<<"Traceroute to " << m_remote <<", "
|
||||
<<m_maxTtl<<" hops Max, "
|
||||
<<m_size<<" bytes of data.\n";
|
||||
std::cout << "Traceroute to " << m_remote << ", "
|
||||
<< m_maxTtl << " hops Max, "
|
||||
<< m_size << " bytes of data.\n";
|
||||
}
|
||||
|
||||
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 (1)); // icmp
|
||||
m_socket->SetAttribute ("Protocol", UintegerValue (Icmpv4L4Protocol::PROT_NUMBER));
|
||||
|
||||
|
||||
NS_ASSERT (m_socket != 0);
|
||||
@@ -163,9 +164,9 @@ V4TraceRoute::StopApplication (void)
|
||||
m_next.Cancel ();
|
||||
}
|
||||
|
||||
if (m_waitIcmpReplyTimer.IsRunning())
|
||||
if (m_waitIcmpReplyTimer.IsRunning ())
|
||||
{
|
||||
m_waitIcmpReplyTimer.Cancel();
|
||||
m_waitIcmpReplyTimer.Cancel ();
|
||||
}
|
||||
|
||||
if (m_socket)
|
||||
@@ -174,10 +175,14 @@ V4TraceRoute::StopApplication (void)
|
||||
}
|
||||
|
||||
if (m_verbose)
|
||||
std::cout<<"\nTrace Complete\n";
|
||||
{
|
||||
std::cout << "\nTrace Complete\n";
|
||||
}
|
||||
|
||||
if (printStream != NULL)
|
||||
*printStream->GetStream () <<"Trace Complete\n"<< std::endl;
|
||||
{
|
||||
*printStream->GetStream () << "Trace Complete\n" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -185,7 +190,7 @@ V4TraceRoute::DoDispose (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
if (m_next.IsRunning () || m_waitIcmpReplyTimer.IsRunning())
|
||||
if (m_next.IsRunning () || m_waitIcmpReplyTimer.IsRunning ())
|
||||
{
|
||||
StopApplication ();
|
||||
}
|
||||
@@ -217,174 +222,150 @@ 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); // protocol should be icmp.
|
||||
Ipv4Header ipv4;
|
||||
p->RemoveHeader (ipv4);
|
||||
NS_ASSERT (ipv4.GetProtocol () == 1); // protocol should be icmp.
|
||||
Icmpv4Header icmp;
|
||||
p->RemoveHeader (icmp);
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (icmp.GetType () == Icmpv4Header::ICMPV4_TIME_EXCEEDED)
|
||||
{
|
||||
|
||||
Icmpv4TimeExceeded timeoutResp;
|
||||
p->RemoveHeader(timeoutResp);
|
||||
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);
|
||||
// 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;
|
||||
// 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;
|
||||
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)
|
||||
std::cout<<m_ttl<<" "<<routeIpv4.str()<<" "<<osRoute.str()<<"\n";
|
||||
routeIpv4.str ("");
|
||||
routeIpv4.clear ();
|
||||
routeIpv4 << realFrom.GetIpv4 ();
|
||||
osRoute << delta.GetMilliSeconds () << " ms ";
|
||||
if (m_probeCount == m_maxProbes)
|
||||
{
|
||||
if (m_verbose)
|
||||
{
|
||||
std::cout << m_ttl << " " << routeIpv4.str () << " " << osRoute.str () << "\n";
|
||||
}
|
||||
|
||||
if (printStream != NULL)
|
||||
{
|
||||
*printStream->GetStream ()<<m_ttl<<" "
|
||||
<<routeIpv4.str()<<" "
|
||||
<<osRoute.str()<<"\n";
|
||||
}
|
||||
osRoute.str("");
|
||||
osRoute.clear();
|
||||
routeIpv4.str("");
|
||||
routeIpv4.clear();
|
||||
if (printStream != NULL)
|
||||
{
|
||||
*printStream->GetStream () << m_ttl << " "
|
||||
<< routeIpv4.str () << " "
|
||||
<< osRoute.str () << "\n";
|
||||
}
|
||||
osRoute.str ("");
|
||||
osRoute.clear ();
|
||||
routeIpv4.str ("");
|
||||
routeIpv4.clear ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
m_waitIcmpReplyTimer.Cancel();
|
||||
m_waitIcmpReplyTimer.Cancel ();
|
||||
|
||||
if (m_ttl < m_maxTtl+1)
|
||||
m_next = Simulator::Schedule (m_interval, &V4TraceRoute::StartWaitReplyTimer, this);
|
||||
}
|
||||
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
|
||||
// , so only the version ICMP packets is used and stop until max_ttl is reached
|
||||
// or until an echo_reply is received m_maxProbes times.
|
||||
}
|
||||
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 ());
|
||||
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 ();
|
||||
uint32_t nodeId;
|
||||
uint32_t appId;
|
||||
if (dataSize == m_size)
|
||||
{
|
||||
echo.GetData ((uint8_t *)buf);
|
||||
Read32 ((const uint8_t *) &buf[0], nodeId);
|
||||
Read32 ((const uint8_t *) &buf[1], appId);
|
||||
if (i != m_sent.end () && echo.GetIdentifier () == 0)
|
||||
{
|
||||
uint32_t * buf = new uint32_t [m_size];
|
||||
uint32_t dataSize = echo.GetDataSize ();
|
||||
|
||||
if (nodeId == GetNode ()->GetId () &&
|
||||
appId == GetApplicationId ())
|
||||
{
|
||||
Time sendTime = i->second;
|
||||
NS_ASSERT (Simulator::Now () >= sendTime);
|
||||
Time delta = Simulator::Now () - sendTime;
|
||||
if (dataSize == m_size)
|
||||
{
|
||||
echo.GetData ((uint8_t *)buf);
|
||||
|
||||
m_sent.erase (i);
|
||||
//m_avgRtt.Update (delta.GetMilliSeconds ());
|
||||
//m_recv++;
|
||||
//m_traceRtt (delta);
|
||||
Time sendTime = i->second;
|
||||
NS_ASSERT (Simulator::Now () >= sendTime);
|
||||
Time delta = Simulator::Now () - sendTime;
|
||||
|
||||
if (m_verbose)
|
||||
{
|
||||
routeIpv4.str("");
|
||||
routeIpv4.clear();
|
||||
routeIpv4<<realFrom.GetIpv4();
|
||||
osRoute<<delta.GetMilliSeconds()<<" ms ";
|
||||
if (m_probeCount == m_maxProbes)
|
||||
{
|
||||
std::cout<<m_ttl<<" "<<routeIpv4.str()<<" "<<osRoute.str()<<"\n";
|
||||
if (printStream != NULL)
|
||||
{
|
||||
*printStream->GetStream()<<m_ttl<<" "
|
||||
<<routeIpv4.str()<<" "
|
||||
<<osRoute.str()<<"\n";
|
||||
}
|
||||
m_sent.erase (i);
|
||||
|
||||
osRoute.clear();
|
||||
routeIpv4.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete[] buf;
|
||||
}
|
||||
if (m_verbose)
|
||||
{
|
||||
routeIpv4.str ("");
|
||||
routeIpv4.clear ();
|
||||
routeIpv4 << realFrom.GetIpv4 ();
|
||||
osRoute << delta.GetMilliSeconds () << " ms ";
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (m_probeCount == m_maxProbes)
|
||||
{
|
||||
std::cout << m_ttl << " " << routeIpv4.str () << " " << osRoute.str () << "\n";
|
||||
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::Write32 (uint8_t *buffer, const uint32_t data)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << (void *) buffer << data);
|
||||
buffer[0] = (data >> 0) & 0xff;
|
||||
buffer[1] = (data >> 8) & 0xff;
|
||||
buffer[2] = (data >> 16) & 0xff;
|
||||
buffer[3] = (data >> 24) & 0xff;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
V4TraceRoute::Read32 (const uint8_t *buffer, uint32_t &data)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << (void *) buffer << data);
|
||||
data = (buffer[3] << 24) + (buffer[2] << 16) + (buffer[1] << 8) + buffer[0];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
V4TraceRoute::Send ()
|
||||
{
|
||||
// NS_LOG_FUNCTION (this);
|
||||
|
||||
NS_LOG_INFO ("m_seq=" << m_seq);
|
||||
Ptr<Packet> p = Create<Packet> ();
|
||||
Icmpv4Echo echo;
|
||||
@@ -399,15 +380,12 @@ V4TraceRoute::Send ()
|
||||
// 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;
|
||||
for (uint32_t i = 0; i < m_size; ++i)
|
||||
{
|
||||
data[i] = 0;
|
||||
}
|
||||
NS_ASSERT (m_size >= 16);
|
||||
|
||||
uint32_t tmp = GetNode ()->GetId ();
|
||||
Write32 (&data[0 * sizeof(uint32_t)], tmp);
|
||||
|
||||
tmp = GetApplicationId ();
|
||||
Write32 (&data[1 * sizeof(uint32_t)], tmp);
|
||||
|
||||
Ptr<Packet> dataPacket = Create<Packet> ((uint8_t *) data, m_size);
|
||||
echo.SetData (dataPacket);
|
||||
p->AddHeader (echo);
|
||||
@@ -423,16 +401,16 @@ V4TraceRoute::Send ()
|
||||
|
||||
if (m_probeCount < m_maxProbes)
|
||||
{
|
||||
m_probeCount++;
|
||||
m_probeCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_probeCount = 1;
|
||||
m_ttl++;
|
||||
}
|
||||
{
|
||||
m_probeCount = 1;
|
||||
m_ttl++;
|
||||
}
|
||||
|
||||
m_sent.insert (std::make_pair (m_seq - 1, Simulator::Now ()));
|
||||
m_socket->SetIpTtl(m_ttl);
|
||||
m_socket->SetIpTtl (m_ttl);
|
||||
|
||||
|
||||
InetSocketAddress dst = InetSocketAddress (m_remote, 0);
|
||||
@@ -453,7 +431,7 @@ V4TraceRoute::StartWaitReplyTimer (void)
|
||||
m_waitIcmpReplyTimeout);
|
||||
|
||||
m_waitIcmpReplyTimer = Simulator::Schedule (m_waitIcmpReplyTimeout,
|
||||
&V4TraceRoute::HandleWaitReplyTimeout, this);
|
||||
&V4TraceRoute::HandleWaitReplyTimeout, this);
|
||||
Send ();
|
||||
}
|
||||
}
|
||||
@@ -462,29 +440,31 @@ V4TraceRoute::StartWaitReplyTimer (void)
|
||||
void
|
||||
V4TraceRoute::HandleWaitReplyTimeout (void)
|
||||
{
|
||||
if (m_ttl < m_maxTtl+1)
|
||||
if (m_ttl < m_maxTtl + 1)
|
||||
{
|
||||
m_next = Simulator::Schedule (m_interval, &V4TraceRoute::StartWaitReplyTimer, this);
|
||||
m_next = Simulator::Schedule (m_interval, &V4TraceRoute::StartWaitReplyTimer, this);
|
||||
}
|
||||
|
||||
osRoute<<"* ";
|
||||
osRoute << "* ";
|
||||
if (m_probeCount == m_maxProbes)
|
||||
{
|
||||
if(m_verbose)
|
||||
std::cout<<m_ttl<<" "<<routeIpv4.str()<<" "<<osRoute.str()<<"\n";
|
||||
|
||||
if (printStream != NULL)
|
||||
if (m_verbose)
|
||||
{
|
||||
*printStream->GetStream()<<m_ttl
|
||||
<<" "<<routeIpv4.str()<<" "
|
||||
<<osRoute.str()<<"\n";
|
||||
std::cout << m_ttl << " " << routeIpv4.str () << " " << osRoute.str () << "\n";
|
||||
}
|
||||
osRoute.str("");
|
||||
osRoute.clear ();
|
||||
routeIpv4.str("");
|
||||
routeIpv4.clear ();
|
||||
}
|
||||
|
||||
if (printStream != NULL)
|
||||
{
|
||||
*printStream->GetStream () << m_ttl
|
||||
<< " " << routeIpv4.str () << " "
|
||||
<< osRoute.str () << "\n";
|
||||
}
|
||||
osRoute.str ("");
|
||||
osRoute.clear ();
|
||||
routeIpv4.str ("");
|
||||
routeIpv4.clear ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} //ns3 namespace
|
||||
} // ns3 namespace
|
||||
|
||||
@@ -34,8 +34,21 @@ namespace ns3 {
|
||||
|
||||
class Socket;
|
||||
|
||||
/**
|
||||
* \ingroup internet-apps
|
||||
* \defgroup v4traceroute V4Traceroute
|
||||
*/
|
||||
|
||||
class V4TraceRoute: public Application {
|
||||
/**
|
||||
* \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.
|
||||
@@ -43,13 +56,12 @@ public:
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
V4TraceRoute();
|
||||
virtual ~V4TraceRoute();
|
||||
V4TraceRoute ();
|
||||
virtual ~V4TraceRoute ();
|
||||
|
||||
void Print (Ptr<OutputStreamWrapper> stream);
|
||||
|
||||
private:
|
||||
|
||||
// inherited from Application base class.
|
||||
virtual void StartApplication (void);
|
||||
virtual void StopApplication (void);
|
||||
@@ -67,39 +79,26 @@ private:
|
||||
*/
|
||||
void Receive (Ptr<Socket> socket);
|
||||
|
||||
/**
|
||||
* \brief Writes data to buffer in little-endian format.
|
||||
*
|
||||
* Least significant byte of data is at lowest buffer address
|
||||
*
|
||||
* \param buffer the buffer to write to
|
||||
* \param data the data to write
|
||||
*/
|
||||
void Write32 (uint8_t *buffer, const uint32_t data);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Writes data from a little-endian formatted buffer to data.
|
||||
*
|
||||
* \param buffer the buffer to read from
|
||||
* \param data the read data
|
||||
*/
|
||||
void Read32 (const uint8_t *buffer, uint32_t &data);
|
||||
|
||||
/*brief Send one (ICMP ECHO) to the destination*/
|
||||
/* \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.
|
||||
* 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
|
||||
|
||||
Reference in New Issue
Block a user