lint
[unix-history] / usr / src / sys / net / raw_usrreq.c
index 82d5e99..b301fde 100644 (file)
@@ -1,33 +1,35 @@
-/*     raw_usrreq.c    4.5     82/01/24        */
+/*     raw_usrreq.c    4.25    83/02/10        */
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
 #include "../h/protosw.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
 #include "../h/protosw.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
-#include "../h/mtpr.h"
-#include "../net/in.h"
-#include "../net/in_systm.h"
+#include "../h/errno.h"
+
 #include "../net/if.h"
 #include "../net/if.h"
+#include "../net/netisr.h"
 #include "../net/raw_cb.h"
 #include "../net/raw_cb.h"
-#include "/usr/include/errno.h"
+
+#include "../vax/mtpr.h"
 
 /*
  * Initialize raw connection block q.
 
 /*
  * Initialize raw connection block q.
-*/
+ */
 raw_init()
 {
 raw_init()
 {
-COUNT(RAW_INIT);
+
        rawcb.rcb_next = rawcb.rcb_prev = &rawcb;
        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, proto, src, dst)
        struct mbuf *m0;
        struct mbuf *m0;
-       struct sockproto pf;
-       struct sockaddr af;
+       struct sockproto *proto;
+       struct sockaddr *src, *dst;
 {
        register struct mbuf *m;
        struct raw_header *rh;
 {
        register struct mbuf *m;
        struct raw_header *rh;
@@ -36,17 +38,17 @@ raw_input(m0, pf, af)
        /*
         * Rip off an mbuf for a generic header.
         */
        /*
         * Rip off an mbuf for a generic header.
         */
-       m = m_get(M_DONTWAIT);
+       m = m_get(M_DONTWAIT, MT_HEADER);
        if (m == 0) {
                m_freem(m0);
                return;
        }
        m->m_next = m0;
        if (m == 0) {
                m_freem(m0);
                return;
        }
        m->m_next = m0;
-       m->m_off = MMINOFF;
        m->m_len = sizeof(struct raw_header);
        rh = mtod(m, struct raw_header *);
        m->m_len = sizeof(struct raw_header);
        rh = mtod(m, struct raw_header *);
-       rh->raw_address = af;
-       rh->raw_protocol = pf;
+       rh->raw_dst = *dst;
+       rh->raw_src = *src;
+       rh->raw_proto = *proto;
 
        /*
         * Header now contains enough info to decide
 
        /*
         * Header now contains enough info to decide
@@ -55,9 +57,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);
 }
 
 /*
 }
 
 /*
@@ -71,96 +76,84 @@ rawintr()
        int s;
        struct mbuf *m;
        register struct rawcb *rp;
        int s;
        struct mbuf *m;
        register struct rawcb *rp;
-       register struct socket *so;
-       register struct protosw *pr;
-       register struct sockproto *sp;
-       register struct sockaddr *sa;
+       register struct protosw *lproto;
+       register struct raw_header *rh;
        struct socket *last;
 
        struct socket *last;
 
-COUNT(RAWINTR);
 next:
        s = splimp();
        IF_DEQUEUE(&rawintrq, m);
        splx(s);
        if (m == 0)
                return;
 next:
        s = splimp();
        IF_DEQUEUE(&rawintrq, m);
        splx(s);
        if (m == 0)
                return;
-       sp = &(mtod(m, struct raw_header *)->raw_protocol);
-       sa = &(mtod(m, struct raw_header *)->raw_address);
-
-       /*
-        * Find the appropriate socket(s) in which to place this
-        * packet.  This is done by matching the protocol and
-        * address information prepended by raw_input against
-        * the info stored in the control block structures.
-        */
+       rh = mtod(m, struct raw_header *);
        last = 0;
        for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
        last = 0;
        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 ||
-                   pr->pr_protocol != sp->sp_protocol)
+               lproto = rp->rcb_socket->so_proto;
+               if (lproto->pr_family != rh->raw_proto.sp_family)
                        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 (lproto->pr_protocol &&
+                   lproto->pr_protocol != rh->raw_proto.sp_protocol)
                        continue;
                /*
                 * We assume the lower level routines have
                 * placed the address in a canonical format
                        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.
+                * suitable for a structure comparison.
                 */
                 */
-               if ((rp->rcb_flags & RAW_ADDR) &&
-                   bcmp(sa->sa_data, so->so_addr.sa_data, 14) != 0)
+#define equal(a1, a2) \
+       (bcmp((caddr_t)&(a1), (caddr_t)&(a2), sizeof (struct sockaddr)) == 0)
+               if ((rp->rcb_flags & RAW_LADDR) &&
+                   !equal(rp->rcb_laddr, rh->raw_dst))
+                       continue;
+               if ((rp->rcb_flags & RAW_FADDR) &&
+                   !equal(rp->rcb_faddr, rh->raw_src))
                        continue;
                        continue;
-               /*
-                * To avoid extraneous packet copies, we keep
-                * track of the last socket the packet should be
-                * placed in, and make copies only after finding a
-                * socket which "collides".
-                */
                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)) == 0)
                                goto nospace;
                                goto nospace;
