trailer's handled wrong on pup's
[unix-history] / usr / src / sys / net / raw_usrreq.c
index 82d5e99..aee828e 100644 (file)
@@ -1,4 +1,4 @@
-/*     raw_usrreq.c    4.5     82/01/24        */
+/*     raw_usrreq.c    4.11    82/03/19        */
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
 #include "../net/in_systm.h"
 #include "../net/if.h"
 #include "../net/raw_cb.h"
 #include "../net/in_systm.h"
 #include "../net/if.h"
 #include "../net/raw_cb.h"
-#include "/usr/include/errno.h"
+#include "../errno.h"
+
+int    rawqmaxlen = IFQ_MAXLEN;
 
 /*
  * Initialize raw connection block q.
 
 /*
  * Initialize raw connection block q.
-*/
+ */
 raw_init()
 {
 raw_init()
 {
+
 COUNT(RAW_INIT);
        rawcb.rcb_next = rawcb.rcb_prev = &rawcb;
 COUNT(RAW_INIT);
        rawcb.rcb_next = rawcb.rcb_prev = &rawcb;
+       rawintrq.ifq_maxlen = IFQ_MAXLEN;
 }
 
 /*
  * Raw protocol interface.
  */
 }
 
 /*
  * Raw protocol interface.
  */
-raw_input(m0, pf, af)
+raw_input(m0, pf, daf, saf)
        struct mbuf *m0;
        struct mbuf *m0;
-       struct sockproto pf;
-       struct sockaddr af;
+       struct sockproto *pf;
+       struct sockaddr *daf, *saf;
 {
        register struct mbuf *m;
        struct raw_header *rh;
        int s;
 
 {
        register struct mbuf *m;
        struct raw_header *rh;
        int s;
 
+COUNT(RAW_INPUT);
        /*
         * Rip off an mbuf for a generic header.
         */
        /*
         * Rip off an mbuf for a generic header.
         */
@@ -45,8 +50,9 @@ raw_input(m0, pf, af)
        m->m_off = MMINOFF;
        m->m_len = sizeof(struct raw_header);
        rh = mtod(m, struct raw_header *);
        m->m_off = MMINOFF;
        m->m_len = sizeof(struct raw_header);
        rh = mtod(m, struct raw_header *);
-       rh->raw_address = af;
-       rh->raw_protocol = pf;
+       rh->raw_dst = *daf;
+       rh->raw_src = *saf;
+       rh->raw_protocol = *pf;
 
        /*
         * Header now contains enough info to decide
 
        /*
         * Header now contains enough info to decide
@@ -55,9 +61,12 @@ raw_input(m0, pf, af)
         * running at software interrupt level.
         */
        s = splimp();
         * running at software interrupt level.
         */
        s = splimp();
-       IF_ENQUEUE(&rawintrq, m);
+       if (IF_QFULL(&rawintrq))
+               m_freem(m);
+       else
+               IF_ENQUEUE(&rawintrq, m);
        splx(s);
        splx(s);
-       setrawintr();
+       schednetisr(NETISR_RAW);
 }
 
 /*
 }
 
 /*
@@ -75,6 +84,7 @@ rawintr()
        register struct protosw *pr;
        register struct sockproto *sp;
        register struct sockaddr *sa;
        register struct protosw *pr;
        register struct sockproto *sp;
        register struct sockaddr *sa;
+       struct raw_header *rawp;
        struct socket *last;
 
 COUNT(RAWINTR);
        struct socket *last;
 
 COUNT(RAWINTR);
@@ -84,8 +94,9 @@ next:
        splx(s);
        if (m == 0)
                return;
        splx(s);
        if (m == 0)
                return;
-       sp = &(mtod(m, struct raw_header *)->raw_protocol);
-       sa = &(mtod(m, struct raw_header *)->raw_address);
+       rawp = mtod(m, struct raw_header *);
+       sp = &rawp->raw_protocol;
+       sa = &rawp->raw_dst;
 
        /*
         * Find the appropriate socket(s) in which to place this
 
        /*
         * Find the appropriate socket(s) in which to place this
@@ -97,25 +108,20 @@ next:
        for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
                so = rp->rcb_socket;
                pr = so->so_proto;
        for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
                so = rp->rcb_socket;
                pr = so->so_proto;
-
-               if (so->so_options & SO_DEBUG) {
-                       printf("rawintr: sp=<%d,%d>, af=<%d,%x>\n",
-                        sp->sp_family, sp->sp_protocol, sa->sa_family,
-                        ((struct sockaddr_in *)sa)->sin_addr);
-                       printf("pr=<%d,%d>\n", pr->pr_family, pr->pr_protocol);
-               }
                if (pr->pr_family != sp->sp_family ||
                if (pr->pr_family != sp->sp_family ||
-                   pr->pr_protocol != sp->sp_protocol)
+                   (pr->pr_protocol && pr->pr_protocol != sp->sp_protocol))
                        continue;
                        continue;
-               printf("rawintr: so=<%d,%x>\n", so->so_addr.sa_family,
-                       ((struct sockaddr_in *)&so->so_addr)->sin_addr);
-               if (sa->sa_family != so->so_addr.sa_family)
+               if (so->so_addr.sa_family && 
+                   sa->sa_family != so->so_addr.sa_family)
                        continue;
                /*
                 * We assume the lower level routines have
                 * placed the address in a canonical format
                 * suitable for a structure comparison. Packets
                 * are duplicated for each receiving socket.
                        continue;
                /*
                 * We assume the lower level routines have
                 * placed the address in a canonical format
                 * suitable for a structure comparison. Packets
                 * are duplicated for each receiving socket.
+                *
+                * SHOULD HAVE A NUMBER OF MECHANISMS FOR
+                * MATCHING BASED ON rcb_flags
                 */
                if ((rp->rcb_flags & RAW_ADDR) &&
                    bcmp(sa->sa_data, so->so_addr.sa_data, 14) != 0)
                 */
                if ((rp->rcb_flags & RAW_ADDR) &&
                    bcmp(sa->sa_data, so->so_addr.sa_data, 14) != 0)
@@ -129,9 +135,16 @@ next:
                if (last) {
                        struct mbuf *n;
 
                if (last) {
                        struct mbuf *n;
 
-                       if (n = m_copy(m->m_next, 0, M_COPYALL))
+                       if (n = m_copy(m->m_next, 0, (int)M_COPYALL))
                                goto nospace;
                                goto nospace;
-                       sbappend(&last->so_rcv, n);
+                       if (sbappendaddr(&last->so_rcv, &rawp->raw_src, n) == 0) {
+                               /*
+                                * Should drop notification of lost packet
+                                * into this guy's queue, but...
+                                */
+                               m_freem(n);
+                               goto nospace;
+                       }
                        sorwakeup(last);
                }
 nospace:
                        sorwakeup(last);
                }
 nospace:
@@ -139,8 +152,12 @@ nospace:
        }
        if (last == 0)
                goto drop;
        }
        if (last == 0)
                goto drop;
