aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett Wollman <wollman@FreeBSD.org>1998-08-23 03:07:17 +0000
committerGarrett Wollman <wollman@FreeBSD.org>1998-08-23 03:07:17 +0000
commitcfe8b629f1f13b06fa1aec801248b7e431e48aba (patch)
tree3eeab04394efe1f50741907aeba96200abbaf6d2
parentbdad325c19fcba9b0c6bd42495fa1ae0eda6c2fb (diff)
downloadsrc-cfe8b629f1f13b06fa1aec801248b7e431e48aba.tar.gz
src-cfe8b629f1f13b06fa1aec801248b7e431e48aba.zip
Notes
-rw-r--r--sys/kern/uipc_proto.c3
-rw-r--r--sys/kern/uipc_socket.c245
-rw-r--r--sys/kern/uipc_syscalls.c78
-rw-r--r--sys/net/if_vlan.c6
-rw-r--r--sys/netinet/in.h17
-rw-r--r--sys/netinet/in_proto.c11
-rw-r--r--sys/netinet/ip_fw.c268
-rw-r--r--sys/netinet/ip_fw.h19
-rw-r--r--sys/netinet/ip_input.c7
-rw-r--r--sys/netinet/ip_mroute.c297
-rw-r--r--sys/netinet/ip_mroute.h8
-rw-r--r--sys/netinet/ip_output.c395
-rw-r--r--sys/netinet/ip_var.h14
-rw-r--r--sys/netinet/raw_ip.c190
-rw-r--r--sys/netinet/tcp_usrreq.c117
-rw-r--r--sys/netinet/tcp_var.h5
-rw-r--r--sys/netipx/ipx_ip.c26
-rw-r--r--sys/netipx/ipx_ip.h4
-rw-r--r--sys/netipx/ipx_usrreq.c91
-rw-r--r--sys/netipx/ipx_var.h6
-rw-r--r--sys/netipx/spx.h5
-rw-r--r--sys/netipx/spx_usrreq.c110
-rw-r--r--sys/nfs/bootp_subr.c46
-rw-r--r--sys/nfs/krpc_subr.c40
-rw-r--r--sys/nfs/nfs.h4
-rw-r--r--sys/nfs/nfs_socket.c32
-rw-r--r--sys/nfs/nfs_syscalls.c30
-rw-r--r--sys/nfsclient/bootp_subr.c46
-rw-r--r--sys/nfsclient/krpc_subr.c40
-rw-r--r--sys/nfsclient/nfs.h4
-rw-r--r--sys/nfsclient/nfs_nfsiod.c30
-rw-r--r--sys/nfsclient/nfs_socket.c32
-rw-r--r--sys/nfsclient/nfsargs.h4
-rw-r--r--sys/nfsclient/nfsstats.h4
-rw-r--r--sys/nfsserver/nfs.h4
-rw-r--r--sys/nfsserver/nfs_srvsock.c32
-rw-r--r--sys/nfsserver/nfs_syscalls.c30
-rw-r--r--sys/nfsserver/nfsrvstats.h4
-rw-r--r--sys/sys/mbuf.h14
-rw-r--r--sys/sys/protosw.h12
-rw-r--r--sys/sys/socketvar.h31
41 files changed, 1238 insertions, 1123 deletions
diff --git a/sys/kern/uipc_proto.c b/sys/kern/uipc_proto.c
index d87e14826b09..094d1bf16bbb 100644
--- a/sys/kern/uipc_proto.c
+++ b/sys/kern/uipc_proto.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_proto.c 8.1 (Berkeley) 6/10/93
- * $Id: uipc_proto.c,v 1.15 1998/05/15 20:11:29 wollman Exp $
+ * $Id: uipc_proto.c,v 1.16 1998/06/21 14:53:18 bde Exp $
*/
#include <sys/param.h>
@@ -41,6 +41,7 @@
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/un.h>
+#include <sys/unpcb.h>
#include <net/raw_cb.h>
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 5abd6fe48e33..f429434fea12 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
- * $Id: uipc_socket.c,v 1.41 1998/07/06 19:27:14 fenner Exp $
+ * $Id: uipc_socket.c,v 1.42 1998/07/18 18:48:45 fenner Exp $
*/
#include <sys/param.h>
@@ -898,31 +898,69 @@ sorflush(so)
sbrelease(&asb);
}
+/*
+ * Perhaps this routine, and sooptcopyout(), below, ought to come in
+ * an additional variant to handle the case where the option value needs
+ * to be some kind of integer, but not a specific size.
+ * In addition to their use here, these functions are also called by the
+ * protocol-level pr_ctloutput() routines.
+ */
int
-sosetopt(so, level, optname, m0, p)
- register struct socket *so;
- int level, optname;
- struct mbuf *m0;
- struct proc *p;
+sooptcopyin(sopt, buf, len, minlen)
+ struct sockopt *sopt;
+ void *buf;
+ size_t len;
+ size_t minlen;
{
- int error = 0;
- register struct mbuf *m = m0;
+ size_t valsize;
+
+ /*
+ * If the user gives us more than we wanted, we ignore it,
+ * but if we don't get the minimum length the caller
+ * wants, we return EINVAL. On success, sopt->sopt_valsize
+ * is set to however much we actually retrieved.
+ */
+ if ((valsize = sopt->sopt_valsize) < minlen)
+ return EINVAL;
+ if (valsize > len)
+ sopt->sopt_valsize = valsize = len;
+
+ if (sopt->sopt_p != 0)
+ return (copyin(sopt->sopt_val, buf, valsize));
- if (level != SOL_SOCKET) {
+ bcopy(sopt->sopt_val, buf, valsize);
+ return 0;
+}
+
+int
+sosetopt(so, sopt)
+ struct socket *so;
+ struct sockopt *sopt;
+{
+ int error, optval;
+ struct linger l;
+ struct timeval tv;
+ short val;
+
+ error = 0;
+ if (sopt->sopt_level != SOL_SOCKET) {
if (so->so_proto && so->so_proto->pr_ctloutput)
return ((*so->so_proto->pr_ctloutput)
- (PRCO_SETOPT, so, level, optname, &m0, p));
+ (so, sopt));
error = ENOPROTOOPT;
} else {
- switch (optname) {
-
+ switch (sopt->sopt_name) {
case SO_LINGER:
- if (m == NULL || m->m_len != sizeof (struct linger)) {
- error = EINVAL;
+ error = sooptcopyin(sopt, &l, sizeof l, sizeof l);
+ if (error)
goto bad;
- }
- so->so_linger = mtod(m, struct linger *)->l_linger;
- /* fall thru... */
+
+ so->so_linger = l.l_linger;
+ if (l.l_onoff)
+ so->so_options |= SO_LINGER;
+ else
+ so->so_options &= ~SO_LINGER;
+ break;
case SO_DEBUG:
case SO_KEEPALIVE:
@@ -933,45 +971,40 @@ sosetopt(so, level, optname, m0, p)
case SO_REUSEPORT:
case SO_OOBINLINE:
case SO_TIMESTAMP:
- if (m == NULL || m->m_len < sizeof (int)) {
- error = EINVAL;
+ error = sooptcopyin(sopt, &optval, sizeof optval,
+ sizeof optval);
+ if (error)
goto bad;
- }
- if (*mtod(m, int *))
- so->so_options |= optname;
+ if (optval)
+ so->so_options |= sopt->sopt_name;
else
- so->so_options &= ~optname;
+ so->so_options &= ~sopt->sopt_name;
break;
case SO_SNDBUF:
case SO_RCVBUF:
case SO_SNDLOWAT:
case SO_RCVLOWAT:
- {
- int optval;
-
- if (m == NULL || m->m_len < sizeof (int)) {
- error = EINVAL;
+ error = sooptcopyin(sopt, &optval, sizeof optval,
+ sizeof optval);
+ if (error)
goto bad;
- }
/*
* Values < 1 make no sense for any of these
* options, so disallow them.
*/
- optval = *mtod(m, int *);
if (optval < 1) {
error = EINVAL;
goto bad;
}
- switch (optname) {
-
+ switch (sopt->sopt_name) {
case SO_SNDBUF:
case SO_RCVBUF:
- if (sbreserve(optname == SO_SNDBUF ?
- &so->so_snd : &so->so_rcv,
- (u_long) optval) == 0) {
+ if (sbreserve(sopt->sopt_name == SO_SNDBUF ?
+ &so->so_snd : &so->so_rcv,
+ (u_long) optval) == 0) {
error = ENOBUFS;
goto bad;
}
@@ -993,27 +1026,21 @@ sosetopt(so, level, optname, m0, p)
break;
}
break;
- }
case SO_SNDTIMEO:
case SO_RCVTIMEO:
- {
- struct timeval *tv;
- short val;
-
- if (m == NULL || m->m_len < sizeof (*tv)) {
- error = EINVAL;
+ error = sooptcopyin(sopt, &tv, sizeof tv,
+ sizeof tv);
+ if (error)
goto bad;
- }
- tv = mtod(m, struct timeval *);
- if (tv->tv_sec > SHRT_MAX / hz - hz) {
+
+ if (tv.tv_sec > SHRT_MAX / hz - hz) {
error = EDOM;
goto bad;
}
- val = tv->tv_sec * hz + tv->tv_usec / tick;
-
- switch (optname) {
+ val = tv.tv_sec * hz + tv.tv_usec / tick;
+ switch (sopt->sopt_name) {
case SO_SNDTIMEO:
so->so_snd.sb_timeo = val;
break;
@@ -1022,7 +1049,6 @@ sosetopt(so, level, optname, m0, p)
break;
}
break;
- }
default:
error = ENOPROTOOPT;
@@ -1030,42 +1056,69 @@ sosetopt(so, level, optname, m0, p)
}
if (error == 0 && so->so_proto && so->so_proto->pr_ctloutput) {
(void) ((*so->so_proto->pr_ctloutput)
- (PRCO_SETOPT, so, level, optname, &m0, p));
- m = NULL; /* freed by protocol */
+ (so, sopt));
}
}
bad:
- if (m)
- (void) m_free(m);
return (error);
}
+/* Helper routine for getsockopt */
int
-sogetopt(so, level, optname, mp, p)
- register struct socket *so;
- int level, optname;
- struct mbuf **mp;
- struct proc *p;
+sooptcopyout(sopt, buf, len)
+ struct sockopt *sopt;
+ void *buf;
+ size_t len;
{
- register struct mbuf *m;
+ int error;
+ size_t valsize;
+
+ error = 0;
+
+ /*
+ * Documented get behavior is that we always return a value,
+ * possibly truncated to fit in the user's buffer.
+ * We leave the correct length in sopt->sopt_valsize,
+ * to be copied out in getsockopt(). Note that this
+ * interface is not idempotent; the entire answer must
+ * generated ahead of time.
+ */
+ valsize = len;
+ if (sopt->sopt_valsize < valsize) {
+ valsize = sopt->sopt_valsize;
+ sopt->sopt_valsize = len;
+ }
+ if (sopt->sopt_val != 0) {
+ if (sopt->sopt_p != 0)
+ error = copyout(buf, sopt->sopt_val, valsize);
+ else
+ bcopy(buf, sopt->sopt_val, valsize);
+ }
+ return error;
+}
+
+int
+sogetopt(so, sopt)
+ struct socket *so;
+ struct sockopt *sopt;
+{
+ int error, optval;
+ struct linger l;
+ struct timeval tv;
- if (level != SOL_SOCKET) {
+ error = 0;
+ if (sopt->sopt_level != SOL_SOCKET) {
if (so->so_proto && so->so_proto->pr_ctloutput) {
return ((*so->so_proto->pr_ctloutput)
- (PRCO_GETOPT, so, level, optname, mp, p));
+ (so, sopt));
} else
return (ENOPROTOOPT);
} else {
- m = m_get(M_WAIT, MT_SOOPTS);
- m->m_len = sizeof (int);
-
- switch (optname) {
-
+ switch (sopt->sopt_name) {
case SO_LINGER:
- m->m_len = sizeof (struct linger);
- mtod(m, struct linger *)->l_onoff =
- so->so_options & SO_LINGER;
- mtod(m, struct linger *)->l_linger = so->so_linger;
+ l.l_onoff = so->so_options & SO_LINGER;
+ l.l_linger = so->so_linger;
+ error = sooptcopyout(sopt, &l, sizeof l);
break;
case SO_USELOOPBACK:
@@ -1077,53 +1130,51 @@ sogetopt(so, level, optname, mp, p)
case SO_BROADCAST:
case SO_OOBINLINE:
case SO_TIMESTAMP:
- *mtod(m, int *) = so->so_options & optname;
+ optval = so->so_options & sopt->sopt_name;
+integer:
+ error = sooptcopyout(sopt, &optval, sizeof optval);
break;
case SO_TYPE:
- *mtod(m, int *) = so->so_type;
- break;
+ optval = so->so_type;
+ goto integer;
case SO_ERROR:
- *mtod(m, int *) = so->so_error;
+ optval = so->so_error;
so->so_error = 0;
- break;
+ goto integer;
case SO_SNDBUF:
- *mtod(m, int *) = so->so_snd.sb_hiwat;
- break;
+ optval = so->so_snd.sb_hiwat;
+ goto integer;
case SO_RCVBUF:
- *mtod(m, int *) = so->so_rcv.sb_hiwat;
- break;
+ optval = so->so_rcv.sb_hiwat;
+ goto integer;
case SO_SNDLOWAT:
- *mtod(m, int *) = so->so_snd.sb_lowat;
- break;
+ optval = so->so_snd.sb_lowat;
+ goto integer;
case SO_RCVLOWAT:
- *mtod(m, int *) = so->so_rcv.sb_lowat;
- break;
+ optval = so->so_rcv.sb_lowat;
+ goto integer;
case SO_SNDTIMEO:
case SO_RCVTIMEO:
- {
- int val = (optname == SO_SNDTIMEO ?
- so->so_snd.sb_timeo : so->so_rcv.sb_timeo);
-
- m->m_len = sizeof(struct timeval);
- mtod(m, struct timeval *)->tv_sec = val / hz;
- mtod(m, struct timeval *)->tv_usec =
- (val % hz) * tick;
- break;
- }
+ optval = (sopt->sopt_name == SO_SNDTIMEO ?
+ so->so_snd.sb_timeo : so->so_rcv.sb_timeo);
+
+ tv.tv_sec = optval / hz;
+ tv.tv_usec = (optval % hz) * tick;
+ error = sooptcopyout(sopt, &tv, sizeof tv);
+ break;
default:
- (void)m_free(m);
- return (ENOPROTOOPT);
+ error = ENOPROTOOPT;
+ break;
}
- *mp = m;
- return (0);
+ return (error);
}
}
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index db764de593a9..a841bfad18c7 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94
- * $Id: uipc_syscalls.c,v 1.39 1998/04/14 06:24:43 phk Exp $
+ * $Id: uipc_syscalls.c,v 1.40 1998/06/10 10:30:23 dfr Exp $
*/
#include "opt_compat.h"
@@ -981,34 +981,26 @@ setsockopt(p, uap)
} */ *uap;
{
struct file *fp;
- struct mbuf *m = NULL;
+ struct sockopt sopt;
int error;
+ if (uap->val == 0 && uap->valsize != 0)
+ return (EFAULT);
+ if (uap->valsize < 0)
+ return (EINVAL);
+
error = getsock(p->p_fd, uap->s, &fp);
if (error)
return (error);
- if (uap->valsize > MCLBYTES)
- return (EINVAL);
- if (uap->val) {
- m = m_get(M_WAIT, MT_SOOPTS);
- if (m == NULL)
- return (ENOBUFS);
- if (uap->valsize > MLEN) {
- MCLGET(m, M_WAIT);
- if(!(m->m_flags & M_EXT)) {
- m_free(m);
- return (ENOBUFS);
- }
- }
- error = copyin(uap->val, mtod(m, caddr_t), (u_int)uap->valsize);
- if (error) {
- (void) m_free(m);
- return (error);
- }
- m->m_len = uap->valsize;
- }
- return (sosetopt((struct socket *)fp->f_data, uap->level,
- uap->name, m, p));
+
+ sopt.sopt_dir = SOPT_SET;
+ sopt.sopt_level = uap->level;
+ sopt.sopt_name = uap->name;
+ sopt.sopt_val = uap->val;
+ sopt.sopt_valsize = uap->valsize;
+ sopt.sopt_p = p;
+
+ return (sosetopt((struct socket *)fp->f_data, &sopt));
}
/* ARGSUSED */
@@ -1023,9 +1015,9 @@ getsockopt(p, uap)
int *avalsize;
} */ *uap;
{
- struct file *fp;
- struct mbuf *m = NULL, *m0;
- int op, i, valsize, error;
+ int valsize, error;
+ struct file *fp;
+ struct sockopt sopt;
error = getsock(p->p_fd, uap->s, &fp);
if (error)
@@ -1035,26 +1027,24 @@ getsockopt(p, uap)
sizeof (valsize));
if (error)
return (error);
+ if (valsize < 0)
+ return (EINVAL);
} else
valsize = 0;
- if ((error = sogetopt((struct socket *)fp->f_data, uap->level,
- uap->name, &m, p)) == 0 && uap->val && valsize && m != NULL) {
- op = 0;
- while (m && !error && op < valsize) {
- i = min(m->m_len, (valsize - op));
- error = copyout(mtod(m, caddr_t), uap->val, (u_int)i);
- op += i;
- uap->val += i;
- m0 = m;
- MFREE(m0,m);
- }
- valsize = op;
- if (error == 0)
- error = copyout((caddr_t)&valsize,
- (caddr_t)uap->avalsize, sizeof (valsize));
+
+ sopt.sopt_dir = SOPT_GET;
+ sopt.sopt_level = uap->level;
+ sopt.sopt_name = uap->name;
+ sopt.sopt_val = uap->val;
+ sopt.sopt_valsize = (size_t)valsize; /* checked non-negative above */
+ sopt.sopt_p = p;
+
+ error = sogetopt((struct socket *)fp->f_data, &sopt);
+ if (error == 0) {
+ valsize = sopt.sopt_valsize;
+ error = copyout((caddr_t)&valsize,
+ (caddr_t)uap->avalsize, sizeof (valsize));
}
- if (m != NULL)
- (void) m_free(m);
return (error);
}
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index b41e7e40d8f0..d6149e9175e1 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -26,7 +26,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: if_vlan.c,v 1.1 1998/03/18 01:40:12 wollman Exp $
+ * $Id: if_vlan.c,v 1.2 1998/05/15 20:02:47 wollman Exp $
*/
/*
@@ -80,7 +80,7 @@ static struct ifvlan ifv_softc[NVLAN];
static void vlan_start(struct ifnet *ifp);
static void vlan_ifinit(void *foo);
-static int vlan_ioctl(struct ifnet *ifp, int cmd, caddr_t addr);
+static int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr);
static void
vlaninit(void *dummy)
@@ -262,7 +262,7 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p)
}
static int
-vlan_ioctl(struct ifnet *ifp, int cmd, caddr_t data)
+vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
struct ifaddr *ifa;
struct ifnet *p;
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index 145018558def..67e58515775b 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)in.h 8.3 (Berkeley) 1/3/94
- * $Id: in.h,v 1.35 1998/06/06 20:45:25 julian Exp $
+ * $Id: in.h,v 1.36 1998/07/06 03:20:12 julian Exp $
*/
#ifndef _NETINET_IN_H_
@@ -429,21 +429,6 @@ int in_cksum __P((struct mbuf *, int));
int in_localaddr __P((struct in_addr));
char *inet_ntoa __P((struct in_addr)); /* in libkern */
-/* Firewall hooks */
-struct ip;
-typedef int ip_fw_chk_t __P((struct ip**, int, struct ifnet*, u_int16_t*, struct mbuf**, struct sockaddr_in**));
-typedef int ip_fw_ctl_t __P((int, struct mbuf**));
-extern ip_fw_chk_t *ip_fw_chk_ptr;
-extern ip_fw_ctl_t *ip_fw_ctl_ptr;
-
-/* IP NAT hooks */
-typedef int ip_nat_t __P((struct ip**, struct mbuf**, struct ifnet*, int));
-typedef int ip_nat_ctl_t __P((int, struct mbuf**));
-extern ip_nat_t *ip_nat_ptr;
-extern ip_nat_ctl_t *ip_nat_ctl_ptr;
-#define IP_NAT_IN 0x00000001
-#define IP_NAT_OUT 0x00000002
-
#endif /* KERNEL */
#endif
diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c
index de7d67d1194f..2976056a5854 100644
--- a/sys/netinet/in_proto.c
+++ b/sys/netinet/in_proto.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)in_proto.c 8.2 (Berkeley) 2/9/95
- * $Id: in_proto.c,v 1.45 1997/12/15 20:31:11 eivind Exp $
+ * $Id: in_proto.c,v 1.46 1998/03/21 11:33:57 peter Exp $
*/
#include "opt_ipdivert.h"
@@ -71,15 +71,6 @@
#include <netns/ns_if.h>
#endif
-#ifdef TPIP
-void tpip_input(), tpip_ctlinput(), tp_init(), tp_slowtimo(), tp_drain();
-int tp_ctloutput(), tp_usrreq();
-#endif
-
-#ifdef EON
-void eoninput(), eonctlinput(), eonprotoinit();
-#endif /* EON */
-
extern struct domain inetdomain;
static struct pr_usrreqs nousrreqs;
diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c
index 5ef7ec657bb4..6376389951c1 100644
--- a/sys/netinet/ip_fw.c
+++ b/sys/netinet/ip_fw.c
@@ -12,7 +12,7 @@
*
* This software is provided ``AS IS'' without any warranties of any kind.
*
- * $Id: ip_fw.c,v 1.94 1998/08/03 17:23:37 dfr Exp $
+ * $Id: ip_fw.c,v 1.95 1998/08/11 19:08:42 bde Exp $
*/
/*
@@ -34,6 +34,7 @@
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
+#include <sys/socketvar.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <netinet/in.h>
@@ -60,6 +61,8 @@ static int fw_verbose_limit = IPFIREWALL_VERBOSE_LIMIT;
static int fw_verbose_limit = 0;
#endif
+#define IPFW_DEFAULT_RULE ((u_int)(u_short)~0)
+
static LIST_HEAD (ip_fw_head, ip_fw_chain) ip_fw_chain;
static MALLOC_DEFINE(M_IPFW, "IpFw/IpAcct", "IpFw/IpAcct chain's");
@@ -83,9 +86,8 @@ SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit, CTLFLAG_RW, &fw_verbose_lim
static int add_entry __P((struct ip_fw_head *chainptr, struct ip_fw *frwl));
static int del_entry __P((struct ip_fw_head *chainptr, u_short number));
-static int zero_entry __P((struct mbuf *m));
-static struct ip_fw *check_ipfw_struct __P((struct ip_fw *m));
-static struct ip_fw *check_ipfw_mbuf __P((struct mbuf *fw));
+static int zero_entry __P((struct ip_fw *));
+static int check_ipfw_struct __P((struct ip_fw *m));
static __inline int
iface_match __P((struct ifnet *ifp, union ip_fw_if *ifu,
int byname));
@@ -106,7 +108,7 @@ static ip_fw_ctl_t *old_ctl_ptr;
static int ip_fw_chk __P((struct ip **pip, int hlen,
struct ifnet *oif, u_int16_t *cookie, struct mbuf **m,
struct sockaddr_in **next_hop));
-static int ip_fw_ctl __P((int stage, struct mbuf **mm));
+static int ip_fw_ctl __P((struct sockopt *sopt));
static char err_prefix[] = "ip_fw_ctl:";
@@ -424,7 +426,7 @@ ip_fw_chk(struct ip **pip, int hlen,
*/
chain = LIST_FIRST(&ip_fw_chain);
if ( skipto ) {
- if (skipto >= 65535)
+ if (skipto >= IPFW_DEFAULT_RULE)
goto dropit;
while (chain && (chain->rule->fw_number <= skipto)) {
chain = LIST_NEXT(chain, chain);
@@ -645,7 +647,7 @@ got_match:
}
#ifdef DIAGNOSTIC
- /* Rule 65535 should always be there and should always match */
+ /* Rule IPFW_DEFAULT_RULE should always be there and should always match */
if (!chain)
panic("ip_fw: chain");
#endif
@@ -734,16 +736,10 @@ add_entry(struct ip_fw_head *chainptr, struct ip_fw *frwl)
s = splnet();
- if (!LIST_FIRST(chainptr)) {
+ if (chainptr->lh_first == 0) {
LIST_INSERT_HEAD(chainptr, fwc, chain);
splx(s);
return(0);
- } else if (ftmp->fw_number == (u_short)-1) {
- if (fwc) free(fwc, M_IPFW);
- if (ftmp) free(ftmp, M_IPFW);
- splx(s);
- dprintf(("%s bad rule number\n", err_prefix));
- return (EINVAL);
}
/* If entry number is 0, find highest numbered rule and add 100 */
@@ -754,7 +750,7 @@ add_entry(struct ip_fw_head *chainptr, struct ip_fw *frwl)
else
break;
}
- if (nbr < (u_short)-1 - 100)
+ if (nbr < IPFW_DEFAULT_RULE - 100)
nbr += 100;
ftmp->fw_number = nbr;
}
@@ -809,21 +805,12 @@ del_entry(struct ip_fw_head *chainptr, u_short number)
}
static int
-zero_entry(struct mbuf *m)
+zero_entry(struct ip_fw *frwl)
{
- struct ip_fw *frwl;
struct ip_fw_chain *fcp;
- int s;
-
- if (m) {
- if (m->m_len != sizeof(struct ip_fw))
- return(EINVAL);
- frwl = mtod(m, struct ip_fw *);
- }
- else
- frwl = NULL;
+ int s, cleared;
- if (!frwl) {
+ if (frwl == 0) {
s = splnet();
for (fcp = LIST_FIRST(&ip_fw_chain); fcp; fcp = LIST_NEXT(fcp, chain)) {
fcp->rule->fw_bcnt = fcp->rule->fw_pcnt = 0;
@@ -832,7 +819,7 @@ zero_entry(struct mbuf *m)
splx(s);
}
else {
- int cleared = 0;
+ cleared = 0;
/*
* It's possible to insert multiple chain entries with the
@@ -851,8 +838,8 @@ zero_entry(struct mbuf *m)
cleared = 1;
break;
}
- if (!cleared)
- return(EINVAL); /* we didn't find any matching rules */
+ if (!cleared) /* we didn't find any matching rules */
+ return (EINVAL);
}
if (fw_verbose) {
@@ -862,34 +849,22 @@ zero_entry(struct mbuf *m)
printf("ipfw: Accounting cleared.\n");
}
- return(0);
-}
-
-static struct ip_fw *
-check_ipfw_mbuf(struct mbuf *m)
-{
- /* Check length */
- if (m->m_len != sizeof(struct ip_fw)) {
- dprintf(("%s len=%d, want %d\n", err_prefix, m->m_len,
- sizeof(struct ip_fw)));
- return (NULL);
- }
- return(check_ipfw_struct(mtod(m, struct ip_fw *)));
+ return (0);
}
-static struct ip_fw *
+static int
check_ipfw_struct(struct ip_fw *frwl)
{
/* Check for invalid flag bits */
if ((frwl->fw_flg & ~IP_FW_F_MASK) != 0) {
dprintf(("%s undefined flag bits set (flags=%x)\n",
err_prefix, frwl->fw_flg));
- return (NULL);
+ return (EINVAL);
}
/* Must apply to incoming or outgoing (or both) */
if (!(frwl->fw_flg & (IP_FW_F_IN | IP_FW_F_OUT))) {
dprintf(("%s neither in nor out\n", err_prefix));
- return (NULL);
+ return (EINVAL);
}
/* Empty interface name is no good */
if (((frwl->fw_flg & IP_FW_F_IIFNAME)
@@ -897,7 +872,7 @@ check_ipfw_struct(struct ip_fw *frwl)
|| ((frwl->fw_flg & IP_FW_F_OIFNAME)
&& !*frwl->fw_out_if.fu_via_if.name)) {
dprintf(("%s empty interface name\n", err_prefix));
- return (NULL);
+ return (EINVAL);
}
/* Sanity check interface matching */
if ((frwl->fw_flg & IF_FW_F_VIAHACK) == IF_FW_F_VIAHACK) {
@@ -906,23 +881,23 @@ check_ipfw_struct(struct ip_fw *frwl)
&& (frwl->fw_flg & IP_FW_F_OIFACE)) {
dprintf(("%s outgoing interface check on incoming\n",
err_prefix));
- return (NULL);
+ return (EINVAL);
}
/* Sanity check port ranges */
if ((frwl->fw_flg & IP_FW_F_SRNG) && IP_FW_GETNSRCP(frwl) < 2) {
dprintf(("%s src range set but n_src_p=%d\n",
err_prefix, IP_FW_GETNSRCP(frwl)));
- return (NULL);
+ return (EINVAL);
}
if ((frwl->fw_flg & IP_FW_F_DRNG) && IP_FW_GETNDSTP(frwl) < 2) {
dprintf(("%s dst range set but n_dst_p=%d\n",
err_prefix, IP_FW_GETNDSTP(frwl)));
- return (NULL);
+ return (EINVAL);
}
if (IP_FW_GETNSRCP(frwl) + IP_FW_GETNDSTP(frwl) > IP_FW_MAX_PORTS) {
dprintf(("%s too many ports (%d+%d)\n",
err_prefix, IP_FW_GETNSRCP(frwl), IP_FW_GETNDSTP(frwl)));
- return (NULL);
+ return (EINVAL);
}
/*
* Protocols other than TCP/UDP don't use port range
@@ -932,7 +907,7 @@ check_ipfw_struct(struct ip_fw *frwl)
(IP_FW_GETNSRCP(frwl) || IP_FW_GETNDSTP(frwl))) {
dprintf(("%s port(s) specified for non TCP/UDP rule\n",
err_prefix));
- return(NULL);
+ return (EINVAL);
}
/*
@@ -943,19 +918,19 @@ check_ipfw_struct(struct ip_fw *frwl)
if ((frwl->fw_src.s_addr & (~frwl->fw_smsk.s_addr)) ||
(frwl->fw_dst.s_addr & (~frwl->fw_dmsk.s_addr))) {
dprintf(("%s rule never matches\n", err_prefix));
- return(NULL);
+ return (EINVAL);
}
if ((frwl->fw_flg & IP_FW_F_FRAG) &&
(frwl->fw_prot == IPPROTO_UDP || frwl->fw_prot == IPPROTO_TCP)) {
if (frwl->fw_nports) {
dprintf(("%s cannot mix 'frag' and ports\n", err_prefix));
- return(NULL);
+ return (EINVAL);
}
if (frwl->fw_prot == IPPROTO_TCP &&
frwl->fw_tcpf != frwl->fw_tcpnf) {
dprintf(("%s cannot mix 'frag' and TCP flags\n", err_prefix));
- return(NULL);
+ return (EINVAL);
}
}
@@ -967,14 +942,14 @@ check_ipfw_struct(struct ip_fw *frwl)
&& !(frwl->fw_prot == IPPROTO_TCP
&& frwl->fw_reject_code == IP_FW_REJECT_RST)) {
dprintf(("%s unknown reject code\n", err_prefix));
- return(NULL);
+ return (EINVAL);
}
break;
case IP_FW_F_DIVERT: /* Diverting to port zero is invalid */
case IP_FW_F_TEE:
if (frwl->fw_divert_port == 0) {
dprintf(("%s can't divert to port 0\n", err_prefix));
- return (NULL);
+ return (EINVAL);
}
break;
case IP_FW_F_DENY:
@@ -987,117 +962,102 @@ check_ipfw_struct(struct ip_fw *frwl)
break;
default:
dprintf(("%s invalid command\n", err_prefix));
- return(NULL);
+ return (EINVAL);
}
- return frwl;
+ return 0;
}
static int
-ip_fw_ctl(int stage, struct mbuf **mm)
+ip_fw_ctl(struct sockopt *sopt)
{
- int error;
- /*
- * If we have any number of rules, then it's worth while
- * using clusters for this. The smaller case is rare.
- * Note that using clusters for setsockopt is only in 3.0 at this time.
- */
- struct mbuf *m;
-
- if (stage == IP_FW_GET) {
- /*
- * If we have any number of rules, then it's worth while
- * using clusters for this. The smaller case is rare.
- * Note that using clusters for setsockopt is only in
- * 3.0 at this time.
- */
- struct ip_fw_chain *fcp = LIST_FIRST(&ip_fw_chain);
- *mm = m = m_get(M_WAIT, MT_SOOPTS);
- if (m == NULL)
- return (ENOBUFS);
- MCLGET(m, M_WAIT);
- if (!(m->m_flags & M_EXT)) {
-abort: m_freem(*mm);
- *mm = NULL;
- return (ENOBUFS);
+ int error, s;
+ size_t size;
+ char *buf, *bp;
+ struct ip_fw_chain *fcp;
+ struct ip_fw frwl;
+
+ /* Disallow sets in really-really secure mode. */
+ if (sopt->sopt_dir == SOPT_SET && securelevel >= 3)
+ return (EPERM);
+ error = 0;
+
+ switch (sopt->sopt_name) {
+ case IP_FW_GET:
+ for (fcp = LIST_FIRST(&ip_fw_chain), size = 0; fcp;
+ fcp = LIST_NEXT(fcp, chain))
+ size += sizeof *fcp->rule;
+ buf = malloc(size, M_TEMP, M_WAITOK);
+ if (buf == 0) {
+ error = ENOBUFS;
+ break;
}
- m->m_len = 0;
- for (; fcp; fcp = LIST_NEXT(fcp, chain)) {
- /* Will we need a new cluster? */
- if ((m->m_len + sizeof *(fcp->rule)) > MCLBYTES) {
- m = m->m_next = m_get(M_WAIT, MT_SOOPTS);
- if (m == NULL) {
- goto abort;
- }
- MCLGET(m, M_WAIT);
- if (!(m->m_flags & M_EXT)) {
- goto abort;
- }
- m->m_len = 0;
- }
- memcpy(m->m_data + m->m_len, fcp->rule,
- sizeof *(fcp->rule));
- m->m_len += sizeof *(fcp->rule);
+
+ for (fcp = LIST_FIRST(&ip_fw_chain), bp = buf; fcp;
+ fcp = LIST_NEXT(fcp, chain)) {
+ bcopy(fcp->rule, bp, sizeof *fcp->rule);
+ bp += sizeof *fcp->rule;
}
- return (0);
- }
- m = *mm;
- /* only allow get calls if secure mode > 2 */
- if (securelevel > 2) {
- if (m) (void)m_free(m);
- return(EPERM);
- }
- if (stage == IP_FW_FLUSH) {
- while (LIST_FIRST(&ip_fw_chain) != NULL &&
- LIST_FIRST(&ip_fw_chain)->rule->fw_number != (u_short)-1) {
- struct ip_fw_chain *fcp = LIST_FIRST(&ip_fw_chain);
- int s = splnet();
- LIST_REMOVE(LIST_FIRST(&ip_fw_chain), chain);
+ error = sooptcopyout(sopt, buf, size);
+ FREE(buf, M_TEMP);
+ break;
+
+ case IP_FW_FLUSH:
+ for (fcp = ip_fw_chain.lh_first;
+ fcp != 0 && fcp->rule->fw_number != IPFW_DEFAULT_RULE;
+ fcp = ip_fw_chain.lh_first) {
+ s = splnet();
+ LIST_REMOVE(fcp, chain);
+ FREE(fcp->rule, M_IPFW);
+ FREE(fcp, M_IPFW);
splx(s);
- free(fcp->rule, M_IPFW);
- free(fcp, M_IPFW);
}
- if (m) (void)m_free(m);
- return (0);
- }
- if (stage == IP_FW_ZERO) {
- error = zero_entry(m);
- if (m) (void)m_free(m);
- return (error);
- }
- if (m == NULL) {
- printf("%s NULL mbuf ptr\n", err_prefix);
- return (EINVAL);
- }
+ break;
- if (stage == IP_FW_ADD) {
- struct ip_fw *frwl = check_ipfw_mbuf(m);
+ case IP_FW_ZERO:
+ if (sopt->sopt_val != 0) {
+ error = sooptcopyin(sopt, &frwl, sizeof frwl,
+ sizeof frwl);
+ if (error || (error = zero_entry(&frwl)))
+ break;
+ } else {
+ error = zero_entry(0);
+ }
+ break;
- if (!frwl)
- error = EINVAL;
- else
- error = add_entry(&ip_fw_chain, frwl);
- if (m) (void)m_free(m);
- return error;
- }
- if (stage == IP_FW_DEL) {
- if (m->m_len != sizeof(struct ip_fw)) {
- dprintf(("%s len=%d, want %d\n", err_prefix, m->m_len,
- sizeof(struct ip_fw)));
+ case IP_FW_ADD:
+ error = sooptcopyin(sopt, &frwl, sizeof frwl, sizeof frwl);
+ if (error || (error = check_ipfw_struct(&frwl)))
+ break;
+
+ if (frwl.fw_number == IPFW_DEFAULT_RULE) {
+ dprintf(("%s can't add rule %u\n", err_prefix,
+ (unsigned)IPFW_DEFAULT_RULE));
error = EINVAL;
- } else if (mtod(m, struct ip_fw *)->fw_number == (u_short)-1) {
- dprintf(("%s can't delete rule 65535\n", err_prefix));
+ } else {
+ error = add_entry(&ip_fw_chain, &frwl);
+ }
+ break;
+
+ case IP_FW_DEL:
+ error = sooptcopyin(sopt, &frwl, sizeof frwl, sizeof frwl);
+ if (error)
+ break;
+
+ if (frwl.fw_number == IPFW_DEFAULT_RULE) {
+ dprintf(("%s can't delete rule %u\n", err_prefix,
+ (unsigned)IPFW_DEFAULT_RULE));
error = EINVAL;
- } else
- error = del_entry(&ip_fw_chain,
- mtod(m, struct ip_fw *)->fw_number);
- if (m) (void)m_free(m);
- return error;
+ } else {
+ error = del_entry(&ip_fw_chain, frwl.fw_number);
+ }
+ break;
+
+ default:
+ panic("ip_fw_ctl");
}
- dprintf(("%s unknown request %d\n", err_prefix, stage));
- if (m) (void)m_free(m);
- return (EINVAL);
+ return (error);
}
void
@@ -1111,14 +1071,14 @@ ip_fw_init(void)
bzero(&default_rule, sizeof default_rule);
default_rule.fw_prot = IPPROTO_IP;
- default_rule.fw_number = (u_short)-1;
+ default_rule.fw_number = IPFW_DEFAULT_RULE;
#ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
default_rule.fw_flg |= IP_FW_F_ACCEPT;
#else
default_rule.fw_flg |= IP_FW_F_DENY;
#endif
default_rule.fw_flg |= IP_FW_F_IN | IP_FW_F_OUT;
- if (check_ipfw_struct(&default_rule) == NULL ||
+ if (check_ipfw_struct(&default_rule) != 0 ||
add_entry(&ip_fw_chain, &default_rule))
panic("ip_fw_init");
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index 572d1b71fd9c..d903c57f1091 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -11,7 +11,7 @@
*
* This software is provided ``AS IS'' without any warranties of any kind.
*
- * $Id: ip_fw.h,v 1.32 1998/02/03 22:15:03 bde Exp $
+ * $Id: ip_fw.h,v 1.33 1998/07/06 03:20:15 julian Exp $
*/
#ifndef _IP_FW_H
@@ -184,6 +184,23 @@ struct ip_fw_chain {
*/
void ip_fw_init __P((void));
+/* Firewall hooks */
+struct ip;
+struct sockopt;
+typedef int ip_fw_chk_t __P((struct ip **, int, struct ifnet *, u_int16_t *,
+ struct mbuf **, struct sockaddr_in **));
+typedef int ip_fw_ctl_t __P((struct sockopt *));
+extern ip_fw_chk_t *ip_fw_chk_ptr;
+extern ip_fw_ctl_t *ip_fw_ctl_ptr;
+
+/* IP NAT hooks */
+typedef int ip_nat_t __P((struct ip **, struct mbuf **, struct ifnet *, int));
+typedef int ip_nat_ctl_t __P((struct sockopt *));
+extern ip_nat_t *ip_nat_ptr;
+extern ip_nat_ctl_t *ip_nat_ctl_ptr;
+#define IP_NAT_IN 0x00000001
+#define IP_NAT_OUT 0x00000002
+
#endif /* KERNEL */
#endif /* _IP_FW_H */
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 16d1abde6839..4527c0885403 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ip_input.c 8.2 (Berkeley) 1/4/94
- * $Id: ip_input.c,v 1.97 1998/07/13 12:12:24 bde Exp $
+ * $Id: ip_input.c,v 1.98 1998/08/17 01:05:24 bde Exp $
* $ANA: ip_input.c,v 1.5 1996/09/18 14:34:59 wollman Exp $
*/
@@ -142,6 +142,9 @@ SYSCTL_INT(_net_inet_ip, IPCTL_DEFMTU, mtu, CTLFLAG_RW,
#endif
#ifdef COMPAT_IPFW
+
+#include <netinet/ip_fw.h>
+
/* Firewall hooks */
ip_fw_chk_t *ip_fw_chk_ptr;
ip_fw_ctl_t *ip_fw_ctl_ptr;
@@ -1234,7 +1237,7 @@ ip_srcroute()
if (ip_nhops == 0)
return ((struct mbuf *)0);
- m = m_get(M_DONTWAIT, MT_SOOPTS);
+ m = m_get(M_DONTWAIT, MT_HEADER);
if (m == 0)
return ((struct mbuf *)0);
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index 1e64bb3e5596..3c11f8247274 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -9,7 +9,7 @@
* Modified by Bill Fenner, PARC, April 1995
*
* MROUTING Revision: 3.5
- * $Id: ip_mroute.c,v 1.47 1998/06/30 10:56:31 phk Exp $
+ * $Id: ip_mroute.c,v 1.48 1998/08/17 01:05:24 bde Exp $
*/
#include "opt_mrouting.h"
@@ -54,10 +54,8 @@ extern u_long _ip_mcast_src __P((int vifi));
extern int _ip_mforward __P((struct ip *ip, struct ifnet *ifp,
struct mbuf *m, struct ip_moptions *imo));
extern int _ip_mrouter_done __P((void));
-extern int _ip_mrouter_get __P((int cmd, struct socket *so,
- struct mbuf **m));
-extern int _ip_mrouter_set __P((int cmd, struct socket *so,
- struct mbuf *m));
+extern int _ip_mrouter_get __P((struct socket *so, struct sockopt *sopt));
+extern int _ip_mrouter_set __P((struct socket *so, struct sockopt *sopt));
extern int _mrt_ioctl __P((int req, caddr_t data, struct proc *p));
/*
@@ -70,27 +68,25 @@ static struct mrtstat mrtstat;
u_int rsvpdebug = 0;
int
-_ip_mrouter_set(cmd, so, m)
- int cmd;
+_ip_mrouter_set(so, sopt)
struct socket *so;
- struct mbuf *m;
+ struct sockopt *sopt;
{
return(EOPNOTSUPP);
}
-int (*ip_mrouter_set)(int, struct socket *, struct mbuf *) = _ip_mrouter_set;
+int (*ip_mrouter_set)(struct socket *, struct sockopt *) = _ip_mrouter_set;
int
-_ip_mrouter_get(cmd, so, m)
- int cmd;
+_ip_mrouter_get(so, sopt)
struct socket *so;
- struct mbuf **m;
+ struct sockopt *sopt;
{
return(EOPNOTSUPP);
}
-int (*ip_mrouter_get)(int, struct socket *, struct mbuf **) = _ip_mrouter_get;
+int (*ip_mrouter_get)(struct socket *, struct sockopt *) = _ip_mrouter_get;
int
_ip_mrouter_done()
@@ -161,17 +157,17 @@ _ip_mcast_src(int vifi) { return INADDR_ANY; }
u_long (*ip_mcast_src)(int) = _ip_mcast_src;
int
-ip_rsvp_vif_init(so, m)
+ip_rsvp_vif_init(so, sopt)
struct socket *so;
- struct mbuf *m;
+ struct sockopt *sopt;
{
return(EINVAL);
}
int
-ip_rsvp_vif_done(so, m)
+ip_rsvp_vif_done(so, sopt)
struct socket *so;
- struct mbuf *m;
+ struct sockopt *sopt;
{
return(EINVAL);
}
@@ -279,22 +275,20 @@ static struct vif *last_encap_vif;
static u_long X_ip_mcast_src __P((int vifi));
static int X_ip_mforward __P((struct ip *ip, struct ifnet *ifp, struct mbuf *m, struct ip_moptions *imo));
static int X_ip_mrouter_done __P((void));
-static int X_ip_mrouter_get __P((int cmd, struct socket *so, struct mbuf **m));
-static int X_ip_mrouter_set __P((int cmd, struct socket *so, struct mbuf *m));
+static int X_ip_mrouter_get __P((struct socket *so, struct sockopt *m));
+static int X_ip_mrouter_set __P((struct socket *so, struct sockopt *m));
static int X_legal_vif_num __P((int vif));
static int X_mrt_ioctl __P((int cmd, caddr_t data));
static int get_sg_cnt(struct sioc_sg_req *);
static int get_vif_cnt(struct sioc_vif_req *);
-static int ip_mrouter_init(struct socket *, struct mbuf *);
+static int ip_mrouter_init(struct socket *, int);
static int add_vif(struct vifctl *);
-static int del_vif(vifi_t *);
+static int del_vif(vifi_t);
static int add_mfc(struct mfcctl *);
static int del_mfc(struct mfcctl *);
static int socket_send(struct socket *, struct mbuf *, struct sockaddr_in *);
-static int get_version(struct mbuf *);
-static int get_assert(struct mbuf *);
-static int set_assert(int *);
+static int set_assert(int);
static void expire_upcalls(void *);
static int ip_mdq(struct mbuf *, struct ifnet *, struct mfc *,
vifi_t);
@@ -386,53 +380,102 @@ static void collate(struct timeval *);
* Handle MRT setsockopt commands to modify the multicast routing tables.
*/
static int
-X_ip_mrouter_set(cmd, so, m)
- int cmd;
- struct socket *so;
- struct mbuf *m;
+X_ip_mrouter_set(so, sopt)
+ struct socket *so;
+ struct sockopt *sopt;
{
- if (cmd != MRT_INIT && so != ip_mrouter) return EACCES;
+ int error, optval;
+ vifi_t vifi;
+ struct vifctl vifc;
+ struct mfcctl mfc;
+
+ if (so != ip_mrouter && sopt->sopt_name != MRT_INIT)
+ return (EPERM);
+
+ error = 0;
+ switch (sopt->sopt_name) {
+ case MRT_INIT:
+ error = sooptcopyin(sopt, &optval, sizeof optval,
+ sizeof optval);
+ if (error)
+ break;
+ error = ip_mrouter_init(so, optval);
+ break;
- switch (cmd) {
- case MRT_INIT: return ip_mrouter_init(so, m);
- case MRT_DONE: return ip_mrouter_done();
- case MRT_ADD_VIF: return add_vif (mtod(m, struct vifctl *));
- case MRT_DEL_VIF: return del_vif (mtod(m, vifi_t *));
- case MRT_ADD_MFC: return add_mfc (mtod(m, struct mfcctl *));
- case MRT_DEL_MFC: return del_mfc (mtod(m, struct mfcctl *));
- case MRT_ASSERT: return set_assert(mtod(m, int *));
- default: return EOPNOTSUPP;
- }
+ case MRT_DONE:
+ error = ip_mrouter_done();
+ break;
+
+ case MRT_ADD_VIF:
+ error = sooptcopyin(sopt, &vifc, sizeof vifc, sizeof vifc);
+ if (error)
+ break;
+ error = add_vif(&vifc);
+ break;
+
+ case MRT_DEL_VIF:
+ error = sooptcopyin(sopt, &vifi, sizeof vifi, sizeof vifi);
+ if (error)
+ break;
+ error = del_vif(vifi);
+ break;
+
+ case MRT_ADD_MFC:
+ case MRT_DEL_MFC:
+ error = sooptcopyin(sopt, &mfc, sizeof mfc, sizeof mfc);
+ if (error)
+ break;
+ if (sopt->sopt_name == MRT_ADD_MFC)
+ error = add_mfc(&mfc);
+ else
+ error = del_mfc(&mfc);
+
+ case MRT_ASSERT:
+ error = sooptcopyin(sopt, &optval, sizeof optval,
+ sizeof optval);
+ if (error)
+ break;
+ set_assert(optval);
+
+ default:
+ error = EOPNOTSUPP;
+ break;
+ }
+ return (error);
}
#ifndef MROUTE_LKM
-int (*ip_mrouter_set)(int, struct socket *, struct mbuf *) = X_ip_mrouter_set;
+int (*ip_mrouter_set)(struct socket *, struct sockopt *) = X_ip_mrouter_set;
#endif
/*
* Handle MRT getsockopt commands
*/
static int
-X_ip_mrouter_get(cmd, so, m)
- int cmd;
- struct socket *so;
- struct mbuf **m;
+X_ip_mrouter_get(so, sopt)
+ struct socket *so;
+ struct sockopt *sopt;
{
- struct mbuf *mb;
+ int error;
+ static int version = 0x0305; /* !!! why is this here? XXX */
- if (so != ip_mrouter) return EACCES;
+ switch (sopt->sopt_name) {
+ case MRT_VERSION:
+ error = sooptcopyout(sopt, &version, sizeof version);
+ break;
- *m = mb = m_get(M_WAIT, MT_SOOPTS);
-
- switch (cmd) {
- case MRT_VERSION: return get_version(mb);
- case MRT_ASSERT: return get_assert(mb);
- default: return EOPNOTSUPP;
- }
+ case MRT_ASSERT:
+ error = sooptcopyout(sopt, &pim_assert, sizeof pim_assert);
+ break;
+ default:
+ error = EOPNOTSUPP;
+ break;
+ }
+ return (error);
}
#ifndef MROUTE_LKM
-int (*ip_mrouter_get)(int, struct socket *, struct mbuf **) = X_ip_mrouter_get;
+int (*ip_mrouter_get)(struct socket *, struct sockopt *) = X_ip_mrouter_get;
#endif
/*
@@ -509,9 +552,9 @@ get_vif_cnt(req)
* Enable multicast routing
*/
static int
-ip_mrouter_init(so, m)
+ip_mrouter_init(so, version)
struct socket *so;
- struct mbuf *m;
+ int version;
{
int *v;
@@ -522,11 +565,7 @@ ip_mrouter_init(so, m)
if (so->so_type != SOCK_RAW ||
so->so_proto->pr_protocol != IPPROTO_IGMP) return EOPNOTSUPP;
- if (!m || (m->m_len != sizeof(int *)))
- return ENOPROTOOPT;
-
- v = mtod(m, int *);
- if (*v != 1)
+ if (version != 1)
return ENOPROTOOPT;
if (ip_mrouter != NULL) return EADDRINUSE;
@@ -626,47 +665,17 @@ X_ip_mrouter_done()
int (*ip_mrouter_done)(void) = X_ip_mrouter_done;
#endif
-static int
-get_version(mb)
- struct mbuf *mb;
-{
- int *v;
-
- v = mtod(mb, int *);
-
- *v = 0x0305; /* XXX !!!! */
- mb->m_len = sizeof(int);
-
- return 0;
-}
-
/*
* Set PIM assert processing global
*/
static int
set_assert(i)
- int *i;
+ int i;
{
- if ((*i != 1) && (*i != 0))
+ if ((i != 1) && (i != 0))
return EINVAL;
- pim_assert = *i;
-
- return 0;
-}
-
-/*
- * Get PIM assert processing global
- */
-static int
-get_assert(m)
- struct mbuf *m;
-{
- int *i;
-
- i = mtod(m, int *);
-
- *i = pim_assert;
+ pim_assert = i;
return 0;
}
@@ -777,17 +786,16 @@ add_vif(vifcp)
* Delete a vif from the vif table
*/
static int
-del_vif(vifip)
- vifi_t *vifip;
+del_vif(vifi)
+ vifi_t vifi;
{
- register struct vif *vifp = viftable + *vifip;
- register vifi_t vifi;
+ register struct vif *vifp = &viftable[vifi];
register struct mbuf *m;
struct ifnet *ifp;
struct ifreq ifr;
int s;
- if (*vifip >= numvifs) return EINVAL;
+ if (vifi >= numvifs) return EINVAL;
if (vifp->v_lcl_addr.s_addr == 0) return EADDRNOTAVAIL;
s = splnet();
@@ -816,6 +824,9 @@ del_vif(vifip)
bzero((caddr_t)vifp->v_tbf, sizeof(*(vifp->v_tbf)));
bzero((caddr_t)vifp, sizeof (*vifp));
+ if (mrtdebug)
+ log(LOG_DEBUG, "del_vif %d, numvifs %d\n", vifi, numvifs);
+
/* Adjust numvifs down */
for (vifi = numvifs; vifi > 0; vifi--)
if (viftable[vifi-1].v_lcl_addr.s_addr != 0) break;
@@ -823,9 +834,6 @@ del_vif(vifip)
splx(s);
- if (mrtdebug)
- log(LOG_DEBUG, "del_vif %d, numvifs %d\n", *vifip, numvifs);
-
return 0;
}
@@ -2009,12 +2017,11 @@ priority(vifp, ip)
*/
int
-ip_rsvp_vif_init(so, m)
- struct socket *so;
- struct mbuf *m;
+ip_rsvp_vif_init(so, sopt)
+ struct socket *so;
+ struct sockopt *sopt;
{
- int i;
- register int s;
+ int error, i, s;
if (rsvpdebug)
printf("ip_rsvp_vif_init: so_type = %d, pr_protocol = %d\n",
@@ -2024,13 +2031,12 @@ ip_rsvp_vif_init(so, m)
return EOPNOTSUPP;
/* Check mbuf. */
- if (m == NULL || m->m_len != sizeof(int)) {
- return EINVAL;
- }
- i = *(mtod(m, int *));
+ error = sooptcopyin(sopt, &i, sizeof i, sizeof i);
+ if (error)
+ return (error);
if (rsvpdebug)
- printf("ip_rsvp_vif_init: vif = %d rsvp_on = %d\n",i,rsvp_on);
+ printf("ip_rsvp_vif_init: vif = %d rsvp_on = %d\n", i, rsvp_on);
s = splnet();
@@ -2060,49 +2066,48 @@ ip_rsvp_vif_init(so, m)
}
int
-ip_rsvp_vif_done(so, m)
- struct socket *so;
- struct mbuf *m;
+ip_rsvp_vif_done(so, sopt)
+ struct socket *so;
+ struct sockopt *sopt;
{
- int i;
- register int s;
+ int error, i, s;
- if (rsvpdebug)
- printf("ip_rsvp_vif_done: so_type = %d, pr_protocol = %d\n",
- so->so_type, so->so_proto->pr_protocol);
+ if (rsvpdebug)
+ printf("ip_rsvp_vif_done: so_type = %d, pr_protocol = %d\n",
+ so->so_type, so->so_proto->pr_protocol);
- if (so->so_type != SOCK_RAW || so->so_proto->pr_protocol != IPPROTO_RSVP)
- return EOPNOTSUPP;
+ if (so->so_type != SOCK_RAW ||
+ so->so_proto->pr_protocol != IPPROTO_RSVP)
+ return EOPNOTSUPP;
- /* Check mbuf. */
- if (m == NULL || m->m_len != sizeof(int)) {
- return EINVAL;
- }
- i = *(mtod(m, int *));
+ error = sooptcopyin(sopt, &i, sizeof i, sizeof i);
+ if (error)
+ return (error);
- s = splnet();
+ s = splnet();
- /* Check vif. */
- if (!legal_vif_num(i)) {
- splx(s);
- return EADDRNOTAVAIL;
- }
+ /* Check vif. */
+ if (!legal_vif_num(i)) {
+ splx(s);
+ return EADDRNOTAVAIL;
+ }
- if (rsvpdebug)
- printf("ip_rsvp_vif_done: v_rsvpd = %p so = %p\n",
- viftable[i].v_rsvpd, so);
+ if (rsvpdebug)
+ printf("ip_rsvp_vif_done: v_rsvpd = %p so = %p\n",
+ viftable[i].v_rsvpd, so);
- viftable[i].v_rsvpd = NULL;
- /* This may seem silly, but we need to be sure we don't over-decrement
- * the RSVP counter, in case something slips up.
- */
- if (viftable[i].v_rsvp_on) {
- viftable[i].v_rsvp_on = 0;
- rsvp_on--;
- }
+ viftable[i].v_rsvpd = NULL;
+ /*
+ * This may seem silly, but we need to be sure we don't over-decrement
+ * the RSVP counter, in case something slips up.
+ */
+ if (viftable[i].v_rsvp_on) {
+ viftable[i].v_rsvp_on = 0;
+ rsvp_on--;
+ }
- splx(s);
- return 0;
+ splx(s);
+ return 0;
}
void
diff --git a/sys/netinet/ip_mroute.h b/sys/netinet/ip_mroute.h
index 5ddd6799d22e..94ddeac0608a 100644
--- a/sys/netinet/ip_mroute.h
+++ b/sys/netinet/ip_mroute.h
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* @(#)ip_mroute.h 8.1 (Berkeley) 6/10/93
- * $Id$
+ * $Id: ip_mroute.h,v 1.13 1997/02/22 09:41:35 peter Exp $
*/
#ifndef _NETINET_IP_MROUTE_H_
@@ -248,8 +248,10 @@ struct tbf
#ifdef KERNEL
-extern int (*ip_mrouter_set) __P((int, struct socket *, struct mbuf *));
-extern int (*ip_mrouter_get) __P((int, struct socket *, struct mbuf **));
+struct sockopt;
+
+extern int (*ip_mrouter_set) __P((struct socket *, struct sockopt *));
+extern int (*ip_mrouter_get) __P((struct socket *, struct sockopt *));
extern int (*ip_mrouter_done) __P((void));
#ifdef MROUTING
extern int (*mrt_ioctl) __P((int, caddr_t));
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 9202b2fc7118..4e6c64675358 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ip_output.c 8.3 (Berkeley) 1/21/94
- * $Id: ip_output.c,v 1.79 1998/07/13 12:12:25 bde Exp $
+ * $Id: ip_output.c,v 1.80 1998/08/01 08:44:33 peter Exp $
*/
#define _IP_VHL
@@ -72,6 +72,10 @@ static MALLOC_DEFINE(M_IPMOPTS, "ip_moptions", "internet multicast options");
#undef COMPAT_IPFW
#endif
+#ifdef COMPAT_IPFW
+#include <netinet/ip_fw.h>
+#endif
+
#ifdef IPFIREWALL_FORWARD_DEBUG
#define print_ip(a) printf("%ld.%ld.%ld.%ld",(ntohl(a.s_addr)>>24)&0xFF,\
(ntohl(a.s_addr)>>16)&0xFF,\
@@ -85,10 +89,10 @@ static struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *));
static void ip_mloopback
__P((struct ifnet *, struct mbuf *, struct sockaddr_in *, int));
static int ip_getmoptions
- __P((int, struct ip_moptions *, struct mbuf **));
-static int ip_pcbopts __P((struct mbuf **, struct mbuf *));
+ __P((struct sockopt *, struct ip_moptions *));
+static int ip_pcbopts __P((int, struct mbuf **, struct mbuf *));
static int ip_setmoptions
- __P((int, struct ip_moptions **, struct mbuf *));
+ __P((struct sockopt *, struct ip_moptions **));
#if defined(IPFILTER_LKM) || defined(IPFILTER)
int ip_optcopy __P((struct ip *, struct ip *));
@@ -742,33 +746,43 @@ ip_optcopy(ip, jp)
* IP socket option processing.
*/
int
-ip_ctloutput(op, so, level, optname, mp, p)
- int op;
+ip_ctloutput(so, sopt)
struct socket *so;
- int level, optname;
- struct mbuf **mp;
- struct proc *p;
+ struct sockopt *sopt;
{
- register struct inpcb *inp = sotoinpcb(so);
- register struct mbuf *m = *mp;
- register int optval = 0;
- int error = 0;
+ struct inpcb *inp = sotoinpcb(so);
+ int error, optval;
- if (level != IPPROTO_IP) {
- error = EINVAL;
- if (op == PRCO_SETOPT && *mp)
- (void) m_free(*mp);
- } else switch (op) {
+ error = optval = 0;
+ if (sopt->sopt_level != IPPROTO_IP) {
+ return (EINVAL);
+ }
- case PRCO_SETOPT:
- switch (optname) {
+ switch (sopt->sopt_dir) {
+ case SOPT_SET:
+ switch (sopt->sopt_name) {
case IP_OPTIONS:
#ifdef notyet
case IP_RETOPTS:
- return (ip_pcbopts(optname, &inp->inp_options, m));
-#else
- return (ip_pcbopts(&inp->inp_options, m));
#endif
+ {
+ struct mbuf *m;
+ if (sopt->sopt_valsize > MLEN) {
+ error = EMSGSIZE;
+ break;
+ }
+ MGET(m, sopt->sopt_p ? M_WAIT : M_DONTWAIT, MT_HEADER);
+ if (m == 0) {
+ error = ENOBUFS;
+ break;
+ }
+ m->m_len = sopt->sopt_valsize;
+ error = sooptcopyin(sopt, mtod(m, char *), m->m_len,
+ m->m_len);
+
+ return (ip_pcbopts(sopt->sopt_name, &inp->inp_options,
+ m));
+ }
case IP_TOS:
case IP_TTL:
@@ -776,41 +790,40 @@ ip_ctloutput(op, so, level, optname, mp, p)
case IP_RECVRETOPTS:
case IP_RECVDSTADDR:
case IP_RECVIF:
- if (m == 0 || m->m_len != sizeof(int))
- error = EINVAL;
- else {
- optval = *mtod(m, int *);
- switch (optname) {
+ error = sooptcopyin(sopt, &optval, sizeof optval,
+ sizeof optval);
+ if (error)
+ break;
- case IP_TOS:
- inp->inp_ip_tos = optval;
- break;
+ switch (sopt->sopt_name) {
+ case IP_TOS:
+ inp->inp_ip_tos = optval;
+ break;
- case IP_TTL:
- inp->inp_ip_ttl = optval;
- break;
+ case IP_TTL:
+ inp->inp_ip_ttl = optval;
+ break;
#define OPTSET(bit) \
if (optval) \
inp->inp_flags |= bit; \
else \
inp->inp_flags &= ~bit;
- case IP_RECVOPTS:
- OPTSET(INP_RECVOPTS);
- break;
+ case IP_RECVOPTS:
+ OPTSET(INP_RECVOPTS);
+ break;
- case IP_RECVRETOPTS:
- OPTSET(INP_RECVRETOPTS);
- break;
+ case IP_RECVRETOPTS:
+ OPTSET(INP_RECVRETOPTS);
+ break;
- case IP_RECVDSTADDR:
- OPTSET(INP_RECVDSTADDR);
- break;
+ case IP_RECVDSTADDR:
+ OPTSET(INP_RECVDSTADDR);
+ break;
- case IP_RECVIF:
- OPTSET(INP_RECVIF);
- break;
- }
+ case IP_RECVIF:
+ OPTSET(INP_RECVIF);
+ break;
}
break;
#undef OPTSET
@@ -821,36 +834,34 @@ ip_ctloutput(op, so, level, optname, mp, p)
case IP_MULTICAST_LOOP:
case IP_ADD_MEMBERSHIP:
case IP_DROP_MEMBERSHIP:
- error = ip_setmoptions(optname, &inp->inp_moptions, m);
+ error = ip_setmoptions(sopt, &inp->inp_moptions);
break;
case IP_PORTRANGE:
- if (m == 0 || m->m_len != sizeof(int))
- error = EINVAL;
- else {
- optval = *mtod(m, int *);
-
- switch (optval) {
+ error = sooptcopyin(sopt, &optval, sizeof optval,
+ sizeof optval);
+ if (error)
+ break;
- case IP_PORTRANGE_DEFAULT:
- inp->inp_flags &= ~(INP_LOWPORT);
- inp->inp_flags &= ~(INP_HIGHPORT);
- break;
+ switch (optval) {
+ case IP_PORTRANGE_DEFAULT:
+ inp->inp_flags &= ~(INP_LOWPORT);
+ inp->inp_flags &= ~(INP_HIGHPORT);
+ break;
- case IP_PORTRANGE_HIGH:
- inp->inp_flags &= ~(INP_LOWPORT);
- inp->inp_flags |= INP_HIGHPORT;
- break;
+ case IP_PORTRANGE_HIGH:
+ inp->inp_flags &= ~(INP_LOWPORT);
+ inp->inp_flags |= INP_HIGHPORT;
+ break;
- case IP_PORTRANGE_LOW:
- inp->inp_flags &= ~(INP_HIGHPORT);
- inp->inp_flags |= INP_LOWPORT;
- break;
+ case IP_PORTRANGE_LOW:
+ inp->inp_flags &= ~(INP_HIGHPORT);
+ inp->inp_flags |= INP_LOWPORT;
+ break;
- default:
- error = EINVAL;
- break;
- }
+ default:
+ error = EINVAL;
+ break;
}
break;
@@ -858,21 +869,19 @@ ip_ctloutput(op, so, level, optname, mp, p)
error = ENOPROTOOPT;
break;
}
- if (m)
- (void)m_free(m);
break;
- case PRCO_GETOPT:
- switch (optname) {
+ case SOPT_GET:
+ switch (sopt->sopt_name) {
case IP_OPTIONS:
case IP_RETOPTS:
- *mp = m = m_get(M_WAIT, MT_SOOPTS);
- if (inp->inp_options) {
- m->m_len = inp->inp_options->m_len;
- bcopy(mtod(inp->inp_options, void *),
- mtod(m, void *), m->m_len);
- } else
- m->m_len = 0;
+ if (inp->inp_options)
+ error = sooptcopyout(sopt,
+ mtod(inp->inp_options,
+ char *),
+ inp->inp_options->m_len);
+ else
+ sopt->sopt_valsize = 0;
break;
case IP_TOS:
@@ -881,9 +890,8 @@ ip_ctloutput(op, so, level, optname, mp, p)
case IP_RECVRETOPTS:
case IP_RECVDSTADDR:
case IP_RECVIF:
- *mp = m = m_get(M_WAIT, MT_SOOPTS);
- m->m_len = sizeof(int);
- switch (optname) {
+ case IP_PORTRANGE:
+ switch (sopt->sopt_name) {
case IP_TOS:
optval = inp->inp_ip_tos;
@@ -910,8 +918,17 @@ ip_ctloutput(op, so, level, optname, mp, p)
case IP_RECVIF:
optval = OPTBIT(INP_RECVIF);
break;
+
+ case IP_PORTRANGE:
+ if (inp->inp_flags & INP_HIGHPORT)
+ optval = IP_PORTRANGE_HIGH;
+ else if (inp->inp_flags & INP_LOWPORT)
+ optval = IP_PORTRANGE_LOW;
+ else
+ optval = 0;
+ break;
}
- *mtod(m, int *) = optval;
+ error = sooptcopyout(sopt, &optval, sizeof optval);
break;
case IP_MULTICAST_IF:
@@ -920,21 +937,7 @@ ip_ctloutput(op, so, level, optname, mp, p)
case IP_MULTICAST_LOOP:
case IP_ADD_MEMBERSHIP:
case IP_DROP_MEMBERSHIP:
- error = ip_getmoptions(optname, inp->inp_moptions, mp);
- break;
-
- case IP_PORTRANGE:
- *mp = m = m_get(M_WAIT, MT_SOOPTS);
- m->m_len = sizeof(int);
-
- if (inp->inp_flags & INP_HIGHPORT)
- optval = IP_PORTRANGE_HIGH;
- else if (inp->inp_flags & INP_LOWPORT)
- optval = IP_PORTRANGE_LOW;
- else
- optval = 0;
-
- *mtod(m, int *) = optval;
+ error = ip_getmoptions(sopt, inp->inp_moptions);
break;
default:
@@ -952,12 +955,8 @@ ip_ctloutput(op, so, level, optname, mp, p)
* with destination address if source routed.
*/
static int
-#ifdef notyet
ip_pcbopts(optname, pcbopt, m)
int optname;
-#else
-ip_pcbopts(pcbopt, m)
-#endif
struct mbuf **pcbopt;
register struct mbuf *m;
{
@@ -1054,23 +1053,28 @@ bad:
}
/*
+ * XXX
+ * The whole multicast option thing needs to be re-thought.
+ * Several of these options are equally applicable to non-multicast
+ * transmission, and one (IP_MULTICAST_TTL) totally duplicates a
+ * standard option (IP_TTL).
+ */
+/*
* Set the IP multicast options in response to user setsockopt().
*/
static int
-ip_setmoptions(optname, imop, m)
- int optname;
+ip_setmoptions(sopt, imop)
+ struct sockopt *sopt;
struct ip_moptions **imop;
- struct mbuf *m;
{
- register int error = 0;
- u_char loop;
- register int i;
+ int error = 0;
+ int i;
struct in_addr addr;
- register struct ip_mreq *mreq;
- register struct ifnet *ifp;
- register struct ip_moptions *imo = *imop;
+ struct ip_mreq mreq;
+ struct ifnet *ifp;
+ struct ip_moptions *imo = *imop;
struct route ro;
- register struct sockaddr_in *dst;
+ struct sockaddr_in *dst;
int s;
if (imo == NULL) {
@@ -1091,18 +1095,16 @@ ip_setmoptions(optname, imop, m)
imo->imo_num_memberships = 0;
}
- switch (optname) {
+ switch (sopt->sopt_name) {
/* store an index number for the vif you wanna use in the send */
case IP_MULTICAST_VIF:
- if (!legal_vif_num) {
+ if (legal_vif_num == 0) {
error = EOPNOTSUPP;
break;
}
- if (m == NULL || m->m_len != sizeof(int)) {
- error = EINVAL;
+ error = sooptcopyin(sopt, &i, sizeof i, sizeof i);
+ if (error)
break;
- }
- i = *(mtod(m, int *));
if (!legal_vif_num(i) && (i != -1)) {
error = EINVAL;
break;
@@ -1114,11 +1116,9 @@ ip_setmoptions(optname, imop, m)
/*
* Select the interface for outgoing multicast packets.
*/
- if (m == NULL || m->m_len != sizeof(struct in_addr)) {
- error = EINVAL;
+ error = sooptcopyin(sopt, &addr, sizeof addr, sizeof addr);
+ if (error)
break;
- }
- addr = *(mtod(m, struct in_addr *));
/*
* INADDR_ANY is used to remove a previous selection.
* When no interface is selected, a default one is
@@ -1147,25 +1147,50 @@ ip_setmoptions(optname, imop, m)
case IP_MULTICAST_TTL:
/*
* Set the IP time-to-live for outgoing multicast packets.
+ * The original multicast API required a char argument,
+ * which is inconsistent with the rest of the socket API.
+ * We allow either a char or an int.
*/
- if (m == NULL || m->m_len != 1) {
- error = EINVAL;
- break;
+ if (sopt->sopt_valsize == 1) {
+ u_char ttl;
+ error = sooptcopyin(sopt, &ttl, 1, 1);
+ if (error)
+ break;
+ imo->imo_multicast_ttl = ttl;
+ } else {
+ u_int ttl;
+ error = sooptcopyin(sopt, &ttl, sizeof ttl,
+ sizeof ttl);
+ if (error)
+ break;
+ if (ttl > 255)
+ error = EINVAL;
+ else
+ imo->imo_multicast_ttl = ttl;
}
- imo->imo_multicast_ttl = *(mtod(m, u_char *));
break;
case IP_MULTICAST_LOOP:
/*
* Set the loopback flag for outgoing multicast packets.
- * Must be zero or one.
+ * Must be zero or one. The original multicast API required a
+ * char argument, which is inconsistent with the rest
+ * of the socket API. We allow either a char or an int.
*/
- if (m == NULL || m->m_len != 1 ||
- (loop = *(mtod(m, u_char *))) > 1) {
- error = EINVAL;
- break;
+ if (sopt->sopt_valsize == 1) {
+ u_char loop;
+ error = sooptcopyin(sopt, &loop, 1, 1);
+ if (error)
+ break;
+ imo->imo_multicast_loop = !!loop;
+ } else {
+ u_int loop;
+ error = sooptcopyin(sopt, &loop, sizeof loop,
+ sizeof loop);
+ if (error)
+ break;
+ imo->imo_multicast_loop = !!loop;
}
- imo->imo_multicast_loop = loop;
break;
case IP_ADD_MEMBERSHIP:
@@ -1173,12 +1198,11 @@ ip_setmoptions(optname, imop, m)
* Add a multicast group membership.
* Group must be a valid IP multicast address.
*/
- if (m == NULL || m->m_len != sizeof(struct ip_mreq)) {
- error = EINVAL;
+ error = sooptcopyin(sopt, &mreq, sizeof mreq, sizeof mreq);
+ if (error)
break;
- }
- mreq = mtod(m, struct ip_mreq *);
- if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) {
+
+ if (!IN_MULTICAST(ntohl(mreq.imr_multiaddr.s_addr))) {
error = EINVAL;
break;
}
@@ -1187,12 +1211,12 @@ ip_setmoptions(optname, imop, m)
* If no interface address was provided, use the interface of
* the route to the given multicast address.
*/
- if (mreq->imr_interface.s_addr == INADDR_ANY) {
+ if (mreq.imr_interface.s_addr == INADDR_ANY) {
bzero((caddr_t)&ro, sizeof(ro));
dst = (struct sockaddr_in *)&ro.ro_dst;
dst->sin_len = sizeof(*dst);
dst->sin_family = AF_INET;
- dst->sin_addr = mreq->imr_multiaddr;
+ dst->sin_addr = mreq.imr_multiaddr;
rtalloc(&ro);
if (ro.ro_rt == NULL) {
error = EADDRNOTAVAIL;
@@ -1203,7 +1227,7 @@ ip_setmoptions(optname, imop, m)
rtfree(ro.ro_rt);
}
else {
- INADDR_TO_IFP(mreq->imr_interface, ifp);
+ INADDR_TO_IFP(mreq.imr_interface, ifp);
}
/*
@@ -1222,7 +1246,7 @@ ip_setmoptions(optname, imop, m)
for (i = 0; i < imo->imo_num_memberships; ++i) {
if (imo->imo_membership[i]->inm_ifp == ifp &&
imo->imo_membership[i]->inm_addr.s_addr
- == mreq->imr_multiaddr.s_addr)
+ == mreq.imr_multiaddr.s_addr)
break;
}
if (i < imo->imo_num_memberships) {
@@ -1240,7 +1264,7 @@ ip_setmoptions(optname, imop, m)
* address list for the given interface.
*/
if ((imo->imo_membership[i] =
- in_addmulti(&mreq->imr_multiaddr, ifp)) == NULL) {
+ in_addmulti(&mreq.imr_multiaddr, ifp)) == NULL) {
error = ENOBUFS;
splx(s);
break;
@@ -1254,12 +1278,11 @@ ip_setmoptions(optname, imop, m)
* Drop a multicast group membership.
* Group must be a valid IP multicast address.
*/
- if (m == NULL || m->m_len != sizeof(struct ip_mreq)) {
- error = EINVAL;
+ error = sooptcopyin(sopt, &mreq, sizeof mreq, sizeof mreq);
+ if (error)
break;
- }
- mreq = mtod(m, struct ip_mreq *);
- if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) {
+
+ if (!IN_MULTICAST(ntohl(mreq.imr_multiaddr.s_addr))) {
error = EINVAL;
break;
}
@@ -1269,10 +1292,10 @@ ip_setmoptions(optname, imop, m)
* If an interface address was specified, get a pointer
* to its ifnet structure.
*/
- if (mreq->imr_interface.s_addr == INADDR_ANY)
+ if (mreq.imr_interface.s_addr == INADDR_ANY)
ifp = NULL;
else {
- INADDR_TO_IFP(mreq->imr_interface, ifp);
+ INADDR_TO_IFP(mreq.imr_interface, ifp);
if (ifp == NULL) {
error = EADDRNOTAVAIL;
splx(s);
@@ -1286,7 +1309,7 @@ ip_setmoptions(optname, imop, m)
if ((ifp == NULL ||
imo->imo_membership[i]->inm_ifp == ifp) &&
imo->imo_membership[i]->inm_addr.s_addr ==
- mreq->imr_multiaddr.s_addr)
+ mreq.imr_multiaddr.s_addr)
break;
}
if (i == imo->imo_num_memberships) {
@@ -1332,57 +1355,63 @@ ip_setmoptions(optname, imop, m)
* Return the IP multicast options in response to user getsockopt().
*/
static int
-ip_getmoptions(optname, imo, mp)
- int optname;
+ip_getmoptions(sopt, imo)
+ struct sockopt *sopt;
register struct ip_moptions *imo;
- register struct mbuf **mp;
{
- u_char *ttl;
- u_char *loop;
- struct in_addr *addr;
+ struct in_addr addr;
struct in_ifaddr *ia;
+ int error, optval;
+ u_char coptval;
- *mp = m_get(M_WAIT, MT_SOOPTS);
-
- switch (optname) {
-
+ error = 0;
+ switch (sopt->sopt_name) {
case IP_MULTICAST_VIF:
if (imo != NULL)
- *(mtod(*mp, int *)) = imo->imo_multicast_vif;
+ optval = imo->imo_multicast_vif;
else
- *(mtod(*mp, int *)) = -1;
- (*mp)->m_len = sizeof(int);
- return(0);
+ optval = -1;
+ error = sooptcopyout(sopt, &optval, sizeof optval);
+ break;
case IP_MULTICAST_IF:
- addr = mtod(*mp, struct in_addr *);
- (*mp)->m_len = sizeof(struct in_addr);
if (imo == NULL || imo->imo_multicast_ifp == NULL)
- addr->s_addr = INADDR_ANY;
+ addr.s_addr = INADDR_ANY;
else {
IFP_TO_IA(imo->imo_multicast_ifp, ia);
- addr->s_addr = (ia == NULL) ? INADDR_ANY
- : IA_SIN(ia)->sin_addr.s_addr;
+ addr.s_addr = (ia == NULL) ? INADDR_ANY
+ : IA_SIN(ia)->sin_addr.s_addr;
}
- return (0);
+ error = sooptcopyout(sopt, &addr, sizeof addr);
+ break;
case IP_MULTICAST_TTL:
- ttl = mtod(*mp, u_char *);
- (*mp)->m_len = 1;
- *ttl = (imo == NULL) ? IP_DEFAULT_MULTICAST_TTL
- : imo->imo_multicast_ttl;
- return (0);
+ if (imo == 0)
+ optval = coptval = IP_DEFAULT_MULTICAST_TTL;
+ else
+ optval = coptval = imo->imo_multicast_ttl;
+ if (sopt->sopt_valsize == 1)
+ error = sooptcopyout(sopt, &coptval, 1);
+ else
+ error = sooptcopyout(sopt, &optval, sizeof optval);
+ break;
case IP_MULTICAST_LOOP:
- loop = mtod(*mp, u_char *);
- (*mp)->m_len = 1;
- *loop = (imo == NULL) ? IP_DEFAULT_MULTICAST_LOOP
- : imo->imo_multicast_loop;
- return (0);
+ if (imo == 0)
+ optval = coptval = IP_DEFAULT_MULTICAST_LOOP;
+ else
+ optval = coptval = imo->imo_multicast_loop;
+ if (sopt->sopt_valsize == 1)
+ error = sooptcopyout(sopt, &coptval, 1);
+ else
+ error = sooptcopyout(sopt, &optval, sizeof optval);
+ break;
default:
- return (EOPNOTSUPP);
+ error = ENOPROTOOPT;
+ break;
}
+ return (error);
}
/*
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index 6e3f7d8bdb63..16e66fcb9e73 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ip_var.h 8.2 (Berkeley) 1/9/95
- * $Id: ip_var.h,v 1.42 1998/07/06 03:20:18 julian Exp $
+ * $Id: ip_var.h,v 1.43 1998/07/13 12:20:07 bde Exp $
*/
#ifndef _NETINET_IP_VAR_H_
@@ -160,8 +160,10 @@ struct ipstat {
#define IP_ROUTETOIF SO_DONTROUTE /* bypass routing tables */
#define IP_ALLOWBROADCAST SO_BROADCAST /* can send broadcast packets */
+struct ip;
struct inpcb;
struct route;
+struct sockopt;
extern struct ipstat ipstat;
extern u_short ip_id; /* ip packet ctr, for ids */
@@ -175,8 +177,7 @@ extern u_long (*ip_mcast_src) __P((int));
extern int rsvp_on;
extern struct pr_usrreqs rip_usrreqs;
-int ip_ctloutput __P((int, struct socket *, int, int, struct mbuf **,
- struct proc *));
+int ip_ctloutput __P((struct socket *, struct sockopt *sopt));
void ip_drain __P((void));
void ip_freemoptions __P((struct ip_moptions *));
void ip_init __P((void));
@@ -190,8 +191,7 @@ void ip_slowtimo __P((void));
struct mbuf *
ip_srcroute __P((void));
void ip_stripoptions __P((struct mbuf *, struct mbuf *));
-int rip_ctloutput __P((int, struct socket *, int, int, struct mbuf **,
- struct proc *p));
+int rip_ctloutput __P((struct socket *, struct sockopt *));
void rip_ctlinput __P((int, struct sockaddr *, void *));
void rip_init __P((void));
void rip_input __P((struct mbuf *, int));
@@ -200,8 +200,8 @@ void ipip_input __P((struct mbuf *, int));
void rsvp_input __P((struct mbuf *, int));
int ip_rsvp_init __P((struct socket *));
int ip_rsvp_done __P((void));
-int ip_rsvp_vif_init __P((struct socket *, struct mbuf *));
-int ip_rsvp_vif_done __P((struct socket *, struct mbuf *));
+int ip_rsvp_vif_init __P((struct socket *, struct sockopt *));
+int ip_rsvp_vif_done __P((struct socket *, struct sockopt *));
void ip_rsvp_force_done __P((struct socket *));
#ifdef IPDIVERT
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 35f4391f52a1..ee05690cb94f 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)raw_ip.c 8.7 (Berkeley) 5/15/95
- * $Id: raw_ip.c,v 1.53 1998/03/28 10:18:24 bde Exp $
+ * $Id: raw_ip.c,v 1.54 1998/05/15 20:11:34 wollman Exp $
*/
#include <sys/param.h>
@@ -225,101 +225,127 @@ rip_output(m, so, dst)
* Raw IP socket option processing.
*/
int
-rip_ctloutput(op, so, level, optname, m, p)
- int op;
+rip_ctloutput(so, sopt)
struct socket *so;
- int level, optname;
- struct mbuf **m;
- struct proc *p;
+ struct sockopt *sopt;
{
- register struct inpcb *inp = sotoinpcb(so);
- register int error;
+ struct inpcb *inp = sotoinpcb(so);
+ int error, optval;
- if (level != IPPROTO_IP) {
- if (op == PRCO_SETOPT && *m)
- (void)m_free(*m);
+ if (sopt->sopt_level != IPPROTO_IP)
return (EINVAL);
- }
- switch (optname) {
+ error = 0;
+
+ switch (sopt->sopt_dir) {
+ case SOPT_GET:
+ switch (sopt->sopt_name) {
+ case IP_HDRINCL:
+ optval = inp->inp_flags & INP_HDRINCL;
+ error = sooptcopyout(sopt, &optval, sizeof optval);
+ break;
+
+#ifdef COMPAT_IPFW
+ case IP_FW_GET:
+ if (ip_fw_ctl_ptr == 0)
+ error = ENOPROTOOPT;
+ else
+ error = ip_fw_ctl_ptr(sopt);
+ break;
+
+ case IP_NAT:
+ if (ip_nat_ctl_ptr == 0)
+ error = ENOPROTOOPT;
+ else
+ error = ip_nat_ctl_ptr(sopt);
+ break;
+#endif /* COMPAT_IPFW */
+
+ case MRT_INIT:
+ case MRT_DONE:
+ case MRT_ADD_VIF:
+ case MRT_DEL_VIF:
+ case MRT_ADD_MFC:
+ case MRT_DEL_MFC:
+ case MRT_VERSION:
+ case MRT_ASSERT:
+ error = ip_mrouter_get(so, sopt);
+ break;
+
+ default:
+ error = ip_ctloutput(so, sopt);
+ break;
+ }
+ break;
- case IP_HDRINCL:
- error = 0;
- if (op == PRCO_SETOPT) {
- if (m == 0 || *m == 0 || (*m)->m_len < sizeof (int))
- error = EINVAL;
- else if (*mtod(*m, int *))
+ case SOPT_SET:
+ switch (sopt->sopt_name) {
+ case IP_HDRINCL:
+ error = sooptcopyin(sopt, &optval, sizeof optval,
+ sizeof optval);
+ if (error)
+ break;
+ if (optval)
inp->inp_flags |= INP_HDRINCL;
else
inp->inp_flags &= ~INP_HDRINCL;
- if (*m)
- (void)m_free(*m);
- } else {
- *m = m_get(M_WAIT, MT_SOOPTS);
- (*m)->m_len = sizeof (int);
- *mtod(*m, int *) = inp->inp_flags & INP_HDRINCL;
- }
- return (error);
+ break;
#ifdef COMPAT_IPFW
- case IP_FW_GET:
- if (ip_fw_ctl_ptr == NULL || op == PRCO_SETOPT) {
- if (*m) (void)m_free(*m);
- return(EINVAL);
- }
- return (*ip_fw_ctl_ptr)(optname, m);
-
- case IP_FW_ADD:
- case IP_FW_DEL:
- case IP_FW_FLUSH:
- case IP_FW_ZERO:
- if (ip_fw_ctl_ptr == NULL || op != PRCO_SETOPT) {
- if (*m) (void)m_free(*m);
- return(EINVAL);
- }
- return (*ip_fw_ctl_ptr)(optname, m);
+ case IP_FW_ADD:
+ case IP_FW_DEL:
+ case IP_FW_FLUSH:
+ case IP_FW_ZERO:
+ if (ip_fw_ctl_ptr == 0)
+ error = ENOPROTOOPT;
+ else
+ error = ip_fw_ctl_ptr(sopt);
+ break;
- case IP_NAT:
- if (ip_nat_ctl_ptr == NULL) {
- if (*m) (void)m_free(*m);
- return(EINVAL);
+ case IP_NAT:
+ if (ip_nat_ctl_ptr == 0)
+ error = ENOPROTOOPT;
+ else
+ error = ip_nat_ctl_ptr(sopt);
+ break;
+#endif /* COMPAT_IPFW */
+
+ case IP_RSVP_ON:
+ error = ip_rsvp_init(so);
+ break;
+
+ case IP_RSVP_OFF:
+ error = ip_rsvp_done();
+ break;
+
+ /* XXX - should be combined */
+ case IP_RSVP_VIF_ON:
+ error = ip_rsvp_vif_init(so, sopt);
+ break;
+
+ case IP_RSVP_VIF_OFF:
+ error = ip_rsvp_vif_done(so, sopt);
+ break;
+
+ case MRT_INIT:
+ case MRT_DONE:
+ case MRT_ADD_VIF:
+ case MRT_DEL_VIF:
+ case MRT_ADD_MFC:
+ case MRT_DEL_MFC:
+ case MRT_VERSION:
+ case MRT_ASSERT:
+ error = ip_mrouter_set(so, sopt);
+ break;
+
+ default:
+ error = ip_ctloutput(so, sopt);
+ break;
}
- return (*ip_nat_ctl_ptr)(op, m);
-
-#endif
- case IP_RSVP_ON:
- return ip_rsvp_init(so);
- break;
-
- case IP_RSVP_OFF:
- return ip_rsvp_done();
break;
-
- case IP_RSVP_VIF_ON:
- return ip_rsvp_vif_init(so, *m);
-
- case IP_RSVP_VIF_OFF:
- return ip_rsvp_vif_done(so, *m);
-
- case MRT_INIT:
- case MRT_DONE:
- case MRT_ADD_VIF:
- case MRT_DEL_VIF:
- case MRT_ADD_MFC:
- case MRT_DEL_MFC:
- case MRT_VERSION:
- case MRT_ASSERT:
- if (op == PRCO_SETOPT) {
- error = ip_mrouter_set(optname, so, *m);
- if (*m)
- (void)m_free(*m);
- } else if (op == PRCO_GETOPT) {
- error = ip_mrouter_get(optname, so, m);
- } else
- error = EINVAL;
- return (error);
}
- return (ip_ctloutput(op, so, level, optname, m, p));
+
+ return (error);
}
/*
@@ -340,7 +366,7 @@ rip_ctlinput(cmd, sa, vip)
int err;
int flags;
- switch(cmd) {
+ switch (cmd) {
case PRC_IFDOWN:
for (ia = in_ifaddrhead.tqh_first; ia;
ia = ia->ia_link.tqe_next) {
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index cc94bbb541bd..ba0c01233636 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* From: @(#)tcp_usrreq.c 8.2 (Berkeley) 1/3/94
- * $Id: tcp_usrreq.c,v 1.36 1997/12/18 09:50:38 davidg Exp $
+ * $Id: tcp_usrreq.c,v 1.37 1998/01/27 09:15:11 davidg Exp $
*/
#include "opt_tcpdebug.h"
@@ -560,104 +560,107 @@ tcp_connect(tp, nam, p)
return 0;
}
+/*
+ * The new sockopt interface makes it possible for us to block in the
+ * copyin/out step (if we take a page fault). Taking a page fault at
+ * splnet() is probably a Bad Thing. (Since sockets and pcbs both now
+ * use TSM, there probably isn't any need for this function to run at
+ * splnet() any more. This needs more examination.)
+ */
int
-tcp_ctloutput(op, so, level, optname, mp, p)
- int op;
+tcp_ctloutput(so, sopt)
struct socket *so;
- int level, optname;
- struct mbuf **mp;
- struct proc *p;
+ struct sockopt *sopt;
{
- int error = 0, s;
- struct inpcb *inp;
- register struct tcpcb *tp;
- register struct mbuf *m;
- register int i;
+ int error, opt, optval, s;
+ struct inpcb *inp;
+ struct tcpcb *tp;
+ struct mbuf *m;
- s = splnet();
+ error = 0;
+ s = splnet(); /* XXX */
inp = sotoinpcb(so);
if (inp == NULL) {
splx(s);
- if (op == PRCO_SETOPT && *mp)
- (void) m_free(*mp);
return (ECONNRESET);
}
- if (level != IPPROTO_TCP) {
- error = ip_ctloutput(op, so, level, optname, mp, p);
+ if (sopt->sopt_level != IPPROTO_TCP) {
+ error = ip_ctloutput(so, sopt);
splx(s);
return (error);
}
tp = intotcpcb(inp);
- switch (op) {
-
- case PRCO_SETOPT:
- m = *mp;
- switch (optname) {
-
+ switch (sopt->sopt_dir) {
+ case SOPT_SET:
+ switch (sopt->sopt_name) {
case TCP_NODELAY:
- if (m == NULL || m->m_len < sizeof (int))
- error = EINVAL;
- else if (*mtod(m, int *))
- tp->t_flags |= TF_NODELAY;
+ case TCP_NOOPT:
+ case TCP_NOPUSH:
+ error = sooptcopyin(sopt, &optval, sizeof optval,
+ sizeof optval);
+ if (error)
+ break;
+
+ switch (sopt->sopt_name) {
+ case TCP_NODELAY:
+ opt = TF_NODELAY;
+ break;
+ case TCP_NOOPT:
+ opt = TF_NOOPT;
+ break;
+ case TCP_NOPUSH:
+ opt = TF_NOPUSH;
+ break;
+ default:
+ opt = 0; /* dead code to fool gcc */
+ break;
+ }
+
+ if (optval)
+ tp->t_flags |= opt;
else
- tp->t_flags &= ~TF_NODELAY;
+ tp->t_flags &= ~opt;
break;
case TCP_MAXSEG:
- if (m && (i = *mtod(m, int *)) > 0 && i <= tp->t_maxseg)
- tp->t_maxseg = i;
- else
- error = EINVAL;
- break;
+ error = sooptcopyin(sopt, &optval, sizeof optval,
+ sizeof optval);
+ if (error)
+ break;
- case TCP_NOOPT:
- if (m == NULL || m->m_len < sizeof (int))
- error = EINVAL;
- else if (*mtod(m, int *))
- tp->t_flags |= TF_NOOPT;
+ if (optval > 0 && optval <= tp->t_maxseg)
+ tp->t_maxseg = optval;
else
- tp->t_flags &= ~TF_NOOPT;
- break;
-
- case TCP_NOPUSH:
- if (m == NULL || m->m_len < sizeof (int))
error = EINVAL;
- else if (*mtod(m, int *))
- tp->t_flags |= TF_NOPUSH;
- else
- tp->t_flags &= ~TF_NOPUSH;
break;
default:
error = ENOPROTOOPT;
break;
}
- if (m)
- (void) m_free(m);
break;
- case PRCO_GETOPT:
- *mp = m = m_get(M_WAIT, MT_SOOPTS);
- m->m_len = sizeof(int);
-
- switch (optname) {
+ case SOPT_GET:
+ switch (sopt->sopt_name) {
case TCP_NODELAY:
- *mtod(m, int *) = tp->t_flags & TF_NODELAY;
+ optval = tp->t_flags & TF_NODELAY;
break;
case TCP_MAXSEG:
- *mtod(m, int *) = tp->t_maxseg;
+ optval = tp->t_maxseg;
break;
case TCP_NOOPT:
- *mtod(m, int *) = tp->t_flags & TF_NOOPT;
+ optval = tp->t_flags & TF_NOOPT;
break;
case TCP_NOPUSH:
- *mtod(m, int *) = tp->t_flags & TF_NOPUSH;
+ optval = tp->t_flags & TF_NOPUSH;
break;
default:
error = ENOPROTOOPT;
break;
}
+ if (error == 0)
+ error = sooptcopyout(sopt, &optval, sizeof optval);
break;
}
splx(s);
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 48b00b7dbac9..15291c2dc87d 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)tcp_var.h 8.4 (Berkeley) 5/24/95
- * $Id: tcp_var.h,v 1.45 1998/06/27 07:30:45 jhay Exp $
+ * $Id: tcp_var.h,v 1.46 1998/07/13 11:09:52 bde Exp $
*/
#ifndef _NETINET_TCP_VAR_H_
@@ -344,8 +344,7 @@ void tcp_canceltimers __P((struct tcpcb *));
struct tcpcb *
tcp_close __P((struct tcpcb *));
void tcp_ctlinput __P((int, struct sockaddr *, void *));
-int tcp_ctloutput __P((int, struct socket *, int, int, struct mbuf **,
- struct proc *));
+int tcp_ctloutput __P((struct socket *, struct sockopt *));
struct tcpcb *
tcp_drop __P((struct tcpcb *, int));
void tcp_drain __P((void));
diff --git a/sys/netipx/ipx_ip.c b/sys/netipx/ipx_ip.c
index 57e8b771fe0e..5b8b8aa0cf17 100644
--- a/sys/netipx/ipx_ip.c
+++ b/sys/netipx/ipx_ip.c
@@ -33,7 +33,7 @@
*
* @(#)ipx_ip.c
*
- * $Id: ipx_ip.c,v 1.20 1998/02/09 06:10:20 eivind Exp $
+ * $Id: ipx_ip.c,v 1.21 1998/06/07 17:12:19 dfr Exp $
*/
/*
@@ -316,17 +316,23 @@ struct ifnet *ifp;
static struct ifreq ifr_ipxip = {"ipxip0"};
int
-ipxip_route(so, m, p)
+ipxip_route(so, sopt)
struct socket *so;
- register struct mbuf *m;
- struct proc *p;
+ struct sockopt *sopt;
{
- register struct ipxip_req *rq = mtod(m, struct ipxip_req *);
- struct sockaddr_ipx *ipx_dst = (struct sockaddr_ipx *)&rq->rq_ipx;
- struct sockaddr_in *ip_dst = (struct sockaddr_in *)&rq->rq_ip;
- struct route ro;
+ int error;
struct ifnet_en *ifn;
struct sockaddr_in *src;
+ struct ipxip_req rq;
+ struct sockaddr_ipx *ipx_dst;
+ struct sockaddr_in *ip_dst;
+ struct route ro;
+
+ error = sooptcopyin(sopt, &rq, sizeof rq, sizeof rq);
+ if (error)
+ return (error);
+ ipx_dst = (struct sockaddr_ipx *)&rq.rq_ipx;
+ ip_dst = (struct sockaddr_in *)&rq.rq_ip;
/*
* First, make sure we already have an IPX address:
@@ -387,14 +393,14 @@ ipxip_route(so, m, p)
ifr_ipxip.ifr_name[4] = '0' + ipxipif.if_unit - 1;
ifr_ipxip.ifr_dstaddr = *(struct sockaddr *)ipx_dst;
ipx_control(so, (int)SIOCSIFDSTADDR, (caddr_t)&ifr_ipxip,
- (struct ifnet *)ifn, p);
+ (struct ifnet *)ifn, sopt->sopt_p);
/* use any of our addresses */
satoipx_addr(ifr_ipxip.ifr_addr).x_host =
ipx_ifaddr->ia_addr.sipx_addr.x_host;
return (ipx_control(so, (int)SIOCSIFADDR, (caddr_t)&ifr_ipxip,
- (struct ifnet *)ifn, p));
+ (struct ifnet *)ifn, sopt->sopt_p));
}
static int
diff --git a/sys/netipx/ipx_ip.h b/sys/netipx/ipx_ip.h
index 1d22e635682e..e8bd9cf80f03 100644
--- a/sys/netipx/ipx_ip.h
+++ b/sys/netipx/ipx_ip.h
@@ -33,7 +33,7 @@
*
* @(#)ipxip.h
*
- * $Id: ipx_ip.h,v 1.10 1997/05/10 09:58:53 jhay Exp $
+ * $Id: ipx_ip.h,v 1.11 1997/06/26 19:35:50 jhay Exp $
*/
#ifndef _NETIPX_IPXIP_H_
@@ -53,7 +53,7 @@ struct ifnet_en {
void ipxip_ctlinput __P((int cmd, struct sockaddr *sa, void *arg));
void ipxip_input __P((struct mbuf *m, int hlen));
-int ipxip_route __P((struct socket *so, struct mbuf *m, struct proc *p));
+int ipxip_route __P((struct socket *so, struct sockopt *sopt));
#endif /* KERNEL */
diff --git a/sys/netipx/ipx_usrreq.c b/sys/netipx/ipx_usrreq.c
index 3c15319cc754..58fb5e24e264 100644
--- a/sys/netipx/ipx_usrreq.c
+++ b/sys/netipx/ipx_usrreq.c
@@ -33,7 +33,7 @@
*
* @(#)ipx_usrreq.c
*
- * $Id: ipx_usrreq.c,v 1.18 1997/12/15 20:31:15 eivind Exp $
+ * $Id: ipx_usrreq.c,v 1.19 1998/02/09 06:10:25 eivind Exp $
*/
#include "opt_ipx.h"
@@ -310,30 +310,23 @@ ipx_output(ipxp, m0)
}
int
-ipx_ctloutput(req, so, level, name, value, p)
- int req, level;
+ipx_ctloutput(so, sopt)
struct socket *so;
- int name;
- struct mbuf **value;
- struct proc *p;
+ struct sockopt *sopt;
{
register struct mbuf *m;
struct ipxpcb *ipxp = sotoipxpcb(so);
- int mask, error = 0;
+ int mask, error, optval;
+ short soptval;
+ struct ipx ioptval;
+ error = 0;
if (ipxp == NULL)
return (EINVAL);
- switch (req) {
-
- case PRCO_GETOPT:
- if (value == NULL)
- return (EINVAL);
- m = m_get(M_DONTWAIT, MT_DATA);
- if (m == NULL)
- return (ENOBUFS);
- switch (name) {
-
+ switch (sopt->sopt_dir) {
+ case SOPT_GET:
+ switch (sopt->sopt_name) {
case SO_ALL_PACKETS:
mask = IPXP_ALL_PACKETS;
goto get_flags;
@@ -345,38 +338,33 @@ ipx_ctloutput(req, so, level, name, value, p)
case SO_HEADERS_ON_OUTPUT:
mask = IPXP_RAWOUT;
get_flags:
- m->m_len = sizeof(short);
- *mtod(m, short *) = ipxp->ipxp_flags & mask;
+ soptval = ipxp->ipxp_flags & mask;
+ error = sooptcopyout(sopt, &soptval, sizeof soptval);
break;
case SO_DEFAULT_HEADERS:
- m->m_len = sizeof(struct ipx);
- {
- register struct ipx *ipx = mtod(m, struct ipx *);
- ipx->ipx_len = 0;
- ipx->ipx_sum = 0;
- ipx->ipx_tc = 0;
- ipx->ipx_pt = ipxp->ipxp_dpt;
- ipx->ipx_dna = ipxp->ipxp_faddr;
- ipx->ipx_sna = ipxp->ipxp_laddr;
- }
+ ioptval.ipx_len = 0;
+ ioptval.ipx_sum = 0;
+ ioptval.ipx_tc = 0;
+ ioptval.ipx_pt = ipxp->ipxp_dpt;
+ ioptval.ipx_dna = ipxp->ipxp_faddr;
+ ioptval.ipx_sna = ipxp->ipxp_laddr;
+ error = sooptcopyout(sopt, &soptval, sizeof soptval);
break;
case SO_SEQNO:
- m->m_len = sizeof(long);
- *mtod(m, long *) = ipx_pexseq++;
+ error = sooptcopyout(sopt, &ipx_pexseq,
+ sizeof ipx_pexseq);
+ ipx_pexseq++;
break;
default:
error = EINVAL;
}
- *value = m;
break;
- case PRCO_SETOPT:
- switch (name) {
- int *ok;
-
+ case SOPT_SET:
+ switch (sopt->sopt_name) {
case SO_ALL_PACKETS:
mask = IPXP_ALL_PACKETS;
goto set_head;
@@ -388,39 +376,38 @@ ipx_ctloutput(req, so, level, name, value, p)
case SO_HEADERS_ON_OUTPUT:
mask = IPXP_RAWOUT;
set_head:
- if (value && *value) {
- ok = mtod(*value, int *);
- if (*ok)
- ipxp->ipxp_flags |= mask;
- else
- ipxp->ipxp_flags &= ~mask;
- } else error = EINVAL;
+ error = sooptcopyin(sopt, &optval, sizeof optval,
+ sizeof optval);
+ if (error)
+ break;
+ if (optval)
+ ipxp->ipxp_flags |= mask;
+ else
+ ipxp->ipxp_flags &= ~mask;
break;
case SO_DEFAULT_HEADERS:
- {
- register struct ipx *ipx
- = mtod(*value, struct ipx *);
- ipxp->ipxp_dpt = ipx->ipx_pt;
- }
+ error = sooptcopyin(sopt, &ioptval, sizeof ioptval,
+ sizeof ioptval);
+ if (error)
+ break;
+ ipxp->ipxp_dpt = ioptval.ipx_pt;
break;
#ifdef IPXIP
case SO_IPXIP_ROUTE:
- error = ipxip_route(so, *value, p);
+ error = ipxip_route(so, sopt);
break;
#endif /* IPXIP */
#ifdef IPTUNNEL
#if 0
case SO_IPXTUNNEL_ROUTE:
- error = ipxtun_route(so, *value, p);
+ error = ipxtun_route(so, sopt);
break;
#endif
#endif
default:
error = EINVAL;
}
- if (value && *value)
- m_freem(*value);
break;
}
return (error);
diff --git a/sys/netipx/ipx_var.h b/sys/netipx/ipx_var.h
index bd05bc9ace35..bda0533dc98f 100644
--- a/sys/netipx/ipx_var.h
+++ b/sys/netipx/ipx_var.h
@@ -33,7 +33,7 @@
*
* @(#)ipx_var.h
*
- * $Id: ipx_var.h,v 1.9 1998/02/01 20:08:34 bde Exp $
+ * $Id: ipx_var.h,v 1.10 1998/06/07 17:12:20 dfr Exp $
*/
#ifndef _NETIPX_IPX_VAR_H_
@@ -79,14 +79,14 @@ struct proc;
struct route;
struct sockaddr;
struct socket;
+struct sockopt;
void ipx_abort __P((struct ipxpcb *ipxp));
u_short ipx_cksum __P((struct mbuf *m, int len));
int ipx_control __P((struct socket *so, u_long cmd, caddr_t data,
struct ifnet *ifp, struct proc *p));
void ipx_ctlinput __P((int cmd, struct sockaddr *arg_as_sa, void *dummy));
-int ipx_ctloutput __P((int req, struct socket *so, int level, int name,
- struct mbuf **value, struct proc *p));
+int ipx_ctloutput __P((struct socket *so, struct sockopt *sopt));
void ipx_drop __P((struct ipxpcb *ipxp, int errno));
void ipx_init __P((void));
void ipx_input __P((struct mbuf *m, struct ipxpcb *ipxp));
diff --git a/sys/netipx/spx.h b/sys/netipx/spx.h
index 2620e259d010..20a4116c2b15 100644
--- a/sys/netipx/spx.h
+++ b/sys/netipx/spx.h
@@ -33,7 +33,7 @@
*
* @(#)spx.h
*
- * $Id: spx.h,v 1.12 1997/05/10 09:58:56 jhay Exp $
+ * $Id: spx.h,v 1.13 1997/06/26 19:36:00 jhay Exp $
*/
#ifndef _NETIPX_SPX_H_
@@ -173,8 +173,7 @@ extern struct pr_usrreqs spx_usrreqs;
extern struct pr_usrreqs spx_usrreq_sps;
void spx_ctlinput __P((int cmd, struct sockaddr *arg_as_sa, void *dummy));
-int spx_ctloutput __P((int req, struct socket *so, int level, int name,
- struct mbuf **value, struct proc *p));
+int spx_ctloutput __P((struct socket *so, struct sockopt *sopt));
void spx_fasttimo __P((void));
void spx_init __P((void));
void spx_input __P((struct mbuf *m, struct ipxpcb *ipxp));
diff --git a/sys/netipx/spx_usrreq.c b/sys/netipx/spx_usrreq.c
index 5fc82271d039..e37a2f89f1e3 100644
--- a/sys/netipx/spx_usrreq.c
+++ b/sys/netipx/spx_usrreq.c
@@ -33,7 +33,7 @@
*
* @(#)spx_usrreq.h
*
- * $Id: spx_usrreq.c,v 1.18 1998/02/09 06:10:26 eivind Exp $
+ * $Id: spx_usrreq.c,v 1.19 1998/05/01 18:30:02 bde Exp $
*/
#include <sys/param.h>
@@ -1154,39 +1154,33 @@ spx_setpersist(cb)
}
int
-spx_ctloutput(req, so, level, name, value, p)
- int req;
+spx_ctloutput(so, sopt)
struct socket *so;
- int level, name;
- struct mbuf **value;
- struct proc *p;
+ struct sockopt *sopt;
{
register struct mbuf *m;
struct ipxpcb *ipxp = sotoipxpcb(so);
register struct spxpcb *cb;
- int mask, error = 0;
+ int mask, error;
+ short soptval;
+ u_short usoptval;
+ int optval;
+
+ error = 0;
- if (level != IPXPROTO_SPX) {
+ if (sopt->sopt_level != IPXPROTO_SPX) {
/* This will have to be changed when we do more general
stacking of protocols */
- return (ipx_ctloutput(req, so, level, name, value, p));
+ return (ipx_ctloutput(so, sopt));
}
- if (ipxp == NULL) {
- error = EINVAL;
- goto release;
- } else
+ if (ipxp == NULL)
+ return (EINVAL);
+ else
cb = ipxtospxpcb(ipxp);
- switch (req) {
-
- case PRCO_GETOPT:
- if (value == NULL)
- return (EINVAL);
- m = m_get(M_DONTWAIT, MT_DATA);
- if (m == NULL)
- return (ENOBUFS);
- switch (name) {
-
+ switch (sopt->sopt_dir) {
+ case SOPT_GET:
+ switch (sopt->sopt_name) {
case SO_HEADERS_ON_INPUT:
mask = SF_HI;
goto get_flags;
@@ -1194,39 +1188,34 @@ spx_ctloutput(req, so, level, name, value, p)
case SO_HEADERS_ON_OUTPUT:
mask = SF_HO;
get_flags:
- m->m_len = sizeof(short);
- *mtod(m, short *) = cb->s_flags & mask;
+ soptval = cb->s_flags & mask;
+ error = sooptcopyout(sopt, &soptval, sizeof soptval);
break;
case SO_MTU:
- m->m_len = sizeof(u_short);
- *mtod(m, short *) = cb->s_mtu;
+ usoptval = cb->s_mtu;
+ error = sooptcopyout(sopt, &usoptval, sizeof usoptval);
break;
case SO_LAST_HEADER:
- m->m_len = sizeof(struct spxhdr);
- *mtod(m, struct spxhdr *) = cb->s_rhdr;
+ error = sooptcopyout(sopt, &cb->s_rhdr,
+ sizeof cb->s_rhdr);
break;
case SO_DEFAULT_HEADERS:
- m->m_len = sizeof(struct spx);
- *mtod(m, struct spxhdr *) = cb->s_shdr;
+ error = sooptcopyout(sopt, &cb->s_shdr,
+ sizeof cb->s_shdr);
break;
default:
- error = EINVAL;
+ error = ENOPROTOOPT;
}
- *value = m;
break;
- case PRCO_SETOPT:
- if (value == 0 || *value == 0) {
- error = EINVAL;
- break;
- }
- switch (name) {
- int *ok;
-
+ case SOPT_SET:
+ switch (sopt->sopt_name) {
+ /* XXX why are these shorts on get and ints on set?
+ that doesn't make any sense... */
case SO_HEADERS_ON_INPUT:
mask = SF_HI;
goto set_head;
@@ -1234,9 +1223,13 @@ spx_ctloutput(req, so, level, name, value, p)
case SO_HEADERS_ON_OUTPUT:
mask = SF_HO;
set_head:
+ error = sooptcopyin(sopt, &optval, sizeof optval,
+ sizeof optval);
+ if (error)
+ break;
+
if (cb->s_flags & SF_PI) {
- ok = mtod(*value, int *);
- if (*ok)
+ if (optval)
cb->s_flags |= mask;
else
cb->s_flags &= ~mask;
@@ -1244,13 +1237,20 @@ spx_ctloutput(req, so, level, name, value, p)
break;
case SO_MTU:
- cb->s_mtu = *(mtod(*value, u_short *));
+ error = sooptcopyin(sopt, &usoptval, sizeof usoptval,
+ sizeof usoptval);
+ if (error)
+ break;
+ cb->s_mtu = usoptval;
break;
#ifdef SF_NEWCALL
case SO_NEWCALL:
- ok = mtod(*value, int *);
- if (*ok) {
+ error = sooptcopyin(sopt, &optval, sizeof optval,
+ sizeof optval);
+ if (error)
+ break;
+ if (optval) {
cb->s_flags2 |= SF_NEWCALL;
spx_newchecks[5]++;
} else {
@@ -1262,21 +1262,23 @@ spx_ctloutput(req, so, level, name, value, p)
case SO_DEFAULT_HEADERS:
{
- register struct spxhdr *sp
- = mtod(*value, struct spxhdr *);
- cb->s_dt = sp->spx_dt;
- cb->s_cc = sp->spx_cc & SPX_EM;
+ struct spxhdr sp;
+
+ error = sooptcopyin(sopt, &sp, sizeof sp,
+ sizeof sp);
+ if (error)
+ break;
+ cb->s_dt = sp.spx_dt;
+ cb->s_cc = sp.spx_cc & SPX_EM;
}
break;
default:
- error = EINVAL;
+ error = ENOPROTOOPT;
}
- m_freem(*value);
break;
}
- release:
- return (error);
+ return (error);
}
static int
diff --git a/sys/nfs/bootp_subr.c b/sys/nfs/bootp_subr.c
index 459af38343dc..c66e38466540 100644
--- a/sys/nfs/bootp_subr.c
+++ b/sys/nfs/bootp_subr.c
@@ -1,4 +1,4 @@
-/* $Id: bootp_subr.c,v 1.13 1998/03/30 09:53:38 phk Exp $ */
+/* $Id: bootp_subr.c,v 1.14 1998/08/18 00:32:47 bde Exp $ */
/*
* Copyright (c) 1995 Gordon Ross, Adam Glass
@@ -264,8 +264,10 @@ bootpc_call(call,reply,procp)
struct sockaddr_in *sin, sa;
struct mbuf *m;
struct uio auio;
+ struct sockopt sopt;
struct iovec aio;
- int error, rcvflg, timo, secs, len;
+ struct timeval tv;
+ int error, on, len, rcvflg, secs, timo;
u_int tport;
/*
@@ -274,36 +276,26 @@ bootpc_call(call,reply,procp)
if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0,procp)))
goto out;
- m = m_get(M_WAIT, MT_SOOPTS);
- if (m == NULL) {
- error = ENOBUFS;
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ bzero(&sopt, sizeof sopt);
+ sopt.sopt_level = SOL_SOCKET;
+ sopt.sopt_name = SO_RCVTIMEO;
+ sopt.sopt_val = &tv;
+ sopt.sopt_valsize = sizeof tv;
+
+ if (error = sosetopt(so, &sopt))
goto out;
- } else {
- struct timeval *tv;
- tv = mtod(m, struct timeval *);
- m->m_len = sizeof(*tv);
- tv->tv_sec = 1;
- tv->tv_usec = 0;
- if ((error = sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m, procp)))
- goto out;
- }
/*
* Enable broadcast.
*/
- {
- int *on;
- m = m_get(M_WAIT, MT_SOOPTS);
- if (m == NULL) {
- error = ENOBUFS;
- goto out;
- }
- on = mtod(m, int *);
- m->m_len = sizeof(*on);
- *on = 1;
- if ((error = sosetopt(so, SOL_SOCKET, SO_BROADCAST, m, procp)))
- goto out;
- }
+ on = 1;
+ sopt.sopt_val = &on;
+ sopt.sopt_valsize = sizeof on;
+ sopt.sopt_name = SO_BROADCAST;
+ if (error = sosetopt(so, &sopt))
+ goto out;
/*
* Bind the local endpoint to a bootp client port.
diff --git a/sys/nfs/krpc_subr.c b/sys/nfs/krpc_subr.c
index c77a5f52b1f5..ad01edb20db2 100644
--- a/sys/nfs/krpc_subr.c
+++ b/sys/nfs/krpc_subr.c
@@ -1,5 +1,5 @@
/* $NetBSD: krpc_subr.c,v 1.12.4.1 1996/06/07 00:52:26 cgd Exp $ */
-/* $Id: krpc_subr.c,v 1.9 1998/03/28 10:33:15 bde Exp $ */
+/* $Id: krpc_subr.c,v 1.10 1998/08/18 00:32:48 bde Exp $ */
/*
* Copyright (c) 1995 Gordon Ross, Adam Glass
@@ -198,6 +198,8 @@ krpc_call(sa, prog, vers, func, data, from_p, procp)
struct mbuf *m, *nam, *mhead;
struct rpc_call *call;
struct rpc_reply *reply;
+ struct sockopt sopt;
+ struct timeval tv;
struct uio auio;
int error, rcvflg, timo, secs, len;
static u_int32_t xid = ~0xFF;
@@ -220,34 +222,26 @@ krpc_call(sa, prog, vers, func, data, from_p, procp)
if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0, procp)))
goto out;
- m = m_get(M_WAIT, MT_SOOPTS);
- if (m == NULL) {
- error = ENOBUFS;
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ bzero(&sopt, sizeof sopt);
+ sopt.sopt_level = SOL_SOCKET;
+ sopt.sopt_name = SO_RCVTIMEO;
+ sopt.sopt_val = &tv;
+ sopt.sopt_valsize = sizeof tv;
+
+ if (error = sosetopt(so, &sopt))
goto out;
- } else {
- struct timeval *tv;
- tv = mtod(m, struct timeval *);
- m->m_len = sizeof(*tv);
- tv->tv_sec = 1;
- tv->tv_usec = 0;
- if ((error = sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m, procp)))
- goto out;
- }
/*
* Enable broadcast if necessary.
*/
if (from_p) {
- int32_t *on;
- m = m_get(M_WAIT, MT_SOOPTS);
- if (m == NULL) {
- error = ENOBUFS;
- goto out;
- }
- on = mtod(m, int32_t *);
- m->m_len = sizeof(*on);
- *on = 1;
- if ((error = sosetopt(so, SOL_SOCKET, SO_BROADCAST, m, procp)))
+ int on = 1;
+ sopt.sopt_name = SO_BROADCAST;
+ sopt.sopt_val = &on;
+ sopt.sopt_valsize = sizeof on;
+ if (error = sosetopt(so, &sopt))
goto out;
}
diff --git a/sys/nfs/nfs.h b/sys/nfs/nfs.h
index e5be581fa031..885a2c19e17a 100644
--- a/sys/nfs/nfs.h
+++ b/sys/nfs/nfs.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
- * $Id: nfs.h,v 1.41 1998/06/30 03:01:37 jmg Exp $
+ * $Id: nfs.h,v 1.42 1998/06/30 11:19:22 jmg Exp $
*/
#ifndef _NFS_NFS_H_
@@ -722,7 +722,7 @@ int nfsrv_symlink __P((struct nfsrv_descript *nfsd,
struct proc *procp, struct mbuf **mrq));
int nfsrv_write __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
struct proc *procp, struct mbuf **mrq));
-void nfsrv_rcv __P((struct socket *so, caddr_t arg, int waitflag));
+void nfsrv_rcv __P((struct socket *so, void *arg, int waitflag));
void nfsrv_slpderef __P((struct nfssvc_sock *slp));
#endif /* KERNEL */
diff --git a/sys/nfs/nfs_socket.c b/sys/nfs/nfs_socket.c
index d4e1a0492033..693899f289b3 100644
--- a/sys/nfs/nfs_socket.c
+++ b/sys/nfs/nfs_socket.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95
- * $Id: nfs_socket.c,v 1.42 1998/07/15 02:32:24 bde Exp $
+ * $Id: nfs_socket.c,v 1.43 1998/08/01 09:04:02 peter Exp $
*/
/*
@@ -282,16 +282,28 @@ nfs_connect(nmp, rep)
if (nmp->nm_sotype != SOCK_STREAM)
panic("nfscon sotype");
if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
- MGET(m, M_WAIT, MT_SOOPTS);
- *mtod(m, int32_t *) = 1;
- m->m_len = sizeof(int32_t);
- sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m, p);
+ struct sockopt sopt;
+ int val;
+
+ bzero(&sopt, sizeof sopt);
+ sopt.sopt_level = SOL_SOCKET;
+ sopt.sopt_name = SO_KEEPALIVE;
+ sopt.sopt_val = &val;
+ sopt.sopt_valsize = sizeof val;
+ val = 1;
+ sosetopt(so, &sopt);
}
if (so->so_proto->pr_protocol == IPPROTO_TCP) {
- MGET(m, M_WAIT, MT_SOOPTS);
- *mtod(m, int32_t *) = 1;
- m->m_len = sizeof(int32_t);
- sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m, p);
+ struct sockopt sopt;
+ int val;
+
+ bzero(&sopt, sizeof sopt);
+ sopt.sopt_level = IPPROTO_TCP;
+ sopt.sopt_name = TCP_NODELAY;
+ sopt.sopt_val = &val;
+ sopt.sopt_valsize = sizeof val;
+ val = 1;
+ sosetopt(so, &sopt);
}
sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR +
sizeof (u_int32_t)) * 2;
@@ -1952,7 +1964,7 @@ nfs_msg(p, server, msg)
void
nfsrv_rcv(so, arg, waitflag)
struct socket *so;
- caddr_t arg;
+ void *arg;
int waitflag;
{
register struct nfssvc_sock *slp = (struct nfssvc_sock *)arg;
diff --git a/sys/nfs/nfs_syscalls.c b/sys/nfs/nfs_syscalls.c
index 08a1f1377daa..c6b92d5f597e 100644
--- a/sys/nfs/nfs_syscalls.c
+++ b/sys/nfs/nfs_syscalls.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95
- * $Id: nfs_syscalls.c,v 1.40 1998/05/31 18:46:06 peter Exp $
+ * $Id: nfs_syscalls.c,v 1.41 1998/05/31 20:08:55 peter Exp $
*/
#include <sys/param.h>
@@ -400,17 +400,29 @@ nfssvc_addsock(fp, mynam, p)
* repeatedly for the same socket, but that isn't harmful.
*/
if (so->so_type == SOCK_STREAM) {
- MGET(m, M_WAIT, MT_SOOPTS);
- *mtod(m, int32_t *) = 1;
- m->m_len = sizeof(int32_t);
- sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m, p);
+ struct sockopt sopt;
+ int val;
+
+ bzero(&sopt, sizeof sopt);
+ sopt.sopt_level = SOL_SOCKET;
+ sopt.sopt_name = SO_KEEPALIVE;
+ sopt.sopt_val = &val;
+ sopt.sopt_valsize = sizeof val;
+ val = 1;
+ sosetopt(so, &sopt);
}
if (so->so_proto->pr_domain->dom_family == AF_INET &&
so->so_proto->pr_protocol == IPPROTO_TCP) {
- MGET(m, M_WAIT, MT_SOOPTS);
- *mtod(m, int32_t *) = 1;
- m->m_len = sizeof(int32_t);
- sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m, p);
+ struct sockopt sopt;
+ int val;
+
+ bzero(&sopt, sizeof sopt);
+ sopt.sopt_level = IPPROTO_TCP;
+ sopt.sopt_name = TCP_NODELAY;
+ sopt.sopt_val = &val;
+ sopt.sopt_valsize = sizeof val;
+ val = 1;
+ sosetopt(so, &sopt);
}
so->so_rcv.sb_flags &= ~SB_NOINTR;
so->so_rcv.sb_timeo = 0;
diff --git a/sys/nfsclient/bootp_subr.c b/sys/nfsclient/bootp_subr.c
index 459af38343dc..c66e38466540 100644
--- a/sys/nfsclient/bootp_subr.c
+++ b/sys/nfsclient/bootp_subr.c
@@ -1,4 +1,4 @@
-/* $Id: bootp_subr.c,v 1.13 1998/03/30 09:53:38 phk Exp $ */
+/* $Id: bootp_subr.c,v 1.14 1998/08/18 00:32:47 bde Exp $ */
/*
* Copyright (c) 1995 Gordon Ross, Adam Glass
@@ -264,8 +264,10 @@ bootpc_call(call,reply,procp)
struct sockaddr_in *sin, sa;
struct mbuf *m;
struct uio auio;
+ struct sockopt sopt;
struct iovec aio;
- int error, rcvflg, timo, secs, len;
+ struct timeval tv;
+ int error, on, len, rcvflg, secs, timo;
u_int tport;
/*
@@ -274,36 +276,26 @@ bootpc_call(call,reply,procp)
if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0,procp)))
goto out;
- m = m_get(M_WAIT, MT_SOOPTS);
- if (m == NULL) {
- error = ENOBUFS;
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ bzero(&sopt, sizeof sopt);
+ sopt.sopt_level = SOL_SOCKET;
+ sopt.sopt_name = SO_RCVTIMEO;
+ sopt.sopt_val = &tv;
+ sopt.sopt_valsize = sizeof tv;
+
+ if (error = sosetopt(so, &sopt))
goto out;
- } else {
- struct timeval *tv;
- tv = mtod(m, struct timeval *);
- m->m_len = sizeof(*tv);
- tv->tv_sec = 1;
- tv->tv_usec = 0;
- if ((error = sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m, procp)))
- goto out;
- }
/*
* Enable broadcast.
*/
- {
- int *on;
- m = m_get(M_WAIT, MT_SOOPTS);
- if (m == NULL) {
- error = ENOBUFS;
- goto out;
- }
- on = mtod(m, int *);
- m->m_len = sizeof(*on);
- *on = 1;
- if ((error = sosetopt(so, SOL_SOCKET, SO_BROADCAST, m, procp)))
- goto out;
- }
+ on = 1;
+ sopt.sopt_val = &on;
+ sopt.sopt_valsize = sizeof on;
+ sopt.sopt_name = SO_BROADCAST;
+ if (error = sosetopt(so, &sopt))
+ goto out;
/*
* Bind the local endpoint to a bootp client port.
diff --git a/sys/nfsclient/krpc_subr.c b/sys/nfsclient/krpc_subr.c
index c77a5f52b1f5..ad01edb20db2 100644
--- a/sys/nfsclient/krpc_subr.c
+++ b/sys/nfsclient/krpc_subr.c
@@ -1,5 +1,5 @@
/* $NetBSD: krpc_subr.c,v 1.12.4.1 1996/06/07 00:52:26 cgd Exp $ */
-/* $Id: krpc_subr.c,v 1.9 1998/03/28 10:33:15 bde Exp $ */
+/* $Id: krpc_subr.c,v 1.10 1998/08/18 00:32:48 bde Exp $ */
/*
* Copyright (c) 1995 Gordon Ross, Adam Glass
@@ -198,6 +198,8 @@ krpc_call(sa, prog, vers, func, data, from_p, procp)
struct mbuf *m, *nam, *mhead;
struct rpc_call *call;
struct rpc_reply *reply;
+ struct sockopt sopt;
+ struct timeval tv;
struct uio auio;
int error, rcvflg, timo, secs, len;
static u_int32_t xid = ~0xFF;
@@ -220,34 +222,26 @@ krpc_call(sa, prog, vers, func, data, from_p, procp)
if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0, procp)))
goto out;
- m = m_get(M_WAIT, MT_SOOPTS);
- if (m == NULL) {
- error = ENOBUFS;
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ bzero(&sopt, sizeof sopt);
+ sopt.sopt_level = SOL_SOCKET;
+ sopt.sopt_name = SO_RCVTIMEO;
+ sopt.sopt_val = &tv;
+ sopt.sopt_valsize = sizeof tv;
+
+ if (error = sosetopt(so, &sopt))
goto out;
- } else {
- struct timeval *tv;
- tv = mtod(m, struct timeval *);
- m->m_len = sizeof(*tv);
- tv->tv_sec = 1;
- tv->tv_usec = 0;
- if ((error = sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m, procp)))
- goto out;
- }
/*
* Enable broadcast if necessary.
*/
if (from_p) {
- int32_t *on;
- m = m_get(M_WAIT, MT_SOOPTS);
- if (m == NULL) {
- error = ENOBUFS;
- goto out;
- }
- on = mtod(m, int32_t *);
- m->m_len = sizeof(*on);
- *on = 1;
- if ((error = sosetopt(so, SOL_SOCKET, SO_BROADCAST, m, procp)))
+ int on = 1;
+ sopt.sopt_name = SO_BROADCAST;
+ sopt.sopt_val = &on;
+ sopt.sopt_valsize = sizeof on;
+ if (error = sosetopt(so, &sopt))
goto out;
}
diff --git a/sys/nfsclient/nfs.h b/sys/nfsclient/nfs.h
index e5be581fa031..885a2c19e17a 100644
--- a/sys/nfsclient/nfs.h
+++ b/sys/nfsclient/nfs.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
- * $Id: nfs.h,v 1.41 1998/06/30 03:01:37 jmg Exp $
+ * $Id: nfs.h,v 1.42 1998/06/30 11:19:22 jmg Exp $
*/
#ifndef _NFS_NFS_H_
@@ -722,7 +722,7 @@ int nfsrv_symlink __P((struct nfsrv_descript *nfsd,
struct proc *procp, struct mbuf **mrq));
int nfsrv_write __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
struct proc *procp, struct mbuf **mrq));
-void nfsrv_rcv __P((struct socket *so, caddr_t arg, int waitflag));
+void nfsrv_rcv __P((struct socket *so, void *arg, int waitflag));
void nfsrv_slpderef __P((struct nfssvc_sock *slp));
#endif /* KERNEL */
diff --git a/sys/nfsclient/nfs_nfsiod.c b/sys/nfsclient/nfs_nfsiod.c
index 08a1f1377daa..c6b92d5f597e 100644
--- a/sys/nfsclient/nfs_nfsiod.c
+++ b/sys/nfsclient/nfs_nfsiod.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95
- * $Id: nfs_syscalls.c,v 1.40 1998/05/31 18:46:06 peter Exp $
+ * $Id: nfs_syscalls.c,v 1.41 1998/05/31 20:08:55 peter Exp $
*/
#include <sys/param.h>
@@ -400,17 +400,29 @@ nfssvc_addsock(fp, mynam, p)
* repeatedly for the same socket, but that isn't harmful.
*/
if (so->so_type == SOCK_STREAM) {
- MGET(m, M_WAIT, MT_SOOPTS);
- *mtod(m, int32_t *) = 1;
- m->m_len = sizeof(int32_t);
- sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m, p);
+ struct sockopt sopt;
+ int val;
+
+ bzero(&sopt, sizeof sopt);
+ sopt.sopt_level = SOL_SOCKET;
+ sopt.sopt_name = SO_KEEPALIVE;
+ sopt.sopt_val = &val;
+ sopt.sopt_valsize = sizeof val;
+ val = 1;
+ sosetopt(so, &sopt);
}
if (so->so_proto->pr_domain->dom_family == AF_INET &&
so->so_proto->pr_protocol == IPPROTO_TCP) {
- MGET(m, M_WAIT, MT_SOOPTS);
- *mtod(m, int32_t *) = 1;
- m->m_len = sizeof(int32_t);
- sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m, p);
+ struct sockopt sopt;
+ int val;
+
+ bzero(&sopt, sizeof sopt);
+ sopt.sopt_level = IPPROTO_TCP;
+ sopt.sopt_name = TCP_NODELAY;
+ sopt.sopt_val = &val;
+ sopt.sopt_valsize = sizeof val;
+ val = 1;
+ sosetopt(so, &sopt);
}
so->so_rcv.sb_flags &= ~SB_NOINTR;
so->so_rcv.sb_timeo = 0;
diff --git a/sys/nfsclient/nfs_socket.c b/sys/nfsclient/nfs_socket.c
index d4e1a0492033..693899f289b3 100644
--- a/sys/nfsclient/nfs_socket.c
+++ b/sys/nfsclient/nfs_socket.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95
- * $Id: nfs_socket.c,v 1.42 1998/07/15 02:32:24 bde Exp $
+ * $Id: nfs_socket.c,v 1.43 1998/08/01 09:04:02 peter Exp $
*/
/*
@@ -282,16 +282,28 @@ nfs_connect(nmp, rep)
if (nmp->nm_sotype != SOCK_STREAM)
panic("nfscon sotype");
if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
- MGET(m, M_WAIT, MT_SOOPTS);
- *mtod(m, int32_t *) = 1;
- m->m_len = sizeof(int32_t);
- sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m, p);
+ struct sockopt sopt;
+ int val;
+
+ bzero(&sopt, sizeof sopt);
+ sopt.sopt_level = SOL_SOCKET;
+ sopt.sopt_name = SO_KEEPALIVE;
+ sopt.sopt_val = &val;
+ sopt.sopt_valsize = sizeof val;
+ val = 1;
+ sosetopt(so, &sopt);
}
if (so->so_proto->pr_protocol == IPPROTO_TCP) {
- MGET(m, M_WAIT, MT_SOOPTS);
- *mtod(m, int32_t *) = 1;
- m->m_len = sizeof(int32_t);
- sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m, p);
+ struct sockopt sopt;
+ int val;
+
+ bzero(&sopt, sizeof sopt);
+ sopt.sopt_level = IPPROTO_TCP;
+ sopt.sopt_name = TCP_NODELAY;
+ sopt.sopt_val = &val;
+ sopt.sopt_valsize = sizeof val;
+ val = 1;
+ sosetopt(so, &sopt);
}
sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR +
sizeof (u_int32_t)) * 2;
@@ -1952,7 +1964,7 @@ nfs_msg(p, server, msg)
void
nfsrv_rcv(so, arg, waitflag)
struct socket *so;
- caddr_t arg;
+ void *arg;
int waitflag;
{
register struct nfssvc_sock *slp = (struct nfssvc_sock *)arg;
diff --git a/sys/nfsclient/nfsargs.h b/sys/nfsclient/nfsargs.h
index e5be581fa031..885a2c19e17a 100644
--- a/sys/nfsclient/nfsargs.h
+++ b/sys/nfsclient/nfsargs.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
- * $Id: nfs.h,v 1.41 1998/06/30 03:01:37 jmg Exp $
+ * $Id: nfs.h,v 1.42 1998/06/30 11:19:22 jmg Exp $
*/
#ifndef _NFS_NFS_H_
@@ -722,7 +722,7 @@ int nfsrv_symlink __P((struct nfsrv_descript *nfsd,
struct proc *procp, struct mbuf **mrq));
int nfsrv_write __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
struct proc *procp, struct mbuf **mrq));
-void nfsrv_rcv __P((struct socket *so, caddr_t arg, int waitflag));
+void nfsrv_rcv __P((struct socket *so, void *arg, int waitflag));
void nfsrv_slpderef __P((struct nfssvc_sock *slp));
#endif /* KERNEL */
diff --git a/sys/nfsclient/nfsstats.h b/sys/nfsclient/nfsstats.h
index e5be581fa031..885a2c19e17a 100644
--- a/sys/nfsclient/nfsstats.h
+++ b/sys/nfsclient/nfsstats.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
- * $Id: nfs.h,v 1.41 1998/06/30 03:01:37 jmg Exp $
+ * $Id: nfs.h,v 1.42 1998/06/30 11:19:22 jmg Exp $
*/
#ifndef _NFS_NFS_H_
@@ -722,7 +722,7 @@ int nfsrv_symlink __P((struct nfsrv_descript *nfsd,
struct proc *procp, struct mbuf **mrq));
int nfsrv_write __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
struct proc *procp, struct mbuf **mrq));
-void nfsrv_rcv __P((struct socket *so, caddr_t arg, int waitflag));
+void nfsrv_rcv __P((struct socket *so, void *arg, int waitflag));
void nfsrv_slpderef __P((struct nfssvc_sock *slp));
#endif /* KERNEL */
diff --git a/sys/nfsserver/nfs.h b/sys/nfsserver/nfs.h
index e5be581fa031..885a2c19e17a 100644
--- a/sys/nfsserver/nfs.h
+++ b/sys/nfsserver/nfs.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
- * $Id: nfs.h,v 1.41 1998/06/30 03:01:37 jmg Exp $
+ * $Id: nfs.h,v 1.42 1998/06/30 11:19:22 jmg Exp $
*/
#ifndef _NFS_NFS_H_
@@ -722,7 +722,7 @@ int nfsrv_symlink __P((struct nfsrv_descript *nfsd,
struct proc *procp, struct mbuf **mrq));
int nfsrv_write __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
struct proc *procp, struct mbuf **mrq));
-void nfsrv_rcv __P((struct socket *so, caddr_t arg, int waitflag));
+void nfsrv_rcv __P((struct socket *so, void *arg, int waitflag));
void nfsrv_slpderef __P((struct nfssvc_sock *slp));
#endif /* KERNEL */
diff --git a/sys/nfsserver/nfs_srvsock.c b/sys/nfsserver/nfs_srvsock.c
index d4e1a0492033..693899f289b3 100644
--- a/sys/nfsserver/nfs_srvsock.c
+++ b/sys/nfsserver/nfs_srvsock.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95
- * $Id: nfs_socket.c,v 1.42 1998/07/15 02:32:24 bde Exp $
+ * $Id: nfs_socket.c,v 1.43 1998/08/01 09:04:02 peter Exp $
*/
/*
@@ -282,16 +282,28 @@ nfs_connect(nmp, rep)
if (nmp->nm_sotype != SOCK_STREAM)
panic("nfscon sotype");
if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
- MGET(m, M_WAIT, MT_SOOPTS);
- *mtod(m, int32_t *) = 1;
- m->m_len = sizeof(int32_t);
- sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m, p);
+ struct sockopt sopt;
+ int val;
+
+ bzero(&sopt, sizeof sopt);
+ sopt.sopt_level = SOL_SOCKET;
+ sopt.sopt_name = SO_KEEPALIVE;
+ sopt.sopt_val = &val;
+ sopt.sopt_valsize = sizeof val;
+ val = 1;
+ sosetopt(so, &sopt);
}
if (so->so_proto->pr_protocol == IPPROTO_TCP) {
- MGET(m, M_WAIT, MT_SOOPTS);
- *mtod(m, int32_t *) = 1;
- m->m_len = sizeof(int32_t);
- sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m, p);
+ struct sockopt sopt;
+ int val;
+
+ bzero(&sopt, sizeof sopt);
+ sopt.sopt_level = IPPROTO_TCP;
+ sopt.sopt_name = TCP_NODELAY;
+ sopt.sopt_val = &val;
+ sopt.sopt_valsize = sizeof val;
+ val = 1;
+ sosetopt(so, &sopt);
}
sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR +
sizeof (u_int32_t)) * 2;
@@ -1952,7 +1964,7 @@ nfs_msg(p, server, msg)
void
nfsrv_rcv(so, arg, waitflag)
struct socket *so;
- caddr_t arg;
+ void *arg;
int waitflag;
{
register struct nfssvc_sock *slp = (struct nfssvc_sock *)arg;
diff --git a/sys/nfsserver/nfs_syscalls.c b/sys/nfsserver/nfs_syscalls.c
index 08a1f1377daa..c6b92d5f597e 100644
--- a/sys/nfsserver/nfs_syscalls.c
+++ b/sys/nfsserver/nfs_syscalls.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95
- * $Id: nfs_syscalls.c,v 1.40 1998/05/31 18:46:06 peter Exp $
+ * $Id: nfs_syscalls.c,v 1.41 1998/05/31 20:08:55 peter Exp $
*/
#include <sys/param.h>
@@ -400,17 +400,29 @@ nfssvc_addsock(fp, mynam, p)
* repeatedly for the same socket, but that isn't harmful.
*/
if (so->so_type == SOCK_STREAM) {
- MGET(m, M_WAIT, MT_SOOPTS);
- *mtod(m, int32_t *) = 1;
- m->m_len = sizeof(int32_t);
- sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m, p);
+ struct sockopt sopt;
+ int val;
+
+ bzero(&sopt, sizeof sopt);
+ sopt.sopt_level = SOL_SOCKET;
+ sopt.sopt_name = SO_KEEPALIVE;
+ sopt.sopt_val = &val;
+ sopt.sopt_valsize = sizeof val;
+ val = 1;
+ sosetopt(so, &sopt);
}
if (so->so_proto->pr_domain->dom_family == AF_INET &&
so->so_proto->pr_protocol == IPPROTO_TCP) {
- MGET(m, M_WAIT, MT_SOOPTS);
- *mtod(m, int32_t *) = 1;
- m->m_len = sizeof(int32_t);
- sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m, p);
+ struct sockopt sopt;
+ int val;
+
+ bzero(&sopt, sizeof sopt);
+ sopt.sopt_level = IPPROTO_TCP;
+ sopt.sopt_name = TCP_NODELAY;
+ sopt.sopt_val = &val;
+ sopt.sopt_valsize = sizeof val;
+ val = 1;
+ sosetopt(so, &sopt);
}
so->so_rcv.sb_flags &= ~SB_NOINTR;
so->so_rcv.sb_timeo = 0;
diff --git a/sys/nfsserver/nfsrvstats.h b/sys/nfsserver/nfsrvstats.h
index e5be581fa031..885a2c19e17a 100644
--- a/sys/nfsserver/nfsrvstats.h
+++ b/sys/nfsserver/nfsrvstats.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
- * $Id: nfs.h,v 1.41 1998/06/30 03:01:37 jmg Exp $
+ * $Id: nfs.h,v 1.42 1998/06/30 11:19:22 jmg Exp $
*/
#ifndef _NFS_NFS_H_
@@ -722,7 +722,7 @@ int nfsrv_symlink __P((struct nfsrv_descript *nfsd,
struct proc *procp, struct mbuf **mrq));
int nfsrv_write __P((struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
struct proc *procp, struct mbuf **mrq));
-void nfsrv_rcv __P((struct socket *so, caddr_t arg, int waitflag));
+void nfsrv_rcv __P((struct socket *so, void *arg, int waitflag));
void nfsrv_slpderef __P((struct nfssvc_sock *slp));
#endif /* KERNEL */
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index 773a0e91eb07..b5e1233d781a 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)mbuf.h 8.5 (Berkeley) 2/19/95
- * $Id: mbuf.h,v 1.26 1997/12/28 01:04:47 bde Exp $
+ * $Id: mbuf.h,v 1.27 1998/07/15 04:17:53 bde Exp $
*/
#ifndef _SYS_MBUF_H_
@@ -138,7 +138,7 @@ struct mbuf {
/*efine MT_HTABLE 6*/ /* IMP host tables */
/*efine MT_ATABLE 7*/ /* address resolution tables */
#define MT_SONAME 8 /* socket name */
-#define MT_SOOPTS 10 /* socket options */
+/*efine MT_SOOPTS 10*/ /* socket options */
#define MT_FTABLE 11 /* fragment reassembly header */
/*efine MT_RIGHTS 12*/ /* access rights */
/*efine MT_IFADDR 13*/ /* interface address */
@@ -168,10 +168,10 @@ union mcluster {
* drivers.
*/
#define MBUFLOCK(code) \
- { int ms = splimp(); \
+ do { int ms = splimp(); \
{ code } \
splx(ms); \
- }
+ } while(0)
/*
* mbuf allocation/deallocation macros:
@@ -348,10 +348,10 @@ union mcluster {
}
/* change mbuf to new type */
-#define MCHTYPE(m, t) { \
- MBUFLOCK(mbstat.m_mtypes[(m)->m_type]--; mbstat.m_mtypes[t]++;) \
+#define MCHTYPE(m, t) do { \
+ MBUFLOCK(mbstat.m_mtypes[(m)->m_type]--; mbstat.m_mtypes[t]++;); \
(m)->m_type = t;\
-}
+} while(0)
/* length to m_copy to copy all */
#define M_COPYALL 1000000000
diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h
index 64aa7e02e4e4..f016fc0f1cf3 100644
--- a/sys/sys/protosw.h
+++ b/sys/sys/protosw.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)protosw.h 8.1 (Berkeley) 6/2/93
- * $Id: protosw.h,v 1.23 1998/02/01 20:08:37 bde Exp $
+ * $Id: protosw.h,v 1.24 1998/06/07 17:13:03 dfr Exp $
*/
#ifndef _SYS_PROTOSW_H_
@@ -42,6 +42,7 @@ struct mbuf;
struct proc;
struct sockaddr;
struct socket;
+struct sockopt;
/*#ifdef KERNEL*/
/*
@@ -58,13 +59,13 @@ struct socket;
*
* Protocols pass data between themselves as chains of mbufs using
* the pr_input and pr_output hooks. Pr_input passes data up (towards
- * UNIX) and pr_output passes it down (towards the imps); control
+ * the users) and pr_output passes it down (towards the interfaces); control
* information passes up and down on pr_ctlinput and pr_ctloutput.
* The protocol is responsible for the space occupied by any the
* arguments to these entries and must dispose it.
*
- * The userreq routine interfaces protocols to the system and is
- * described below.
+ * In retrospect, it would be a lot nicer to use an interface
+ * similar to the vnode VOP interface.
*/
struct protosw {
short pr_type; /* socket type used for */
@@ -78,8 +79,7 @@ struct protosw {
/* output to protocol (from above) */
void (*pr_ctlinput)__P((int, struct sockaddr *, void *));
/* control input (from below) */
- int (*pr_ctloutput)__P((int, struct socket *, int, int,
- struct mbuf **, struct proc *));
+ int (*pr_ctloutput)__P((struct socket *, struct sockopt *));
/* control output (from above) */
/* user-protocol hook */
void *pr_ousrreq;
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h
index a55153bf0fe1..86c17edcf0fc 100644
--- a/sys/sys/socketvar.h
+++ b/sys/sys/socketvar.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)socketvar.h 8.3 (Berkeley) 2/19/95
- * $Id: socketvar.h,v 1.27 1998/05/31 18:37:22 peter Exp $
+ * $Id: socketvar.h,v 1.28 1998/06/07 17:13:03 dfr Exp $
*/
#ifndef _SYS_SOCKETVAR_H_
@@ -102,9 +102,10 @@ struct socket {
#define SB_UPCALL 0x20 /* someone wants an upcall */
#define SB_NOINTR 0x40 /* operations not interruptible */
- void (*so_upcall) __P((struct socket *so, caddr_t arg, int waitf));
- caddr_t so_upcallarg; /* Arg for above */
+ void (*so_upcall) __P((struct socket *, void *, int));
+ void *so_upcallarg;
uid_t so_uid; /* who opened the socket */
+ /* NB: generation count must not be first; easiest to make it last. */
so_gen_t so_gencnt; /* generation count */
};
@@ -119,7 +120,6 @@ struct socket {
#define SS_CANTRCVMORE 0x0020 /* can't receive more data from peer */
#define SS_RCVATMARK 0x0040 /* at mark on input */
-/*efine SS_PRIV 0x0080 privileged for broadcast, raw... */
#define SS_NBIO 0x0100 /* non-blocking ops */
#define SS_ASYNC 0x0200 /* async i/o notify */
#define SS_ISCONFIRMING 0x0400 /* deciding to accept connection req */
@@ -242,6 +242,20 @@ struct xsocket {
#ifdef KERNEL
+/*
+ * Argument structure for sosetopt et seq. This is in the KERNEL
+ * section because it will never be visible to user code.
+ */
+enum sopt_dir { SOPT_GET, SOPT_SET };
+struct sockopt {
+ enum sopt_dir sopt_dir; /* is this a get or a set? */
+ int sopt_level; /* second arg of [gs]etsockopt */
+ int sopt_name; /* third arg of [gs]etsockopt */
+ void *sopt_val; /* fourth arg of [gs]etsockopt */
+ size_t sopt_valsize; /* (almost) fifth arg of [gs]etsockopt */
+ struct proc *sopt_p; /* calling process or null if kernel */
+};
+
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_PCB);
MALLOC_DECLARE(M_SONAME);
@@ -309,8 +323,7 @@ int socreate __P((int dom, struct socket **aso, int type, int proto,
void sodealloc __P((struct socket *so));
int sodisconnect __P((struct socket *so));
void sofree __P((struct socket *so));
-int sogetopt __P((struct socket *so, int level, int optname,
- struct mbuf **mp, struct proc *p));
+int sogetopt __P((struct socket *so, struct sockopt *sopt));
void sohasoutofband __P((struct socket *so));
void soisconnected __P((struct socket *so));
void soisconnecting __P((struct socket *so));
@@ -321,6 +334,9 @@ struct socket *
sodropablereq __P((struct socket *head));
struct socket *
sonewconn __P((struct socket *head, int connstatus));
+int sooptcopyin __P((struct sockopt *sopt, void *buf, size_t len,
+ size_t minlen));
+int sooptcopyout __P((struct sockopt *sopt, void *buf, size_t len));
int sopoll __P((struct socket *so, int events, struct ucred *cred,
struct proc *p));
int soreceive __P((struct socket *so, struct sockaddr **paddr,
@@ -331,8 +347,7 @@ void sorflush __P((struct socket *so));
int sosend __P((struct socket *so, struct sockaddr *addr, struct uio *uio,
struct mbuf *top, struct mbuf *control, int flags,
struct proc *p));
-int sosetopt __P((struct socket *so, int level, int optname,
- struct mbuf *m0, struct proc *p));
+int sosetopt __P((struct socket *so, struct sockopt *sopt));
int soshutdown __P((struct socket *so, int how));
void sotoxsocket __P((struct socket *so, struct xsocket *xso));
void sowakeup __P((struct socket *so, struct sockbuf *sb));