Home | History | Annotate | Line # | Download | only in common
      1 /*	$NetBSD: linux_socket.c,v 1.164 2026/10/17 14:59:45 alnsn Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Frank van der Linden and Eric Haszlakiewicz.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*
     33  * Functions in multiarch:
     34  *	linux_sys_socketcall		: linux_socketcall.c
     35  */
     36 
     37 #include <sys/cdefs.h>
     38 __KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.164 2026/10/17 14:59:45 alnsn Exp $");
     39 
     40 #if defined(_KERNEL_OPT)
     41 #include "opt_inet.h"
     42 #endif /* defined(_KERNEL_OPT) */
     43 
     44 #include <sys/param.h>
     45 #include <sys/kernel.h>
     46 #include <sys/systm.h>
     47 #include <sys/buf.h>
     48 #include <sys/ioctl.h>
     49 #include <sys/tty.h>
     50 #include <sys/file.h>
     51 #include <sys/filedesc.h>
     52 #include <sys/select.h>
     53 #include <sys/socket.h>
     54 #include <sys/socketvar.h>
     55 #include <sys/domain.h>
     56 #include <net/if.h>
     57 #include <net/if_dl.h>
     58 #include <net/if_types.h>
     59 #include <netinet/in.h>
     60 #include <netinet/tcp.h>
     61 #include <sys/mount.h>
     62 #include <sys/proc.h>
     63 #include <sys/vnode.h>
     64 #include <sys/device.h>
     65 #include <sys/protosw.h>
     66 #include <sys/mbuf.h>
     67 #include <sys/syslog.h>
     68 #include <sys/exec.h>
     69 #include <sys/kauth.h>
     70 #include <sys/syscallargs.h>
     71 #include <sys/ktrace.h>
     72 
     73 #include <lib/libkern/libkern.h>
     74 
     75 #include <netinet/ip6.h>
     76 #include <netinet6/ip6_var.h>
     77 
     78 #include <compat/sys/socket.h>
     79 #include <compat/sys/sockio.h>
     80 
     81 #include <compat/linux/common/linux_types.h>
     82 #include <compat/linux/common/linux_util.h>
     83 #include <compat/linux/common/linux_signal.h>
     84 #include <compat/linux/common/linux_ioctl.h>
     85 #include <compat/linux/common/linux_sched.h>
     86 #include <compat/linux/common/linux_socket.h>
     87 #include <compat/linux/common/linux_fcntl.h>
     88 #if !defined(__aarch64__) && !defined(__alpha__) && !defined(__amd64__)
     89 #include <compat/linux/common/linux_socketcall.h>
     90 #endif
     91 #include <compat/linux/common/linux_sockio.h>
     92 #include <compat/linux/common/linux_ipc.h>
     93 #include <compat/linux/common/linux_sem.h>
     94 
     95 #include <compat/linux/linux_syscallargs.h>
     96 
     97 #ifdef DEBUG_LINUX
     98 #define DPRINTF(a) uprintf a
     99 #else
    100 #define DPRINTF(a)
    101 #endif
    102 
    103 /*
    104  * The calls in this file are entered either via the linux_socketcall()
    105  * interface or, on the Alpha, as individual syscalls.  The
    106  * linux_socketcall function does any massaging of arguments so that all
    107  * the calls in here need not think that they are anything other
    108  * than a normal syscall.
    109  */
    110 
    111 static int linux_to_bsd_domain(int);
    112 static int bsd_to_linux_domain(int);
    113 static int linux_to_bsd_type(int);
    114 int linux_to_bsd_sopt_level(int);
    115 int linux_to_bsd_so_sockopt(int);
    116 int linux_to_bsd_ip_sockopt(int);
    117 int linux_to_bsd_ipv6_sockopt(int);
    118 int linux_to_bsd_tcp_sockopt(int);
    119 int linux_to_bsd_udp_sockopt(int);
    120 int linux_getifname(struct lwp *, register_t *, void *);
    121 int linux_getifconf(struct lwp *, register_t *, void *);
    122 int linux_getifhwaddr(struct lwp *, register_t *, u_int, void *);
    123 static int linux_get_sa(struct lwp *, int, struct sockaddr_big *,
    124 		const struct osockaddr *, socklen_t);
    125 static int linux_sa_put(struct osockaddr *osa);
    126 static int linux_to_bsd_msg_flags(int);
    127 static int bsd_to_linux_msg_flags(int);
    128 static int linux_to_bsd_msghdr(const struct linux_msghdr *, struct msghdr *);
    129 static void bsd_to_linux_msghdr(const struct msghdr *, struct linux_msghdr *);
    130 
    131 static const int linux_to_bsd_domain_[LINUX_AF_MAX] = {
    132 	AF_UNSPEC,
    133 	AF_UNIX,
    134 	AF_INET,
    135 	AF_CCITT,	/* LINUX_AF_AX25 */
    136 	AF_IPX,
    137 	AF_APPLETALK,
    138 	-1,		/* LINUX_AF_NETROM */
    139 	-1,		/* LINUX_AF_BRIDGE */
    140 	-1,		/* LINUX_AF_ATMPVC */
    141 	AF_CCITT,	/* LINUX_AF_X25 */
    142 	AF_INET6,
    143 	-1,		/* LINUX_AF_ROSE */
    144 	AF_DECnet,
    145 	-1,		/* LINUX_AF_NETBEUI */
    146 	-1,		/* LINUX_AF_SECURITY */
    147 	pseudo_AF_KEY,
    148 	AF_ROUTE,	/* LINUX_AF_NETLINK */
    149 	-1,		/* LINUX_AF_PACKET */
    150 	-1,		/* LINUX_AF_ASH */
    151 	-1,		/* LINUX_AF_ECONET */
    152 	-1,		/* LINUX_AF_ATMSVC */
    153 	AF_SNA,
    154 	/* rest up to LINUX_AF_MAX-1 is not allocated */
    155 	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    156 };
    157 
    158 static const int bsd_to_linux_domain_[AF_MAX] = {
    159 	LINUX_AF_UNSPEC,
    160 	LINUX_AF_UNIX,
    161 	LINUX_AF_INET,
    162 	-1,		/* AF_IMPLINK */
    163 	-1,		/* AF_PUP */
    164 	-1,		/* AF_CHAOS */
    165 	-1,		/* AF_NS */
    166 	-1,		/* AF_ISO */
    167 	-1,		/* AF_ECMA */
    168 	-1,		/* AF_DATAKIT */
    169 	LINUX_AF_AX25,	/* AF_CCITT */
    170 	LINUX_AF_SNA,
    171 	LINUX_AF_DECnet,
    172 	-1,		/* AF_DLI */
    173 	-1,		/* AF_LAT */
    174 	-1,		/* AF_HYLINK */
    175 	LINUX_AF_APPLETALK,
    176 	LINUX_AF_NETLINK,
    177 	-1,		/* AF_LINK */
    178 	-1,		/* AF_XTP */
    179 	-1,		/* AF_COIP */
    180 	-1,		/* AF_CNT */
    181 	-1,		/* pseudo_AF_RTIP */
    182 	LINUX_AF_IPX,
    183 	LINUX_AF_INET6,
    184 	-1,		/* pseudo_AF_PIP */
    185 	-1,		/* AF_ISDN */
    186 	-1,		/* AF_NATM */
    187 	-1,		/* AF_ARP */
    188 	LINUX_pseudo_AF_KEY,
    189 	-1,		/* pseudo_AF_HDRCMPLT */
    190 };
    191 
    192 static const struct {
    193 	int bfl;
    194 	int lfl;
    195 } bsd_to_linux_msg_flags_[] = {
    196 	{MSG_OOB,		LINUX_MSG_OOB},
    197 	{MSG_PEEK,		LINUX_MSG_PEEK},
    198 	{MSG_DONTROUTE,		LINUX_MSG_DONTROUTE},
    199 	{MSG_EOR,		LINUX_MSG_EOR},
    200 	{MSG_TRUNC,		LINUX_MSG_TRUNC},
    201 	{MSG_CTRUNC,		LINUX_MSG_CTRUNC},
    202 	{MSG_WAITALL,		LINUX_MSG_WAITALL},
    203 	{MSG_DONTWAIT,		LINUX_MSG_DONTWAIT},
    204 	{MSG_BCAST,		0},		/* not supported, clear */
    205 	{MSG_MCAST,		0},		/* not supported, clear */
    206 	{MSG_NOSIGNAL,		LINUX_MSG_NOSIGNAL},
    207 	{-1, /* not supp */	LINUX_MSG_PROBE},
    208 	{-1, /* not supp */	LINUX_MSG_FIN},
    209 	{-1, /* not supp */	LINUX_MSG_SYN},
    210 	{-1, /* not supp */	LINUX_MSG_CONFIRM},
    211 	{-1, /* not supp */	LINUX_MSG_RST},
    212 	{-1, /* not supp */	LINUX_MSG_ERRQUEUE},
    213 	{-1, /* not supp */	LINUX_MSG_MORE},
    214 };
    215 
    216 /*
    217  * Convert between Linux and BSD socket domain values
    218  */
    219 static int
    220 linux_to_bsd_domain(int ldom)
    221 {
    222 	if (ldom < 0 || ldom >= LINUX_AF_MAX)
    223 		return (-1);
    224 
    225 	return linux_to_bsd_domain_[ldom];
    226 }
    227 
    228 /*
    229  * Convert between BSD and Linux socket domain values
    230  */
    231 static int
    232 bsd_to_linux_domain(int bdom)
    233 {
    234 	if (bdom < 0 || bdom >= AF_MAX)
    235 		return (-1);
    236 
    237 	return bsd_to_linux_domain_[bdom];
    238 }
    239 
    240 static int
    241 linux_to_bsd_type(int ltype)
    242 {
    243 	int type, flags;
    244 
    245 	/* Real types are identical between Linux and NetBSD */
    246 	type = ltype & LINUX_SOCK_TYPE_MASK;
    247 
    248 	/* But flags are not .. */
    249 	flags = ltype & ~LINUX_SOCK_TYPE_MASK;
    250 	if (flags & ~(LINUX_SOCK_CLOEXEC|LINUX_SOCK_NONBLOCK))
    251 		return -1;
    252 
    253 	if (flags & LINUX_SOCK_CLOEXEC)
    254 		type |= SOCK_CLOEXEC;
    255 	if (flags & LINUX_SOCK_NONBLOCK)
    256 		type |= SOCK_NONBLOCK;
    257 
    258 	return type;
    259 }
    260 
    261 static int
    262 linux_to_bsd_msg_flags(int lflag)
    263 {
    264 	int i, lfl, bfl;
    265 	int bflag = 0;
    266 
    267 	if (lflag == 0)
    268 		return (0);
    269 
    270 	for(i = 0; i < __arraycount(bsd_to_linux_msg_flags_); i++) {
    271 		bfl = bsd_to_linux_msg_flags_[i].bfl;
    272 		lfl = bsd_to_linux_msg_flags_[i].lfl;
    273 
    274 		if (lfl == 0)
    275 			continue;
    276 
    277 		if (lflag & lfl) {
    278 			if (bfl < 0)
    279 				return (-1);
    280 
    281 			bflag |= bfl;
    282 		}
    283 	}
    284 
    285 	return (bflag);
    286 }
    287 
    288 static int
    289 bsd_to_linux_msg_flags(int bflag)
    290 {
    291 	int i, lfl, bfl;
    292 	int lflag = 0;
    293 
    294 	if (bflag == 0)
    295 		return (0);
    296 
    297 	for(i = 0; i < __arraycount(bsd_to_linux_msg_flags_); i++) {
    298 		bfl = bsd_to_linux_msg_flags_[i].bfl;
    299 		lfl = bsd_to_linux_msg_flags_[i].lfl;
    300 
    301 		if (bfl <= 0)
    302 			continue;
    303 
    304 		if (bflag & bfl) {
    305 			if (lfl < 0)
    306 				return (-1);
    307 
    308 			lflag |= lfl;
    309 		}
    310 	}
    311 
    312 	return (lflag);
    313 }
    314 
    315 int
    316 linux_sys_socket(struct lwp *l, const struct linux_sys_socket_args *uap, register_t *retval)
    317 {
    318 	/* {
    319 		syscallarg(int)	domain;
    320 		syscallarg(int)	type;
    321 		syscallarg(int) protocol;
    322 	} */
    323 	struct sys___socket30_args bsa;
    324 	int error;
    325 
    326 	memset(&bsa, 0, sizeof(bsa));
    327 	SCARG(&bsa, protocol) = SCARG(uap, protocol);
    328 	SCARG(&bsa, domain) = linux_to_bsd_domain(SCARG(uap, domain));
    329 	if (SCARG(&bsa, domain) == -1)
    330 		return EINVAL;
    331 	SCARG(&bsa, type) = linux_to_bsd_type(SCARG(uap, type));
    332 	if (SCARG(&bsa, type) == -1)
    333 		return EINVAL;
    334 	/*
    335 	 * Apparently linux uses this to talk to ISDN sockets. If we fail
    336 	 * now programs seems to handle it, but if we don't we are going
    337 	 * to fail when we bind and programs don't handle this well.
    338 	 */
    339 	if (SCARG(&bsa, domain) == AF_ROUTE && SCARG(&bsa, type) == SOCK_RAW)
    340 		return ENOTSUP;
    341 	error = sys___socket30(l, &bsa, retval);
    342 
    343 #ifdef INET6
    344 	/*
    345 	 * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by
    346 	 * default and some apps depend on this. So, set V6ONLY to 0
    347 	 * for Linux apps if the sysctl value is set to 1.
    348 	 */
    349 	if (!error && ip6_v6only && SCARG(&bsa, domain) == PF_INET6) {
    350 		struct socket *so;
    351 
    352 		if (fd_getsock(*retval, &so) == 0) {
    353 			int val = 0;
    354 
    355 			/* ignore error */
    356 			(void)so_setsockopt(l, so, IPPROTO_IPV6, IPV6_V6ONLY,
    357 			    &val, sizeof(val));
    358 
    359 			fd_putfile(*retval);
    360 		}
    361 	}
    362 #endif
    363 
    364 	return (error);
    365 }
    366 
    367 int
    368 linux_sys_socketpair(struct lwp *l, const struct linux_sys_socketpair_args *uap, register_t *retval)
    369 {
    370 	/* {
    371 		syscallarg(int) domain;
    372 		syscallarg(int) type;
    373 		syscallarg(int) protocol;
    374 		syscallarg(int *) rsv;
    375 	} */
    376 	struct sys_socketpair_args bsa;
    377 
    378 	memset(&bsa, 0, sizeof(bsa));
    379 	SCARG(&bsa, domain) = linux_to_bsd_domain(SCARG(uap, domain));
    380 	if (SCARG(&bsa, domain) == -1)
    381 		return EINVAL;
    382 	SCARG(&bsa, type) = linux_to_bsd_type(SCARG(uap, type));
    383 	if (SCARG(&bsa, type) == -1)
    384 		return EINVAL;
    385 	SCARG(&bsa, protocol) = SCARG(uap, protocol);
    386 	SCARG(&bsa, rsv) = SCARG(uap, rsv);
    387 
    388 	return sys_socketpair(l, &bsa, retval);
    389 }
    390 
    391 int
    392 linux_sys_sendto(struct lwp *l, const struct linux_sys_sendto_args *uap, register_t *retval)
    393 {
    394 	/* {
    395 		syscallarg(int)				s;
    396 		syscallarg(void *)			msg;
    397 		syscallarg(int)				len;
    398 		syscallarg(int)				flags;
    399 		syscallarg(struct osockaddr *)		to;
    400 		syscallarg(int)				tolen;
    401 	} */
    402 	struct msghdr   msg;
    403 	struct iovec    aiov;
    404 	struct sockaddr_big nam;
    405 	struct mbuf *m;
    406 	int bflags;
    407 	int error;
    408 
    409 	/* Translate message flags.  */
    410 	bflags = linux_to_bsd_msg_flags(SCARG(uap, flags));
    411 	if (bflags < 0)
    412 		/* Some supported flag */
    413 		return EINVAL;
    414 
    415 	msg.msg_flags = 0;
    416 	msg.msg_name = NULL;
    417 	msg.msg_control = NULL;
    418 
    419 	if (SCARG(uap, tolen)) {
    420 		/* Read in and convert the sockaddr */
    421 		error = linux_get_sa(l, SCARG(uap, s), &nam, SCARG(uap, to),
    422 		    SCARG(uap, tolen));
    423 		if (error)
    424 			return error;
    425 		error = sockargs(&m, &nam, nam.sb_len, UIO_SYSSPACE, MT_SONAME);
    426 		if (error)
    427 			return error;
    428 		msg.msg_flags |= MSG_NAMEMBUF;
    429 		msg.msg_name = m;
    430 		msg.msg_namelen = nam.sb_len;
    431 	}
    432 
    433 	msg.msg_iov = &aiov;
    434 	msg.msg_iovlen = 1;
    435 	aiov.iov_base = __UNCONST(SCARG(uap, msg));
    436 	aiov.iov_len = SCARG(uap, len);
    437 
    438 	return do_sys_sendmsg(l, SCARG(uap, s), &msg, bflags, retval);
    439 }
    440 
    441 static int
    442 linux_to_bsd_msghdr(const struct linux_msghdr *lmsg, struct msghdr *bmsg)
    443 {
    444 
    445 	/*
    446 	 * Verify no integer truncation of the inputs.  For overly
    447 	 * large inputs, fail with the same error codes Linux uses.
    448 	 */
    449 	if (lmsg->msg_namelen < 0)
    450 		return EINVAL;
    451 	CTASSERT(!__type_is_signed(__typeof(lmsg->msg_iovlen)));
    452 	if (lmsg->msg_iovlen > UIO_MAXIOV)
    453 		return EMSGSIZE;
    454 	CTASSERT(!__type_is_signed(__typeof(lmsg->msg_controllen)));
    455 	if (lmsg->msg_controllen > __type_max(__typeof(bmsg->msg_controllen)))
    456 		return ENOBUFS;
    457 
    458 	memset(bmsg, 0, sizeof(*bmsg));
    459 	bmsg->msg_name = lmsg->msg_name;
    460 	bmsg->msg_namelen = MIN(lmsg->msg_namelen,
    461 	    sizeof(struct sockaddr_storage));
    462 	bmsg->msg_iov = lmsg->msg_iov;
    463 	bmsg->msg_iovlen = lmsg->msg_iovlen;
    464 	bmsg->msg_control = lmsg->msg_control;
    465 	bmsg->msg_controllen = lmsg->msg_controllen;
    466 	bmsg->msg_flags = lmsg->msg_flags;
    467 
    468 	return 0;
    469 }
    470 
    471 static void
    472 bsd_to_linux_msghdr(const struct msghdr *bmsg, struct linux_msghdr *lmsg)
    473 {
    474 
    475 	/*
    476 	 * Assert no truncation on the way out.
    477 	 *
    478 	 * - msg_namelen should have been preserved or shortened by
    479 	 *   copyout_sockname.
    480 	 * - msg_iovlen should have been preserved and previously
    481 	 *   confirmed by linux_to_bsd_msghdr to lie in [0,UIO_MAXIOV].
    482 	 * - msg_controllen can always be faithfully converted from BSD
    483 	 *   struct msghdr to Linux struct msghdr without truncation.
    484 	 */
    485 	CTASSERT(__type_min(__typeof(bmsg->msg_namelen)) == 0);
    486 	KASSERT(bmsg->msg_namelen <= __type_max(__typeof(lmsg->msg_namelen)));
    487 	CTASSERT(__type_min(__typeof(lmsg->msg_iovlen)) <= 0);
    488 	KASSERT(lmsg->msg_iovlen >= 0);
    489 	KASSERT(lmsg->msg_iovlen <= UIO_MAXIOV);
    490 	CTASSERT(__type_min(__typeof(lmsg->msg_controllen)) <=
    491 	    __type_min(__typeof(bmsg->msg_controllen)));
    492 	CTASSERT(__type_max(__typeof(lmsg->msg_controllen)) >=
    493 	    __type_max(__typeof(bmsg->msg_controllen)));
    494 
    495 	memset(lmsg, 0, sizeof(*lmsg));
    496 	lmsg->msg_name = bmsg->msg_name;
    497 	lmsg->msg_namelen = bmsg->msg_namelen;
    498 	lmsg->msg_iov = bmsg->msg_iov;
    499 	lmsg->msg_iovlen = bmsg->msg_iovlen;
    500 	lmsg->msg_control = bmsg->msg_control;
    501 	lmsg->msg_controllen = bmsg->msg_controllen;
    502 	lmsg->msg_flags = bmsg->msg_flags;
    503 }
    504 
    505 int
    506 linux_sys_sendmsg(struct lwp *l, const struct linux_sys_sendmsg_args *uap, register_t *retval)
    507 {
    508 	/* {
    509 		syscallarg(int) s;
    510 		syscallarg(struct linux_msghdr *) msg;
    511 		syscallarg(u_int) flags;
    512 	} */
    513 	struct msghdr	msg;
    514 	struct linux_msghdr lmsg;
    515 	int		error;
    516 	int		bflags;
    517 	struct sockaddr_big nam;
    518 	u_int8_t	*control;
    519 	struct mbuf     *ctl_mbuf = NULL;
    520 
    521 	error = copyin(SCARG(uap, msg), &lmsg, sizeof(lmsg));
    522 	if (error)
    523 		return error;
    524 	error = linux_to_bsd_msghdr(&lmsg, &msg);
    525 	if (error)
    526 		return error;
    527 
    528 	msg.msg_flags = MSG_IOVUSRSPACE;
    529 
    530 	/*
    531 	 * Translate message flags.
    532 	 */
    533 	bflags = linux_to_bsd_msg_flags(SCARG(uap, flags));
    534 	if (bflags < 0)
    535 		/* Some supported flag */
    536 		return EINVAL;
    537 
    538 	if (lmsg.msg_name) {
    539 		/* Read in and convert the sockaddr */
    540 		error = linux_get_sa(l, SCARG(uap, s), &nam, msg.msg_name,
    541 		    msg.msg_namelen);
    542 		if (error)
    543 			return (error);
    544 		msg.msg_name = &nam;
    545 	}
    546 
    547 	/*
    548 	 * Handle cmsg if there is any.
    549 	 */
    550 	if (LINUX_CMSG_FIRSTHDR(&lmsg)) {
    551 		struct linux_cmsghdr l_cmsg, *l_cc;
    552 		struct cmsghdr *cmsg;
    553 		socklen_t resid = msg.msg_controllen;
    554 		size_t clen, cidx = 0, cspace;
    555 
    556 		ctl_mbuf = m_get(M_WAIT, MT_CONTROL);
    557 		clen = MLEN;
    558 		control = mtod(ctl_mbuf, void *);
    559 
    560 		l_cc = LINUX_CMSG_FIRSTHDR(&lmsg);
    561 		do {
    562 			if (resid < sizeof(l_cmsg)) {
    563 				error = EINVAL;
    564 				goto done;
    565 			}
    566 			error = copyin(l_cc, &l_cmsg, sizeof(l_cmsg));
    567 			if (error)
    568 				goto done;
    569 
    570 			/*
    571 			 * Sanity check the control message length.
    572 			 * If either:
    573 			 *
    574 			 * 1. aligning it would overflow socklen_t, or
    575 			 * 2. aligning it exceeds msg_controllen, or
    576 			 * 3. adding the delta would overflow socklen_t, or
    577 			 * 4. it's not enough for a struct cmsghdr,
    578 			 *
    579 			 * then fail with EINVAL.
    580 			 */
    581 			CTASSERT(LINUX_CMSG_ALIGN(1) <=
    582 			    __type_max(__typeof(resid)));
    583 			if ((l_cmsg.cmsg_len >= __type_max(__typeof(resid)) -
    584 				LINUX_CMSG_ALIGN(1)) ||
    585 			    (LINUX_CMSG_ALIGN(l_cmsg.cmsg_len) > resid) ||
    586 			    (l_cmsg.cmsg_len >
    587 				__type_max(__typeof(cmsg->cmsg_len)) -
    588 				LINUX_CMSG_ALIGN_DELTA) ||
    589 			    (l_cmsg.cmsg_len < sizeof(l_cmsg))) {
    590 				error = EINVAL;
    591 				goto done;
    592 			}
    593 
    594 			/*
    595 			 * Refuse unsupported control messages, and
    596 			 * translate fields as appropriate.
    597 			 */
    598 			switch (l_cmsg.cmsg_level) {
    599 			case LINUX_SOL_SOCKET:
    600 				/* It only differs on some archs */
    601 				if (LINUX_SOL_SOCKET != SOL_SOCKET)
    602 					l_cmsg.cmsg_level = SOL_SOCKET;
    603 
    604 				switch(l_cmsg.cmsg_type) {
    605 				case LINUX_SCM_RIGHTS:
    606 					/* Linux SCM_RIGHTS is same as NetBSD */
    607 					break;
    608 
    609 				case LINUX_SCM_CREDENTIALS:
    610 					/* no native equivalent, just drop it */
    611 					if (control != mtod(ctl_mbuf, void *))
    612 						free(control, M_MBUF);
    613 					m_free(ctl_mbuf);
    614 					ctl_mbuf = NULL;
    615 					msg.msg_control = NULL;
    616 					msg.msg_controllen = 0;
    617 					goto skipcmsg;
    618 
    619 				default:
    620 					/* other types not supported */
    621 					error = EINVAL;
    622 					goto done;
    623 				}
    624 				break;
    625 			default:
    626 				/* pray and leave intact */
    627 				break;
    628 			}
    629 
    630 			cspace = CMSG_SPACE(l_cmsg.cmsg_len - sizeof(l_cmsg));
    631 
    632 			/* Check the buffer is big enough */
    633 			if (__predict_false(cidx + cspace > clen)) {
    634 				u_int8_t *nc;
    635 				size_t nclen;
    636 
    637 				nclen = cidx + cspace;
    638 				if (nclen >= PAGE_SIZE) {
    639 					error = EINVAL;
    640 					goto done;
    641 				}
    642 				nc = realloc(clen <= MLEN ? NULL : control,
    643 						nclen, M_TEMP, M_WAITOK);
    644 				if (!nc) {
    645 					error = ENOMEM;
    646 					goto done;
    647 				}
    648 				if (cidx <= MLEN)
    649 					/* Old buffer was in mbuf... */
    650 					memcpy(nc, control, cidx);
    651 				control = nc;
    652 				clen = nclen;
    653 			}
    654 
    655 			/* Copy header */
    656 			cmsg = (void *)&control[cidx];
    657 			cmsg->cmsg_len = l_cmsg.cmsg_len + LINUX_CMSG_ALIGN_DELTA;
    658 			cmsg->cmsg_level = l_cmsg.cmsg_level;
    659 			cmsg->cmsg_type = l_cmsg.cmsg_type;
    660 
    661 			/* Zero area between header and data */
    662 			memset(cmsg + 1, 0,
    663 				CMSG_ALIGN(sizeof(*cmsg)) - sizeof(*cmsg));
    664 
    665 			/* Copyin the data */
    666 			error = copyin(LINUX_CMSG_DATA(l_cc),
    667 				CMSG_DATA(cmsg),
    668 				l_cmsg.cmsg_len - sizeof(l_cmsg));
    669 			if (error)
    670 				goto done;
    671 
    672 			resid -= LINUX_CMSG_ALIGN(l_cmsg.cmsg_len);
    673 			cidx += cspace;
    674 		} while ((l_cc = LINUX_CMSG_NXTHDR(&msg, l_cc, &l_cmsg)) && resid > 0);
    675 
    676 		/* If we allocated a buffer, attach to mbuf */
    677 		if (cidx > MLEN) {
    678 			MEXTADD(ctl_mbuf, control, clen, M_MBUF, NULL, NULL);
    679 			ctl_mbuf->m_flags |= M_EXT_RW;
    680 		}
    681 		control = NULL;
    682 		ctl_mbuf->m_len = cidx;
    683 
    684 		msg.msg_control = ctl_mbuf;
    685 		msg.msg_flags |= MSG_CONTROLMBUF;
    686 
    687 		ktrkuser("mbcontrol", mtod(ctl_mbuf, void *),
    688 		    msg.msg_controllen);
    689 	}
    690 
    691 skipcmsg:
    692 	error = do_sys_sendmsg(l, SCARG(uap, s), &msg, bflags, retval);
    693 	/* Freed internally */
    694 	ctl_mbuf = NULL;
    695 
    696 done:
    697 	if (ctl_mbuf != NULL) {
    698 		if (control != NULL && control != mtod(ctl_mbuf, void *))
    699 			free(control, M_MBUF);
    700 		m_free(ctl_mbuf);
    701 	}
    702 	return (error);
    703 }
    704 
    705 int
    706 linux_sys_recvfrom(struct lwp *l, const struct linux_sys_recvfrom_args *uap, register_t *retval)
    707 {
    708 	/* {
    709 		syscallarg(int) s;
    710 		syscallarg(void *) buf;
    711 		syscallarg(int) len;
    712 		syscallarg(int) flags;
    713 		syscallarg(struct osockaddr *) from;
    714 		syscallarg(int *) fromlenaddr;
    715 	} */
    716 	int		error;
    717 	int		bflags;
    718 	struct sys_recvfrom_args bra;
    719 
    720 	/*
    721 	 * Translate message flags.
    722 	 */
    723 	bflags = linux_to_bsd_msg_flags(SCARG(uap, flags));
    724 	if (bflags < 0)
    725 		return EINVAL;
    726 
    727 	memset(&bra, 0, sizeof(bra));
    728 	SCARG(&bra, s) = SCARG(uap, s);
    729 	SCARG(&bra, buf) = SCARG(uap, buf);
    730 	SCARG(&bra, len) = SCARG(uap, len);
    731 	SCARG(&bra, flags) = bflags;
    732 	SCARG(&bra, from) = (struct sockaddr *) SCARG(uap, from);
    733 	SCARG(&bra, fromlenaddr) = (socklen_t *)SCARG(uap, fromlenaddr);
    734 
    735 	if ((error = sys_recvfrom(l, &bra, retval)))
    736 		return (error);
    737 
    738 	if (SCARG(uap, from) && (error = linux_sa_put(SCARG(uap, from))))
    739 		return (error);
    740 
    741 	return (0);
    742 }
    743 
    744 static int
    745 linux_copyout_msg_control(struct lwp *l, struct msghdr *mp, struct mbuf *control)
    746 {
    747 	socklen_t dlen;
    748 	int error = 0;
    749 	struct cmsghdr *cmsg;
    750 	struct linux_cmsghdr linux_cmsg;
    751 	struct mbuf *m;
    752 	char *q, *q_end;
    753 
    754 	if (mp->msg_controllen <= 0 || control == 0) {
    755 		mp->msg_controllen = 0;
    756 		free_control_mbuf(l, control, control);
    757 		return 0;
    758 	}
    759 
    760 	ktrkuser("msgcontrol", mtod(control, void *), mp->msg_controllen);
    761 
    762 	q = (char *)mp->msg_control;
    763 	q_end = q + mp->msg_controllen;
    764 
    765 	for (m = control; m != NULL; ) {
    766 		cmsg = mtod(m, struct cmsghdr *);
    767 
    768 		/*
    769 		 * Fixup cmsg. We handle two things:
    770 		 * 0. different sizeof cmsg_len.
    771 		 * 1. different values for level/type on some archs
    772 		 * 2. different alignment of CMSG_DATA on some archs
    773 		 */
    774 		memset(&linux_cmsg, 0, sizeof(linux_cmsg));
    775 		CTASSERT(LINUX_CMSG_ALIGN_DELTA >= 0);
    776 		CTASSERT(CMSG_LEN(0) ==
    777 		    sizeof(linux_cmsg) + LINUX_CMSG_ALIGN_DELTA);
    778 		KASSERTMSG(cmsg->cmsg_len >= CMSG_LEN(0),
    779 		    "cmsg->cmsg_len=%u", cmsg->cmsg_len);
    780 		linux_cmsg.cmsg_len = cmsg->cmsg_len - LINUX_CMSG_ALIGN_DELTA;
    781 		KASSERTMSG(linux_cmsg.cmsg_len >= sizeof(linux_cmsg),
    782 		    "linux_cmsg.cmsg_len=%zu", linux_cmsg.cmsg_len);
    783 		linux_cmsg.cmsg_level = cmsg->cmsg_level;
    784 		linux_cmsg.cmsg_type = cmsg->cmsg_type;
    785 
    786 		dlen = q_end - q;
    787 		if (linux_cmsg.cmsg_len > dlen) {
    788 			/* Not enough room for the parameter */
    789 			if (dlen < sizeof linux_cmsg)
    790 				/* Discard if header wont fit */
    791 				break;
    792 			dlen -= sizeof linux_cmsg;
    793 			mp->msg_flags |= MSG_CTRUNC;
    794 			if (linux_cmsg.cmsg_level == SOL_SOCKET
    795 			    && linux_cmsg.cmsg_type == SCM_RIGHTS)
    796 				/* Do not truncate me ... */
    797 				break;
    798 		} else
    799 			dlen = linux_cmsg.cmsg_len - sizeof linux_cmsg;
    800 
    801 		/*
    802 		 * NetBSD will not create a cmsg record whose header
    803 		 * length plus aligned content length would overflow
    804 		 * socklen_t.  This justifies computing
    805 		 * LINUX_CMSG_SPACE(dlen) (and LINUX_CMSG_LEN) below
    806 		 * without overflow.
    807 		 */
    808 		CTASSERT(LINUX_CMSG_SPACE(1) <= CMSG_SPACE(1));
    809 		CTASSERT(CMSG_SPACE(0) <=
    810 		    __type_max(__typeof(cmsg->cmsg_len)));
    811 		KASSERTMSG((dlen <= __type_max(__typeof(dlen)) -
    812 			CMSG_SPACE(0)),
    813 		    "dlen=%u", dlen);
    814 		CTASSERT(LINUX_CMSG_LEN(1) <= LINUX_CMSG_SPACE(1));
    815 
    816 		switch (linux_cmsg.cmsg_level) {
    817 		case SOL_SOCKET:
    818 			linux_cmsg.cmsg_level = LINUX_SOL_SOCKET;
    819 			switch (linux_cmsg.cmsg_type) {
    820 			case SCM_RIGHTS:
    821 				/* Linux SCM_RIGHTS is same as NetBSD */
    822 				break;
    823 
    824 			default:
    825 				/* other types not supported */
    826 				error = EINVAL;
    827 				goto done;
    828 			}
    829 			/* machine dependent ! */
    830 			break;
    831 		default:
    832 			/* pray and leave intact */
    833 			break;
    834 		}
    835 
    836 		/* There can be padding between the header and data... */
    837 		error = copyout(&linux_cmsg, q, sizeof linux_cmsg);
    838 		if (error != 0) {
    839 			break;
    840 		}
    841 		error = copyout(CCMSG_DATA(cmsg), q + sizeof linux_cmsg, dlen);
    842 		if (error != 0) {
    843 			break;
    844 		}
    845 		m = m->m_next;
    846 		if (m == NULL || LINUX_CMSG_SPACE(dlen) > q_end - q) {
    847 			q += LINUX_CMSG_LEN(dlen);
    848 			break;
    849 		}
    850 		q += LINUX_CMSG_SPACE(dlen);
    851 	}
    852 
    853   done:
    854 	if (error) {
    855 		/* We must free all the SCM_RIGHTS */
    856 		m = control;
    857 	}
    858 	free_control_mbuf(l, control, m);
    859 
    860 	mp->msg_controllen = q - (char *)mp->msg_control;
    861 	return error;
    862 }
    863 
    864 int
    865 linux_sys_recvmsg(struct lwp *l, const struct linux_sys_recvmsg_args *uap, register_t *retval)
    866 {
    867 	/* {
    868 		syscallarg(int) s;
    869 		syscallarg(struct linux_msghdr *) msg;
    870 		syscallarg(u_int) flags;
    871 	} */
    872 	struct msghdr	msg;
    873 	struct linux_msghdr lmsg;
    874 	int		error;
    875 	struct mbuf	*from, *control;
    876 
    877 	error = copyin(SCARG(uap, msg), &lmsg, sizeof(lmsg));
    878 	if (error)
    879 		return error;
    880 	error = linux_to_bsd_msghdr(&lmsg, &msg);
    881 	if (error)
    882 		return error;
    883 
    884 	msg.msg_flags = linux_to_bsd_msg_flags(SCARG(uap, flags));
    885 	if (msg.msg_flags < 0) {
    886 		/* Some unsupported flag */
    887 		return (EINVAL);
    888 	}
    889 	msg.msg_flags |= MSG_IOVUSRSPACE;
    890 
    891 	error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from,
    892 	    msg.msg_control != NULL ? &control : NULL, retval);
    893 	if (error != 0)
    894 		return error;
    895 
    896 	if (msg.msg_control != NULL)
    897 		error = linux_copyout_msg_control(l, &msg, control);
    898 
    899 	if (error == 0 && from != 0) {
    900 		mtod(from, struct osockaddr *)->sa_family =
    901 		    bsd_to_linux_domain(mtod(from, struct sockaddr *)->sa_family);
    902 		error = copyout_sockname(msg.msg_name, &msg.msg_namelen, 0,
    903 			from);
    904 	} else
    905 		msg.msg_namelen = 0;
    906 
    907 	if (from != NULL)
    908 		m_free(from);
    909 
    910 	if (error == 0) {
    911 		msg.msg_flags = bsd_to_linux_msg_flags(msg.msg_flags);
    912 		if (msg.msg_flags < 0)
    913 			/* Some flag unsupported by Linux */
    914 			error = EINVAL;
    915 		else {
    916 			ktrkuser("msghdr", &msg, sizeof(msg));
    917 			bsd_to_linux_msghdr(&msg, &lmsg);
    918 			error = copyout(&lmsg, SCARG(uap, msg), sizeof(lmsg));
    919 		}
    920 	}
    921 
    922 	return (error);
    923 }
    924 
    925 /*
    926  * Convert socket option level from Linux to NetBSD value. Only SOL_SOCKET
    927  * is different, the rest matches IPPROTO_* on both systems.
    928  */
    929 int
    930 linux_to_bsd_sopt_level(int llevel)
    931 {
    932 
    933 	switch (llevel) {
    934 	case LINUX_SOL_SOCKET:
    935 		return SOL_SOCKET;
    936 	case LINUX_SOL_IP:
    937 		return IPPROTO_IP;
    938 #ifdef INET6
    939 	case LINUX_SOL_IPV6:
    940 		return IPPROTO_IPV6;
    941 #endif
    942 	case LINUX_SOL_TCP:
    943 		return IPPROTO_TCP;
    944 	case LINUX_SOL_UDP:
    945 		return IPPROTO_UDP;
    946 	default:
    947 		return -1;
    948 	}
    949 }
    950 
    951 /*
    952  * Convert Linux socket level socket option numbers to NetBSD values.
    953  */
    954 int
    955 linux_to_bsd_so_sockopt(int lopt)
    956 {
    957 
    958 	switch (lopt) {
    959 	case LINUX_SO_DEBUG:
    960 		return SO_DEBUG;
    961 	case LINUX_SO_REUSEADDR:
    962 		/*
    963 		 * Linux does not implement SO_REUSEPORT, but allows reuse of
    964 		 * a host:port pair through SO_REUSEADDR even if the address
    965 		 * is not a multicast-address. Effectively, this means that we
    966 		 * should use SO_REUSEPORT to allow Linux applications to not
    967 		 * exit with EADDRINUSE
    968 		 */
    969 		return SO_REUSEPORT;
    970 	case LINUX_SO_TYPE:
    971 		return SO_TYPE;
    972 	case LINUX_SO_ERROR:
    973 		return SO_ERROR;
    974 	case LINUX_SO_DONTROUTE:
    975 		return SO_DONTROUTE;
    976 	case LINUX_SO_BROADCAST:
    977 		return SO_BROADCAST;
    978 	case LINUX_SO_SNDBUF:
    979 		return SO_SNDBUF;
    980 	case LINUX_SO_RCVBUF:
    981 		return SO_RCVBUF;
    982 	case LINUX_SO_KEEPALIVE:
    983 		return SO_KEEPALIVE;
    984 	case LINUX_SO_OOBINLINE:
    985 		return SO_OOBINLINE;
    986 	case LINUX_SO_NO_CHECK:
    987 	case LINUX_SO_PRIORITY:
    988 		return -1;
    989 	case LINUX_SO_LINGER:
    990 		return SO_LINGER;
    991 	case LINUX_SO_BSDCOMPAT:
    992 	case LINUX_SO_PASSCRED:
    993 	case LINUX_SO_PEERCRED:
    994 		return -1;
    995 	case LINUX_SO_RCVLOWAT:
    996 		return SO_RCVLOWAT;
    997 	case LINUX_SO_SNDLOWAT:
    998 		return SO_SNDLOWAT;
    999 	case LINUX_SO_RCVTIMEO:
   1000 		return SO_RCVTIMEO;
   1001 	case LINUX_SO_SNDTIMEO:
   1002 		return SO_SNDTIMEO;
   1003 	case LINUX_SO_SECURITY_AUTHENTICATION:
   1004 	case LINUX_SO_SECURITY_ENCRYPTION_TRANSPORT:
   1005 	case LINUX_SO_SECURITY_ENCRYPTION_NETWORK:
   1006 	case LINUX_SO_BINDTODEVICE:
   1007 	case LINUX_SO_ATTACH_FILTER:
   1008 	case LINUX_SO_DETACH_FILTER:
   1009 	case LINUX_SO_PEERNAME:
   1010 		return -1;
   1011 	case LINUX_SO_TIMESTAMP:
   1012 		return SO_TIMESTAMP;
   1013 	case LINUX_SO_ACCEPTCONN:
   1014 	case LINUX_SO_PEERSEC:
   1015 	case LINUX_SO_SNDBUFFORCE:
   1016 	case LINUX_SO_RCVBUFFORCE:
   1017 	case LINUX_SO_PASSSEC:
   1018 	case LINUX_SO_TIMESTAMPNS:
   1019 	case LINUX_SO_MARK:
   1020 	case LINUX_SO_TIMESTAMPING:
   1021 	case LINUX_SO_PROTOCOL:
   1022 	case LINUX_SO_DOMAIN:
   1023 	case LINUX_SO_RXQ_OVFL:
   1024 	case LINUX_SO_WIFI_STATUS:
   1025 	case LINUX_SO_PEEK_OFF:
   1026 	case LINUX_SO_NOFCS:
   1027 	default:
   1028 		return -1;
   1029 	}
   1030 }
   1031 
   1032 /*
   1033  * Convert Linux IP level socket option number to NetBSD values.
   1034  */
   1035 int
   1036 linux_to_bsd_ip_sockopt(int lopt)
   1037 {
   1038 
   1039 	switch (lopt) {
   1040 	case LINUX_IP_TOS:
   1041 		return IP_TOS;
   1042 	case LINUX_IP_TTL:
   1043 		return IP_TTL;
   1044 	case LINUX_IP_RETOPTS:
   1045 		return IP_RETOPTS;
   1046 	case LINUX_IP_PKTINFO:
   1047 		return IP_PKTINFO;
   1048 	case LINUX_IP_RECVOPTS:
   1049 		return IP_RECVOPTS;
   1050 	case LINUX_IP_HDRINCL:
   1051 		return IP_HDRINCL;
   1052 	case LINUX_IP_MULTICAST_TTL:
   1053 		return IP_MULTICAST_TTL;
   1054 	case LINUX_IP_MULTICAST_LOOP:
   1055 		return IP_MULTICAST_LOOP;
   1056 	case LINUX_IP_MULTICAST_IF:
   1057 		return IP_MULTICAST_IF;
   1058 	case LINUX_IP_ADD_MEMBERSHIP:
   1059 		return IP_ADD_MEMBERSHIP;
   1060 	case LINUX_IP_DROP_MEMBERSHIP:
   1061 		return IP_DROP_MEMBERSHIP;
   1062 	case LINUX_IP_RECVERR:
   1063 	case LINUX_IP_FREEBIND:
   1064 		return -2;	/* ignored */
   1065 	case LINUX_IP_MULTICAST_ALL:
   1066 		return -3;	/* noprotoopt */
   1067 	default:
   1068 		return -1;
   1069 	}
   1070 }
   1071 
   1072 /*
   1073  * Convert Linux IPV6 level socket option number to NetBSD values.
   1074  */
   1075 #ifdef INET6
   1076 int
   1077 linux_to_bsd_ipv6_sockopt(int lopt)
   1078 {
   1079 
   1080 	switch (lopt) {
   1081 	case LINUX_IPV6_V6ONLY:
   1082 		return IPV6_V6ONLY;
   1083 	case LINUX_IPV6_MULTICAST_HOPS:
   1084 		return IPV6_MULTICAST_HOPS;
   1085 	case LINUX_IPV6_MULTICAST_ALL:
   1086 		return -3;	/* noprotoopt */
   1087 	default:
   1088 		return -1;
   1089 	}
   1090 }
   1091 #endif
   1092 
   1093 /*
   1094  * Convert Linux TCP level socket option number to NetBSD values.
   1095  */
   1096 int
   1097 linux_to_bsd_tcp_sockopt(int lopt)
   1098 {
   1099 
   1100 	switch (lopt) {
   1101 	case LINUX_TCP_NODELAY:
   1102 		return TCP_NODELAY;
   1103 	case LINUX_TCP_MAXSEG:
   1104 		return TCP_MAXSEG;
   1105 	default:
   1106 		return -1;
   1107 	}
   1108 }
   1109 
   1110 /*
   1111  * Convert Linux UDP level socket option number to NetBSD values.
   1112  */
   1113 int
   1114 linux_to_bsd_udp_sockopt(int lopt)
   1115 {
   1116 
   1117 	switch (lopt) {
   1118 	default:
   1119 		return -1;
   1120 	}
   1121 }
   1122 
   1123 /*
   1124  * Another reasonably straightforward function: setsockopt(2).
   1125  * The level and option numbers are converted; the values passed
   1126  * are not (yet) converted, the ones currently implemented don't
   1127  * need conversion, as they are the same on both systems.
   1128  */
   1129 int
   1130 linux_sys_setsockopt(struct lwp *l, const struct linux_sys_setsockopt_args *uap, register_t *retval)
   1131 {
   1132 	/* {
   1133 		syscallarg(int) s;
   1134 		syscallarg(int) level;
   1135 		syscallarg(int) optname;
   1136 		syscallarg(void *) optval;
   1137 		syscallarg(int) optlen;
   1138 	} */
   1139 	struct sys_setsockopt_args bsa;
   1140 	int name;
   1141 
   1142 	memset(&bsa, 0, sizeof(bsa));
   1143 	SCARG(&bsa, s) = SCARG(uap, s);
   1144 	SCARG(&bsa, level) = linux_to_bsd_sopt_level(SCARG(uap, level));
   1145 	SCARG(&bsa, val) = SCARG(uap, optval);
   1146 	SCARG(&bsa, valsize) = SCARG(uap, optlen);
   1147 
   1148 	/*
   1149 	 * Linux supports only SOL_SOCKET for AF_LOCAL domain sockets
   1150 	 * and returns EOPNOTSUPP for other levels
   1151 	 */
   1152 	if (SCARG(&bsa, level) != SOL_SOCKET) {
   1153 		struct socket *so;
   1154 		int error, family;
   1155 
   1156 		/* fd_getsock() will use the descriptor for us */
   1157 	    	if ((error = fd_getsock(SCARG(&bsa, s), &so)) != 0)
   1158 		    	return error;
   1159 		family = so->so_proto->pr_domain->dom_family;
   1160 		fd_putfile(SCARG(&bsa, s));
   1161 
   1162 		if (family == AF_LOCAL)
   1163 			return EOPNOTSUPP;
   1164 	}
   1165 
   1166 	switch (SCARG(&bsa, level)) {
   1167 	case SOL_SOCKET:
   1168 		name = linux_to_bsd_so_sockopt(SCARG(uap, optname));
   1169 		break;
   1170 	case IPPROTO_IP:
   1171 		name = linux_to_bsd_ip_sockopt(SCARG(uap, optname));
   1172 		break;
   1173 #ifdef INET6
   1174 	case IPPROTO_IPV6:
   1175 		name = linux_to_bsd_ipv6_sockopt(SCARG(uap, optname));
   1176 		break;
   1177 #endif
   1178 	case IPPROTO_TCP:
   1179 		name = linux_to_bsd_tcp_sockopt(SCARG(uap, optname));
   1180 		break;
   1181 	case IPPROTO_UDP:
   1182 		name = linux_to_bsd_udp_sockopt(SCARG(uap, optname));
   1183 		break;
   1184 	default:
   1185 		return EINVAL;
   1186 	}
   1187 
   1188 	switch (name) {
   1189 	case -1:
   1190 		return EINVAL;
   1191 	case -2:
   1192 		return 0;
   1193 	case -3:
   1194 		return ENOPROTOOPT;
   1195 	}
   1196 	SCARG(&bsa, name) = name;
   1197 
   1198 	return sys_setsockopt(l, &bsa, retval);
   1199 }
   1200 
   1201 /*
   1202  * getsockopt(2) is very much the same as setsockopt(2) (see above)
   1203  */
   1204 int
   1205 linux_sys_getsockopt(struct lwp *l, const struct linux_sys_getsockopt_args *uap, register_t *retval)
   1206 {
   1207 	/* {
   1208 		syscallarg(int) s;
   1209 		syscallarg(int) level;
   1210 		syscallarg(int) optname;
   1211 		syscallarg(void *) optval;
   1212 		syscallarg(int *) optlen;
   1213 	} */
   1214 	struct sys_getsockopt_args bga;
   1215 	int name;
   1216 
   1217 	memset(&bga, 0, sizeof(bga));
   1218 	SCARG(&bga, s) = SCARG(uap, s);
   1219 	SCARG(&bga, level) = linux_to_bsd_sopt_level(SCARG(uap, level));
   1220 	SCARG(&bga, val) = SCARG(uap, optval);
   1221 	SCARG(&bga, avalsize) = (socklen_t *)SCARG(uap, optlen);
   1222 
   1223 	switch (SCARG(&bga, level)) {
   1224 	case SOL_SOCKET:
   1225 		name = linux_to_bsd_so_sockopt(SCARG(uap, optname));
   1226 		break;
   1227 	case IPPROTO_IP:
   1228 		name = linux_to_bsd_ip_sockopt(SCARG(uap, optname));
   1229 		break;
   1230 #ifdef INET6
   1231 	case IPPROTO_IPV6:
   1232 		name = linux_to_bsd_ipv6_sockopt(SCARG(uap, optname));
   1233 		break;
   1234 #endif
   1235 	case IPPROTO_TCP:
   1236 		name = linux_to_bsd_tcp_sockopt(SCARG(uap, optname));
   1237 		break;
   1238 	case IPPROTO_UDP:
   1239 		name = linux_to_bsd_udp_sockopt(SCARG(uap, optname));
   1240 		break;
   1241 	default:
   1242 		return EINVAL;
   1243 	}
   1244 
   1245 	switch (name) {
   1246 	case -1:
   1247 	case -2: /* we can't ignore, since we don't know what to return */
   1248 		return EINVAL;
   1249 	case -3:
   1250 		return ENOPROTOOPT;
   1251 	}
   1252 	SCARG(&bga, name) = name;
   1253 
   1254 	return sys_getsockopt(l, &bga, retval);
   1255 }
   1256 
   1257 int
   1258 linux_getifname(struct lwp *l, register_t *retval, void *data)
   1259 {
   1260 	struct ifnet *ifp;
   1261 	struct linux_ifreq ifr;
   1262 	int error;
   1263 	int s;
   1264 
   1265 	error = copyin(data, &ifr, sizeof(ifr));
   1266 	if (error)
   1267 		return error;
   1268 
   1269 	s = pserialize_read_enter();
   1270 	ifp = if_byindex(ifr.ifr_ifru.ifru_ifindex);
   1271 	if (ifp == NULL) {
   1272 		pserialize_read_exit(s);
   1273 		return ENODEV;
   1274 	}
   1275 
   1276 	strncpy(ifr.ifr_name, ifp->if_xname, sizeof(ifr.ifr_name));
   1277 	pserialize_read_exit(s);
   1278 
   1279 	return copyout(&ifr, data, sizeof(ifr));
   1280 }
   1281 
   1282 int
   1283 linux_getifconf(struct lwp *l, register_t *retval, void *data)
   1284 {
   1285 	struct linux_ifreq ifr, *ifrp = NULL;
   1286 	struct linux_ifconf ifc;
   1287 	struct ifnet *ifp;
   1288 	struct sockaddr *sa;
   1289 	struct osockaddr *osa;
   1290 	int space = 0, error;
   1291 	const int sz = (int)sizeof(ifr);
   1292 	bool docopy;
   1293 	int s;
   1294 	int bound;
   1295 	struct psref psref;
   1296 
   1297 	error = copyin(data, &ifc, sizeof(ifc));
   1298 	if (error)
   1299 		return error;
   1300 
   1301 	docopy = ifc.ifc_req != NULL;
   1302 	if (docopy) {
   1303 		if (ifc.ifc_len < 0)
   1304 			return EINVAL;
   1305 
   1306 		space = ifc.ifc_len;
   1307 		ifrp = ifc.ifc_req;
   1308 	}
   1309 	memset(&ifr, 0, sizeof(ifr));
   1310 
   1311 	bound = curlwp_bind();
   1312 	s = pserialize_read_enter();
   1313 	IFNET_READER_FOREACH(ifp) {
   1314 		struct ifaddr *ifa;
   1315 		if_acquire(ifp, &psref);
   1316 		pserialize_read_exit(s);
   1317 
   1318 		(void)strncpy(ifr.ifr_name, ifp->if_xname,
   1319 		    sizeof(ifr.ifr_name));
   1320 		if (ifr.ifr_name[sizeof(ifr.ifr_name) - 1] != '\0') {
   1321 			error = ENAMETOOLONG;
   1322 			goto release_exit;
   1323 		}
   1324 
   1325 		s = pserialize_read_enter();
   1326 		IFADDR_READER_FOREACH(ifa, ifp) {
   1327 			struct psref psref_ifa;
   1328 			ifa_acquire(ifa, &psref_ifa);
   1329 			pserialize_read_exit(s);
   1330 
   1331 			sa = ifa->ifa_addr;
   1332 			if (sa->sa_family != AF_INET ||
   1333 			    sa->sa_len > sizeof(*osa))
   1334 				goto next;
   1335 			memcpy(&ifr.ifr_addr, sa, sa->sa_len);
   1336 			osa = (struct osockaddr *)&ifr.ifr_addr;
   1337 			osa->sa_family = sa->sa_family;
   1338 			if (space >= sz) {
   1339 				error = copyout(&ifr, ifrp, sz);
   1340 				if (error != 0) {
   1341 					ifa_release(ifa, &psref_ifa);
   1342 					goto release_exit;
   1343 				}
   1344 				ifrp++;
   1345 			}
   1346 			space -= sz;
   1347 		next:
   1348 			s = pserialize_read_enter();
   1349 			ifa_release(ifa, &psref_ifa);
   1350 		}
   1351 
   1352 		KASSERT(pserialize_in_read_section());
   1353 		if_release(ifp, &psref);
   1354 	}
   1355 	pserialize_read_exit(s);
   1356 	curlwp_bindx(bound);
   1357 
   1358 	if (docopy)
   1359 		ifc.ifc_len -= space;
   1360 	else
   1361 		ifc.ifc_len = -space;
   1362 
   1363 	return copyout(&ifc, data, sizeof(ifc));
   1364 
   1365 release_exit:
   1366 	if_release(ifp, &psref);
   1367 	curlwp_bindx(bound);
   1368 	return error;
   1369 }
   1370 
   1371 int
   1372 linux_getifhwaddr(struct lwp *l, register_t *retval, u_int fd,
   1373     void *data)
   1374 {
   1375 	/* Not the full structure, just enough to map what we do here */
   1376 	struct linux_ifreq lreq;
   1377 	file_t *fp;
   1378 	struct ifaddr *ifa;
   1379 	struct ifnet *ifp;
   1380 	struct sockaddr_dl *sadl;
   1381 	int error, found;
   1382 	int index, ifnum;
   1383 	int s;
   1384 
   1385 	/*
   1386 	 * We can't emulate this ioctl by calling sys_ioctl() to run
   1387 	 * SIOCGIFCONF, because the user buffer is not of the right
   1388 	 * type to take those results.  We can't use kernel buffers to
   1389 	 * receive the results, as the implementation of sys_ioctl()
   1390 	 * and ifconf() [which implements SIOCGIFCONF] use
   1391 	 * copyin()/copyout() which will fail on kernel addresses.
   1392 	 *
   1393 	 * So, we must duplicate code from sys_ioctl() and ifconf().  Ugh.
   1394 	 */
   1395 
   1396 	if ((fp = fd_getfile(fd)) == NULL)
   1397 		return (EBADF);
   1398 
   1399 	KERNEL_LOCK(1, NULL);
   1400 
   1401 	if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
   1402 		error = EBADF;
   1403 		goto out;
   1404 	}
   1405 
   1406 	error = copyin(data, &lreq, sizeof(lreq));
   1407 	if (error)
   1408 		goto out;
   1409 	lreq.ifr_name[LINUX_IFNAMSIZ-1] = '\0';		/* just in case */
   1410 
   1411 	/*
   1412 	 * Try real interface name first, then fake "ethX"
   1413 	 */
   1414 	found = 0;
   1415 	s = pserialize_read_enter();
   1416 	IFNET_READER_FOREACH(ifp) {
   1417 		if (found)
   1418 			break;
   1419 		if (strcmp(lreq.ifr_name, ifp->if_xname))
   1420 			/* not this interface */
   1421 			continue;
   1422 
   1423 		found=1;
   1424 		if (IFADDR_READER_EMPTY(ifp)) {
   1425 			pserialize_read_exit(s);
   1426 			error = ENODEV;
   1427 			goto out;
   1428 		}
   1429 		IFADDR_READER_FOREACH(ifa, ifp) {
   1430 			sadl = satosdl(ifa->ifa_addr);
   1431 			/* only return ethernet addresses */
   1432 			/* XXX what about FDDI, etc. ? */
   1433 			if (sadl->sdl_family != AF_LINK ||
   1434 			    sadl->sdl_type != IFT_ETHER)
   1435 				continue;
   1436 			memcpy(&lreq.ifr_hwaddr.sa_data, CLLADDR(sadl),
   1437 			       MIN(sadl->sdl_alen,
   1438 				   sizeof(lreq.ifr_hwaddr.sa_data)));
   1439 			lreq.ifr_hwaddr.sa_family =
   1440 				sadl->sdl_family;
   1441 			pserialize_read_exit(s);
   1442 
   1443 			error = copyout(&lreq, data, sizeof(lreq));
   1444 			goto out;
   1445 		}
   1446 	}
   1447 	pserialize_read_exit(s);
   1448 
   1449 	if (strncmp(lreq.ifr_name, "eth", 3) != 0) {
   1450 		/* unknown interface, not even an "eth*" name */
   1451 		error = ENODEV;
   1452 		goto out;
   1453 	}
   1454 
   1455 	for (ifnum = 0, index = 3;
   1456 	     index < LINUX_IFNAMSIZ && lreq.ifr_name[index] != '\0';
   1457 	     index++) {
   1458 		ifnum *= 10;
   1459 		ifnum += lreq.ifr_name[index] - '0';
   1460 	}
   1461 
   1462 	error = EINVAL;			/* in case we don't find one */
   1463 	s = pserialize_read_enter();
   1464 	IFNET_READER_FOREACH(ifp) {
   1465 		memcpy(lreq.ifr_name, ifp->if_xname,
   1466 		       MIN(LINUX_IFNAMSIZ, IFNAMSIZ));
   1467 		IFADDR_READER_FOREACH(ifa, ifp) {
   1468 			sadl = satosdl(ifa->ifa_addr);
   1469 			/* only return ethernet addresses */
   1470 			/* XXX what about FDDI, etc. ? */
   1471 			if (sadl->sdl_family != AF_LINK ||
   1472 			    sadl->sdl_type != IFT_ETHER)
   1473 				continue;
   1474 			if (ifnum--)
   1475 				/* not the requested iface */
   1476 				continue;
   1477 			memcpy(&lreq.ifr_hwaddr.sa_data,
   1478 			       CLLADDR(sadl),
   1479 			       MIN(sadl->sdl_alen,
   1480 				   sizeof(lreq.ifr_hwaddr.sa_data)));
   1481 			lreq.ifr_hwaddr.sa_family =
   1482 				sadl->sdl_family;
   1483 			pserialize_read_exit(s);
   1484 
   1485 			error = copyout(&lreq, data, sizeof(lreq));
   1486 			goto out;
   1487 		}
   1488 	}
   1489 	pserialize_read_exit(s);
   1490 
   1491 out:
   1492 	KERNEL_UNLOCK_ONE(NULL);
   1493 	fd_putfile(fd);
   1494 	return error;
   1495 }
   1496 
   1497 int
   1498 linux_ioctl_socket(struct lwp *l, const struct linux_sys_ioctl_args *uap, register_t *retval)
   1499 {
   1500 	/* {
   1501 		syscallarg(int) fd;
   1502 		syscallarg(u_long) com;
   1503 		syscallarg(void *) data;
   1504 	} */
   1505 	u_long com;
   1506 	int error = 0, isdev = 0, dosys = 1;
   1507 	struct sys_ioctl_args ia;
   1508 	file_t *fp;
   1509 	struct vnode *vp;
   1510 	int (*ioctlf)(file_t *, u_long, void *);
   1511 	struct ioctl_pt pt;
   1512 
   1513 	if ((fp = fd_getfile(SCARG(uap, fd))) == NULL)
   1514 		return (EBADF);
   1515 
   1516 	if (fp->f_type == DTYPE_VNODE) {
   1517 		vp = (struct vnode *)fp->f_data;
   1518 		isdev = vp->v_type == VCHR;
   1519 	}
   1520 
   1521 	/*
   1522 	 * Don't try to interpret socket ioctl calls that are done
   1523 	 * on a device filedescriptor, just pass them through, to
   1524 	 * emulate Linux behaviour. Use PTIOCLINUX so that the
   1525 	 * device will only handle these if it's prepared to do
   1526 	 * so, to avoid unexpected things from happening.
   1527 	 */
   1528 	if (isdev) {
   1529 		dosys = 0;
   1530 		ioctlf = fp->f_ops->fo_ioctl;
   1531 		pt.com = SCARG(uap, com);
   1532 		pt.data = SCARG(uap, data);
   1533 		error = ioctlf(fp, PTIOCLINUX, &pt);
   1534 		/*
   1535 		 * XXX hack: if the function returns EJUSTRETURN,
   1536 		 * it has stuffed a sysctl return value in pt.data.
   1537 		 */
   1538 		if (error == EJUSTRETURN) {
   1539 			retval[0] = (register_t)pt.data;
   1540 			error = 0;
   1541 		}
   1542 		goto out;
   1543 	}
   1544 
   1545 	com = SCARG(uap, com);
   1546 	retval[0] = 0;
   1547 
   1548 	memset(&ia, 0, sizeof(ia));
   1549 
   1550 	switch (com) {
   1551 	case LINUX_SIOCGIFNAME:
   1552 		error = linux_getifname(l, retval, SCARG(uap, data));
   1553 		dosys = 0;
   1554 		break;
   1555 	case LINUX_SIOCGIFCONF:
   1556 		error = linux_getifconf(l, retval, SCARG(uap, data));
   1557 		dosys = 0;
   1558 		break;
   1559 	case LINUX_SIOCGIFFLAGS:
   1560 		SCARG(&ia, com) = OSIOCGIFFLAGS;
   1561 		break;
   1562 	case LINUX_SIOCSIFFLAGS:
   1563 		SCARG(&ia, com) = OSIOCSIFFLAGS;
   1564 		break;
   1565 	case LINUX_SIOCGIFADDR:
   1566 		SCARG(&ia, com) = OOSIOCGIFADDR;
   1567 		break;
   1568 	case LINUX_SIOCGIFDSTADDR:
   1569 		SCARG(&ia, com) = OOSIOCGIFDSTADDR;
   1570 		break;
   1571 	case LINUX_SIOCGIFBRDADDR:
   1572 		SCARG(&ia, com) = OOSIOCGIFBRDADDR;
   1573 		break;
   1574 	case LINUX_SIOCGIFNETMASK:
   1575 		SCARG(&ia, com) = OOSIOCGIFNETMASK;
   1576 		break;
   1577 	case LINUX_SIOCGIFMTU:
   1578 		SCARG(&ia, com) = OSIOCGIFMTU;
   1579 		break;
   1580 	case LINUX_SIOCADDMULTI:
   1581 		SCARG(&ia, com) = OSIOCADDMULTI;
   1582 		break;
   1583 	case LINUX_SIOCDELMULTI:
   1584 		SCARG(&ia, com) = OSIOCDELMULTI;
   1585 		break;
   1586 	case LINUX_SIOCGIFHWADDR:
   1587 		error = linux_getifhwaddr(l, retval, SCARG(uap, fd),
   1588 		    SCARG(uap, data));
   1589 		dosys = 0;
   1590 		break;
   1591 	default:
   1592 		error = EINVAL;
   1593 	}
   1594 
   1595  out:
   1596  	fd_putfile(SCARG(uap, fd));
   1597 
   1598 	if (error ==0 && dosys) {
   1599 		SCARG(&ia, fd) = SCARG(uap, fd);
   1600 		SCARG(&ia, data) = SCARG(uap, data);
   1601 		error = sys_ioctl(curlwp, &ia, retval);
   1602 	}
   1603 
   1604 	return error;
   1605 }
   1606 
   1607 int
   1608 linux_sys_connect(struct lwp *l, const struct linux_sys_connect_args *uap, register_t *retval)
   1609 {
   1610 	/* {
   1611 		syscallarg(int) s;
   1612 		syscallarg(const struct sockaddr *) name;
   1613 		syscallarg(int) namelen;
   1614 	} */
   1615 	int		error;
   1616 	struct sockaddr_big sb;
   1617 
   1618 	error = linux_get_sa(l, SCARG(uap, s), &sb, SCARG(uap, name),
   1619 	    SCARG(uap, namelen));
   1620 	if (error)
   1621 		return (error);
   1622 
   1623 	error = do_sys_connect(l, SCARG(uap, s), (struct sockaddr *)&sb);
   1624 
   1625 	if (error == EISCONN) {
   1626 		struct socket *so;
   1627 		int state, prflags;
   1628 
   1629 		/* fd_getsock() will use the descriptor for us */
   1630 	    	if (fd_getsock(SCARG(uap, s), &so) != 0)
   1631 		    	return EISCONN;
   1632 
   1633 		solock(so);
   1634 		state = so->so_state;
   1635 		prflags = so->so_proto->pr_flags;
   1636 		sounlock(so);
   1637 		fd_putfile(SCARG(uap, s));
   1638 		/*
   1639 		 * We should only let this call succeed once per
   1640 		 * non-blocking connect; however we don't have
   1641 		 * a convenient place to keep that state..
   1642 		 */
   1643 		if ((state & (SS_ISCONNECTED|SS_NBIO)) ==
   1644 		    (SS_ISCONNECTED|SS_NBIO) &&
   1645 		    (prflags & PR_CONNREQUIRED))
   1646 			return 0;
   1647 	}
   1648 
   1649 	return (error);
   1650 }
   1651 
   1652 int
   1653 linux_sys_bind(struct lwp *l, const struct linux_sys_bind_args *uap, register_t *retval)
   1654 {
   1655 	/* {
   1656 		syscallarg(int) s;
   1657 		syscallarg(const struct osockaddr *) name;
   1658 		syscallarg(int) namelen;
   1659 	} */
   1660 	int		error;
   1661 	struct sockaddr_big sb;
   1662 
   1663 	error = linux_get_sa(l, SCARG(uap, s), &sb, SCARG(uap, name),
   1664 	    SCARG(uap, namelen));
   1665 	if (error)
   1666 		return (error);
   1667 
   1668 	return do_sys_bind(l, SCARG(uap, s), (struct sockaddr *)&sb);
   1669 }
   1670 
   1671 int
   1672 linux_sys_getsockname(struct lwp *l, const struct linux_sys_getsockname_args *uap, register_t *retval)
   1673 {
   1674 	/* {
   1675 		syscallarg(int) fdes;
   1676 		syscallarg(void *) asa;
   1677 		syscallarg(int *) alen;
   1678 	} */
   1679 	int error;
   1680 
   1681 	if ((error = sys_getsockname(l, (const void *)uap, retval)) != 0)
   1682 		return (error);
   1683 
   1684 	if ((error = linux_sa_put((struct osockaddr *)SCARG(uap, asa))))
   1685 		return (error);
   1686 
   1687 	return (0);
   1688 }
   1689 
   1690 int
   1691 linux_sys_getpeername(struct lwp *l, const struct linux_sys_getpeername_args *uap, register_t *retval)
   1692 {
   1693 	/* {
   1694 		syscallarg(int) fdes;
   1695 		syscallarg(void *) asa;
   1696 		syscallarg(int *) alen;
   1697 	} */
   1698 	int error;
   1699 
   1700 	if ((error = sys_getpeername(l, (const void *)uap, retval)) != 0)
   1701 		return (error);
   1702 
   1703 	if ((error = linux_sa_put((struct osockaddr *)SCARG(uap, asa))))
   1704 		return (error);
   1705 
   1706 	return (0);
   1707 }
   1708 
   1709 /*
   1710  * Copy the osockaddr structure pointed to by name to sb, adjust
   1711  * family and convert to sockaddr.
   1712  */
   1713 static int
   1714 linux_get_sa(struct lwp *l, int s, struct sockaddr_big *sb,
   1715     const struct osockaddr *name, socklen_t namelen)
   1716 {
   1717 	int error, bdom;
   1718 
   1719 	if (namelen > UCHAR_MAX ||
   1720 	    namelen <= offsetof(struct sockaddr_big, sb_data))
   1721 		return EINVAL;
   1722 
   1723 	error = copyin(name, sb, namelen);
   1724 	if (error)
   1725 		return error;
   1726 
   1727 	bdom = linux_to_bsd_domain(sb->sb_family);
   1728 	if (bdom == -1)
   1729 		return EINVAL;
   1730 
   1731 	/*
   1732 	 * If the family is unspecified, use address family of the socket.
   1733 	 * This avoid triggering strict family checks in netinet/in_pcb.c et.al.
   1734 	 */
   1735 	if (bdom == AF_UNSPEC) {
   1736 		struct socket *so;
   1737 
   1738 		/* fd_getsock() will use the descriptor for us */
   1739 		if ((error = fd_getsock(s, &so)) != 0)
   1740 			return error;
   1741 
   1742 		bdom = so->so_proto->pr_domain->dom_family;
   1743 		fd_putfile(s);
   1744 	}
   1745 
   1746 	/*
   1747 	 * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6,
   1748 	 * which lacks the scope id compared with RFC2553 one. If we detect
   1749 	 * the situation, reject the address and write a message to system log.
   1750 	 *
   1751 	 * Still accept addresses for which the scope id is not used.
   1752 	 */
   1753 	if (bdom == AF_INET6 &&
   1754 	    namelen == sizeof(struct sockaddr_in6) - sizeof(uint32_t)) {
   1755 		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sb;
   1756 		if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) &&
   1757 		    (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||
   1758 		     IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) ||
   1759 		     IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) ||
   1760 		     IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
   1761 		     IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) {
   1762 			struct proc *p = l->l_proc;
   1763 			int uid = l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1;
   1764 
   1765 			log(LOG_DEBUG,
   1766 			    "pid %d (%s), uid %d: obsolete pre-RFC2553 "
   1767 			    "sockaddr_in6 rejected",
   1768 			    p->p_pid, p->p_comm, uid);
   1769 			return EINVAL;
   1770 		}
   1771 		namelen = sizeof(struct sockaddr_in6);
   1772 		sin6->sin6_scope_id = 0;
   1773 	}
   1774 
   1775 	/*
   1776 	 * Linux is less strict than NetBSD and permits namelen to be larger
   1777 	 * than valid struct sockaddr_in*.  If this is the case, truncate
   1778 	 * the value to the correct size, so that NetBSD networking does not
   1779 	 * return an error.
   1780 	 */
   1781 	switch (bdom) {
   1782 	case AF_INET:
   1783 		namelen = MIN(namelen, sizeof(struct sockaddr_in));
   1784 		break;
   1785 	case AF_INET6:
   1786 		namelen = MIN(namelen, sizeof(struct sockaddr_in6));
   1787 		break;
   1788 	}
   1789 
   1790 	sb->sb_family = bdom;
   1791 	sb->sb_len = namelen;
   1792 	ktrkuser("mbsoname", sb, namelen);
   1793 	return 0;
   1794 }
   1795 
   1796 static int
   1797 linux_sa_put(struct osockaddr *osa)
   1798 {
   1799 	struct sockaddr sa;
   1800 	struct osockaddr *kosa;
   1801 	int error, bdom, len;
   1802 
   1803 	/*
   1804 	 * Only read/write the sockaddr family and length part, the rest is
   1805 	 * not changed.
   1806 	 */
   1807 	len = sizeof(sa.sa_len) + sizeof(sa.sa_family);
   1808 
   1809 	error = copyin(osa, &sa, len);
   1810 	if (error)
   1811 		return (error);
   1812 
   1813 	bdom = bsd_to_linux_domain(sa.sa_family);
   1814 	if (bdom == -1)
   1815 		return (EINVAL);
   1816 
   1817 	/* Note: we convert from sockaddr to osockaddr here, too */
   1818 	kosa = (struct osockaddr *) &sa;
   1819 	kosa->sa_family = bdom;
   1820 	error = copyout(kosa, osa, len);
   1821 	if (error)
   1822 		return (error);
   1823 
   1824 	return (0);
   1825 }
   1826 
   1827 #if !defined(__aarch64__) && !defined(__amd64__)
   1828 int
   1829 linux_sys_recv(struct lwp *l, const struct linux_sys_recv_args *uap, register_t *retval)
   1830 {
   1831 	/* {
   1832 		syscallarg(int) s;
   1833 		syscallarg(void *) buf;
   1834 		syscallarg(int) len;
   1835 		syscallarg(int) flags;
   1836 	} */
   1837 	struct sys_recvfrom_args bra;
   1838 
   1839 	memset(&bra, 0, sizeof(bra));
   1840 	SCARG(&bra, s) = SCARG(uap, s);
   1841 	SCARG(&bra, buf) = SCARG(uap, buf);
   1842 	SCARG(&bra, len) = (size_t) SCARG(uap, len);
   1843 	SCARG(&bra, flags) = SCARG(uap, flags);
   1844 	SCARG(&bra, from) = NULL;
   1845 	SCARG(&bra, fromlenaddr) = NULL;
   1846 
   1847 	return (sys_recvfrom(l, &bra, retval));
   1848 }
   1849 
   1850 int
   1851 linux_sys_send(struct lwp *l, const struct linux_sys_send_args *uap, register_t *retval)
   1852 {
   1853 	/* {
   1854 		syscallarg(int) s;
   1855 		syscallarg(void *) buf;
   1856 		syscallarg(int) len;
   1857 		syscallarg(int) flags;
   1858 	} */
   1859 	struct sys_sendto_args bsa;
   1860 
   1861 	memset(&bsa, 0, sizeof(bsa));
   1862 	SCARG(&bsa, s)		= SCARG(uap, s);
   1863 	SCARG(&bsa, buf)	= SCARG(uap, buf);
   1864 	SCARG(&bsa, len)	= SCARG(uap, len);
   1865 	SCARG(&bsa, flags)	= SCARG(uap, flags);
   1866 	SCARG(&bsa, to)		= NULL;
   1867 	SCARG(&bsa, tolen)	= 0;
   1868 
   1869 	return (sys_sendto(l, &bsa, retval));
   1870 }
   1871 #endif
   1872 
   1873 int
   1874 linux_sys_accept(struct lwp *l, const struct linux_sys_accept_args *uap, register_t *retval)
   1875 {
   1876 	/* {
   1877 		syscallarg(int) s;
   1878 		syscallarg(struct osockaddr *) name;
   1879 		syscallarg(int *) anamelen;
   1880 	} */
   1881 	int error;
   1882 	struct sys_accept_args baa;
   1883 
   1884 	memset(&baa, 0, sizeof(baa));
   1885 	SCARG(&baa, s)		= SCARG(uap, s);
   1886 	SCARG(&baa, name)	= (struct sockaddr *) SCARG(uap, name);
   1887 	SCARG(&baa, anamelen)	= (unsigned int *) SCARG(uap, anamelen);
   1888 
   1889 	if ((error = sys_accept(l, &baa, retval)))
   1890 		return (error);
   1891 
   1892 	if (SCARG(uap, name) && (error = linux_sa_put(SCARG(uap, name))))
   1893 		return (error);
   1894 
   1895 	return (0);
   1896 }
   1897 
   1898 int
   1899 linux_sys_accept4(struct lwp *l, const struct linux_sys_accept4_args *uap, register_t *retval)
   1900 {
   1901 	/* {
   1902 		syscallarg(int) s;
   1903 		syscallarg(struct osockaddr *) name;
   1904 		syscallarg(int *) anamelen;
   1905 		syscallarg(int) flags;
   1906 	} */
   1907 	int error, flags;
   1908 	struct sockaddr_big name;
   1909 
   1910 	if ((flags = linux_to_bsd_type(SCARG(uap, flags))) == -1)
   1911 		return EINVAL;
   1912 
   1913 	name.sb_len = UCHAR_MAX;
   1914 	error = do_sys_accept(l, SCARG(uap, s), (struct sockaddr *)&name,
   1915 	    retval, NULL, flags, 0);
   1916 	if (error != 0)
   1917 		return error;
   1918 
   1919 	error = copyout_sockname_sb((struct sockaddr *)SCARG(uap, name),
   1920 	    SCARG(uap, anamelen), MSG_LENUSRSPACE, &name);
   1921 	if (error != 0) {
   1922 		int fd = (int)*retval;
   1923 		if (fd_getfile(fd) != NULL)
   1924 			(void)fd_close(fd);
   1925 		return error;
   1926 	}
   1927 	if (SCARG(uap, name) && (error = linux_sa_put(SCARG(uap, name))))
   1928 		return error;
   1929 
   1930 	return 0;
   1931 }
   1932 
   1933 int
   1934 linux_sys_sendmmsg(struct lwp *l, const struct linux_sys_sendmmsg_args *uap,
   1935     register_t *retval)
   1936 {
   1937 	/* {
   1938 		syscallarg(int) s;
   1939 		syscallarg(struct linux_mmsghdr *) msgvec;
   1940 		syscallarg(unsigned int) vlen;
   1941 		syscallarg(unsigned int) flags;
   1942 	} */
   1943 	struct linux_mmsghdr lmsg;
   1944 	struct mmsghdr bmsg;
   1945 	struct socket *so;
   1946 	file_t *fp;
   1947 	struct msghdr *msg = &bmsg.msg_hdr;
   1948 	int error, s;
   1949 	unsigned int vlen, flags, dg;
   1950 
   1951 	if ((flags = linux_to_bsd_msg_flags(SCARG(uap, flags))) == -1)
   1952 		return EINVAL;
   1953 
   1954 	flags = (flags & MSG_USERFLAGS) | MSG_IOVUSRSPACE;
   1955 
   1956 	s = SCARG(uap, s);
   1957 	if ((error = fd_getsock1(s, &so, &fp)) != 0)
   1958 		return error;
   1959 
   1960 	vlen = SCARG(uap, vlen);
   1961 	if (vlen > 1024)
   1962 		vlen = 1024;
   1963 
   1964 	for (dg = 0; dg < vlen;) {
   1965 		error = copyin(SCARG(uap, msgvec) + dg, &lmsg, sizeof(lmsg));
   1966 		if (error)
   1967 			break;
   1968 		error = linux_to_bsd_msghdr(&lmsg.msg_hdr, &bmsg.msg_hdr);
   1969 		if (error)
   1970 			break;
   1971 
   1972 		msg->msg_flags = flags;
   1973 
   1974 		error = do_sys_sendmsg_so(l, s, so, fp, msg, flags, retval);
   1975 		if (error)
   1976 			break;
   1977 
   1978 		ktrkuser("msghdr", msg, sizeof *msg);
   1979 		lmsg.msg_len = *retval;
   1980 		error = copyout(&lmsg, SCARG(uap, msgvec) + dg, sizeof(lmsg));
   1981 		if (error)
   1982 			break;
   1983 		dg++;
   1984 
   1985 	}
   1986 
   1987 	*retval = dg;
   1988 
   1989 	fd_putfile(s);
   1990 
   1991 	/*
   1992 	 * If we succeeded at least once, return 0.
   1993 	 */
   1994 	if (dg)
   1995 		return 0;
   1996 	return error;
   1997 }
   1998 
   1999 int
   2000 linux_sys_recvmmsg(struct lwp *l, const struct linux_sys_recvmmsg_args *uap,
   2001     register_t *retval)
   2002 {
   2003 	/* {
   2004 		syscallarg(int) s;
   2005 		syscallarg(struct linux_mmsghdr *) msgvec;
   2006 		syscallarg(unsigned int) vlen;
   2007 		syscallarg(unsigned int) flags;
   2008 		syscallarg(struct linux_timespec *) timeout;
   2009 	} */
   2010 	struct linux_mmsghdr lmsg;
   2011 	struct mmsghdr bmsg;
   2012 	struct socket *so;
   2013 	struct msghdr *msg = &bmsg.msg_hdr;
   2014 	int error, s;
   2015 	struct mbuf *from, *control;
   2016 	struct timespec ts = {0}, now;
   2017 	struct linux_timespec lts;
   2018 	unsigned int vlen, flags, dg;
   2019 
   2020 	if (SCARG(uap, timeout)) {
   2021 		error = copyin(SCARG(uap, timeout), &lts, sizeof(lts));
   2022 		if (error)
   2023 			return error;
   2024 		ts.tv_sec = lts.tv_sec;
   2025 		ts.tv_nsec = lts.tv_nsec;
   2026 		getnanotime(&now);
   2027 		timespecadd(&now, &ts, &ts);
   2028 	}
   2029 
   2030 	s = SCARG(uap, s);
   2031 	if ((error = fd_getsock(s, &so)) != 0)
   2032 		return error;
   2033 
   2034 	/*
   2035 	 * If so->so_rerror holds a deferred error return it now.
   2036 	 */
   2037 	if (so->so_rerror) {
   2038 		error = so->so_rerror;
   2039 		so->so_rerror = 0;
   2040 		fd_putfile(s);
   2041 		return error;
   2042 	}
   2043 
   2044 	vlen = SCARG(uap, vlen);
   2045 	if (vlen > 1024)
   2046 		vlen = 1024;
   2047 
   2048 	from = NULL;
   2049 	flags = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE;
   2050 
   2051 	for (dg = 0; dg < vlen;) {
   2052 		error = copyin(SCARG(uap, msgvec) + dg, &lmsg, sizeof(lmsg));
   2053 		if (error)
   2054 			break;
   2055 		error = linux_to_bsd_msghdr(&lmsg.msg_hdr, &bmsg.msg_hdr);
   2056 		if (error)
   2057 			break;
   2058 		msg->msg_flags = flags & ~MSG_WAITFORONE;
   2059 
   2060 		if (from != NULL) {
   2061 			m_free(from);
   2062 			from = NULL;
   2063 		}
   2064 
   2065 		error = do_sys_recvmsg_so(l, s, so, msg, &from,
   2066 		    msg->msg_control != NULL ? &control : NULL, retval);
   2067 		if (error) {
   2068 			if (error == EAGAIN && dg > 0)
   2069 				error = 0;
   2070 			break;
   2071 		}
   2072 
   2073 		if (msg->msg_control != NULL)
   2074 			error = linux_copyout_msg_control(l, msg, control);
   2075 		if (error)
   2076 			break;
   2077 
   2078 		if (from != NULL) {
   2079 			mtod(from, struct osockaddr *)->sa_family =
   2080 			    bsd_to_linux_domain(mtod(from,
   2081 			    struct sockaddr *)->sa_family);
   2082 			error = copyout_sockname(msg->msg_name,
   2083 			    &msg->msg_namelen, 0, from);
   2084 			if (error)
   2085 				break;
   2086 		}
   2087 
   2088 
   2089 		lmsg.msg_len = *retval;
   2090 		ktrkuser("msghdr", msg, sizeof(*msg));
   2091 		bsd_to_linux_msghdr(msg, &lmsg.msg_hdr);
   2092 		error = copyout(&lmsg, SCARG(uap, msgvec) + dg, sizeof(lmsg));
   2093 		if (error)
   2094 			break;
   2095 
   2096 		dg++;
   2097 		if (msg->msg_flags & MSG_OOB)
   2098 			break;
   2099 
   2100 		if (SCARG(uap, timeout)) {
   2101 			getnanotime(&now);
   2102 			timespecsub(&now, &ts, &now);
   2103 			if (now.tv_sec > 0)
   2104 				break;
   2105 		}
   2106 
   2107 		if (flags & MSG_WAITFORONE)
   2108 			flags |= MSG_DONTWAIT;
   2109 
   2110 	}
   2111 
   2112 	if (from != NULL)
   2113 		m_free(from);
   2114 
   2115 	*retval = dg;
   2116 
   2117 	/*
   2118 	 * If we succeeded at least once, return 0, hopefully so->so_rerror
   2119 	 * will catch it next time.
   2120 	 */
   2121 	if (error && dg > 0) {
   2122 		so->so_rerror = error;
   2123 		error = 0;
   2124 	}
   2125 
   2126 	fd_putfile(s);
   2127 
   2128 	return error;
   2129 }
   2130