/* Serial line tracing routines * Katie Stevens, UC Davis (original code) * Phil Karn, KA9Q */ #include #include "global.h" #include "mbuf.h" #include "internet.h" #include "ip.h" #include "slcomp.h" #include "trace.h" static int16 decodeint __ARGS((struct mbuf **bpp)); /* dump serial line IP packet; may have Van Jacobson TCP header compression */ void sl_dump(fp,bpp,unused) FILE *fp; struct mbuf **bpp; int unused; { struct mbuf *bp, *tbp; unsigned char c; int len; bp = *bpp; c = bp->data[0]; if ((c & 0xf0) == (IPVERSION << 4)) { fprintf(fp,"serial line IP: len: %3u\n",len_p(*bpp)); ip_dump(fp,bpp,1); } else if (c & 0x80) { fprintf(fp,"serial line VJ Compressed TCP: len %3u\n",len_p(*bpp)); vjcomp_dump(fp,bpp,0); } else { len = len_p(bp); fprintf(fp,"serial line VJ Uncompressed TCP: len %3u connection ID: %3u\n", len, uchar(bp->data[9])); /* FIX THIS! */ /* Get our own copy so we can mess with the data */ tbp = copy_p(bp, len); free_p(bp); *bpp = NULLBUF; /* Restore the bytes used with Uncompressed TCP */ tbp->data[0] &= 0x4f; /* FIX THIS! */ tbp->data[9] = TCP_PTCL; /* FIX THIS! */ /* Dump contents as a regular IP packet */ ip_dump(fp,&tbp,1); } } static int16 decodeint(bpp) struct mbuf **bpp; { char tmpbuf[2]; pullup(bpp,tmpbuf,1); if (tmpbuf[0] == 0) pullup(bpp,tmpbuf,2); else { tmpbuf[1] = tmpbuf[0]; tmpbuf[0] = 0; } return(get16(tmpbuf)); } void vjcomp_dump(fp,bpp,unused) FILE *fp; struct mbuf **bpp; int unused; { char changes; char tmpbuf[2]; if(bpp == NULLBUFP || *bpp == NULLBUF) return; /* Dump compressed TCP/IP header */ fprintf(fp,"VJ Compr TCP/IP: "); pullup(bpp,&changes,1); fprintf(fp,"changes: 0x%02x ",uchar(changes)); if (changes & NEW_C) { pullup(bpp,tmpbuf,1); fprintf(fp,"connection: 0x%02x ",uchar(tmpbuf[0])); } pullup(bpp,tmpbuf,2); fprintf(fp,"TCP checksum: 0x%04x ",get16(tmpbuf)); if (changes & TCP_PUSH_BIT) fprintf(fp,"PUSH\n"); else fprintf(fp,"\n"); switch (changes & SPECIALS_MASK) { case SPECIAL_I: fprintf(fp,"\t\t delta ACK and delta SEQ implied by length of data\n"); break; case SPECIAL_D: fprintf(fp,"\t\t delta SEQ implied by length of data\n"); break; default: fprintf(fp,"\t\t "); if (changes & NEW_U) { fprintf(fp,"Urgent pointer: 0x%02x ",decodeint(bpp)); } if (changes & NEW_W) fprintf(fp,"delta WINDOW: 0x%02x ",decodeint(bpp)); if (changes & NEW_A) fprintf(fp,"delta ACK: 0x%02x ",decodeint(bpp)); if (changes & NEW_S) fprintf(fp,"delta SEQ: 0x%02x ",decodeint(bpp)); break; } if (changes & NEW_I) { fprintf(fp,"new ID: %02x ",decodeint(bpp)); } else fprintf(fp,"increment ID "); fprintf(fp,"\n"); }