diff options
Diffstat (limited to 'sys/net/raw_usrreq.c')
-rw-r--r-- | sys/net/raw_usrreq.c | 306 |
1 files changed, 152 insertions, 154 deletions
diff --git a/sys/net/raw_usrreq.c b/sys/net/raw_usrreq.c index ae7729f..9ec02fb 100644 --- a/sys/net/raw_usrreq.c +++ b/sys/net/raw_usrreq.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)raw_usrreq.c 8.1 (Berkeley) 6/10/93 - * $Id: raw_usrreq.c,v 1.10 1997/02/22 09:41:14 peter Exp $ + * $Id: raw_usrreq.c,v 1.11 1997/04/14 18:23:25 phk Exp $ */ #include <sys/param.h> @@ -39,6 +39,7 @@ #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/domain.h> +#include <sys/proc.h> #include <sys/protosw.h> #include <sys/socket.h> #include <sys/socketvar.h> @@ -140,175 +141,172 @@ raw_ctlinput(cmd, arg, dummy) /* INCOMPLETE */ } -/*ARGSUSED*/ -int -raw_usrreq(so, req, m, nam, control) - struct socket *so; - int req; - struct mbuf *m, *nam, *control; +static int +raw_uabort(struct socket *so) { - register struct rawcb *rp = sotorawcb(so); - register int error = 0; - int len; + struct rawcb *rp = sotorawcb(so); - if (req == PRU_CONTROL) - return (EOPNOTSUPP); - if (control && control->m_len) { - error = EOPNOTSUPP; - goto release; + if (rp == 0) + return EINVAL; + raw_disconnect(rp); + sofree(so); + soisdisconnected(so); + return 0; +} + +/* pru_accept is EOPNOTSUPP */ + +static int +raw_uattach(struct socket *so, int proto, struct proc *p) +{ + struct rawcb *rp = sotorawcb(so); + int error; + + if (rp == 0) + return EINVAL; + if (p && (error = suser(p->p_ucred, &p->p_acflag)) != 0) + return error; + return raw_attach(so, proto); +} + +static int +raw_ubind(struct socket *so, struct mbuf *nam, struct proc *p) +{ + return EINVAL; +} + +static int +raw_uconnect(struct socket *so, struct mbuf *nam, struct proc *p) +{ + return EINVAL; +} + +/* pru_connect2 is EOPNOTSUPP */ +/* pru_control is EOPNOTSUPP */ + +static int +raw_udetach(struct socket *so) +{ + struct rawcb *rp = sotorawcb(so); + + if (rp == 0) + return EINVAL; + + raw_detach(rp); + return 0; +} + +static int +raw_udisconnect(struct socket *so) +{ + struct rawcb *rp = sotorawcb(so); + + if (rp == 0) + return EINVAL; + if (rp->rcb_faddr == 0) { + return ENOTCONN; + } + raw_disconnect(rp); + soisdisconnected(so); + return 0; +} + +/* pru_listen is EOPNOTSUPP */ + +static int +raw_upeeraddr(struct socket *so, struct mbuf *nam) +{ + struct rawcb *rp = sotorawcb(so); + unsigned len; + + if (rp == 0) + return EINVAL; + if (rp->rcb_faddr == 0) { + return ENOTCONN; } + len = rp->rcb_faddr->sa_len; + bcopy((caddr_t)rp->rcb_faddr, mtod(nam, caddr_t), len); + nam->m_len = len; + return 0; +} + +/* pru_rcvd is EOPNOTSUPP */ +/* pru_rcvoob is EOPNOTSUPP */ + +static int +raw_usend(struct socket *so, int flags, struct mbuf *m, + struct mbuf *nam, struct mbuf *control, struct proc *p) +{ + int error; + struct rawcb *rp = sotorawcb(so); + if (rp == 0) { error = EINVAL; goto release; } - switch (req) { - - /* - * Allocate a raw control block and fill in the - * necessary info to allow packets to be routed to - * the appropriate raw interface routine. - */ - case PRU_ATTACH: - if ((so->so_state & SS_PRIV) == 0) { - error = EACCES; - break; - } - error = raw_attach(so, (int)nam); - break; - - /* - * Destroy state just before socket deallocation. - * Flush data or not depending on the options. - */ - case PRU_DETACH: - if (rp == 0) { - error = ENOTCONN; - break; - } - raw_detach(rp); - break; - - /* - * If a socket isn't bound to a single address, - * the raw input routine will hand it anything - * within that protocol family (assuming there's - * nothing else around it should go to). - */ - case PRU_CONNECT: - error = EINVAL; -#if 0 - if (rp->rcb_faddr) { - error = EISCONN; - break; - } - nam = m_copym(nam, 0, M_COPYALL, M_WAIT); - rp->rcb_faddr = mtod(nam, struct sockaddr *); - soisconnected(so); -#endif - break; - - case PRU_BIND: - error = EINVAL; -#if 0 - if (rp->rcb_laddr) { - error = EINVAL; /* XXX */ - break; - } - error = raw_bind(so, nam); -#endif - break; - case PRU_CONNECT2: + if (flags & PRUS_OOB) { error = EOPNOTSUPP; goto release; + } - case PRU_DISCONNECT: - if (rp->rcb_faddr == 0) { - error = ENOTCONN; - break; - } - raw_disconnect(rp); - soisdisconnected(so); - break; - - /* - * Mark the connection as being incapable of further input. - */ - case PRU_SHUTDOWN: - socantsendmore(so); - break; - - /* - * Ship a packet out. The appropriate raw output - * routine handles any massaging necessary. - */ - case PRU_SEND: - if (nam) { - if (rp->rcb_faddr) { - error = EISCONN; - break; - } - rp->rcb_faddr = mtod(nam, struct sockaddr *); - } else if (rp->rcb_faddr == 0) { - error = ENOTCONN; - break; - } - error = (*so->so_proto->pr_output)(m, so); - m = NULL; - if (nam) - rp->rcb_faddr = 0; - break; - - case PRU_ABORT: - raw_disconnect(rp); - sofree(so); - soisdisconnected(so); - break; - - case PRU_SENSE: - /* - * stat: don't bother with a blocksize. - */ - return (0); - - /* - * Not supported. - */ - case PRU_RCVOOB: - case PRU_RCVD: - return(EOPNOTSUPP); - - case PRU_LISTEN: - case PRU_ACCEPT: - case PRU_SENDOOB: + if (control && control->m_len) { error = EOPNOTSUPP; - break; - - case PRU_SOCKADDR: - if (rp->rcb_laddr == 0) { - error = EINVAL; - break; - } - len = rp->rcb_laddr->sa_len; - bcopy((caddr_t)rp->rcb_laddr, mtod(nam, caddr_t), (unsigned)len); - nam->m_len = len; - break; - - case PRU_PEERADDR: - if (rp->rcb_faddr == 0) { - error = ENOTCONN; - break; + goto release; + } + if (nam) { + if (rp->rcb_faddr) { + error = EISCONN; + goto release; } - len = rp->rcb_faddr->sa_len; - bcopy((caddr_t)rp->rcb_faddr, mtod(nam, caddr_t), (unsigned)len); - nam->m_len = len; - break; - - default: - panic("raw_usrreq"); + rp->rcb_faddr = mtod(nam, struct sockaddr *); + } else if (rp->rcb_faddr == 0) { + error = ENOTCONN; + goto release; } + error = (*so->so_proto->pr_output)(m, so); + m = NULL; + if (nam) + rp->rcb_faddr = 0; release: if (m != NULL) m_freem(m); return (error); } + +/* pru_sense is null */ + +static int +raw_ushutdown(struct socket *so) +{ + struct rawcb *rp = sotorawcb(so); + + if (rp == 0) + return EINVAL; + socantsendmore(so); + return 0; +} + +static int +raw_usockaddr(struct socket *so, struct mbuf *nam) +{ + struct rawcb *rp = sotorawcb(so); + unsigned len; + + if (rp == 0) + return EINVAL; + if (rp->rcb_laddr == 0) + return EINVAL; + len = rp->rcb_laddr->sa_len; + bcopy((caddr_t)rp->rcb_laddr, mtod(nam, caddr_t), len); + nam->m_len = len; + return 0; +} + +struct pr_usrreqs raw_usrreqs = { + raw_uabort, pru_accept_notsupp, raw_uattach, raw_ubind, raw_uconnect, + pru_connect2_notsupp, pru_control_notsupp, raw_udetach, + raw_udisconnect, pru_listen_notsupp, raw_upeeraddr, pru_rcvd_notsupp, + pru_rcvoob_notsupp, raw_usend, pru_sense_null, raw_ushutdown, + raw_usockaddr, sosend, soreceive, soselect +}; |