I can see the "hops node"

711 views
Skip to first unread message

domenico foglia

unread,
Jul 1, 2012, 11:37:24 AM7/1/12
to ns-3-...@googlegroups.com
Hi!
I can see the "source node" and "destination node", but I can see the "hops node"!
There is a command that I add to my code?
I would like to see the results in style "traceroute" directly into "terminal" for now I see only "source node" and "destination node"
What can I do?
this is my code:
in
 // Plot the statistics for each data flow
std::cout << "\nFlow " << k << " (" << t.sourceAddress << " -> "<< t.destinationAddress << ")\n";

I can add as a command string?

p.s I've used "netanim" and "wireshark", though I need results more clear, it's OK to just see the number of hops without ip

I hope someone can help me
thanks


#include "ns3/core-module.h"
#include "ns3/simulator.h"
#include "ns3/node.h"
#include "ns3/internet-stack-helper.h"
#include "ns3/wifi-module.h"
#include "ns3/mesh-module.h"
#include "ns3/mobility-helper.h"
#include "ns3/mesh-helper.h"
#include "ns3/mesh-module.h"
#include "ns3/wifi-phy.h"
#include "ns3/application-container.h"
#include "ns3/inet-socket-address.h"
#include "ns3/packet-sink-helper.h"
#include "ns3/flow-monitor.h"
#include "ns3/flow-monitor-helper.h"
#include "ns3/ipv4-address-helper.h"
#include "ns3/ipv4-interface-container.h"
#include "ns3/ipv4-flow-classifier.h"
#include "ns3/random-variable.h"
#include "ns3/on-off-helper.h"
#include "ns3/boolean.h"
#include "ns3/csma-module.h"
#include "ns3/netanim-module.h"
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
using namespace ns3;
class MeshTest
{
public:
// Init test
MeshTest ();
// Configure test from command line arguments
void Configure (int argc, char ** argv);
// Run test
int Run ();
private:
int m_nnodes; // number of nodes
int m_nconn; // number of connections
double m_step;
double m_randomStart;
double m_totalTime;
uint16_t m_packetSize;
uint32_t m_nIfaces;
bool m_chan;
bool m_pcap;
std::string m_stack;
std::string m_txrate;
//to calculate the lenght of the simulation
float m_timeTotal, m_timeStart, m_timeEnd;
// List of network nodes
NodeContainer nodes;
// List of all mesh point devices
NetDeviceContainer meshDevices;
//Addresses of interfaces:
Ipv4InterfaceContainer interfaces;
// MeshHelper. Report is not static methods
MeshHelper mesh;
private:
// Create nodes and setup their mobility
void CreateNodes ();
// Install internet m_stack on nodes
void InstallInternetStack ();
// Install applications randomly
void InstallApplicationRandom ();
// Print mesh devices diagnostics
void Report ();
};
MeshTest::MeshTest () :
m_nnodes (40),
m_nconn (35),
m_step (630),
m_randomStart (0.5),
m_totalTime (240),
m_packetSize (1024),
m_nIfaces (1),
m_chan (false),
m_pcap (false),
m_stack ("ns3::Dot11sStack"),
m_txrate ("340kbps")
{
}
void
MeshTest::Configure (int argc, char *argv[])
{
CommandLine cmd;
cmd.AddValue ("m_step", "Separation", m_step);
cmd.AddValue ("m_nconn", "Number of connections", m_nconn);
cmd.Parse (argc, argv);
}
void MeshTest::CreateNodes ()
{
double m_txpower = 18.0; // dbm
// Calculate nnodes stations random topology
nodes.Create (m_nnodes);
// Setup mobility - static rectangle topology
MobilityHelper mobility;
mobility.SetPositionAllocator ("ns3::RandomRectanglePositionAllocator", "X", RandomVariableValue (UniformVariable (0, m_step)),
"Y", RandomVariableValue (UniformVariable (0, m_step/2)));
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (nodes);
// Configure YansWifiChannel
YansWifiPhyHelper WifiPhy = YansWifiPhyHelper::Default ();
WifiPhy.Set("EnergyDetectionThreshold", DoubleValue (-89.0) );
WifiPhy.Set("CcaMode1Threshold", DoubleValue (-62.0) );
WifiPhy.Set("TxGain", DoubleValue (1.0) );
WifiPhy.Set("RxGain", DoubleValue (1.0) );
WifiPhy.Set("TxPowerLevels", UintegerValue (1) );
WifiPhy.Set("TxPowerEnd", DoubleValue (m_txpower) );
WifiPhy.Set("TxPowerStart", DoubleValue (m_txpower) );
WifiPhy.Set("RxNoiseFigure", DoubleValue (7.0) );
YansWifiChannelHelper WifiChannel;
WifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
WifiChannel.AddPropagationLoss ("ns3::LogDistancePropagationLossModel","Exponent", StringValue ("2.7"));
WifiPhy.SetChannel (WifiChannel.Create ());
// Configure the parameters of the Peer Link
Config::SetDefault ("ns3::dot11s::PeerLink::MaxBeaconLoss", UintegerValue (20));
Config::SetDefault ("ns3::dot11s::PeerLink::MaxRetries", UintegerValue (4));
Config::SetDefault ("ns3::dot11s::PeerLink::MaxPacketFailure", UintegerValue (5));
// Configure the parameters of the Peer Management Protocol
//Config::SetDefault ("ns3::dot11s::PeerManagementProtocol::EnableBeaconCollision-Avoidance", BooleanValue (false));
// Configure the parameters of the HWMP
Config::SetDefault ("ns3::dot11s::HwmpProtocol::Dot11MeshHWMPactivePathTimeout", TimeValue (Seconds (100)));
Config::SetDefault ("ns3::dot11s::HwmpProtocol::Dot11MeshHWMPactiveRootTimeout", TimeValue (Seconds (100)));
Config::SetDefault ("ns3::dot11s::HwmpProtocol::Dot11MeshHWMPmaxPREQretries", UintegerValue (5));
Config::SetDefault ("ns3::dot11s::HwmpProtocol::UnicastPreqThreshold", UintegerValue (10));
Config::SetDefault ("ns3::dot11s::HwmpProtocol::UnicastDataThreshold", UintegerValue (5));
Config::SetDefault ("ns3::dot11s::HwmpProtocol::DoFlag", BooleanValue (false));
Config::SetDefault ("ns3::dot11s::HwmpProtocol::RfFlag", BooleanValue (true));
// Create mesh helper and set stack installer to it
// Stack installer creates all needed protocols and install them to device
mesh = MeshHelper::Default ();
mesh.SetStandard (WIFI_PHY_STANDARD_80211a);
mesh.SetMacType ("RandomStart", TimeValue (Seconds(m_randomStart)));
mesh.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue ("OfdmRate6Mbps"), "RtsCtsThreshold", UintegerValue (2500));
// Set number of interfaces - default is single-interface mesh point
mesh.SetNumberOfInterfaces (m_nIfaces);
mesh.SetStackInstaller (m_stack);
//If multiple channels is activated
if (m_chan)
{
mesh.SetSpreadInterfaceChannels (MeshHelper::SPREAD_CHANNELS);
}
else
{
mesh.SetSpreadInterfaceChannels (MeshHelper::ZERO_CHANNEL);
}
// Install protocols and return container if MeshPointDevices
meshDevices = mesh.Install (WifiPhy, nodes);
if (m_pcap)
    WifiPhy.EnablePcapAll (std::string ("mp-"));


}
void MeshTest::InstallInternetStack ()
{
//Install the internet protocol stack on all nodes
InternetStackHelper internetStack;
internetStack.Install (nodes);
//Assign IP addresses to the devices interfaces (m_nIfaces)
Ipv4AddressHelper address;
address.SetBase ("192.168.1.0", "255.255.255.0");
interfaces = address.Assign (meshDevices);
}
void MeshTest::InstallApplicationRandom ()
{
int i=0;
int m_source, m_dest, m_dest_port;
char num [2];
char onoff [7];
char sink [6];
double start_time, stop_time, duration;
// Set the parameters of the onoff application
Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (m_packetSize));
Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue (m_txrate));
ApplicationContainer apps [m_nconn];
UniformVariable rand_nodes (0,m_nnodes-1);
UniformVariable rand_port (49000,49100);
// 50 seconds for transitori are left at the beginning.
UniformVariable a(50,m_totalTime-15);
for (i = 0; i < m_nconn; i++){
start_time = a.GetValue();
ExponentialVariable b(25);
duration = b.GetValue()+1;
//If the exponential variable gives us a value that added to the start time
//is greater than the maximum permitted, this is changed for the maximum
//10 seconds are left at the end to calculate well the statistics of each flow
if ( (start_time + duration) > (m_totalTime - 10)){
stop_time = m_totalTime-10;
}else{
stop_time = start_time + duration;
}
//create different names for the connections
//(we can not use vectors for OnOffHelper)
strcpy(onoff,"onoff");
strcpy(sink,"sink");
sprintf(num,"%d",i);
strcat(onoff,num);
strcat(sink,num);
//set random variables of the destination (server) and destination port.
m_dest = rand_nodes.GetInteger (0,m_nnodes-1);
m_dest_port = rand_port.GetInteger (49000,49100);
// Set random variables of the source (client).
// Client and server can not be the same node.
m_source = rand_nodes.GetInteger (0,m_nnodes-1);
while (m_source == m_dest){
m_source = rand_nodes.GetInteger (0,m_nnodes-1);
}
// Plot the connection values
std::cout << "\n\t Node "<< m_source << " to " << m_dest;
std::cout << "\n Start_time: " << start_time << "s";
std::cout << "\n Stop_time: " << stop_time << "s";
std::cout << "\n Duration: " << stop_time-start_time << "s\n";
// Define UDP traffic for the onoff application
OnOffHelper onoff ("ns3::UdpSocketFactory", Address (InetSocketAddress (interfaces.GetAddress (m_dest), m_dest_port)));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
apps[i] = onoff.Install (nodes.Get(m_source));
apps[i].Start (Seconds (start_time));
apps[i].Stop (Seconds (stop_time));
// Create a packet sink to receive these packets
PacketSinkHelper sink ("ns3::UdpSocketFactory",InetSocketAddress (interfaces.GetAddress (m_dest), 49001));
apps[i] = sink.Install (nodes.Get (m_dest));
apps[i].Start (Seconds (1.0));

}
}
int MeshTest::Run ()
{
CreateNodes ();
InstallInternetStack ();
InstallApplicationRandom ();
// Install FlowMonitor on all nodes
FlowMonitorHelper flowmon;
Ptr<FlowMonitor> monitor = flowmon.InstallAll();
//AnimationInterface anim("hwmp-test-anim.xml");
m_timeStart=clock();
Simulator::Schedule (Seconds(m_totalTime), & MeshTest::Report, this);
Simulator::Stop (Seconds (m_totalTime));
Simulator::Run ();
// Define variables to calculate the metrics
int k=0;
int totaltxPackets = 0;
int totalrxPackets = 0;
double totaltxbytes = 0;
double totalrxbytes = 0;
double totaldelay = 0;
double totalrxbitrate = 0;
double totalpacketloss =0;
double difftx, diffrx;
double pdf_value, rxbitrate_value, txbitrate_value, delay_value;
double pdf_total, rxbitrate_total, delay_total;
//Print per flow statistics
monitor->CheckForLostPackets ();
Ptr<Ipv4FlowClassifier> classifier = DynamicCast<Ipv4FlowClassifier>(flowmon.GetClassifier ());
std::map<FlowId, FlowMonitor::FlowStats> stats = monitor->GetFlowStats ();

for (std::map<FlowId, FlowMonitor::FlowStats>::const_iterator i = stats.begin (); i != stats.end (); ++i)
{
Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow (i->first);
difftx = i->second.timeLastTxPacket.GetSeconds() - i->second.timeFirstTxPacket.GetSeconds();
diffrx = i->second.timeLastRxPacket.GetSeconds() - i->second.timeFirstRxPacket.GetSeconds();
pdf_value = (double) i->second.lostPackets / (double) i->second.txPackets * 100;
txbitrate_value = (double) i->second.txBytes * 8 / 1024 / difftx;
if (i->second.rxPackets != 0){
rxbitrate_value = (double)i->second.rxBytes / diffrx*8/m_packetSize;
delay_value = (double) i->second.delaySum.GetSeconds() / (double) i->second.rxPackets;
}
else{
rxbitrate_value = 0;
delay_value = 0;
}
// We are only interested in the metrics of the data flows
if ((!t.destinationAddress.IsSubnetDirectedBroadcast("255.255.255.0")))
{
k++;
// Plot the statistics for each data flow
std::cout << "\nFlow " << k << " (" << t.sourceAddress << " -> "<< t.destinationAddress << ")\n";
//std::cout << "Tx Packets: " << i->second.txPackets << "\n";
//std::cout << "Rx Packets: " << i->second.rxPackets << "\n";
//std::cout << "Lost Packets: " << i->second.lostPackets << "\n";
//std::cout << "Dropped Packets: " << i->second.packetsDropped.size() << "\n";
std::cout << "Packetloss for flow: " << pdf_value << " %\n";
std::cout << "Average delay x flow: " << delay_value << "s\n";
std::cout << "Throughput x flow: " << rxbitrate_value << " kbps\n";
std::cout << "Tx bitrate x flow: " << txbitrate_value << " kbps\n\n";
// Acumulate for average statistics
totaltxPackets += i->second.txPackets;
totalpacketloss += i->second.lostPackets;
totaltxbytes += i->second.txBytes;
totalrxPackets += i->second.rxPackets;
totaldelay += i->second.delaySum.GetSeconds();
totalrxbitrate += rxbitrate_value;
totalrxbytes += i->second.rxBytes;
    }
 }
  // Average all nodes statistics
if (totaltxPackets != 0){
pdf_total = (double) totalpacketloss / (double) totaltxPackets * 100;
}
else{
pdf_total = 0;
}
if (totalrxPackets != 0){
rxbitrate_total = totalrxbitrate;
delay_total = (double) totaldelay / (double) totalrxPackets;
}
else{
rxbitrate_total = 0;
delay_total = 0;
}
//print all nodes statistics
std::cout << "\nTotal Packetloss: " << pdf_total << " %\n";
std::cout << "Total throughput: " << rxbitrate_total << " kbps\n";
std::cout << "Total Delay: " << delay_total << " s\n";
Simulator::Destroy ();
m_timeEnd=clock();
m_timeTotal=(m_timeEnd - m_timeStart)/(double) CLOCKS_PER_SEC;
std::cout << "\n*** Simulation time: " << m_timeTotal << "s\n\n";
return 0;
}
void MeshTest::Report ()
{
// Using this function we print detailed statistics of each mesh point device
// These statistics are used later with an AWK files to extract routing metrics
unsigned n (0);
for (NetDeviceContainer::Iterator i = meshDevices.Begin (); i != meshDevices.End (); ++i, ++n)
{
std::ostringstream os;
os << "mp-report.xml";
std::cerr << "Printing mesh point device #" << n << " diagnostics to " << os.str () << "\n";
std::ofstream of;
of.open (os.str().c_str(), ios::out | ios::app);
if (! of.is_open ())
{
std::cerr << "Error: Can’t open file " << os.str() << "\n";
return;
}
mesh.Report (*i, of);
of.close ();
 }
}
int main (int argc, char *argv[])
{
MeshTest t;
t.Configure (argc, argv);
return t.Run();
}


