The procedures and functions described in this chapter can be found in ~ns/trace.{cc, h}, ~ns/tcl/lib/ns-trace.tcl, ~ns/queuemonitor.{cc, h}, ~ns/tcl/lib/ns-link.tcl, ~ns/packet.h, ~ns/flowmon.cc, and ~ns/classifier-hash.cc.

There are a number of ways of collecting output or trace data on a simulation. Generally, trace data is either displayed directly during execution of the simulation, or (more commonly) stored in a file to be post-processed and analyzed. There are two primary but distinct types of monitoring capabilities currently supported by the simulator. The first, called traces, record each individual packet as it arrives, departs, or is dropped at a link or queue. Trace objects are configured into a simulation as nodes in the network topology, usually with a Tcl “Channel” object hooked to them, representing the destination of collected data (typically a trace file in the current directory). The other types of objects, called monitors, record counts of various interesting quantities such as packet and byte arrivals, departures, etc. Monitors can monitor counts associated with all packets, or on a per-flow basis using a flow monitor.

To support traces, there is a special common header included in each packet (this format is defined in ~ns/packet.h as
hdr_cmn). It presently includes a unique identifier on each packet, a packet type field (set by agents when they generate packets), a packet size field (in bytes, used to determine the transmission time for packets), and an interface label (used for computing multicast distribution trees).

Monitors are supported by a separate set of objects that are created and inserted into the network topology around queues. They provide a place where arrival statistics and times are gathered andmake use of the class Integrator to compute statistics over time intervals.

Trace Support

The trace support in OTcl consists of a number of specialized classes visible in OTcl but implemented in C++, combined with
a set of Tcl helper procedures and classes defined in the ns library.

All following OTcl classes are supported by underlying C++ classes defined in ~ns/trace.cc. Objects of the following types
are inserted directly in-line in the network topology:

Trace/Hop

trace a “hop” (XXX what does this mean exactly; it is not really used XXX)

Trace/Enque

a packet arrival (usually at a queue)

Trace/Deque

a packet departure (usually at a queue)

Trace/Drop

packet drop (packet delivered to drop-target)

Trace/Recv

packet receive event at the destination node of a link

SnoopQueue/In

on input, collect a time/size sample (pass packet on)

SnoopQueue/Out

on output, collect a time/size sample (pass packet on)

SnoopQueue/Drop

on drop, collect a time/size sample (pass packet on)

SnoopQueue/EDrop

on an "early" drop, collect a time/size sample (pass packet on)

Objects of the following types are added in the simulation and a referenced by the objects listed above. They are used to
aggregate statistics collected by the SnoopQueue objects:

QueueMonitor

receive and aggregate collected samples from snoopers

QueueMonitor/ED

queue-monitor capable of distinguishing between “early” and standard packet drops

QueueMonitor/ED/Flowmon

per-flow statistics monitor (manager)

QueueMonitor/ED/Flow

per-flow statistics container

QueueMonitor/Compat

a replacement for a standard QueueMonitor when ns v1 compatibility is in use

OTcl Helper Functions

The following helper functions may be used within simulation scripts to help in attaching trace elements (see ~ns/tcl/lib/nslib.
tcl); they are instance procedures of the class Simulator:

flush-trace {}

flush buffers for all trace objects in simulation

create-trace { type file src dst }

create a trace object of type type between the given src and dest nodes. If file is non-null, it is interpreted as a Tcl channel and is attached to the newly-created trace object. The procedure returns the handle to the newly created trace object.

trace-queue { n1 n2 file }

arrange for tracing on the link between nodes n1 and n2. This function calls create-trace, so the same rules apply with respect to the file argument.

trace-callback{ ns command }

arranges to call command when a line is to be traced. The procedure treats command as a string and evaluates it for every line traced. See ~ns/tcl/ex/callback_demo.tcl for additional details on usage.

monitor-queue { n1 n2 }

this function calls the init-monitor function on the link between

nodes n1 and n2.

drop-trace { n1 n2 trace }

the given trace object is made the drop-target of the queue associated

with the link between nodes n1 and n2.

The create-trace{} procedure is used to create a new Trace object of the appropriate kind and attach an Tcl I/O channel
to it (typically a file handle). The src_ and dst_ fields are are used by the underlying C++ object for producing the trace output file so that trace output can include the node addresses defining the endpoints of the link which is being traced. Note that they are not used for matching. Specifically, these values in no way relate to the packet header src and dst fields, which are also displayed when tracing. See the description of the Trace class below.

