ns-3 learning notes

ns-3 is a powerful network simulator. This is a note for learning how ns-3 works.

official tutorial at here.

install

follow the instruction at the tutorial.

We can use git/bake or download a release version. Use build.py or bake to compile & install.

waf is an interesting tool. Need to go deep.

Then we can run tests, about 600+ tests. In my test, 3 items were skipped, related to tcp, since NSC is required. NSC seemed to be obsoleted(not sure). Maybe I need to integrate it later.

run scipt

ns3 runs scripts under the control of Waf.

At the root of NS-3:

$ ./waf --run <ns3-program> --command-template="%s <args>"

or

$ ./waf --run '<ns3-program> --arg1=value1 --arg2=value2 ...'

debug the script with gdb:

$ ./waf --run=hello-simulator --command-template="gdb %s --args <args>"

basic idea

key abstraction:

  • node —> computer —> Class Node
  • application —> software(system & user) —> Class Application
  • Channel —> link —> Class Channel
  • net device —> NICs & drivers —> Class NetDevice
  • topology helpers: a convenient tool to help create topo

csma/pointToPoint/wifi netdevice are each associated to its channel.

basic code

Time::SetResolution to set time resolution.

LogComponentEnable/Disable("name",level) to start/stop log info.

use nodecontainer to create node chain:

1
2
NodeContainer nodes;
nodes.Create (2);

use topologyhelper to define topo and add attributes:

1
2
3
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
1
2
3
4
5
6
CsmaHelper csma;
csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));

NetDeviceContainer csmaDevices;
csmaDevices = csma.Install (csmaNodes);

use the helper’s install method to associate the device and channel, a device chain returned:

1
2
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);

install Internet stack to node and set address to device interface:

1
2
3
4
5
6
7
InternetStackHelper stack;
stack.Install (nodes);

Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");

Ipv4InterfaceContainer interfaces = address.Assign (devices);

simple routing:

1
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

use server helper to define server, client helper to define client.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
UdpEchoServerHelper echoServer (9);

ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));

UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));

ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));

run the simulation and destroy it when finished:

1
2
Simulator::Run ();
Simulator::Destroy ();

compile and run the script:

1
2
3
4
5
6
7
/* copy the script to scratch folder */
$ cd ../..
$ cp examples/tutorial/first.cc scratch/myfirst.cc
/* build it */
$ ./waf
/* run */
$ ./waf --run scratch/myfirst

log info

There are currently seven levels of log messages of increasing verbosity defined in the system.

  • LOG_ERROR — Log error messages (associated macro: NS_LOG_ERROR);
  • LOG_WARN — Log warning messages (associated macro: NS_LOG_WARN);
  • LOG_DEBUG — Log relatively rare, ad-hoc debugging messages (associated macro: NS_LOG_DEBUG);
  • LOG_INFO — Log informational messages about program progress (associated macro: NS_LOG_INFO);
  • LOG_FUNCTION — Log a message describing each function called (two associated macros: NS_LOG_FUNCTION, used for member functions, and NS_LOG_FUNCTION_NOARGS, used for static functions);
  • LOG_LOGIC – Log messages describing logical flow within a function (associated macro: NS_LOG_LOGIC);
  • LOG_ALL — Log everything mentioned above (no associated macro).
  • NS_LOG_UNCOND – Log the associated message unconditionally (no associated log level).

For each LOG_TYPE there is also LOG_LEVEL_TYPE that, if used, enables logging of all the levels above it in addition to it’s level.

2 ways to print log message

set env var

$ export 'NS_LOG=<>=level'

  • <>: log component, i.e. *, UdpEchoClinetApplication, nameDefinedInScript
  • level: log level, i.e. level_all, info, prefix_func, prefix_time. Use | to combine multi config
  • use : to define multi component

i.e.

1
2
export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func|prefix_time:
UdpEchoServerApplication=level_all|prefix_func|prefix_time'

add to code

define log component and enable it in code

1
2
3
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");
LogComponentEnable ("FirstScriptExample", LOG_LEVEL_INFO);
NS_LOG_INFO ("Creating Topology");

use command line argument

we can use command line argument to define attribute.

1
2
3
4
$ ./waf --run "scratch/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::Delay=2ms
--ns3::UdpEchoClient::MaxPackets=2"

use help to find groups, typeid and attributes.

1
$ ./waf --run "scratch/myfirst --PrintHelp"

we can also find them at ns-3 doxygen.

we can use hook the set variables according to the args.

1
cmd.AddValue("nPackets", "Number of packets to echo", nPackets);

tracing system

Through tracing system we can get tracing events on the transmit queue in every p2p net device.

We can adopt it by adding code:

1
2
AsciiTraceHelper ascii;
pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr"));

The file would be created at the root directory of ns3.

each line in the trace file begins with a lone character (has a space after it). This character will have the following meaning:

  • +: An enqueue operation occurred on the device queue;
  • -: A dequeue operation occurred on the device queue;
  • d: A packet was dropped, typically because the queue was full;
  • r: A packet was received by the net device.

we can also get pcap trace.

1
pointToPoint.EnablePcapAll ("myfirst");

for each node ns3 will create pcap file with name of prefix-node-device.pcap

several override for enablepcap: net device ptr/ node name/ net device container/ node container.