Home | History | Annotate | Line # | Download | only in netbsd32
netbsd32_socket.c revision 1.41.14.1.6.1
      1  1.41.14.1.6.1    martin /*	$NetBSD: netbsd32_socket.c,v 1.41.14.1.6.1 2018/11/21 12:09:54 martin Exp $	*/
      2            1.1       mrg 
      3            1.1       mrg /*
      4            1.1       mrg  * Copyright (c) 1998, 2001 Matthew R. Green
      5            1.1       mrg  * All rights reserved.
      6            1.1       mrg  *
      7            1.1       mrg  * Redistribution and use in source and binary forms, with or without
      8            1.1       mrg  * modification, are permitted provided that the following conditions
      9            1.1       mrg  * are met:
     10            1.1       mrg  * 1. Redistributions of source code must retain the above copyright
     11            1.1       mrg  *    notice, this list of conditions and the following disclaimer.
     12            1.1       mrg  * 2. Redistributions in binary form must reproduce the above copyright
     13            1.1       mrg  *    notice, this list of conditions and the following disclaimer in the
     14            1.1       mrg  *    documentation and/or other materials provided with the distribution.
     15            1.1       mrg  *
     16            1.1       mrg  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17            1.1       mrg  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18            1.1       mrg  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19            1.1       mrg  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20            1.1       mrg  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21            1.1       mrg  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     22            1.1       mrg  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23            1.1       mrg  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24            1.1       mrg  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25            1.1       mrg  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26            1.1       mrg  * SUCH DAMAGE.
     27            1.1       mrg  */
     28            1.6     lukem 
     29            1.6     lukem #include <sys/cdefs.h>
     30  1.41.14.1.6.1    martin __KERNEL_RCSID(0, "$NetBSD: netbsd32_socket.c,v 1.41.14.1.6.1 2018/11/21 12:09:54 martin Exp $");
     31            1.1       mrg 
     32            1.1       mrg #include <sys/param.h>
     33            1.1       mrg #include <sys/systm.h>
     34            1.1       mrg #define msg __msg /* Don't ask me! */
     35            1.1       mrg #include <sys/mount.h>
     36            1.1       mrg #include <sys/socket.h>
     37            1.1       mrg #include <sys/sockio.h>
     38            1.1       mrg #include <sys/socketvar.h>
     39            1.1       mrg #include <sys/mbuf.h>
     40            1.1       mrg #include <sys/ktrace.h>
     41            1.1       mrg #include <sys/file.h>
     42            1.1       mrg #include <sys/filedesc.h>
     43            1.1       mrg #include <sys/syscallargs.h>
     44            1.1       mrg #include <sys/proc.h>
     45           1.15  christos #include <sys/dirent.h>
     46            1.1       mrg 
     47            1.1       mrg #include <compat/netbsd32/netbsd32.h>
     48            1.1       mrg #include <compat/netbsd32/netbsd32_syscallargs.h>
     49            1.1       mrg #include <compat/netbsd32/netbsd32_conv.h>
     50            1.1       mrg 
     51           1.37     rmind /*
     52           1.39     joerg  * XXX Assumes that struct sockaddr is compatible.
     53           1.37     rmind  */
     54           1.39     joerg 
     55           1.39     joerg #define	CMSG32_ALIGN(n)	(((n) + ALIGNBYTES32) & ~ALIGNBYTES32)
     56           1.39     joerg #define	CMSG32_DATA(cmsg) \
     57           1.39     joerg 	((u_char *)(void *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr)))
     58           1.39     joerg 
     59           1.39     joerg #define	CMSG32_NXTHDR(mhdr, cmsg)	\
     60           1.39     joerg 	(((char *)(cmsg) + CMSG32_ALIGN((cmsg)->cmsg_len) + \
     61           1.39     joerg 			    CMSG32_ALIGN(sizeof(struct cmsghdr)) > \
     62           1.39     joerg 	    (((char *)(mhdr)->msg_control) + (mhdr)->msg_controllen)) ? \
     63           1.39     joerg 	    (struct cmsghdr *)0 : \
     64           1.39     joerg 	    (struct cmsghdr *)((char *)(cmsg) + \
     65           1.39     joerg 	        CMSG32_ALIGN((cmsg)->cmsg_len)))
     66           1.39     joerg #define	CMSG32_FIRSTHDR(mhdr) \
     67           1.39     joerg 	((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
     68           1.39     joerg 	 (struct cmsghdr *)(mhdr)->msg_control : \
     69           1.39     joerg 	 (struct cmsghdr *)0)
     70           1.39     joerg 
     71           1.39     joerg #define CMSG32_SPACE(l)	(CMSG32_ALIGN(sizeof(struct cmsghdr)) + CMSG32_ALIGN(l))
     72           1.39     joerg #define CMSG32_LEN(l)	(CMSG32_ALIGN(sizeof(struct cmsghdr)) + (l))
     73           1.39     joerg 
     74           1.39     joerg static int
     75           1.39     joerg copyout32_msg_control_mbuf(struct lwp *l, struct msghdr *mp, int *len, struct mbuf *m, char **q, bool *truncated)
     76           1.39     joerg {
     77           1.39     joerg 	struct cmsghdr *cmsg, cmsg32;
     78           1.39     joerg 	int i, j, error;
     79           1.39     joerg 
     80           1.39     joerg 	*truncated = false;
     81           1.39     joerg 	cmsg = mtod(m, struct cmsghdr *);
     82           1.39     joerg 	do {
     83           1.39     joerg 		if ((char *)cmsg == mtod(m, char *) + m->m_len)
     84           1.39     joerg 			break;
     85           1.39     joerg 		if ((char *)cmsg > mtod(m, char *) + m->m_len - sizeof(*cmsg))
     86           1.39     joerg 			return EINVAL;
     87           1.39     joerg 		cmsg32 = *cmsg;
     88           1.39     joerg 		j = cmsg->cmsg_len - CMSG_LEN(0);
     89           1.39     joerg 		i = cmsg32.cmsg_len = CMSG32_LEN(j);
     90           1.39     joerg 		if (i > *len) {
     91           1.39     joerg 			mp->msg_flags |= MSG_CTRUNC;
     92           1.39     joerg 			if (cmsg->cmsg_level == SOL_SOCKET
     93           1.39     joerg 			    && cmsg->cmsg_type == SCM_RIGHTS) {
     94           1.39     joerg 				*truncated = true;
     95           1.39     joerg 				return 0;
     96           1.39     joerg 			}
     97           1.39     joerg 			j -= i - *len;
     98           1.39     joerg 			i = *len;
     99           1.39     joerg 		}
    100           1.39     joerg 
    101           1.39     joerg 		ktrkuser("msgcontrol", cmsg, cmsg->cmsg_len);
    102  1.41.14.1.6.1    martin 		error = copyout(&cmsg32, *q, MIN(i, sizeof(cmsg32)));
    103           1.39     joerg 		if (error)
    104           1.39     joerg 			return (error);
    105           1.39     joerg 		if (i > CMSG32_LEN(0)) {
    106           1.39     joerg 			error = copyout(CMSG_DATA(cmsg), *q + CMSG32_LEN(0), i - CMSG32_LEN(0));
    107           1.39     joerg 			if (error)
    108           1.39     joerg 				return (error);
    109           1.39     joerg 		}
    110           1.39     joerg 		j = CMSG32_SPACE(cmsg->cmsg_len - CMSG_LEN(0));
    111           1.39     joerg 		if (*len >= j) {
    112           1.39     joerg 			*len -= j;
    113           1.39     joerg 			*q += j;
    114           1.39     joerg 		} else {
    115           1.39     joerg 			*q += i;
    116           1.39     joerg 			*len = 0;
    117           1.39     joerg 		}
    118           1.39     joerg 		cmsg = (void *)((char *)cmsg + CMSG_ALIGN(cmsg->cmsg_len));
    119           1.39     joerg 	} while (*len > 0);
    120           1.39     joerg 
    121           1.39     joerg 	return 0;
    122           1.39     joerg }
    123           1.39     joerg 
    124           1.39     joerg static int
    125           1.39     joerg copyout32_msg_control(struct lwp *l, struct msghdr *mp, struct mbuf *control)
    126           1.39     joerg {
    127           1.39     joerg 	int len, error = 0;
    128           1.39     joerg 	struct mbuf *m;
    129           1.39     joerg 	char *q;
    130           1.39     joerg 	bool truncated;
    131           1.39     joerg 
    132           1.39     joerg 	len = mp->msg_controllen;
    133           1.39     joerg 	if (len <= 0 || control == 0) {
    134           1.39     joerg 		mp->msg_controllen = 0;
    135           1.39     joerg 		free_control_mbuf(l, control, control);
    136           1.39     joerg 		return 0;
    137           1.39     joerg 	}
    138           1.39     joerg 
    139           1.39     joerg 	q = (char *)mp->msg_control;
    140           1.39     joerg 
    141           1.40      matt 	for (m = control; len > 0 && m != NULL; m = m->m_next) {
    142           1.39     joerg 		error = copyout32_msg_control_mbuf(l, mp, &len, m, &q, &truncated);
    143           1.39     joerg 		if (truncated) {
    144           1.39     joerg 			m = control;
    145           1.39     joerg 			break;
    146           1.39     joerg 		}
    147           1.39     joerg 		if (error)
    148           1.39     joerg 			break;
    149           1.39     joerg 	}
    150           1.39     joerg 
    151           1.39     joerg 	free_control_mbuf(l, control, m);
    152           1.39     joerg 
    153           1.39     joerg 	mp->msg_controllen = q - (char *)mp->msg_control;
    154           1.39     joerg 	return error;
    155           1.39     joerg }
    156           1.39     joerg 
    157            1.1       mrg int
    158           1.30       dsl netbsd32_recvmsg(struct lwp *l, const struct netbsd32_recvmsg_args *uap, register_t *retval)
    159            1.1       mrg {
    160           1.30       dsl 	/* {
    161            1.1       mrg 		syscallarg(int) s;
    162            1.1       mrg 		syscallarg(netbsd32_msghdrp_t) msg;
    163            1.1       mrg 		syscallarg(int) flags;
    164           1.30       dsl 	} */
    165           1.38     joerg 	struct netbsd32_msghdr	msg32;
    166           1.35     njoly 	struct iovec aiov[UIO_SMALLIOV], *iov;
    167           1.38     joerg 	struct msghdr	msg;
    168           1.38     joerg 	int		error;
    169           1.38     joerg 	struct mbuf	*from, *control;
    170           1.37     rmind 	size_t iovsz;
    171            1.1       mrg 
    172           1.38     joerg 	error = copyin(SCARG_P32(uap, msg), &msg32, sizeof(msg32));
    173            1.1       mrg 	if (error)
    174            1.1       mrg 		return (error);
    175           1.38     joerg 
    176           1.38     joerg 	iovsz = msg32.msg_iovlen * sizeof(struct iovec);
    177           1.38     joerg 	if (msg32.msg_iovlen > UIO_SMALLIOV) {
    178           1.38     joerg 		if (msg32.msg_iovlen > IOV_MAX)
    179            1.1       mrg 			return (EMSGSIZE);
    180           1.37     rmind 		iov = kmem_alloc(iovsz, KM_SLEEP);
    181           1.25  christos 	} else
    182            1.1       mrg 		iov = aiov;
    183           1.38     joerg 	error = netbsd32_to_iovecin(NETBSD32PTR64(msg32.msg_iov), iov,
    184           1.38     joerg 	    msg32.msg_iovlen);
    185            1.1       mrg 	if (error)
    186            1.1       mrg 		goto done;
    187            1.1       mrg 
    188           1.38     joerg 	msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS;
    189           1.38     joerg 	msg.msg_name = NETBSD32PTR64(msg32.msg_name);
    190           1.38     joerg 	msg.msg_namelen = msg32.msg_namelen;
    191           1.38     joerg 	msg.msg_control = NETBSD32PTR64(msg32.msg_control);
    192           1.38     joerg 	msg.msg_controllen = msg32.msg_controllen;
    193           1.38     joerg 	msg.msg_iov = iov;
    194           1.38     joerg 	msg.msg_iovlen = msg32.msg_iovlen;
    195           1.13     perry 
    196           1.38     joerg 	error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from,
    197           1.38     joerg 	    msg.msg_control != NULL ? &control : NULL, retval);
    198           1.38     joerg 	if (error != 0)
    199           1.38     joerg 		goto done;
    200            1.1       mrg 
    201           1.38     joerg 	if (msg.msg_control != NULL)
    202           1.39     joerg 		error = copyout32_msg_control(l, &msg, control);
    203           1.27        ad 
    204           1.38     joerg 	if (error == 0)
    205           1.38     joerg 		error = copyout_sockname(msg.msg_name, &msg.msg_namelen, 0,
    206           1.38     joerg 			from);
    207           1.38     joerg 	if (from != NULL)
    208           1.38     joerg 		m_free(from);
    209           1.38     joerg 	if (error == 0) {
    210           1.38     joerg 		ktrkuser("msghdr", &msg, sizeof msg);
    211           1.38     joerg 		msg32.msg_namelen = msg.msg_namelen;
    212           1.38     joerg 		msg32.msg_controllen = msg.msg_controllen;
    213           1.38     joerg 		msg32.msg_flags = msg.msg_flags;
    214           1.38     joerg 		error = copyout(&msg32, SCARG_P32(uap, msg), sizeof(msg32));
    215            1.1       mrg 	}
    216           1.27        ad 
    217           1.38     joerg  done:
    218           1.38     joerg 	if (iov != aiov)
    219           1.38     joerg 		kmem_free(iov, iovsz);
    220            1.1       mrg 	return (error);
    221            1.1       mrg }
    222            1.1       mrg 
    223           1.39     joerg static int
    224           1.39     joerg copyin32_msg_control(struct lwp *l, struct msghdr *mp)
    225           1.39     joerg {
    226           1.39     joerg 	/*
    227           1.39     joerg 	 * Handle cmsg if there is any.
    228           1.39     joerg 	 */
    229           1.39     joerg 	struct cmsghdr *cmsg, cmsg32, *cc;
    230           1.39     joerg 	struct mbuf *ctl_mbuf;
    231           1.39     joerg 	ssize_t resid = mp->msg_controllen;
    232           1.39     joerg 	size_t clen, cidx = 0, cspace;
    233           1.39     joerg 	u_int8_t *control;
    234           1.39     joerg 	int error;
    235           1.39     joerg 
    236           1.39     joerg 	ctl_mbuf = m_get(M_WAIT, MT_CONTROL);
    237           1.39     joerg 	clen = MLEN;
    238           1.39     joerg 	control = mtod(ctl_mbuf, void *);
    239           1.39     joerg 	memset(control, 0, clen);
    240           1.39     joerg 
    241           1.39     joerg 	cc = CMSG32_FIRSTHDR(mp);
    242           1.39     joerg 	do {
    243           1.39     joerg 		error = copyin(cc, &cmsg32, sizeof(cmsg32));
    244           1.39     joerg 		if (error)
    245           1.39     joerg 			goto failure;
    246           1.39     joerg 
    247           1.39     joerg 		/*
    248           1.39     joerg 		 * Sanity check the control message length.
    249           1.39     joerg 		 */
    250           1.39     joerg 		if (cmsg32.cmsg_len > resid ||
    251           1.39     joerg 		    cmsg32.cmsg_len < sizeof(cmsg32)) {
    252           1.39     joerg 			error = EINVAL;
    253           1.39     joerg 			goto failure;
    254           1.39     joerg 		}
    255           1.39     joerg 
    256           1.39     joerg 		cspace = CMSG_SPACE(cmsg32.cmsg_len - CMSG32_LEN(0));
    257           1.39     joerg 
    258           1.39     joerg 		/* Check the buffer is big enough */
    259           1.39     joerg 		if (__predict_false(cidx + cspace > clen)) {
    260           1.39     joerg 			u_int8_t *nc;
    261           1.39     joerg 			size_t nclen;
    262           1.39     joerg 
    263           1.39     joerg 			nclen = cidx + cspace;
    264           1.39     joerg 			if (nclen >= PAGE_SIZE) {
    265           1.39     joerg 				error = EINVAL;
    266           1.39     joerg 				goto failure;
    267           1.39     joerg 			}
    268           1.39     joerg 			nc = realloc(clen <= MLEN ? NULL : control,
    269           1.39     joerg 				     nclen, M_TEMP, M_WAITOK);
    270           1.39     joerg 			if (!nc) {
    271           1.39     joerg 				error = ENOMEM;
    272           1.39     joerg 				goto failure;
    273           1.39     joerg 			}
    274           1.39     joerg 			if (cidx <= MLEN) {
    275           1.39     joerg 				/* Old buffer was in mbuf... */
    276           1.39     joerg 				memcpy(nc, control, cidx);
    277           1.39     joerg 				memset(nc + cidx, 0, nclen - cidx);
    278           1.39     joerg 			} else {
    279           1.39     joerg 				memset(nc + nclen, 0, nclen - clen);
    280           1.39     joerg 			}
    281           1.39     joerg 			control = nc;
    282           1.39     joerg 			clen = nclen;
    283           1.39     joerg 		}
    284           1.39     joerg 
    285           1.39     joerg 		/* Copy header */
    286           1.39     joerg 		cmsg = (void *)&control[cidx];
    287           1.39     joerg 		cmsg->cmsg_len = CMSG_LEN(cmsg32.cmsg_len - CMSG32_LEN(0));
    288           1.39     joerg 		cmsg->cmsg_level = cmsg32.cmsg_level;
    289           1.39     joerg 		cmsg->cmsg_type = cmsg32.cmsg_type;
    290           1.39     joerg 
    291           1.39     joerg 		/* Copyin the data */
    292           1.39     joerg 		error = copyin(CMSG32_DATA(cc), CMSG_DATA(cmsg),
    293           1.39     joerg 		    cmsg32.cmsg_len - CMSG32_LEN(0));
    294           1.39     joerg 		if (error)
    295           1.39     joerg 			goto failure;
    296           1.39     joerg 
    297           1.39     joerg 		resid -= CMSG32_ALIGN(cmsg32.cmsg_len);
    298           1.39     joerg 		cidx += cmsg->cmsg_len;
    299           1.41    martin 	} while (resid > 0 && (cc = CMSG32_NXTHDR(mp, &cmsg32)));
    300           1.39     joerg 
    301           1.39     joerg 	/* If we allocated a buffer, attach to mbuf */
    302           1.39     joerg 	if (cidx > MLEN) {
    303           1.39     joerg 		MEXTADD(ctl_mbuf, control, clen, M_MBUF, NULL, NULL);
    304           1.39     joerg 		ctl_mbuf->m_flags |= M_EXT_RW;
    305           1.39     joerg 	}
    306           1.39     joerg 	control = NULL;
    307           1.39     joerg 	mp->msg_controllen = ctl_mbuf->m_len = CMSG_ALIGN(cidx);
    308           1.39     joerg 
    309           1.39     joerg 	mp->msg_control = ctl_mbuf;
    310           1.39     joerg 	mp->msg_flags |= MSG_CONTROLMBUF;
    311           1.39     joerg 
    312           1.39     joerg 	ktrkuser("msgcontrol", mtod(ctl_mbuf, void *),
    313           1.39     joerg 	    mp->msg_controllen);
    314           1.39     joerg 
    315           1.39     joerg 	return 0;
    316           1.39     joerg 
    317           1.39     joerg failure:
    318           1.39     joerg 	if (control != mtod(ctl_mbuf, void *))
    319           1.39     joerg 		free(control, M_MBUF);
    320           1.39     joerg 	m_free(ctl_mbuf);
    321           1.39     joerg 	return error;
    322           1.39     joerg }
    323           1.39     joerg 
    324            1.1       mrg int
    325           1.30       dsl netbsd32_sendmsg(struct lwp *l, const struct netbsd32_sendmsg_args *uap, register_t *retval)
    326            1.1       mrg {
    327           1.30       dsl 	/* {
    328            1.1       mrg 		syscallarg(int) s;
    329            1.1       mrg 		syscallarg(const netbsd32_msghdrp_t) msg;
    330            1.1       mrg 		syscallarg(int) flags;
    331           1.30       dsl 	} */
    332            1.1       mrg 	struct msghdr msg;
    333            1.1       mrg 	struct netbsd32_msghdr msg32;
    334      1.41.14.1    martin 	struct iovec aiov[UIO_SMALLIOV], *iov = aiov;
    335           1.35     njoly 	struct netbsd32_iovec *iov32;
    336           1.37     rmind 	size_t iovsz;
    337            1.1       mrg 	int error;
    338            1.1       mrg 
    339           1.24       dsl 	error = copyin(SCARG_P32(uap, msg), &msg32, sizeof(msg32));
    340            1.1       mrg 	if (error)
    341            1.1       mrg 		return (error);
    342            1.1       mrg 	netbsd32_to_msghdr(&msg32, &msg);
    343           1.39     joerg 	msg.msg_flags = 0;
    344           1.39     joerg 
    345           1.39     joerg 	if (CMSG32_FIRSTHDR(&msg)) {
    346           1.39     joerg 		error = copyin32_msg_control(l, &msg);
    347           1.39     joerg 		if (error)
    348           1.39     joerg 			return (error);
    349      1.41.14.1    martin 		/* From here on, msg.msg_control is allocated */
    350           1.39     joerg 	} else {
    351           1.39     joerg 		msg.msg_control = NULL;
    352           1.39     joerg 		msg.msg_controllen = 0;
    353           1.39     joerg 	}
    354           1.26       dsl 
    355           1.37     rmind 	iovsz = msg.msg_iovlen * sizeof(struct iovec);
    356            1.1       mrg 	if ((u_int)msg.msg_iovlen > UIO_SMALLIOV) {
    357      1.41.14.1    martin 		if ((u_int)msg.msg_iovlen > IOV_MAX) {
    358      1.41.14.1    martin 			error = EMSGSIZE;
    359      1.41.14.1    martin 			goto out;
    360      1.41.14.1    martin 		}
    361           1.37     rmind 		iov = kmem_alloc(iovsz, KM_SLEEP);
    362      1.41.14.1    martin 	}
    363           1.26       dsl 
    364           1.35     njoly 	iov32 = NETBSD32PTR64(msg32.msg_iov);
    365           1.35     njoly 	error = netbsd32_to_iovecin(iov32, iov, msg.msg_iovlen);
    366            1.1       mrg 	if (error)
    367      1.41.14.1    martin 		goto out;
    368            1.1       mrg 	msg.msg_iov = iov;
    369           1.26       dsl 
    370           1.26       dsl 	error = do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
    371      1.41.14.1    martin 	/* msg.msg_control freed by do_sys_sendmsg() */
    372      1.41.14.1    martin 
    373            1.1       mrg 	if (iov != aiov)
    374           1.37     rmind 		kmem_free(iov, iovsz);
    375            1.1       mrg 	return (error);
    376      1.41.14.1    martin 
    377      1.41.14.1    martin out:
    378      1.41.14.1    martin 	if (iov != aiov)
    379      1.41.14.1    martin 		kmem_free(iov, iovsz);
    380      1.41.14.1    martin 	if (msg.msg_control)
    381      1.41.14.1    martin 		m_free(msg.msg_control);
    382      1.41.14.1    martin 	return error;
    383            1.1       mrg }
    384            1.1       mrg 
    385            1.1       mrg int
    386           1.30       dsl netbsd32_recvfrom(struct lwp *l, const struct netbsd32_recvfrom_args *uap, register_t *retval)
    387            1.1       mrg {
    388           1.30       dsl 	/* {
    389            1.1       mrg 		syscallarg(int) s;
    390            1.1       mrg 		syscallarg(netbsd32_voidp) buf;
    391            1.1       mrg 		syscallarg(netbsd32_size_t) len;
    392            1.1       mrg 		syscallarg(int) flags;
    393            1.1       mrg 		syscallarg(netbsd32_sockaddrp_t) from;
    394            1.1       mrg 		syscallarg(netbsd32_intp) fromlenaddr;
    395           1.30       dsl 	} */
    396           1.38     joerg 	struct msghdr	msg;
    397           1.38     joerg 	struct iovec	aiov;
    398           1.38     joerg 	int		error;
    399           1.38     joerg 	struct mbuf	*from;
    400            1.1       mrg 
    401           1.38     joerg 	msg.msg_name = NULL;
    402           1.38     joerg 	msg.msg_iov = &aiov;
    403            1.1       mrg 	msg.msg_iovlen = 1;
    404           1.24       dsl 	aiov.iov_base = SCARG_P32(uap, buf);
    405           1.38     joerg 	aiov.iov_len = SCARG(uap, len);
    406           1.38     joerg 	msg.msg_control = NULL;
    407           1.38     joerg 	msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS;
    408           1.38     joerg 
    409           1.38     joerg 	error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, NULL, retval);
    410           1.38     joerg 	if (error != 0)
    411           1.38     joerg 		return error;
    412           1.38     joerg 
    413           1.38     joerg 	error = copyout_sockname(SCARG_P32(uap, from), SCARG_P32(uap, fromlenaddr),
    414           1.38     joerg 	    MSG_LENUSRSPACE, from);
    415           1.38     joerg 	if (from != NULL)
    416           1.38     joerg 		m_free(from);
    417           1.38     joerg 	return error;
    418            1.1       mrg }
    419            1.1       mrg 
    420            1.1       mrg int
    421           1.30       dsl netbsd32_sendto(struct lwp *l, const struct netbsd32_sendto_args *uap, register_t *retval)
    422            1.1       mrg {
    423           1.30       dsl 	/* {
    424            1.1       mrg 		syscallarg(int) s;
    425            1.1       mrg 		syscallarg(const netbsd32_voidp) buf;
    426            1.1       mrg 		syscallarg(netbsd32_size_t) len;
    427            1.1       mrg 		syscallarg(int) flags;
    428            1.1       mrg 		syscallarg(const netbsd32_sockaddrp_t) to;
    429            1.1       mrg 		syscallarg(int) tolen;
    430           1.30       dsl 	} */
    431            1.1       mrg 	struct msghdr msg;
    432            1.1       mrg 	struct iovec aiov;
    433            1.1       mrg 
    434           1.24       dsl 	msg.msg_name = SCARG_P32(uap, to); /* XXX kills const */
    435            1.1       mrg 	msg.msg_namelen = SCARG(uap, tolen);
    436            1.1       mrg 	msg.msg_iov = &aiov;
    437            1.1       mrg 	msg.msg_iovlen = 1;
    438            1.1       mrg 	msg.msg_control = 0;
    439           1.24       dsl 	aiov.iov_base = SCARG_P32(uap, buf);	/* XXX kills const */
    440            1.1       mrg 	aiov.iov_len = SCARG(uap, len);
    441           1.26       dsl 	msg.msg_flags = 0;
    442           1.26       dsl 	return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
    443            1.1       mrg }
    444