listing
[unix-history] / usr / src / sys / netinet / tcp_usrreq.c
index e2c5bed..abad774 100644 (file)
-/* tcp_usrreq.c 1.23 81/11/03 */
+/* tcp_usrreq.c 1.35 81/11/25 */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/mbuf.h"
 #include "../h/socket.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/mbuf.h"
 #include "../h/socket.h"
-#include "../inet/inet.h"
-#include "../inet/inet_systm.h"
-#include "../inet/imp.h"
-#include "../inet/ip.h"
-#include "../inet/tcp.h"
-#define TCPFSTAB
-#ifdef TCPDEBUG
-#define TCPSTATES
-#endif
-#include "../inet/tcp_fsm.h"
-
-tcp_timeo()
-{
-       register struct tcb *tp;
-       int s = splnet();
-       register u_char *tmp;
-       register int i;
-COUNT(TCP_TIMEO);
-
-       /*
-        * Search through tcb's and update active timers.
-        */
-       for (tp = tcb.tcb_next; tp != (struct tcb *)&tcb; tp = tp->tcb_next) {
-               tmp = &tp->t_init;
-               for (i = 0; i < TNTIMERS; i++)
-                       if (*tmp && --*tmp == 0)
-                               tcp_usrreq(ISTIMER, i, tp, 0);
-               tp->t_xmt++;
-       }
-       tcp_iss += ISSINCR;             /* increment iss */
-       timeout(tcp_timeo, 0, hz);      /* reschedule every second */
-       splx(s);
-}
-
+#include "../h/socketvar.h"
+#include "../h/protosw.h"
+#include "../net/inet.h"
+#include "../net/inet_pcb.h"
+#include "../net/inet_systm.h"
+#include "../net/if.h"
+#include "../net/imp.h"
+#include "../net/ip.h"
+#include "../net/ip_var.h"
+#include "../net/tcp.h"
+#include "../net/tcp_fsm.h"
+#include "../net/tcp_var.h"
+#include "/usr/include/errno.h"
+
+struct tcpcb *tcp_newtcpcb();
 /*
  * Process a TCP user request for tcp tb.  If this is a send request
  * then m is the mbuf chain of send data.  If this is a timer expiration
  * (called from the software clock routine), then timertype tells which timer.
  */
 /*
  * Process a TCP user request for tcp tb.  If this is a send request
  * then m is the mbuf chain of send data.  If this is a timer expiration
  * (called from the software clock routine), then timertype tells which timer.
  */
-tcp_usrreq(input, timertype, tp, m)
-       int input, timertype;
-       register struct tcb *tp;
+tcp_usrreq(so, req, m, addr)
+       struct socket *so;
+       int req;
        struct mbuf *m;
        struct mbuf *m;
