BSD 4_3_Net_2 release
[unix-history] / usr / src / sys / netiso / tp_pcb.c
index 6d2a82a..6c9d309 100644 (file)
@@ -1,5 +1,40 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)tp_pcb.c    7.11 (Berkeley) 5/6/91
+ */
+
 /***********************************************************
 /***********************************************************
-               Copyright IBM Corporation 1987
+                               Copyright IBM Corporation 1987
 
                       All Rights Reserved
 
 
                       All Rights Reserved
 
@@ -43,11 +78,6 @@ SOFTWARE.
  *
  */
 
  *
  */
 
-#ifndef lint
-static char *rcsid = "$Header: tp_pcb.c,v 5.4 88/11/18 17:28:24 nhall Exp $";
-#endif lint
-
-#include "argoxtwentyfive.h"
 #include "types.h"
 #include "param.h"
 #include "mbuf.h"
 #include "types.h"
 #include "param.h"
 #include "mbuf.h"
@@ -56,20 +86,17 @@ static char *rcsid = "$Header: tp_pcb.c,v 5.4 88/11/18 17:28:24 nhall Exp $";
 #include "protosw.h"
 #include "errno.h"
 #include "time.h"
 #include "protosw.h"
 #include "errno.h"
 #include "time.h"
-#include "../netiso/tp_param.h"
-#include "../netiso/tp_timer.h"
-#include "../netiso/tp_ip.h"
-#include "../netiso/tp_stat.h"
-#include "../netiso/tp_pcb.h"
-#include "../netiso/argo_debug.h"
-#include "../netiso/tp_tpdu.h"
-#include "../netiso/tp_trace.h"
-#include "../netiso/tp_meas.h"
-#include "../netiso/tp_seq.h"
-#include "../netiso/tp_clnp.h"
-
-/* list of reference structures */
-struct tp_ref tp_ref[N_TPREF];
+#include "argo_debug.h"
+#include "tp_param.h"
+#include "tp_timer.h"
+#include "tp_ip.h"
+#include "tp_stat.h"
+#include "tp_pcb.h"
+#include "tp_tpdu.h"
+#include "tp_trace.h"
+#include "tp_meas.h"
+#include "tp_seq.h"
+#include "tp_clnp.h"
 
 struct tp_param tp_param = {
        1,                              /*  configured          */
 
 struct tp_param tp_param = {
        1,                              /*  configured          */
@@ -113,7 +140,7 @@ struct tp_conn_param tp_conn_param[] = {
                0,                                              /* 1 bit use net xpd */
                0,                                              /* 1 bit use rcc */
                0,                                              /* 1 bit use efc */
                0,                                              /* 1 bit use net xpd */
                0,                                              /* 1 bit use rcc */
                0,                                              /* 1 bit use efc */
-               0,                                              /* no disc indications */
+               1,                                              /* no disc indications */
                0,                                              /* don't change params */
                ISO_CLNS,                               /* p_netservice */
        },
                0,                                              /* don't change params */
                ISO_CLNS,                               /* p_netservice */
        },
@@ -148,7 +175,7 @@ struct tp_conn_param tp_conn_param[] = {
                0,                                              /* 1 bit use net xpd */
                0,                                              /* 1 bit use rcc */
                0,                                              /* 1 bit use efc */
                0,                                              /* 1 bit use net xpd */
                0,                                              /* 1 bit use rcc */
                0,                                              /* 1 bit use efc */
-               0,                                              /* no disc indications */
+               1,                                              /* no disc indications */
                0,                                              /* don't change params */
                IN_CLNS,                                /* p_netservice */
        },
                0,                                              /* don't change params */
                IN_CLNS,                                /* p_netservice */
        },
