Friday, October 8, 2010

Analyze ns-2 trace file

Ns-2 has two options to generate traces with different fomats. Basically, you could use
$ns use-newtrace
to generate the new trace and the detailed explanation could be found in Ns Manual. A very good reference about the trace is the ns-2 wiki page. See: http://nsnam.isi.edu/nsnam/index.php/NS-2_Trace_Formats

By default, old trace format is used. The source code ./trace/cmu-trace.cc needs to be read to understand it completely. For instance, the function format_ip will explain the trace of IP part.
void
CMUTrace::format_ip(Packet *p, int offset)
{
        struct hdr_cmn *ch = HDR_CMN(p);
        struct hdr_ip *ih = HDR_IP(p);

        // hack the IP address to convert pkt format to hostid format
        // for now until port ids are removed from IP address. -Padma.
        int src = Address::instance().get_nodeaddr(ih->saddr());
        int dst = Address::instance().get_nodeaddr(ih->daddr());

    ............

}

void
CMUTrace::format_mac(Packet *p, int offset)
{

else {
                sprintf(pt_->buffer() + offset,
                        " [%x %x %x %x] ",
                        //*((u_int16_t*) &mh->dh_fc),
                        mh->dh_duration,

                        ETHER_ADDR(mh->dh_ra),
                        ETHER_ADDR(mh->dh_ta),


                        GET_ETHER_TYPE(mh->dh_body));
        }
......

}


A typical trace for a CBR traffic is:

s 20.000000000 _0_ AGT  --- 6 cbr 512 [0 0 0 0] ------- [0:0 1:0 32 0] [0] 0 0
r 20.000000000 _0_ RTR  --- 6 cbr 512 [0 0 0 0] ------- [0:0 1:0 32 0] [0] 0 0
s 20.000000000 _0_ RTR  --- 6 cbr 532 [0 0 0 0] ------- [0:0 1:0 32 1] [0] 0 0
s 20.000275000 _0_ MAC  --- 6 cbr 584 [13a 1 0 800] ------- [0:0 1:0 32 1] [0] 0 0
r 20.004947063 _1_ MAC  --- 6 cbr 532 [13a 1 0 800] ------- [0:0 1:0 32 1] [0] 1 0
s 20.004957063 _1_ MAC  --- 0 ACK 38 [0 0 0 0]
r 20.004972063 _1_ AGT  --- 6 cbr 532 [13a 1 0 800] ------- [0:0 1:0 32 1] [0] 1 0
r 20.005261125 _0_ MAC  --- 0 ACK 38 [0 0 0 0]

An AWK script example to analyze the trace and calculate throughput
 
For a topology involve 4 flows with distinguishing source and destination nodes, this following awk script gets throughout data and put in wu.dat file
BEGIN {counter1 = 0; counter2 = 0; counter3 = 0; counter4 = 0;}
$1~/r/ && $2>50 && $2< 100  && /_12_/ && /AGT/  {   counter1 += ($8- 20)
                        size = $8 - 20 }
$1~/r/ && $2>50 && $2 <100 && /_13_/ && /AGT/  {   counter2 += ($8- 20)
                        size = $8 - 20 }
$1~/r/ && $2>50 && $2<100 && /_14_/ && /AGT/  {   counter3 += ($8- 20)
                        size = $8 - 20 }
$1~/r/ && $2>50 && $2<100 && /_15_/ && /AGT/  {   counter4 += ($8- 20)
                        size = $8 - 20 } throughout

END {
      print (size , counter1*8/(50), counter2*8/50, counter3*8/(50), counter4*8/50,
                  (counter1+counter2+counter3+counter4)*8/50 )  >> "wu.dat"}

To analyze the throughout or delay in a finite time duration, we need extract sending and receiving time from the trace file

$2>100 && $2 < 150 && (/_6_/ || /_2_/)  &&  /AGT/    {  print $1, $2, $6  > "dst2.tr" }
$2>100 && $2 <150 && (/_0_/ || /_9_/)  &&  /AGT/    {   print $1, $2, $6  > "dst9.tr" }
$2>100 && $2 <150 && (/_12_/ || /_3_/)  &&  /AGT/    {   print $1, $2, $6  > "dst3.tr" }
$2>100 && $2 <150 && (/_10_/ || /_4_/)  &&  /AGT/    {   print $1, $2, $6  > "dst4.tr" }
$2>100 && $2 <150 && (/_11_/ || /_8_/)  &&  /AGT/    {   print $1, $2, $6  > "dst8.tr" }