-                       sbappend(&last->so_rcv, n);
+                       if (sbappendaddr(&last->so_rcv, &rh->raw_src, n)==0) {
+                               /* should notify about lost packet */
+                               m_freem(n);
+                               goto nospace;
+                       }
                        sorwakeup(last);
                }
 nospace:
                        sorwakeup(last);
                }
 nospace:
-               last = so;
+               last = rp->rcb_socket;
+       }
+       if (last) {
+               m = m_free(m);          /* header */
+               if (sbappendaddr(&last->so_rcv, &rh->raw_src, m) == 0)
+                       goto drop;
+               sorwakeup(last);
+               goto next;
        }
        }
-       if (last == 0)
-               goto drop;
-       m = m_free(m);          /* drop generic header */
-       sbappend(&last->so_rcv, m->m_next);
-       sorwakeup(last);
-       goto next;
 drop:
        m_freem(m);
        goto next;
 }
 
 /*ARGSUSED*/
 drop:
        m_freem(m);
        goto next;
 }
 
 /*ARGSUSED*/
-raw_usrreq(so, req, m, addr)
+raw_ctlinput(cmd, arg)
+       int cmd;
+       caddr_t arg;
+{
+
+       if (cmd < 0 || cmd > PRC_NCMDS)
+               return;
+       /* INCOMPLETE */
+}
+
+/*ARGSUSED*/
+raw_usrreq(so, req, m, nam)
        struct socket *so;
        int req;
        struct socket *so;
        int req;
-       struct mbuf *m;
-       caddr_t addr;
+       struct mbuf *m, *nam;
 {
        register struct rawcb *rp = sotorawcb(so);
        int error = 0;
 
 {
        register struct rawcb *rp = sotorawcb(so);
        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,9 +165,11 @@ 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 (EACCES);
                if (rp)
                if (rp)
-                       return (EINVAL);;
-               error = raw_attach(so, (struct sockaddr *)addr);
+                       return (EINVAL);
+               error = raw_attach(so);
                break;
 
        /*
                break;
 
        /*
@@ -194,14 +189,14 @@ COUNT(RAW_USRREQ);
         * nothing else around it should go to). 
         */
        case PRU_CONNECT:
         * nothing else around it should go to). 
         */
        case PRU_CONNECT:
-               if (rp->rcb_flags & RAW_ADDR)
+               if (rp->rcb_flags & RAW_FADDR)
                        return (EISCONN);
                        return (EISCONN);
-               raw_connaddr(rp, (struct sockaddr *)addr);
+               raw_connaddr(rp, nam);
                soisconnected(so);
                break;
 
        case PRU_DISCONNECT:
                soisconnected(so);
                break;
 
        case PRU_DISCONNECT:
-               if ((rp->rcb_flags & RAW_ADDR) == 0)
+               if ((rp->rcb_flags & RAW_FADDR) == 0)
                        return (ENOTCONN);
                raw_disconnect(rp);
                soisdisconnected(so);
                        return (ENOTCONN);
                raw_disconnect(rp);
                soisdisconnected(so);
@@ -219,15 +214,15 @@ COUNT(RAW_USRREQ);
         * routine handles any massaging necessary.
         */
        case PRU_SEND:
         * routine handles any massaging necessary.
         */
        case PRU_SEND:
-               if (addr) {
-                       if (rp->rcb_flags & RAW_ADDR)
+               if (nam) {
+                       if (rp->rcb_flags & RAW_FADDR)
                                return (EISCONN);
                                return (EISCONN);
-                       raw_connaddr(rp, (struct sockaddr *)addr);
-               } else if ((rp->rcb_flags & RAW_ADDR) == 0)
+                       raw_connaddr(rp, nam);
+               } else if ((rp->rcb_flags & RAW_FADDR) == 0)
                        return (ENOTCONN);
                        return (ENOTCONN);
-               (void) (*so->so_proto->pr_output)(m, so);
-               if (addr)
-                       rp->rcb_flags &= ~RAW_ADDR;
+               error = (*so->so_proto->pr_output)(m, so);
+               if (nam)
+                       rp->rcb_flags &= ~RAW_FADDR;
                break;
 
        case PRU_ABORT:
                break;
 
        case PRU_ABORT:
@@ -248,6 +243,12 @@ COUNT(RAW_USRREQ);
                error = EOPNOTSUPP;
                break;
 
                error = EOPNOTSUPP;
                break;
 
+       case PRU_SOCKADDR:
+               bcopy((caddr_t)&rp->rcb_laddr, mtod(nam, caddr_t),
+                   sizeof (struct sockaddr));
+               nam->m_len = sizeof (struct sockaddr);
+               break;
+
        default:
                panic("raw_usrreq");
        }
        default:
                panic("raw_usrreq");
        }