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