The respective new trace files such as "dst2.tr" will keep the sending or receiving time, "s'" or "r" label and, node's MAC address. From those data, we could use a program to calculate the average throughputor mean value of end-to-end delay of the flow.

The C source file (delay.c) to calculate delay is given as below:



#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  FILE *fin, *fout, *fout2;
  int pkt_index[1000]; 
  double pkt_send_time[1000];
  int head;
  //int tail;
  /* make sure it is large enough to hold all temprary data! */
  int i,j,num;
  double tm, tm_delay, total_delay, avg_delay, var_delay;
  int idx;
  char type;
  int flag;
  int num_sent;
  
  head = 0;
  for ( i=0; i<1000; i++)
  {
     pkt_index[i]  = -1;
     pkt_send_time[i] = 0.0f;
  }
  
  fin = fopen(argv[1], "r");
  fout = fopen (argv[2], "w");
  fout2 = fopen ( argv[3],"a");
  
  if(fin==NULL) {
    printf("Error: can't open file.\n");
    return 1;
  }
  else {
    printf("File opened successfully.\n");

    i = 0 ;  
    num  = 0;  
    num_sent = 0;
    while(!feof(fin)) 
    { 
      /* loop through and store the numbers into the array */
      fscanf(fin, "%c %lf %d \n", &type,&tm, &idx);
      //printf( "%f\n", tm);
      
  if ( type == 's' )
  {
   //addentry(idx, tm);
   pkt_index[head] = idx;
   pkt_send_time[head] = tm;
   head++;
   if ( head == 1000 ) head = 0;
   num_sent++;
     
     
  }
  else if ( type == 'r' )
  {
   flag = 0;
   for ( j=0; j< 1000; j++)
   {
    
    if (  pkt_index[j] == idx )
    {
    //printf("match,%f, %f\n!" ,tm, pkt_send_time[j]);
    tm_delay =  tm - pkt_send_time[j];
    flag = 1;
    break;
    } 
   }
   //addentry to output
   if ( flag == 1)
   {
   fprintf( fout,"%d %lf \n", idx, tm_delay ); 
   total_delay += tm_delay;    
   num++;
   }
  }
      i++;
    }
    avg_delay = total_delay / num ;
    fprintf(fout2,"Number of entries read: %d\n", i);
    fprintf(fout2,"Number of entries sent: %d\n", num_sent);
    fprintf(fout2,"Number of entries received:  %d\n", num);
    fprintf(fout2,"average delay of entries :  %lf\n", avg_delay);
    
    fclose(fin);
    fclose(fout);
  
    
    //finally, calcualte variance
    fout = fopen ( argv[2], "r") ;
    if ( fout == NULL ) return -1;
    var_delay = 0;
    while (!feof(fout))
    {
       fscanf(fout, "%d %lf\n", &idx ,&tm);
       var_delay += ( tm - avg_delay  ) * (tm - avg_delay);    
    }
    var_delay /= num;     
    fprintf(fout2, "variance of  delay is :  %lf\n", var_delay);
    fclose (fout);
    fclose (fout2);
    
    return 0;
  }
} 

To use this C code:
$ gcc delay.c -o delaycal
$ ./delaycal dst2.tr wu0.dat wu1.dat

2 comments:

DarkCompiled said...

Hi,

I found this article very useful, it explains every detail, good job!

I've developed the tool NS2 Visual Trace Analyzer, I hope it helps someone too. You can visit its blog at:
http://nsvisualtraceanalyzer.wordpress.com/


Best regards,
Fernando Rocha

Vanparia Pradip G. said...

hi sir.

i am facing error when i generate xgraph from trace(.tr) file like this

Error in file 'out.tr' at line ...
unknown line type
problems found with input data.

please sir give me solution it is very important to me.
pradeep.vanparia@gmail.com