BSD 4_3_Tahoe release
[unix-history] / usr / src / sys / netns / ns_input.c
index 437201f..15e3240 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.6 (Berkeley) %G%
+ *     @(#)ns_input.c  7.4 (Berkeley) 6/29/88
  */
 
 #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"
@@ -48,7 +47,6 @@ union ns_host ns_zerohost;
 union ns_host  ns_broadhost;
 union ns_net   ns_zeronet;
 union ns_net   ns_broadnet;
 union ns_host  ns_broadhost;
 union ns_net   ns_zeronet;
 union ns_net   ns_broadnet;
-struct sockaddr_ns ns_netmask, ns_hostmask;
 
 static u_short allones[] = {-1, -1, -1};
 
 
 static u_short allones[] = {-1, -1, -1};
 
@@ -71,11 +69,6 @@ ns_init()
        nsrawpcb.nsp_next = nsrawpcb.nsp_prev = &nsrawpcb;
        nsintrq.ifq_maxlen = nsqmaxlen;
        ns_pexseq = time.tv_usec;
        nsrawpcb.nsp_next = nsrawpcb.nsp_prev = &nsrawpcb;
        nsintrq.ifq_maxlen = nsqmaxlen;
        ns_pexseq = time.tv_usec;
-       ns_netmask.sns_len = 6;
-       ns_netmask.sns_addr.x_net = ns_broadnet;
-       ns_hostmask.sns_len = 12;
-       ns_hostmask.sns_addr.x_net = ns_broadnet;
-       ns_hostmask.sns_addr.x_host = ns_broadhost;
 }
 
 /*
 }
 
 /*
@@ -88,6 +81,8 @@ nsintr()
        register struct idp *idp;
        register struct mbuf *m;
        register struct nspcb *nsp;
        register struct idp *idp;
        register struct mbuf *m;
        register struct nspcb *nsp;
+       struct ifnet *ifp;
+       struct mbuf *m0;
        register int i;
        int len, s, error;
        char oddpacketp;
        register int i;
        int len, s, error;
        char oddpacketp;
@@ -98,12 +93,12 @@ next:
         * in first mbuf.
         */
        s = splimp();
         * in first mbuf.
         */
        s = splimp();
-       IF_DEQUEUE(&nsintrq, m);
+       IF_DEQUEUEIF(&nsintrq, m, ifp);
        splx(s);
        nsintr_getpck++;
        if (m == 0)
                return;
        splx(s);
        nsintr_getpck++;
        if (m == 0)
                return;
-       if ((m->m_flags & M_EXT || m->m_len < sizeof (struct idp)) &&
+       if ((m->m_off > MMAXOFF || 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;
@@ -114,7 +109,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);
+               if (m1) idp_input(m1, nsp, ifp);
        }
 
        idp = mtod(m, struct idp *);
        }
 
        idp = mtod(m, struct idp *);
@@ -130,20 +125,29 @@ 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.
         */
-       if (m->m_pkthdr.len < len) {
-               idpstat.idps_tooshort++;
-               goto bad;
+       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) {
-               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);
+       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);
        }
        }
+       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))
@@ -173,7 +177,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(m);
+                               idp_forward(idp);
                                goto next;
                        }
                }
                                goto next;
                        }
                }
