diff options
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/sys_socket.c | 5 | ||||
-rw-r--r-- | sys/kern/uipc_sockbuf.c | 165 | ||||
-rw-r--r-- | sys/kern/uipc_socket.c | 38 | ||||
-rw-r--r-- | sys/kern/uipc_socket2.c | 165 | ||||
-rw-r--r-- | sys/kern/uipc_syscalls.c | 158 | ||||
-rw-r--r-- | sys/kern/uipc_usrreq.c | 112 | ||||
-rw-r--r-- | sys/kern/vfs_export.c | 6 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 6 |
8 files changed, 222 insertions, 433 deletions
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c index 8e9e90e..e0394b7 100644 --- a/sys/kern/sys_socket.c +++ b/sys/kern/sys_socket.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)sys_socket.c 8.1 (Berkeley) 6/10/93 - * $Id: sys_socket.c,v 1.13 1997/04/27 20:00:42 wollman Exp $ + * $Id: sys_socket.c,v 1.14 1997/08/02 14:31:36 bde Exp $ */ #include <sys/param.h> @@ -75,7 +75,8 @@ soo_write(fp, uio, cred) struct ucred *cred; { struct socket *so = (struct socket *)fp->f_data; - return so->so_proto->pr_usrreqs->pru_sosend(so, 0, uio, 0, 0, 0); + return so->so_proto->pr_usrreqs->pru_sosend(so, 0, uio, 0, 0, 0, + uio->uio_procp); } int diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index 978b46a..b20b9ee 100644 --- a/sys/kern/uipc_sockbuf.c +++ b/sys/kern/uipc_sockbuf.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93 - * $Id: uipc_socket2.c,v 1.25 1997/05/24 17:23:10 peter Exp $ + * $Id: uipc_socket2.c,v 1.26 1997/07/19 20:15:35 fenner Exp $ */ #include <sys/param.h> @@ -814,159 +814,18 @@ sbcreatecontrol(p, size, type, level) return (m); } -#ifdef PRU_OLDSTYLE -/* - * The following routines mediate between the old-style `pr_usrreq' - * protocol implementations and the new-style `struct pr_usrreqs' - * calling convention. - */ - -/* syntactic sugar */ -#define nomb (struct mbuf *)0 - -static int -old_abort(struct socket *so) -{ - return so->so_proto->pr_ousrreq(so, PRU_ABORT, nomb, nomb, nomb); -} - -static int -old_accept(struct socket *so, struct mbuf *nam) -{ - return so->so_proto->pr_ousrreq(so, PRU_ACCEPT, nomb, nam, nomb); -} - -static int -old_attach(struct socket *so, int proto) -{ - return so->so_proto->pr_ousrreq(so, PRU_ATTACH, nomb, - (struct mbuf *)proto, /* XXX */ - nomb); -} - -static int -old_bind(struct socket *so, struct mbuf *nam) -{ - return so->so_proto->pr_ousrreq(so, PRU_BIND, nomb, nam, nomb); -} - -static int -old_connect(struct socket *so, struct mbuf *nam) -{ - return so->so_proto->pr_ousrreq(so, PRU_CONNECT, nomb, nam, nomb); -} - -static int -old_connect2(struct socket *so1, struct socket *so2) -{ - return so1->so_proto->pr_ousrreq(so1, PRU_CONNECT2, nomb, - (struct mbuf *)so2, nomb); -} - -static int -old_control(struct socket *so, int cmd, caddr_t data, struct ifnet *ifp) -{ - return so->so_proto->pr_ousrreq(so, PRU_CONTROL, (struct mbuf *)cmd, - (struct mbuf *)data, - (struct mbuf *)ifp); -} - -static int -old_detach(struct socket *so) -{ - return so->so_proto->pr_ousrreq(so, PRU_DETACH, nomb, nomb, nomb); -} - -static int -old_disconnect(struct socket *so) -{ - return so->so_proto->pr_ousrreq(so, PRU_DISCONNECT, nomb, nomb, nomb); -} - -static int -old_listen(struct socket *so) -{ - return so->so_proto->pr_ousrreq(so, PRU_LISTEN, nomb, nomb, nomb); -} - -static int -old_peeraddr(struct socket *so, struct mbuf *nam) -{ - return so->so_proto->pr_ousrreq(so, PRU_PEERADDR, nomb, nam, nomb); -} - -static int -old_rcvd(struct socket *so, int flags) -{ - return so->so_proto->pr_ousrreq(so, PRU_RCVD, nomb, - (struct mbuf *)flags, /* XXX */ - nomb); -} - -static int -old_rcvoob(struct socket *so, struct mbuf *m, int flags) -{ - return so->so_proto->pr_ousrreq(so, PRU_RCVOOB, m, - (struct mbuf *)flags, /* XXX */ - nomb); -} - -static int -old_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *addr, - struct mbuf *control) -{ - int req; - - if (flags & PRUS_OOB) { - req = PRU_SENDOOB; - } else if(flags & PRUS_EOF) { - req = PRU_SEND_EOF; - } else { - req = PRU_SEND; - } - return so->so_proto->pr_ousrreq(so, req, m, addr, control); -} - -static int -old_sense(struct socket *so, struct stat *sb) -{ - return so->so_proto->pr_ousrreq(so, PRU_SENSE, (struct mbuf *)sb, - nomb, nomb); -} - -static int -old_shutdown(struct socket *so) -{ - return so->so_proto->pr_ousrreq(so, PRU_SHUTDOWN, nomb, nomb, nomb); -} - -static int -old_sockaddr(struct socket *so, struct mbuf *nam) -{ - return so->so_proto->pr_ousrreq(so, PRU_SOCKADDR, nomb, nam, nomb); -} - -struct pr_usrreqs pru_oldstyle = { - old_abort, old_accept, old_attach, old_bind, old_connect, - old_connect2, old_control, old_detach, old_disconnect, - old_listen, old_peeraddr, old_rcvd, old_rcvoob, old_send, - old_sense, old_shutdown, old_sockaddr -}; - -#endif /* PRU_OLDSTYLE */ - /* * Some routines that return EOPNOTSUPP for entry points that are not * supported by a protocol. Fill in as needed. */ int -pru_accept_notsupp(struct socket *so, struct mbuf *nam) +pru_accept_notsupp(struct socket *so, struct sockaddr **nam) { return EOPNOTSUPP; } int -pru_connect_notsupp(struct socket *so, struct mbuf *nam, struct proc *p) +pru_connect_notsupp(struct socket *so, struct sockaddr *nam, struct proc *p) { return EOPNOTSUPP; } @@ -1014,6 +873,23 @@ pru_sense_null(struct socket *so, struct stat *sb) } /* + * Make a copy of a sockaddr in a malloced buffer of type M_SONAME. + */ +struct sockaddr * +dup_sockaddr(sa, canwait) + struct sockaddr *sa; + int canwait; +{ + struct sockaddr *sa2; + + MALLOC(sa2, struct sockaddr *, sa->sa_len, M_SONAME, + canwait ? M_WAITOK : M_NOWAIT); + if (sa2) + bcopy(sa, sa2, sa->sa_len); + return sa2; +} + +/* * Here is the definition of some of the basic objects in the kern.ipc * branch of the MIB. */ @@ -1026,3 +902,4 @@ SYSCTL_INT(_kern, KERN_DUMMY, dummy, CTLFLAG_RW, &dummy, 0, ""); SYSCTL_INT(_kern_ipc, KIPC_MAXSOCKBUF, maxsockbuf, CTLFLAG_RW, &sb_max, 0, "") SYSCTL_INT(_kern_ipc, KIPC_SOCKBUF_WASTE, sockbuf_waste_factor, CTLFLAG_RW, &sb_efficiency, 0, ""); + diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 8c1319a..8a554d0 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.26 1997/04/27 20:00:44 wollman Exp $ + * $Id: uipc_socket.c,v 1.27 1997/06/27 15:28:54 peter Exp $ */ #include <sys/param.h> @@ -101,7 +101,7 @@ socreate(dom, aso, type, proto, p) int sobind(so, nam, p) struct socket *so; - struct mbuf *nam; + struct sockaddr *nam; struct proc *p; { int s = splnet(); @@ -233,7 +233,7 @@ soabort(so) int soaccept(so, nam) register struct socket *so; - struct mbuf *nam; + struct sockaddr **nam; { int s = splnet(); int error; @@ -249,7 +249,7 @@ soaccept(so, nam) int soconnect(so, nam, p) register struct socket *so; - struct mbuf *nam; + struct sockaddr *nam; struct proc *p; { int s; @@ -327,15 +327,15 @@ bad: * Data and control buffers are freed on return. */ int -sosend(so, addr, uio, top, control, flags) +sosend(so, addr, uio, top, control, flags, p) register struct socket *so; - struct mbuf *addr; + struct sockaddr *addr; struct uio *uio; struct mbuf *top; struct mbuf *control; int flags; + struct proc *p; { - struct proc *p = curproc; /* XXX */ struct mbuf **mp; register struct mbuf *m; register long space, len, resid; @@ -512,9 +512,9 @@ out: * only for the count in uio_resid. */ int -soreceive(so, paddr, uio, mp0, controlp, flagsp) +soreceive(so, psa, uio, mp0, controlp, flagsp) register struct socket *so; - struct mbuf **paddr; + struct sockaddr **psa; struct uio *uio; struct mbuf **mp0; struct mbuf **controlp; @@ -528,8 +528,8 @@ soreceive(so, paddr, uio, mp0, controlp, flagsp) int orig_resid = uio->uio_resid; mp = mp0; - if (paddr) - *paddr = 0; + if (psa) + *psa = 0; if (controlp) *controlp = 0; if (flagsp) @@ -630,21 +630,15 @@ dontblock: panic("receive 1a"); #endif orig_resid = 0; + if (psa) + *psa = dup_sockaddr(mtod(m, struct sockaddr *), + mp0 == 0); if (flags & MSG_PEEK) { - if (paddr) - *paddr = m_copy(m, 0, m->m_len); m = m->m_next; } else { sbfree(&so->so_rcv, m); - if (paddr) { - *paddr = m; - so->so_rcv.sb_mb = m->m_next; - m->m_next = 0; - m = so->so_rcv.sb_mb; - } else { - MFREE(m, so->so_rcv.sb_mb); - m = so->so_rcv.sb_mb; - } + MFREE(m, so->so_rcv.sb_mb); + m = so->so_rcv.sb_mb; } } while (m && m->m_type == MT_CONTROL && error == 0) { diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index 978b46a..b20b9ee 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93 - * $Id: uipc_socket2.c,v 1.25 1997/05/24 17:23:10 peter Exp $ + * $Id: uipc_socket2.c,v 1.26 1997/07/19 20:15:35 fenner Exp $ */ #include <sys/param.h> @@ -814,159 +814,18 @@ sbcreatecontrol(p, size, type, level) return (m); } -#ifdef PRU_OLDSTYLE -/* - * The following routines mediate between the old-style `pr_usrreq' - * protocol implementations and the new-style `struct pr_usrreqs' - * calling convention. - */ - -/* syntactic sugar */ -#define nomb (struct mbuf *)0 - -static int -old_abort(struct socket *so) -{ - return so->so_proto->pr_ousrreq(so, PRU_ABORT, nomb, nomb, nomb); -} - -static int -old_accept(struct socket *so, struct mbuf *nam) -{ - return so->so_proto->pr_ousrreq(so, PRU_ACCEPT, nomb, nam, nomb); -} - -static int -old_attach(struct socket *so, int proto) -{ - return so->so_proto->pr_ousrreq(so, PRU_ATTACH, nomb, - (struct mbuf *)proto, /* XXX */ - nomb); -} - -static int -old_bind(struct socket *so, struct mbuf *nam) -{ - return so->so_proto->pr_ousrreq(so, PRU_BIND, nomb, nam, nomb); -} - -static int -old_connect(struct socket *so, struct mbuf *nam) -{ - return so->so_proto->pr_ousrreq(so, PRU_CONNECT, nomb, nam, nomb); -} - -static int -old_connect2(struct socket *so1, struct socket *so2) -{ - return so1->so_proto->pr_ousrreq(so1, PRU_CONNECT2, nomb, - (struct mbuf *)so2, nomb); -} - -static int -old_control(struct socket *so, int cmd, caddr_t data, struct ifnet *ifp) -{ - return so->so_proto->pr_ousrreq(so, PRU_CONTROL, (struct mbuf *)cmd, - (struct mbuf *)data, - (struct mbuf *)ifp); -} - -static int -old_detach(struct socket *so) -{ - return so->so_proto->pr_ousrreq(so, PRU_DETACH, nomb, nomb, nomb); -} - -static int -old_disconnect(struct socket *so) -{ - return so->so_proto->pr_ousrreq(so, PRU_DISCONNECT, nomb, nomb, nomb); -} - -static int -old_listen(struct socket *so) -{ - return so->so_proto->pr_ousrreq(so, PRU_LISTEN, nomb, nomb, nomb); -} - -static int -old_peeraddr(struct socket *so, struct mbuf *nam) -{ - return so->so_proto->pr_ousrreq(so, PRU_PEERADDR, nomb, nam, nomb); -} - -static int -old_rcvd(struct socket *so, int flags) -{ - return so->so_proto->pr_ousrreq(so, PRU_RCVD, nomb, - (struct mbuf *)flags, /* XXX */ - nomb); -} - -static int -old_rcvoob(struct socket *so, struct mbuf *m, int flags) -{ - return so->so_proto->pr_ousrreq(so, PRU_RCVOOB, m, - (struct mbuf *)flags, /* XXX */ - nomb); -} - -static int -old_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *addr, - struct mbuf *control) -{ - int req; - - if (flags & PRUS_OOB) { - req = PRU_SENDOOB; - } else if(flags & PRUS_EOF) { - req = PRU_SEND_EOF; - } else { - req = PRU_SEND; - } - return so->so_proto->pr_ousrreq(so, req, m, addr, control); -} - -static int -old_sense(struct socket *so, struct stat *sb) -{ - return so->so_proto->pr_ousrreq(so, PRU_SENSE, (struct mbuf *)sb, - nomb, nomb); -} - -static int -old_shutdown(struct socket *so) -{ - return so->so_proto->pr_ousrreq(so, PRU_SHUTDOWN, nomb, nomb, nomb); -} - -static int -old_sockaddr(struct socket *so, struct mbuf *nam) -{ - return so->so_proto->pr_ousrreq(so, PRU_SOCKADDR, nomb, nam, nomb); -} - -struct pr_usrreqs pru_oldstyle = { - old_abort, old_accept, old_attach, old_bind, old_connect, - old_connect2, old_control, old_detach, old_disconnect, - old_listen, old_peeraddr, old_rcvd, old_rcvoob, old_send, - old_sense, old_shutdown, old_sockaddr -}; - -#endif /* PRU_OLDSTYLE */ - /* * Some routines that return EOPNOTSUPP for entry points that are not * supported by a protocol. Fill in as needed. */ int -pru_accept_notsupp(struct socket *so, struct mbuf *nam) +pru_accept_notsupp(struct socket *so, struct sockaddr **nam) { return EOPNOTSUPP; } int -pru_connect_notsupp(struct socket *so, struct mbuf *nam, struct proc *p) +pru_connect_notsupp(struct socket *so, struct sockaddr *nam, struct proc *p) { return EOPNOTSUPP; } @@ -1014,6 +873,23 @@ pru_sense_null(struct socket *so, struct stat *sb) } /* + * Make a copy of a sockaddr in a malloced buffer of type M_SONAME. + */ +struct sockaddr * +dup_sockaddr(sa, canwait) + struct sockaddr *sa; + int canwait; +{ + struct sockaddr *sa2; + + MALLOC(sa2, struct sockaddr *, sa->sa_len, M_SONAME, + canwait ? M_WAITOK : M_NOWAIT); + if (sa2) + bcopy(sa, sa2, sa->sa_len); + return sa2; +} + +/* * Here is the definition of some of the basic objects in the kern.ipc * branch of the MIB. */ @@ -1026,3 +902,4 @@ SYSCTL_INT(_kern, KERN_DUMMY, dummy, CTLFLAG_RW, &dummy, 0, ""); SYSCTL_INT(_kern_ipc, KIPC_MAXSOCKBUF, maxsockbuf, CTLFLAG_RW, &sb_max, 0, "") SYSCTL_INT(_kern_ipc, KIPC_SOCKBUF_WASTE, sockbuf_waste_factor, CTLFLAG_RW, &sb_efficiency, 0, ""); + diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index fb8f428..409f68f 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.25 1997/04/09 16:53:40 bde Exp $ + * $Id: uipc_syscalls.c,v 1.26 1997/04/27 20:00:45 wollman Exp $ */ #include "opt_ktrace.h" @@ -121,17 +121,17 @@ bind(p, uap, retval) int *retval; { struct file *fp; - struct mbuf *nam; + struct sockaddr *sa; int error; error = getsock(p->p_fd, uap->s, &fp); if (error) return (error); - error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME); + error = getsockaddr(&sa, uap->name, uap->namelen); if (error) return (error); - error = sobind((struct socket *)fp->f_data, nam, p); - m_freem(nam); + error = sobind((struct socket *)fp->f_data, sa, p); + FREE(sa, M_SONAME); return (error); } @@ -166,7 +166,7 @@ accept1(p, uap, retval, compat) int compat; { struct file *fp; - struct mbuf *nam; + struct sockaddr *sa; int namelen, error, s; struct socket *head, *so; short fflag; /* type must match fp->f_flag */ @@ -243,24 +243,32 @@ accept1(p, uap, retval, compat) fp->f_flag = fflag; fp->f_ops = &socketops; fp->f_data = (caddr_t)so; - nam = m_get(M_WAIT, MT_SONAME); - (void) soaccept(so, nam); + sa = 0; + (void) soaccept(so, &sa); + if (sa == 0) { + namelen = 0; + if (uap->name) + goto gotnoname; + return 0; + } + if ((u_long)sa < 0xf0000000) { + panic("accept1 bad sa"); + } if (uap->name) { #ifdef COMPAT_OLDSOCK if (compat) - mtod(nam, struct osockaddr *)->sa_family = - mtod(nam, struct sockaddr *)->sa_family; + ((struct osockaddr *)sa)->sa_family = + sa->sa_family; #endif - if (namelen > nam->m_len) - namelen = nam->m_len; - /* SHOULD COPY OUT A CHAIN HERE */ - error = copyout(mtod(nam, caddr_t), (caddr_t)uap->name, - (u_int)namelen); + if (namelen > sa->sa_len) + namelen = sa->sa_len; + error = copyout(sa, (caddr_t)uap->name, (u_int)namelen); if (!error) +gotnoname: error = copyout((caddr_t)&namelen, (caddr_t)uap->anamelen, sizeof (*uap->anamelen)); } - m_freem(nam); + FREE(sa, M_SONAME); splx(s); return (error); } @@ -300,7 +308,7 @@ connect(p, uap, retval) { struct file *fp; register struct socket *so; - struct mbuf *nam; + struct sockaddr *sa; int error, s; error = getsock(p->p_fd, uap->s, &fp); @@ -309,14 +317,14 @@ connect(p, uap, retval) so = (struct socket *)fp->f_data; if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) return (EALREADY); - error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME); + error = getsockaddr(&sa, uap->name, uap->namelen); if (error) return (error); - error = soconnect(so, nam, p); + error = soconnect(so, sa, p); if (error) goto bad; if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { - m_freem(nam); + FREE(sa, M_SONAME); return (EINPROGRESS); } s = splnet(); @@ -333,7 +341,7 @@ connect(p, uap, retval) splx(s); bad: so->so_state &= ~SS_ISCONNECTING; - m_freem(nam); + FREE(sa, M_SONAME); if (error == ERESTART) error = EINTR; return (error); @@ -418,7 +426,8 @@ sendit(p, s, mp, flags, retsize) struct uio auio; register struct iovec *iov; register int i; - struct mbuf *to, *control; + struct mbuf *control; + struct sockaddr *to; int len, error; struct socket *so; #ifdef KTRACE @@ -441,7 +450,7 @@ sendit(p, s, mp, flags, retsize) return (EINVAL); } if (mp->msg_name) { - error = sockargs(&to, mp->msg_name, mp->msg_namelen, MT_SONAME); + error = getsockaddr(&to, mp->msg_name, mp->msg_namelen); if (error) return (error); } else @@ -488,7 +497,7 @@ sendit(p, s, mp, flags, retsize) len = auio.uio_resid; so = (struct socket *)fp->f_data; error = so->so_proto->pr_usrreqs->pru_sosend(so, to, &auio, 0, control, - flags); + flags, p); if (error) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) @@ -508,7 +517,7 @@ sendit(p, s, mp, flags, retsize) #endif bad: if (to) - m_freem(to); + FREE(to, M_SONAME); return (error); } @@ -659,9 +668,10 @@ recvit(p, s, mp, namelenp, retsize) register struct iovec *iov; register int i; int len, error; - struct mbuf *m, *from = 0, *control = 0; + struct mbuf *m, *control = 0; caddr_t ctlbuf; struct socket *so; + struct sockaddr *fromsa = 0; #ifdef KTRACE struct iovec *ktriov = NULL; #endif @@ -691,7 +701,7 @@ recvit(p, s, mp, namelenp, retsize) #endif len = auio.uio_resid; so = (struct socket *)fp->f_data; - error = so->so_proto->pr_usrreqs->pru_soreceive(so, &from, &auio, + error = so->so_proto->pr_usrreqs->pru_soreceive(so, &fromsa, &auio, (struct mbuf **)0, mp->msg_control ? &control : (struct mbuf **)0, &mp->msg_flags); if (error) { @@ -712,18 +722,19 @@ recvit(p, s, mp, namelenp, retsize) *retsize = len - auio.uio_resid; if (mp->msg_name) { len = mp->msg_namelen; - if (len <= 0 || from == 0) + if (len <= 0 || fromsa == 0) len = 0; else { #ifdef COMPAT_OLDSOCK if (mp->msg_flags & MSG_COMPAT) - mtod(from, struct osockaddr *)->sa_family = - mtod(from, struct sockaddr *)->sa_family; + ((struct osockaddr *)fromsa)->sa_family = + fromsa->sa_family; +#endif +#ifndef MIN +#define MIN(a,b) ((a)>(b)?(b):(a)) #endif - if (len > from->m_len) - len = from->m_len; - /* else if len < from->m_len ??? */ - error = copyout(mtod(from, caddr_t), + len = MIN(len, fromsa->sa_len); + error = copyout(fromsa, (caddr_t)mp->msg_name, (unsigned)len); if (error) goto out; @@ -786,8 +797,8 @@ recvit(p, s, mp, namelenp, retsize) mp->msg_controllen = ctlbuf - mp->msg_control; } out: - if (from) - m_freem(from); + if (fromsa) + FREE(fromsa, M_SONAME); if (control) m_freem(control); return (error); @@ -1084,7 +1095,7 @@ getsockname1(p, uap, retval, compat) { struct file *fp; register struct socket *so; - struct mbuf *m; + struct sockaddr *sa; int len, error; error = getsock(p->p_fd, uap->fdes, &fp); @@ -1094,25 +1105,28 @@ getsockname1(p, uap, retval, compat) if (error) return (error); so = (struct socket *)fp->f_data; - m = m_getclr(M_WAIT, MT_SONAME); - if (m == NULL) - return (ENOBUFS); - error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, m); + sa = 0; + error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, &sa); if (error) goto bad; - if (len > m->m_len) - len = m->m_len; + if (sa == 0) { + len = 0; + goto gotnothing; + } + + len = MIN(len, sa->sa_len); #ifdef COMPAT_OLDSOCK if (compat) - mtod(m, struct osockaddr *)->sa_family = - mtod(m, struct sockaddr *)->sa_family; + ((struct osockaddr *)sa)->sa_family = sa->sa_family; #endif - error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len); + error = copyout(sa, (caddr_t)uap->asa, (u_int)len); if (error == 0) +gotnothing: error = copyout((caddr_t)&len, (caddr_t)uap->alen, sizeof (len)); bad: - m_freem(m); + if (sa) + FREE(sa, M_SONAME); return (error); } @@ -1155,7 +1169,7 @@ getpeername1(p, uap, retval, compat) { struct file *fp; register struct socket *so; - struct mbuf *m; + struct sockaddr *sa; int len, error; error = getsock(p->p_fd, uap->fdes, &fp); @@ -1167,25 +1181,27 @@ getpeername1(p, uap, retval, compat) error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)); if (error) return (error); - m = m_getclr(M_WAIT, MT_SONAME); - if (m == NULL) - return (ENOBUFS); - error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, m); + sa = 0; + error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, &sa); if (error) goto bad; - if (len > m->m_len) - len = m->m_len; + if (sa == 0) { + len = 0; + goto gotnothing; + } + len = MIN(len, sa->sa_len); #ifdef COMPAT_OLDSOCK if (compat) - mtod(m, struct osockaddr *)->sa_family = - mtod(m, struct sockaddr *)->sa_family; + ((struct osockaddr *)sa)->sa_family = + sa->sa_family; #endif - error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len); + error = copyout(sa, (caddr_t)uap->asa, (u_int)len); if (error) goto bad; +gotnothing: error = copyout((caddr_t)&len, (caddr_t)uap->alen, sizeof (len)); bad: - m_freem(m); + if (sa) FREE(sa, M_SONAME); return (error); } @@ -1253,6 +1269,32 @@ sockargs(mp, buf, buflen, type) } int +getsockaddr(namp, uaddr, len) + struct sockaddr **namp; + caddr_t uaddr; + size_t len; +{ + struct sockaddr *sa; + int error; + + if (len > SOCK_MAXADDRLEN) + return ENAMETOOLONG; + MALLOC(sa, struct sockaddr *, len, M_SONAME, M_WAITOK); + error = copyin(uaddr, sa, len); + if (error) { + FREE(sa, M_SONAME); + } else { +#if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN + if (sa->sa_family == 0 && sa->sa_len < AF_MAX) + sa->sa_family = sa->sa_len; +#endif + sa->sa_len = len; + *namp = sa; + } + return error; +} + +int getsock(fdp, fdes, fpp) struct filedesc *fdp; int fdes; diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 2734778d..a908e19 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * From: @(#)uipc_usrreq.c 8.3 (Berkeley) 1/4/94 - * $Id: uipc_usrreq.c,v 1.22 1997/03/23 03:36:33 bde Exp $ + * $Id: uipc_usrreq.c,v 1.23 1997/04/27 20:00:46 wollman Exp $ */ #include <sys/param.h> @@ -67,8 +67,9 @@ static ino_t unp_ino; /* prototype for fake inode numbers */ static int unp_attach __P((struct socket *)); static void unp_detach __P((struct unpcb *)); -static int unp_bind __P((struct unpcb *,struct mbuf *, struct proc *)); -static int unp_connect __P((struct socket *,struct mbuf *, struct proc *)); +static int unp_bind __P((struct unpcb *,struct sockaddr *, struct proc *)); +static int unp_connect __P((struct socket *,struct sockaddr *, + struct proc *)); static void unp_disconnect __P((struct unpcb *)); static void unp_shutdown __P((struct unpcb *)); static void unp_drop __P((struct unpcb *, int)); @@ -90,7 +91,7 @@ uipc_abort(struct socket *so) } static int -uipc_accept(struct socket *so, struct mbuf *nam) +uipc_accept(struct socket *so, struct sockaddr **nam) { struct unpcb *unp = sotounpcb(so); @@ -103,12 +104,10 @@ uipc_accept(struct socket *so, struct mbuf *nam) * (our peer may have closed already!). */ if (unp->unp_conn && unp->unp_conn->unp_addr) { - nam->m_len = unp->unp_conn->unp_addr->m_len; - bcopy(mtod(unp->unp_conn->unp_addr, caddr_t), - mtod(nam, caddr_t), (unsigned)nam->m_len); + *nam = dup_sockaddr((struct sockaddr *)unp->unp_conn->unp_addr, + 1); } else { - nam->m_len = sizeof(sun_noname); - *(mtod(nam, struct sockaddr *)) = sun_noname; + *nam = dup_sockaddr((struct sockaddr *)&sun_noname, 1); } return 0; } @@ -124,7 +123,7 @@ uipc_attach(struct socket *so, int proto, struct proc *p) } static int -uipc_bind(struct socket *so, struct mbuf *nam, struct proc *p) +uipc_bind(struct socket *so, struct sockaddr *nam, struct proc *p) { struct unpcb *unp = sotounpcb(so); @@ -135,7 +134,7 @@ uipc_bind(struct socket *so, struct mbuf *nam, struct proc *p) } static int -uipc_connect(struct socket *so, struct mbuf *nam, struct proc *p) +uipc_connect(struct socket *so, struct sockaddr *nam, struct proc *p) { struct unpcb *unp = sotounpcb(so); @@ -191,18 +190,15 @@ uipc_listen(struct socket *so, struct proc *p) } static int -uipc_peeraddr(struct socket *so, struct mbuf *nam) +uipc_peeraddr(struct socket *so, struct sockaddr **nam) { struct unpcb *unp = sotounpcb(so); if (unp == 0) return EINVAL; - if (unp->unp_conn && unp->unp_conn->unp_addr) { - nam->m_len = unp->unp_conn->unp_addr->m_len; - bcopy(mtod(unp->unp_conn->unp_addr, caddr_t), - mtod(nam, caddr_t), (unsigned)nam->m_len); - } else - nam->m_len = 0; + if (unp->unp_conn && unp->unp_conn->unp_addr) + *nam = dup_sockaddr((struct sockaddr *)unp->unp_conn->unp_addr, + 1); return 0; } @@ -247,7 +243,7 @@ uipc_rcvd(struct socket *so, int flags) /* pru_rcvoob is EOPNOTSUPP */ static int -uipc_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *nam, +uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, struct mbuf *control, struct proc *p) { int error = 0; @@ -287,7 +283,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *nam, } so2 = unp->unp_conn->unp_socket; if (unp->unp_addr) - from = mtod(unp->unp_addr, struct sockaddr *); + from = (struct sockaddr *)unp->unp_addr; else from = &sun_noname; if (sbappendaddr(&so2->so_rcv, from, m, control)) { @@ -402,18 +398,14 @@ uipc_shutdown(struct socket *so) } static int -uipc_sockaddr(struct socket *so, struct mbuf *nam) +uipc_sockaddr(struct socket *so, struct sockaddr **nam) { struct unpcb *unp = sotounpcb(so); if (unp == 0) return EINVAL; - if (unp->unp_addr) { - nam->m_len = unp->unp_addr->m_len; - bcopy(mtod(unp->unp_addr, caddr_t), - mtod(nam, caddr_t), (unsigned)nam->m_len); - } else - nam->m_len = 0; + if (unp->unp_addr) + *nam = dup_sockaddr((struct sockaddr *)unp->unp_addr, 1); return 0; } @@ -478,10 +470,10 @@ unp_attach(so) if (error) return (error); } - m = m_getclr(M_DONTWAIT, MT_PCB); - if (m == NULL) + MALLOC(unp, struct unpcb *, sizeof *unp, M_PCB, M_NOWAIT); + if (unp == NULL) return (ENOBUFS); - unp = mtod(m, struct unpcb *); + bzero(unp, sizeof *unp); so->so_pcb = (caddr_t)unp; unp->unp_socket = so; return (0); @@ -491,7 +483,6 @@ static void unp_detach(unp) register struct unpcb *unp; { - if (unp->unp_vnode) { unp->unp_vnode->v_socket = 0; vrele(unp->unp_vnode); @@ -514,31 +505,34 @@ unp_detach(unp) sorflush(unp->unp_socket); unp_gc(); } - m_freem(unp->unp_addr); - (void) m_free(dtom(unp)); + if (unp->unp_addr) + FREE(unp->unp_addr, M_SONAME); + FREE(unp, M_PCB); } static int unp_bind(unp, nam, p) struct unpcb *unp; - struct mbuf *nam; + struct sockaddr *nam; struct proc *p; { - struct sockaddr_un *soun = mtod(nam, struct sockaddr_un *); + struct sockaddr_un *soun = (struct sockaddr_un *)nam; register struct vnode *vp; struct vattr vattr; - int error; + int error, namelen; struct nameidata nd; + char buf[SOCK_MAXADDRLEN]; - NDINIT(&nd, CREATE, FOLLOW | LOCKPARENT, UIO_SYSSPACE, - soun->sun_path, p); if (unp->unp_vnode != NULL) return (EINVAL); - if (nam->m_len == MLEN) { - if (*(mtod(nam, caddr_t) + nam->m_len - 1) != 0) - return (EINVAL); - } else - *(mtod(nam, caddr_t) + nam->m_len) = 0; +#define offsetof(s, e) ((char *)&((s *)0)->e - (char *)((s *)0)) + namelen = soun->sun_len - offsetof(struct sockaddr_un, sun_path); + if (namelen <= 0) + return EINVAL; + strncpy(buf, soun->sun_path, namelen); + buf[namelen] = 0; /* null-terminate the string */ + NDINIT(&nd, CREATE, FOLLOW | LOCKPARENT, UIO_SYSSPACE, + buf, p); /* SHOULD BE ABLE TO ADOPT EXISTING AND wakeup() ALA FIFO's */ error = namei(&nd); if (error) @@ -562,7 +556,7 @@ unp_bind(unp, nam, p) vp = nd.ni_vp; vp->v_socket = unp->unp_socket; unp->unp_vnode = vp; - unp->unp_addr = m_copy(nam, 0, (int)M_COPYALL); + unp->unp_addr = (struct sockaddr_un *)dup_sockaddr(nam, 1); VOP_UNLOCK(vp, 0, p); return (0); } @@ -570,22 +564,24 @@ unp_bind(unp, nam, p) static int unp_connect(so, nam, p) struct socket *so; - struct mbuf *nam; + struct sockaddr *nam; struct proc *p; { - register struct sockaddr_un *soun = mtod(nam, struct sockaddr_un *); + register struct sockaddr_un *soun = (struct sockaddr_un *)nam; register struct vnode *vp; register struct socket *so2, *so3; struct unpcb *unp2, *unp3; - int error; + int error, len; struct nameidata nd; + char buf[SOCK_MAXADDRLEN]; - NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, soun->sun_path, p); - if (nam->m_data + nam->m_len == &nam->m_dat[MLEN]) { /* XXX */ - if (*(mtod(nam, caddr_t) + nam->m_len - 1) != 0) - return (EMSGSIZE); - } else - *(mtod(nam, caddr_t) + nam->m_len) = 0; + len = nam->sa_len - offsetof(struct sockaddr_un, sun_path); + if (len <= 0) + return EINVAL; + strncpy(buf, soun->sun_path, len); + buf[len] = 0; + + NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, buf, p); error = namei(&nd); if (error) return (error); @@ -615,8 +611,9 @@ unp_connect(so, nam, p) unp2 = sotounpcb(so2); unp3 = sotounpcb(so3); if (unp2->unp_addr) - unp3->unp_addr = - m_copy(unp2->unp_addr, 0, (int)M_COPYALL); + unp3->unp_addr = (struct sockaddr_un *) + dup_sockaddr((struct sockaddr *) + unp2->unp_addr, 1); so2 = so3; } error = unp_connect2(so, so2); @@ -726,8 +723,9 @@ unp_drop(unp, errno) unp_disconnect(unp); if (so->so_head) { so->so_pcb = (caddr_t) 0; - m_freem(unp->unp_addr); - (void) m_free(dtom(unp)); + if (unp->unp_addr) + FREE(unp->unp_addr, M_SONAME); + FREE(unp, M_PCB); sofree(so); } } diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index 3a8c88c..6b55c85 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95 - * $Id: vfs_subr.c,v 1.89 1997/07/17 07:17:31 dfr Exp $ + * $Id: vfs_subr.c,v 1.90 1997/08/04 07:43:28 dyson Exp $ */ /* @@ -2145,7 +2145,7 @@ struct netcred * vfs_export_lookup(mp, nep, nam) register struct mount *mp; struct netexport *nep; - struct mbuf *nam; + struct sockaddr *nam; { register struct netcred *np; register struct radix_node_head *rnh; @@ -2157,7 +2157,7 @@ vfs_export_lookup(mp, nep, nam) * Lookup in the export list first. */ if (nam != NULL) { - saddr = mtod(nam, struct sockaddr *); + saddr = nam; rnh = nep->ne_rtable[saddr->sa_family]; if (rnh != NULL) { np = (struct netcred *) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 3a8c88c..6b55c85 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95 - * $Id: vfs_subr.c,v 1.89 1997/07/17 07:17:31 dfr Exp $ + * $Id: vfs_subr.c,v 1.90 1997/08/04 07:43:28 dyson Exp $ */ /* @@ -2145,7 +2145,7 @@ struct netcred * vfs_export_lookup(mp, nep, nam) register struct mount *mp; struct netexport *nep; - struct mbuf *nam; + struct sockaddr *nam; { register struct netcred *np; register struct radix_node_head *rnh; @@ -2157,7 +2157,7 @@ vfs_export_lookup(mp, nep, nam) * Lookup in the export list first. */ if (nam != NULL) { - saddr = mtod(nam, struct sockaddr *); + saddr = nam; rnh = nep->ne_rtable[saddr->sa_family]; if (rnh != NULL) { np = (struct netcred *) |