home *** CD-ROM | disk | FTP | other *** search
- From: Stephen Hemminger <tektronix!orca!hammer!steveh@Ucb-Vax.ARPA>
- Newsgroups: net.sources
- Subject: Re: TCP debugging aid for 4.2BSD
- Date: 31 May 85 18:26:27 GMT
-
- Chris, I already had one of these based on your Window library....
-
- I didn't write any documentation for it but it should be pretty obvious.. 8-)
-
- ---- cut here ---
- /*
- * Tcp Debug - visual picture of Tcp connections
- *
- * Simple menu driven display of information about Tcp based connections.
- * This combines the information of netstat + trpt.
- */
-
- #ifndef lint
- static char _rcsid[] = "$Header: tcpic.c,v 1.1 85/04/09 15:25:00 steveh Exp $$Locker: $";
- #endif
-
- #include <stdio.h>
- #include <netdb.h>
- #include <nlist.h>
- #include <local/window.h>
-
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/socketvar.h>
- #define PRUREQUESTS
- #include <sys/protosw.h>
- #include <sys/ioctl.h>
- #include <sys/mbuf.h>
-
- #include <net/route.h>
- #include <net/if.h>
-
- #include <netinet/in.h>
- #include <netinet/in_pcb.h>
- #include <netinet/in_systm.h>
- #include <netinet/ip.h>
- #include <netinet/ip_var.h>
- #include <netinet/tcp.h>
- #define TCPSTATES
- #include <netinet/tcp_fsm.h>
- #include <netinet/tcp_seq.h>
- #define TCPTIMERS
- #include <netinet/tcp_timer.h>
- #include <netinet/tcp_var.h>
- #include <netinet/tcpip.h>
- #define TANAMES
- #include <netinet/tcp_debug.h>
-
-
- struct nlist nml[] = {
- #define N_TCB 0
- { "_tcb" },
- #define N_TCP_DEBUG 1
- { "_tcp_debug" },
- #define N_TCP_DEBX 2
- { "_tcp_debx" },
- #define N_MBSTAT 3
- { "_mbstat" },
- #define N_TCPSTAT 4
- { "_tcpstat" },
- 0
- };
-
-
- char Tf_flags[] = "\1ACKNOW\2DELACK\3DONTKEEP\4NOOPT";
- char Th_flags[] = "\1FIN\2SYN\3RST\4PUSH\5ACK\6URG";
-
- int kmem;
- int aflag = 0;
- int iflag = 0;
- int mflag = 0;
- int dflag = 0;
- int interval = 10;
-
- /* This determines what windows to display */
- /* The 4 ints specify the position & size;
- the two strings are optional, and
- are the label and initial contents for the window
- */
- struct initscreen {
- int i_x, i_y, i_xe, i_ye;
- char *i_lbl, *i_str;
- } InitScreen[] = {
- #define W_NETSTAT (wins[0])
- /*0*/ 0, 0, 80, 23, 0,
- 0,
- #define W_SOCK (wins[1])
- /*1*/ 0, 0, 16, 4, "Socket",
- "SendQ\nRecvQ",
- #define W_BYTES (wins[2])
- /*2*/ 0, 4, 16, 4, "Data Xfer",
- "Sent\nRcvd",
- #define W_RECV (wins[3])
- /*3*/ 0, 9, 16, 6, "Recv Seq",
- "Wind\nNext\nUrg\nAdv",
- #define W_TIMER (wins[4])
- /*4*/ 17, 0, 16, 6, "Tcp Timers",
- 0,
- #define W_SEND (wins[5])
- /*5*/ 17, 6, 16, 9, "Send Seq",
- "Wind\nNext\nUrg\nMax\nUna\nSeq#\nAck#",
- #define W_RETRY (wins[6])
- /*6*/ 35, 0, 16, 7, "Retransmit",
- "Shift\nIdle\nRtt\nRtseq\nSrtt",
- #define W_PARAM (wins[7])
- /*7*/ 34, 9, 20, 6, "Parameters",
- "State\nMax seg size\nForce\nFlags",
- #define W_IFNET (wins[8])
- /*8*/ 56, 0, 20, 7, "",
- "In packets\nIn error\nOut packets\nOut errors\nCollisions",
- #define W_MBSTAT (wins[9])
- /*9*/ 56, 8, 20, 6, "Mbuf stat",
- "In use\nFree\nPages\nFree Pages",
- #define W_TCPSTAT (wins[10])
- /*10*/ 56, 8, 20, 7, "Tcp stat",
- "Bad Sum\nBad Off\nHdr Drop\nBad Segs\nUnack",
- #define W_DEBUG (wins[11])
- /*11*/ 0, 15, 80, 8, 0, 0,
- #define W_HELP (wins[12])
- /*12*/ 0, 23, 80, 1, 0, 0
- };
-
- #define NWINS (sizeof InitScreen/sizeof *InitScreen)
-
- static char buf[BUFSIZ];
-
- #define WPR(w,y,x,fmt,n) WAcursor (w, y, x), \
- (void) sprintf (buf, fmt, n), \
- Wputs (buf, w)
-
- Win *wins[NWINS];
- int Maxrows, Maxcols;
-
- struct inpcb *GetInpcb();
- char *strsave();
- extern char *strcpy(), *malloc(), *calloc(), *index(),
- *inet_ntoa();
- extern long lseek();
-
- /*
- * Main program
- * Parse arguments, choose connection and display it.
- */
- main(argc, argv)
- int argc;
- char *argv[];
- {
- register struct inpcb *inp;
-
- while(--argc && **++argv == '-') {
- switch(argv[0][1]) {
- case 'a': ++aflag; break;
- case 'd': ++dflag; break;
- case 'i': ++iflag; break;
- case 'm': ++mflag; break;
- default:
- fprintf(stderr, "tcpic: unknown arg %s\n", argv[1]);
- fprintf(stderr,"Usage: tcpic [flags] [ interval ]\n");
- fprintf(stderr,"flags: %s\n%s\n%s\n%s\n",
- "\t-a\tall (include) servers",
- "\t-d\tshow debug trace (trpt)",
- "\t-i\tshow interfaces",
- "\t-m\tshow mbuf stats");
- exit(1);
- }
- }
-
- if(argc)
- interval = atoi(*++argv);
-
-
- nlist("/vmunix", nml);
-
- if(nml[0].n_value == 0) {
- fprintf(stderr,"tcpic: can't read kernel symbol table\n");
- exit(1);
- }
-
- if( (kmem = open("/dev/kmem", 0)) < 0) {
- perror("/dev/kmem");
- exit(1);
- }
-
- SetupWindows();
- Wfront(W_NETSTAT);
- Wsetmode(W_HELP, WBOLD);
- Wnewline(W_HELP, 0);
- Wlabel( W_NETSTAT,
- "# Local Address Foreign Address State",
- 0, 0);
-
- if(!iflag)
- Whide(W_IFNET);
- if(!mflag)
- Whide(W_MBSTAT);
- else
- Whide(W_TCPSTAT);
- BuildPortTable();
-
- sethostent(1);
-
- while( (inp = GetInpcb()) != NULL) {
- Whide(W_NETSTAT);
- Display(inp);
- Wunhide(W_NETSTAT);
- }
-
- Wexit(0);
- }
-
- /*
- * Set up the initial window display.
- */
- SetupWindows()
- {
- register struct initscreen *ip;
- register char *str;
- register Win *w;
- register int n;
-
- if(Winit(0,0)) {
- fprintf(stderr, "This terminal doesn't support windows\n");
- exit(1);
- }
- Wscreensize(&Maxrows, &Maxcols);
-
- /* initialize windows */
- for(n = 0, ip = InitScreen; n < NWINS; n++, ip++) {
- /* adjust size of some windows to fit screen */
-
- if(n == &W_NETSTAT - wins) {
- ip->i_ye = Maxrows-1; /* netstat takes full screen */
- ip->i_xe = Maxcols;
- } else if(n == &W_HELP - wins) {
- ip->i_y = Maxrows-1; /* help at bottom */
- ip->i_xe = Maxcols;
- } else if(n == &W_DEBUG - wins) {/* debug takes what is left on screen */
- ip->i_ye = Maxrows - ip->i_y - 2;
- ip->i_xe = Maxcols;
- }
-
- w = Wopen(0, ip->i_x, ip->i_y, ip->i_xe, ip->i_ye, 0, 0);
- if (w == 0) {
- Wcleanup();
- fprintf(stderr, "can't fit window '%s' at %d,%d of %d,%d\n",
- ip->i_lbl, ip->i_x, ip->i_y, ip->i_xe, ip->i_ye);
- fprintf(stderr, "Screen is too small\n");
- exit(1);
- }
- wins[ip - InitScreen] = w;
- Woncursor(w, 0);
- Wnewline(w, 1);
- Wwrap(w, 0);
- if(ip->i_lbl) {
- Wframe(w);
- Wlabel(w, ip->i_lbl, 0, 1);
- }
- if(str = ip ->i_str) {
- if(*str == '$') {
- Wsetmode(w, WINVERSE);
- str++;
- }
- Wputs(str, w);
- Wsetmode(w,0);
- }
- }
- }
-
- /*
- * Read the port names out of /etc/services and store in memory
- * for faster access.
- */
- char *PortTable[IPPORT_RESERVED];
-
- BuildPortTable() {
- register struct servent *sp;
- u_short port;
-
- setservent();
- while( (sp = getservent()) != NULL) {
- if(strcmp(sp->s_proto, "tcp") != 0)
- continue;
- port = ntohs((u_short) sp->s_port);
- if(port < IPPORT_RESERVED)
- PortTable[port] = strsave(sp->s_name);
- }
- endservent();
- }
-
- /*
- * Lookup a port name
- */
- char *inetport(port)
- u_short port;
- {
- u_short p = ntohs(port);
- static char portbuf[10];
-
- if(p == 0)
- return "*";
- else if(p >= IPPORT_RESERVED || PortTable[p] == NULL) {
- (void) sprintf(portbuf, "%d", p);
- return portbuf;
- } else
- return PortTable[p];
- }
-
- /*
- * Host address to name translation
- * keep already looked up entries around to speed things up.
- */
-
- struct hosts {
- struct hosts *ho_next;
- char *ho_name;
- u_long ho_addr;
- } *headhost = NULL;
-
- char *inethost(in)
- struct in_addr in;
- {
- register struct hosts *ho;
- register struct hostent *hp;
-
- if (inet_lnaof(in) == INADDR_ANY)
- return "*";
-
- /* look in save list */
- for(ho = headhost; ho != NULL; ho = ho->ho_next)
- if(ho->ho_addr == in.s_addr)
- return ho->ho_name;
- hp = gethostbyaddr(&in, sizeof (struct in_addr), AF_INET);
- if (hp == NULL)
- return inet_ntoa(in);
-
- /* add to save list */
- ho = (struct hosts *) malloc(sizeof(struct hosts));
- ho->ho_addr = in.s_addr;
- ho->ho_name = strsave(hp->h_name);
- ho->ho_next = headhost;
- headhost = ho;
-
- return hp->h_name;
- }
- /*
- * Pretty print an Internet address (net address + port).
- */
- char *
- inetprint(in, port)
- struct in_addr in;
- u_short port;
- {
- static char line[80];
-
- (void) sprintf(line, "%s.%s", inethost(in), inetport(port));
- return line;
- }
-
- /*
- * Print a value a la the %b format of the kernel's printf
- */
- char *
- flagprint(v, bits)
- register char *bits;
- u_short v;
- {
- register char *cp;
- register int i, any = 0;
- static char obuf[128];
-
- (void) sprintf(obuf,"%x", v);
- cp = obuf + strlen(obuf);
- if (v) {
- *cp++ = '<';
- while (i = *bits++) {
- if (v & (1 << (i-1))) {
- if (any)
- *cp++ = ',';
- any = 1;
- for (; *bits > 32; bits++)
- *cp++ = *bits;
- } else
- for (; *bits > 32; bits++)
- ;
- }
- *cp++ = '>';
- *cp = '\0';
- }
- return obuf;
- }
-
- /*
- * Print out tcp state
- */
- char *
- inetstate(off)
- long off;
- {
- static char line[40];
- struct tcpcb tcpcb;
-
- (void) lseek(kmem, off, 0);
- (void) read(kmem, (char *) &tcpcb, sizeof (tcpcb));
-
- if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
- (void) sprintf(line, "%d", tcpcb.t_state);
- else
- (void) strcpy(line, tcpstates[tcpcb.t_state]);
- return line;
- }
-
- ReadChar() {
- char c;
-
- if(read(0, &c, 1) != 1)
- Wexit(0);
- c &= 0x7f;
- ioctl(0, FIONREAD, (char *) &InputPending);
-
- return c;
- }
-
- struct inpcb *
- GetInpcb() {
- register struct inpcb *next, *prev;
- register int n;
- char c, *cp;
- struct inpcb inpcb;
- long off = nml[N_TCB].n_value;
- static int npcbs = 0;
- static struct inpcb **inpcbs;
- static char keys[] =
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
- if(npcbs == 0) {
- npcbs = Maxrows - 2;
- inpcbs = (struct inpcb **)
- calloc(npcbs, sizeof (struct inpcb *));
- }
-
- reread:
- WAcursor(W_NETSTAT, 0, 0);
- Wclear(W_NETSTAT, 2);
-
- (void) lseek(kmem, off, 0);
- (void) read(kmem, (char *) &inpcb, sizeof (struct inpcb));
-
- prev = (struct inpcb *) off;
-
- n = 0;
- /* follow around circular list */
- while(inpcb.inp_next != (struct inpcb *)off && n < npcbs) {
- next = inpcb.inp_next;
-
- (void) lseek(kmem, (long) next, 0);
- (void) read(kmem, (char *) &inpcb, sizeof(struct inpcb));
- if(inpcb.inp_prev != prev) {
- Wputs("??? (lost sync)\n", W_NETSTAT);
- break;
- }
-
- if(!aflag && inet_lnaof(inpcb.inp_laddr) == INADDR_ANY) {
- prev = next;
- continue;
- }
-
- WAcursor(W_NETSTAT, n, 0);
- Wsetmode(W_NETSTAT, WBOLD);
- Wputc( keys[n], W_NETSTAT);
- Wsetmode(W_NETSTAT, 0);
- (void) sprintf(buf, " %-18.18s",
- inetprint(inpcb.inp_laddr,inpcb.inp_lport));
- Wputs(buf, W_NETSTAT);
- (void) sprintf(buf, " %-18.18s %s",
- inetprint(inpcb.inp_faddr,inpcb.inp_fport),
- inetstate((long)inpcb.inp_ppcb));
- Wputs(buf, W_NETSTAT);
-
- prev = next;
- if(inpcbs[n] == 0)
- inpcbs[n] = (struct inpcb *) malloc(sizeof(inpcb));
- *inpcbs[n] = inpcb;
- ++n;
- }
-
- Wclearline(W_HELP, 2);
- Wputs("<letter> => show conn, <SPACE> => reread, <ESC> => quit, '^L' => redraw\r",
- W_HELP);
- Wrefresh(0);
-
- for(;;) {
- switch(c = ReadChar()) {
- case CTRL(l):
- ++ScreenGarbaged;
- /* fall into */
- case ' ':
- goto reread;
- case CTRL([):
- return NULL;
- default:
- cp = index(keys, c);
- }
- if(cp == NULL || cp >= &keys[n])
- Ding();
- else
- break;
- }
-
- return inpcbs[cp - keys];
- }
-
- struct socket sockstr;
- struct rtentry rtentry;
- struct ifnet iflast;
- struct tcpstat tcplast;
- struct mbuf mtcpcb; /* mbuf containing tcpcb */
- char ifname[10];
-
- Display(inp)
- register struct inpcb *inp;
- {
- register struct mbuf *mptr;
- register int i;
-
- Wclearline(W_HELP,2);
- Wputs("<ESC> => quit back to menu, '^L' => redraw\r", W_HELP);
-
-
- for(i = 0; i < TCPT_NTIMERS; ++i) {
- WPR(W_TIMER, i, 0, "%s", tcptimers[i]);
- }
-
- if(iflag) {
- (void) lseek(kmem, (long) inp->inp_route.ro_rt, 0);
- (void) read(kmem, (char *) &rtentry, sizeof(rtentry));
-
- (void) lseek(kmem, (long) rtentry.rt_ifp, 0);
- (void) read(kmem, (char *) &iflast, sizeof(struct ifnet));
-
- (void) lseek(kmem, (long) iflast.if_name, 0);
- (void) read(kmem, ifname, sizeof(ifname));
-
- (void) sprintf(buf, "If %s%d", ifname, iflast.if_unit);
- Wlabel(W_IFNET, buf, 0, 1);
- }
-
- if(!mflag) {
- (void) lseek(kmem, nml[N_TCPSTAT].n_value, 0);
- (void) read(kmem, (caddr_t) &tcplast, sizeof tcplast);
- }
-
- Whide(W_DEBUG);
-
- mptr = dtom(inp->inp_ppcb);
-
- for(;;) {
- (void) lseek(kmem, (long) mptr, 0);
- (void) read(kmem, (char *) &mtcpcb, sizeof(mtcpcb));
-
- if(mtcpcb.m_type != MT_PCB ) {
- Wclearline(W_HELP, 2);
- Wputs("Connection closed\r", W_HELP);
- Wrefresh(0);
- sleep(1);
- break;
- }
-
- (void) lseek(kmem, (long) inp->inp_socket, 0);
- (void) read(kmem, (char *) &sockstr, sizeof(sockstr));
-
- DisplayTcp(mtod(&mtcpcb,struct tcpcb *));
- if(iflag)
- DisplayIf();
- if(mflag)
- DisplayMbuf();
- else
- DisplayStat();
-
- Wrefresh (0);
- if(dflag && sockstr.so_options & SO_DEBUG) {
- Wunhide(W_DEBUG);
- DoDebug(inp->inp_ppcb);
- }
-
- /* Refresh and redisplay */
- while (InputPending) {
- switch( ReadChar() ) {
- case CTRL(l):
- ScreenGarbaged++;
- break;
- case 'q':
- case 'Q':
- case CTRL([):
- return;
- }
- }
-
- if(interval)
- sleep(interval);
-
- }
- }
-
- DisplayStat()
- {
- struct tcpstat tcpcur;
-
- (void) lseek(kmem, nml[N_TCPSTAT].n_value, 0);
- (void) read(kmem, (char *) &tcpcur, sizeof tcpcur);
-
- WPR(W_TCPSTAT, 0, 10, "%8d", tcpcur.tcps_badsum-tcplast.tcps_badsum);
- WPR(W_TCPSTAT, 1, 10, "%8d", tcpcur.tcps_badoff-tcplast.tcps_badoff);
- WPR(W_TCPSTAT, 2, 10, "%8d", tcpcur.tcps_hdrops-tcplast.tcps_hdrops);
- WPR(W_TCPSTAT, 3, 10, "%8d", tcpcur.tcps_badsegs-tcplast.tcps_badsegs);
- WPR(W_TCPSTAT, 4, 10, "%8d", tcpcur.tcps_unack-tcplast.tcps_unack);
- tcplast = tcpcur;
- }
-
- DisplayMbuf()
- {
- struct mbstat mbstat;
-
- if(nml[N_MBSTAT].n_type == 0)
- return;
-
- (void) lseek(kmem, nml[N_MBSTAT].n_value, 0);
- (void) read(kmem, (char *) &mbstat, sizeof mbstat);
-
- WPR(W_MBSTAT, 0, 10, "%8d", mbstat.m_mbufs - mbstat.m_mbfree);
- WPR(W_MBSTAT, 1, 10, "%8d", mbstat.m_mbfree);
- WPR(W_MBSTAT, 2, 10, "%8d", mbstat.m_clusters - mbstat.m_clfree);
- WPR(W_MBSTAT, 3, 10, "%8d", mbstat.m_clfree);
- }
-
- DisplayIf()
- {
- struct ifnet ifcur;
-
- (void) lseek(kmem, (long) rtentry.rt_ifp, 0);
- (void) read(kmem, (char *) &ifcur, sizeof(struct ifnet));
-
- WPR(W_IFNET, 0, 11, "%8d", ifcur.if_ipackets - iflast.if_ipackets);
- WPR(W_IFNET, 1, 11, "%8d", ifcur.if_ierrors - iflast.if_ierrors);
- WPR(W_IFNET, 2, 11, "%8d", ifcur.if_opackets - iflast.if_opackets);
- WPR(W_IFNET, 3, 11, "%8d", ifcur.if_ierrors - iflast.if_ierrors);
- WPR(W_IFNET, 4, 11, "%8d", ifcur.if_collisions - iflast.if_collisions);
- iflast = ifcur;
- }
-
- DisplayTcp(tcp)
- register struct tcpcb *tcp;
- {
- register int i;
-
- for(i = 0; i < TCPT_NTIMERS; i++) {
- WPR(W_TIMER, i, 8, "%6d", tcp->t_timer[i]);
- }
-
- WPR(W_RETRY, 0, 6, "%8d", tcp->t_rxtshift);
- WPR(W_RETRY, 1, 6, "%8d", tcp->t_idle);
- WPR(W_RETRY, 2, 6, "%8d", tcp->t_rtt);
- WPR(W_RETRY, 3, 6, "%8x", tcp->t_rtseq);
- #ifdef NOFLOAT
- WPR(W_RETRY, 4, 6, "%8.2f", (double) tcp->t_srtt/((double) TCPT_SCALE));
- #else
- WPR(W_RETRY, 4, 6, "%8.2f", tcp->t_srtt);
- #endif
-
- WAcursor(W_PARAM, 0, 6);
- if (tcp->t_state < 0 || tcp->t_state >= TCP_NSTATES)
- (void) sprintf(buf, "%12d" , tcp->t_state);
- else
- (void) sprintf(buf, "%12s", tcpstates[tcp->t_state]);
- Wputs(buf, W_PARAM);
- WPR(W_PARAM, 1, 13, "%5d", tcp->t_maxseg);
- WPR(W_PARAM, 2, 14, "%4d", tcp->t_force);
- WPR(W_PARAM, 3, 6, "%12s", flagprint((u_short)tcp->t_flags, Tf_flags));
-
- WPR(W_SEND, 0, 6, "%8d", tcp->snd_wnd);
- WPR(W_SEND, 1, 6, "%8x", tcp->snd_nxt);
- WPR(W_SEND, 2, 6, "%8x", tcp->snd_up);
- WPR(W_SEND, 3, 6, "%8x", tcp->snd_max);
- WPR(W_SEND, 4, 6, "%8x", tcp->snd_una);
- WPR(W_SEND, 5, 6, "%8x", tcp->snd_wl1);
- WPR(W_SEND, 6, 6, "%8x", tcp->snd_wl2);
-
- WPR(W_RECV, 0, 6, "%8d", tcp->rcv_wnd);
- WPR(W_RECV, 1, 6, "%8x", tcp->rcv_nxt);
- WPR(W_RECV, 2, 6, "%8x", tcp->rcv_up);
- WPR(W_RECV, 3, 6, "%8x", tcp->rcv_adv);
-
- WPR(W_BYTES, 0, 5, "%10d", (u_long)tcp->snd_nxt - (u_long)tcp->iss);
- WPR(W_BYTES, 1, 5, "%10d", (u_long)tcp->rcv_nxt - (u_long)tcp->irs);
-
- WPR(W_SOCK, 0, 5, "%10d", sockstr.so_snd.sb_cc);
- WPR(W_SOCK, 1, 5, "%10d", sockstr.so_rcv.sb_cc);
-
- }
-
- char *strsave(str)
- register char *str;
- {
- register int len = strlen(str);
- register char *new;
- extern char *malloc();
-
- new = malloc(++len);
- (void) strcpy(new, str);
- return new;
- }
-
- /*
- * Tcp debug routines
- */
-
- DoDebug(tcp)
- caddr_t tcp;
- {
- static int last_debx = -1;
- register int debx;
-
- if(nml[N_TCP_DEBUG].n_type == 0)
- return;
- (void) lseek(kmem, nml[N_TCP_DEBX].n_value, 0);
- (void) read(kmem, (char *) &tcp_debx, sizeof(tcp_debx));
-
- (void) lseek(kmem, nml[N_TCP_DEBUG].n_value, 0);
- (void) read(kmem, (char *) tcp_debug, sizeof(tcp_debug));
-
- Wunhide(W_DEBUG);
- if(last_debx == -1) {
- last_debx = tcp_debx;
- return;
- }
-
- for(debx = last_debx; debx != tcp_debx; debx = ++debx % TCP_NDEBUG) {
- if(tcp != tcp_debug[debx].td_tcb)
- continue;
- tcp_trace(&tcp_debug[debx]);
- Wrefresh(0);
- if(InputPending)
- break;
- }
- last_debx = debx;
- }
-
- /*
- * Print out a Tcp debug record
- */
- tcp_trace(td)
- register struct tcp_debug *td;
- {
- register struct tcpiphdr *ti = &td->td_ti;
- tcp_seq seq, ack;
- short act = td->td_act;
- short req = td->td_req;
- int len, flags, win, timer;
-
- (void) sprintf(buf,"%03d %s:%s ", (ntohl(td->td_time)/10) % 1000,
- tcpstates[td->td_ostate], tanames[act]);
- Wputs(buf, W_DEBUG);
-
- switch (act) {
- case TA_INPUT:
- case TA_OUTPUT:
- case TA_DROP:
- (void) sprintf(buf,"(src=%s,%d, dst=%s,%d)\n\t",
- inet_ntoa(ti->ti_src), ntohs(ti->ti_sport),
- inet_ntoa(ti->ti_dst), ntohs(ti->ti_dport));
- Wputs(buf, W_DEBUG);
-
- seq = ti->ti_seq;
- ack = ti->ti_ack;
- len = ti->ti_len;
- win = ti->ti_win;
- if (act == TA_OUTPUT) {
- seq = ntohl(seq);
- ack = ntohl(ack);
- len = ntohs(len);
- win = ntohs(win);
- }
- if (act == TA_OUTPUT)
- len -= sizeof (struct tcphdr);
- if (len)
- (void) sprintf(buf,"[%x..%x)@%x", seq, seq+len, ack);
- else
- (void) sprintf(buf,"%x@%x", seq, ack);
-
- Wputs(buf, W_DEBUG);
- if (win) {
- (void) sprintf(buf,"(win=%x)", win);
- Wputs(buf, W_DEBUG);
- }
-
- if (flags = ti->ti_flags) {
- Wputs(" flags=",W_DEBUG);
- Wputs(flagprint((u_short)flags, Th_flags), W_DEBUG);
- }
- break;
-
- case TA_USER:
- timer = req >> 8;
- req &= 0xff;
- (void) sprintf(buf,"%s", prurequests[req]);
- Wputs(buf, W_DEBUG);
- if (req == PRU_SLOWTIMO || req == PRU_FASTTIMO) {
- (void) sprintf(buf,"<%s>", tcptimers[timer]);
- Wputs(buf, W_DEBUG);
- }
- break;
- }
- (void) sprintf(buf," -> %s\n", tcpstates[td->td_cb.t_state]);
- Wputs(buf,W_DEBUG);
- }
-