Home | History | Annotate | Line # | Download | only in netbsd32
netbsd32_socket.c revision 1.37.8.1
      1  1.37.8.1      yamt /*	$NetBSD: netbsd32_socket.c,v 1.37.8.1 2012/04/17 00:07:21 yamt 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.37.8.1      yamt __KERNEL_RCSID(0, "$NetBSD: netbsd32_socket.c,v 1.37.8.1 2012/04/17 00:07:21 yamt 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.37.8.1      yamt  * XXX Assumes that struct sockaddr is compatible.
     53      1.37     rmind  */
     54  1.37.8.1      yamt 
     55  1.37.8.1      yamt #define	CMSG32_ALIGN(n)	(((n) + ALIGNBYTES32) & ~ALIGNBYTES32)
     56  1.37.8.1      yamt #define	CMSG32_DATA(cmsg) \
     57  1.37.8.1      yamt 	((u_char *)(void *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr)))
     58  1.37.8.1      yamt 
     59  1.37.8.1      yamt #define	CMSG32_NXTHDR(mhdr, cmsg)	\
     60  1.37.8.1      yamt 	(((char *)(cmsg) + CMSG32_ALIGN((cmsg)->cmsg_len) + \
     61  1.37.8.1      yamt 			    CMSG32_ALIGN(sizeof(struct cmsghdr)) > \
     62  1.37.8.1      yamt 	    (((char *)(mhdr)->msg_control) + (mhdr)->msg_controllen)) ? \
     63  1.37.8.1      yamt 	    (struct cmsghdr *)0 : \
     64  1.37.8.1      yamt 	    (struct cmsghdr *)((char *)(cmsg) + \
     65  1.37.8.1      yamt 	        CMSG32_ALIGN((cmsg)->cmsg_len)))
     66  1.37.8.1      yamt #define	CMSG32_FIRSTHDR(mhdr) \
     67  1.37.8.1      yamt 	((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
     68  1.37.8.1      yamt 	 (struct cmsghdr *)(mhdr)->msg_control : \
     69  1.37.8.1      yamt 	 (struct cmsghdr *)0)
     70  1.37.8.1      yamt 
     71  1.37.8.1      yamt #define CMSG32_SPACE(l)	(CMSG32_ALIGN(sizeof(struct cmsghdr)) + CMSG32_ALIGN(l))
     72  1.37.8.1      yamt #define CMSG32_LEN(l)	(CMSG32_ALIGN(sizeof(struct cmsghdr)) + (l))
     73  1.37.8.1      yamt 
     74  1.37.8.1      yamt static int
     75  1.37.8.1      yamt copyout32_msg_control_mbuf(struct lwp *l, struct msghdr *mp, int *len, struct mbuf *m, char **q, bool *truncated)
     76  1.37.8.1      yamt {
     77  1.37.8.1      yamt 	struct cmsghdr *cmsg, cmsg32;
     78  1.37.8.1      yamt 	int i, j, error;
     79  1.37.8.1      yamt 
     80  1.37.8.1      yamt 	*truncated = false;
     81  1.37.8.1      yamt 	cmsg = mtod(m, struct cmsghdr *);
     82  1.37.8.1      yamt 	do {
     83  1.37.8.1      yamt 		if ((char *)cmsg == mtod(m, char *) + m->m_len)
     84  1.37.8.1      yamt 			break;
     85  1.37.8.1      yamt 		if ((char *)cmsg > mtod(m, char *) + m->m_len - sizeof(*cmsg))
     86  1.37.8.1      yamt 			return EINVAL;
     87  1.37.8.1      yamt 		cmsg32 = *cmsg;
     88  1.37.8.1      yamt 		j = cmsg->cmsg_len - CMSG_LEN(0);
     89  1.37.8.1      yamt 		i = cmsg32.cmsg_len = CMSG32_LEN(j);
     90  1.37.8.1      yamt 		if (i > *len) {
     91  1.37.8.1      yamt 			mp->msg_flags |= MSG_CTRUNC;
     92  1.37.8.1      yamt 			if (cmsg->cmsg_level == SOL_SOCKET
     93  1.37.8.1      yamt 			    && cmsg->cmsg_type == SCM_RIGHTS) {
     94  1.37.8.1      yamt 				*truncated = true;
     95  1.37.8.1      yamt 				return 0;
     96  1.37.8.1      yamt 			}
     97  1.37.8.1      yamt 			j -= i - *len;
     98  1.37.8.1      yamt 			i = *len;
     99  1.37.8.1      yamt 		}
    100  1.37.8.1      yamt 
    101  1.37.8.1      yamt 		ktrkuser("msgcontrol", cmsg, cmsg->cmsg_len);
    102  1.37.8.1      yamt 		error = copyout(&cmsg32, *q, MAX(i, sizeof(cmsg32)));
    103  1.37.8.1      yamt 		if (error)
    104  1.37.8.1      yamt 			return (error);
    105  1.37.8.1      yamt 		if (i > CMSG32_LEN(0)) {
    106  1.37.8.1      yamt 			error = copyout(CMSG_DATA(cmsg), *q + CMSG32_LEN(0), i - CMSG32_LEN(0));
    107  1.37.8.1      yamt 			if (error)
    108  1.37.8.1      yamt 				return (error);
    109  1.37.8.1      yamt 		}
    110  1.37.8.1      yamt 		j = CMSG32_SPACE(cmsg->cmsg_len - CMSG_LEN(0));
    111  1.37.8.1      yamt 		if (*len >= j) {
    112  1.37.8.1      yamt 			*len -= j;
    113  1.37.8.1      yamt 			*q += j;
    114  1.37.8.1      yamt 		} else {
    115  1.37.8.1      yamt 			*q += i;
    116  1.37.8.1      yamt 			*len = 0;
    117  1.37.8.1      yamt 		}
    118  1.37.8.1      yamt 		cmsg = (void *)((char *)cmsg + CMSG_ALIGN(cmsg->cmsg_len));
    119  1.37.8.1      yamt 	} while (*len > 0);
    120  1.37.8.1      yamt 
    121  1.37.8.1      yamt 	return 0;
    122  1.37.8.1      yamt }
    123  1.37.8.1      yamt 
    124  1.37.8.1      yamt static int
    125  1.37.8.1      yamt copyout32_msg_control(struct lwp *l, struct msghdr *mp, struct mbuf *control)
    126  1.37.8.1      yamt {
    127  1.37.8.1      yamt 	int len, error = 0;
    128  1.37.8.1      yamt 	struct mbuf *m;
    129  1.37.8.1      yamt 	char *q;
    130  1.37.8.1      yamt 	bool truncated;
    131  1.37.8.1      yamt 
    132  1.37.8.1      yamt 	len = mp->msg_controllen;
    133  1.37.8.1      yamt 	if (len <= 0 || control == 0) {
    134  1.37.8.1      yamt 		mp->msg_controllen = 0;
    135  1.37.8.1      yamt 		free_control_mbuf(l, control, control);
    136  1.37.8.1      yamt 		return 0;
    137  1.37.8.1      yamt 	}
    138  1.37.8.1      yamt 
    139  1.37.8.1      yamt 	q = (char *)mp->msg_control;
    140  1.37.8.1      yamt 
    141  1.37.8.1      yamt 	for (m = control; m != NULL; m = m->m_next) {
    142  1.37.8.1      yamt 		error = copyout32_msg_control_mbuf(l, mp, &len, m, &q, &truncated);
    143  1.37.8.1      yamt 		if (truncated) {
    144  1.37.8.1      yamt 			m = control;
    145  1.37.8.1      yamt 			break;
    146  1.37.8.1      yamt 		}
    147  1.37.8.1      yamt 		if (error)
    148  1.37.8.1      yamt 			break;
    149  1.37.8.1      yamt 		if (len <= 0)
    150  1.37.8.1      yamt 			break;
    151  1.37.8.1      yamt 	}
    152  1.37.8.1      yamt 
    153  1.37.8.1      yamt 	free_control_mbuf(l, control, m);
    154  1.37.8.1      yamt 
    155  1.37.8.1      yamt 	mp->msg_controllen = q - (char *)mp->msg_control;
    156  1.37.8.1      yamt 	return error;
    157  1.37.8.1      yamt }
    158       1.1       mrg 
    159       1.1       mrg int
    160      1.30       dsl netbsd32_recvmsg(struct lwp *l, const struct netbsd32_recvmsg_args *uap, register_t *retval)
    161       1.1       mrg {
    162      1.30       dsl 	/* {
    163       1.1       mrg 		syscallarg(int) s;
    164       1.1       mrg 		syscallarg(netbsd32_msghdrp_t) msg;
    165       1.1       mrg 		syscallarg(int) flags;
    166      1.30       dsl 	} */
    167  1.37.8.1      yamt 	struct netbsd32_msghdr	msg32;
    168      1.35     njoly 	struct iovec aiov[UIO_SMALLIOV], *iov;
    169  1.37.8.1      yamt 	struct msghdr	msg;
    170  1.37.8.1      yamt 	int		error;
    171  1.37.8.1      yamt 	struct mbuf	*from, *control;
    172      1.37     rmind 	size_t iovsz;
    173       1.1       mrg 
    174  1.37.8.1      yamt 	error = copyin(SCARG_P32(uap, msg), &msg32, sizeof(msg32));
    175       1.1       mrg 	if (error)
    176       1.1       mrg 		return (error);
    177  1.37.8.1      yamt 
    178  1.37.8.1      yamt 	iovsz = msg32.msg_iovlen * sizeof(struct iovec);
    179  1.37.8.1      yamt 	if (msg32.msg_iovlen > UIO_SMALLIOV) {
    180  1.37.8.1      yamt 		if (msg32.msg_iovlen > IOV_MAX)
    181       1.1       mrg 			return (EMSGSIZE);
    182      1.37     rmind 		iov = kmem_alloc(iovsz, KM_SLEEP);
    183      1.25  christos 	} else
    184       1.1       mrg 		iov = aiov;
    185  1.37.8.1      yamt 	error = netbsd32_to_iovecin(NETBSD32PTR64(msg32.msg_iov), iov,
    186  1.37.8.1      yamt 	    msg32.msg_iovlen);
    187       1.1       mrg 	if (error)
    188       1.1       mrg 		goto done;
    189  1.37.8.1      yamt 
    190  1.37.8.1      yamt 	msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS;
    191  1.37.8.1      yamt 	msg.msg_name = NETBSD32PTR64(msg32.msg_name);
    192  1.37.8.1      yamt 	msg.msg_namelen = msg32.msg_namelen;
    193  1.37.8.1      yamt 	msg.msg_control = NETBSD32PTR64(msg32.msg_control);
    194  1.37.8.1      yamt 	msg.msg_controllen = msg32.msg_controllen;
    195  1.37.8.1      yamt 	msg.msg_iov = iov;
    196  1.37.8.1      yamt 	msg.msg_iovlen = msg32.msg_iovlen;
    197  1.37.8.1      yamt 
    198  1.37.8.1      yamt 	error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from,
    199  1.37.8.1      yamt 	    msg.msg_control != NULL ? &control : NULL, retval);
    200  1.37.8.1      yamt 	if (error != 0)
    201  1.37.8.1      yamt 		goto done;
    202  1.37.8.1      yamt 
    203  1.37.8.1      yamt 	if (msg.msg_control != NULL)
    204  1.37.8.1      yamt 		error = copyout32_msg_control(l, &msg, control);
    205  1.37.8.1      yamt 
    206  1.37.8.1      yamt 	if (error == 0)
    207  1.37.8.1      yamt 		error = copyout_sockname(msg.msg_name, &msg.msg_namelen, 0,
    208  1.37.8.1      yamt 			from);
    209  1.37.8.1      yamt 	if (from != NULL)
    210  1.37.8.1      yamt 		m_free(from);
    211  1.37.8.1      yamt 	if (error == 0) {
    212  1.37.8.1      yamt 		ktrkuser("msghdr", &msg, sizeof msg);
    213  1.37.8.1      yamt 		msg32.msg_namelen = msg.msg_namelen;
    214  1.37.8.1      yamt 		msg32.msg_controllen = msg.msg_controllen;
    215  1.37.8.1      yamt 		msg32.msg_flags = msg.msg_flags;
    216  1.37.8.1      yamt 		error = copyout(&msg32, SCARG_P32(uap, msg), sizeof(msg32));
    217       1.1       mrg 	}
    218  1.37.8.1      yamt 
    219  1.37.8.1      yamt  done:
    220       1.1       mrg 	if (iov != aiov)
    221      1.37     rmind 		kmem_free(iov, iovsz);
    222       1.1       mrg 	return (error);
    223       1.1       mrg }
    224       1.1       mrg 
    225  1.37.8.1      yamt static int
    226  1.37.8.1      yamt copyin32_msg_control(struct lwp *l, struct msghdr *mp)
    227       1.1       mrg {
    228  1.37.8.1      yamt 	/*
    229  1.37.8.1      yamt 	 * Handle cmsg if there is any.
    230  1.37.8.1      yamt 	 */
    231  1.37.8.1      yamt 	struct cmsghdr *cmsg, cmsg32, *cc;
    232  1.37.8.1      yamt 	struct mbuf *ctl_mbuf;
    233  1.37.8.1      yamt 	ssize_t resid = mp->msg_controllen;
    234  1.37.8.1      yamt 	size_t clen, cidx = 0, cspace;
    235  1.37.8.1      yamt 	u_int8_t *control;
    236  1.37.8.1      yamt 	int error;
    237  1.37.8.1      yamt 
    238  1.37.8.1      yamt 	ctl_mbuf = m_get(M_WAIT, MT_CONTROL);
    239  1.37.8.1      yamt 	clen = MLEN;
    240  1.37.8.1      yamt 	control = mtod(ctl_mbuf, void *);
    241  1.37.8.1      yamt 	memset(control, 0, clen);
    242  1.37.8.1      yamt 
    243  1.37.8.1      yamt 	cc = CMSG32_FIRSTHDR(mp);
    244  1.37.8.1      yamt 	do {
    245  1.37.8.1      yamt 		error = copyin(cc, &cmsg32, sizeof(cmsg32));
    246  1.37.8.1      yamt 		if (error)
    247  1.37.8.1      yamt 			goto failure;
    248      1.13     perry 
    249       1.1       mrg 		/*
    250  1.37.8.1      yamt 		 * Sanity check the control message length.
    251       1.1       mrg 		 */
    252  1.37.8.1      yamt 		if (cmsg32.cmsg_len > resid ||
    253  1.37.8.1      yamt 		    cmsg32.cmsg_len < sizeof(cmsg32)) {
    254       1.1       mrg 			error = EINVAL;
    255  1.37.8.1      yamt 			goto failure;
    256       1.1       mrg 		}
    257       1.1       mrg 
    258  1.37.8.1      yamt 		cspace = CMSG_SPACE(cmsg32.cmsg_len - CMSG32_LEN(0));
    259      1.27        ad 
    260  1.37.8.1      yamt 		/* Check the buffer is big enough */
    261  1.37.8.1      yamt 		if (__predict_false(cidx + cspace > clen)) {
    262  1.37.8.1      yamt 			u_int8_t *nc;
    263  1.37.8.1      yamt 			size_t nclen;
    264  1.37.8.1      yamt 
    265  1.37.8.1      yamt 			nclen = cidx + cspace;
    266  1.37.8.1      yamt 			if (nclen >= PAGE_SIZE) {
    267  1.37.8.1      yamt 				error = EINVAL;
    268  1.37.8.1      yamt 				goto failure;
    269  1.37.8.1      yamt 			}
    270  1.37.8.1      yamt 			nc = realloc(clen <= MLEN ? NULL : control,
    271  1.37.8.1      yamt 				     nclen, M_TEMP, M_WAITOK);
    272  1.37.8.1      yamt 			if (!nc) {
    273  1.37.8.1      yamt 				error = ENOMEM;
    274  1.37.8.1      yamt 				goto failure;
    275  1.37.8.1      yamt 			}
    276  1.37.8.1      yamt 			if (cidx <= MLEN) {
    277  1.37.8.1      yamt 				/* Old buffer was in mbuf... */
    278  1.37.8.1      yamt 				memcpy(nc, control, cidx);
    279  1.37.8.1      yamt 				memset(nc + cidx, 0, nclen - cidx);
    280  1.37.8.1      yamt 			} else {
    281  1.37.8.1      yamt 				memset(nc + nclen, 0, nclen - clen);
    282  1.37.8.1      yamt 			}
    283  1.37.8.1      yamt 			control = nc;
    284  1.37.8.1      yamt 			clen = nclen;
    285  1.37.8.1      yamt 		}
    286      1.27        ad 
    287  1.37.8.1      yamt 		/* Copy header */
    288  1.37.8.1      yamt 		cmsg = (void *)&control[cidx];
    289  1.37.8.1      yamt 		cmsg->cmsg_len = CMSG_LEN(cmsg32.cmsg_len - CMSG32_LEN(0));
    290  1.37.8.1      yamt 		cmsg->cmsg_level = cmsg32.cmsg_level;
    291  1.37.8.1      yamt 		cmsg->cmsg_type = cmsg32.cmsg_type;
    292  1.37.8.1      yamt 
    293  1.37.8.1      yamt 		/* Copyin the data */
    294  1.37.8.1      yamt 		error = copyin(CMSG32_DATA(cc), CMSG_DATA(cmsg),
    295  1.37.8.1      yamt 		    cmsg32.cmsg_len - CMSG32_LEN(0));
    296  1.37.8.1      yamt 		if (error)
    297  1.37.8.1      yamt 			goto failure;
    298      1.27        ad 
    299  1.37.8.1      yamt 		resid -= CMSG32_ALIGN(cmsg32.cmsg_len);
    300  1.37.8.1      yamt 		cidx += cmsg->cmsg_len;
    301  1.37.8.1      yamt 	} while ((cc = CMSG32_NXTHDR(mp, cc)) && resid > 0);
    302  1.37.8.1      yamt 
    303  1.37.8.1      yamt 	/* If we allocated a buffer, attach to mbuf */
    304  1.37.8.1      yamt 	if (cidx > MLEN) {
    305  1.37.8.1      yamt 		MEXTADD(ctl_mbuf, control, clen, M_MBUF, NULL, NULL);
    306  1.37.8.1      yamt 		ctl_mbuf->m_flags |= M_EXT_RW;
    307       1.1       mrg 	}
    308  1.37.8.1      yamt 	control = NULL;
    309  1.37.8.1      yamt 	mp->msg_controllen = ctl_mbuf->m_len = CMSG_ALIGN(cidx);
    310  1.37.8.1      yamt 
    311  1.37.8.1      yamt 	mp->msg_control = ctl_mbuf;
    312  1.37.8.1      yamt 	mp->msg_flags |= MSG_CONTROLMBUF;
    313  1.37.8.1      yamt 
    314  1.37.8.1      yamt 	ktrkuser("msgcontrol", mtod(ctl_mbuf, void *),
    315  1.37.8.1      yamt 	    mp->msg_controllen);
    316  1.37.8.1      yamt 
    317  1.37.8.1      yamt 	return 0;
    318  1.37.8.1      yamt 
    319  1.37.8.1      yamt failure:
    320  1.37.8.1      yamt 	if (control != mtod(ctl_mbuf, void *))
    321  1.37.8.1      yamt 		free(control, M_MBUF);
    322  1.37.8.1      yamt 	m_free(ctl_mbuf);
    323  1.37.8.1      yamt 	return error;
    324       1.1       mrg }
    325       1.1       mrg 
    326       1.1       mrg int
    327      1.30       dsl netbsd32_sendmsg(struct lwp *l, const struct netbsd32_sendmsg_args *uap, register_t *retval)
    328       1.1       mrg {
    329      1.30       dsl 	/* {
    330       1.1       mrg 		syscallarg(int) s;
    331       1.1       mrg 		syscallarg(const netbsd32_msghdrp_t) msg;
    332       1.1       mrg 		syscallarg(int) flags;
    333      1.30       dsl 	} */
    334       1.1       mrg 	struct msghdr msg;
    335       1.1       mrg 	struct netbsd32_msghdr msg32;
    336       1.1       mrg 	struct iovec aiov[UIO_SMALLIOV], *iov;
    337      1.35     njoly 	struct netbsd32_iovec *iov32;
    338      1.37     rmind 	size_t iovsz;
    339       1.1       mrg 	int error;
    340       1.1       mrg 
    341      1.24       dsl 	error = copyin(SCARG_P32(uap, msg), &msg32, sizeof(msg32));
    342       1.1       mrg 	if (error)
    343       1.1       mrg 		return (error);
    344       1.1       mrg 	netbsd32_to_msghdr(&msg32, &msg);
    345  1.37.8.1      yamt 	msg.msg_flags = 0;
    346  1.37.8.1      yamt 
    347  1.37.8.1      yamt 	if (CMSG32_FIRSTHDR(&msg)) {
    348  1.37.8.1      yamt 		error = copyin32_msg_control(l, &msg);
    349  1.37.8.1      yamt 		if (error)
    350  1.37.8.1      yamt 			return (error);
    351  1.37.8.1      yamt 	} else {
    352  1.37.8.1      yamt 		msg.msg_control = NULL;
    353  1.37.8.1      yamt 		msg.msg_controllen = 0;
    354  1.37.8.1      yamt 	}
    355      1.26       dsl 
    356      1.37     rmind 	iovsz = msg.msg_iovlen * sizeof(struct iovec);
    357       1.1       mrg 	if ((u_int)msg.msg_iovlen > UIO_SMALLIOV) {
    358       1.1       mrg 		if ((u_int)msg.msg_iovlen > IOV_MAX)
    359       1.1       mrg 			return (EMSGSIZE);
    360      1.37     rmind 		iov = kmem_alloc(iovsz, KM_SLEEP);
    361      1.36     njoly 	} else
    362       1.1       mrg 		iov = aiov;
    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.1       mrg 		goto done;
    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.1       mrg done:
    372       1.1       mrg 	if (iov != aiov)
    373      1.37     rmind 		kmem_free(iov, iovsz);
    374       1.1       mrg 	return (error);
    375       1.1       mrg }
    376       1.1       mrg 
    377       1.1       mrg int
    378      1.30       dsl netbsd32_recvfrom(struct lwp *l, const struct netbsd32_recvfrom_args *uap, register_t *retval)
    379       1.1       mrg {
    380      1.30       dsl 	/* {
    381       1.1       mrg 		syscallarg(int) s;
    382       1.1       mrg 		syscallarg(netbsd32_voidp) buf;
    383       1.1       mrg 		syscallarg(netbsd32_size_t) len;
    384       1.1       mrg 		syscallarg(int) flags;
    385       1.1       mrg 		syscallarg(netbsd32_sockaddrp_t) from;
    386       1.1       mrg 		syscallarg(netbsd32_intp) fromlenaddr;
    387      1.30       dsl 	} */
    388  1.37.8.1      yamt 	struct msghdr	msg;
    389  1.37.8.1      yamt 	struct iovec	aiov;
    390  1.37.8.1      yamt 	int		error;
    391  1.37.8.1      yamt 	struct mbuf	*from;
    392       1.1       mrg 
    393  1.37.8.1      yamt 	msg.msg_name = NULL;
    394  1.37.8.1      yamt 	msg.msg_iov = &aiov;
    395       1.1       mrg 	msg.msg_iovlen = 1;
    396      1.24       dsl 	aiov.iov_base = SCARG_P32(uap, buf);
    397  1.37.8.1      yamt 	aiov.iov_len = SCARG(uap, len);
    398  1.37.8.1      yamt 	msg.msg_control = NULL;
    399  1.37.8.1      yamt 	msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS;
    400  1.37.8.1      yamt 
    401  1.37.8.1      yamt 	error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, NULL, retval);
    402  1.37.8.1      yamt 	if (error != 0)
    403  1.37.8.1      yamt 		return error;
    404  1.37.8.1      yamt 
    405  1.37.8.1      yamt 	error = copyout_sockname(SCARG_P32(uap, from), SCARG_P32(uap, fromlenaddr),
    406  1.37.8.1      yamt 	    MSG_LENUSRSPACE, from);
    407  1.37.8.1      yamt 	if (from != NULL)
    408  1.37.8.1      yamt 		m_free(from);
    409  1.37.8.1      yamt 	return error;
    410       1.1       mrg }
    411       1.1       mrg 
    412       1.1       mrg int
    413      1.30       dsl netbsd32_sendto(struct lwp *l, const struct netbsd32_sendto_args *uap, register_t *retval)
    414       1.1       mrg {
    415      1.30       dsl 	/* {
    416       1.1       mrg 		syscallarg(int) s;
    417       1.1       mrg 		syscallarg(const netbsd32_voidp) buf;
    418       1.1       mrg 		syscallarg(netbsd32_size_t) len;
    419       1.1       mrg 		syscallarg(int) flags;
    420       1.1       mrg 		syscallarg(const netbsd32_sockaddrp_t) to;
    421       1.1       mrg 		syscallarg(int) tolen;
    422      1.30       dsl 	} */
    423       1.1       mrg 	struct msghdr msg;
    424       1.1       mrg 	struct iovec aiov;
    425       1.1       mrg 
    426      1.24       dsl 	msg.msg_name = SCARG_P32(uap, to); /* XXX kills const */
    427       1.1       mrg 	msg.msg_namelen = SCARG(uap, tolen);
    428       1.1       mrg 	msg.msg_iov = &aiov;
    429       1.1       mrg 	msg.msg_iovlen = 1;
    430       1.1       mrg 	msg.msg_control = 0;
    431      1.24       dsl 	aiov.iov_base = SCARG_P32(uap, buf);	/* XXX kills const */
    432       1.1       mrg 	aiov.iov_len = SCARG(uap, len);
    433      1.26       dsl 	msg.msg_flags = 0;
    434      1.26       dsl 	return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
    435       1.1       mrg }
    436