summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_syscalls.c
diff options
context:
space:
mode:
authorwollman <wollman@FreeBSD.org>1998-08-23 03:07:17 +0000
committerwollman <wollman@FreeBSD.org>1998-08-23 03:07:17 +0000
commita76fb5eefabdc9418c911bf0b61768d533c15cbd (patch)
tree02b1e59b8833c25c113cc2a72ebb74ec057423bb /sys/kern/uipc_syscalls.c
parent3846bf0ec8c81eca47577791dff72e8b96928749 (diff)
downloadFreeBSD-src-a76fb5eefabdc9418c911bf0b61768d533c15cbd.zip
FreeBSD-src-a76fb5eefabdc9418c911bf0b61768d533c15cbd.tar.gz
Yow! Completely change the way socket options are handled, eliminating
another specialized mbuf type in the process. Also clean up some of the cruft surrounding IPFW, multicast routing, RSVP, and other ill-explored corners.
Diffstat (limited to 'sys/kern/uipc_syscalls.c')
-rw-r--r--sys/kern/uipc_syscalls.c78
1 files changed, 34 insertions, 44 deletions
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index db764de..a841bfa 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);
}
OpenPOWER on IntegriCloud