-       m = m_free(m);          /* drop generic header */
-       sbappend(&last->so_rcv, m->m_next);
+       if (sbappendaddr(&last->so_rcv, &rawp->raw_src, m->m_next) == 0)
+{
+printf("rawintr: sbappendaddr failed\n");
+               goto drop;
+}
+       (void) m_free(m);       /* generic header */
        sorwakeup(last);
        goto next;
 drop:
        sorwakeup(last);
        goto next;
 drop:
@@ -159,8 +176,6 @@ raw_usrreq(so, req, m, addr)
        int error = 0;
 
 COUNT(RAW_USRREQ);
        int error = 0;
 
 COUNT(RAW_USRREQ);
-       if (so->so_options & SO_DEBUG)
-               printf("raw_usrreq: req=%d\n");
        if (rp == 0 && req != PRU_ATTACH)
                return (EINVAL);
 
        if (rp == 0 && req != PRU_ATTACH)
                return (EINVAL);
 
@@ -172,8 +187,10 @@ COUNT(RAW_USRREQ);
         * the appropriate raw interface routine.
         */
        case PRU_ATTACH:
         * the appropriate raw interface routine.
         */
        case PRU_ATTACH:
+               if ((so->so_state & SS_PRIV) == 0)
+                       return (EPERM);
                if (rp)
                if (rp)
-                       return (EINVAL);;
+                       return (EINVAL);
                error = raw_attach(so, (struct sockaddr *)addr);
                break;
 
                error = raw_attach(so, (struct sockaddr *)addr);
                break;