The trace-queue function enables Enque, Deque, and Drop tracing on the link between nodes n1 and n2. The Link
trace procedure is described below.

The monitor-queue function is constructed similarly to trace-queue. By calling the link’s init-monitor procedure,
it arranges for the creation of objects (SnoopQueue and QueueMonitor objects) which can, in turn, be used to
ascertain time-aggregated queue statistics.

The drop-trace function provides a way to specify a Queue’s drop target without having a direct handle of the queue.

Library support and examples

The Simulator procedures described above require the trace and init-monitor methods associated with the OTcl
Link class. Several subclasses of link are defined, the most common of which is called SimpleLink. Thus, the trace
and init-monitor methods are actually part of the SimpleLink class rather than the Link base class. The trace
function is defined as follows (in ns-link.tcl):

This function establishes Enque, Deque, and Drop traces in the simulator $ns and directs their output to I/O handle $f.
The function assumes a queue has been associated with the link. It operates by first creating three new trace objects and inserting the Enque object before the queue, the Deque object after the queue, and the Drop object between the queue and its previous drop target. Note that all trace output is directed to the same I/O handle.

This function performs one other additional tasks. It checks to see if a link contains a network interface, and if so, leaves it as the first object in the chain of objects in the link, but otherwise inserts the Enque object as the first one.

The following functions, init-monitor and attach-monitor, are used to create a set of objects used to monitor queue
sizes of a queue associated with a link. They are defined as follows:

These functions establish queue monitoring on the SimpleLink object in the simulator ns. Queue monitoring is implemented
by constructing three SnoopQueue objects and one QueueMonitor object. The SnoopQueue objects are
linked in around a Queue in a way similar to Trace objects. The SnoopQueue/In(Out) object monitors packet arrivals(
departures) and reports them to an associated QueueMonitor agent. In addition, a SnoopQueue/Out object is
also used to accumulate packet drop statistics to an associated QueueMonitor object. For init-monitor the same
QueueMonitor object is used in all cases. The C++ definitions of the SnoopQueue and QueueMonitor classes are
described below.

The C++ Trace Class

Underlying C++ objects are created in support of the interface specified in this Section and are linked into the network topology as network elements. The single C++ Trace class is used to implement the OTcl classes Trace/Hop, Trace/Enque, Trace/Deque, and Trace/Drop. The type_ field is used to differentiate among the various types of traces any particular Trace object might implement. Currently, this field may contain one of the following symbolic characters: + for enque, - for deque, h for hop, and d for drop. The overall class is defined as follows in ~ns/trace.cc:

The functionmerely formats a trace entry using the source, destination, and particular trace type character. The dump function
writes the formatted entry out to the I/O handle associated with channel_. The format function, in effect, dictates the
trace file format.

Trace File Format

The Trace::format() method defines the trace file format used in trace files produced by the Trace class. It is constructed
to maintain backward compatibility with output files in earlier versions of the simulator (i.e., ns v1) so that ns v1
post-processing scripts continue to operate. The important pieces of its implementation are as follows:

This function is somewhat unelegant, primarily due to the desire to maintain backward compatibility. It formats the source, destination, and type fields defined in the trace object (not in the packet headers), the current time, along with various packet header fields including, type of packet (as a name), size, flags (symbolically), flow identifier, source and destination packet header fields, sequence number (if present), and unique identifier. The show_tcphdr_ variable indicates whether the trace output should append tcp header information (ack number, flags, header length) at the end of each output line. This is especially useful for simulations using FullTCP agents. An example of a trace file (without the tcp header fields) might appear as follows:

Here we see 14 trace entries, five enque operations (indicated by “+” in the first column), four deque operations (indicated by “-”), four receive events (indicated by “r”), and one drop event. (this had better be a trace fragment, or some packets would have just vanished!). The simulated time (in seconds) at which each event occurred is listed in the second column. The next two fields indicate between which two nodes tracing is happening. The next field is a descriptive name for the the type of packet seen. The next field is the packet’s size, as encoded in its IP header.

The next field contains the flags, which not used in this example. The flags are defined in the flags[] array in trace.cc. Four of the flags are used for ECN: “E” for Congestion Experienced (CE) and “N” for ECN-Capable-Transport (ECT) indications in the IP header, and “C” for ECN-Echo and “A” for Congestion Window Reduced (CWR) in the TCP header. For the other flags, “P” is for priority, and “F” is for TCP Fast Start.

