xref: /netbsd-src/sys/compat/linux/common/linux_socket.c (revision aaf4ece63a859a04e37cf3a7229b5fab0157cc06)
1 /*	$NetBSD: linux_socket.c,v 1.58 2005/12/11 12:20:19 christos Exp $	*/
2 
3 /*-
4  * Copyright (c) 1995, 1998 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  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the NetBSD
21  *	Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 /*
40  * Functions in multiarch:
41  *	linux_sys_socketcall		: linux_socketcall.c
42  */
43 
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.58 2005/12/11 12:20:19 christos Exp $");
46 
47 #if defined(_KERNEL_OPT)
48 #include "opt_inet.h"
49 #endif
50 
51 #include <sys/param.h>
52 #include <sys/kernel.h>
53 #include <sys/systm.h>
54 #include <sys/buf.h>
55 #include <sys/malloc.h>
56 #include <sys/ioctl.h>
57 #include <sys/tty.h>
58 #include <sys/file.h>
59 #include <sys/filedesc.h>
60 #include <sys/select.h>
61 #include <sys/socket.h>
62 #include <sys/socketvar.h>
63 #include <sys/domain.h>
64 #include <net/if.h>
65 #include <net/if_dl.h>
66 #include <net/if_types.h>
67 #include <netinet/in.h>
68 #include <netinet/tcp.h>
69 #include <sys/mount.h>
70 #include <sys/proc.h>
71 #include <sys/vnode.h>
72 #include <sys/device.h>
73 #include <sys/protosw.h>
74 #include <sys/mbuf.h>
75 #include <sys/syslog.h>
76 #include <sys/exec.h>
77 
78 #include <sys/sa.h>
79 #include <sys/syscallargs.h>
80 
81 #ifdef INET6
82 #include <netinet/ip6.h>
83 #include <netinet6/ip6_var.h>
84 #endif
85 
86 #include <compat/sys/socket.h>
87 
88 #include <compat/linux/common/linux_types.h>
89 #include <compat/linux/common/linux_util.h>
90 #include <compat/linux/common/linux_signal.h>
91 #include <compat/linux/common/linux_ioctl.h>
92 #include <compat/linux/common/linux_socket.h>
93 #include <compat/linux/common/linux_socketcall.h>
94 #include <compat/linux/common/linux_sockio.h>
95 
96 #include <compat/linux/linux_syscallargs.h>
97 
98 #ifdef DEBUG_LINUX
99 #define DPRINTF(a) uprintf a
100 #else
101 #define DPRINTF(a)
102 #endif
103 
104 /*
105  * The calls in this file are entered either via the linux_socketcall()
106  * interface or, on the Alpha, as individual syscalls.  The
107  * linux_socketcall function does any massaging of arguments so that all
108  * the calls in here need not think that they are anything other
109  * than a normal syscall.
110  */
111 
112 static int linux_to_bsd_domain __P((int));
113 static int bsd_to_linux_domain __P((int));
114 int linux_to_bsd_sopt_level __P((int));
115 int linux_to_bsd_so_sockopt __P((int));
116 int linux_to_bsd_ip_sockopt __P((int));
117 int linux_to_bsd_tcp_sockopt __P((int));
118 int linux_to_bsd_udp_sockopt __P((int));
119 int linux_getifhwaddr __P((struct lwp *, register_t *, u_int, void *));
120 static int linux_sa_get __P((struct lwp *, int, caddr_t *, struct sockaddr **,
121 		const struct osockaddr *, int *));
122 static int linux_sa_put __P((struct osockaddr *osa));
123 static int linux_to_bsd_msg_flags __P((int));
124 static int bsd_to_linux_msg_flags __P((int));
125 
126 static const int linux_to_bsd_domain_[LINUX_AF_MAX] = {
127 	AF_UNSPEC,
128 	AF_UNIX,
129 	AF_INET,
130 	AF_CCITT,	/* LINUX_AF_AX25 */
131 	AF_IPX,
132 	AF_APPLETALK,
133 	-1,		/* LINUX_AF_NETROM */
134 	-1,		/* LINUX_AF_BRIDGE */
135 	-1,		/* LINUX_AF_ATMPVC */
136 	AF_CCITT,	/* LINUX_AF_X25 */
137 	AF_INET6,
138 	-1,		/* LINUX_AF_ROSE */
139 	AF_DECnet,
140 	-1,		/* LINUX_AF_NETBEUI */
141 	-1,		/* LINUX_AF_SECURITY */
142 	pseudo_AF_KEY,
143 	AF_ROUTE,	/* LINUX_AF_NETLINK */
144 	-1,		/* LINUX_AF_PACKET */
145 	-1,		/* LINUX_AF_ASH */
146 	-1,		/* LINUX_AF_ECONET */
147 	-1,		/* LINUX_AF_ATMSVC */
148 	AF_SNA,
149 	/* rest up to LINUX_AF_MAX-1 is not allocated */
150 	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
151 };
152 
153 static const int bsd_to_linux_domain_[AF_MAX] = {
154 	LINUX_AF_UNSPEC,
155 	LINUX_AF_UNIX,
156 	LINUX_AF_INET,
157 	-1,		/* AF_IMPLINK */
158 	-1,		/* AF_PUP */
159 	-1,		/* AF_CHAOS */
160 	-1,		/* AF_NS */
161 	-1,		/* AF_ISO */
162 	-1,		/* AF_ECMA */
163 	-1,		/* AF_DATAKIT */
164 	LINUX_AF_AX25,	/* AF_CCITT */
165 	LINUX_AF_SNA,
166 	LINUX_AF_DECnet,
167 	-1,		/* AF_DLI */
168 	-1,		/* AF_LAT */
169 	-1,		/* AF_HYLINK */
170 	LINUX_AF_APPLETALK,
171 	LINUX_AF_NETLINK,
172 	-1,		/* AF_LINK */
173 	-1,		/* AF_XTP */
174 	-1,		/* AF_COIP */
175 	-1,		/* AF_CNT */
176 	-1,		/* pseudo_AF_RTIP */
177 	LINUX_AF_IPX,
178 	LINUX_AF_INET6,
179 	-1,		/* pseudo_AF_PIP */
180 	-1,		/* AF_ISDN */
181 	-1,		/* AF_NATM */
182 	-1,		/* AF_ARP */
183 	LINUX_pseudo_AF_KEY,
184 	-1,		/* pseudo_AF_HDRCMPLT */
185 };
186 
187 static const int bsd_to_linux_msg_flags_[] = {
188 	MSG_OOB,		LINUX_MSG_OOB,
189 	MSG_PEEK,		LINUX_MSG_PEEK,
190 	MSG_DONTROUTE,		LINUX_MSG_DONTROUTE,
191 	MSG_EOR,		LINUX_MSG_EOR,
192 	MSG_TRUNC,		LINUX_MSG_TRUNC,
193 	MSG_CTRUNC,		LINUX_MSG_CTRUNC,
194 	MSG_WAITALL,		LINUX_MSG_WAITALL,
195 	MSG_DONTWAIT,		LINUX_MSG_DONTWAIT,
196 	MSG_BCAST,		0,		/* not supported, clear */
197 	MSG_MCAST,		0,		/* not supported, clear */
198 	-1, /* not supp */	LINUX_MSG_PROBE,
199 	-1, /* not supp */	LINUX_MSG_FIN,
200 	-1, /* not supp */	LINUX_MSG_SYN,
201 	-1, /* not supp */	LINUX_MSG_CONFIRM,
202 	-1, /* not supp */	LINUX_MSG_RST,
203 	-1, /* not supp */	LINUX_MSG_ERRQUEUE,
204 	-1, /* not supp */	LINUX_MSG_NOSIGNAL,
205 	-1, /* not supp */	LINUX_MSG_MORE,
206 };
207 
208 /*
209  * Convert between Linux and BSD socket domain values
210  */
211 static int
212 linux_to_bsd_domain(ldom)
213 	int ldom;
214 {
215 	if (ldom < 0 || ldom >= LINUX_AF_MAX)
216 		return (-1);
217 
218 	return linux_to_bsd_domain_[ldom];
219 }
220 
221 /*
222  * Convert between BSD and Linux socket domain values
223  */
224 static int
225 bsd_to_linux_domain(bdom)
226 	int bdom;
227 {
228 	if (bdom < 0 || bdom >= AF_MAX)
229 		return (-1);
230 
231 	return bsd_to_linux_domain_[bdom];
232 }
233 
234 static int
235 linux_to_bsd_msg_flags(lflag)
236 	int lflag;
237 {
238 	int i, lfl, bfl;
239 	int bflag = 0;
240 
241 	if (lflag == 0)
242 		return (0);
243 
244 	for(i=0; i < sizeof(bsd_to_linux_msg_flags_)/
245 	    sizeof(bsd_to_linux_msg_flags_[0])/2; i += 2) {
246 		bfl = bsd_to_linux_msg_flags_[i];
247 		lfl = bsd_to_linux_msg_flags_[i+1];
248 
249 		if (lfl == 0)
250 			continue;
251 
252 		if (lflag & lfl) {
253 			if (bfl < 0)
254 				return (-1);
255 
256 			bflag |= bfl;
257 		}
258 	}
259 
260 	return (bflag);
261 }
262 
263 static int
264 bsd_to_linux_msg_flags(bflag)
265 	int bflag;
266 {
267 	int i, lfl, bfl;
268 	int lflag = 0;
269 
270 	if (bflag == 0)
271 		return (0);
272 
273 	for(i=0; i < sizeof(bsd_to_linux_msg_flags_)/
274 	    sizeof(bsd_to_linux_msg_flags_[0])/2; i += 2) {
275 		bfl = bsd_to_linux_msg_flags_[i];
276 		lfl = bsd_to_linux_msg_flags_[i+1];
277 
278 		if (bfl <= 0)
279 			continue;
280 
281 		if (bflag & bfl) {
282 			if (lfl < 0)
283 				return (-1);
284 
285 			lflag |= lfl;
286 		}
287 	}
288 
289 	return (lflag);
290 }
291 
292 int
293 linux_sys_socket(l, v, retval)
294 	struct lwp *l;
295 	void *v;
296 	register_t *retval;
297 {
298 	struct linux_sys_socket_args /* {
299 		syscallarg(int)	domain;
300 		syscallarg(int)	type;
301 		syscallarg(int) protocol;
302 	} */ *uap = v;
303 	struct sys_socket_args bsa;
304 	int error;
305 
306 	SCARG(&bsa, protocol) = SCARG(uap, protocol);
307 	SCARG(&bsa, type) = SCARG(uap, type);
308 	SCARG(&bsa, domain) = linux_to_bsd_domain(SCARG(uap, domain));
309 	if (SCARG(&bsa, domain) == -1)
310 		return EINVAL;
311 	error = sys_socket(l, &bsa, retval);
312 
313 #ifdef INET6
314 	/*
315 	 * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by
316 	 * default and some apps depend on this. So, set V6ONLY to 0
317 	 * for Linux apps if the sysctl value is set to 1.
318 	 */
319 	if (!error && ip6_v6only && SCARG(&bsa, domain) == PF_INET6) {
320 		struct proc *p = l->l_proc;
321 		struct file *fp;
322 
323 		if (getsock(p->p_fd, *retval, &fp) == 0) {
324 			struct mbuf *m;
325 
326 			m = m_get(M_WAIT, MT_SOOPTS);
327 			m->m_len = sizeof(int);
328 			*mtod(m, int *) = 0;
329 
330 			/* ignore error */
331 			(void) sosetopt((struct socket *)fp->f_data,
332 				IPPROTO_IPV6, IPV6_V6ONLY, m);
333 
334 			FILE_UNUSE(fp, l);
335 		}
336 	}
337 #endif
338 
339 	return (error);
340 }
341 
342 int
343 linux_sys_socketpair(l, v, retval)
344 	struct lwp *l;
345 	void *v;
346 	register_t *retval;
347 {
348 	struct linux_sys_socketpair_args /* {
349 		syscallarg(int) domain;
350 		syscallarg(int) type;
351 		syscallarg(int) protocol;
352 		syscallarg(int *) rsv;
353 	} */ *uap = v;
354 	struct sys_socketpair_args bsa;
355 
356 	SCARG(&bsa, domain) = linux_to_bsd_domain(SCARG(uap, domain));
357 	if (SCARG(&bsa, domain) == -1)
358 		return EINVAL;
359 	SCARG(&bsa, type) = SCARG(uap, type);
360 	SCARG(&bsa, protocol) = SCARG(uap, protocol);
361 	SCARG(&bsa, rsv) = SCARG(uap, rsv);
362 
363 	return sys_socketpair(l, &bsa, retval);
364 }
365 
366 int
367 linux_sys_sendto(l, v, retval)
368 	struct lwp *l;
369 	void *v;
370 	register_t *retval;
371 {
372 	struct linux_sys_sendto_args /* {
373 		syscallarg(int)				s;
374 		syscallarg(void *)			msg;
375 		syscallarg(int)				len;
376 		syscallarg(int)				flags;
377 		syscallarg(struct osockaddr *)		to;
378 		syscallarg(int)				tolen;
379 	} */ *uap = v;
380 	struct proc *p = l->l_proc;
381 	struct sys_sendto_args bsa;
382 	int tolen;
383 
384 	SCARG(&bsa, s) = SCARG(uap, s);
385 	SCARG(&bsa, buf) = SCARG(uap, msg);
386 	SCARG(&bsa, len) = (size_t) SCARG(uap, len);
387 	SCARG(&bsa, flags) = SCARG(uap, flags);
388 	tolen = SCARG(uap, tolen);
389 	if (SCARG(uap, to)) {
390 		struct sockaddr *sa;
391 		int error;
392 		caddr_t sg = stackgap_init(p, 0);
393 
394 		error = linux_sa_get(l, SCARG(uap, s), &sg, &sa,
395 		    SCARG(uap, to), &tolen);
396 		if (error)
397 			return (error);
398 
399 		SCARG(&bsa, to) = sa;
400 	} else
401 		SCARG(&bsa, to) = NULL;
402 	SCARG(&bsa, tolen) = tolen;
403 
404 	return (sys_sendto(l, &bsa, retval));
405 }
406 
407 int
408 linux_sys_sendmsg(l, v, retval)
409 	struct lwp *l;
410 	void *v;
411 	register_t *retval;
412 {
413 	struct linux_sys_sendmsg_args /* {
414 		syscallarg(int) s;
415 		syscallarg(struct msghdr *) msg;
416 		syscallarg(u_int) flags;
417 	} */ *uap = v;
418 	struct proc *p = l->l_proc;
419 	struct msghdr	msg;
420 	int		error;
421 	struct iovec	aiov[UIO_SMALLIOV], *iov;
422 	caddr_t sg = 0;
423 	int		bflags;
424 	u_int8_t	*control=NULL;
425 
426 	error = copyin(SCARG(uap, msg), (caddr_t)&msg, sizeof(msg));
427 	if (error)
428 		return (error);
429 	if ((unsigned int)msg.msg_iovlen > UIO_SMALLIOV) {
430 		if ((unsigned int)msg.msg_iovlen > IOV_MAX)
431 			return (EMSGSIZE);
432 		iov = malloc(sizeof(struct iovec) * msg.msg_iovlen,
433 		    M_IOV, M_WAITOK);
434 	} else
435 		iov = aiov;
436 	if ((unsigned int)msg.msg_iovlen > 0) {
437 		error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
438 		    (size_t)(msg.msg_iovlen * sizeof(struct iovec)));
439 		if (error)
440 			goto done;
441 	}
442 	msg.msg_iov = iov;
443 	msg.msg_flags = 0;
444 
445 	/* Convert the sockaddr if necessary */
446 	if (msg.msg_name) {
447 		struct sockaddr *sa;
448 		sg = stackgap_init(p, 0);
449 
450 		error = linux_sa_get(l, SCARG(uap, s), &sg, &sa,
451 		    (struct osockaddr *) msg.msg_name, &msg.msg_namelen);
452 		if (error)
453 			goto done;
454 		msg.msg_name = sa;
455 	}
456 
457 	/*
458 	 * Translate message flags.
459 	 */
460 	bflags = linux_to_bsd_msg_flags(SCARG(uap, flags));
461 	if (bflags < 0) {
462 		/* Some supported flag */
463 		error = EINVAL;
464 		goto done;
465 	}
466 
467 	/*
468 	 * Handle cmsg if there is any.
469 	 */
470 	if (CMSG_FIRSTHDR(&msg)) {
471 		struct cmsghdr cmsg, *cc;
472 		int changed = 0;
473 		ssize_t resid = msg.msg_controllen;
474 		size_t clen, cidx = 0, cspace;
475 
476 		/*
477 		 * Limit the size even more than what sockargs() would do,
478 		 * We need to fit into stackgap space.
479 		 */
480 		if (msg.msg_controllen > (STACKGAPLEN / 2)) {
481 			/* Sorry guys! */
482 			error = EMSGSIZE;
483 			goto done;
484 		}
485 
486 		control = malloc((clen = msg.msg_controllen), M_TEMP, M_WAITOK);
487 		if (!control) {
488 			error = ENOMEM;
489 			goto done;
490 		}
491 
492 		cc = CMSG_FIRSTHDR(&msg);
493 		do {
494 			error = copyin(cc, &cmsg, sizeof(cmsg));
495 			if (error)
496 				goto done;
497 
498 			/*
499 			 * Sanity check the control message length.
500 			 */
501 			if (cmsg.cmsg_len > resid
502 			    || cmsg.cmsg_len < sizeof(struct cmsghdr)) {
503 				error = EINVAL;
504 				goto done;
505 			}
506 
507 			/*
508 			 * Refuse unsupported control messages, and
509 			 * translate fields as appropriate.
510 			 */
511 			switch (cmsg.cmsg_level) {
512 			case LINUX_SOL_SOCKET:
513 				/* It only differs on some archs */
514 				if (LINUX_SOL_SOCKET != SOL_SOCKET) {
515 					cmsg.cmsg_level = SOL_SOCKET;
516 					changed = 1;
517 				}
518 
519 				switch(cmsg.cmsg_type) {
520 				case LINUX_SCM_RIGHTS:
521 					/* Linux SCM_RIGHTS is same as NetBSD */
522 					break;
523 
524 				default:
525 					/* other types not supported */
526 					error = EINVAL;
527 					goto done;
528 				}
529 				break;
530 			default:
531 				/* pray and leave intact */
532 				break;
533 			}
534 
535 			cspace = CMSG_SPACE(cmsg.cmsg_len - sizeof(cmsg));
536 
537 			/* Check the buffer is big enough */
538 			if (__predict_false(cidx + cspace > clen)) {
539 				u_int8_t *nc;
540 
541 				clen = cidx + cspace;
542 				nc = realloc(control, clen, M_TEMP, M_WAITOK);
543 				if (!nc) {
544 					error = ENOMEM;
545 					goto done;
546 				}
547 				control = nc;
548 			}
549 
550 			/* Copy header */
551 			memcpy(&control[cidx], &cmsg, sizeof(cmsg));
552 
553 			/* Zero are between header and data */
554 			memset(&control[cidx+sizeof(cmsg)], 0,
555 				CMSG_ALIGN(sizeof(cmsg)) - sizeof(cmsg));
556 
557 			/* Copyin the data */
558 			error = copyin(LINUX_CMSG_DATA(cc),
559 				CMSG_DATA(control),
560 				cmsg.cmsg_len - sizeof(cmsg));
561 			if (error)
562 				goto done;
563 
564 			/*
565 			 * If there is alignment difference, we changed
566 			 * layout of cmsg.
567 			 */
568 			if (LINUX_CMSG_ALIGNDIFF)
569 				changed = 1;
570 
571 			resid -= cspace;
572 			cidx += cspace;
573 		} while ((cc = LINUX_CMSG_NXTHDR(&msg, cc)) && resid > 0);
574 
575 		/*
576 		 * If any of the passed control message needed
577 		 * a change, put the changed data into stackgap
578 		 * and adjust msg appropriately.
579 		 */
580 		if (changed) {
581 			char *newc;
582 
583 			/*
584 			 * Check again the total len is maximum half of
585 			 * stackgap. The length might change if the
586 			 * alignment is different.
587 			 */
588 			if (clen > STACKGAPLEN/2) {
589 				error = EMSGSIZE;
590 				goto done;
591 			}
592 
593 			/*
594 			 * Allocate space on stack within stackgap, and
595 			 * copy changed data there.
596 			 */
597 			if (!sg)
598 				sg = stackgap_init(p, STACKGAPLEN/3);
599 			newc = stackgap_alloc(p, &sg, clen);
600 			if (!newc) {
601 				error = ENOMEM;
602 				goto done;
603 			}
604 
605 			error = copyout(control, newc, clen);
606 			if (error)
607 				goto done;
608 
609 			msg.msg_control = newc;
610 			msg.msg_controllen = clen;
611 		}
612 
613 		free(control, M_TEMP);
614 		control = NULL;
615 	}
616 
617 	error = sendit(l, SCARG(uap, s), &msg, bflags, retval);
618 
619 done:
620 	if (control)
621 		free(control, M_TEMP);
622 	if (iov != aiov)
623 		free(iov, M_IOV);
624 	return (error);
625 }
626 
627 int
628 linux_sys_recvfrom(l, v, retval)
629 	struct lwp *l;
630 	void *v;
631 	register_t *retval;
632 {
633 	struct linux_sys_recvfrom_args /* {
634 		syscallarg(int) s;
635 		syscallarg(void *) buf;
636 		syscallarg(int) len;
637 		syscallarg(int) flags;
638 		syscallarg(struct osockaddr *) from;
639 		syscallarg(int *) fromlenaddr;
640 	} */ *uap = v;
641 	int		error;
642 	struct sys_recvfrom_args bra;
643 
644 	SCARG(&bra, s) = SCARG(uap, s);
645 	SCARG(&bra, buf) = SCARG(uap, buf);
646 	SCARG(&bra, len) = SCARG(uap, len);
647 	SCARG(&bra, flags) = SCARG(uap, flags);
648 	SCARG(&bra, from) = (struct sockaddr *) SCARG(uap, from);
649 	SCARG(&bra, fromlenaddr) = SCARG(uap, fromlenaddr);
650 
651 	if ((error = sys_recvfrom(l, &bra, retval)))
652 		return (error);
653 
654 	if (SCARG(uap, from) && (error = linux_sa_put(SCARG(uap, from))))
655 		return (error);
656 
657 	return (0);
658 }
659 
660 int
661 linux_sys_recvmsg(l, v, retval)
662 	struct lwp *l;
663 	void *v;
664 	register_t *retval;
665 {
666 	struct linux_sys_recvmsg_args /* {
667 		syscallarg(int) s;
668 		syscallarg(struct msghdr *) msg;
669 		syscallarg(u_int) flags;
670 	} */ *uap = v;
671 	struct msghdr	msg;
672 	int		error;
673 	struct sys_recvmsg_args bsa;
674 	int lflags;
675 	u_int8_t *ocontrol = NULL; /* XXX: gcc */
676 	socklen_t ocontrollen = 0;
677 
678 	/*
679 	 * Data alignment is different on some architectures. If control
680 	 * message is expected, we must arrange for the control message
681 	 * to be initially put elsewhere, and copy to target place
682 	 * with Linux alignment.
683 	 */
684 	if (LINUX_CMSG_ALIGNDIFF) {
685 		error = copyin(SCARG(uap, msg), &msg, sizeof(msg));
686 		if (error)
687 			return (error);
688 
689 		if (CMSG_FIRSTHDR(&msg)) {
690 			caddr_t sg;
691 
692 			/* Need to fit within stackgap */
693 			if (msg.msg_controllen > STACKGAPLEN/2) {
694 				/* Sorry guys! */
695 				return (EINVAL);
696 			}
697 
698 			sg = stackgap_init(l->l_proc, STACKGAPLEN/3);
699 
700 			ocontrol = msg.msg_control;
701 			ocontrollen = msg.msg_controllen;
702 
703 			/* space for at least one message's worth align */
704 			msg.msg_controllen += CMSG_ALIGN(1);
705 
706 			msg.msg_control = stackgap_alloc(l->l_proc, &sg,
707 				msg.msg_controllen);
708 			if (!msg.msg_control)
709 				return (ENOMEM);
710 
711 			/*
712 			 * Okay to overwrite the original structure, it's
713 			 * supposed to be writable.
714 			 */
715 			error = copyout(&msg, SCARG(uap, msg), sizeof(msg));
716 			if (error)
717 				return (error);
718 		}
719 	}
720 
721 	SCARG(&bsa, s) = SCARG(uap, s);
722 	SCARG(&bsa, msg) = SCARG(uap, msg);
723 	SCARG(&bsa, flags) = linux_to_bsd_msg_flags(SCARG(uap, flags));
724 
725 	if (SCARG(&bsa, flags) < 0) {
726 		/* Some unsupported flag */
727 		return (EINVAL);
728 	}
729 
730 	if ((error = sys_recvmsg(l, &bsa, retval)))
731 		goto done;
732 
733 	/* Fixup sockaddr */
734 	error = copyin((caddr_t)SCARG(uap, msg), (caddr_t)&msg,
735 		       sizeof(msg));
736 	if (error)
737 		goto done;
738 
739 	if (msg.msg_name && msg.msg_namelen > 2) {
740 		if ((error = linux_sa_put(msg.msg_name)))
741 			goto done;
742 	}
743 
744 	/* Fixup msg flags */
745 	lflags = bsd_to_linux_msg_flags(msg.msg_flags);
746 	if (lflags < 0) {
747 		/* Some flag unsupported by Linux */
748 		error = EINVAL;
749 		goto done;
750 	}
751 	error = copyout(&lflags, (u_int8_t *) SCARG(uap, msg) +
752 			offsetof(struct msghdr, msg_flags), sizeof(lflags));
753 	if (error)
754 		goto done;
755 
756 	/*
757 	 * Fixup cmsg. We handle two things:
758 	 * 1. different values for level/type on some archs
759 	 * 2. different alignment of CMSG_DATA on some archs
760 	 */
761 	if (CMSG_FIRSTHDR(&msg)) {
762 		struct cmsghdr cmsg, *cc;
763 		int changed = 0;
764 		size_t resid = ocontrollen;
765 
766 		cc = CMSG_FIRSTHDR(&msg);
767 		do {
768 			error = copyin(cc, &cmsg, sizeof(cmsg));
769 			if (error)
770 				goto done;
771 
772 			switch (cmsg.cmsg_level) {
773 			case SOL_SOCKET:
774 				if (SOL_SOCKET != LINUX_SOL_SOCKET) {
775 					cmsg.cmsg_level = LINUX_SOL_SOCKET;
776 					changed = 1;
777 				}
778 
779 				switch (cmsg.cmsg_type) {
780 				case SCM_RIGHTS:
781 					/* Linux SCM_RIGHTS is same as NetBSD */
782 					break;
783 
784 				default:
785 					/* other types not supported */
786 					error = EINVAL;
787 					goto done;
788 				}
789 			default:
790 				/* pray and leave intact */
791 				break;
792 			}
793 
794 			if (LINUX_CMSG_ALIGNDIFF) {
795 				int i;
796 				u_int8_t d, *sd, *td;
797 
798 				/*
799 				 * Sanity check.
800 				 */
801 				if (cmsg.cmsg_len > resid
802 				    || cmsg.cmsg_len < sizeof(cmsg)) {
803 					error = EINVAL;
804 					goto done;
805 				}
806 
807 				/*
808 				 * Need to copy the cmsg from scratch area
809 				 * to the original place, converting data
810 				 * alignment from NetBSD to Linux one.
811 				 */
812 				error = copyout(&cmsg, ocontrol, sizeof(cmsg));
813 				if (error)
814 					goto done;
815 				/* zero pad */
816 				for(i=0; i < LINUX_CMSG_ALIGN(sizeof(cmsg)) - sizeof(cmsg); i++) {
817 					copyout("",&ocontrol[sizeof(cmsg)+i],1);
818 				}
819 
820 				sd = CMSG_DATA(cc);
821 				td = LINUX_CMSG_DATA(ocontrol);
822 
823 				/* This is not particularily effective, but ..*/
824 				d = '\0';
825 				for(i=0; i < cmsg.cmsg_len - sizeof(cmsg); i++){
826 					copyin(sd++, &d, 1);
827 					copyout(&d, td++, 1);
828 				}
829 
830 				resid -= (td - ocontrol);
831 				ocontrol = td;
832 			} else if (changed) {
833 				/* Update cmsghdr in-place */
834 				error = copyout(&cmsg, cc, sizeof(cmsg));
835 				if (error)
836 					goto done;
837 				changed = 0;
838 			}
839 		} while((cc = CMSG_NXTHDR(&msg, cc)));
840 	}
841 
842 done:
843 	return (error);
844 }
845 
846 /*
847  * Convert socket option level from Linux to NetBSD value. Only SOL_SOCKET
848  * is different, the rest matches IPPROTO_* on both systems.
849  */
850 int
851 linux_to_bsd_sopt_level(llevel)
852 	int llevel;
853 {
854 
855 	switch (llevel) {
856 	case LINUX_SOL_SOCKET:
857 		return SOL_SOCKET;
858 	case LINUX_SOL_IP:
859 		return IPPROTO_IP;
860 	case LINUX_SOL_TCP:
861 		return IPPROTO_TCP;
862 	case LINUX_SOL_UDP:
863 		return IPPROTO_UDP;
864 	default:
865 		return -1;
866 	}
867 }
868 
869 /*
870  * Convert Linux socket level socket option numbers to NetBSD values.
871  */
872 int
873 linux_to_bsd_so_sockopt(lopt)
874 	int lopt;
875 {
876 
877 	switch (lopt) {
878 	case LINUX_SO_DEBUG:
879 		return SO_DEBUG;
880 	case LINUX_SO_REUSEADDR:
881 		/*
882 		 * Linux does not implement SO_REUSEPORT, but allows reuse of a
883 		 * host:port pair through SO_REUSEADDR even if the address is not a
884 		 * multicast-address.  Effectively, this means that we should use
885 		 * SO_REUSEPORT to allow Linux applications to not exit with
886 		 * EADDRINUSE
887 		 */
888 		return SO_REUSEPORT;
889 	case LINUX_SO_TYPE:
890 		return SO_TYPE;
891 	case LINUX_SO_ERROR:
892 		return SO_ERROR;
893 	case LINUX_SO_DONTROUTE:
894 		return SO_DONTROUTE;
895 	case LINUX_SO_BROADCAST:
896 		return SO_BROADCAST;
897 	case LINUX_SO_SNDBUF:
898 		return SO_SNDBUF;
899 	case LINUX_SO_RCVBUF:
900 		return SO_RCVBUF;
901 	case LINUX_SO_KEEPALIVE:
902 		return SO_KEEPALIVE;
903 	case LINUX_SO_OOBINLINE:
904 		return SO_OOBINLINE;
905 	case LINUX_SO_LINGER:
906 		return SO_LINGER;
907 	case LINUX_SO_PRIORITY:
908 	case LINUX_SO_NO_CHECK:
909 	default:
910 		return -1;
911 	}
912 }
913 
914 /*
915  * Convert Linux IP level socket option number to NetBSD values.
916  */
917 int
918 linux_to_bsd_ip_sockopt(lopt)
919 	int lopt;
920 {
921 
922 	switch (lopt) {
923 	case LINUX_IP_TOS:
924 		return IP_TOS;
925 	case LINUX_IP_TTL:
926 		return IP_TTL;
927 	case LINUX_IP_MULTICAST_TTL:
928 		return IP_MULTICAST_TTL;
929 	case LINUX_IP_MULTICAST_LOOP:
930 		return IP_MULTICAST_LOOP;
931 	case LINUX_IP_MULTICAST_IF:
932 		return IP_MULTICAST_IF;
933 	case LINUX_IP_ADD_MEMBERSHIP:
934 		return IP_ADD_MEMBERSHIP;
935 	case LINUX_IP_DROP_MEMBERSHIP:
936 		return IP_DROP_MEMBERSHIP;
937 	default:
938 		return -1;
939 	}
940 }
941 
942 /*
943  * Convert Linux TCP level socket option number to NetBSD values.
944  */
945 int
946 linux_to_bsd_tcp_sockopt(lopt)
947 	int lopt;
948 {
949 
950 	switch (lopt) {
951 	case LINUX_TCP_NODELAY:
952 		return TCP_NODELAY;
953 	case LINUX_TCP_MAXSEG:
954 		return TCP_MAXSEG;
955 	default:
956 		return -1;
957 	}
958 }
959 
960 /*
961  * Convert Linux UDP level socket option number to NetBSD values.
962  */
963 int
964 linux_to_bsd_udp_sockopt(lopt)
965 	int lopt;
966 {
967 
968 	switch (lopt) {
969 	default:
970 		return -1;
971 	}
972 }
973 
974 /*
975  * Another reasonably straightforward function: setsockopt(2).
976  * The level and option numbers are converted; the values passed
977  * are not (yet) converted, the ones currently implemented don't
978  * need conversion, as they are the same on both systems.
979  */
980 int
981 linux_sys_setsockopt(l, v, retval)
982 	struct lwp *l;
983 	void *v;
984 	register_t *retval;
985 {
986 	struct linux_sys_setsockopt_args /* {
987 		syscallarg(int) s;
988 		syscallarg(int) level;
989 		syscallarg(int) optname;
990 		syscallarg(void *) optval;
991 		syscallarg(int) optlen;
992 	} */ *uap = v;
993 	struct sys_setsockopt_args bsa;
994 	int name;
995 
996 	SCARG(&bsa, s) = SCARG(uap, s);
997 	SCARG(&bsa, level) = linux_to_bsd_sopt_level(SCARG(uap, level));
998 	SCARG(&bsa, val) = SCARG(uap, optval);
999 	SCARG(&bsa, valsize) = SCARG(uap, optlen);
1000 
1001 	switch (SCARG(&bsa, level)) {
1002 	case SOL_SOCKET:
1003 		name = linux_to_bsd_so_sockopt(SCARG(uap, optname));
1004 		break;
1005 	case IPPROTO_IP:
1006 		name = linux_to_bsd_ip_sockopt(SCARG(uap, optname));
1007 		break;
1008 	case IPPROTO_TCP:
1009 		name = linux_to_bsd_tcp_sockopt(SCARG(uap, optname));
1010 		break;
1011 	case IPPROTO_UDP:
1012 		name = linux_to_bsd_udp_sockopt(SCARG(uap, optname));
1013 		break;
1014 	default:
1015 		return EINVAL;
1016 	}
1017 
1018 	if (name == -1)
1019 		return EINVAL;
1020 	SCARG(&bsa, name) = name;
1021 
1022 	return sys_setsockopt(l, &bsa, retval);
1023 }
1024 
1025 /*
1026  * getsockopt(2) is very much the same as setsockopt(2) (see above)
1027  */
1028 int
1029 linux_sys_getsockopt(l, v, retval)
1030 	struct lwp *l;
1031 	void *v;
1032 	register_t *retval;
1033 {
1034 	struct linux_sys_getsockopt_args /* {
1035 		syscallarg(int) s;
1036 		syscallarg(int) level;
1037 		syscallarg(int) optname;
1038 		syscallarg(void *) optval;
1039 		syscallarg(int *) optlen;
1040 	} */ *uap = v;
1041 	struct sys_getsockopt_args bga;
1042 	int name;
1043 
1044 	SCARG(&bga, s) = SCARG(uap, s);
1045 	SCARG(&bga, level) = linux_to_bsd_sopt_level(SCARG(uap, level));
1046 	SCARG(&bga, val) = SCARG(uap, optval);
1047 	SCARG(&bga, avalsize) = SCARG(uap, optlen);
1048 
1049 	switch (SCARG(&bga, level)) {
1050 	case SOL_SOCKET:
1051 		name = linux_to_bsd_so_sockopt(SCARG(uap, optname));
1052 		break;
1053 	case IPPROTO_IP:
1054 		name = linux_to_bsd_ip_sockopt(SCARG(uap, optname));
1055 		break;
1056 	case IPPROTO_TCP:
1057 		name = linux_to_bsd_tcp_sockopt(SCARG(uap, optname));
1058 		break;
1059 	case IPPROTO_UDP:
1060 		name = linux_to_bsd_udp_sockopt(SCARG(uap, optname));
1061 		break;
1062 	default:
1063 		return EINVAL;
1064 	}
1065 
1066 	if (name == -1)
1067 		return EINVAL;
1068 	SCARG(&bga, name) = name;
1069 
1070 	return sys_getsockopt(l, &bga, retval);
1071 }
1072 
1073 #define IF_NAME_LEN 16
1074 
1075 int
1076 linux_getifhwaddr(l, retval, fd, data)
1077 	struct lwp *l;
1078 	register_t *retval;
1079 	u_int fd;
1080 	void *data;
1081 {
1082 	/* Not the full structure, just enough to map what we do here */
1083 	struct linux_ifreq {
1084 		char if_name[IF_NAME_LEN];
1085 		struct osockaddr hwaddr;
1086 	} lreq;
1087 	struct proc *p = l->l_proc;
1088 	struct filedesc *fdp;
1089 	struct file *fp;
1090 	struct ifaddr *ifa;
1091 	struct ifnet *ifp;
1092 	struct sockaddr_dl *sadl;
1093 	int error, found;
1094 	int index, ifnum;
1095 
1096 	/*
1097 	 * We can't emulate this ioctl by calling sys_ioctl() to run
1098 	 * SIOCGIFCONF, because the user buffer is not of the right
1099 	 * type to take those results.  We can't use kernel buffers to
1100 	 * receive the results, as the implementation of sys_ioctl()
1101 	 * and ifconf() [which implements SIOCGIFCONF] use
1102 	 * copyin()/copyout() which will fail on kernel addresses.
1103 	 *
1104 	 * So, we must duplicate code from sys_ioctl() and ifconf().  Ugh.
1105 	 */
1106 
1107 	fdp = p->p_fd;
1108 	if ((fp = fd_getfile(fdp, fd)) == NULL)
1109 		return (EBADF);
1110 
1111 	FILE_USE(fp);
1112 	if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
1113 		error = EBADF;
1114 		goto out;
1115 	}
1116 
1117 	error = copyin(data, (caddr_t)&lreq, sizeof(lreq));
1118 	if (error)
1119 		goto out;
1120 	lreq.if_name[IF_NAME_LEN-1] = '\0';		/* just in case */
1121 
1122 	/*
1123 	 * Try real interface name first, then fake "ethX"
1124 	 */
1125 	for (ifp = ifnet.tqh_first, found = 0;
1126 	     ifp != 0 && !found;
1127 	     ifp = ifp->if_list.tqe_next) {
1128 		if (strcmp(lreq.if_name, ifp->if_xname))
1129 			/* not this interface */
1130 			continue;
1131 		found=1;
1132 		if ((ifa = ifp->if_addrlist.tqh_first) != 0) {
1133 			for (; ifa != 0; ifa = ifa->ifa_list.tqe_next) {
1134 				sadl = (struct sockaddr_dl *)ifa->ifa_addr;
1135 				/* only return ethernet addresses */
1136 				/* XXX what about FDDI, etc. ? */
1137 				if (sadl->sdl_family != AF_LINK ||
1138 				    sadl->sdl_type != IFT_ETHER)
1139 					continue;
1140 				memcpy((caddr_t)&lreq.hwaddr.sa_data,
1141 				       LLADDR(sadl),
1142 				       MIN(sadl->sdl_alen,
1143 					   sizeof(lreq.hwaddr.sa_data)));
1144 				lreq.hwaddr.sa_family =
1145 					sadl->sdl_family;
1146 				error = copyout((caddr_t)&lreq, data,
1147 						sizeof(lreq));
1148 				goto out;
1149 			}
1150 		} else {
1151 			error = ENODEV;
1152 			goto out;
1153 		}
1154 	}
1155 
1156 	if (strncmp(lreq.if_name, "eth", 3) == 0) {
1157 		for (ifnum = 0, index = 3;
1158 		     lreq.if_name[index] != '\0' && index < IF_NAME_LEN;
1159 		     index++) {
1160 			ifnum *= 10;
1161 			ifnum += lreq.if_name[index] - '0';
1162 		}
1163 
1164 		error = EINVAL;			/* in case we don't find one */
1165 		for (ifp = ifnet.tqh_first, found = 0;
1166 		     ifp != 0 && !found;
1167 		     ifp = ifp->if_list.tqe_next) {
1168 			memcpy(lreq.if_name, ifp->if_xname,
1169 			       MIN(IF_NAME_LEN, IFNAMSIZ));
1170 			if ((ifa = ifp->if_addrlist.tqh_first) == 0)
1171 				/* no addresses on this interface */
1172 				continue;
1173 			else
1174 				for (; ifa != 0; ifa = ifa->ifa_list.tqe_next) {
1175 					sadl = (struct sockaddr_dl *)ifa->ifa_addr;
1176 					/* only return ethernet addresses */
1177 					/* XXX what about FDDI, etc. ? */
1178 					if (sadl->sdl_family != AF_LINK ||
1179 					    sadl->sdl_type != IFT_ETHER)
1180 						continue;
1181 					if (ifnum--)
1182 						/* not the reqested iface */
1183 						continue;
1184 					memcpy((caddr_t)&lreq.hwaddr.sa_data,
1185 					       LLADDR(sadl),
1186 					       MIN(sadl->sdl_alen,
1187 						   sizeof(lreq.hwaddr.sa_data)));
1188 					lreq.hwaddr.sa_family =
1189 						sadl->sdl_family;
1190 					error = copyout((caddr_t)&lreq, data,
1191 							sizeof(lreq));
1192 					found = 1;
1193 					break;
1194 				}
1195 		}
1196 	} else {
1197 		/* unknown interface, not even an "eth*" name */
1198 		error = ENODEV;
1199 	}
1200 
1201 out:
1202 	FILE_UNUSE(fp, l);
1203 	return error;
1204 }
1205 #undef IF_NAME_LEN
1206 
1207 int
1208 linux_ioctl_socket(l, uap, retval)
1209 	struct lwp *l;
1210 	struct linux_sys_ioctl_args /* {
1211 		syscallarg(int) fd;
1212 		syscallarg(u_long) com;
1213 		syscallarg(caddr_t) data;
1214 	} */ *uap;
1215 	register_t *retval;
1216 {
1217 	struct proc *p = l->l_proc;
1218 	u_long com;
1219 	int error = 0, isdev = 0, dosys = 1;
1220 	struct sys_ioctl_args ia;
1221 	struct file *fp;
1222 	struct filedesc *fdp;
1223 	struct vnode *vp;
1224 	int (*ioctlf)(struct file *, u_long, void *, struct lwp *);
1225 	struct ioctl_pt pt;
1226 
1227         fdp = p->p_fd;
1228 	if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
1229 		return (EBADF);
1230 
1231 	FILE_USE(fp);
1232 
1233 	if (fp->f_type == DTYPE_VNODE) {
1234 		vp = (struct vnode *)fp->f_data;
1235 		isdev = vp->v_type == VCHR;
1236 	}
1237 
1238 	/*
1239 	 * Don't try to interpret socket ioctl calls that are done
1240 	 * on a device filedescriptor, just pass them through, to
1241 	 * emulate Linux behaviour. Use PTIOCLINUX so that the
1242 	 * device will only handle these if it's prepared to do
1243 	 * so, to avoid unexpected things from happening.
1244 	 */
1245 	if (isdev) {
1246 		dosys = 0;
1247 		ioctlf = fp->f_ops->fo_ioctl;
1248 		pt.com = SCARG(uap, com);
1249 		pt.data = SCARG(uap, data);
1250 		error = ioctlf(fp, PTIOCLINUX, (caddr_t)&pt, l);
1251 		/*
1252 		 * XXX hack: if the function returns EJUSTRETURN,
1253 		 * it has stuffed a sysctl return value in pt.data.
1254 		 */
1255 		if (error == EJUSTRETURN) {
1256 			retval[0] = (register_t)pt.data;
1257 			error = 0;
1258 		}
1259 		goto out;
1260 	}
1261 
1262 	com = SCARG(uap, com);
1263 	retval[0] = 0;
1264 
1265 	switch (com) {
1266 	case LINUX_SIOCGIFCONF:
1267 		SCARG(&ia, com) = OSIOCGIFCONF;
1268 		break;
1269 	case LINUX_SIOCGIFFLAGS:
1270 		SCARG(&ia, com) = SIOCGIFFLAGS;
1271 		break;
1272 	case LINUX_SIOCSIFFLAGS:
1273 		SCARG(&ia, com) = SIOCSIFFLAGS;
1274 		break;
1275 	case LINUX_SIOCGIFADDR:
1276 		SCARG(&ia, com) = OSIOCGIFADDR;
1277 		break;
1278 	case LINUX_SIOCGIFDSTADDR:
1279 		SCARG(&ia, com) = OSIOCGIFDSTADDR;
1280 		break;
1281 	case LINUX_SIOCGIFBRDADDR:
1282 		SCARG(&ia, com) = OSIOCGIFBRDADDR;
1283 		break;
1284 	case LINUX_SIOCGIFNETMASK:
1285 		SCARG(&ia, com) = OSIOCGIFNETMASK;
1286 		break;
1287 	case LINUX_SIOCADDMULTI:
1288 		SCARG(&ia, com) = SIOCADDMULTI;
1289 		break;
1290 	case LINUX_SIOCDELMULTI:
1291 		SCARG(&ia, com) = SIOCDELMULTI;
1292 		break;
1293 	case LINUX_SIOCGIFHWADDR:
1294 	        error = linux_getifhwaddr(l, retval, SCARG(uap, fd),
1295 					 SCARG(uap, data));
1296 		dosys = 0;
1297 		break;
1298 	default:
1299 		error = EINVAL;
1300 	}
1301 
1302 out:
1303 	FILE_UNUSE(fp, l);
1304 
1305 	if (error ==0 && dosys) {
1306 		SCARG(&ia, fd) = SCARG(uap, fd);
1307 		SCARG(&ia, data) = SCARG(uap, data);
1308 		/* XXX NJWLWP */
1309 		error = sys_ioctl(curlwp, &ia, retval);
1310 	}
1311 
1312 	return error;
1313 }
1314 
1315 int
1316 linux_sys_connect(l, v, retval)
1317 	struct lwp *l;
1318 	void *v;
1319 	register_t *retval;
1320 {
1321 	struct linux_sys_connect_args /* {
1322 		syscallarg(int) s;
1323 		syscallarg(const struct sockaddr *) name;
1324 		syscallarg(int) namelen;
1325 	} */ *uap = v;
1326 	struct proc *p = l->l_proc;
1327 	int		error;
1328 	struct sockaddr *sa;
1329 	struct sys_connect_args bca;
1330 	caddr_t sg = stackgap_init(p, 0);
1331 	int namlen;
1332 
1333 	namlen = SCARG(uap, namelen);
1334 	error = linux_sa_get(l, SCARG(uap, s), &sg, &sa,
1335 	    SCARG(uap, name), &namlen);
1336 	if (error)
1337 		return (error);
1338 
1339 	SCARG(&bca, s) = SCARG(uap, s);
1340 	SCARG(&bca, name) = sa;
1341 	SCARG(&bca, namelen) = (unsigned int) namlen;
1342 
1343 	error = sys_connect(l, &bca, retval);
1344 
1345 	if (error == EISCONN) {
1346 		struct file *fp;
1347 		struct socket *so;
1348 		int s, state, prflags;
1349 
1350 		/* getsock() will use the descriptor for us */
1351 	    	if (getsock(p->p_fd, SCARG(uap, s), &fp) != 0)
1352 		    	return EISCONN;
1353 
1354 		s = splsoftnet();
1355 		so = (struct socket *)fp->f_data;
1356 		state = so->so_state;
1357 		prflags = so->so_proto->pr_flags;
1358 		splx(s);
1359 		FILE_UNUSE(fp, l);
1360 		/*
1361 		 * We should only let this call succeed once per
1362 		 * non-blocking connect; however we don't have
1363 		 * a convenient place to keep that state..
1364 		 */
1365 		if ((state & SS_NBIO) && (state & SS_ISCONNECTED) &&
1366 		    (prflags & PR_CONNREQUIRED))
1367 			return 0;
1368 	}
1369 
1370 	return (error);
1371 }
1372 
1373 int
1374 linux_sys_bind(l, v, retval)
1375 	struct lwp *l;
1376 	void *v;
1377 	register_t *retval;
1378 {
1379 	struct linux_sys_bind_args /* {
1380 		syscallarg(int) s;
1381 		syscallarg(const struct osockaddr *) name;
1382 		syscallarg(int) namelen;
1383 	} */ *uap = v;
1384 	struct proc *p = l->l_proc;
1385 	int		error, namlen;
1386 	struct sys_bind_args bsa;
1387 
1388 	namlen = SCARG(uap, namelen);
1389 	SCARG(&bsa, s) = SCARG(uap, s);
1390 	if (SCARG(uap, name)) {
1391 		struct sockaddr *sa;
1392 		caddr_t sg = stackgap_init(p, 0);
1393 
1394 		error = linux_sa_get(l, SCARG(uap, s), &sg, &sa,
1395 		    SCARG(uap, name), &namlen);
1396 		if (error)
1397 			return (error);
1398 
1399 		SCARG(&bsa, name) = sa;
1400 	} else
1401 		SCARG(&bsa, name) = NULL;
1402 	SCARG(&bsa, namelen) = namlen;
1403 
1404 	return (sys_bind(l, &bsa, retval));
1405 }
1406 
1407 int
1408 linux_sys_getsockname(l, v, retval)
1409 	struct lwp *l;
1410 	void *v;
1411 	register_t *retval;
1412 {
1413 	struct linux_sys_getsockname_args /* {
1414 		syscallarg(int) fdes;
1415 		syscallarg(caddr_t) asa;
1416 		syscallarg(int *) alen;
1417 	} */ *uap = v;
1418 	int error;
1419 
1420 	if ((error = sys_getsockname(l, uap, retval)) != 0)
1421 		return (error);
1422 
1423 	if ((error = linux_sa_put((struct osockaddr *)SCARG(uap, asa))))
1424 		return (error);
1425 
1426 	return (0);
1427 }
1428 
1429 int
1430 linux_sys_getpeername(l, v, retval)
1431 	struct lwp *l;
1432 	void *v;
1433 	register_t *retval;
1434 {
1435 	struct sys_getpeername_args /* {
1436 		syscallarg(int) fdes;
1437 		syscallarg(caddr_t) asa;
1438 		syscallarg(int *) alen;
1439 	} */ *uap = v;
1440 	int error;
1441 
1442 	if ((error = sys_getpeername(l, uap, retval)) != 0)
1443 		return (error);
1444 
1445 	if ((error = linux_sa_put((struct osockaddr *)SCARG(uap, asa))))
1446 		return (error);
1447 
1448 	return (0);
1449 }
1450 
1451 /*
1452  * Copy the osockaddr structure pointed to by osa to kernel, adjust
1453  * family and convert to sockaddr, allocate stackgap and put the
1454  * the converted structure there, address on stackgap returned in sap.
1455  */
1456 static int
1457 linux_sa_get(l, s, sgp, sap, osa, osalen)
1458 	struct lwp *l;
1459 	int s;
1460 	caddr_t *sgp;
1461 	struct sockaddr **sap;
1462 	const struct osockaddr *osa;
1463 	int *osalen;
1464 {
1465 	int error=0, bdom;
1466 	struct sockaddr *sa, *usa;
1467 	struct osockaddr *kosa = (struct osockaddr *) &sa;
1468 	struct proc *p = l->l_proc;
1469 	int alloclen;
1470 #ifdef INET6
1471 	int oldv6size;
1472 	struct sockaddr_in6 *sin6;
1473 #endif
1474 
1475 	if (*osalen < 2 || *osalen > UCHAR_MAX || !osa) {
1476 		DPRINTF(("bad osa=%p osalen=%d\n", osa, *osalen));
1477 		return (EINVAL);
1478 	}
1479 
1480 	alloclen = *osalen;
1481 #ifdef INET6
1482 	oldv6size = 0;
1483 	/*
1484 	 * Check for old (pre-RFC2553) sockaddr_in6. We may accept it
1485 	 * if it's a v4-mapped address, so reserve the proper space
1486 	 * for it.
1487 	 */
1488 	if (alloclen == sizeof (struct sockaddr_in6) - sizeof (u_int32_t)) {
1489 		alloclen = sizeof (struct sockaddr_in6);
1490 		oldv6size = 1;
1491 	}
1492 #endif
1493 
1494 	kosa = (struct osockaddr *) malloc(alloclen, M_TEMP, M_WAITOK);
1495 
1496 	if ((error = copyin(osa, (caddr_t) kosa, *osalen))) {
1497 		DPRINTF(("error copying osa %d\n", error));
1498 		goto out;
1499 	}
1500 
1501 	bdom = linux_to_bsd_domain(kosa->sa_family);
1502 	if (bdom == -1) {
1503 		DPRINTF(("bad linux family=%d\n", kosa->sa_family));
1504 		error = EINVAL;
1505 		goto out;
1506 	}
1507 
1508 #ifdef INET6
1509 	/*
1510 	 * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6,
1511 	 * which lacks the scope id compared with RFC2553 one. If we detect
1512 	 * the situation, reject the address and write a message to system log.
1513 	 *
1514 	 * Still accept addresses for which the scope id is not used.
1515 	 */
1516 	if (oldv6size && bdom == AF_INET6) {
1517 		sin6 = (struct sockaddr_in6 *)kosa;
1518 		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ||
1519 		    (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
1520 		     !IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) &&
1521 		     !IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) &&
1522 		     !IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) &&
1523 		     !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) {
1524 			sin6->sin6_scope_id = 0;
1525 		} else {
1526 			int uid = p->p_cred && p->p_ucred ?
1527 					p->p_ucred->cr_uid : -1;
1528 
1529 			log(LOG_DEBUG,
1530 			    "pid %d (%s), uid %d: obsolete pre-RFC2553 "
1531 			    "sockaddr_in6 rejected",
1532 			    p->p_pid, p->p_comm, uid);
1533 			error = EINVAL;
1534 			goto out;
1535 		}
1536 	}
1537 #endif
1538 
1539 	/*
1540 	 * If the family is unspecified, use address family of the
1541 	 * socket. This avoid triggering COMPAT_43 struct socket family check
1542 	 * in sockargs() on little-endian machines, and strict family checks
1543 	 * in netinet/in_pcb.c et.al.
1544 	 */
1545 	if (bdom == AF_UNSPEC) {
1546 		struct file *fp;
1547 		struct socket *so;
1548 
1549 		/* getsock() will use the descriptor for us */
1550 		if ((error = getsock(p->p_fd, s, &fp)) != 0)
1551 			goto out;
1552 
1553 		so = (struct socket *)fp->f_data;
1554 		bdom = so->so_proto->pr_domain->dom_family;
1555 
1556 		FILE_UNUSE(fp, l);
1557 
1558 		DPRINTF(("AF_UNSPEC family adjusted to %d\n", bdom));
1559 	}
1560 
1561 	if (bdom == AF_INET) {
1562 		alloclen = sizeof(struct sockaddr_in);
1563 	}
1564 
1565 	sa = (struct sockaddr *) kosa;
1566 	sa->sa_family = bdom;
1567 	sa->sa_len = alloclen;
1568 #ifdef DEBUG_LINUX
1569 	DPRINTF(("family %d, len = %d [ ", sa->sa_family, sa->sa_len));
1570 	for (bdom = 0; bdom < sizeof(sa->sa_data); bdom++)
1571 	    DPRINTF(("%02x ", (unsigned char) sa->sa_data[bdom]));
1572 	DPRINTF(("\n"));
1573 #endif
1574 
1575 	usa = (struct sockaddr *) stackgap_alloc(p, sgp, alloclen);
1576 	if (!usa) {
1577 		error = ENOMEM;
1578 		goto out;
1579 	}
1580 
1581 	if ((error = copyout(sa, usa, alloclen))) {
1582 		DPRINTF(("error copying out socket %d\n", error));
1583 		goto out;
1584 	}
1585 
1586 	*sap = usa;
1587 
1588     out:
1589 	*osalen = alloclen;
1590 	free(kosa, M_TEMP);
1591 	return (error);
1592 }
1593 
1594 static int
1595 linux_sa_put(osa)
1596 	struct osockaddr *osa;
1597 {
1598 	struct sockaddr sa;
1599 	struct osockaddr *kosa;
1600 	int error, bdom, len;
1601 
1602 	/*
1603 	 * Only read/write the sockaddr family and length part, the rest is
1604 	 * not changed.
1605 	 */
1606 	len = sizeof(sa.sa_len) + sizeof(sa.sa_family);
1607 
1608 	error = copyin((caddr_t) osa, (caddr_t) &sa, len);
1609 	if (error)
1610 		return (error);
1611 
1612 	bdom = bsd_to_linux_domain(sa.sa_family);
1613 	if (bdom == -1)
1614 		return (EINVAL);
1615 
1616 	/* Note: we convert from sockaddr to osockaddr here, too */
1617 	kosa = (struct osockaddr *) &sa;
1618 	kosa->sa_family = bdom;
1619 	error = copyout(kosa, osa, len);
1620 	if (error)
1621 		return (error);
1622 
1623 	return (0);
1624 }
1625 
1626 #ifndef __amd64__
1627 int
1628 linux_sys_recv(l, v, retval)
1629 	struct lwp *l;
1630 	void *v;
1631 	register_t *retval;
1632 {
1633 	struct linux_sys_recv_args /* {
1634 		syscallarg(int) s;
1635 		syscallarg(void *) buf;
1636 		syscallarg(int) len;
1637 		syscallarg(int) flags;
1638 	} */ *uap = v;
1639 	struct sys_recvfrom_args bra;
1640 
1641 
1642 	SCARG(&bra, s) = SCARG(uap, s);
1643 	SCARG(&bra, buf) = SCARG(uap, buf);
1644 	SCARG(&bra, len) = (size_t) SCARG(uap, len);
1645 	SCARG(&bra, flags) = SCARG(uap, flags);
1646 	SCARG(&bra, from) = NULL;
1647 	SCARG(&bra, fromlenaddr) = NULL;
1648 
1649 	return (sys_recvfrom(l, &bra, retval));
1650 }
1651 
1652 int
1653 linux_sys_send(l, v, retval)
1654 	struct lwp *l;
1655 	void *v;
1656 	register_t *retval;
1657 {
1658 	struct linux_sys_send_args /* {
1659 		syscallarg(int) s;
1660 		syscallarg(caddr_t) buf;
1661 		syscallarg(int) len;
1662 		syscallarg(int) flags;
1663 	} */ *uap = v;
1664 	struct sys_sendto_args bsa;
1665 
1666 	SCARG(&bsa, s)		= SCARG(uap, s);
1667 	SCARG(&bsa, buf)	= SCARG(uap, buf);
1668 	SCARG(&bsa, len)	= SCARG(uap, len);
1669 	SCARG(&bsa, flags)	= SCARG(uap, flags);
1670 	SCARG(&bsa, to)		= NULL;
1671 	SCARG(&bsa, tolen)	= 0;
1672 
1673 	return (sys_sendto(l, &bsa, retval));
1674 }
1675 #endif /* __amd64__ */
1676 
1677 int
1678 linux_sys_accept(l, v, retval)
1679 	struct lwp *l;
1680 	void *v;
1681 	register_t *retval;
1682 {
1683 	struct linux_sys_accept_args /* {
1684 		syscallarg(int) s;
1685 		syscallarg(struct osockaddr *) name;
1686 		syscallarg(int *) anamelen;
1687 	} */ *uap = v;
1688 	int error;
1689 	struct sys_accept_args baa;
1690 
1691 	SCARG(&baa, s)		= SCARG(uap, s);
1692 	SCARG(&baa, name)	= (struct sockaddr *) SCARG(uap, name);
1693 	SCARG(&baa, anamelen)	= (unsigned int *) SCARG(uap, anamelen);
1694 
1695 	if ((error = sys_accept(l, &baa, retval)))
1696 		return (error);
1697 
1698 	if (SCARG(uap, name) && (error = linux_sa_put(SCARG(uap, name))))
1699 		return (error);
1700 
1701 	return (0);
1702 }
1703