@@ -181,7 +185,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(m);
+               idp_forward(idp);
                goto next;
        }
        /*
                goto next;
        }
        /*
@@ -194,20 +198,20 @@ next:
        nsintr_swtch++;
        if (nsp) {
                if (oddpacketp) {
        nsintr_swtch++;
        if (nsp) {
                if (oddpacketp) {
-                       m_adj(m, -1);
+                       m_adj(m0, -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);
+                                   spp_input(m, nsp, ifp);
                                    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);
+               idp_input(m, nsp, ifp);
        } else {
                ns_error(m, NS_ERR_NOSOCK, 0);
        }
        } else {
                ns_error(m, NS_ERR_NOSOCK, 0);
        }
@@ -251,7 +255,7 @@ idp_ctlinput(cmd, arg)
        case PRC_HOSTDEAD:
        case PRC_HOSTUNREACH:
                sns = (struct sockaddr_ns *)arg;
        case PRC_HOSTDEAD:
        case PRC_HOSTUNREACH:
                sns = (struct sockaddr_ns *)arg;
-               if (sns->sns_family != AF_NS)
+               if (sns->sns_family != AF_INET)
                        return;
                ns = &sns->sns_addr;
                break;
                        return;
                ns = &sns->sns_addr;
                break;
@@ -287,10 +291,9 @@ int        idpforwarding = 1;
 struct route idp_droute;
 struct route idp_sroute;
 
 struct route idp_droute;
 struct route idp_sroute;
 
-idp_forward(m)
-struct mbuf *m;
+idp_forward(idp)
+       register struct idp *idp;
 {
 {
-       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;
@@ -319,7 +322,7 @@ struct mbuf *m;
         * 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(m, 0, imin((int)ntohs(idp->idp_len), 42));
+       mcopy = m_copy(dtom(idp), 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;
@@ -342,7 +345,7 @@ struct mbuf *m;
                }
                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(m);
+                       m_freem(dtom(idp));
                        goto cleanup;
                }
                if (idp_droute.ro_rt &&
                        goto cleanup;
                }
                if (idp_droute.ro_rt &&
@@ -370,7 +373,7 @@ struct mbuf *m;
                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(m, &idp_droute, flags)) && 
+       if ((error = ns_output(dtom(idp), &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;
@@ -395,7 +398,7 @@ struct mbuf *m;
                }
                mcopy = NULL;
        senderror:
                }
                mcopy = NULL;
        senderror:
-               ns_error(m, type, code);
+               ns_error(dtom(idp), type, code);
        }
 cleanup:
        if (ok_there)
        }
 cleanup:
        if (ok_there)
@@ -416,7 +419,6 @@ struct route *ro;
        bzero((caddr_t)ro, sizeof (*ro));
        dst = (struct sockaddr_ns *)&ro->ro_dst;
 
        bzero((caddr_t)ro, sizeof (*ro));
        dst = (struct sockaddr_ns *)&ro->ro_dst;
 
-       dst->sns_len = sizeof(*dst);
        dst->sns_family = AF_NS;
        dst->sns_addr = *src;
        dst->sns_addr.x_port = 0;
        dst->sns_family = AF_NS;
        dst->sns_addr = *src;
        dst->sns_addr.x_port = 0;
@@ -441,31 +443,38 @@ struct mbuf *m;
 struct ifnet *ifp;
 {
        register struct nspcb *nsp;
 struct ifnet *ifp;
 {
        register struct nspcb *nsp;
-       register struct ifaddr *ifa;
+       register struct ifaddr *ia;
        /*
         * Give any raw listeners a crack at the packet
         */
        for (nsp = nsrawpcb.nsp_next; nsp != &nsrawpcb; nsp = nsp->nsp_next) {
                struct mbuf *m0 = m_copy(m, 0, (int)M_COPYALL);
                if (m0) {
        /*
         * Give any raw listeners a crack at the packet
         */
        for (nsp = nsrawpcb.nsp_next; nsp != &nsrawpcb; nsp = nsp->nsp_next) {
                struct mbuf *m0 = m_copy(m, 0, (int)M_COPYALL);
                if (m0) {
-                       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(ifa = ifp->if_addrlist; ifa;
-                                               ifa = ifa->ifa_next) {
-                               if (ifa->ifa_addr->sa_family==AF_NS) {
-                                   idp->idp_sna = IA_SNS(ifa)->sns_addr;
-                                   break;
-                               }
-                           }
-                       idp->idp_len = ntohl(m0->m_pkthdr.len);
-                       idp_input(m0, nsp);
+                       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);
+                       }
                }
        }
 }
                }
        }
 }