Konstantinos

unread,
Jul 1, 2012, 12:39:30 PM7/1/12
to ns-3-...@googlegroups.com
There is no easy way to print the intermiddiate hops. However there are several ways, some examples I give below

a) Enable full logging for the routing protocol (which ever you use) and then filter-out the logs for RouteOutput and RouteInput methods. From these you can see which node receives a packet and which sends.

b) For the total number of hops you can get the TTL counter of IP-header and do the calculations how much it has been reduced. Similar way I think it is used by Flowmonitor to calculate the hop count.

c) If you just want average total hop count then FlowMonitor can provide such thing without anyother modification.

theere can be other ways of doing it. It always depends on what are your requirements.

domenico foglia

unread,
Jul 1, 2012, 1:23:27 PM7/1/12
to ns-3-...@googlegroups.com
Hi,
through the files. xml and .pcap can see the traffic that is generated for each node, and the entire simulation, however, I would like to obtain separate measurements for each flow on the on / off, where the duration of the simulation is random, not the total. like for the parameters that I have in the "for"
In practice I would measure the delay in each data stream, just as is calculated using the traceroute ...
how should I do?
thanks

Konstantinos

unread,
Jul 1, 2012, 1:32:03 PM7/1/12
to ns-3-...@googlegroups.com
I can't really understand what you want.

