diff options
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if.c | 4 | ||||
-rw-r--r-- | sys/net/raw_cb.c | 2 | ||||
-rw-r--r-- | sys/net/raw_cb.h | 6 | ||||
-rw-r--r-- | sys/net/raw_usrreq.c | 306 | ||||
-rw-r--r-- | sys/net/rtsock.c | 227 |
5 files changed, 336 insertions, 209 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index b1f7087..115cd64 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)if.c 8.3 (Berkeley) 1/4/94 - * $Id: if.c,v 1.45 1997/02/14 15:30:54 wollman Exp $ + * $Id: if.c,v 1.46 1997/03/24 11:33:08 bde Exp $ */ #include <sys/param.h> @@ -640,7 +640,7 @@ ifioctl(so, cmd, data, p) error = ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, - ifp)); + ifp, p)); switch (ocmd) { case OSIOCGIFADDR: diff --git a/sys/net/raw_cb.c b/sys/net/raw_cb.c index 5b39bc0..9db18a3 100644 --- a/sys/net/raw_cb.c +++ b/sys/net/raw_cb.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)raw_cb.c 8.1 (Berkeley) 6/10/93 - * $Id: raw_cb.c,v 1.10 1997/02/22 09:41:13 peter Exp $ + * $Id: raw_cb.c,v 1.11 1997/04/14 18:23:22 phk Exp $ */ #include <sys/param.h> diff --git a/sys/net/raw_cb.h b/sys/net/raw_cb.h index bff3989..2cc5ccc 100644 --- a/sys/net/raw_cb.h +++ b/sys/net/raw_cb.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)raw_cb.h 8.1 (Berkeley) 6/10/93 - * $Id: raw_cb.h,v 1.7 1997/02/22 09:41:13 peter Exp $ + * $Id: raw_cb.h,v 1.8 1997/04/14 18:23:23 phk Exp $ */ #ifndef _NET_RAW_CB_H_ @@ -67,8 +67,8 @@ void raw_disconnect __P((struct rawcb *)); void raw_init __P((void)); void raw_input __P((struct mbuf *, struct sockproto *, struct sockaddr *, struct sockaddr *)); -int raw_usrreq __P((struct socket *, - int, struct mbuf *, struct mbuf *, struct mbuf *)); + +extern struct pr_usrreqs raw_usrreqs; #endif #endif 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 +}; diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 36afca9..ae1a900 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -31,9 +31,10 @@ * SUCH DAMAGE. * * @(#)rtsock.c 8.5 (Berkeley) 11/2/94 - * $Id$ + * $Id: rtsock.c,v 1.26 1997/02/22 09:41:15 peter Exp $ */ + #include <sys/param.h> #include <sys/queue.h> #include <sys/systm.h> @@ -69,8 +70,6 @@ static void rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *)); static int sysctl_dumpentry __P((struct radix_node *rn, void *vw)); static int sysctl_iflist __P((int af, struct walkarg *w)); static int route_output __P((struct mbuf *, struct socket *)); -static int route_usrreq __P((struct socket *, - int, struct mbuf *, struct mbuf *, struct mbuf *)); static void rt_setmetrics __P((u_long, struct rt_metrics *, struct rt_metrics *)); /* Sleazy use of local variables throughout file, warning!!!! */ @@ -82,62 +81,191 @@ static void rt_setmetrics __P((u_long, struct rt_metrics *, struct rt_metrics * #define ifaaddr info.rti_info[RTAX_IFA] #define brdaddr info.rti_info[RTAX_BRD] -/*ARGSUSED*/ +/* + * It really doesn't make any sense at all for this code to share much + * with raw_usrreq.c, since its functionality is so restricted. XXX + */ +static int +rts_abort(struct socket *so) +{ + int s, error; + s = splnet(); + error = raw_usrreqs.pru_abort(so); + splx(s); + return error; +} + +/* pru_accept is EOPNOTSUPP */ + static int -route_usrreq(so, req, m, nam, control) - register struct socket *so; - int req; - struct mbuf *m, *nam, *control; +rts_attach(struct socket *so, int proto, struct proc *p) { - register int error = 0; - register struct rawcb *rp = sotorawcb(so); - int s; - - if (req == PRU_ATTACH) { - MALLOC(rp, struct rawcb *, sizeof(*rp), M_PCB, M_WAITOK); - so->so_pcb = (caddr_t)rp; - if (so->so_pcb) - bzero(so->so_pcb, sizeof(*rp)); + struct rawcb *rp; + int s, error; + + if (sotorawcb(so) != 0) + return EISCONN; /* XXX panic? */ + MALLOC(rp, struct rawcb *, sizeof *rp, M_PCB, M_WAITOK); /* XXX */ + if (rp == 0) + return ENOBUFS; + bzero(rp, sizeof *rp); + + /* + * The splnet() is necessary to block protocols from sending + * error notifications (like RTM_REDIRECT or RTM_LOSING) while + * this PCB is extant but incompletely initialized. + * Probably we should try to do more of this work beforehand and + * eliminate the spl. + */ + s = splnet(); + so->so_pcb = (caddr_t)rp; + error = raw_usrreqs.pru_attach(so, proto, p); + rp = sotorawcb(so); + if (error) { + splx(s); + free(rp, M_PCB); + return error; + } + switch(rp->rcb_proto.sp_protocol) { + case AF_INET: + route_cb.ip_count++; + break; + case AF_IPX: + route_cb.ipx_count++; + break; + case AF_NS: + route_cb.ns_count++; + break; + case AF_ISO: + route_cb.iso_count++; + break; } - if (req == PRU_DETACH && rp) { - int af = rp->rcb_proto.sp_protocol; - if (af == AF_INET) + rp->rcb_faddr = &route_src; + route_cb.any_count++; + soisconnected(so); + so->so_options |= SO_USELOOPBACK; + splx(s); + return 0; +} + +static int +rts_bind(struct socket *so, struct mbuf *nam, struct proc *p) +{ + int s, error; + s = splnet(); + error = raw_usrreqs.pru_bind(so, nam, p); /* xxx just EINVAL */ + splx(s); + return error; +} + +static int +rts_connect(struct socket *so, struct mbuf *nam, struct proc *p) +{ + int s, error; + s = splnet(); + error = raw_usrreqs.pru_connect(so, nam, p); /* XXX just EINVAL */ + splx(s); + return error; +} + +/* pru_connect2 is EOPNOTSUPP */ +/* pru_control is EOPNOTSUPP */ + +static int +rts_detach(struct socket *so) +{ + struct rawcb *rp = sotorawcb(so); + int s, error; + + s = splnet(); + if (rp != 0) { + switch(rp->rcb_proto.sp_protocol) { + case AF_INET: route_cb.ip_count--; - else if (af == AF_IPX) + break; + case AF_IPX: route_cb.ipx_count--; - else if (af == AF_NS) + break; + case AF_NS: route_cb.ns_count--; - else if (af == AF_ISO) + break; + case AF_ISO: route_cb.iso_count--; + break; + } route_cb.any_count--; } + error = raw_usrreqs.pru_detach(so); + splx(s); + return error; +} + +static int +rts_disconnect(struct socket *so) +{ + int s, error; s = splnet(); - error = raw_usrreq(so, req, m, nam, control); - rp = sotorawcb(so); - if (req == PRU_ATTACH && rp) { - int af = rp->rcb_proto.sp_protocol; - if (error) { - free((caddr_t)rp, M_PCB); - splx(s); - return (error); - } - if (af == AF_INET) - route_cb.ip_count++; - else if (af == AF_IPX) - route_cb.ipx_count++; - else if (af == AF_NS) - route_cb.ns_count++; - else if (af == AF_ISO) - route_cb.iso_count++; - rp->rcb_faddr = &route_src; - route_cb.any_count++; - soisconnected(so); - so->so_options |= SO_USELOOPBACK; - } + error = raw_usrreqs.pru_disconnect(so); splx(s); - return (error); + return error; } +/* pru_listen is EOPNOTSUPP */ + +static int +rts_peeraddr(struct socket *so, struct mbuf *nam) +{ + int s, error; + s = splnet(); + error = raw_usrreqs.pru_peeraddr(so, nam); + splx(s); + return error; +} + +/* pru_rcvd is EOPNOTSUPP */ +/* pru_rcvoob is EOPNOTSUPP */ + +static int +rts_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct proc *p) +{ + int s, error; + s = splnet(); + error = raw_usrreqs.pru_send(so, flags, m, nam, control, p); + splx(s); + return error; +} + +/* pru_sense is null */ + +static int +rts_shutdown(struct socket *so) +{ + int s, error; + s = splnet(); + error = raw_usrreqs.pru_shutdown(so); + splx(s); + return error; +} + +static int +rts_sockaddr(struct socket *so, struct mbuf *nam) +{ + int s, error; + s = splnet(); + error = raw_usrreqs.pru_sockaddr(so, nam); + splx(s); + return error; +} + +static struct pr_usrreqs route_usrreqs = { + rts_abort, pru_accept_notsupp, rts_attach, rts_bind, rts_connect, + pru_connect2_notsupp, pru_control_notsupp, rts_detach, rts_disconnect, + pru_listen_notsupp, rts_peeraddr, pru_rcvd_notsupp, pru_rcvoob_notsupp, + rts_send, pru_sense_null, rts_shutdown, rts_sockaddr, + sosend, soreceive, soselect +}; + /*ARGSUSED*/ static int route_output(m, so) @@ -811,7 +939,7 @@ sysctl_rtsock SYSCTL_HANDLER_ARGS return (error); } -SYSCTL_NODE(_net, PF_ROUTE, routetable, CTLFLAG_RD, sysctl_rtsock,""); +SYSCTL_NODE(_net, PF_ROUTE, routetable, CTLFLAG_RD, sysctl_rtsock, ""); /* * Definitions of protocols supported in the ROUTE domain. @@ -822,8 +950,9 @@ extern struct domain routedomain; /* or at least forward */ static struct protosw routesw[] = { { SOCK_RAW, &routedomain, 0, PR_ATOMIC|PR_ADDR, 0, route_output, raw_ctlinput, 0, - route_usrreq, - raw_init + 0, + raw_init, 0, 0, 0, + &route_usrreqs } }; |