@@ -229,6 +256,7 @@ struct tp_conn_param tp_conn_param[] = {
 #ifdef INET
 int            in_putnetaddr();
 int            in_getnetaddr();
 #ifdef INET
 int            in_putnetaddr();
 int            in_getnetaddr();
+int            in_cmpnetaddr();
 int    in_putsufx(); 
 int    in_getsufx(); 
 int    in_recycle_tsuffix(); 
 int    in_putsufx(); 
 int    in_getsufx(); 
 int    in_recycle_tsuffix(); 
@@ -245,6 +273,7 @@ struct inpcb        tp_inpcb;
 #ifdef ISO
 int            iso_putnetaddr();
 int            iso_getnetaddr();
 #ifdef ISO
 int            iso_putnetaddr();
 int            iso_getnetaddr();
+int            iso_cmpnetaddr();
 int    iso_putsufx(); 
 int    iso_getsufx(); 
 int    iso_recycle_tsuffix(); 
 int    iso_putsufx(); 
 int    iso_getsufx(); 
 int    iso_recycle_tsuffix(); 
@@ -259,27 +288,28 @@ int       tpclnp_output_dg();
 int            iso_nlctloutput();
 struct isopcb  tp_isopcb;
 #endif ISO
 int            iso_nlctloutput();
 struct isopcb  tp_isopcb;
 #endif ISO
-#if NARGOXTWENTYFIVE > 0
+#ifdef TPCONS
 int            iso_putnetaddr();
 int            iso_getnetaddr();
 int            iso_putnetaddr();
 int            iso_getnetaddr();
+int            iso_cmpnetaddr();
 int    iso_putsufx(); 
 int    iso_getsufx(); 
 int    iso_recycle_tsuffix(); 
 int    iso_putsufx(); 
 int    iso_getsufx(); 
 int    iso_recycle_tsuffix(); 
-int            tpcons_mtu(); 
 int            iso_pcbbind(); 
 int            iso_pcbbind(); 
-int            iso_pcbconnect(); 
+int            tpcons_pcbconnect(); 
+int            tpclnp_mtu();
 int            iso_pcbdisconnect(); 
 int    iso_pcbdetach(); 
 int    iso_pcballoc(); 
 int    tpcons_output(); 
 int            iso_pcbdisconnect(); 
 int    iso_pcbdetach(); 
 int    iso_pcballoc(); 
 int    tpcons_output(); 
-int    tpcons_output_dg(); 
 struct isopcb  tp_isopcb;
 struct isopcb  tp_isopcb;
-#endif NARGOXTWENTYFIVE
+#endif TPCONS
+
 
 struct nl_protosw nl_protosw[] = {
        /* ISO_CLNS */
 #ifdef ISO
 
 struct nl_protosw nl_protosw[] = {
        /* ISO_CLNS */
 #ifdef ISO
-       { AF_ISO, iso_putnetaddr, iso_getnetaddr,
+       { AF_ISO, iso_putnetaddr, iso_getnetaddr, iso_cmpnetaddr,
                iso_putsufx, iso_getsufx,
                iso_recycle_tsuffix,
                tpclnp_mtu, iso_pcbbind, iso_pcbconnect,
                iso_putsufx, iso_getsufx,
                iso_recycle_tsuffix,
                tpclnp_mtu, iso_pcbbind, iso_pcbconnect,
@@ -288,10 +318,12 @@ struct nl_protosw nl_protosw[] = {
                tpclnp_output, tpclnp_output_dg, iso_nlctloutput,
                (caddr_t) &tp_isopcb,
                },
                tpclnp_output, tpclnp_output_dg, iso_nlctloutput,
                (caddr_t) &tp_isopcb,
                },
+#else
+       { 0 },
 #endif ISO
        /* IN_CLNS */
 #ifdef INET
 #endif ISO
        /* IN_CLNS */
 #ifdef INET
-       { AF_INET, in_putnetaddr, in_getnetaddr,
+       { AF_INET, in_putnetaddr, in_getnetaddr, in_cmpnetaddr,
                in_putsufx, in_getsufx,
                in_recycle_tsuffix,
                tpip_mtu, in_pcbbind, in_pcbconnect,
                in_putsufx, in_getsufx,
                in_recycle_tsuffix,
                tpip_mtu, in_pcbbind, in_pcbconnect,
@@ -300,30 +332,25 @@ struct nl_protosw nl_protosw[] = {
                tpip_output, tpip_output_dg, /* nl_ctloutput */ NULL,
                (caddr_t) &tp_inpcb,
                },
                tpip_output, tpip_output_dg, /* nl_ctloutput */ NULL,
                (caddr_t) &tp_inpcb,
                },
+#else
+       { 0 },
 #endif INET
        /* ISO_CONS */
 #endif INET
        /* ISO_CONS */
-#ifdef ISO
-#if    NARGOXTWENTYFIVE > 0
-       { AF_ISO, iso_putnetaddr, iso_getnetaddr,
+#if defined(ISO) && defined(TPCONS)
+       { AF_ISO, iso_putnetaddr, iso_getnetaddr, iso_cmpnetaddr,
                iso_putsufx, iso_getsufx,
                iso_recycle_tsuffix,
                iso_putsufx, iso_getsufx,
                iso_recycle_tsuffix,
-               tpcons_mtu, iso_pcbbind, iso_pcbconnect,
+               tpclnp_mtu, iso_pcbbind, tpcons_pcbconnect,
                iso_pcbdisconnect,      iso_pcbdetach,
                iso_pcballoc,
                iso_pcbdisconnect,      iso_pcbdetach,
                iso_pcballoc,
-               tpcons_output, tpcons_output_dg, iso_nlctloutput,
+               tpcons_output, tpcons_output, iso_nlctloutput,
                (caddr_t) &tp_isopcb,
                },
                (caddr_t) &tp_isopcb,
                },
-#endif NARGOXTWENTYFIVE
-#endif ISO
-       { 0, 0, 0,
-               0, 0,
-               0,
-               0, 0, 0,
-               0,      0,
-               0,
-               0, 0, 0,
-               (caddr_t) 0,
-               }
+#else
+       { 0 },
+#endif ISO_CONS
+       /* End of protosw marker */
+       { 0 }
 };
 
 /*
 };
 
 /*
@@ -341,33 +368,26 @@ struct nl_protosw nl_protosw[] = {
  * 
  * NOTES:
  */
  * 
  * NOTES:
  */
-void
+int
 tp_init()
 {
        static int      init_done=0;
        void            tp_timerinit();
 
        if (init_done++)
 tp_init()
 {
        static int      init_done=0;
        void            tp_timerinit();
 
        if (init_done++)
-               return;
-
-#ifndef lint
-       if ( (sizeof(struct tp_pcb) >= MLEN)  || (sizeof(struct tp_pcb_aux) >= MLEN)  ){
-               tp_param.tpp_configed = 0;
-               printf(
-                       "TP not configured !!! pcb (0x%x, %d) or aux (0x%x, %d) too big!\n",
-                       sizeof(struct tp_pcb), sizeof(struct tp_pcb), 
-                       sizeof(struct tp_pcb_aux), sizeof(struct tp_pcb_aux));
-               printf("MLEN (0x%x, %d)\n", MLEN, MLEN);
-       }
-#endif lint
+               return 0;
+
 
        /* FOR INET */
        tp_inpcb.inp_next = tp_inpcb.inp_prev = &tp_inpcb;
        /* FOR ISO */
        tp_isopcb.isop_next = tp_isopcb.isop_prev = &tp_isopcb;
 
 
        /* FOR INET */
        tp_inpcb.inp_next = tp_inpcb.inp_prev = &tp_inpcb;
        /* FOR ISO */
        tp_isopcb.isop_next = tp_isopcb.isop_prev = &tp_isopcb;
 
+    tp_start_win = 2;
+
        tp_timerinit();
        bzero((caddr_t)&tp_stat, sizeof(struct tp_stat));
        tp_timerinit();
        bzero((caddr_t)&tp_stat, sizeof(struct tp_stat));
+       return 0;
 }
 
 /*
 }
 
 /*
@@ -394,25 +414,16 @@ void
 tp_soisdisconnecting(so)
        register struct socket *so;
 {
 tp_soisdisconnecting(so)
        register struct socket *so;
 {
-       so->so_state &= ~SS_ISCONNECTING;
-       so->so_state |= SS_ISDISCONNECTING;
-       if (so->so_head) {
-               if (!soqremque(so, 0) && !soqremque(so, 1))
-                       panic("tp_soisdisconnecting");
-               so->so_head = 0;
-       }
-       wakeup((caddr_t)&so->so_timeo);
-       sowwakeup(so);
-       sorwakeup(so);
+       soisdisconnecting(so);
+       so->so_state &= ~SS_CANTSENDMORE;
        IFPERF(sototpcb(so))
                register struct tp_pcb *tpcb = sototpcb(so);
                u_int   fsufx, lsufx;
 
        IFPERF(sototpcb(so))
                register struct tp_pcb *tpcb = sototpcb(so);
                u_int   fsufx, lsufx;
 
-               bcopy ( tpcb->tp_fsuffix, &fsufx, sizeof(u_int) );
-               bcopy ( tpcb->tp_lsuffix, &lsufx, sizeof(u_int) );
+               bcopy ((caddr_t)tpcb->tp_fsuffix, (caddr_t)&fsufx, sizeof(u_int) );
+               bcopy ((caddr_t)tpcb->tp_lsuffix, (caddr_t)&lsufx, sizeof(u_int) );
 
 
-               tpmeas( tpcb->tp_lref, TPtime_close, 
-                       &time, fsufx, lsufx, tpcb->tp_fref);
+               tpmeas(tpcb->tp_lref, TPtime_close, &time, fsufx, lsufx, tpcb->tp_fref);
                tpcb->tp_perf_on = 0; /* turn perf off */
        ENDPERF
 }
                tpcb->tp_perf_on = 0; /* turn perf off */
        ENDPERF
 }
@@ -447,25 +458,18 @@ tp_soisdisconnected(tpcb)
 {
        register struct socket  *so = tpcb->tp_sock;
 
 {
        register struct socket  *so = tpcb->tp_sock;
 
-       so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
-       if (so->so_head) {
-               if (!soqremque(so, 0) && !soqremque(so, 1))
-                       panic("tp_soisdisconnected");
-               so->so_head = 0;
-       }
-       wakeup((caddr_t)&so->so_timeo);
-       sowwakeup(so);
-       sorwakeup(so);
+       soisdisconnecting(so);
+       so->so_state &= ~SS_CANTSENDMORE;
        IFPERF(sototpcb(so))
        IFPERF(sototpcb(so))
-               register struct tp_pcb *tpcb = sototpcb(so);
+               register struct tp_pcb *ttpcb = sototpcb(so);
                u_int   fsufx, lsufx;
 
                /* CHOKE */
                u_int   fsufx, lsufx;
 
                /* CHOKE */
-               bcopy ( tpcb->tp_fsuffix, &fsufx, sizeof(u_int) );
-               bcopy ( tpcb->tp_lsuffix, &lsufx, sizeof(u_int) );
+               bcopy ((caddr_t)ttpcb->tp_fsuffix, (caddr_t)&fsufx, sizeof(u_int) );
+               bcopy ((caddr_t)ttpcb->tp_lsuffix, (caddr_t)&lsufx, sizeof(u_int) );
 
 
-               tpmeas( tpcb->tp_lref, TPtime_close, 
-                       &time, &lsufx, &fsufx, tpcb->tp_fref);
+               tpmeas(ttpcb->tp_lref, TPtime_close, 
+                  &time, &lsufx, &fsufx, ttpcb->tp_fref);
                tpcb->tp_perf_on = 0; /* turn perf off */
        ENDPERF
 
                tpcb->tp_perf_on = 0; /* turn perf off */
        ENDPERF
 
@@ -547,18 +551,13 @@ static RefNum
 tp_getref(tpcb) 
        register struct tp_pcb *tpcb;
 {
 tp_getref(tpcb) 
        register struct tp_pcb *tpcb;
 {
-       register struct tp_ref  *r = tp_ref; 
+       register struct tp_ref  *r = tp_ref; /* tp_ref[0] is never used */
        register int                    i=1;
 
        register int                    i=1;
 
-       r++; /* tp_ref[0] is never used */
 
 
-       /* REF_FREE is zero */
-       while( r->tpr_state ) {
-               r++; 
-               if ( i == N_TPREF ) {
+       while ((++r)->tpr_state != REF_FREE) {
+               if (++i == N_TPREF)
                        return TP_ENOREF;
                        return TP_ENOREF;
-               }
-               i++;
        }
        r->tpr_state = REF_OPENING;
        if (tp_maxrefopen < i) 
        }
        r->tpr_state = REF_OPENING;
        if (tp_maxrefopen < i) 
@@ -594,14 +593,11 @@ tp_getref(tpcb)
  *
  * NOTES:
  */
  *
  * NOTES:
  */
-int
-tp_attach(so,dom)
+tp_attach(so, dom)
        struct socket   *so;
        int                     dom;
 {
        register struct tp_pcb  *tpcb;
        struct socket   *so;
        int                     dom;
 {
        register struct tp_pcb  *tpcb;
-       register struct mbuf    *m;
-       register struct mbuf    *p;
        int                                     error;
        int                                     protocol = so->so_proto->pr_protocol;
        extern struct tp_conn_param tp_conn_param[];
        int                                     error;
        int                                     protocol = so->so_proto->pr_protocol;
        extern struct tp_conn_param tp_conn_param[];
@@ -627,27 +623,13 @@ tp_attach(so,dom)
        if (error)
                goto bad2;
 
        if (error)
                goto bad2;
 
-       MGET(m, M_DONTWAIT, TPMT_PCB);  /* for tpcb, main half */
-       if (m == NULL) {
+       MALLOC(tpcb, struct tp_pcb *, sizeof(*tpcb), M_PCB, M_NOWAIT);
+       if (tpcb == NULL) {
                error = ENOBUFS;
                goto bad2;
        }
                error = ENOBUFS;
                goto bad2;
        }
-
-       tpcb = mtod( m, struct tp_pcb * );
        bzero( (caddr_t)tpcb, sizeof (struct tp_pcb) );
 
        bzero( (caddr_t)tpcb, sizeof (struct tp_pcb) );
 
-       MGET(p, M_DONTWAIT, TPMT_PCB);  /* for the tpcb, auxilliary half */
-       if (p == NULL) {
-               error = ENOBUFS;
-               m_free(m); /* which is tpcb */
-               goto bad2;
-       } else {
-               p->m_len = sizeof(struct tp_pcb_aux);
-               p->m_act = MNULL;
-               tpcb->tp_aux = mtod(p, struct tp_pcb_aux *);
-               bzero( (caddr_t)tpcb->tp_aux, sizeof (struct tp_pcb_aux) );
-       }
-
        if ( ((tpcb->tp_lref = tp_getref(tpcb)) &  TP_ENOREF) != 0 ) { 
                error = ETOOMANYREFS; 
                goto bad3;
        if ( ((tpcb->tp_lref = tp_getref(tpcb)) &  TP_ENOREF) != 0 ) { 
                error = ETOOMANYREFS; 
                goto bad3;
@@ -732,8 +714,7 @@ bad3:
                printf("BAD3 in tp_attach, so 0x%x\n", so);
        ENDDEBUG
 
                printf("BAD3 in tp_attach, so 0x%x\n", so);
        ENDDEBUG
 
-       m_free(dtom(tpcb)); /* never a cluster  */
-       m_free(dtom(tpcb->tp_aux)); /* never a cluster */
+       free((caddr_t)tpcb, M_PCB); /* never a cluster  */
 
 bad2:
        IFDEBUG(D_CONN)
 
 bad2:
        IFDEBUG(D_CONN)
@@ -741,9 +722,8 @@ bad2:
        ENDDEBUG
        so->so_pcb = 0;
        so->so_tpcb = 0;
        ENDDEBUG
        so->so_pcb = 0;
        so->so_tpcb = 0;
-       sofree(so);
 
 
-bad:
+/*bad:*/
        IFDEBUG(D_CONN)
                printf("BAD in tp_attach, so 0x%x\n", so);
        ENDDEBUG
        IFDEBUG(D_CONN)
                printf("BAD in tp_attach, so 0x%x\n", so);
        ENDDEBUG
@@ -781,12 +761,12 @@ tp_detach(tpcb)
        register struct socket   *so = tpcb->tp_sock;
 
        IFDEBUG(D_CONN)
        register struct socket   *so = tpcb->tp_sock;
 
        IFDEBUG(D_CONN)
-               printf("tp_detach(tpcb 0x%x, so 0x%x) freelist 0%x\n",
-                       tpcb,so, mfree);
+               printf("tp_detach(tpcb 0x%x, so 0x%x)\n",
+                       tpcb,so);
        ENDDEBUG
        IFTRACE(D_CONN)
                tptraceTPCB(TPPTmisc, "tp_detach tpcb so lsufx", 
        ENDDEBUG
        IFTRACE(D_CONN)
                tptraceTPCB(TPPTmisc, "tp_detach tpcb so lsufx", 
-                       tpcb, so, *(int *)(tpcb->tp_lsuffix), 0);
+                       tpcb, so, *(u_short *)(tpcb->tp_lsuffix), 0);
        ENDTRACE
 
        if (so->so_head) {
        ENDTRACE
 
        if (so->so_head) {
@@ -816,6 +796,20 @@ tp_detach(tpcb)
 
 #undef FREE_RTC_LIST
 
 
 #undef FREE_RTC_LIST
 
+       IFDEBUG(D_CONN)
+               printf("so_snd at 0x%x so_rcv at 0x%x\n", &so->so_snd, &so->so_rcv);
+               dump_mbuf(so->so_snd.sb_mb, "so_snd at detach ");
+               printf("about to call LL detach, nlproto 0x%x, nl_detach 0x%x\n",
+                               tpcb->tp_nlproto, tpcb->tp_nlproto->nlp_pcbdetach);
+       ENDDEBUG
+
+       if (so->so_snd.sb_cc != 0)
+               sbflush(&so->so_snd);
+       if (tpcb->tp_Xrcv.sb_cc != 0)
+               sbdrop(&tpcb->tp_Xrcv, (int)tpcb->tp_Xrcv.sb_cc);
+       if (tpcb->tp_ucddata)
+               m_freem(tpcb->tp_ucddata);
+
        IFDEBUG(D_CONN)
                printf("calling (...nlproto->...)(0x%x, so 0x%x)\n", 
                        so->so_pcb, so);
        IFDEBUG(D_CONN)
                printf("calling (...nlproto->...)(0x%x, so 0x%x)\n", 
                        so->so_pcb, so);
@@ -824,45 +818,10 @@ tp_detach(tpcb)
                so->so_q0len, so->so_qlen, so->so_qlimit);
        ENDDEBUG
 
                so->so_q0len, so->so_qlen, so->so_qlimit);
        ENDDEBUG
 
-       if ( tpcb->tp_flags & (TPF_CONN_DATA_OUT | TPF_DISC_DATA_OUT ) ) {
-               ASSERT( so->so_snd.sb_cc != 0 );
-               IFDEBUG(D_CONN)
-                       printf(
-                       "detach, flags 0x%x doing sbdrop on so_snd, mb 0x%x cc 0x%x\n", 
-                               tpcb->tp_flags, so->so_snd.sb_mb, so->so_snd.sb_cc);
-                       dump_mbuf( so->so_snd.sb_mb, "detach so snd: \n");
-               ENDDEBUG
-               if ( so->so_snd.sb_cc != 0 )
-                       sbdrop( &so->so_snd, so->so_snd.sb_cc);
-               tpcb->tp_flags &= ~(TPF_CONN_DATA_OUT | TPF_DISC_DATA_OUT); 
-       }
-       if ( tpcb->tp_flags & (TPF_DISC_DATA_IN | TPF_CONN_DATA_IN ) ) {
-               ASSERT( tpcb->tp_Xrcv.sb_cc != 0 );
-               IFDEBUG(D_CONN)
-                       printf(
-                       "detach, flags 0x%x doing sbdrop on tp_Xrcv, mb 0x%x cc 0x%x\n", 
-                               tpcb->tp_flags, tpcb->tp_Xrcv.sb_mb, tpcb->tp_Xrcv.sb_cc);
-                       dump_mbuf( tpcb->tp_Xrcv.sb_mb, "detach Xrcv: \n");
-               ENDDEBUG
-               if( tpcb->tp_Xrcv.sb_cc != 0 )
-                       sbdrop( &tpcb->tp_Xrcv, tpcb->tp_Xrcv.sb_cc);
-               tpcb->tp_flags &= ~(TPF_CONN_DATA_IN | TPF_DISC_DATA_IN); 
-       }
 
 
-       IFDEBUG(D_CONN)
-               printf("so_snd at 0x%x so_rcv at 0x%x\n", &so->so_snd, &so->so_rcv);
-               dump_mbuf(so->so_snd.sb_mb, "so_snd at detach ");
-               printf("about to call LL detach, nlproto 0x%x, nl_detach 0x%x\n",
-                               tpcb->tp_nlproto, tpcb->tp_nlproto->nlp_pcbdetach);
-       ENDDEBUG
+       (tpcb->tp_nlproto->nlp_pcbdetach)(so->so_pcb);
+                               /* does an sofree(so) */
 
 
-       if ((tpcb->tp_nlproto->nlp_pcbdetach) (
-                               (struct inpcb *)so->so_pcb) /* does an sofree(so) */ < 0 ) {
-#ifdef         ARGO_DEBUG
-               printf("tp: nl_detach failed: tpcb 0x%x so 0x%x\n", tpcb, so);
-#endif         ARGO_DEBUG
-       }
-               
        IFDEBUG(D_CONN)
                printf("after xxx_pcbdetach\n");
        ENDDEBUG
        IFDEBUG(D_CONN)
                printf("after xxx_pcbdetach\n");
        ENDDEBUG
@@ -877,6 +836,10 @@ tp_detach(tpcb)
                tp_freeref(tpcb->tp_refp);
        }
 
                tp_freeref(tpcb->tp_refp);
        }
 
+       if (tpcb->tp_Xsnd.sb_mb) {
+               printf("Unsent Xdata on detach; would panic");
+               sbflush(&tpcb->tp_Xsnd);
+       }
        so->so_tpcb = (caddr_t)0;
 
        /* 
        so->so_tpcb = (caddr_t)0;
 
        /* 
@@ -887,27 +850,23 @@ tp_detach(tpcb)
         * of code, not the IFPERFs)
         */
 #ifdef TP_PERF_MEAS
         * of code, not the IFPERFs)
         */
 #ifdef TP_PERF_MEAS
-       if( tpcb->tp_p_meas != (struct tp_pmeas *)0 ) {
-               register struct mbuf *n;
-
-               n = MTOCL((struct mbuf *)(tpcb->tp_p_meas));
+       if (tpcb->tp_p_mbuf) {
+               register struct mbuf *m = tpcb->tp_p_mbuf;
+               struct mbuf *n;
                IFDEBUG(D_PERF_MEAS)
                        printf("freeing tp_p_meas 0x%x  ", tpcb->tp_p_meas);
                IFDEBUG(D_PERF_MEAS)
                        printf("freeing tp_p_meas 0x%x  ", tpcb->tp_p_meas);
-                       printf("n = 0x%x\n", n);
                ENDDEBUG
                ENDDEBUG
-               if (--mclrefcnt[mtocl(n)] == 0) { 
-                       n->m_next = mclfree;
-                       mclfree = n;
-                       mbstat.m_clfree++;
-               } 
+               do {
+                   MFREE(m, n);
+                   m = n;
+               } while (n);
+               tpcb->tp_p_meas = 0;
+               tpcb->tp_p_mbuf = 0;
        }
 #endif TP_PERF_MEAS
 
        IFDEBUG(D_CONN)
        }
 #endif TP_PERF_MEAS
 
        IFDEBUG(D_CONN)
-               printf(
-"end of detach, NOT single, tpcb 0x%x, dtom(tpcb) 0x%x tp_aux 0x%x dtom(aux) 0x%x\n",
-                tpcb, dtom(tpcb), tpcb->tp_aux, dtom(tpcb->tp_aux));
+               printf( "end of detach, NOT single, tpcb 0x%x\n", tpcb);
        ENDDEBUG
        ENDDEBUG
-       m_free(dtom(tpcb->tp_aux)); 
-       m_free(dtom(tpcb)); 
+       /* free((caddr_t)tpcb, M_PCB); WHere to put this ? */
 }
 }