move packetizing routine to tp_subr.c
[unix-history] / usr / src / sys / netiso / tp_usrreq.c
index 9dd4c34..242865b 100644 (file)
@@ -1,3 +1,12 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * %sccs.include.redist.c%
+ *
+ *     @(#)tp_usrreq.c 7.22 (Berkeley) %G%
+ */
+
 /***********************************************************
                                Copyright IBM Corporation 1987
 
 /***********************************************************
                                Copyright IBM Corporation 1987
 
@@ -29,7 +38,6 @@ SOFTWARE.
  *
  * $Header: tp_usrreq.c,v 5.4 88/11/18 17:29:18 nhall Exp $
  * $Source: /usr/argo/sys/netiso/RCS/tp_usrreq.c,v $
  *
  * $Header: tp_usrreq.c,v 5.4 88/11/18 17:29:18 nhall Exp $
  * $Source: /usr/argo/sys/netiso/RCS/tp_usrreq.c,v $
- *     @(#)tp_usrreq.c 7.9 (Berkeley) %G%
  *
  * tp_usrreq(), the fellow that gets called from most of the socket code.
  * Pretty straighforward.
  *
  * tp_usrreq(), the fellow that gets called from most of the socket code.
  * Pretty straighforward.
@@ -38,19 +46,15 @@ SOFTWARE.
  * tp_rcvoob() and tp_sendoob() are contained here and called by tp_usrreq().
  */
 
  * tp_rcvoob() and tp_sendoob() are contained here and called by tp_usrreq().
  */
 
-#ifndef lint
-static char *rcsid = "$Header: tp_usrreq.c,v 5.4 88/11/18 17:29:18 nhall Exp $";
-#endif lint
-
 #include "param.h"
 #include "systm.h"
 #include "param.h"
 #include "systm.h"
-#include "user.h"
 #include "mbuf.h"
 #include "socket.h"
 #include "socketvar.h"
 #include "domain.h"
 #include "protosw.h"
 #include "errno.h"
 #include "mbuf.h"
 #include "socket.h"
 #include "socketvar.h"
 #include "domain.h"
 #include "protosw.h"
 #include "errno.h"
+#include "time.h"
 
 #include "tp_param.h"
 #include "tp_timer.h"
 
 #include "tp_param.h"
 #include "tp_timer.h"
@@ -64,9 +68,10 @@ static char *rcsid = "$Header: tp_usrreq.c,v 5.4 88/11/18 17:29:18 nhall Exp $";
 #include "iso.h"
 #include "iso_errno.h"
 
 #include "iso.h"
 #include "iso_errno.h"
 
-int tp_attach(), tp_driver();
+int tp_attach(), tp_driver(), tp_pcbbind();
 int TNew;
 int TPNagle1, TPNagle2;
 int TNew;
 int TPNagle1, TPNagle2;
+struct tp_pcb *tp_listeners, *tp_intercepts;
 
 #ifdef ARGO_DEBUG
 /*
 
 #ifdef ARGO_DEBUG
 /*
@@ -84,12 +89,12 @@ dump_mbuf(n, str)
 
        printf("dump %s\n", str);
 
 
        printf("dump %s\n", str);
 
-       ifn == MNULL)  {
+       if (n == MNULL)  {
                printf("EMPTY:\n");
                return;
        }
                
                printf("EMPTY:\n");
                return;
        }
                
-       for(;n;) {
+       while (n) {
                nextrecord = n->m_act;
                printf("RECORD:\n");
                while (n) {
                nextrecord = n->m_act;
                printf("RECORD:\n");
                while (n) {
@@ -101,15 +106,15 @@ dump_mbuf(n, str)
                                register int i;
 
                                printf("data: ");
                                register int i;
 
                                printf("data: ");
-                               for(i=0; i < n->m_len; i++ ) {
-                                       if(i%8 == 0)
+                               for (i = 0; i < n->m_len; i++) {
+                                       if (i%8 == 0)
                                                printf("\n");
                                        printf("0x%x ", *(p+i));
                                }
                                printf("\n");
                        }
 #endif notdef
                                                printf("\n");
                                        printf("0x%x ", *(p+i));
                                }
                                printf("\n");
                        }
 #endif notdef
-                       if( n->m_next == n ) {
+                       if (n->m_next == n) {
                                printf("LOOP!\n");
                                return;
                        }
                                printf("LOOP!\n");
                                return;
                        }
@@ -155,7 +160,7 @@ tp_rcvoob(tpcb, so, m, outflags, inflags)
        ENDDEBUG
 
        /* if you use soreceive */
        ENDDEBUG
 
        /* if you use soreceive */
-       if (m==MNULL)
+       if (m == MNULL)
                return ENOBUFS;
 
 restart:
                return ENOBUFS;
 
 restart:
@@ -183,7 +188,6 @@ restart:
                        break;
 
        if (n == 0) {
                        break;
 
        if (n == 0) {
-               ASSERT( (tpcb->tp_flags & TPF_DISC_DATA_IN)  == 0 );
                IFDEBUG(D_XPD)
                        printf("RCVOOB: empty queue!\n");
                ENDDEBUG
                IFDEBUG(D_XPD)
                        printf("RCVOOB: empty queue!\n");
                ENDDEBUG
@@ -197,7 +201,7 @@ restart:
        m->m_len = 0;
 
        /* Assuming at most one xpd tpdu is in the buffer at once */
        m->m_len = 0;
 
        /* Assuming at most one xpd tpdu is in the buffer at once */
-       while ( n != MNULL ) {
+       while (n != MNULL) {
                m->m_len += n->m_len;
                bcopy(mtod(n, caddr_t), mtod(m, caddr_t), (unsigned)n->m_len);
                m->m_data += n->m_len; /* so mtod() in bcopy() above gives right addr */
                m->m_len += n->m_len;
                bcopy(mtod(n, caddr_t), mtod(m, caddr_t), (unsigned)n->m_len);
                m->m_data += n->m_len; /* so mtod() in bcopy() above gives right addr */
@@ -212,7 +216,7 @@ restart:
                dump_mbuf(sb->sb_mb, "RCVOOB: Xrcv socketbuf");
        ENDDEBUG
 
                dump_mbuf(sb->sb_mb, "RCVOOB: Xrcv socketbuf");
        ENDDEBUG
 
-       if( (inflags & MSG_PEEK) == 0 ) {
+       if ((inflags & MSG_PEEK) == 0) {
                n = *nn;
                *nn = n->m_act;
                sb->sb_cc -= m->m_len;
                n = *nn;
                *nn = n->m_act;
                sb->sb_cc -= m->m_len;
@@ -223,7 +227,7 @@ release:
 
        IFTRACE(D_XPD)
                tptraceTPCB(TPPTmisc, "PRU_RCVOOB @ release sb_cc m_len",
 
        IFTRACE(D_XPD)
                tptraceTPCB(TPPTmisc, "PRU_RCVOOB @ release sb_cc m_len",
-                       tpcb->tp_Xrcv.sb_cc, m->m_len,0,0 );
+                       tpcb->tp_Xrcv.sb_cc, m->m_len, 0, 0);
        ENDTRACE
        if (error == 0)
                error = DoEvent(T_USR_Xrcvd); 
        ENDTRACE
        if (error == 0)
                error = DoEvent(T_USR_Xrcvd); 
@@ -266,7 +270,7 @@ tp_sendoob(tpcb, so, xdata, outflags)
 
        IFDEBUG(D_XPD)
                printf("tp_sendoob:");
 
        IFDEBUG(D_XPD)
                printf("tp_sendoob:");
-               if(xdata)
+               if (xdata)
                        printf("xdata len 0x%x\n", xdata->m_len);
        ENDDEBUG
        /* DO NOT LOCK the Xsnd buffer!!!! You can have at MOST one 
                        printf("xdata len 0x%x\n", xdata->m_len);
        ENDDEBUG
        /* DO NOT LOCK the Xsnd buffer!!!! You can have at MOST one 
@@ -298,7 +302,7 @@ tp_sendoob(tpcb, so, xdata, outflags)
        }
        IFDEBUG(D_XPD)
                printf("tp_sendoob 1:");
        }
        IFDEBUG(D_XPD)
                printf("tp_sendoob 1:");
-               if(xdata)
+               if (xdata)
                        printf("xdata len 0x%x\n", xdata->m_len);
        ENDDEBUG
        xmark = xdata; /* temporary use of variable xmark */
                        printf("xdata len 0x%x\n", xdata->m_len);
        ENDDEBUG
        xmark = xdata; /* temporary use of variable xmark */
@@ -311,7 +315,7 @@ tp_sendoob(tpcb, so, xdata, outflags)
        }
        IFDEBUG(D_XPD)
                printf("tp_sendoob 2:");
        }
        IFDEBUG(D_XPD)
                printf("tp_sendoob 2:");
-               if(xdata)
+               if (xdata)
                        printf("xdata len 0x%x\n", len);
        ENDDEBUG
 
                        printf("xdata len 0x%x\n", len);
        ENDDEBUG
 
@@ -357,7 +361,7 @@ tp_usrreq(so, req, m, nam, controlp)
 
        IFDEBUG(D_REQUEST)
                printf("usrreq(0x%x,%d,0x%x,0x%x,0x%x)\n",so,req,m,nam,outflags);
 
        IFDEBUG(D_REQUEST)
                printf("usrreq(0x%x,%d,0x%x,0x%x,0x%x)\n",so,req,m,nam,outflags);
-               if(so->so_error)
+               if (so->so_error)
                        printf("WARNING!!! so->so_error is 0x%x\n", so->so_error);
        ENDDEBUG
        IFTRACE(D_REQUEST)
                        printf("WARNING!!! so->so_error is 0x%x\n", so->so_error);
        ENDDEBUG
        IFTRACE(D_REQUEST)
@@ -378,18 +382,15 @@ tp_usrreq(so, req, m, nam, controlp)
        case PRU_ATTACH:
                if (tpcb) {
                        error = EISCONN;
        case PRU_ATTACH:
                if (tpcb) {
                        error = EISCONN;
-                       break;
-               }
-               if( error = tp_attach(so, so->so_proto->pr_domain->dom_family ) )
-                       break;
-               tpcb = sototpcb(so);
+               } else if ((error = tp_attach(so, (int)nam)) == 0)
+                       tpcb = sototpcb(so);
                break;
 
        case PRU_ABORT:         /* called from close() */
                /* called for each incoming connect queued on the 
                 *      parent (accepting) socket 
                 */
                break;
 
        case PRU_ABORT:         /* called from close() */
                /* called for each incoming connect queued on the 
                 *      parent (accepting) socket 
                 */
-               if( tpcb->tp_state == TP_OPEN ) {
+               if (tpcb->tp_state == TP_OPEN || tpcb->tp_state == TP_CONFIRMING) {
                        E.ATTR(T_DISC_req).e_reason = E_TP_NO_SESSION;
                        error = DoEvent(T_DISC_req); /* pretend it was a close() */
                        break;
                        E.ATTR(T_DISC_req).e_reason = E_TP_NO_SESSION;
                        error = DoEvent(T_DISC_req); /* pretend it was a close() */
                        break;
@@ -397,6 +398,20 @@ tp_usrreq(so, req, m, nam, controlp)
 
        case PRU_DETACH:        /* called from close() */
                /* called only after disconnect was called */
 
        case PRU_DETACH:        /* called from close() */
                /* called only after disconnect was called */
+               if (tpcb->tp_state == TP_LISTENING) {
+                       register struct tp_pcb **tt;
+                       for (tt = &tp_listeners; *tt; tt = &((*tt)->tp_nextlisten))
+                               if (*tt == tpcb)
+                                       break;
+                       if (*tt)
+                               *tt = tpcb->tp_nextlisten;
+                       else
+                               printf("tp_usrreq - detach: should panic\n");
+               }
+               if (tpcb->tp_next) {
+                       remque(tpcb);
+                       tpcb->tp_next = tpcb->tp_prev = 0;
+               }
                error = DoEvent(T_DETACH);
                if (tpcb->tp_state == TP_CLOSED) {
                        free((caddr_t)tpcb, M_PCB);
                error = DoEvent(T_DETACH);
                if (tpcb->tp_state == TP_CLOSED) {
                        free((caddr_t)tpcb, M_PCB);
@@ -412,25 +427,24 @@ tp_usrreq(so, req, m, nam, controlp)
                break;
 
        case PRU_BIND:
                break;
 
        case PRU_BIND:
-               error =  (tpcb->tp_nlproto->nlp_pcbbind)( so->so_pcb, nam );
-               if (error == 0) {
-                       (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_lsuffixlen,
-                               tpcb->tp_lsuffix, TP_LOCAL );
-               }
+               error =  tp_pcbbind(tpcb, nam);
                break;
 
        case PRU_LISTEN:
                break;
 
        case PRU_LISTEN:
-               if( tpcb->tp_lsuffixlen ==  0) {
-                       if( error = (tpcb->tp_nlproto->nlp_pcbbind)(so->so_pcb, MNULL) )
-                               break;
-                       (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_lsuffixlen,
-                               tpcb->tp_lsuffix, TP_LOCAL );
+               if (tpcb->tp_state != TP_CLOSED || tpcb->tp_lsuffixlen == 0 ||
+                               tpcb->tp_next == 0)
+                       error = EINVAL;
+               else {
+                       register struct tp_pcb **tt;
+                       remque(tpcb);
+                       tpcb->tp_next = tpcb->tp_prev = tpcb;
+                       for (tt = &tp_listeners; *tt; tt = &((*tt)->tp_nextlisten))
+                               if ((*tt)->tp_lsuffixlen)
+                                       break;
+                       tpcb->tp_nextlisten = *tt;
+                       *tt = tpcb;
+                       error = DoEvent(T_LISTEN_req);
                }
                }
-               IFDEBUG(D_TPISO)
-                       if(tpcb->tp_state != TP_CLOSED)
-                               printf("LISTEN ERROR: state 0x%x\n", tpcb->tp_state);
-               ENDDEBUG
-               error = DoEvent(T_LISTEN_req);
                break;
 
        case PRU_CONNECT2:
                break;
 
        case PRU_CONNECT2:
@@ -449,42 +463,39 @@ tp_usrreq(so, req, m, nam, controlp)
                        tpcb->tp_sock, *SHORT_LSUFXP(tpcb), tpcb->tp_lsuffixlen,
                                tpcb->tp_class);
                ENDDEBUG
                        tpcb->tp_sock, *SHORT_LSUFXP(tpcb), tpcb->tp_lsuffixlen,
                                tpcb->tp_class);
                ENDDEBUG
-               if( tpcb->tp_lsuffixlen ==  0) {
-                       if( error = (tpcb->tp_nlproto->nlp_pcbbind)(so->so_pcb, MNULL) ) {
+               if (tpcb->tp_lsuffixlen == 0) {
+                       if (error = tp_pcbbind(tpcb, MNULL)) {
                                IFDEBUG(D_CONN)
                                IFDEBUG(D_CONN)
-                                       printf("pcbbind returns error 0x%x\n", error );
+                                       printf("pcbbind returns error 0x%x\n", error);
                                ENDDEBUG
                                break;
                        }
                                ENDDEBUG
                                break;
                        }
-                       (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_lsuffixlen,
-                               tpcb->tp_lsuffix, TP_LOCAL );
                }
                }
-
                IFDEBUG(D_CONN)
                        printf("isop 0x%x isop->isop_socket offset 12 :\n", tpcb->tp_npcb);
                IFDEBUG(D_CONN)
                        printf("isop 0x%x isop->isop_socket offset 12 :\n", tpcb->tp_npcb);
-                       dump_buf( tpcb->tp_npcb, 16);
+                       dump_buf(tpcb->tp_npcb, 16);
                ENDDEBUG
                ENDDEBUG
-               if( error = tp_route_to( nam, tpcb, /* channel */0) )
+               if (error = tp_route_to(nam, tpcb, /* channel */0))
                        break;
                IFDEBUG(D_CONN)
                        printf(
                                "PRU_CONNECT after tpcb 0x%x so 0x%x npcb 0x%x flags 0x%x\n", 
                                tpcb, so, tpcb->tp_npcb, tpcb->tp_flags);
                        printf("isop 0x%x isop->isop_socket offset 12 :\n", tpcb->tp_npcb);
                        break;
                IFDEBUG(D_CONN)
                        printf(
                                "PRU_CONNECT after tpcb 0x%x so 0x%x npcb 0x%x flags 0x%x\n", 
                                tpcb, so, tpcb->tp_npcb, tpcb->tp_flags);
                        printf("isop 0x%x isop->isop_socket offset 12 :\n", tpcb->tp_npcb);
-                       dump_buf( tpcb->tp_npcb, 16);
+                       dump_buf(tpcb->tp_npcb, 16);
                ENDDEBUG
                ENDDEBUG
-               iftpcb->tp_fsuffixlen ==  0) {
+               if (tpcb->tp_fsuffixlen ==  0) {
                        /* didn't set peer extended suffix */
                        /* didn't set peer extended suffix */
-                       (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_fsuffixlen,
-                               tpcb->tp_fsuffix, TP_FOREIGN );
+                       (tpcb->tp_nlproto->nlp_getsufx)(tpcb->tp_npcb, &tpcb->tp_fsuffixlen,
+                               tpcb->tp_fsuffix, TP_FOREIGN);
                }
                }
-               (void) (tpcb->tp_nlproto->nlp_mtu)(so, so->so_pcb,
+               (void) (tpcb->tp_nlproto->nlp_mtu)(so, tpcb->tp_npcb,
                                        &tpcb->tp_l_tpdusize, &tpcb->tp_tpdusize, 0);
                                        &tpcb->tp_l_tpdusize, &tpcb->tp_tpdusize, 0);
-               iftpcb->tp_state == TP_CLOSED) {
+               if (tpcb->tp_state == TP_CLOSED) {
                        soisconnecting(so);  
                        error = DoEvent(T_CONN_req);
                } else {
                        soisconnecting(so);  
                        error = DoEvent(T_CONN_req);
                } else {
-                       (tpcb->tp_nlproto->nlp_pcbdisc)(so->so_pcb);
+                       (tpcb->tp_nlproto->nlp_pcbdisc)(tpcb->tp_npcb);
                        error = EISCONN;
                }
                IFPERF(tpcb)
                        error = EISCONN;
                }
                IFPERF(tpcb)
@@ -492,14 +503,14 @@ tp_usrreq(so, req, m, nam, controlp)
                        lsufx = *(u_short *)(tpcb->tp_lsuffix);
                        fsufx = *(u_short *)(tpcb->tp_fsuffix);
 
                        lsufx = *(u_short *)(tpcb->tp_lsuffix);
                        fsufx = *(u_short *)(tpcb->tp_fsuffix);
 
-                       tpmeas( tpcb->tp_lref, 
-                               TPtime_open | (tpcb->tp_xtd_format <<), 
+                       tpmeas(tpcb->tp_lref, 
+                               TPtime_open | (tpcb->tp_xtd_format << 4), 
                                &time, lsufx, fsufx, tpcb->tp_fref);
                ENDPERF
                break;
 
        case PRU_ACCEPT: 
                                &time, lsufx, fsufx, tpcb->tp_fref);
                ENDPERF
                break;
 
        case PRU_ACCEPT: 
-               (tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, nam, TP_FOREIGN);
+               (tpcb->tp_nlproto->nlp_getnetaddr)(tpcb->tp_npcb, nam, TP_FOREIGN);
                IFDEBUG(D_REQUEST)
                        printf("ACCEPT PEERADDDR:");
                        dump_buf(mtod(nam, char *), nam->m_len);
                IFDEBUG(D_REQUEST)
                        printf("ACCEPT PEERADDDR:");
                        dump_buf(mtod(nam, char *), nam->m_len);
@@ -509,7 +520,7 @@ tp_usrreq(so, req, m, nam, controlp)
                        lsufx = *(u_short *)(tpcb->tp_lsuffix);
                        fsufx = *(u_short *)(tpcb->tp_fsuffix);
 
                        lsufx = *(u_short *)(tpcb->tp_lsuffix);
                        fsufx = *(u_short *)(tpcb->tp_fsuffix);
 
-                       tpmeas( tpcb->tp_lref, TPtime_open, 
+                       tpmeas(tpcb->tp_lref, TPtime_open, 
                                &time, lsufx, fsufx, tpcb->tp_fref);
                ENDPERF
                break;
                                &time, lsufx, fsufx, tpcb->tp_fref);
                ENDPERF
                break;
@@ -547,7 +558,7 @@ tp_usrreq(so, req, m, nam, controlp)
                        error = ENOTCONN;
                        break;
                }
                        error = ENOTCONN;
                        break;
                }
-               if( ! tpcb->tp_xpd_service ) {
+               if (! tpcb->tp_xpd_service) {
                        error = EOPNOTSUPP;
                        break;
                }
                        error = EOPNOTSUPP;
                        break;
                }
@@ -563,26 +574,25 @@ tp_usrreq(so, req, m, nam, controlp)
                        if (error)
                                break;
                }
                        if (error)
                                break;
                }
-               if (so->so_state & SS_ISCONFIRMING) {
-                       if (tpcb->tp_state == TP_CONFIRMING)
-                               error = tp_confirm(tpcb);
-                       if (m) {
-                               if (error == 0 && m->m_len != 0)
-                                       error =  ENOTCONN;
-                               m_freem(m);
-                               m = 0;
-                       }
+               if ((so->so_state & SS_ISCONFIRMING) &&
+                   (tpcb->tp_state == TP_CONFIRMING) &&
+                   (error = tp_confirm(tpcb)))
+                           break;
+               if (req == PRU_SENDOOB) {
+                       error = (tpcb->tp_xpd_service == 0) ?
+                                               EOPNOTSUPP : tp_sendoob(tpcb, so, m, outflags);
                        break;
                }
                if (m == 0)
                        break;
                        break;
                }
                if (m == 0)
                        break;
-
-               if (req == PRU_SENDOOB) {
-                       if (tpcb->tp_xpd_service == 0) {
-                               error = EOPNOTSUPP;
-                               break;
-                       }
-                       error = tp_sendoob(tpcb, so, m, outflags);
+               if (m->m_flags & M_EOR) {
+                       eotsdu = 1;
+                       m->m_flags &= ~M_EOR;
+               }
+               if (eotsdu == 0 && m->m_pkthdr.len == 0)
+                       break;
+               if (tpcb->tp_state != TP_AKWAIT && tpcb->tp_state != TP_OPEN) {
+                       error = ENOTCONN;
                        break;
                }
                /*
                        break;
                }
                /*
@@ -596,23 +606,12 @@ tp_usrreq(so, req, m, nam, controlp)
                 * possibly by a whole cluster.
                 */
                {
                 * possibly by a whole cluster.
                 */
                {
-                       register struct mbuf *n = m;
-                       register struct sockbuf *sb = &so->so_snd;
-                       int     maxsize = tpcb->tp_l_tpdusize 
-                                   - tp_headersize(DT_TPDU_type, tpcb)
-                                   - (tpcb->tp_use_checksum?4:0) ;
-                       int totlen = n->m_pkthdr.len;
-                       int     mbufcnt = 0;
-                       struct mbuf *nn;
-
                        /*
                         * Could have eotsdu and no data.(presently MUST have
                         * an mbuf though, even if its length == 0) 
                         */
                        /*
                         * Could have eotsdu and no data.(presently MUST have
                         * an mbuf though, even if its length == 0) 
                         */
-                       if (n->m_flags & M_EOR) {
-                               eotsdu = 1;
-                               n->m_flags &= ~M_EOR;
-                       }
+                       int totlen = m->m_pkthdr.len;
+                       struct sockbuf *sb = &so->so_snd;
                        IFPERF(tpcb)
                           PStat(tpcb, Nb_from_sess) += totlen;
                           tpmeas(tpcb->tp_lref, TPtime_from_session, 0, 0, 
                        IFPERF(tpcb)
                           PStat(tpcb, Nb_from_sess) += totlen;
                           tpmeas(tpcb->tp_lref, TPtime_from_session, 0, 0, 
@@ -625,68 +624,13 @@ tp_usrreq(so, req, m, nam, controlp)
                                dump_mbuf(sb->sb_mb, "so_snd.sb_mb");
                                dump_mbuf(m, "m : to be added");
                        ENDDEBUG
                                dump_mbuf(sb->sb_mb, "so_snd.sb_mb");
                                dump_mbuf(m, "m : to be added");
                        ENDDEBUG
-                       /*
-                        * Pre-packetize the data in the sockbuf
-                        * according to negotiated mtu.  Do it here
-                        * where we can safely wait for mbufs.
-                        *
-                        * This presumes knowledge of sockbuf conventions.
-                        */
-                       if (n = sb->sb_mb)
-                               while (n->m_act)
-                                       n = n->m_act;
-                       if ((nn = n) && n->m_pkthdr.len < maxsize) {
-                               u_int space = maxsize - n->m_pkthdr.len;
-
-                               do {
-                                       if (n->m_flags & M_EOR)
-                                               goto on1;
-                               } while (n->m_next && (n = n->m_next));
-                               if (totlen <= space) {
-                                       TPNagle1++;
-                                       n->m_next = m; 
-                                       nn->m_pkthdr.len += totlen;
-                                       while (n = n->m_next)
-                                               sballoc(sb, n);
-                                       if (eotsdu)
-                                               nn->m_flags |= M_EOR; 
-                                       goto on2; 
-                               } else {
-                                       /*
-                                        * Can't sleep here, because when you wake up
-                                        * packet you want to attach to may be gone!
-                                        */
-                                       if (TNew && (n->m_next = m_copym(m, 0, space, M_NOWAIT))) {
-                                               nn->m_pkthdr.len += space;
-                                               TPNagle2++;
-                                               while (n = n->m_next)
-                                                       sballoc(sb, n);
-                                               m_adj(m, space);
-                                       }
-                               }
-                       }       
-       on1:    mbufcnt++;
-                       for (n = m; n->m_pkthdr.len > maxsize;) {
-                               nn = m_copym(n, 0, maxsize, M_WAIT);
-                               sbappendrecord(sb, nn);
-                               m_adj(n, maxsize);
-                               mbufcnt++;
-                       }
-                       if (eotsdu)
-                               n->m_flags |= M_EOR;
-                       sbappendrecord(sb, n);
-       on2:    
-                       IFTRACE(D_DATA)
-                               tptraceTPCB(TPPTmisc,
-                               "SEND BF: maxsize totlen mbufcnt eotsdu",
-                                       maxsize, totlen, mbufcnt, eotsdu);
-                       ENDTRACE
+                       tp_packetize(tpcb, m, eotsdu);
                        IFDEBUG(D_SYSCALL)
                        IFDEBUG(D_SYSCALL)
-                               printf("PRU_SEND: eot %d after sbappend 0x%x mbufcnt 0x%x\n",
-                                       eotsdu, n, mbufcnt);
+                               printf("PRU_SEND: eot %d after sbappend 0x%x\n", eotsdu, m);
                                dump_mbuf(sb->sb_mb, "so_snd.sb_mb");
                        ENDDEBUG
                                dump_mbuf(sb->sb_mb, "so_snd.sb_mb");
                        ENDDEBUG
-                       error = DoEvent(T_DATA_req); 
+                       if (tpcb->tp_state == TP_OPEN)
+                               error = DoEvent(T_DATA_req); 
                        IFDEBUG(D_SYSCALL)
                                printf("PRU_SEND: after driver error 0x%x \n",error);
                                printf("so_snd 0x%x cc 0t%d mbcnt 0t%d\n",
                        IFDEBUG(D_SYSCALL)
                                printf("PRU_SEND: after driver error 0x%x \n",error);
                                printf("so_snd 0x%x cc 0t%d mbcnt 0t%d\n",
@@ -697,11 +641,11 @@ tp_usrreq(so, req, m, nam, controlp)
                break;
 
        case PRU_SOCKADDR:
                break;
 
        case PRU_SOCKADDR:
-               (tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, nam, TP_LOCAL);
+               (tpcb->tp_nlproto->nlp_getnetaddr)(tpcb->tp_npcb, nam, TP_LOCAL);
                break;
 
        case PRU_PEERADDR:
                break;
 
        case PRU_PEERADDR:
-               (tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, nam, TP_FOREIGN);
+               (tpcb->tp_nlproto->nlp_getnetaddr)(tpcb->tp_npcb, nam, TP_FOREIGN);
                break;
 
        case PRU_CONTROL:
                break;
 
        case PRU_CONTROL:
@@ -771,11 +715,11 @@ tp_snd_control(m, so, data)
        struct socket *so;
        register struct mbuf **data;
 {
        struct socket *so;
        register struct mbuf **data;
 {
-       register struct tp_control_hdr *ch;
+       register struct cmsghdr *ch;
        int error = 0;
 
        if (m && m->m_len) {
        int error = 0;
 
        if (m && m->m_len) {
-               ch = mtod(m, struct tp_control_hdr *);
+               ch = mtod(m, struct cmsghdr *);
                m->m_len -= sizeof (*ch);
                m->m_data += sizeof (*ch);
                error = tp_ctloutput(PRCO_SETOPT,
                m->m_len -= sizeof (*ch);
                m->m_data += sizeof (*ch);
                error = tp_ctloutput(PRCO_SETOPT,