home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Source Code 1994 March
/
Source_Code_CD-ROM_Walnut_Creek_March_1994.iso
/
unix_c
/
networks
/
tcpdebug.c
< prev
next >
Wrap
Internet Message Format
|
1989-03-21
|
18KB
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);
}