<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">diff -c ../6.0.0a5/ns.c ./ns.c
*** ../6.0.0a5/ns.c	Mon Apr 16 13:17:20 2001
--- ./ns.c	Wed Jun  6 10:18:33 2001
***************
*** 1,6 ****
--- 1,11 ----
  /*
   * Kevin Lahey (kml@novell.com)
   * Novell, Inc.
+  *
+  * SACK support added by Daikichi Osuga (osuga@mml.yrp.nttdocomo.co.jp)
+  *
+  * NOTE : In official release ns2, trace file doesn't have SACK infomation.
+  *        to visualize SACK blocks ns2 trace format function must be modefied.
   */
  
  static char const rcsid[] =
***************
*** 16,31 ****
--- 21,58 ----
  
  #ifdef GROK_NS
  
+ /* constants */
+ #define MAXLINE 300
+ #define NSA 3
+ 
+ /* data structures */
+ struct sackblk {   
+   tcp_seq start;          /* start seq no. of sack block */
+   tcp_seq end;            /* end seq no. */
+ };  
+ 
+ struct sackopt {
+   unsigned char nop1;
+   unsigned char nop2;
+   unsigned char kind;
+   unsigned char length;
+   struct sackblk sackblk[1];
+ };
  
  /* static buffers for reading */
  static struct ether_header *pep;
  static int *pip_buf;
  static struct ip *ipb;
  static struct tcphdr *tcpb;
+ static struct sackopt *sackoptb;
+ static char line[MAXLINE];
  
  /* for debugging */
  static unsigned linenum;
  
+ /* prototypes */
+ int fgetline(FILE *fp, char s[], int lim);
+ 
  /* return the next packet header */
  /* currently only works for ETHERNET */
  static int