The next field gives the IP flow identifier field as defined for IP version 6.
<ref>In ns v1, each packet included a class field, which was used by CBQ to classify packets. It then found additional use to differentiate between “flows” at one trace point. In ns v2, the flow ID field is available for this purpose, but any additional information (which was commonly overloaded into the class field in ns v1) should be placed in its own separate field, possibly in some other header.</ref> The subsequent two fields indicate the packet’s source and destination node addresses, respectively. The following field indicates the sequence number.<ref>In ns v1, all packets contained a sequence number, whereas in ns v2 only those Agents interested in providing sequencing will generate sequence
numbers. Thus, this field may not be useful in ns v2 for packets generated by agents that have not filled in a sequence number. It is used here to remain
backward compatible with ns v1.</ref>
The last field is a unique packet identifier. Each new packet created in the simulation is assigned a new, unique identifier.

Packet Types

Each packet contains a packet type field used by Trace::format to print out the type of packet encountered. The type field is defined in the TraceHeader class, and is considered to be part of the trace support; it is not interpreted elsewhere in the simulator. Initialization of the type field in packets is performed by the Agent::allocpkt(void)method. The type field is set to integer values associated with the definition passed to the Agent constructor (Section 10.6.3). The currently-supported
definitions, their values, and their associated symblic names are as follows (defined in ~ns/packet.h):

Queue Monitoring

Queue monitoring refers to the capability of tracking the dynamics of packets at a queue (or other object). A queue monitor
tracks packet arrival/departure/drop statistics, and may optionally compute averages of these values. Monitoring may be
applied to all packets (aggregate statistics), or per-flow statistics (using a Flow Monitor).

Several classes are used in supporting queue monitoring. When a packet arrives at a link where queue monitoring is enabled, it
generally passes through a SnoopQueue object when it arrives and leaves (or is dropped). These objects contain a reference
to a QueueMonitor object.

