X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/faad37c08e8f726cf25987ba634804e06f38010b..72e4f44ed4ef54adc3a77eaf4d319bd3c766f807:/usr/src/sys/net/raw_usrreq.c diff --git a/usr/src/sys/net/raw_usrreq.c b/usr/src/sys/net/raw_usrreq.c index 136ed5c370..5e2bc2aab7 100644 --- a/usr/src/sys/net/raw_usrreq.c +++ b/usr/src/sys/net/raw_usrreq.c @@ -1,4 +1,4 @@ -/* raw_usrreq.c 4.6 82/02/01 */ +/* raw_usrreq.c 4.15 82/04/24 */ #include "../h/param.h" #include "../h/mbuf.h" @@ -10,29 +10,34 @@ #include "../net/in_systm.h" #include "../net/if.h" #include "../net/raw_cb.h" -#include "/usr/include/errno.h" +#include + +int rawqmaxlen = IFQ_MAXLEN; /* * Initialize raw connection block q. -*/ + */ raw_init() { + COUNT(RAW_INIT); rawcb.rcb_next = rawcb.rcb_prev = &rawcb; + rawintrq.ifq_maxlen = IFQ_MAXLEN; } /* * Raw protocol interface. */ -raw_input(m0, pf, daf, saf) +raw_input(m0, proto, src, dst) struct mbuf *m0; - struct sockproto pf; - struct sockaddr daf, saf; + struct sockproto *proto; + struct sockaddr *src, *dst; { register struct mbuf *m; struct raw_header *rh; int s; +COUNT(RAW_INPUT); /* * Rip off an mbuf for a generic header. */ @@ -45,9 +50,9 @@ raw_input(m0, pf, daf, saf) m->m_off = MMINOFF; m->m_len = sizeof(struct raw_header); rh = mtod(m, struct raw_header *); - rh->raw_dst = daf; - rh->raw_src = saf; - rh->raw_protocol = pf; + rh->raw_dst = *dst; + rh->raw_src = *src; + rh->raw_proto = *proto; /* * Header now contains enough info to decide @@ -56,9 +61,12 @@ raw_input(m0, pf, daf, saf) * 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); - setrawintr(); + schednetisr(NETISR_RAW); } /* @@ -72,11 +80,8 @@ rawintr() 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; - struct raw_header *rawp; + register struct protosw *lproto; + register struct raw_header *rh; struct socket *last; COUNT(RAWINTR); @@ -86,70 +91,61 @@ next: splx(s); if (m == 0) return; - rawp = mtod(m, struct raw_header *); - sp = &rawp->raw_protocol; - sa = &rawp->raw_dst; - - /* - * 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) { - so = rp->rcb_socket; - pr = so->so_proto; - 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; - 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 - * 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; - /* - * 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 (n = m_copy(m->m_next, 0, M_COPYALL)) + if (n = m_copy(m->m_next, 0, (int)M_COPYALL)) goto nospace; - if (sbappendaddr(&last->so_rcv, &rawp->raw_src, n) == 0) { - /* - * Should drop notification of lost packet - * into this guy's queue, but... - */ + if (sbappendaddr(&last->so_rcv, &rh->raw_src, n)==0) { + /* should notify about lost packet */ m_freem(n); goto 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; - if (sbappendaddr(&last->so_rcv, &rawp->raw_src, m->m_next) == 0) - goto drop; - (void) m_free(m); /* generic header */ - sorwakeup(last); - goto next; drop: m_freem(m); goto next; } +raw_ctlinput(cmd, arg) + int cmd; + caddr_t arg; +{ +COUNT(RAW_CTLINPUT); +} + /*ARGSUSED*/ raw_usrreq(so, req, m, addr) struct socket *so; @@ -172,8 +168,10 @@ COUNT(RAW_USRREQ); * the appropriate raw interface routine. */ case PRU_ATTACH: + if ((so->so_state & SS_PRIV) == 0) + return (EACCES); if (rp) - return (EINVAL);; + return (EINVAL); error = raw_attach(so, (struct sockaddr *)addr); break; @@ -194,14 +192,14 @@ COUNT(RAW_USRREQ); * nothing else around it should go to). */ case PRU_CONNECT: - if (rp->rcb_flags & RAW_ADDR) + if (rp->rcb_flags & RAW_FADDR) return (EISCONN); raw_connaddr(rp, (struct sockaddr *)addr); 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); @@ -220,14 +218,14 @@ COUNT(RAW_USRREQ); */ case PRU_SEND: if (addr) { - if (rp->rcb_flags & RAW_ADDR) + if (rp->rcb_flags & RAW_FADDR) return (EISCONN); raw_connaddr(rp, (struct sockaddr *)addr); - } else if ((rp->rcb_flags & RAW_ADDR) == 0) + } else if ((rp->rcb_flags & RAW_FADDR) == 0) return (ENOTCONN); - (void) (*so->so_proto->pr_output)(m, so); + error = (*so->so_proto->pr_output)(m, so); if (addr) - rp->rcb_flags &= ~RAW_ADDR; + rp->rcb_flags &= ~RAW_FADDR; break; case PRU_ABORT: @@ -248,6 +246,10 @@ COUNT(RAW_USRREQ); error = EOPNOTSUPP; break; + case PRU_SOCKADDR: + bcopy(addr, (caddr_t)&rp->rcb_laddr, sizeof (struct sockaddr)); + break; + default: panic("raw_usrreq"); }