+       caddr_t addr;
 {
 {
+       register struct inpcb *inp = sotoinpcb(so);
+       register struct tcpcb *tp;
        int s = splnet();
        int s = splnet();
-       register int nstate;
-#ifdef TCPDEBUG
-       struct tcp_debug tdb;
-#endif
+       int error = 0;
+       struct tcpiphdr ti;
 COUNT(TCP_USRREQ);
 
 COUNT(TCP_USRREQ);
 
-       nstate = tp->t_state;
-       tp->tc_flags &= ~TC_NET_KEEP;
+       /*
+        * Make sure attached.  If not,
+        * only PRU_ATTACH is valid.
+        */
+       if (inp == 0 && req != PRU_ATTACH)
+               splx(s);
+               return (EINVAL);
+       }
+       if (inp) {
+               tp = intotcpcb(inp);
 #ifdef KPROF
 #ifdef KPROF
-       acounts[nstate][input]++;
-#endif
-#ifdef TCPDEBUG
-       if ((tp->t_ucb->uc_flags & UDEBUG) || tcpconsdebug) {
-               tdb_setup(tp, (struct th *)0, input, &tdb);
-               tdb.td_tim = timertype;
-       } else
-               tdb.td_tod = 0;
+               tcp_acounts[tp->t_state][req]++;
 #endif
 #endif
-       switch (input) {
+       }
+       switch (req) {
 
 
-       /*
-        * Passive open.  Create a tcp control block
-        * and enter listen state.
-        */
-       case IUOPENA:                           /* 2 */
-               if (nstate != 0 && nstate != CLOSED)
-                       goto bad;
-               tcp_open(tp, PASSIVE);
-               nstate = LISTEN;
+       case PRU_ATTACH:
+               if (inp) {
+                       error = EISCONN;
+                       break;
+               }
+               error = in_pcballoc(so, &tcb, 2048, 2048, (struct sockaddr_in *)addr);
+               if (error)
+                       break;
+               inp = (struct inpcb *)so->so_pcb;
+               if (so->so_options & SO_ACCEPTCONN) {
+                       tp = tcp_newtcpcb(inp);
+                       if (tp == 0) {
+                               in_pcbfree(inp);
+                               error = ENOBUFS;
+                               break;
+                       }
+                       tp->t_state = TCPS_LISTEN;
+               } else
+                       tp->t_state = TCPS_CLOSED;
                break;
 
                break;
 
-       /*
-        * Active open.  Create a tcp control block,
-        * send a SYN and enter SYN_SENT state.
-        */
-       case IUOPENR:                           /* 1 */
-               if (nstate != 0 && nstate != CLOSED)
-                       goto bad;
-               tcp_open(tp, ACTIVE);
-               tcp_sndctl(tp);
-               nstate = SYN_SENT;
+       case PRU_DETACH:
                break;
 
                break;
 
-       /*
-        * Tcp close call.  Can be generated by a user ioctl (half-close),
-        * or when higher level close occurs, if a close hasn't happened
-        * already.
-        */
-       case IUCLOSE:
-               switch (nstate) {
-
-               /*
-                * If we are aborting out of a listener or a active
-                * connection which has not yet completed we can just
-                * delete the tcb.
-                */
-               case LISTEN:
-               case SYN_SENT:                  /* 10 */
-                       tcp_close(tp, UCLOSED);
-                       nstate = CLOSED;
+       case PRU_CONNECT:
+               error = in_pcbsetpeer(inp, (struct sockaddr_in *)addr);
+               if (error)
                        break;
                        break;
-
-               /*
-                * If we have gotten as far as receiving a syn from
-                * our foreign peer, we must be sure to send a FIN.
-                * If we have gotten a FIN from the foreign peer already
-                * (CLOSE_WAIT state), then all that remains is to wait
-                * for his ack of the FIN (LAST_ACK state).  If we have
-                * not gotten a FIN from the foreign peer then we need
-                * to either:
-                *      1. rcv ack of our FIN (to FIN_W2) and then
-                *         send an ACK (to TIME_WAIT) and timeout at 2*MSL.
-                * or   2. receive hist FIN (to CLOSING), send an ACK
-                *         (to TIME_WAIT), and then timeout.
-                * In any case this starts with a transition to FIN_W1 here.
-                */
-               case SYN_RCVD:                  /* 24,25 */
-               case L_SYN_RCVD:
-               case ESTAB:     
-               case CLOSE_WAIT:                /* 10 */
-                       tp->tc_flags |= TC_SND_FIN;
-                       tcp_sndctl(tp);
-                       tp->tc_flags |= TC_USR_CLOSED;
-                       nstate = nstate != CLOSE_WAIT ? FIN_W1 : LAST_ACK;
+               tp = tcp_newtcpcb(inp);
+               if (tp == 0) {
+                       inp->inp_faddr.s_addr = 0;
+                       error = ENOBUFS;
                        break;
                        break;
-                       
-               /*
-                * In these states the user has already closed;
-                * trying to close again is an error.
-                */
-               case FIN_W1:
-               case FIN_W2:
-               case TIME_WAIT:
-               case CLOSING:
-               case LAST_ACK:
-               case RCV_WAIT:
-                       to_user(tp->t_ucb, UCLSERR);
-                       break;
-
-               default:
-                       goto bad;
                }
                }
+               tp->t_inpcb = inp;
+               inp->inp_ppcb = (caddr_t)tp;
+               soisconnecting(so);
+               tp->t_state = TCPS_SYN_SENT;
+               tcp_output(tp);
                break;
 
                break;
 
-       /*
-        * TCP Timer processing.
-        * Timers should expire only on open connections
-        * not in LISTEN state.
-        */
-       case ISTIMER:                           /* 14,17,34,35,36,37,38 */
-               switch (nstate) {
-
-               case 0:
-               case CLOSED:
-               case LISTEN:
-                       goto bad;
-
-               default:
-                       nstate = tcp_timers(tp, timertype);
-               }
+       case PRU_ACCEPT:
+               soisconnected(so);
                break;
 
                break;
 
-       /*
-        * User notification of more window availability after
-        * reading out data.  This should not happen before a connection
-        * is established or after it is closed.
-        * If the foreign peer has closed and the local entity
-        * has not, inform him of the FIN (give end of file).
-        * If the local entity is in RCV_WAIT state (draining data
-        * out of the TCP buffers after foreign close) and there
-        * is no more data, institute a close.
-        */
-       case IURECV:                            /* 42 */
-               if (nstate < ESTAB || nstate == CLOSED)
-                       goto bad;
-               tcp_sndwin(tp);         /* send new window */
-               if ((tp->tc_flags&TC_FIN_RCVD) &&
-                   (tp->tc_flags&TC_USR_CLOSED) == 0 &&
-                   rcv_empty(tp))
-                       to_user(tp, UCLOSED);
-               if (nstate == RCV_WAIT && rcv_empty(tp)) {
-                       tcp_close(tp, UCLOSED);
-                       nstate = CLOSED;
+       case PRU_DISCONNECT:
+               if (tp->t_state < TCPS_ESTABLISHED)
+                       tcp_close(tp);
+               else {
+                       soisdisconnecting(so);
+                       tcp_output(tp);
                }
                break;
 
                }
                break;
 
-       /*
-        * Send request on open connection.
-        * Should not happen if the connection is not yet established.
-        * Allowed only on ESTAB connection and after FIN from
-        * foreign peer.
-        */
-       case IUSEND:                            /* 40,41 */
-               switch (nstate) {
+       case PRU_SHUTDOWN:
+               socantsndmore(so);
+               switch (tp->t_state) {
 
 
-               case ESTAB:
-               case CLOSE_WAIT:
-                       nstate = tcp_usrsend(tp, m);
+               case TCPS_LISTEN:
+               case TCPS_SYN_SENT:
+                       tp->t_state = TCPS_CLOSED;
                        break;
                        break;
-               
-               default:
-                       if (nstate < ESTAB)
-                               goto bad;
-                       to_user(tp, UCLSERR);
-                       break;
-               }
-               break;
 
 
-       /*
-        * User abort of connection.
-        * If a SYN has been received, but we have not exchanged FINs
-        * then we need to send an RST.  In any case we then 
-        * enter closed state.
-        */
-       case IUABORT:                           /* 44,45 */
-               if (nstate == 0 || nstate == CLOSED)
+               case TCPS_SYN_RCVD:
+               case TCPS_ESTAB:
+                       tp->t_state = TCPS_FIN_WAIT_1;
+                       tcp_output(tp);
                        break;
                        break;
-               switch (nstate) {
 
 
-               case 0:
-               case CLOSED:
+               case TCPS_CLOSE_WAIT:
+                       tp->t_state = TCPS_LAST_ACK;
+                       tcp_output(tp);
                        break;
                        break;
+               }
+               break;
 
 
-               case SYN_RCVD:
-               case ESTAB:
-               case FIN_W1:
-               case FIN_W2:
-               case CLOSE_WAIT:
-                       tp->tc_flags |= TC_SND_RST;
-                       tcp_sndnull(tp);
-                       /* fall into ... */
-
-               default:
-                       tcp_close(tp, UABORT);
-                       nstate = CLOSED;
+       case PRU_RCVD:
+               if (tp->t_state < TCPS_ESTABLISHED) {
+                       error = ENOTCONN;
+                       break;
                }
                }
+               tcp_output(tp);
                break;
 
                break;
 
-       /*
-        * Network down entry.  Discard the tcb and force
-        * the state to be closed, ungracefully.
-        */
-       case INCLEAR:                           /* 47 */
-               if (nstate == 0 || nstate == CLOSED)
+       case PRU_SEND:
+               if (tp->t_state < TCPS_ESTABLISHED) {
+                       error = ENOTCONN;
+                       break;
+               }
+               if (tp->t_state > TCPS_CLOSE_WAIT) {
+                       error = EISDISCONN;
+                       m_freem(m);
                        break;
                        break;
-               tcp_close(tp, UNETDWN);
-               nstate = CLOSED;
+               }
+               sbappend(&so->so_snd, m);
+               if (tp->t_options & TO_EOL)
+                       tp->snd_end = tp->snd_una + so->so_snd.sb_cc;
+               if (tp->t_options & TO_URG)
+                       tp->snd_urp = tp->snd_una + so->so_snd.sb_cc + 1;
+               tcp_output(tp);
                break;
 
                break;
 
-       default:
-               panic("tcp_usrreq");
-       bad:
-               printf("tcp: bad state: tcb=%x state=%d input=%d\n",
-                   tp, tp->t_state, input);
-               nstate = EFAILEC;
+       case PRU_ABORT:
+               tcp_drop(tp, ECONNABORTED);
                break;
                break;
-       }
-#ifdef TCPDEBUG
-       if (tdb.td_tod)
-               tdb_stuff(&tdb, nstate);
-#endif
-       /* YECH */
-       switch (nstate) {
 
 
-       case CLOSED:
-       case SAME:
+       case PRU_CONTROL:
+               error = EOPNOTSUPP;
                break;
 
                break;
 
-       case EFAILEC:
-               if (m)
-                       m_freem(dtom(m));
+       case PRU_SLOWTIMO:
+               tcp_timers(tp, (int)addr);
                break;
 
        default:
                break;
 
        default:
-               tp->t_state = nstate;
-               break;
+               panic("tcp_usrreq");
        }
        splx(s);
        }
        splx(s);
+       return (error);
 }
 }