It addition to the packet and byte counters, a queue monitor may optionally refer to objects that keep an integral of the queue size over time using [[Manual: Mathematical Support#Integrals|Integrator objects. The Integrator class provides a simple implementation of integral approximation by discrete sums.

All bound variables beginning with p refer to packet counts, and all variables beginning with b refer to byte counts. The variable size_ records the instantaneous queue size in bytes, and the variable pkts_ records the same value in packets. When a QueueMonitor is configured to include the integral functions (on bytes or packets or both), it computes the approximate integral of the queue size (in bytes) with respect to time over the interval [t0, now], where t0 is either the start of the simulation or the last time the sum_ field of the underlying Integrator class was reset.

The QueueMonitor class is not derived from Connector, and is not linked directly into the network topology. Rather, objects of the SnoopQueue class (or its derived classes) are inserted into the network topology, and these objects contain references to an associated queue monitor. Ordinarily, multiple SnoopQueue objects will refer to the same queue monitor. Objects constructed out of these classes are linked in the simulation topology as described above and call QueueMonitor out, in, or drop procedures, depending on the particular type of snoopy queue.

Per-Flow Monitoring

A collection of specialized classes are used to to implement per-flow statistics gathering. These classes include:
QueueMonitor/ED/Flowmon, QueueMonitor/ED/Flow, and Classifier/Hash. Typically, an arriving packet
is inspected to determine to which flow it belongs. This inspection and flow mapping is performed by a classifier object. Once the correct flow is determined, the packet is passed to a flow monitor, which is responsible for collecting per-flow state. Per-flow state is contained in flow objects in a one-to-one relationship to the flows known by the flow monitor. Typically, a flow monitor will create flow objects on-demand when packets arrive that cannot be mapped to an already-known flow.

The Flow Monitor

The QueueMonitor/ED/Flowmon class is responsible for managing the creation of new flow objects when packets arrive
on previously unknown flows and for updating existing flow objects. Because it is a subclass of QueueMonitor, each flow
monitor contains an aggregate count of packet and byte arrivals, departures, and drops. Thus, it is not necessary to create a separate queue monitor to record aggregate statistics. It provides the following OTcl interface:

classifier

get(set) classifier to map packets to flows

attach

attach a Tcl I/O channel to this monitor

dump

dump contents of flow monitor to Tcl channel

flows

return string of flow object names known to this monitor

The classifier function sets or gets the name of the previously-allocated object which will perform packet-to-flow
mapping for the flow monitor. Typically, the type of classifier used will have to do with the notion of “flow” held by the user. One of the hash based classifiers that inspect various IP-level header fields is typically used here (e.g. fid, src/dst, src/dst/fid). Note that while classifiers usually receive packets and forward them on to downstream objects, the flow monitor uses the classifier only for its packet mapping capability, so the flow monitor acts as a passive monitor only and does not actively forward packets.

The attach and dump functions are used to associate a Tcl I/O stream with the flow monitor, and dump its contents
on-demand. The file format used by the dump command is described below.

The flows function returns a list of the names of flows known by the flow monitor in a way understandable to Tcl. This
allows tcl code to interrogate a flow monitor in order to obtain handles to the individual flows it maintains.

Flow Monitor Trace Format

The flow monitor defines a trace format which may be used by post-processing scripts to determine various counts on a
per-flow basis. The format is defined by the following code in ~ns/flowmon.cc:

Most of the fields are explained in the code comments. The “category” is historical, but is used to maintain loose backwardcompatibility with the flow manager format in ns version 1.

The Flow Class

The class QueueMonitor/ED/Flow is used by the flow monitor for containing per-flow counters. As a subclass of
QueueMonitor, it inherits the standard counters for arrivals, departures, and drops, both in packets and bytes. In addition,
because each flow is typically identified by some combination of the packet source, destination, and flow identifier fields,
these objects contain such fields. Its OTcl interface contains only bound variables:

src_

source address on packets for this flow

dst_

destination address on packets for this flow

flowid_

flow id on packets for this flow

Note that packets may be mapped to flows (by classifiers) using criteria other than a src/dst/flowid triple. In such circumstances,
only those fields actually used by the classifier in performing the packet-flow mapping should be considered reliable.

Commands at a glance

Following is a list of trace related commands commonly used in simulation scripts:

$ns_ trace-all <tracefile>

This is the command used to setup tracing in ns. All traces are written in the <tracefile>.

$ns_ namtrace-all <namtracefile>

This command sets up nam tracing in ns. All nam traces are written in to the <namtracefile>.

$ns_ namtrace-all-wireless <namtracefile> <X> <Y>

This command sets up wireless nam tracing. <X> and <Y> are the x-y co-ordinates for the wireless topology and all wireless nam traces are written into the <namtracefile>.

$ns_ nam-end-wireless <stoptime>

This tells nam the simulation stop time given in <stoptime>.

$ns_ trace-all-satlinks <tracefile>

This is a method to trace satellite links and write traces into <tracefile>.

$ns_ flush-trace

This command flushes the trace buffer and is typically called before the simulation run ends.

$ns_ get-nam-traceall

Returns the namtrace file descriptor stored as the Simulator instance variable called namtraceAllFile_.

$ns_ get-ns-traceall

Similar to get-nam-traceall. This returns the file descriptor for ns tracefile which is stored as the Simulator instance called traceAllFile_.

$ns_ create-trace <type> <file> <src> <dst> <optional:op>

This command creates a trace object of type <type> between the <src> and <dst> nodes. The traces are written into the <file>. <op> is the argument that may be used to specify the type of trace, like nam. if <op> is not defined, the default trace object created is for nstraces.

$ns_ trace-queue <n1> <n2> <optional:file>

This is a wrapper method for create-trace. This command creates a trace object for tracing events on the link represented by the nodes <n1> and <n2>.

$ns_ namtrace-queue <n1> <n2> <optional:file>

This is used to create a trace object for namtracing on the link between nodes <n1> and <n2>. This method is very similar to and is the namtrace counterpart of method trace-queue.

$ns_ drop-trace <n1> <n2> <trace>

This command makes the given <trace> object a drop-target for the queue associated with the link between nodes <n1> and <n2>.

$ns_ monitor-queue <n1> <n2> <qtrace> <optional:sampleinterval>

This sets up a monitor that keeps track of average queue length of the queue on the link between nodes <n1> and <n2>. The default value of sampleinterval is 0.1.

$link trace-dynamics <ns> <fileID> Trace the dynamics of this link and write the output to fileID filehandle.

ns is an instance of the Simulator or MultiSim object that was created to invoke the simulation.

The tracefile format is backward compatible with the output files in the ns version 1 simulator so that ns-1 postprocessing
scripts can still be used. Trace records of traffic for link objects with Enque, Deque, receive or Drop Tracing have the
following form:

Only those agents interested in providing sequencing will generate sequence numbers and hence this field may not be useful
for packets generated by some agents. For links that use RED gateways, there are additional trace records as follows: