checkpoint version with mbuf changes before var sockaddrs
authorKeith Sklower <sklower@ucbvax.Berkeley.EDU>
Thu, 13 Oct 1988 06:56:35 +0000 (22:56 -0800)
committerKeith Sklower <sklower@ucbvax.Berkeley.EDU>
Thu, 13 Oct 1988 06:56:35 +0000 (22:56 -0800)
SCCS-vsn: sys/netns/idp_usrreq.c 7.5
SCCS-vsn: sys/netns/spp_usrreq.c 7.9
SCCS-vsn: sys/netns/ns_input.c 7.5
SCCS-vsn: sys/netns/ns_output.c 7.4

usr/src/sys/netns/idp_usrreq.c
usr/src/sys/netns/ns_input.c
usr/src/sys/netns/ns_output.c
usr/src/sys/netns/spp_usrreq.c

index 881d15d..b47196a 100644 (file)
@@ -20,6 +20,7 @@
 #include "param.h"
 #include "dir.h"
 #include "user.h"
 #include "param.h"
 #include "dir.h"
 #include "user.h"
+#include "malloc.h"
 #include "mbuf.h"
 #include "protosw.h"
 #include "socket.h"
 #include "mbuf.h"
 #include "protosw.h"
 #include "socket.h"
@@ -46,12 +47,12 @@ struct      sockaddr_ns idp_ns = { AF_NS };
 /*
  *  This may also be called for raw listeners.
  */
 /*
  *  This may also be called for raw listeners.
  */
-idp_input(m, nsp, ifp)
+idp_input(m, nsp)
        struct mbuf *m;
        register struct nspcb *nsp;
        struct mbuf *m;
        register struct nspcb *nsp;
-       struct ifnet *ifp;
 {
        register struct idp *idp = mtod(m, struct idp *);
 {
        register struct idp *idp = mtod(m, struct idp *);
+       struct ifnet *ifp = m->m_pkthdr.rcvif;
 
        if (nsp==0)
                panic("No nspcb");
 
        if (nsp==0)
                panic("No nspcb");
@@ -74,7 +75,8 @@ idp_input(m, nsp, ifp)
        nsp->nsp_rpt = idp->idp_pt;
        if ( ! (nsp->nsp_flags & NSP_RAWIN) ) {
                m->m_len -= sizeof (struct idp);
        nsp->nsp_rpt = idp->idp_pt;
        if ( ! (nsp->nsp_flags & NSP_RAWIN) ) {
                m->m_len -= sizeof (struct idp);
-               m->m_off += sizeof (struct idp);
+               m->m_pkthdr.len -= sizeof (struct idp);
+               m->m_data += sizeof (struct idp);
        }
        if (sbappendaddr(&nsp->nsp_socket->so_rcv, (struct sockaddr *)&idp_ns,
            m, (struct mbuf *)0) == 0)
        }
        if (sbappendaddr(&nsp->nsp_socket->so_rcv, (struct sockaddr *)&idp_ns,
            m, (struct mbuf *)0) == 0)
@@ -144,7 +146,8 @@ idp_output(nsp, m0)
        
        if (len & 1) {
                m = mprev;
        
        if (len & 1) {
                m = mprev;
-               if (m->m_len + m->m_off < MMAXOFF) {
+               if ((m->m_flags & M_EXT) == 0 &&
+                       (m->m_len + m->m_data < &m->m_dat[MLEN])) {
                        m->m_len++;
                } else {
                        struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA);
                        m->m_len++;
                } else {
                        struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA);
@@ -154,30 +157,23 @@ idp_output(nsp, m0)
                                return (ENOBUFS);
                        }
                        m1->m_len = 1;
                                return (ENOBUFS);
                        }
                        m1->m_len = 1;
-                       m1->m_off = MMAXOFF - 1;
                        * mtod(m1, char *) = 0;
                        m->m_next = m1;
                }
                        * mtod(m1, char *) = 0;
                        m->m_next = m1;
                }
+               m0->m_pkthdr.len++;
        }
 
        /*
         * Fill in mbuf with extended IDP header
         * and addresses and length put into network format.
         */
        }
 
        /*
         * Fill in mbuf with extended IDP header
         * and addresses and length put into network format.
         */
+       m = m0;
        if (nsp->nsp_flags & NSP_RAWOUT) {
        if (nsp->nsp_flags & NSP_RAWOUT) {
-               m = m0;
                idp = mtod(m, struct idp *);
        } else {
                idp = mtod(m, struct idp *);
        } else {
-               m = m_get(M_DONTWAIT, MT_HEADER);
-               if (m == 0) {
-                       m_freem(m0);
+               M_PREPEND(m, sizeof (struct idp), M_DONTWAIT);
+               if (m == 0)
                        return (ENOBUFS);
                        return (ENOBUFS);
-               }
-               m->m_off = MMAXOFF - sizeof (struct idp) - 2;
-                               /* adjust to start on longword bdry
-                                  for NSIP on gould */
-               m->m_len = sizeof (struct idp);
-               m->m_next = m0;
                idp = mtod(m, struct idp *);
                idp->idp_tc = 0;
                idp->idp_pt = nsp->nsp_dpt;
                idp = mtod(m, struct idp *);
                idp->idp_tc = 0;
                idp->idp_pt = nsp->nsp_dpt;
@@ -284,13 +280,11 @@ idp_ctloutput(req, so, level, name, value)
                        mask = NSP_RAWOUT;
                get_flags:
                        m->m_len = sizeof(short);
                        mask = NSP_RAWOUT;
                get_flags:
                        m->m_len = sizeof(short);
-                       m->m_off = MMAXOFF - sizeof(short);
                        *mtod(m, short *) = nsp->nsp_flags & mask;
                        break;
 
                case SO_DEFAULT_HEADERS:
                        m->m_len = sizeof(struct idp);
                        *mtod(m, short *) = nsp->nsp_flags & mask;
                        break;
 
                case SO_DEFAULT_HEADERS:
                        m->m_len = sizeof(struct idp);
-                       m->m_off = MMAXOFF - sizeof(struct idp);
                        {
                                register struct idp *idp = mtod(m, struct idp *);
                                idp->idp_len = 0;
                        {
                                register struct idp *idp = mtod(m, struct idp *);
                                idp->idp_len = 0;
@@ -304,7 +298,6 @@ idp_ctloutput(req, so, level, name, value)
 
                case SO_SEQNO:
                        m->m_len = sizeof(long);
 
                case SO_SEQNO:
                        m->m_len = sizeof(long);
-                       m->m_off = MMAXOFF - sizeof(long);
                        *mtod(m, long *) = ns_pexseq++;
                        break;
 
                        *mtod(m, long *) = ns_pexseq++;
                        break;
 
index f6a30b9..040280c 100644 (file)
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)ns_input.c  7.4 (Berkeley) %G%
+ *     @(#)ns_input.c  7.5 (Berkeley) %G%
  */
 
 #include "param.h"
 #include "systm.h"
  */
 
 #include "param.h"
 #include "systm.h"
+#include "malloc.h"
 #include "mbuf.h"
 #include "domain.h"
 #include "protosw.h"
 #include "mbuf.h"
 #include "domain.h"
 #include "protosw.h"
@@ -93,12 +94,12 @@ next:
         * in first mbuf.
         */
        s = splimp();
         * in first mbuf.
         */
        s = splimp();
-       IF_DEQUEUEIF(&nsintrq, m, ifp);
+       IF_DEQUEUE(&nsintrq, m);
        splx(s);
        nsintr_getpck++;
        if (m == 0)
                return;
        splx(s);
        nsintr_getpck++;
        if (m == 0)
                return;
-       if ((m->m_off > MMAXOFF || m->m_len < sizeof (struct idp)) &&
+       if ((m->m_flags & M_EXT || m->m_len < sizeof (struct idp)) &&
            (m = m_pullup(m, sizeof (struct idp))) == 0) {
                idpstat.idps_toosmall++;
                goto next;
            (m = m_pullup(m, sizeof (struct idp))) == 0) {
                idpstat.idps_toosmall++;
                goto next;
@@ -109,7 +110,7 @@ next:
         */
        for (nsp = nsrawpcb.nsp_next; nsp != &nsrawpcb; nsp = nsp->nsp_next) {
                struct mbuf *m1 = m_copy(m, 0, (int)M_COPYALL);
         */
        for (nsp = nsrawpcb.nsp_next; nsp != &nsrawpcb; nsp = nsp->nsp_next) {
                struct mbuf *m1 = m_copy(m, 0, (int)M_COPYALL);
-               if (m1) idp_input(m1, nsp, ifp);
+               if (m1) idp_input(m1, nsp);
        }
 
        idp = mtod(m, struct idp *);
        }
 
        idp = mtod(m, struct idp *);
@@ -125,29 +126,20 @@ next:
         * Trim mbufs if longer than we expect.
         * Drop packet if shorter than we expect.
         */
         * Trim mbufs if longer than we expect.
         * Drop packet if shorter than we expect.
         */
-       i = -len;
-       m0 = m;
-       for (;;) {
-               i += m->m_len;
-               if (m->m_next == 0)
-                       break;
-               m = m->m_next;
+       if (m->m_pkthdr.len < len) {
+               idpstat.idps_tooshort++;
+               goto bad;
        }
        }
-       if (i != 0) {
-               if (i < 0) {
-                       idpstat.idps_tooshort++;
-                       m = m0;
-                       goto bad;
-               }
-               if (i <= m->m_len)
-                       m->m_len -= i;
-               else
-                       m_adj(m0, -i);
+       if (m->m_pkthdr.len > len) {
+               if (m->m_len == m->m_pkthdr.len) {
+                       m->m_len = len;
+                       m->m_pkthdr.len = len;
+               } else
+                       m_adj(m, len - m->m_pkthdr.len);
        }
        }
-       m = m0;
        if (idpcksum && ((i = idp->idp_sum)!=0xffff)) {
                idp->idp_sum = 0;
        if (idpcksum && ((i = idp->idp_sum)!=0xffff)) {
                idp->idp_sum = 0;
-               if (i != (idp->idp_sum = ns_cksum(m,len))) {
+               if (i != (idp->idp_sum = ns_cksum(m, len))) {
                        idpstat.idps_badsum++;
                        idp->idp_sum = i;
                        if (ns_hosteqnh(ns_thishost, idp->idp_dna.x_host))
                        idpstat.idps_badsum++;
                        idp->idp_sum = i;
                        if (ns_hosteqnh(ns_thishost, idp->idp_dna.x_host))
@@ -177,7 +169,7 @@ next:
                         * Suggestion of Bill Nesheim, Cornell U.
                         */
                        if (idp->idp_tc < NS_MAXHOPS) {
                         * Suggestion of Bill Nesheim, Cornell U.
                         */
                        if (idp->idp_tc < NS_MAXHOPS) {
-                               idp_forward(idp);
+                               idp_forward(m);
                                goto next;
                        }
                }
                                goto next;
                        }
                }
@@ -185,7 +177,7 @@ next:
         * Is this our packet? If not, forward.
         */
        } else if (!ns_hosteqnh(ns_thishost,idp->idp_dna.x_host)) {
         * Is this our packet? If not, forward.
         */
        } else if (!ns_hosteqnh(ns_thishost,idp->idp_dna.x_host)) {
-               idp_forward(idp);
+               idp_forward(m);
                goto next;
        }
        /*
                goto next;
        }
        /*
@@ -198,20 +190,20 @@ next:
        nsintr_swtch++;
        if (nsp) {
                if (oddpacketp) {
        nsintr_swtch++;
        if (nsp) {
                if (oddpacketp) {
-                       m_adj(m0, -1);
+                       m_adj(m, -1);
                }
                if ((nsp->nsp_flags & NSP_ALL_PACKETS)==0)
                        switch (idp->idp_pt) {
 
                            case NSPROTO_SPP:
                }
                if ((nsp->nsp_flags & NSP_ALL_PACKETS)==0)
                        switch (idp->idp_pt) {
 
                            case NSPROTO_SPP:
-                                   spp_input(m, nsp, ifp);
+                                   spp_input(m, nsp);
                                    goto next;
 
                            case NSPROTO_ERROR:
                                    ns_err_input(m);
                                    goto next;
                        }
                                    goto next;
 
                            case NSPROTO_ERROR:
                                    ns_err_input(m);
                                    goto next;
                        }
-               idp_input(m, nsp, ifp);
+               idp_input(m, nsp);
        } else {
                ns_error(m, NS_ERR_NOSOCK, 0);
        }
        } else {
                ns_error(m, NS_ERR_NOSOCK, 0);
        }
@@ -291,9 +283,10 @@ int        idpforwarding = 1;
 struct route idp_droute;
 struct route idp_sroute;
 
 struct route idp_droute;
 struct route idp_sroute;
 
-idp_forward(idp)
-       register struct idp *idp;
+idp_forward(m)
+struct mbuf *m;
 {
 {
+       register struct idp *idp = mtod(m, struct idp *);
        register int error, type, code;
        struct mbuf *mcopy = NULL;
        int agedelta = 1;
        register int error, type, code;
        struct mbuf *mcopy = NULL;
        int agedelta = 1;
@@ -322,7 +315,7 @@ idp_forward(idp)
         * Save at most 42 bytes of the packet in case
         * we need to generate an NS error message to the src.
         */
         * Save at most 42 bytes of the packet in case
         * we need to generate an NS error message to the src.
         */
-       mcopy = m_copy(dtom(idp), 0, imin((int)ntohs(idp->idp_len), 42));
+       mcopy = m_copy(m, 0, imin((int)ntohs(idp->idp_len), 42));
 
        if ((ok_there = idp_do_route(&idp->idp_dna,&idp_droute))==0) {
                type = NS_ERR_UNREACH_HOST, code = 0;
 
        if ((ok_there = idp_do_route(&idp->idp_dna,&idp_droute))==0) {
                type = NS_ERR_UNREACH_HOST, code = 0;
@@ -345,7 +338,7 @@ idp_forward(idp)
                }
                if ((ok_back = idp_do_route(&idp->idp_sna,&idp_sroute))==0) {
                        /* error = ENETUNREACH; He'll never get it! */
                }
                if ((ok_back = idp_do_route(&idp->idp_sna,&idp_sroute))==0) {
                        /* error = ENETUNREACH; He'll never get it! */
-                       m_freem(dtom(idp));
+                       m_freem(m);
                        goto cleanup;
                }
                if (idp_droute.ro_rt &&
                        goto cleanup;
                }
                if (idp_droute.ro_rt &&
@@ -373,7 +366,7 @@ idp_forward(idp)
                x.l = x.s[0] + x.s[1];
                if (x.l==0xffff) idp->idp_sum = 0; else idp->idp_sum = x.l;
        }
                x.l = x.s[0] + x.s[1];
                if (x.l==0xffff) idp->idp_sum = 0; else idp->idp_sum = x.l;
        }
-       if ((error = ns_output(dtom(idp), &idp_droute, flags)) && 
+       if ((error = ns_output(m, &idp_droute, flags)) && 
            (mcopy!=NULL)) {
                idp = mtod(mcopy, struct idp *);
                type = NS_ERR_UNSPEC_T, code = 0;
            (mcopy!=NULL)) {
                idp = mtod(mcopy, struct idp *);
                type = NS_ERR_UNSPEC_T, code = 0;
@@ -398,7 +391,7 @@ idp_forward(idp)
                }
                mcopy = NULL;
        senderror:
                }
                mcopy = NULL;
        senderror:
-               ns_error(dtom(idp), type, code);
+               ns_error(m, type, code);
        }
 cleanup:
        if (ok_there)
        }
 cleanup:
        if (ok_there)
@@ -450,31 +443,25 @@ struct ifnet *ifp;
        for (nsp = nsrawpcb.nsp_next; nsp != &nsrawpcb; nsp = nsp->nsp_next) {
                struct mbuf *m0 = m_copy(m, 0, (int)M_COPYALL);
                if (m0) {
        for (nsp = nsrawpcb.nsp_next; nsp != &nsrawpcb; nsp = nsp->nsp_next) {
                struct mbuf *m0 = m_copy(m, 0, (int)M_COPYALL);
                if (m0) {
-                       struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA);
-
-                       if(m1 == NULL)
-                               m_freem(m0);
-                       else {
-                               register struct idp *idp;
-
-                               m1->m_off = MMINOFF;
-                               m1->m_len = sizeof (*idp);
-                               m1->m_next = m0;
-                               idp = mtod(m1, struct idp *);
-                               idp->idp_sna.x_net = ns_zeronet;
-                               idp->idp_sna.x_host = ns_thishost;
-                               if (ifp && (ifp->if_flags & IFF_POINTOPOINT))
-                                   for(ia = ifp->if_addrlist; ia;
-                                                       ia = ia->ifa_next) {
-                                       if (ia->ifa_addr.sa_family==AF_NS) {
-                                           idp->idp_sna = 
-                                               satons_addr(ia->ifa_dstaddr);
-                                           break;
-                                       }
-                                   }
-                               idp->idp_len = 0xffff;
-                               idp_input(m1, nsp, ifp);
-                       }
+                       register struct idp *idp;
+
+                       M_PREPEND(m0, sizeof (*idp), M_DONTWAIT);
+                       if (m0 == NULL)
+                               continue;
+                       idp = mtod(m0, struct idp *);
+                       idp->idp_sna.x_net = ns_zeronet;
+                       idp->idp_sna.x_host = ns_thishost;
+                       if (ifp && (ifp->if_flags & IFF_POINTOPOINT))
+                           for(ia = ifp->if_addrlist; ia;
+                                               ia = ia->ifa_next) {
+                               if (ia->ifa_addr.sa_family==AF_NS) {
+                                   idp->idp_sna = 
+                                       satons_addr(ia->ifa_dstaddr);
+                                   break;
+                               }
+                           }
+                       idp->idp_len = ntohl(m0->m_pkthdr.len);
+                       idp_input(m0, nsp);
                }
        }
 }
                }
        }
 }
index 4942aec..bedb993 100644 (file)
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)ns_output.c 7.3 (Berkeley) %G%
+ *     @(#)ns_output.c 7.4 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
+#include "malloc.h"
 #include "mbuf.h"
 #include "errno.h"
 #include "socket.h"
 #include "mbuf.h"
 #include "errno.h"
 #include "socket.h"
index dcfc563..502eac6 100644 (file)
@@ -21,6 +21,7 @@
 #include "systm.h"
 #include "dir.h"
 #include "user.h"
 #include "systm.h"
 #include "dir.h"
 #include "user.h"
+#include "malloc.h"
 #include "mbuf.h"
 #include "protosw.h"
 #include "socket.h"
 #include "mbuf.h"
 #include "protosw.h"
 #include "socket.h"
@@ -55,12 +56,12 @@ int traceallspps = 0;
 extern int sppconsdebug;
 int spp_hardnosed;
 int spp_use_delack = 0;
 extern int sppconsdebug;
 int spp_hardnosed;
 int spp_use_delack = 0;
+u_short spp_newchecks[50];
 
 /*ARGSUSED*/
 
 /*ARGSUSED*/
-spp_input(m, nsp, ifp)
+spp_input(m, nsp)
        register struct mbuf *m;
        register struct nspcb *nsp;
        register struct mbuf *m;
        register struct nspcb *nsp;
-       struct ifnet *ifp;
 {
        register struct sppcb *cb;
        register struct spidp *si = mtod(m, struct spidp *);
 {
        register struct sppcb *cb;
        register struct spidp *si = mtod(m, struct spidp *);
@@ -118,6 +119,7 @@ spp_input(m, nsp, ifp)
                cb = nstosppcb(nsp);
                cb->s_mtu = ocb->s_mtu;         /* preserve sockopts */
                cb->s_flags = ocb->s_flags;     /* preserve sockopts */
                cb = nstosppcb(nsp);
                cb->s_mtu = ocb->s_mtu;         /* preserve sockopts */
                cb->s_flags = ocb->s_flags;     /* preserve sockopts */
+               cb->s_flags2 = ocb->s_flags2;   /* preserve sockopts */
                cb->s_state = TCPS_LISTEN;
        }
 
                cb->s_state = TCPS_LISTEN;
        }
 
@@ -232,7 +234,8 @@ spp_input(m, nsp, ifp)
                spp_trace(SA_INPUT, (u_char)ostate, cb, &spp_savesi, 0);
 
        m->m_len -= sizeof (struct idp);
                spp_trace(SA_INPUT, (u_char)ostate, cb, &spp_savesi, 0);
 
        m->m_len -= sizeof (struct idp);
-       m->m_off += sizeof (struct idp);
+       m->m_pkthdr.len -= sizeof (struct idp);
+       m->m_data += sizeof (struct idp);
 
        if (spp_reass(cb, si)) {
                (void) m_freem(m);
 
        if (spp_reass(cb, si)) {
                (void) m_freem(m);
@@ -380,8 +383,8 @@ register struct spidp *si;
         */
        incr = CUNIT;
        if (cb->s_cwnd > cb->s_ssthresh)
         */
        incr = CUNIT;
        if (cb->s_cwnd > cb->s_ssthresh)
-               incr = MAX(incr * incr / cb->s_cwnd, 1);
-       cb->s_cwnd = MIN(cb->s_cwnd + incr, cb->s_cwmx);
+               incr = max(incr * incr / cb->s_cwnd, 1);
+       cb->s_cwnd = min(cb->s_cwnd + incr, cb->s_cwmx);
        /*
         * Trim Acked data from output queue.
         */
        /*
         * Trim Acked data from output queue.
         */
@@ -391,8 +394,7 @@ register struct spidp *si;
                else
                        break;
        }
                else
                        break;
        }
-       if ((so->so_snd.sb_flags & SB_WAIT) || so->so_snd.sb_sel)
-                sowwakeup(so);
+       sowwakeup(so);
        cb->s_rack = si->si_ack;
 update_window:
        if (SSEQ_LT(cb->s_snxt, cb->s_rack))
        cb->s_rack = si->si_ack;
 update_window:
        if (SSEQ_LT(cb->s_snxt, cb->s_rack))
@@ -503,12 +505,51 @@ present:
                        remque(q->si_next);
                        wakeup = 1;
                        sppstat.spps_rcvpack++;
                        remque(q->si_next);
                        wakeup = 1;
                        sppstat.spps_rcvpack++;
+#ifdef SF_NEWCALL
+                       if (cb->s_flags2 & SF_NEWCALL) {
+                               struct sphdr *sp = mtod(m, struct sphdr *);
+                               u_char dt = sp->sp_dt;
+                               spp_newchecks[4]++;
+                               if (dt != cb->s_rhdr.sp_dt) {
+                                       struct mbuf *mm =
+                                          m_getclr(M_DONTWAIT, MT_CONTROL);
+                                       spp_newchecks[0]++;
+                                       if (mm != NULL) {
+                                               u_short *s =
+                                                       mtod(mm, u_short *);
+                                               cb->s_rhdr.sp_dt = dt;
+                                               mm->m_len = 5; /*XXX*/
+                                               s[0] = 5;
+                                               s[1] = 1;
+                                               *(u_char *)(&s[2]) = dt;
+                                               sbappend(&so->so_rcv, mm);
+                                       }
+                               }
+                               if (sp->sp_cc & SP_OB) {
+                                       MCHTYPE(m, MT_OOBDATA);
+                                       spp_newchecks[1]++;
+                                       so->so_oobmark = 0;
+                                       so->so_state &= ~SS_RCVATMARK;
+                               }
+                               if (packetp == 0) {
+                                       m->m_data += SPINC;
+                                       m->m_len -= SPINC;
+                                       m->m_pkthdr.len -= SPINC;
+                               }
+                               if ((sp->sp_cc & SP_EM) || packetp) {
+                                       sbappendrecord(&so->so_rcv, m);
+                                       spp_newchecks[9]++;
+                               } else
+                                       sbappend(&so->so_rcv, m);
+                       } else
+#endif
                        if (packetp) {
                                sbappendrecord(&so->so_rcv, m);
                        } else {
                                cb->s_rhdr = *mtod(m, struct sphdr *);
                        if (packetp) {
                                sbappendrecord(&so->so_rcv, m);
                        } else {
                                cb->s_rhdr = *mtod(m, struct sphdr *);
-                               m->m_off += SPINC;
+                               m->m_data += SPINC;
                                m->m_len -= SPINC;
                                m->m_len -= SPINC;
+                               m->m_pkthdr.len -= SPINC;
                                sbappend(&so->so_rcv, m);
                        }
                  } else
                                sbappend(&so->so_rcv, m);
                        }
                  } else
@@ -649,7 +690,7 @@ spp_output(cb, m0)
        register struct spidp *si = (struct spidp *) 0;
        register struct sockbuf *sb = &so->so_snd;
        int len = 0, win, rcv_win;
        register struct spidp *si = (struct spidp *) 0;
        register struct sockbuf *sb = &so->so_snd;
        int len = 0, win, rcv_win;
-       short span, off;
+       short span, off, recordp = 0;
        u_short alo;
        int error = 0, sendalot;
 #ifdef notdef
        u_short alo;
        int error = 0, sendalot;
 #ifdef notdef
@@ -667,6 +708,8 @@ spp_output(cb, m0)
                for (m = m0; m ; m = m->m_next) {
                        mprev = m;
                        len += m->m_len;
                for (m = m0; m ; m = m->m_next) {
                        mprev = m;
                        len += m->m_len;
+                       if (m->m_flags & M_EOR)
+                               recordp = 1;
                }
                datalen = (cb->s_flags & SF_HO) ?
                                len - sizeof (struct sphdr) : len;
                }
                datalen = (cb->s_flags & SF_HO) ?
                                len - sizeof (struct sphdr) : len;
@@ -684,6 +727,14 @@ spp_output(cb, m0)
                                                error = ENOBUFS;
                                                goto bad_copy;
                                        }
                                                error = ENOBUFS;
                                                goto bad_copy;
                                        }
+                                       if (cb->s_flags & SF_NEWCALL) {
+                                           struct mbuf *mm = m;
+                                           spp_newchecks[7]++;
+                                           while (mm) {
+                                               mm->m_flags &= ~M_EOR;
+                                               mm = mm->m_next;
+                                           }
+                                       }
                                        error = spp_output(cb, m);
                                        if (error) {
                                        bad_copy:
                                        error = spp_output(cb, m);
                                        if (error) {
                                        bad_copy:
@@ -703,7 +754,7 @@ spp_output(cb, m0)
                 */
                if (len & 1) {
                        m = mprev;
                 */
                if (len & 1) {
                        m = mprev;
-                       if (m->m_len + m->m_off < MMAXOFF)
+                       if (M_TRAILINGSPACE(m) >= 1)
                                m->m_len++;
                        else {
                                struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA);
                                m->m_len++;
                        else {
                                struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA);
@@ -713,11 +764,11 @@ spp_output(cb, m0)
                                        return (ENOBUFS);
                                }
                                m1->m_len = 1;
                                        return (ENOBUFS);
                                }
                                m1->m_len = 1;
-                               m1->m_off = MMAXOFF - 1;
+                               *(mtod(m1, u_char *)) = 0;
                                m->m_next = m1;
                        }
                }
                                m->m_next = m1;
                        }
                }
-               m = m_get(M_DONTWAIT, MT_HEADER);
+               m = m_gethdr(M_DONTWAIT, MT_HEADER);
                if (m == 0) {
                        m_freem(m0);
                        return (ENOBUFS);
                if (m == 0) {
                        m_freem(m0);
                        return (ENOBUFS);
@@ -725,9 +776,8 @@ spp_output(cb, m0)
                /*
                 * Fill in mbuf with extended SP header
                 * and addresses and length put into network format.
                /*
                 * Fill in mbuf with extended SP header
                 * and addresses and length put into network format.
-                * Long align so prepended ip headers will work on Gould.
                 */
                 */
-               m->m_off = MMAXOFF - sizeof (struct spidp) - 2;
+               MH_ALIGN(m, sizeof (struct spidp));
                m->m_len = sizeof (struct spidp);
                m->m_next = m0;
                si = mtod(m, struct spidp *);
                m->m_len = sizeof (struct spidp);
                m->m_next = m0;
                si = mtod(m, struct spidp *);
@@ -747,10 +797,14 @@ spp_output(cb, m0)
                        si->si_dt = sh->sp_dt;
                        si->si_cc |= sh->sp_cc & SP_EM;
                        m0->m_len -= sizeof (*sh);
                        si->si_dt = sh->sp_dt;
                        si->si_cc |= sh->sp_cc & SP_EM;
                        m0->m_len -= sizeof (*sh);
-                       m0->m_off += sizeof (*sh);
+                       m0->m_data += sizeof (*sh);
                        len -= sizeof (*sh);
                }
                len += sizeof(*si);
                        len -= sizeof (*sh);
                }
                len += sizeof(*si);
+               if ((cb->s_flags2 & SF_NEWCALL) && recordp) {
+                       si->si_cc  |= SP_EM;
+                       spp_newchecks[8]++;
+               }
                if (cb->s_oobflags & SF_SOOB) {
                        /*
                         * Per jqj@cornell:
                if (cb->s_oobflags & SF_SOOB) {
                        /*
                         * Per jqj@cornell:
@@ -766,6 +820,7 @@ spp_output(cb, m0)
                        }
                }
                si->si_len = htons((u_short)len);
                        }
                }
                si->si_len = htons((u_short)len);
+               m->m_pkthdr.len = ((len - 1) | 1) + 1;
                /*
                 * queue stuff up for output
                 */
                /*
                 * queue stuff up for output
                 */
@@ -778,7 +833,7 @@ spp_output(cb, m0)
 again:
        sendalot = 0;
        off = cb->s_snxt - cb->s_rack;
 again:
        sendalot = 0;
        off = cb->s_snxt - cb->s_rack;
-       win = MIN(cb->s_swnd, (cb->s_cwnd/CUNIT));
+       win = min(cb->s_swnd, (cb->s_cwnd/CUNIT));
 
        /*
         * If in persist timeout with window of 0, send a probe.
 
        /*
         * If in persist timeout with window of 0, send a probe.
@@ -793,7 +848,7 @@ again:
                }
        }
        span = cb->s_seq - cb->s_rack;
                }
        }
        span = cb->s_seq - cb->s_rack;
-       len = MIN(span, win) - off;
+       len = min(span, win) - off;
 
        if (len < 0) {
                /*
 
        if (len < 0) {
                /*
@@ -913,7 +968,6 @@ send:
                if (m == NULL) {
                        return (ENOBUFS);
                }
                if (m == NULL) {
                        return (ENOBUFS);
                }
-               m0 = m;
                si = mtod(m, struct spidp *);
                if (SSEQ_LT(si->si_seq, cb->s_smax))
                        sppstat.spps_sndrexmitpack++;
                si = mtod(m, struct spidp *);
                if (SSEQ_LT(si->si_seq, cb->s_smax))
                        sppstat.spps_sndrexmitpack++;
@@ -927,19 +981,16 @@ send:
                        sppstat.spps_sndprobe++;
                if (cb->s_flags & SF_ACKNOW)
                        sppstat.spps_sndacks++;
                        sppstat.spps_sndprobe++;
                if (cb->s_flags & SF_ACKNOW)
                        sppstat.spps_sndacks++;
-               m = m_get(M_DONTWAIT, MT_HEADER);
-               if (m == 0) {
+               m = m_gethdr(M_DONTWAIT, MT_HEADER);
+               if (m == 0)
                        return (ENOBUFS);
                        return (ENOBUFS);
-               }
                /*
                 * Fill in mbuf with extended SP header
                 * and addresses and length put into network format.
                /*
                 * Fill in mbuf with extended SP header
                 * and addresses and length put into network format.
-                * Allign beginning of packet to long to prepend
-                * ifp's on loopback, or NSIP encaspulation for fussy cpu's.
                 */
                 */
-               m->m_off = MMAXOFF - sizeof (struct spidp) - 2;
+               MH_ALIGN(m, sizeof (struct spidp));
                m->m_len = sizeof (*si);
                m->m_len = sizeof (*si);
-               m->m_next = 0;
+               m->m_pkthdr.len = sizeof (*si);
                si = mtod(m, struct spidp *);
                si->si_i = *cb->s_idp;
                si->si_s = cb->s_shdr;
                si = mtod(m, struct spidp *);
                si->si_i = *cb->s_idp;
                si->si_s = cb->s_shdr;
@@ -1010,7 +1061,7 @@ send:
                        len = ntohs(si->si_len);
                        if (len & 1)
                                len++;
                        len = ntohs(si->si_len);
                        if (len & 1)
                                len++;
-                       si->si_sum = ns_cksum(dtom(si), len);
+                       si->si_sum = ns_cksum(m, len);
                } else
                        si->si_sum = 0xffff;
 
                } else
                        si->si_sum = 0xffff;
 