-
-/*
- * Open routine, called to initialize newly created tcb fields.
- */
-tcp_open(tp, mode)
-       register struct tcb *tp;
-       int mode;
-{
-       register struct ucb *up = tp->t_ucb;
-COUNT(TCP_OPEN);
-
-       /*
-        * Link in tcb queue and make
-        * initialize empty reassembly queue.
-        */
-       tp->tcb_next = tcb.tcb_next;
-       tcb.tcb_next->tcb_prev = tp;
-       tp->tcb_prev = (struct tcb *)&tcb;
-       tcb.tcb_next = tp;
-       tp->t_rcv_next = tp->t_rcv_prev = (struct th *)tp;
-
-       /*
-        * Initialize sequence numbers and
-        * round trip retransmit timer.
-        * (Other fields were init'd to zero when tcb allocated.)
-        */
-       tp->t_xmtime = T_REXMT;
-       tp->snd_end = tp->seq_fin = tp->snd_nxt = tp->snd_hi = tp->snd_una =
-           tp->iss = tcp_iss;
-       tp->snd_off = tp->iss + 1;
-       tcp_iss += (ISSINCR >> 1) + 1;
-
-       /*
-        * Set timeout for open.
-        * SHOULD THIS BE A HIGHER LEVEL FUNCTION!?! THINK SO.
-        */
-       if (up->uc_timeo)
-               tp->t_init = up->uc_timeo;
-       else if (mode == ACTIVE)
-               tp->t_init = T_INIT;
-       /* else
-               tp->t_init = 0; */
-       up->uc_timeo = 0;                               /* ### */
-}
-
-/*
- * Internal close of a connection, shutting down the tcb.
- */
-tcp_close(tp, state)
-       register struct tcb *tp;
-       short state;
-{
-       register struct ucb *up = tp->t_ucb;
-       register struct th *t;
-       register struct mbuf *m;
-COUNT(TCP_CLOSE);
-
-       /*
-        * Cancel all timers.
-        * SHOULD LOOP HERE !?!
-        */
-       tp->t_init = tp->t_rexmt = tp->t_rexmttl = tp->t_persist = 
-           tp->t_finack = 0;
-
-       /*
-        * Remque the tcb
-        */
-       tp->tcb_prev->tcb_next = tp->tcb_next;
-       tp->tcb_next->tcb_prev = tp->tcb_prev;
-
-       /*
-        * Discard all buffers...
-        *
-        * SHOULD COUNT EACH RESOURCE TO 0 AND PANIC IF CONFUSED
-        */
-       for (t = tp->t_rcv_next; t != (struct th *)tp; t = t->t_next)
-               m_freem(dtom(t));
-       if (up->uc_rbuf != NULL) {
-               m_freem(up->uc_rbuf);
-               up->uc_rbuf = NULL;
-       }
-       up->uc_rcc = 0;
-       if (up->uc_sbuf != NULL) {
-               m_freem(up->uc_sbuf);
-               up->uc_sbuf = NULL;
-       }
-       up->uc_ssize = 0;
-       for (m = tp->t_rcv_unack; m != NULL; m = m->m_act) {
-               m_freem(m);
-               tp->t_rcv_unack = NULL;
-       }
-
-       /*
-        * Free tcp send template.
-        */
-       if (up->uc_template) {
-               m_free(dtom(up->uc_template));
-               up->uc_template = 0;
-       }
-
-       /*
-        * Free the tcb
-        * WOULD THIS BETTER BE DONE AT USER CLOSE?
-        */
-       wmemfree((caddr_t)tp, 1024);
-       up->uc_tcb = NULL;
-
-       /*
-        * Lower buffer allocation.
-        * SHOULD BE A M_ROUTINE CALL.
-        */
-       mbstat.m_lowat -= up->uc_snd + (up->uc_rhiwat/MSIZE) + 2;
-       mbstat.m_hiwat = 2 * mbstat.m_lowat;
-
-       /*
-        * Free routing table entry.
-        */
-       if (up->uc_host != NULL) {
-               h_free(up->uc_host);
-               up->uc_host = NULL;
-       }
-
-       /*
-        * If user has initiated close (via close call), delete ucb
-        * entry, otherwise just wakeup so user can issue close call
-        */
-       if (tp->tc_flags&TC_USR_ABORT)
-               up->uc_proc = NULL;
-       else
-               to_user(up, state);                     /* ### */
-}
-
-/*
- * User routine to send data queue headed by m0 into the protocol.
- */
-tcp_usrsend(tp, m0)
-       register struct tcb *tp;
-       struct mbuf *m0;
-{
-       register struct mbuf *m, *n;
-       register struct ucb *up = tp->t_ucb;
-       register off;
-       seq_t last;
-COUNT(TCP_USRSEND);
-
-       last = tp->snd_off;
-       for (m = n = m0; m != NULL; m = m->m_next) {
-               up->uc_ssize++;
-               if (m->m_off > MMAXOFF)
-                       up->uc_ssize += NMBPG;
-               last += m->m_len;
-       }
-       if ((m = up->uc_sbuf) == NULL)
-               up->uc_sbuf = n;
-       else {
-               while (m->m_next != NULL) {
-                       m = m->m_next;
-                       last += m->m_len;
-               }
-               if (m->m_off <= MMAXOFF) {
-                       last += m->m_len;
-                       off = m->m_off + m->m_len;
-                       while (n && n->m_off <= MMAXOFF &&
-                           (MMAXOFF - off) >= n->m_len) {
-                               bcopy((caddr_t)((int)n + n->m_off),
-                                     (caddr_t)((int)m + off), n->m_len);
-                               m->m_len += n->m_len;
-                               off += n->m_len;
-                               up->uc_ssize--;
-                               n = m_free(n);
-                       }
-               }
-               m->m_next = n;
-       }
-       if (up->uc_flags & UEOL)
-               tp->snd_end = last;
-       if (up->uc_flags & UURG) {
-               tp->snd_urp = last+1;
-               tp->tc_flags |= TC_SND_URG;
-       }
-       tcp_send(tp);
-       return (SAME);
-}
-
-/*
- * TCP timer went off processing.
- */
-tcp_timers(tp, timertype)
-       register struct tcb *tp;
-       int timertype;
-{
-
-COUNT(TCP_TIMERS);
-       switch (timertype) {
-
-       case TINIT:             /* initialization timer */
-               if ((tp->tc_flags&TC_SYN_ACKED) == 0) {         /* 35 */
-                       tcp_close(tp, UINTIMO);
-                       return (CLOSED);
-               }
-               return (SAME);
-
-       case TFINACK:           /* fin-ack timer */
-               switch (tp->t_state) {
-
-               case TIME_WAIT:
-                       /*
-                        * We can be sure our ACK of foreign FIN was rcvd,
-                        * and can close if no data left for user.
-                        */
-                       if (rcv_empty(tp)) {
-                               tcp_close(tp, UCLOSED);         /* 14 */
-                               return (CLOSED);
-                       }
-                       return (RCV_WAIT);                      /* 17 */
-
-               case CLOSING:
-                       tp->tc_flags |= TC_WAITED_2_ML;
-                       return (SAME);
-
-               default:
-                       return (SAME);
-               }
-
-       case TREXMT:            /* retransmission timer */
-               if (tp->t_rexmt_val > tp->snd_una) {            /* 34 */
-                       /*
-                        * Set up for a retransmission, increase rexmt time
-                        * in case of multiple retransmissions.
-                        */
-                       tp->snd_nxt = tp->snd_una;
-                       tp->tc_flags |= TC_REXMT;
-                       tp->t_xmtime = tp->t_xmtime << 1;
-                       if (tp->t_xmtime > T_REMAX)
-                               tp->t_xmtime = T_REMAX;
-                       tcp_send(tp);
-               }
-               return (SAME);
-
-       case TREXMTTL:          /* retransmit too long */
-               if (tp->t_rtl_val > tp->snd_una)                /* 36 */
-                       to_user(tp->t_ucb, URXTIMO);
-               /*
-                * If user has already closed, abort the connection.
-                */
-               if (tp->tc_flags & TC_USR_CLOSED) {
-                       tcp_close(tp, URXTIMO);
-                       return (CLOSED);
-               }
-               return (SAME);
-
-       case TPERSIST:          /* persist timer */
-               /*
-                * Force a byte send through closed window.
-                */
-               tp->tc_flags |= TC_FORCE_ONE;
-               tcp_send(tp);
-               return (SAME);
-       }
-       panic("tcp_timers");
-}
-
-/* THIS ROUTINE IS A CROCK */
-to_user(up, state)
-       register struct ucb *up;
-       register short state;
-{
-COUNT(TO_USER);
-
-       up->uc_state |= state;
-       netwakeup(up);
-       if (state == UURGENT)
-               psignal(up->uc_proc, SIGURG);
-}
-
-#ifdef TCPDEBUG
-/*
- * TCP debugging utility subroutines.
- * THE NAMES OF THE FIELDS USED BY THESE ROUTINES ARE STUPID.
- */
-tdb_setup(tp, n, input, tdp)
-       struct tcb *tp;
-       register struct th *n;
-       int input;
-       register struct tcp_debug *tdp;
-{
-
-COUNT(TDB_SETUP);
-       tdp->td_tod = time;
-       tdp->td_tcb = tp;
-       tdp->td_old = tp->t_state;
-       tdp->td_inp = input;
-       tdp->td_tim = 0;
-       tdp->td_new = -1;
-       if (n) {
-               tdp->td_sno = n->t_seq;
-               tdp->td_ano = n->t_ackno;
-               tdp->td_wno = n->t_win;
-               tdp->td_lno = n->t_len;
-               tdp->td_flg = n->th_flags;
-       } else
-               tdp->td_sno = tdp->td_ano = tdp->td_wno = tdp->td_lno =
-                   tdp->td_flg = 0;
-}
-
-tdb_stuff(tdp, nstate)
-       struct tcp_debug *tdp;
-       int nstate;
-{
-COUNT(TDB_STUFF);
-
-       tdp->td_new = nstate;
-       tcp_debug[tdbx++ % TDBSIZE] = *tdp;
-       if (tcpconsdebug & 2)
-               tcp_prt(tdp);
-}
-
-tcp_prt(tdp)
-       register struct tcp_debug *tdp;
-{
-COUNT(TCP_PRT);
-
-       printf("%x ", ((int)tdp->td_tcb)&0xffffff);
-       if (tdp->td_inp == INSEND) {
-               printf("SEND #%x", tdp->td_sno);
-               tdp->td_lno = ntohs(tdp->td_lno);
-               tdp->td_wno = ntohs(tdp->td_wno);
-       } else {
-               if (tdp->td_inp == INRECV)
-                       printf("RCV #%x ", tdp->td_sno);
-               printf("%s.%s",
-                   tcpstates[tdp->td_old], tcpinputs[tdp->td_inp]);
-               if (tdp->td_inp == ISTIMER)
-                       printf("(%s)", tcptimers[tdp->td_tim]);
-               printf(" -> %s",
-                   tcpstates[(tdp->td_new > 0) ? tdp->td_new : tdp->td_old]);
-               if (tdp->td_new == -1)
-                       printf(" (FAILED)");
-       }
-       /* GROSS... DEPENDS ON SIGN EXTENSION OF CHARACTERS */
-       if (tdp->td_lno)
-               printf(" len=%d", tdp->td_lno);
-       if (tdp->td_wno)
-               printf(" win=%d", tdp->td_wno);
-       if (tdp->td_flg & TH_FIN) printf(" FIN");
-       if (tdp->td_flg & TH_SYN) printf(" SYN");
-       if (tdp->td_flg & TH_RST) printf(" RST");
-       if (tdp->td_flg & TH_EOL) printf(" EOL");
-       if (tdp->td_flg & TH_ACK)  printf(" ACK %x", tdp->td_ano);
-       if (tdp->td_flg & TH_URG) printf(" URG");
-       printf("\n");
-}
-#endif