summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if.c4
-rw-r--r--sys/net/raw_cb.c2
-rw-r--r--sys/net/raw_cb.h6
-rw-r--r--sys/net/raw_usrreq.c306
-rw-r--r--sys/net/rtsock.c227
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
}
};
OpenPOWER on IntegriCloud