@@ -1103,25 +1154,21 @@ spp_ctloutput(req, so, level, name, value)
                        mask = SF_HO;
                get_flags:
                        m->m_len = sizeof(short);
                        mask = SF_HO;
                get_flags:
                        m->m_len = sizeof(short);
-                       m->m_off = MMAXOFF - sizeof(short);
                        *mtod(m, short *) = cb->s_flags & mask;
                        break;
 
                case SO_MTU:
                        m->m_len = sizeof(u_short);
                        *mtod(m, short *) = cb->s_flags & mask;
                        break;
 
                case SO_MTU:
                        m->m_len = sizeof(u_short);
-                       m->m_off = MMAXOFF - sizeof(short);
                        *mtod(m, short *) = cb->s_mtu;
                        break;
 
                case SO_LAST_HEADER:
                        m->m_len = sizeof(struct sphdr);
                        *mtod(m, short *) = cb->s_mtu;
                        break;
 
                case SO_LAST_HEADER:
                        m->m_len = sizeof(struct sphdr);
-                       m->m_off = MMAXOFF - sizeof(struct sphdr);
                        *mtod(m, struct sphdr *) = cb->s_rhdr;
                        break;
 
                case SO_DEFAULT_HEADERS:
                        m->m_len = sizeof(struct spidp);
                        *mtod(m, struct sphdr *) = cb->s_rhdr;
                        break;
 
                case SO_DEFAULT_HEADERS:
                        m->m_len = sizeof(struct spidp);
-                       m->m_off = MMAXOFF - sizeof(struct sphdr);
                        *mtod(m, struct sphdr *) = cb->s_shdr;
                        break;
 
                        *mtod(m, struct sphdr *) = cb->s_shdr;
                        break;
 
@@ -1159,6 +1206,19 @@ spp_ctloutput(req, so, level, name, value)
                        cb->s_mtu = *(mtod(*value, u_short *));
                        break;
 
                        cb->s_mtu = *(mtod(*value, u_short *));
                        break;
 