From the xml file of FlowMonitor (not netanim) you can get PER FLOW statistics. In your previous post, that's what you have described you wanted.
I didn't say anything about total of all flows. But since you have more than one packets travelling (for a single flow), and potentially follows a different path (in mobile netwroks) then with FlowMonitor, you can calculate the average hop count for all the packets of that particular flow.

Also, FlowMonitor can give you the average end-to-end delay and jitter PER FLOW.

domenico foglia

unread,
Jul 1, 2012, 1:46:29 PM7/1/12
to ns-3-...@googlegroups.com
exactly, I need to know the average number of hops traversed for each "flow", how can I configure the FlowMonitor for this statistic?

Konstantinos

unread,
Jul 1, 2012, 5:28:54 PM7/1/12
to ns-3-...@googlegroups.com


On Sunday, 1 July 2012 18:46:29 UTC+1, domenico foglia wrote:
exactly, I need to know the average number of hops traversed for each "flow", how can I configure the FlowMonitor for this statistic?

You will need to use the timesforwarded method of flowmonitor

uint32_t ns3::FlowMonitor::FlowStats::timesForwarded

Contains the number of times a packet has been reportedly forwarded, summed for all received packets in the flow

See the presentation of FlowMonitor here (http://telecom.inescporto.pt/~gjc/flowmon-presentation.pdf)
It explains how you can easily calculate things like average hop count you want.

domenico foglia

unread,
Jul 1, 2012, 6:52:54 PM7/1/12
to ns-3-...@googlegroups.com
in my case, I just add 

hopcount_value = ((double) i-> second.timesForwarded / (double) i-> second.rxPackets) + 1;

in my code?

because I have already
"// Install FlowMonitor on all nodes
FlowMonitorHelper flowmon;
Ptr<FlowMonitor> monitor = flowmon.InstallAll(); "

and

//Print per flow statistics
monitor->CheckForLostPackets ();
Ptr<Ipv4FlowClassifier> classifier = DynamicCast<Ipv4FlowClassifier>(flowmon.GetClassifier ());
std::map<FlowId, FlowMonitor::FlowStats> stats = monitor->GetFlowStats ();

for (std::map<FlowId, FlowMonitor::FlowStats>::const_iterator i = stats.begin (); i != stats.end (); ++i)
{
Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow (i->first);
hopcount_value = ((double) i-> second.timesForwarded / (double) i-> second.rxPackets) + 1;
}
 
or do I add the method "uint32_t ns3::FlowMonitor::FlowStats::timesForwarded", and if so, where and how?

again thanks!



domenico foglia

unread,
Jul 2, 2012, 7:05:46 AM7/2/12
to ns-3-...@googlegroups.com
I'm sorry again for the trouble, kostantinos, but could you give me one last help!?
I can not set the variable "timesForwarded"
 output on the terminal I always and only "1" as it applies the method in my code?
what is wrong?
thanks again

Konstantinos

unread,
Jul 2, 2012, 7:19:35 AM7/2/12
to ns-3-...@googlegroups.com

I see that you are using Mesh network. This type of network is supposed to be 1-hop away for every node (at least w.r.t. the network).
All the routing is achieved at lower layer (MAC).

The main part of MAC-layer routing model is specific type of a network device -- ns3::MeshPointDevice. Being an interface to upper-layer protocols, it provides routing functionality hidden from upper-layer protocols, by means of ns3::MeshL2RoutingProtocol. (http://www.nsnam.org/doxygen/group__mesh.html)

This way, FlowMonitor CAN NOT understand that a packet is forwarded to other nodes, because it does not go to Network Layer.
So, you have to follow something like (a) or (b) but at the routing protocols that you use.

domenico foglia

unread,
Jul 2, 2012, 7:35:12 AM7/2/12
to ns-3-...@googlegroups.com
So I can not use "Flow Monitors"?


Konstantinos

unread,
Jul 2, 2012, 7:56:02 AM7/2/12
to ns-3-...@googlegroups.com
You will always see 1-hop and that's correct with respect to the network layer (FlowMonitor works on network).

domenico foglia

unread,
Jul 2, 2012, 8:16:05 AM7/2/12
to ns-3-...@googlegroups.com
So it is better to use "wireshark" and see the "ttl"? But with it I do not have clear information,  it is as if the "wireshark" sees the entire simulation and not separate data streams for each interval of time, I have time intervals that are sometimes overlapping, if I have two intervals of time how do I figure out which data stream is? 
I've got it clear what I mean?

domenico foglia

unread,
Jul 3, 2012, 12:01:15 PM7/3/12
to ns-3-...@googlegroups.com
hello Constantinos
I followed your suggestion about the "ttl" But I do not know how to extract the "ttl" from "ipheader", in particular I would like to perform "initial ttl - ttl final" so as to understand the average hops traversed
how can I extract this information using the ns-3?
I hope you can help me again!
thank you so much!
Reply all
Reply to author
Forward
0 new messages