***************
*** 42,49 ****
      double c, d, e;
  
      while (1) {
- 	/* read the packet info */
  
  	char tt;
  	double timestamp;
  	int junk;
--- 69,77 ----
      double c, d, e;
  
      while (1) {
  
+ 	/* read the packet info */
+         int i;
  	char tt;
  	double timestamp;
  	int junk;
***************
*** 54,64 ****
  	int is_ack;
  	int is_tcp;
  	int rlen;
  
  	++linenum;
  
! 	/* correct NS output line would have 14 fields: */
! 	rlen = fscanf(stdin, "%c %lg %d %d %s %d %s %d %d.%hu %d.%hu %d %hu\n",
  		      &amp;tt,
  		      &amp;timestamp,
  		      &amp;junk,
--- 82,115 ----
  	int is_ack;
  	int is_tcp;
  	int rlen;
+ 	u_long src_addr;
+ 	u_long dst_addr;
+ 	u_short src_port;
+ 	u_short dst_port;
+ 	u_short ip_id;
+ 
+ 	/* read and discard. not used. */
+ 	int ackno;
+ 	int hex_flags;
+ 	int hlen;
+ 	
+ 	/* for SACK option */
+ 	int sa_len;
+ 	int sb[NSA][2];
+ 	int optlen = 0;
  
  	++linenum;
  
! 	if (fgetline(stdin, line, sizeof(line)) == 0)
! 	    return 0;
! 
! 	/*
! 	 * correct NS output line would have 14 fields:
! 	 * or 24 fields with additional SACK infomation
! 	 */
! 	rlen = sscanf(line, "%c %lg %d %d %s %d %s %d %d.%hu %d.%hu %d %hu"
! 		      " %d %x %d"
! 		      " %d %d %d %d %d %d %d",
  		      &amp;tt,
  		      &amp;timestamp,
  		      &amp;junk,
***************
*** 67,91 ****
  		      plen,
  		      flags,
  		      &amp;iteration,
! 		      &amp;ipb-&gt;ip_src.s_addr,
! 		      &amp;tcpb-&gt;th_sport,
! 		      &amp;ipb-&gt;ip_dst.s_addr,
! 		      &amp;tcpb-&gt;th_dport,
  		      &amp;seq,
! 		      &amp;ipb-&gt;ip_id);
  
! 	/* if we can't match all 14 fields, we give up on the file */
! 	if (rlen != 14) {
  	    fprintf(stderr,"Bad ns packet header in line %u\n", linenum);
  	    return(0);
  	}
  
- 	if (rlen == EOF) {
- 	    return(0);
- 	}
- 
- 	tcpb-&gt;th_sport = tcpb-&gt;th_dport = iteration;
- 
  	is_tcp = strcmp(type, "tcp") == 0;
  	is_ack = strcmp(type, "ack") == 0;
  
--- 118,147 ----
  		      plen,
  		      flags,
  		      &amp;iteration,
! 		      &amp;src_addr,
! 		      &amp;src_port,
! 		      &amp;dst_addr,
! 		      &amp;dst_port,
  		      &amp;seq,
! 		      &amp;ip_id,
! 		      &amp;ackno,
! 		      &amp;hex_flags,
! 		      &amp;hlen,
! 		      &amp;sa_len,
! 		      &amp;sb[0][0],
! 		      &amp;sb[0][1],
! 		      &amp;sb[1][0],
! 		      &amp;sb[1][1],
! 		      &amp;sb[2][0],
! 		      &amp;sb[2][1]
! 		      );
  
! 	/* if we can't match all 24 or 14 fields, we give up on the file */
! 	if (rlen != 14 &amp;&amp; rlen != 24) {
  	    fprintf(stderr,"Bad ns packet header in line %u\n", linenum);
  	    return(0);
  	}
  
  	is_tcp = strcmp(type, "tcp") == 0;
  	is_ack = strcmp(type, "ack") == 0;
  
***************
*** 93,101 ****
  	if (!is_tcp &amp;&amp; !is_ack)
  	    continue;
  
! 	if (packlen == 0 &amp;&amp; is_tcp)
! 	    packlen = *plen - sizeof(struct ip) - sizeof(struct tcphdr);
  
  	ipb-&gt;ip_len = htons(*plen);
  
  	if (is_tcp) {
--- 149,178 ----
  	if (!is_tcp &amp;&amp; !is_ack)
  	    continue;
  
! 	ipb-&gt;ip_src.s_addr = htonl(src_addr);
! 	tcpb-&gt;th_sport = htons(src_port);
! 	ipb-&gt;ip_dst.s_addr = htonl(dst_addr);
! 	tcpb-&gt;th_dport = htons(dst_port);
! 
! 	if (is_ack &amp;&amp; rlen == 24 &amp;&amp; sa_len) {
! 	    /* build sack option */
! 	    sackoptb-&gt;nop1 = TCPOPT_NOP;
! 	    sackoptb-&gt;nop2 = TCPOPT_NOP;
! 	    sackoptb-&gt;kind = TCPOPT_SACK;
! 	    for (i = 0; i &lt; sa_len; i++) {
! 	        /* fill sack block */
! 	        sackoptb-&gt;sackblk[i].start = htonl(sb[i][0] * packlen);
! 		sackoptb-&gt;sackblk[i].end = htonl(sb[i][1] * packlen);
! 	    }
! 	    sackoptb-&gt;length = 2 + sa_len * 8;
! 	    optlen = 4 + sa_len * 8;
! 	    *plen += 4; /* ns doesn't consider NOP, NOP, SACK, len */
! 	}
  
+ 	if (packlen == 0 &amp;&amp; is_tcp) {
+ 	    packlen = *plen - sizeof(struct ip) - sizeof(struct tcphdr)
+ 	              - optlen;
+ 	}
  	ipb-&gt;ip_len = htons(*plen);
  
  	if (is_tcp) {
***************
*** 114,120 ****
  	ipb-&gt;ip_ttl = 64;  /* nice round number */
  	ipb-&gt;ip_p = 6;     /* TCP */
  	ipb-&gt;ip_sum = 0;   /* IP checksum, hope it doesn't get checked! */
! 	ipb-&gt;ip_id = htons(ipb-&gt;ip_id);
  
  	/* is the transport "ECN-Capable"? */
  	if (strchr(flags, 'N') != NULL)
--- 191,197 ----
  	ipb-&gt;ip_ttl = 64;  /* nice round number */
  	ipb-&gt;ip_p = 6;     /* TCP */
  	ipb-&gt;ip_sum = 0;   /* IP checksum, hope it doesn't get checked! */
! 	ipb-&gt;ip_id = htons(ip_id);
  
  	/* is the transport "ECN-Capable"? */
  	if (strchr(flags, 'N') != NULL)
***************
*** 125,131 ****
  	    ipb-&gt;ip_tos |= IPTOS_CE;
  
  	/* make up a reasonable TCP segment header */
! 	tcpb-&gt;th_off = 5;  /* no options, normal length of 20 */
  	tcpb-&gt;th_flags = TH_ACK; /* sdo: what about first SYN?? */
  	tcpb-&gt;th_x2 = 0;
  	tcpb-&gt;th_sum = 0;
--- 202,208 ----
  	    ipb-&gt;ip_tos |= IPTOS_CE;
  
  	/* make up a reasonable TCP segment header */
! 	tcpb-&gt;th_off = 5 + optlen / 4; /* now only consider sack option */
  	tcpb-&gt;th_flags = TH_ACK; /* sdo: what about first SYN?? */
  	tcpb-&gt;th_x2 = 0;
  	tcpb-&gt;th_sum = 0;
***************
*** 195,200 ****
--- 272,278 ----
      
      ipb = (struct ip *) pip_buf;
      tcpb = (struct tcphdr *) (ipb + 1);
+     sackoptb = (struct sackopt *) (tcpb + 1);
  
      /* Set up the stuff that shouldn't change */
      pep-&gt;ether_type = ETHERTYPE_IP;
***************
*** 203,207 ****
--- 281,298 ----
      linenum = 0;
  
      return(pread_ns);
+ }
+ 
+ static int fgetline(FILE *fp, char s[], int lim)
+ {
+   int c, i;
+ 
+   i = 0;
+   while (--lim &gt; 0 &amp;&amp; (c = getc(fp)) != EOF &amp;&amp; c != '\n')
+     s[i++] = c;
+   if (c == '\n')
+     s[i++] = c;
+   s[i] = '\0';
+   return i;
  }
  #endif /* GROK_NS */

</pre></body></html>