+#ifdef SF_NEWCALL
+               case SO_NEWCALL:
+                       ok = mtod(*value, int *);
+                       if (*ok) {
+                               cb->s_flags2 |= SF_NEWCALL;
+                               spp_newchecks[5]++;
+                       } else {
+                               cb->s_flags2 &= ~SF_NEWCALL;
+                               spp_newchecks[6]++;
+                       }
+                       break;
+#endif
+
                case SO_DEFAULT_HEADERS:
                        {
                                register struct sphdr *sp
                case SO_DEFAULT_HEADERS:
                        {
                                register struct sphdr *sp
@@ -1179,10 +1239,10 @@ spp_ctloutput(req, so, level, name, value)
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/
-spp_usrreq(so, req, m, nam, rights)
+spp_usrreq(so, req, m, nam, rights, controlp)
        struct socket *so;
        int req;
        struct socket *so;
        int req;
-       struct mbuf *m, *nam, *rights;
+       struct mbuf *m, *nam, *rights, *controlp;
 {
        struct nspcb *nsp = sotonspcb(so);
        register struct sppcb *cb;
 {
        struct nspcb *nsp = sotonspcb(so);
        register struct sppcb *cb;
@@ -1248,7 +1308,7 @@ spp_usrreq(so, req, m, nam, rights)
                cb->s_mtu = 576 - sizeof (struct spidp);
                cb->s_cwnd = sbspace(sb) * CUNIT / cb->s_mtu;
                cb->s_ssthresh = cb->s_cwnd;
                cb->s_mtu = 576 - sizeof (struct spidp);
                cb->s_cwnd = sbspace(sb) * CUNIT / cb->s_mtu;
                cb->s_ssthresh = cb->s_cwnd;
-               cb->s_cwmx = sb->sb_mbmax * CUNIT /
+               cb->s_cwmx = sbspace(sb) * CUNIT /
                                (2 * sizeof (struct spidp));
                /* Above is recomputed when connecting to account
                   for changed buffering or mtu's */
                                (2 * sizeof (struct spidp));
                /* Above is recomputed when connecting to account
                   for changed buffering or mtu's */
@@ -1388,6 +1448,14 @@ spp_usrreq(so, req, m, nam, rights)
                cb->s_oobflags |= SF_SOOB;
                /* fall into */
        case PRU_SEND:
                cb->s_oobflags |= SF_SOOB;
                /* fall into */
        case PRU_SEND:
+               if (controlp) {
+                       u_short *s = mtod(controlp, u_short *);
+                       spp_newchecks[2]++;
+                       if ((s[0] == 5) && s[1] == 1 ) { /* XXXX, for testing */
+                               cb->s_shdr.sp_dt = *(u_char *)(&s[2]);
+                               spp_newchecks[3]++;
+                       }
+               }
                error = spp_output(cb, m);
                m = NULL;
                break;
                error = spp_output(cb, m);
                m = NULL;
                break;
@@ -1423,12 +1491,12 @@ release:
        return (error);
 }
 
        return (error);
 }
 
-spp_usrreq_sp(so, req, m, nam, rights)
+spp_usrreq_sp(so, req, m, nam, rights, controlp)
        struct socket *so;
        int req;
        struct socket *so;
        int req;
-       struct mbuf *m, *nam, *rights;
+       struct mbuf *m, *nam, *rights, *controlp;
 {
 {
-       int error = spp_usrreq(so, req, m, nam, rights);
+       int error = spp_usrreq(so, req, m, nam, rights, controlp);
 
        if (req == PRU_ATTACH && error == 0) {
                struct nspcb *nsp = sotonspcb(so);
 
        if (req == PRU_ATTACH && error == 0) {
                struct nspcb *nsp = sotonspcb(so);
@@ -1460,8 +1528,8 @@ spp_template(cb)
        cb->s_cwnd = (sbspace(sb) * CUNIT) / cb->s_mtu;
        cb->s_ssthresh = cb->s_cwnd; /* Try to expand fast to full complement
                                        of large packets */
        cb->s_cwnd = (sbspace(sb) * CUNIT) / cb->s_mtu;
        cb->s_ssthresh = cb->s_cwnd; /* Try to expand fast to full complement
                                        of large packets */
-       cb->s_cwmx = (sb->sb_mbmax * CUNIT) / (2 * sizeof(struct spidp));
-       cb->s_cwmx = MAX(cb->s_cwmx, cb->s_cwnd);
+       cb->s_cwmx = (sbspace(sb) * CUNIT) / (2 * sizeof(struct spidp));
+       cb->s_cwmx = max(cb->s_cwmx, cb->s_cwnd);
                /* But allow for lots of little packets as well */
 }
 
                /* But allow for lots of little packets as well */
 }
 
@@ -1672,7 +1740,7 @@ spp_timers(cb, timer)
                 * See very long discussion in tcp_timer.c about congestion
                 * window and sstrhesh
                 */
                 * See very long discussion in tcp_timer.c about congestion
                 * window and sstrhesh
                 */
-               win = MIN(cb->s_swnd, (cb->s_cwnd/CUNIT)) / 2;
+               win = min(cb->s_swnd, (cb->s_cwnd/CUNIT)) / 2;
                if (win < 2)
                        win = 2;
                cb->s_cwnd = CUNIT;
                if (win < 2)
                        win = 2;
                cb->s_cwnd = CUNIT;