16.1.6 Trace Support

The trace support for wireless simulations currently use cmu-trace objects. In the future this shall be extended to merge with trace and monitoring support available in ns, which would also include nam support for wireless modules. For now we will explain briefly with cmu-trace objects and how they may be used to trace packets for wireless scenarios.

The cmu-trace objects are of three types - CMUTrace/Drop, CMUTrace/Recv and CMUTrace/Send. These are used for tracing packets that are dropped, received and sent by agents, routers, mac layers or interface queues in ns. The methods and procedures used for implementing wireless trace support can be found under ~ns/trace.{cc,h} and ~ns/tcl/lib/ns-cmutrace.tcl.

A cmu-trace object may be created by the following API:

set sndT [cmu-trace Send "RTR" $self]
which creates a trace object, sndT, of the type CMUTrace/Send for tracing all packets that are sent out in a router. The trace objects may be used to trace packets in MAC, agents (routing or others), routers or any other NsObject.

The cmu-trace object CMUTrace is derived from the base class Trace. See Chapter 26 for details on class Trace. The class CMUTrace is defined as the following:

class CMUTrace : public Trace {
public:
        CMUTrace(const char *s, char t);
        void    recv(Packet *p, Handler *h);
        void    recv(Packet *p, const char* why);

private:
        int off_arp_;
        int off_mac_;
        int off_sr_;

        char    tracename[MAX_ID_LEN + 1];
        int     tracetype;
        MobileNode *node_;

        int initialized() { return node_ && 1; }

        int     command(int argc, const char*const* argv);
        void    format(Packet *p, const char *why);

        void    format_mac(Packet *p, const char *why, int offset);
        void    format_ip(Packet *p, int offset);

        void    format_arp(Packet *p, int offset);
        void    format_dsr(Packet *p, int offset);
        void    format_msg(Packet *p, int offset);
        void    format_tcp(Packet *p, int offset);
        void    format_rtp(Packet *p, int offset);
};

The type field (described in Trace class definition) is used to differentiate among different types of traces. For cmu-trace this can be s for sending, r for receiving or D for dropping a packet. A fourth type f is used to denote forwarding of a packet (When the node is not the originator of the packet). Similar to the method Trace::format(), the CMUTrace::format() defines and dictates the trace file format. The method is shown below:

void CMUTrace::format(Packet* p, const char *why)
{
        hdr_cmn *ch = HDR_CMN(p);
        int offset = 0;

        /*
         * Log the MAC Header
         */
        format_mac(p, why, offset);
        offset = strlen(wrk_);

        switch(ch-\>ptype()) {

        case PT_MAC:
                break;

        case PT_ARP:
                format_arp(p, offset);
                break;

        default:
                format_ip(p, offset);
                offset = strlen(wrk_);

                switch(ch-\>ptype()) {

                case PT_DSR:
                        format_dsr(p, offset);
                        break;

                case PT_MESSAGE:
                case PT_UDP:
                        format_msg(p, offset);
                        break;
                        
                case PT_TCP:
                case PT_ACK:
                        format_tcp(p, offset);
                        break;
                        
                case PT_CBR:
                        format_rtp(p, offset);
                        break;
                ..........

                }
        }
}
The above function calls different format functions depending on the type of the packet being traced. All traces are written to the buffer wrk_. A count of the offset for the buffer is kept and is passed along the different trace functions. The most basic format is defined by format_mac() and is used to trace all pkt types. The other format functions print additional information as defined by the packet types. The mac format prints the following:
\#ifdef LOG_POSITION
        double x = 0.0, y = 0.0, z = 0.0;
        node_-\>getLoc(&x, &y, &z);
\#endif

        sprintf(wrk_ + offset,
\#ifdef LOG_POSITION
                "%c %.9f %d (%6.2f %6.2f) %3s %4s %d %s %d [%x %x %x %x] ",
\#else
                "%c %.9f _%d_ %3s %4s %d %s %d [%x %x %x %x] ",
\#endif
                op,                    // s, r, D or f
                Scheduler::instance().clock(),  // time stamp
                src_,                  // the nodeid for this node
\#ifdef LOG_POSITION
                x,                     // x co-ord 
                y,                     // y co-ord
\#endif
                tracename,             // name of object type tracing
                why,                   // reason, if any

                ch-\>uid(),             // identifier for this event
                packet_info.name(ch-\>ptype()), // packet type
                ch-\>size(),                    // size of cmn header
                mh-\>dh_duration,       // expected time to send data 
                ETHER_ADDR(mh-\>dh_da), // mac_destination address
                ETHER_ADDR(mh-\>dh_sa),         // mac_sender address
                GET_ETHER_TYPE(mh-\>dh_body));  // type - arp or IP

If the LOG_POSITION is defined the x and y co-ordinates for the mobilenode is also printed. The descriptions for different fields in the mac trace are given in the comments above. For all IP packets additional IP header fields are also added to the above trace. The IP trace is described below:

sprintf(wrk_ + offset, "------- [%d:%d %d:%d %d %d] ",
                src,          // IP src address
                ih-\>sport_,   // src port number
                dst,          // IP dest address
                ih-\>dport_,   // dest port number
                ih-\>ttl_,     // TTL value 
                (ch-\>next_hop_ \< 0) ? 0 : ch-\>next_hop_); // next hopaddress, if any.

An example of a trace for a tcp packet is as follows:

r 160.093884945 _6_ RTR  --- 5 tcp 1492 [a2 4 6 800] ------- [655
36:0 16777984:0 31 16777984] [1 0] 2 0
Here we see a TCP data packet being received by a node with id of 6. UID of this pkt is 5 with a cmn hdr size of 1492. The mac details shows an IP pkt (ETHERTYPE_IP is defined as 0x0800, ETHERTYPE_ARP is 0x0806 ), mac-id of this receiving node is 4. That of the sending node is 6 and expected time to send this data pkt over the wireless channel is a2 (hex2dec conversion: 160+2 sec). Additionally, IP traces information about IP src and destination addresses. The src translates (using a 3 level hier-address of 8/8/8) to a address string of 0.1.0 with port of 0. The dest address is 1.0.3 with port address of 0. The TTL value is 31 and the destination was a hop away from the src. Additionally TCP format prints information about tcp seqno of 1, ackno of 0. See other formats described in ~ns//cmu-trace.cc for DSR, UDP/MESSAGE, TCP/ACK and CBR packet types.

Other trace formats are also used by the routing agents (TORA and DSR) to log certain special routing events like "originating" (adding a SR header to a packet) or "ran off the end of a source route" indicating some sort of routing problem with the source route etc. These special event traces begin with "S" for DSR and "T" for Tora and may be found in ~ns/tora/tora.cc for TORA and ~ns/dsr/dsrgent.cc for DSR routing agent.

Tom Henderson 2011-11-05