summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/kern/uipc_syscalls.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-12-09 14:19:03 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-01-10 09:53:34 +0100
commit75b706fde4cbf82bcd41a1cec319778aa0f8eb2d (patch)
treeea39a351a1f6337b5a5dd6036314693adef5ffe6 /freebsd/sys/kern/uipc_syscalls.c
parentVMSTAT(8): Port to RTEMS (diff)
downloadrtems-libbsd-75b706fde4cbf82bcd41a1cec319778aa0f8eb2d.tar.bz2
Update to FreeBSD head 2016-12-10
Git mirror commit 80c55f08a05ab3b26a73b226ccb56adc3122a55c.
Diffstat (limited to 'freebsd/sys/kern/uipc_syscalls.c')
-rw-r--r--freebsd/sys/kern/uipc_syscalls.c310
1 files changed, 71 insertions, 239 deletions
diff --git a/freebsd/sys/kern/uipc_syscalls.c b/freebsd/sys/kern/uipc_syscalls.c
index 99ae6392..2d81fc20 100644
--- a/freebsd/sys/kern/uipc_syscalls.c
+++ b/freebsd/sys/kern/uipc_syscalls.c
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -94,20 +94,23 @@ static int sockargs(struct mbuf **, char *, socklen_t, int);
/*
* Convert a user file descriptor to a kernel file entry and check if required
* capability rights are present.
+ * If required copy of current set of capability rights is returned.
* A reference on the file entry is held upon returning.
*/
int
getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
- struct file **fpp, u_int *fflagp)
+ struct file **fpp, u_int *fflagp, struct filecaps *havecapsp)
{
struct file *fp;
int error;
- error = fget_unlocked(td->td_proc->p_fd, fd, rightsp, &fp, NULL);
+ error = fget_cap(td, fd, rightsp, &fp, havecapsp);
if (error != 0)
return (error);
if (fp->f_type != DTYPE_SOCKET) {
fdrop(fp, td);
+ if (havecapsp != NULL)
+ filecaps_free(havecapsp);
return (ENOTSOCK);
}
if (fflagp != NULL)
@@ -148,7 +151,7 @@ rtems_bsd_getsock(int fd, struct file **fpp, u_int *fflagp)
return (error);
}
-#define getsock_cap(td, fd, rights, fpp, fflagp) rtems_bsd_getsock(fd, fpp, fflagp)
+#define getsock_cap(td, fd, rights, fpp, fflagp, havecapsp) rtems_bsd_getsock(fd, fpp, fflagp)
#endif /* __rtems__ */
/*
@@ -162,13 +165,7 @@ rtems_bsd_getsock(int fd, struct file **fpp, u_int *fflagp)
static
#endif /* __rtems__ */
int
-sys_socket(td, uap)
- struct thread *td;
- struct socket_args /* {
- int domain;
- int type;
- int protocol;
- } */ *uap;
+sys_socket(struct thread *td, struct socket_args *uap)
{
struct socket *so;
struct file *fp;
@@ -239,7 +236,6 @@ socket(int domain, int type, int protocol)
}
#endif /* __rtems__ */
-/* ARGSUSED */
#ifdef __rtems__
static int kern_bindat(struct thread *td, int dirfd, int fd,
struct sockaddr *sa);
@@ -247,13 +243,7 @@ static int kern_bindat(struct thread *td, int dirfd, int fd,
static
#endif /* __rtems__ */
int
-sys_bind(td, uap)
- struct thread *td;
- struct bind_args /* {
- int s;
- caddr_t name;
- int namelen;
- } */ *uap;
+sys_bind(struct thread *td, struct bind_args *uap)
{
struct sockaddr *sa;
int error;
@@ -298,7 +288,7 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
AUDIT_ARG_FD(fd);
AUDIT_ARG_SOCKADDR(td, dirfd, sa);
error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_BIND),
- &fp, NULL);
+ &fp, NULL, NULL);
if (error != 0)
return (error);
so = fp->f_data;
@@ -321,18 +311,10 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
return (error);
}
-/* ARGSUSED */
#ifndef __rtems__
static
int
-sys_bindat(td, uap)
- struct thread *td;
- struct bindat_args /* {
- int fd;
- int s;
- caddr_t name;
- int namelen;
- } */ *uap;
+sys_bindat(struct thread *td, struct bindat_args *uap)
{
struct sockaddr *sa;
int error;
@@ -346,14 +328,8 @@ sys_bindat(td, uap)
}
#endif /* __rtems__ */
-/* ARGSUSED */
int
-sys_listen(td, uap)
- struct thread *td;
- struct listen_args /* {
- int s;
- int backlog;
- } */ *uap;
+sys_listen(struct thread *td, struct listen_args *uap)
{
struct socket *so;
struct file *fp;
@@ -362,7 +338,7 @@ sys_listen(td, uap)
AUDIT_ARG_FD(uap->s);
error = getsock_cap(td, uap->s, cap_rights_init(&rights, CAP_LISTEN),
- &fp, NULL);
+ &fp, NULL, NULL);
if (error == 0) {
so = fp->f_data;
#ifdef MAC
@@ -483,6 +459,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name,
struct file *headfp, *nfp = NULL;
struct sockaddr *sa = NULL;
struct socket *head, *so;
+ struct filecaps fcaps;
cap_rights_t rights;
u_int fflag;
pid_t pgid;
@@ -493,7 +470,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name,
AUDIT_ARG_FD(s);
error = getsock_cap(td, s, cap_rights_init(&rights, CAP_ACCEPT),
- &headfp, &fflag);
+ &headfp, &fflag, &fcaps);
if (error != 0)
return (error);
head = headfp->f_data;
@@ -506,7 +483,8 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name,
if (error != 0)
goto done;
#endif
- error = falloc(td, &nfp, &fd, (flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0);
+ error = falloc_caps(td, &nfp, &fd,
+ (flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0, &fcaps);
if (error != 0)
goto done;
ACCEPT_LOCK();
@@ -615,6 +593,8 @@ noconnection:
* a reference on nfp to the caller on success if they request it.
*/
done:
+ if (nfp == NULL)
+ filecaps_free(&fcaps);
if (fp != NULL) {
if (error == 0) {
*fp = nfp;
@@ -663,7 +643,6 @@ oaccept(td, uap)
#endif /* COMPAT_OLDSOCK */
#endif /* __rtems__ */
-/* ARGSUSED */
#ifdef __rtems__
static int kern_connectat(struct thread *td, int dirfd, int fd,
struct sockaddr *sa);
@@ -671,13 +650,7 @@ static int kern_connectat(struct thread *td, int dirfd, int fd,
static
#endif /* __rtems__ */
int
-sys_connect(td, uap)
- struct thread *td;
- struct connect_args /* {
- int s;
- caddr_t name;
- int namelen;
- } */ *uap;
+sys_connect(struct thread *td, struct connect_args *uap)
{
struct sockaddr *sa;
int error;
@@ -722,7 +695,7 @@ kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
AUDIT_ARG_FD(fd);
AUDIT_ARG_SOCKADDR(td, dirfd, sa);
error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_CONNECT),
- &fp, NULL);
+ &fp, NULL, NULL);
if (error != 0)
return (error);
so = fp->f_data;
@@ -775,16 +748,8 @@ done1:
}
#ifndef __rtems__
-/* ARGSUSED */
int
-sys_connectat(td, uap)
- struct thread *td;
- struct connectat_args /* {
- int fd;
- int s;
- caddr_t name;
- int namelen;
- } */ *uap;
+sys_connectat(struct thread *td, struct connectat_args *uap)
{
struct sockaddr *sa;
int error;
@@ -936,11 +901,7 @@ kern_sendit( struct thread *td, int s, struct msghdr *mp, int flags,
struct mbuf *control, enum uio_seg segflg);
#endif /* __rtems__ */
static int
-sendit(td, s, mp, flags)
- struct thread *td;
- int s;
- struct msghdr *mp;
- int flags;
+sendit(struct thread *td, int s, struct msghdr *mp, int flags)
{
struct mbuf *control;
struct sockaddr *to;
@@ -998,13 +959,8 @@ bad:
}
int
-kern_sendit(td, s, mp, flags, control, segflg)
- struct thread *td;
- int s;
- struct msghdr *mp;
- int flags;
- struct mbuf *control;
- enum uio_seg segflg;
+kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
+ struct mbuf *control, enum uio_seg segflg)
{
struct file *fp;
struct uio auio;
@@ -1026,12 +982,12 @@ kern_sendit(td, s, mp, flags, control, segflg)
AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name);
cap_rights_set(&rights, CAP_CONNECT);
}
- error = getsock_cap(td, s, &rights, &fp, NULL);
- if (error != 0)
#endif /* __rtems__ */
- error = getsock_cap(td->td_proc->p_fd, s, rights, &fp, NULL);
- if (error)
+ error = getsock_cap(td, s, &rights, &fp, NULL, NULL);
+ if (error != 0) {
+ m_freem(control);
return (error);
+ }
so = (struct socket *)fp->f_data;
#ifdef KTRACE
@@ -1042,12 +998,16 @@ kern_sendit(td, s, mp, flags, control, segflg)
if (mp->msg_name != NULL) {
error = mac_socket_check_connect(td->td_ucred, so,
mp->msg_name);
- if (error != 0)
+ if (error != 0) {
+ m_freem(control);
goto bad;
+ }
}
error = mac_socket_check_send(td->td_ucred, so);
- if (error != 0)
+ if (error != 0) {
+ m_freem(control);
goto bad;
+ }
#endif
auio.uio_iov = mp->msg_iov;
@@ -1061,6 +1021,7 @@ kern_sendit(td, s, mp, flags, control, segflg)
for (i = 0; i < mp->msg_iovlen; i++, iov++) {
if ((auio.uio_resid += iov->iov_len) < 0) {
error = EINVAL;
+ m_freem(control);
goto bad;
}
}
@@ -1103,16 +1064,7 @@ bad:
static
#endif /* __rtems__ */
int
-sys_sendto(td, uap)
- struct thread *td;
- struct sendto_args /* {
- int s;
- caddr_t buf;
- size_t len;
- int flags;
- caddr_t to;
- int tolen;
- } */ *uap;
+sys_sendto(struct thread *td, struct sendto_args *uap)
{
struct msghdr msg;
struct iovec aiov;
@@ -1167,7 +1119,7 @@ rtems_bsd_sendto(int socket, struct mbuf *m, int flags,
struct socket *so;
int error;
- error = getsock_cap(td->td_proc->p_fd, socket, CAP_WRITE, &fp, NULL);
+ error = getsock_cap(td->td_proc->p_fd, socket, CAP_WRITE, &fp, NULL, NULL);
if (error)
return (error);
so = (struct socket *)fp->f_data;
@@ -1186,14 +1138,7 @@ rtems_bsd_sendto(int socket, struct mbuf *m, int flags,
#ifndef __rtems__
#ifdef COMPAT_OLDSOCK
int
-osend(td, uap)
- struct thread *td;
- struct osend_args /* {
- int s;
- caddr_t buf;
- int len;
- int flags;
- } */ *uap;
+osend(struct thread *td, struct osend_args *uap)
{
struct msghdr msg;
struct iovec aiov;
@@ -1210,13 +1155,7 @@ osend(td, uap)
}
int
-osendmsg(td, uap)
- struct thread *td;
- struct osendmsg_args /* {
- int s;
- caddr_t msg;
- int flags;
- } */ *uap;
+osendmsg(struct thread *td, struct osendmsg_args *uap)
{
struct msghdr msg;
struct iovec *iov;
@@ -1241,13 +1180,7 @@ osendmsg(td, uap)
static
#endif /* __rtems__ */
int
-sys_sendmsg(td, uap)
- struct thread *td;
- struct sendmsg_args /* {
- int s;
- caddr_t msg;
- int flags;
- } */ *uap;
+sys_sendmsg(struct thread *td, struct sendmsg_args *uap)
{
struct msghdr msg;
struct iovec *iov;
@@ -1297,12 +1230,8 @@ sendmsg(int socket, const struct msghdr *message, int flags)
static
#endif /* __rtems__ */
int
-kern_recvit(td, s, mp, fromseg, controlp)
- struct thread *td;
- int s;
- struct msghdr *mp;
- enum uio_seg fromseg;
- struct mbuf **controlp;
+kern_recvit(struct thread *td, int s, struct msghdr *mp, enum uio_seg fromseg,
+ struct mbuf **controlp)
{
struct uio auio;
struct iovec *iov;
@@ -1323,7 +1252,7 @@ kern_recvit(td, s, mp, fromseg, controlp)
AUDIT_ARG_FD(s);
error = getsock_cap(td, s, cap_rights_init(&rights, CAP_RECV),
- &fp, NULL);
+ &fp, NULL, NULL);
if (error != 0)
return (error);
so = fp->f_data;
@@ -1459,11 +1388,7 @@ out:
}
static int
-recvit(td, s, mp, namelenp)
- struct thread *td;
- int s;
- struct msghdr *mp;
- void *namelenp;
+recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp)
{
int error;
@@ -1484,16 +1409,7 @@ recvit(td, s, mp, namelenp)
static
#endif /* __rtems__ */
int
-sys_recvfrom(td, uap)
- struct thread *td;
- struct recvfrom_args /* {
- int s;
- caddr_t buf;
- size_t len;
- int flags;
- struct sockaddr * __restrict from;
- socklen_t * __restrict fromlenaddr;
- } */ *uap;
+sys_recvfrom(struct thread *td, struct recvfrom_args *uap)
{
struct msghdr msg;
struct iovec aiov;
@@ -1551,9 +1467,7 @@ recvfrom(int socket, void *__restrict buffer, size_t length, int flags,
#ifndef __rtems__
#ifdef COMPAT_OLDSOCK
int
-orecvfrom(td, uap)
- struct thread *td;
- struct recvfrom_args *uap;
+orecvfrom(struct thread *td, struct recvfrom_args *uap)
{
uap->flags |= MSG_COMPAT;
@@ -1563,14 +1477,7 @@ orecvfrom(td, uap)
#ifdef COMPAT_OLDSOCK
int
-orecv(td, uap)
- struct thread *td;
- struct orecv_args /* {
- int s;
- caddr_t buf;
- int len;
- int flags;
- } */ *uap;
+orecv(struct thread *td, struct orecv_args *uap)
{
struct msghdr msg;
struct iovec aiov;
@@ -1592,13 +1499,7 @@ orecv(td, uap)
* rights where the control fields are now.
*/
int
-orecvmsg(td, uap)
- struct thread *td;
- struct orecvmsg_args /* {
- int s;
- struct omsghdr *msg;
- int flags;
- } */ *uap;
+orecvmsg(struct thread *td, struct orecvmsg_args *uap)
{
struct msghdr msg;
struct iovec *iov;
@@ -1626,13 +1527,7 @@ orecvmsg(td, uap)
static
#endif /* __rtems__ */
int
-sys_recvmsg(td, uap)
- struct thread *td;
- struct recvmsg_args /* {
- int s;
- struct msghdr *msg;
- int flags;
- } */ *uap;
+sys_recvmsg(struct thread *td, struct recvmsg_args *uap)
{
struct msghdr msg;
struct iovec *uiov, *iov;
@@ -1684,17 +1579,11 @@ recvmsg(int socket, struct msghdr *message, int flags)
}
#endif /* __rtems__ */
-/* ARGSUSED */
#ifdef __rtems__
static
#endif /* __rtems__ */
int
-sys_shutdown(td, uap)
- struct thread *td;
- struct shutdown_args /* {
- int s;
- int how;
- } */ *uap;
+sys_shutdown(struct thread *td, struct shutdown_args *uap)
{
struct socket *so;
struct file *fp;
@@ -1703,7 +1592,7 @@ sys_shutdown(td, uap)
AUDIT_ARG_FD(uap->s);
error = getsock_cap(td, uap->s, cap_rights_init(&rights, CAP_SHUTDOWN),
- &fp, NULL);
+ &fp, NULL, NULL);
if (error == 0) {
so = fp->f_data;
error = soshutdown(so, uap->how);
@@ -1736,7 +1625,6 @@ shutdown(int socket, int how)
}
#endif /* __rtems__ */
-/* ARGSUSED */
#ifdef __rtems__
static int kern_setsockopt( struct thread *td, int s, int level, int name,
void *val, enum uio_seg valseg, socklen_t valsize);
@@ -1744,15 +1632,7 @@ static int kern_setsockopt( struct thread *td, int s, int level, int name,
static
#endif /* __rtems__ */
int
-sys_setsockopt(td, uap)
- struct thread *td;
- struct setsockopt_args /* {
- int s;
- int level;
- int name;
- caddr_t val;
- int valsize;
- } */ *uap;
+sys_setsockopt(struct thread *td, struct setsockopt_args *uap)
{
return (kern_setsockopt(td, uap->s, uap->level, uap->name,
@@ -1784,14 +1664,8 @@ setsockopt(int socket, int level, int option_name, const void *option_value,
#endif /* __rtems__ */
int
-kern_setsockopt(td, s, level, name, val, valseg, valsize)
- struct thread *td;
- int s;
- int level;
- int name;
- void *val;
- enum uio_seg valseg;
- socklen_t valsize;
+kern_setsockopt(struct thread *td, int s, int level, int name, void *val,
+ enum uio_seg valseg, socklen_t valsize)
{
struct socket *so;
struct file *fp;
@@ -1822,7 +1696,7 @@ kern_setsockopt(td, s, level, name, val, valseg, valsize)
AUDIT_ARG_FD(s);
error = getsock_cap(td, s, cap_rights_init(&rights, CAP_SETSOCKOPT),
- &fp, NULL);
+ &fp, NULL, NULL);
if (error == 0) {
so = fp->f_data;
error = sosetopt(so, &sopt);
@@ -1831,7 +1705,6 @@ kern_setsockopt(td, s, level, name, val, valseg, valsize)
return(error);
}
-/* ARGSUSED */
#ifdef __rtems__
static int kern_getsockopt( struct thread *td, int s, int level, int name,
void *val, enum uio_seg valseg, socklen_t *valsize);
@@ -1839,15 +1712,7 @@ static int kern_getsockopt( struct thread *td, int s, int level, int name,
static
#endif /* __rtems__ */
int
-sys_getsockopt(td, uap)
- struct thread *td;
- struct getsockopt_args /* {
- int s;
- int level;
- int name;
- void * __restrict val;
- socklen_t * __restrict avalsize;
- } */ *uap;
+sys_getsockopt(struct thread *td, struct getsockopt_args *uap)
{
socklen_t valsize;
int error;
@@ -1895,14 +1760,8 @@ getsockopt(int socket, int level, int option_name, void *__restrict
* optval can be a userland or userspace. optlen is always a kernel pointer.
*/
int
-kern_getsockopt(td, s, level, name, val, valseg, valsize)
- struct thread *td;
- int s;
- int level;
- int name;
- void *val;
- enum uio_seg valseg;
- socklen_t *valsize;
+kern_getsockopt(struct thread *td, int s, int level, int name, void *val,
+ enum uio_seg valseg, socklen_t *valsize)
{
struct socket *so;
struct file *fp;
@@ -1933,7 +1792,7 @@ kern_getsockopt(td, s, level, name, val, valseg, valsize)
AUDIT_ARG_FD(s);
error = getsock_cap(td, s, cap_rights_init(&rights, CAP_GETSOCKOPT),
- &fp, NULL);
+ &fp, NULL, NULL);
if (error == 0) {
so = fp->f_data;
error = sogetopt(so, &sopt);
@@ -1951,16 +1810,8 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
/*
* getsockname1() - Get socket name.
*/
-/* ARGSUSED */
static int
-getsockname1(td, uap, compat)
- struct thread *td;
- struct getsockname_args /* {
- int fdes;
- struct sockaddr * __restrict asa;
- socklen_t * __restrict alen;
- } */ *uap;
- int compat;
+getsockname1(struct thread *td, struct getsockname_args *uap, int compat)
{
struct sockaddr *sa;
socklen_t len;
@@ -2000,7 +1851,7 @@ getsockname(int socket, struct sockaddr *__restrict address,
int error;
if (td != NULL) {
- error = getsockname1(td, &ua);
+ error = getsockname1(td, &ua, 0);
} else {
error = ENOMEM;
}
@@ -2021,7 +1872,7 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
AUDIT_ARG_FD(fd);
error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETSOCKNAME),
- &fp, NULL);
+ &fp, NULL, NULL);
if (error != 0)
return (error);
so = fp->f_data;
@@ -2051,9 +1902,7 @@ bad:
#ifndef __rtems__
int
-sys_getsockname(td, uap)
- struct thread *td;
- struct getsockname_args *uap;
+sys_getsockname(struct thread *td, struct getsockname_args *uap)
{
return (getsockname1(td, uap, 0));
@@ -2061,9 +1910,7 @@ sys_getsockname(td, uap)
#ifdef COMPAT_OLDSOCK
int
-ogetsockname(td, uap)
- struct thread *td;
- struct getsockname_args *uap;
+ogetsockname(struct thread *td, struct getsockname_args *uap)
{
return (getsockname1(td, uap, 1));
@@ -2079,16 +1926,8 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
/*
* getpeername1() - Get name of peer for connected socket.
*/
-/* ARGSUSED */
static int
-getpeername1(td, uap, compat)
- struct thread *td;
- struct getpeername_args /* {
- int fdes;
- struct sockaddr * __restrict asa;
- socklen_t * __restrict alen;
- } */ *uap;
- int compat;
+getpeername1(struct thread *td, struct getpeername_args *uap, int compat)
{
struct sockaddr *sa;
socklen_t len;
@@ -2128,7 +1967,7 @@ getpeername(int socket, struct sockaddr *__restrict address,
int error;
if (td != NULL) {
- error = getpeername1(td, &ua);
+ error = getpeername1(td, &ua, 0);
} else {
error = ENOMEM;
}
@@ -2149,7 +1988,7 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
AUDIT_ARG_FD(fd);
error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETPEERNAME),
- &fp, NULL);
+ &fp, NULL, NULL);
if (error != 0)
return (error);
so = fp->f_data;
@@ -2184,9 +2023,7 @@ done:
#ifndef __rtems__
int
-sys_getpeername(td, uap)
- struct thread *td;
- struct getpeername_args *uap;
+sys_getpeername(struct thread *td, struct getpeername_args *uap)
{
return (getpeername1(td, uap, 0));
@@ -2194,9 +2031,7 @@ sys_getpeername(td, uap)
#ifdef COMPAT_OLDSOCK
int
-ogetpeername(td, uap)
- struct thread *td;
- struct ogetpeername_args *uap;
+ogetpeername(struct thread *td, struct ogetpeername_args *uap)
{
/* XXX uap should have type `getpeername_args *' to begin with. */
@@ -2242,10 +2077,7 @@ sockargs(struct mbuf **mp, char *buf, socklen_t buflen, int type)
}
int
-getsockaddr(namp, uaddr, len)
- struct sockaddr **namp;
- caddr_t uaddr;
- size_t len;
+getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len)
{
struct sockaddr *sa;
int error;