Tracers are files created to trace packets passing through SAPs. They are created for off-line statistical purposes and debug.
Creating a customized tracer for your needs is an easy procedure. You have to create a header file where define a constructor and a method, named format()
. This is the function called by each SAP when a packet get through it, so it is important that in every tracer you create a method with this name. The format()
function is always called passing a reference to the packet going through the SAP and a reference to the SAP itself as arguments.
Let's now explain how the Common Header Tracer works:
class CommonHeaderTracer : public Tracer { public: /** * The class constructor initialize the level to 1. This * means that it will be the first Tracer which will * process the incoming packets * * @see Tracer **/ CommonHeaderTracer(); /** * This method writes a string in the trace file: * * @param p pointer to the packet to be traced * @param sap pointer to the SAP instance which ask for the trace * **/ // ad hoc tracer for common header void format(Packet *p, SAP *sap); };
The way you trace packets is then included in format()
method. Let's see how it is defined in .cc file. The first definition regards the tracer constructor. It inherits from Trace
class. You have also to add a parameter defining at which level of the stack you want to insert your tracer. In this case we see Tracer(1)
, so this tracer is positioned at first level. The next lines are dedicated to description of format()
function. It lies on writeTrace()
function. In this case we access the common header and then we write the info we need. When simulation ends, we'll find infos regarding all packet passed through SAPs stored in a tracefile.
CommonHeaderTracer::CommonHeaderTracer() : Tracer(1) {} void CommonHeaderTracer::format(Packet *p, SAP *sap) { //access the header hdr_cmn *ch = hdr_cmn::access(p); //write infos writeTrace(sap, "string %d", ch->value()) }where
string
and ch->value()
have no meaning except for clarification.
To make the tracer active, you have to add your tracer to SAPs. You have to insert the following lines in (usually) initlib.cc file so tracers are loaded when you load your library. Notice that tracer can constitute a standing alone library, so they can be loaded on demand.
extern "C" int Trace_Init() { ... SAP::addTracer(new CommonHeaderTracer); SAP::addTracer(new IpHeaderTracer); ... return 0; }
The last note is about the setting up of a trace file in Tcl. You have simply to define a trace file name variable and open a file, tf
in this case, with this name. Last command redirects the simulator trace output to your file.
set tracefname "/tmp/out.tr" set tf [open $tracefname w] $ns trace-all $tf
When simulation ends, you have to terminate the trace update, writing last datas on file and then closing the tracefile.
$ns flush-trace close $tf
It is possible to create a Trace file for cross layer messages too. The procedure is the same, you always use the format()
function. The difference is in the initlib.cc
file: you have to add the tracer to a cross layer SAP and not to a simple SAP because cross layer messages travel through different paths than ordinary packets. All you have to do is replace SAP::addTracer(new ...)
with ClSAP::addTracer(new ...)
.
Sometimes you can encounter the BIN string on your trace files. It means that a packet had been dropped. It is often followed by an achronym that describes the reason of dropping.
Referring to cbr-module
files we'll explain how BIN
works. In header file you can find the definition of various dropping reason as:
#define CBR_DROP_REASON_UNKNOWN_TYPE "UKT"
In the .cc file then we see how it is used. The key method is the drop()
function belonging to Module
class. It activates the packet tracing and deallocating procedure. For example, in cbr-module.cc
when we receive a packet we check if we can comprehend its content:
void CbrModule::recv(Packet* p) { hdr_cmn* ch = hdr_cmn::access(p); if (ch->ptype() != PT_MCBR) { drop(p,1,CBR_DROP_REASON_UNKNOWN_TYPE); ... return; }
Then the drop function moves packet to ns2 Bin function and traces the event, appending the drop reason. You can also define verbosity of drop tracing setting the second value of the drop()
function
An example of what you can see in a trace file is:
D 2.012392783 17 BIN LL SYN 23
The capital D stands for ``Dropped'', then there is a timestamp, the node id and then you can read the rest as ``The packet number 23 was moved to Bin by Link Layer because MAC_SYNC_FAILED''.