]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/compat/linux/linux_socket.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / compat / linux / linux_socket.c
1 /*-
2  * Copyright (c) 1995 Søren Schmidt
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer
10  *    in this position and unchanged.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 /* XXX we use functions that might not exist. */
33 #include "opt_compat.h"
34 #include "opt_inet6.h"
35
36 #include <sys/param.h>
37 #include <sys/proc.h>
38 #include <sys/systm.h>
39 #include <sys/sysproto.h>
40 #include <sys/capability.h>
41 #include <sys/fcntl.h>
42 #include <sys/file.h>
43 #include <sys/limits.h>
44 #include <sys/lock.h>
45 #include <sys/malloc.h>
46 #include <sys/mutex.h>
47 #include <sys/mbuf.h>
48 #include <sys/socket.h>
49 #include <sys/socketvar.h>
50 #include <sys/syscallsubr.h>
51 #include <sys/uio.h>
52 #include <sys/syslog.h>
53 #include <sys/un.h>
54
55 #include <net/if.h>
56 #include <netinet/in.h>
57 #include <netinet/in_systm.h>
58 #include <netinet/ip.h>
59 #include <netinet/tcp.h>
60 #ifdef INET6
61 #include <netinet/ip6.h>
62 #include <netinet6/ip6_var.h>
63 #include <netinet6/in6_var.h>
64 #endif
65
66 #ifdef COMPAT_LINUX32
67 #include <machine/../linux32/linux.h>
68 #include <machine/../linux32/linux32_proto.h>
69 #else
70 #include <machine/../linux/linux.h>
71 #include <machine/../linux/linux_proto.h>
72 #endif
73 #include <compat/linux/linux_socket.h>
74 #include <compat/linux/linux_util.h>
75
76 static int linux_to_bsd_domain(int);
77
78 /*
79  * Reads a linux sockaddr and does any necessary translation.
80  * Linux sockaddrs don't have a length field, only a family.
81  * Copy the osockaddr structure pointed to by osa to kernel, adjust
82  * family and convert to sockaddr.
83  */
84 static int
85 linux_getsockaddr(struct sockaddr **sap, const struct osockaddr *osa, int salen)
86 {
87         struct sockaddr *sa;
88         struct osockaddr *kosa;
89 #ifdef INET6
90         struct sockaddr_in6 *sin6;
91         int oldv6size;
92 #endif
93         char *name;
94         int bdom, error, hdrlen, namelen;
95
96         if (salen < 2 || salen > UCHAR_MAX || !osa)
97                 return (EINVAL);
98
99 #ifdef INET6
100         oldv6size = 0;
101         /*
102          * Check for old (pre-RFC2553) sockaddr_in6. We may accept it
103          * if it's a v4-mapped address, so reserve the proper space
104          * for it.
105          */
106         if (salen == sizeof(struct sockaddr_in6) - sizeof(uint32_t)) {
107                 salen += sizeof(uint32_t);
108                 oldv6size = 1;
109         }
110 #endif
111
112         kosa = malloc(salen, M_SONAME, M_WAITOK);
113
114         if ((error = copyin(osa, kosa, salen)))
115                 goto out;
116
117         bdom = linux_to_bsd_domain(kosa->sa_family);
118         if (bdom == -1) {
119                 error = EAFNOSUPPORT;
120                 goto out;
121         }
122
123 #ifdef INET6
124         /*
125          * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6,
126          * which lacks the scope id compared with RFC2553 one. If we detect
127          * the situation, reject the address and write a message to system log.
128          *
129          * Still accept addresses for which the scope id is not used.
130          */
131         if (oldv6size) {
132                 if (bdom == AF_INET6) {
133                         sin6 = (struct sockaddr_in6 *)kosa;
134                         if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ||
135                             (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
136                              !IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) &&
137                              !IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) &&
138                              !IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) &&
139                              !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) {
140                                 sin6->sin6_scope_id = 0;
141                         } else {
142                                 log(LOG_DEBUG,
143                                     "obsolete pre-RFC2553 sockaddr_in6 rejected\n");
144                                 error = EINVAL;
145                                 goto out;
146                         }
147                 } else
148                         salen -= sizeof(uint32_t);
149         }
150 #endif
151         if (bdom == AF_INET) {
152                 if (salen < sizeof(struct sockaddr_in)) {
153                         error = EINVAL;
154                         goto out;
155                 }
156                 salen = sizeof(struct sockaddr_in);
157         }
158
159         if (bdom == AF_LOCAL && salen > sizeof(struct sockaddr_un)) {
160                 hdrlen = offsetof(struct sockaddr_un, sun_path);
161                 name = ((struct sockaddr_un *)kosa)->sun_path;
162                 if (*name == '\0') {
163                         /*
164                          * Linux abstract namespace starts with a NULL byte.
165                          * XXX We do not support abstract namespace yet.
166                          */
167                         namelen = strnlen(name + 1, salen - hdrlen - 1) + 1;
168                 } else
169                         namelen = strnlen(name, salen - hdrlen);
170                 salen = hdrlen + namelen;
171                 if (salen > sizeof(struct sockaddr_un)) {
172                         error = ENAMETOOLONG;
173                         goto out;
174                 }
175         }
176
177         sa = (struct sockaddr *)kosa;
178         sa->sa_family = bdom;
179         sa->sa_len = salen;
180
181         *sap = sa;
182         return (0);
183
184 out:
185         free(kosa, M_SONAME);
186         return (error);
187 }
188
189 static int
190 linux_to_bsd_domain(int domain)
191 {
192
193         switch (domain) {
194         case LINUX_AF_UNSPEC:
195                 return (AF_UNSPEC);
196         case LINUX_AF_UNIX:
197                 return (AF_LOCAL);
198         case LINUX_AF_INET:
199                 return (AF_INET);
200         case LINUX_AF_INET6:
201                 return (AF_INET6);
202         case LINUX_AF_AX25:
203                 return (AF_CCITT);
204         case LINUX_AF_IPX:
205                 return (AF_IPX);
206         case LINUX_AF_APPLETALK:
207                 return (AF_APPLETALK);
208         }
209         return (-1);
210 }
211
212 static int
213 bsd_to_linux_domain(int domain)
214 {
215
216         switch (domain) {
217         case AF_UNSPEC:
218                 return (LINUX_AF_UNSPEC);
219         case AF_LOCAL:
220                 return (LINUX_AF_UNIX);
221         case AF_INET:
222                 return (LINUX_AF_INET);
223         case AF_INET6:
224                 return (LINUX_AF_INET6);
225         case AF_CCITT:
226                 return (LINUX_AF_AX25);
227         case AF_IPX:
228                 return (LINUX_AF_IPX);
229         case AF_APPLETALK:
230                 return (LINUX_AF_APPLETALK);
231         }
232         return (-1);
233 }
234
235 static int
236 linux_to_bsd_sockopt_level(int level)
237 {
238
239         switch (level) {
240         case LINUX_SOL_SOCKET:
241                 return (SOL_SOCKET);
242         }
243         return (level);
244 }
245
246 static int
247 bsd_to_linux_sockopt_level(int level)
248 {
249
250         switch (level) {
251         case SOL_SOCKET:
252                 return (LINUX_SOL_SOCKET);
253         }
254         return (level);
255 }
256
257 static int
258 linux_to_bsd_ip_sockopt(int opt)
259 {
260
261         switch (opt) {
262         case LINUX_IP_TOS:
263                 return (IP_TOS);
264         case LINUX_IP_TTL:
265                 return (IP_TTL);
266         case LINUX_IP_OPTIONS:
267                 return (IP_OPTIONS);
268         case LINUX_IP_MULTICAST_IF:
269                 return (IP_MULTICAST_IF);
270         case LINUX_IP_MULTICAST_TTL:
271                 return (IP_MULTICAST_TTL);
272         case LINUX_IP_MULTICAST_LOOP:
273                 return (IP_MULTICAST_LOOP);
274         case LINUX_IP_ADD_MEMBERSHIP:
275                 return (IP_ADD_MEMBERSHIP);
276         case LINUX_IP_DROP_MEMBERSHIP:
277                 return (IP_DROP_MEMBERSHIP);
278         case LINUX_IP_HDRINCL:
279                 return (IP_HDRINCL);
280         }
281         return (-1);
282 }
283
284 static int
285 linux_to_bsd_so_sockopt(int opt)
286 {
287
288         switch (opt) {
289         case LINUX_SO_DEBUG:
290                 return (SO_DEBUG);
291         case LINUX_SO_REUSEADDR:
292                 return (SO_REUSEADDR);
293         case LINUX_SO_TYPE:
294                 return (SO_TYPE);
295         case LINUX_SO_ERROR:
296                 return (SO_ERROR);
297         case LINUX_SO_DONTROUTE:
298                 return (SO_DONTROUTE);
299         case LINUX_SO_BROADCAST:
300                 return (SO_BROADCAST);
301         case LINUX_SO_SNDBUF:
302                 return (SO_SNDBUF);
303         case LINUX_SO_RCVBUF:
304                 return (SO_RCVBUF);
305         case LINUX_SO_KEEPALIVE:
306                 return (SO_KEEPALIVE);
307         case LINUX_SO_OOBINLINE:
308                 return (SO_OOBINLINE);
309         case LINUX_SO_LINGER:
310                 return (SO_LINGER);
311         case LINUX_SO_PEERCRED:
312                 return (LOCAL_PEERCRED);
313         case LINUX_SO_RCVLOWAT:
314                 return (SO_RCVLOWAT);
315         case LINUX_SO_SNDLOWAT:
316                 return (SO_SNDLOWAT);
317         case LINUX_SO_RCVTIMEO:
318                 return (SO_RCVTIMEO);
319         case LINUX_SO_SNDTIMEO:
320                 return (SO_SNDTIMEO);
321         case LINUX_SO_TIMESTAMP:
322                 return (SO_TIMESTAMP);
323         case LINUX_SO_ACCEPTCONN:
324                 return (SO_ACCEPTCONN);
325         }
326         return (-1);
327 }
328
329 static int
330 linux_to_bsd_tcp_sockopt(int opt)
331 {
332
333         switch (opt) {
334         case LINUX_TCP_NODELAY:
335                 return (TCP_NODELAY);
336         case LINUX_TCP_MAXSEG:
337                 return (TCP_MAXSEG);
338         case LINUX_TCP_KEEPIDLE:
339                 return (TCP_KEEPIDLE);
340         case LINUX_TCP_KEEPINTVL:
341                 return (TCP_KEEPINTVL);
342         case LINUX_TCP_KEEPCNT:
343                 return (TCP_KEEPCNT);
344         case LINUX_TCP_MD5SIG:
345                 return (TCP_MD5SIG);
346         }
347         return (-1);
348 }
349
350 static int
351 linux_to_bsd_msg_flags(int flags)
352 {
353         int ret_flags = 0;
354
355         if (flags & LINUX_MSG_OOB)
356                 ret_flags |= MSG_OOB;
357         if (flags & LINUX_MSG_PEEK)
358                 ret_flags |= MSG_PEEK;
359         if (flags & LINUX_MSG_DONTROUTE)
360                 ret_flags |= MSG_DONTROUTE;
361         if (flags & LINUX_MSG_CTRUNC)
362                 ret_flags |= MSG_CTRUNC;
363         if (flags & LINUX_MSG_TRUNC)
364                 ret_flags |= MSG_TRUNC;
365         if (flags & LINUX_MSG_DONTWAIT)
366                 ret_flags |= MSG_DONTWAIT;
367         if (flags & LINUX_MSG_EOR)
368                 ret_flags |= MSG_EOR;
369         if (flags & LINUX_MSG_WAITALL)
370                 ret_flags |= MSG_WAITALL;
371         if (flags & LINUX_MSG_NOSIGNAL)
372                 ret_flags |= MSG_NOSIGNAL;
373 #if 0 /* not handled */
374         if (flags & LINUX_MSG_PROXY)
375                 ;
376         if (flags & LINUX_MSG_FIN)
377                 ;
378         if (flags & LINUX_MSG_SYN)
379                 ;
380         if (flags & LINUX_MSG_CONFIRM)
381                 ;
382         if (flags & LINUX_MSG_RST)
383                 ;
384         if (flags & LINUX_MSG_ERRQUEUE)
385                 ;
386 #endif
387         return ret_flags;
388 }
389
390 /*
391 * If bsd_to_linux_sockaddr() or linux_to_bsd_sockaddr() faults, then the
392 * native syscall will fault.  Thus, we don't really need to check the
393 * return values for these functions.
394 */
395
396 static int
397 bsd_to_linux_sockaddr(struct sockaddr *arg)
398 {
399         struct sockaddr sa;
400         size_t sa_len = sizeof(struct sockaddr);
401         int error;
402         
403         if ((error = copyin(arg, &sa, sa_len)))
404                 return (error);
405         
406         *(u_short *)&sa = sa.sa_family;
407         
408         error = copyout(&sa, arg, sa_len);
409         
410         return (error);
411 }
412
413 static int
414 linux_to_bsd_sockaddr(struct sockaddr *arg, int len)
415 {
416         struct sockaddr sa;
417         size_t sa_len = sizeof(struct sockaddr);
418         int error;
419
420         if ((error = copyin(arg, &sa, sa_len)))
421                 return (error);
422
423         sa.sa_family = *(sa_family_t *)&sa;
424         sa.sa_len = len;
425
426         error = copyout(&sa, arg, sa_len);
427
428         return (error);
429 }
430
431
432 static int
433 linux_sa_put(struct osockaddr *osa)
434 {
435         struct osockaddr sa;
436         int error, bdom;
437
438         /*
439          * Only read/write the osockaddr family part, the rest is
440          * not changed.
441          */
442         error = copyin(osa, &sa, sizeof(sa.sa_family));
443         if (error)
444                 return (error);
445
446         bdom = bsd_to_linux_domain(sa.sa_family);
447         if (bdom == -1)
448                 return (EINVAL);
449
450         sa.sa_family = bdom;
451         error = copyout(&sa, osa, sizeof(sa.sa_family));
452         if (error)
453                 return (error);
454
455         return (0);
456 }
457
458 static int
459 linux_to_bsd_cmsg_type(int cmsg_type)
460 {
461
462         switch (cmsg_type) {
463         case LINUX_SCM_RIGHTS:
464                 return (SCM_RIGHTS);
465         case LINUX_SCM_CREDENTIALS:
466                 return (SCM_CREDS);
467         }
468         return (-1);
469 }
470
471 static int
472 bsd_to_linux_cmsg_type(int cmsg_type)
473 {
474
475         switch (cmsg_type) {
476         case SCM_RIGHTS:
477                 return (LINUX_SCM_RIGHTS);
478         case SCM_CREDS:
479                 return (LINUX_SCM_CREDENTIALS);
480         }
481         return (-1);
482 }
483
484 static int
485 linux_to_bsd_msghdr(struct msghdr *bhdr, const struct l_msghdr *lhdr)
486 {
487         if (lhdr->msg_controllen > INT_MAX)
488                 return (ENOBUFS);
489
490         bhdr->msg_name          = PTRIN(lhdr->msg_name);
491         bhdr->msg_namelen       = lhdr->msg_namelen;
492         bhdr->msg_iov           = PTRIN(lhdr->msg_iov);
493         bhdr->msg_iovlen        = lhdr->msg_iovlen;
494         bhdr->msg_control       = PTRIN(lhdr->msg_control);
495
496         /*
497          * msg_controllen is skipped since BSD and LINUX control messages
498          * are potentially different sizes (e.g. the cred structure used
499          * by SCM_CREDS is different between the two operating system).
500          *
501          * The caller can set it (if necessary) after converting all the
502          * control messages.
503          */
504
505         bhdr->msg_flags         = linux_to_bsd_msg_flags(lhdr->msg_flags);
506         return (0);
507 }
508
509 static int
510 bsd_to_linux_msghdr(const struct msghdr *bhdr, struct l_msghdr *lhdr)
511 {
512         lhdr->msg_name          = PTROUT(bhdr->msg_name);
513         lhdr->msg_namelen       = bhdr->msg_namelen;
514         lhdr->msg_iov           = PTROUT(bhdr->msg_iov);
515         lhdr->msg_iovlen        = bhdr->msg_iovlen;
516         lhdr->msg_control       = PTROUT(bhdr->msg_control);
517
518         /*
519          * msg_controllen is skipped since BSD and LINUX control messages
520          * are potentially different sizes (e.g. the cred structure used
521          * by SCM_CREDS is different between the two operating system).
522          *
523          * The caller can set it (if necessary) after converting all the
524          * control messages.
525          */
526
527         /* msg_flags skipped */
528         return (0);
529 }
530
531 static int
532 linux_set_socket_flags(struct thread *td, int s, int flags)
533 {
534         int error;
535
536         if (flags & LINUX_SOCK_NONBLOCK) {
537                 error = kern_fcntl(td, s, F_SETFL, O_NONBLOCK);
538                 if (error)
539                         return (error);
540         }
541         if (flags & LINUX_SOCK_CLOEXEC) {
542                 error = kern_fcntl(td, s, F_SETFD, FD_CLOEXEC);
543                 if (error)
544                         return (error);
545         }
546         return (0);
547 }
548
549 static int
550 linux_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
551     struct mbuf *control, enum uio_seg segflg)
552 {
553         struct sockaddr *to;
554         int error;
555
556         if (mp->msg_name != NULL) {
557                 error = linux_getsockaddr(&to, mp->msg_name, mp->msg_namelen);
558                 if (error)
559                         return (error);
560                 mp->msg_name = to;
561         } else
562                 to = NULL;
563
564         error = kern_sendit(td, s, mp, linux_to_bsd_msg_flags(flags), control,
565             segflg);
566
567         if (to)
568                 free(to, M_SONAME);
569         return (error);
570 }
571
572 /* Return 0 if IP_HDRINCL is set for the given socket. */
573 static int
574 linux_check_hdrincl(struct thread *td, int s)
575 {
576         int error, optval, size_val;
577
578         size_val = sizeof(optval);
579         error = kern_getsockopt(td, s, IPPROTO_IP, IP_HDRINCL,
580             &optval, UIO_SYSSPACE, &size_val);
581         if (error)
582                 return (error);
583
584         return (optval == 0);
585 }
586
587 struct linux_sendto_args {
588         int s;
589         l_uintptr_t msg;
590         int len;
591         int flags;
592         l_uintptr_t to;
593         int tolen;
594 };
595
596 /*
597  * Updated sendto() when IP_HDRINCL is set:
598  * tweak endian-dependent fields in the IP packet.
599  */
600 static int
601 linux_sendto_hdrincl(struct thread *td, struct linux_sendto_args *linux_args)
602 {
603 /*
604  * linux_ip_copysize defines how many bytes we should copy
605  * from the beginning of the IP packet before we customize it for BSD.
606  * It should include all the fields we modify (ip_len and ip_off).
607  */
608 #define linux_ip_copysize       8
609
610         struct ip *packet;
611         struct msghdr msg;
612         struct iovec aiov[1];
613         int error;
614
615         /* Check that the packet isn't too big or too small. */
616         if (linux_args->len < linux_ip_copysize ||
617             linux_args->len > IP_MAXPACKET)
618                 return (EINVAL);
619
620         packet = (struct ip *)malloc(linux_args->len, M_TEMP, M_WAITOK);
621
622         /* Make kernel copy of the packet to be sent */
623         if ((error = copyin(PTRIN(linux_args->msg), packet,
624             linux_args->len)))
625                 goto goout;
626
627         /* Convert fields from Linux to BSD raw IP socket format */
628         packet->ip_len = linux_args->len;
629         packet->ip_off = ntohs(packet->ip_off);
630
631         /* Prepare the msghdr and iovec structures describing the new packet */
632         msg.msg_name = PTRIN(linux_args->to);
633         msg.msg_namelen = linux_args->tolen;
634         msg.msg_iov = aiov;
635         msg.msg_iovlen = 1;
636         msg.msg_control = NULL;
637         msg.msg_flags = 0;
638         aiov[0].iov_base = (char *)packet;
639         aiov[0].iov_len = linux_args->len;
640         error = linux_sendit(td, linux_args->s, &msg, linux_args->flags,
641             NULL, UIO_SYSSPACE);
642 goout:
643         free(packet, M_TEMP);
644         return (error);
645 }
646
647 struct linux_socket_args {
648         int domain;
649         int type;
650         int protocol;
651 };
652
653 static int
654 linux_socket(struct thread *td, struct linux_socket_args *args)
655 {
656         struct socket_args /* {
657                 int domain;
658                 int type;
659                 int protocol;
660         } */ bsd_args;
661         int retval_socket, socket_flags;
662
663         bsd_args.protocol = args->protocol;
664         socket_flags = args->type & ~LINUX_SOCK_TYPE_MASK;
665         if (socket_flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK))
666                 return (EINVAL);
667         bsd_args.type = args->type & LINUX_SOCK_TYPE_MASK;
668         if (bsd_args.type < 0 || bsd_args.type > LINUX_SOCK_MAX)
669                 return (EINVAL);
670         bsd_args.domain = linux_to_bsd_domain(args->domain);
671         if (bsd_args.domain == -1)
672                 return (EAFNOSUPPORT);
673
674         retval_socket = sys_socket(td, &bsd_args);
675         if (retval_socket)
676                 return (retval_socket);
677
678         retval_socket = linux_set_socket_flags(td, td->td_retval[0],
679             socket_flags);
680         if (retval_socket) {
681                 (void)kern_close(td, td->td_retval[0]);
682                 goto out;
683         }
684
685         if (bsd_args.type == SOCK_RAW
686             && (bsd_args.protocol == IPPROTO_RAW || bsd_args.protocol == 0)
687             && bsd_args.domain == PF_INET) {
688                 /* It's a raw IP socket: set the IP_HDRINCL option. */
689                 int hdrincl;
690
691                 hdrincl = 1;
692                 /* We ignore any error returned by kern_setsockopt() */
693                 kern_setsockopt(td, td->td_retval[0], IPPROTO_IP, IP_HDRINCL,
694                     &hdrincl, UIO_SYSSPACE, sizeof(hdrincl));
695         }
696 #ifdef INET6
697         /*
698          * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by default
699          * and some apps depend on this. So, set V6ONLY to 0 for Linux apps.
700          * For simplicity we do this unconditionally of the net.inet6.ip6.v6only
701          * sysctl value.
702          */
703         if (bsd_args.domain == PF_INET6) {
704                 int v6only;
705
706                 v6only = 0;
707                 /* We ignore any error returned by setsockopt() */
708                 kern_setsockopt(td, td->td_retval[0], IPPROTO_IPV6, IPV6_V6ONLY,
709                     &v6only, UIO_SYSSPACE, sizeof(v6only));
710         }
711 #endif
712
713 out:
714         return (retval_socket);
715 }
716
717 struct linux_bind_args {
718         int s;
719         l_uintptr_t name;
720         int namelen;
721 };
722
723 static int
724 linux_bind(struct thread *td, struct linux_bind_args *args)
725 {
726         struct sockaddr *sa;
727         int error;
728
729         error = linux_getsockaddr(&sa, PTRIN(args->name),
730             args->namelen);
731         if (error)
732                 return (error);
733
734         error = kern_bind(td, args->s, sa);
735         free(sa, M_SONAME);
736         if (error == EADDRNOTAVAIL && args->namelen != sizeof(struct sockaddr_in))
737                 return (EINVAL);
738         return (error);
739 }
740
741 struct linux_connect_args {
742         int s;
743         l_uintptr_t name;
744         int namelen;
745 };
746 int linux_connect(struct thread *, struct linux_connect_args *);
747
748 int
749 linux_connect(struct thread *td, struct linux_connect_args *args)
750 {
751         struct socket *so;
752         struct sockaddr *sa;
753         u_int fflag;
754         int error;
755
756         error = linux_getsockaddr(&sa, (struct osockaddr *)PTRIN(args->name),
757             args->namelen);
758         if (error)
759                 return (error);
760
761         error = kern_connect(td, args->s, sa);
762         free(sa, M_SONAME);
763         if (error != EISCONN)
764                 return (error);
765
766         /*
767          * Linux doesn't return EISCONN the first time it occurs,
768          * when on a non-blocking socket. Instead it returns the
769          * error getsockopt(SOL_SOCKET, SO_ERROR) would return on BSD.
770          *
771          * XXXRW: Instead of using fgetsock(), check that it is a
772          * socket and use the file descriptor reference instead of
773          * creating a new one.
774          */
775         error = fgetsock(td, args->s, CAP_CONNECT, &so, &fflag);
776         if (error == 0) {
777                 error = EISCONN;
778                 if (fflag & FNONBLOCK) {
779                         SOCK_LOCK(so);
780                         if (so->so_emuldata == 0)
781                                 error = so->so_error;
782                         so->so_emuldata = (void *)1;
783                         SOCK_UNLOCK(so);
784                 }
785                 fputsock(so);
786         }
787         return (error);
788 }
789
790 struct linux_listen_args {
791         int s;
792         int backlog;
793 };
794
795 static int
796 linux_listen(struct thread *td, struct linux_listen_args *args)
797 {
798         struct listen_args /* {
799                 int s;
800                 int backlog;
801         } */ bsd_args;
802
803         bsd_args.s = args->s;
804         bsd_args.backlog = args->backlog;
805         return (sys_listen(td, &bsd_args));
806 }
807
808 static int
809 linux_accept_common(struct thread *td, int s, l_uintptr_t addr,
810     l_uintptr_t namelen, int flags)
811 {
812         struct accept_args /* {
813                 int     s;
814                 struct sockaddr * __restrict name;
815                 socklen_t * __restrict anamelen;
816         } */ bsd_args;
817         int error;
818
819         if (flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK))
820                 return (EINVAL);
821
822         bsd_args.s = s;
823         /* XXX: */
824         bsd_args.name = (struct sockaddr * __restrict)PTRIN(addr);
825         bsd_args.anamelen = PTRIN(namelen);/* XXX */
826         error = sys_accept(td, &bsd_args);
827         bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.name);
828         if (error) {
829                 if (error == EFAULT && namelen != sizeof(struct sockaddr_in))
830                         return (EINVAL);
831                 return (error);
832         }
833
834         /*
835          * linux appears not to copy flags from the parent socket to the
836          * accepted one, so we must clear the flags in the new descriptor
837          * and apply the requested flags.
838          */
839         error = kern_fcntl(td, td->td_retval[0], F_SETFL, 0);
840         if (error)
841                 goto out;
842         error = linux_set_socket_flags(td, td->td_retval[0], flags);
843         if (error)
844                 goto out;
845         if (addr)
846                 error = linux_sa_put(PTRIN(addr));
847
848 out:
849         if (error) {
850                 (void)kern_close(td, td->td_retval[0]);
851                 td->td_retval[0] = 0;
852         }
853         return (error);
854 }
855
856 struct linux_accept_args {
857         int s;
858         l_uintptr_t addr;
859         l_uintptr_t namelen;
860 };
861
862 static int
863 linux_accept(struct thread *td, struct linux_accept_args *args)
864 {
865
866         return (linux_accept_common(td, args->s, args->addr,
867             args->namelen, 0));
868 }
869
870 struct linux_accept4_args {
871         int s;
872         l_uintptr_t addr;
873         l_uintptr_t namelen;
874         int flags;
875 };
876
877 static int
878 linux_accept4(struct thread *td, struct linux_accept4_args *args)
879 {
880
881         return (linux_accept_common(td, args->s, args->addr,
882             args->namelen, args->flags));
883 }
884
885 struct linux_getsockname_args {
886         int s;
887         l_uintptr_t addr;
888         l_uintptr_t namelen;
889 };
890
891 static int
892 linux_getsockname(struct thread *td, struct linux_getsockname_args *args)
893 {
894         struct getsockname_args /* {
895                 int     fdes;
896                 struct sockaddr * __restrict asa;
897                 socklen_t * __restrict alen;
898         } */ bsd_args;
899         int error;
900
901         bsd_args.fdes = args->s;
902         /* XXX: */
903         bsd_args.asa = (struct sockaddr * __restrict)PTRIN(args->addr);
904         bsd_args.alen = PTRIN(args->namelen);   /* XXX */
905         error = sys_getsockname(td, &bsd_args);
906         bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.asa);
907         if (error)
908                 return (error);
909         error = linux_sa_put(PTRIN(args->addr));
910         if (error)
911                 return (error);
912         return (0);
913 }
914
915 struct linux_getpeername_args {
916         int s;
917         l_uintptr_t addr;
918         l_uintptr_t namelen;
919 };
920
921 static int
922 linux_getpeername(struct thread *td, struct linux_getpeername_args *args)
923 {
924         struct getpeername_args /* {
925                 int fdes;
926                 caddr_t asa;
927                 int *alen;
928         } */ bsd_args;
929         int error;
930
931         bsd_args.fdes = args->s;
932         bsd_args.asa = (struct sockaddr *)PTRIN(args->addr);
933         bsd_args.alen = (int *)PTRIN(args->namelen);
934         error = sys_getpeername(td, &bsd_args);
935         bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.asa);
936         if (error)
937                 return (error);
938         error = linux_sa_put(PTRIN(args->addr));
939         if (error)
940                 return (error);
941         return (0);
942 }
943
944 struct linux_socketpair_args {
945         int domain;
946         int type;
947         int protocol;
948         l_uintptr_t rsv;
949 };
950
951 static int
952 linux_socketpair(struct thread *td, struct linux_socketpair_args *args)
953 {
954         struct socketpair_args /* {
955                 int domain;
956                 int type;
957                 int protocol;
958                 int *rsv;
959         } */ bsd_args;
960         int error, socket_flags;
961         int sv[2];
962
963         bsd_args.domain = linux_to_bsd_domain(args->domain);
964         if (bsd_args.domain != PF_LOCAL)
965                 return (EAFNOSUPPORT);
966
967         socket_flags = args->type & ~LINUX_SOCK_TYPE_MASK;
968         if (socket_flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK))
969                 return (EINVAL);
970         bsd_args.type = args->type & LINUX_SOCK_TYPE_MASK;
971         if (bsd_args.type < 0 || bsd_args.type > LINUX_SOCK_MAX)
972                 return (EINVAL);
973
974         if (args->protocol != 0 && args->protocol != PF_UNIX)
975
976                 /*
977                  * Use of PF_UNIX as protocol argument is not right,
978                  * but Linux does it.
979                  * Do not map PF_UNIX as its Linux value is identical
980                  * to FreeBSD one.
981                  */
982                 return (EPROTONOSUPPORT);
983         else
984                 bsd_args.protocol = 0;
985         bsd_args.rsv = (int *)PTRIN(args->rsv);
986         error = kern_socketpair(td, bsd_args.domain, bsd_args.type,
987             bsd_args.protocol, sv);
988         if (error)
989                 return (error);
990         error = linux_set_socket_flags(td, sv[0], socket_flags);
991         if (error)
992                 goto out;
993         error = linux_set_socket_flags(td, sv[1], socket_flags);
994         if (error)
995                 goto out;
996
997         error = copyout(sv, bsd_args.rsv, 2 * sizeof(int));
998
999 out:
1000         if (error) {
1001                 (void)kern_close(td, sv[0]);
1002                 (void)kern_close(td, sv[1]);
1003         }
1004         return (error);
1005 }
1006
1007 struct linux_send_args {
1008         int s;
1009         l_uintptr_t msg;
1010         int len;
1011         int flags;
1012 };
1013
1014 static int
1015 linux_send(struct thread *td, struct linux_send_args *args)
1016 {
1017         struct sendto_args /* {
1018                 int s;
1019                 caddr_t buf;
1020                 int len;
1021                 int flags;
1022                 caddr_t to;
1023                 int tolen;
1024         } */ bsd_args;
1025
1026         bsd_args.s = args->s;
1027         bsd_args.buf = (caddr_t)PTRIN(args->msg);
1028         bsd_args.len = args->len;
1029         bsd_args.flags = args->flags;
1030         bsd_args.to = NULL;
1031         bsd_args.tolen = 0;
1032         return sys_sendto(td, &bsd_args);
1033 }
1034
1035 struct linux_recv_args {
1036         int s;
1037         l_uintptr_t msg;
1038         int len;
1039         int flags;
1040 };
1041
1042 static int
1043 linux_recv(struct thread *td, struct linux_recv_args *args)
1044 {
1045         struct recvfrom_args /* {
1046                 int s;
1047                 caddr_t buf;
1048                 int len;
1049                 int flags;
1050                 struct sockaddr *from;
1051                 socklen_t fromlenaddr;
1052         } */ bsd_args;
1053
1054         bsd_args.s = args->s;
1055         bsd_args.buf = (caddr_t)PTRIN(args->msg);
1056         bsd_args.len = args->len;
1057         bsd_args.flags = linux_to_bsd_msg_flags(args->flags);
1058         bsd_args.from = NULL;
1059         bsd_args.fromlenaddr = 0;
1060         return (sys_recvfrom(td, &bsd_args));
1061 }
1062
1063 static int
1064 linux_sendto(struct thread *td, struct linux_sendto_args *args)
1065 {
1066         struct msghdr msg;
1067         struct iovec aiov;
1068         int error;
1069
1070         if (linux_check_hdrincl(td, args->s) == 0)
1071                 /* IP_HDRINCL set, tweak the packet before sending */
1072                 return (linux_sendto_hdrincl(td, args));
1073
1074         msg.msg_name = PTRIN(args->to);
1075         msg.msg_namelen = args->tolen;
1076         msg.msg_iov = &aiov;
1077         msg.msg_iovlen = 1;
1078         msg.msg_control = NULL;
1079         msg.msg_flags = 0;
1080         aiov.iov_base = PTRIN(args->msg);
1081         aiov.iov_len = args->len;
1082         error = linux_sendit(td, args->s, &msg, args->flags, NULL,
1083             UIO_USERSPACE);
1084         return (error);
1085 }
1086
1087 struct linux_recvfrom_args {
1088         int s;
1089         l_uintptr_t buf;
1090         int len;
1091         int flags;
1092         l_uintptr_t from;
1093         l_uintptr_t fromlen;
1094 };
1095
1096 static int
1097 linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args)
1098 {
1099         struct recvfrom_args /* {
1100                 int     s;
1101                 caddr_t buf;
1102                 size_t  len;
1103                 int     flags;
1104                 struct sockaddr * __restrict from;
1105                 socklen_t * __restrict fromlenaddr;
1106         } */ bsd_args;
1107         size_t len;
1108         int error;
1109
1110         if ((error = copyin(PTRIN(args->fromlen), &len, sizeof(size_t))))
1111                 return (error);
1112
1113         bsd_args.s = args->s;
1114         bsd_args.buf = PTRIN(args->buf);
1115         bsd_args.len = args->len;
1116         bsd_args.flags = linux_to_bsd_msg_flags(args->flags);
1117         /* XXX: */
1118         bsd_args.from = (struct sockaddr * __restrict)PTRIN(args->from);
1119         bsd_args.fromlenaddr = PTRIN(args->fromlen);/* XXX */
1120         
1121         linux_to_bsd_sockaddr((struct sockaddr *)bsd_args.from, len);
1122         error = sys_recvfrom(td, &bsd_args);
1123         bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.from);
1124         
1125         if (error)
1126                 return (error);
1127         if (args->from) {
1128                 error = linux_sa_put((struct osockaddr *)
1129                     PTRIN(args->from));
1130                 if (error)
1131                         return (error);
1132         }
1133         return (0);
1134 }
1135
1136 struct linux_sendmsg_args {
1137         int s;
1138         l_uintptr_t msg;
1139         int flags;
1140 };
1141
1142 static int
1143 linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args)
1144 {
1145         struct cmsghdr *cmsg;
1146         struct cmsgcred cmcred;
1147         struct mbuf *control;
1148         struct msghdr msg;
1149         struct l_cmsghdr linux_cmsg;
1150         struct l_cmsghdr *ptr_cmsg;
1151         struct l_msghdr linux_msg;
1152         struct iovec *iov;
1153         socklen_t datalen;
1154         struct sockaddr *sa;
1155         sa_family_t sa_family;
1156         void *data;
1157         int error;
1158
1159         error = copyin(PTRIN(args->msg), &linux_msg, sizeof(linux_msg));
1160         if (error)
1161                 return (error);
1162
1163         /*
1164          * Some Linux applications (ping) define a non-NULL control data
1165          * pointer, but a msg_controllen of 0, which is not allowed in the
1166          * FreeBSD system call interface.  NULL the msg_control pointer in
1167          * order to handle this case.  This should be checked, but allows the
1168          * Linux ping to work.
1169          */
1170         if (PTRIN(linux_msg.msg_control) != NULL && linux_msg.msg_controllen == 0)
1171                 linux_msg.msg_control = PTROUT(NULL);
1172
1173         error = linux_to_bsd_msghdr(&msg, &linux_msg);
1174         if (error)
1175                 return (error);
1176
1177 #ifdef COMPAT_LINUX32
1178         error = linux32_copyiniov(PTRIN(msg.msg_iov), msg.msg_iovlen,
1179             &iov, EMSGSIZE);
1180 #else
1181         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
1182 #endif
1183         if (error)
1184                 return (error);
1185
1186         control = NULL;
1187         cmsg = NULL;
1188
1189         if ((ptr_cmsg = LINUX_CMSG_FIRSTHDR(&linux_msg)) != NULL) {
1190                 error = kern_getsockname(td, args->s, &sa, &datalen);
1191                 if (error)
1192                         goto bad;
1193                 sa_family = sa->sa_family;
1194                 free(sa, M_SONAME);
1195
1196                 error = ENOBUFS;
1197                 cmsg = malloc(CMSG_HDRSZ, M_TEMP, M_WAITOK | M_ZERO);
1198                 control = m_get(M_WAIT, MT_CONTROL);
1199                 if (control == NULL)
1200                         goto bad;
1201
1202                 do {
1203                         error = copyin(ptr_cmsg, &linux_cmsg,
1204                             sizeof(struct l_cmsghdr));
1205                         if (error)
1206                                 goto bad;
1207
1208                         error = EINVAL;
1209                         if (linux_cmsg.cmsg_len < sizeof(struct l_cmsghdr))
1210                                 goto bad;
1211
1212                         /*
1213                          * Now we support only SCM_RIGHTS and SCM_CRED,
1214                          * so return EINVAL in any other cmsg_type
1215                          */
1216                         cmsg->cmsg_type =
1217                             linux_to_bsd_cmsg_type(linux_cmsg.cmsg_type);
1218                         cmsg->cmsg_level =
1219                             linux_to_bsd_sockopt_level(linux_cmsg.cmsg_level);
1220                         if (cmsg->cmsg_type == -1
1221                             || cmsg->cmsg_level != SOL_SOCKET)
1222                                 goto bad;
1223
1224                         /*
1225                          * Some applications (e.g. pulseaudio) attempt to
1226                          * send ancillary data even if the underlying protocol
1227                          * doesn't support it which is not allowed in the
1228                          * FreeBSD system call interface.
1229                          */
1230                         if (sa_family != AF_UNIX)
1231                                 continue;
1232
1233                         data = LINUX_CMSG_DATA(ptr_cmsg);
1234                         datalen = linux_cmsg.cmsg_len - L_CMSG_HDRSZ;
1235
1236                         switch (cmsg->cmsg_type)
1237                         {
1238                         case SCM_RIGHTS:
1239                                 break;
1240
1241                         case SCM_CREDS:
1242                                 data = &cmcred;
1243                                 datalen = sizeof(cmcred);
1244
1245                                 /*
1246                                  * The lower levels will fill in the structure
1247                                  */
1248                                 bzero(data, datalen);
1249                                 break;
1250                         }
1251
1252                         cmsg->cmsg_len = CMSG_LEN(datalen);
1253
1254                         error = ENOBUFS;
1255                         if (!m_append(control, CMSG_HDRSZ, (c_caddr_t)cmsg))
1256                                 goto bad;
1257                         if (!m_append(control, datalen, (c_caddr_t)data))
1258                                 goto bad;
1259                 } while ((ptr_cmsg = LINUX_CMSG_NXTHDR(&linux_msg, ptr_cmsg)));
1260
1261                 if (m_length(control, NULL) == 0) {
1262                         m_freem(control);
1263                         control = NULL;
1264                 }
1265         }
1266
1267         msg.msg_iov = iov;
1268         msg.msg_flags = 0;
1269         error = linux_sendit(td, args->s, &msg, args->flags, control,
1270             UIO_USERSPACE);
1271
1272 bad:
1273         free(iov, M_IOV);
1274         if (cmsg)
1275                 free(cmsg, M_TEMP);
1276         return (error);
1277 }
1278
1279 struct linux_recvmsg_args {
1280         int s;
1281         l_uintptr_t msg;
1282         int flags;
1283 };
1284
1285 static int
1286 linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args)
1287 {
1288         struct cmsghdr *cm;
1289         struct cmsgcred *cmcred;
1290         struct msghdr msg;
1291         struct l_cmsghdr *linux_cmsg = NULL;
1292         struct l_ucred linux_ucred;
1293         socklen_t datalen, outlen;
1294         struct l_msghdr linux_msg;
1295         struct iovec *iov, *uiov;
1296         struct mbuf *control = NULL;
1297         struct mbuf **controlp;
1298         caddr_t outbuf;
1299         void *data;
1300         int error, i, fd, fds, *fdp;
1301
1302         error = copyin(PTRIN(args->msg), &linux_msg, sizeof(linux_msg));
1303         if (error)
1304                 return (error);
1305
1306         error = linux_to_bsd_msghdr(&msg, &linux_msg);
1307         if (error)
1308                 return (error);
1309
1310 #ifdef COMPAT_LINUX32
1311         error = linux32_copyiniov(PTRIN(msg.msg_iov), msg.msg_iovlen,
1312             &iov, EMSGSIZE);
1313 #else
1314         error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
1315 #endif
1316         if (error)
1317                 return (error);
1318
1319         if (msg.msg_name) {
1320                 error = linux_to_bsd_sockaddr((struct sockaddr *)msg.msg_name,
1321                     msg.msg_namelen);
1322                 if (error)
1323                         goto bad;
1324         }
1325
1326         uiov = msg.msg_iov;
1327         msg.msg_iov = iov;
1328         controlp = (msg.msg_control != NULL) ? &control : NULL;
1329         error = kern_recvit(td, args->s, &msg, UIO_USERSPACE, controlp);
1330         msg.msg_iov = uiov;
1331         if (error)
1332                 goto bad;
1333
1334         error = bsd_to_linux_msghdr(&msg, &linux_msg);
1335         if (error)
1336                 goto bad;
1337
1338         if (linux_msg.msg_name) {
1339                 error = bsd_to_linux_sockaddr((struct sockaddr *)
1340                     PTRIN(linux_msg.msg_name));
1341                 if (error)
1342                         goto bad;
1343         }
1344         if (linux_msg.msg_name && linux_msg.msg_namelen > 2) {
1345                 error = linux_sa_put(PTRIN(linux_msg.msg_name));
1346                 if (error)
1347                         goto bad;
1348         }
1349
1350         outbuf = PTRIN(linux_msg.msg_control);
1351         outlen = 0;
1352
1353         if (control) {
1354                 linux_cmsg = malloc(L_CMSG_HDRSZ, M_TEMP, M_WAITOK | M_ZERO);
1355
1356                 msg.msg_control = mtod(control, struct cmsghdr *);
1357                 msg.msg_controllen = control->m_len;
1358
1359                 cm = CMSG_FIRSTHDR(&msg);
1360
1361                 while (cm != NULL) {
1362                         linux_cmsg->cmsg_type =
1363                             bsd_to_linux_cmsg_type(cm->cmsg_type);
1364                         linux_cmsg->cmsg_level =
1365                             bsd_to_linux_sockopt_level(cm->cmsg_level);
1366                         if (linux_cmsg->cmsg_type == -1
1367                             || cm->cmsg_level != SOL_SOCKET)
1368                         {
1369                                 error = EINVAL;
1370                                 goto bad;
1371                         }
1372
1373                         data = CMSG_DATA(cm);
1374                         datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
1375
1376                         switch (cm->cmsg_type)
1377                         {
1378                         case SCM_RIGHTS:
1379                                 if (args->flags & LINUX_MSG_CMSG_CLOEXEC) {
1380                                         fds = datalen / sizeof(int);
1381                                         fdp = data;
1382                                         for (i = 0; i < fds; i++) {
1383                                                 fd = *fdp++;
1384                                                 (void)kern_fcntl(td, fd,
1385                                                     F_SETFD, FD_CLOEXEC);
1386                                         }
1387                                 }
1388                                 break;
1389
1390                         case SCM_CREDS:
1391                                 /*
1392                                  * Currently LOCAL_CREDS is never in
1393                                  * effect for Linux so no need to worry
1394                                  * about sockcred
1395                                  */
1396                                 if (datalen != sizeof(*cmcred)) {
1397                                         error = EMSGSIZE;
1398                                         goto bad;
1399                                 }
1400                                 cmcred = (struct cmsgcred *)data;
1401                                 bzero(&linux_ucred, sizeof(linux_ucred));
1402                                 linux_ucred.pid = cmcred->cmcred_pid;
1403                                 linux_ucred.uid = cmcred->cmcred_uid;
1404                                 linux_ucred.gid = cmcred->cmcred_gid;
1405                                 data = &linux_ucred;
1406                                 datalen = sizeof(linux_ucred);
1407                                 break;
1408                         }
1409
1410                         if (outlen + LINUX_CMSG_LEN(datalen) >
1411                             linux_msg.msg_controllen) {
1412                                 if (outlen == 0) {
1413                                         error = EMSGSIZE;
1414                                         goto bad;
1415                                 } else {
1416                                         linux_msg.msg_flags |=
1417                                             LINUX_MSG_CTRUNC;
1418                                         goto out;
1419                                 }
1420                         }
1421
1422                         linux_cmsg->cmsg_len = LINUX_CMSG_LEN(datalen);
1423
1424                         error = copyout(linux_cmsg, outbuf, L_CMSG_HDRSZ);
1425                         if (error)
1426                                 goto bad;
1427                         outbuf += L_CMSG_HDRSZ;
1428
1429                         error = copyout(data, outbuf, datalen);
1430                         if (error)
1431                                 goto bad;
1432
1433                         outbuf += LINUX_CMSG_ALIGN(datalen);
1434                         outlen += LINUX_CMSG_LEN(datalen);
1435
1436                         cm = CMSG_NXTHDR(&msg, cm);
1437                 }
1438         }
1439
1440 out:
1441         linux_msg.msg_controllen = outlen;
1442         error = copyout(&linux_msg, PTRIN(args->msg), sizeof(linux_msg));
1443
1444 bad:
1445         free(iov, M_IOV);
1446         if (control != NULL)
1447                 m_freem(control);
1448         if (linux_cmsg != NULL)
1449                 free(linux_cmsg, M_TEMP);
1450
1451         return (error);
1452 }
1453
1454 struct linux_shutdown_args {
1455         int s;
1456         int how;
1457 };
1458
1459 static int
1460 linux_shutdown(struct thread *td, struct linux_shutdown_args *args)
1461 {
1462         struct shutdown_args /* {
1463                 int s;
1464                 int how;
1465         } */ bsd_args;
1466
1467         bsd_args.s = args->s;
1468         bsd_args.how = args->how;
1469         return (sys_shutdown(td, &bsd_args));
1470 }
1471
1472 struct linux_setsockopt_args {
1473         int s;
1474         int level;
1475         int optname;
1476         l_uintptr_t optval;
1477         int optlen;
1478 };
1479
1480 static int
1481 linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args)
1482 {
1483         struct setsockopt_args /* {
1484                 int s;
1485                 int level;
1486                 int name;
1487                 caddr_t val;
1488                 int valsize;
1489         } */ bsd_args;
1490         l_timeval linux_tv;
1491         struct timeval tv;
1492         int error, name;
1493
1494         bsd_args.s = args->s;
1495         bsd_args.level = linux_to_bsd_sockopt_level(args->level);
1496         switch (bsd_args.level) {
1497         case SOL_SOCKET:
1498                 name = linux_to_bsd_so_sockopt(args->optname);
1499                 switch (name) {
1500                 case SO_RCVTIMEO:
1501                         /* FALLTHROUGH */
1502                 case SO_SNDTIMEO:
1503                         error = copyin(PTRIN(args->optval), &linux_tv,
1504                             sizeof(linux_tv));
1505                         if (error)
1506                                 return (error);
1507                         tv.tv_sec = linux_tv.tv_sec;
1508                         tv.tv_usec = linux_tv.tv_usec;
1509                         return (kern_setsockopt(td, args->s, bsd_args.level,
1510                             name, &tv, UIO_SYSSPACE, sizeof(tv)));
1511                         /* NOTREACHED */
1512                         break;
1513                 default:
1514                         break;
1515                 }
1516                 break;
1517         case IPPROTO_IP:
1518                 name = linux_to_bsd_ip_sockopt(args->optname);
1519                 break;
1520         case IPPROTO_TCP:
1521                 name = linux_to_bsd_tcp_sockopt(args->optname);
1522                 break;
1523         default:
1524                 name = -1;
1525                 break;
1526         }
1527         if (name == -1)
1528                 return (ENOPROTOOPT);
1529
1530         bsd_args.name = name;
1531         bsd_args.val = PTRIN(args->optval);
1532         bsd_args.valsize = args->optlen;
1533
1534         if (name == IPV6_NEXTHOP) {
1535                 linux_to_bsd_sockaddr((struct sockaddr *)bsd_args.val,
1536                         bsd_args.valsize);
1537                 error = sys_setsockopt(td, &bsd_args);
1538                 bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.val);
1539         } else
1540                 error = sys_setsockopt(td, &bsd_args);
1541
1542         return (error);
1543 }
1544
1545 struct linux_getsockopt_args {
1546         int s;
1547         int level;
1548         int optname;
1549         l_uintptr_t optval;
1550         l_uintptr_t optlen;
1551 };
1552
1553 static int
1554 linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
1555 {
1556         struct getsockopt_args /* {
1557                 int s;
1558                 int level;
1559                 int name;
1560                 caddr_t val;
1561                 int *avalsize;
1562         } */ bsd_args;
1563         l_timeval linux_tv;
1564         struct timeval tv;
1565         socklen_t tv_len, xulen;
1566         struct xucred xu;
1567         struct l_ucred lxu;
1568         int error, name;
1569
1570         bsd_args.s = args->s;
1571         bsd_args.level = linux_to_bsd_sockopt_level(args->level);
1572         switch (bsd_args.level) {
1573         case SOL_SOCKET:
1574                 name = linux_to_bsd_so_sockopt(args->optname);
1575                 switch (name) {
1576                 case SO_RCVTIMEO:
1577                         /* FALLTHROUGH */
1578                 case SO_SNDTIMEO:
1579                         tv_len = sizeof(tv);
1580                         error = kern_getsockopt(td, args->s, bsd_args.level,
1581                             name, &tv, UIO_SYSSPACE, &tv_len);
1582                         if (error)
1583                                 return (error);
1584                         linux_tv.tv_sec = tv.tv_sec;
1585                         linux_tv.tv_usec = tv.tv_usec;
1586                         return (copyout(&linux_tv, PTRIN(args->optval),
1587                             sizeof(linux_tv)));
1588                         /* NOTREACHED */
1589                         break;
1590                 case LOCAL_PEERCRED:
1591                         if (args->optlen != sizeof(lxu))
1592                                 return (EINVAL);
1593                         xulen = sizeof(xu);
1594                         error = kern_getsockopt(td, args->s, bsd_args.level,
1595                             name, &xu, UIO_SYSSPACE, &xulen);
1596                         if (error)
1597                                 return (error);
1598                         /*
1599                          * XXX Use 0 for pid as the FreeBSD does not cache peer pid.
1600                          */
1601                         lxu.pid = 0;
1602                         lxu.uid = xu.cr_uid;
1603                         lxu.gid = xu.cr_gid;
1604                         return (copyout(&lxu, PTRIN(args->optval), sizeof(lxu)));
1605                         /* NOTREACHED */
1606                         break;
1607                 default:
1608                         break;
1609                 }
1610                 break;
1611         case IPPROTO_IP:
1612                 name = linux_to_bsd_ip_sockopt(args->optname);
1613                 break;
1614         case IPPROTO_TCP:
1615                 name = linux_to_bsd_tcp_sockopt(args->optname);
1616                 break;
1617         default:
1618                 name = -1;
1619                 break;
1620         }
1621         if (name == -1)
1622                 return (EINVAL);
1623
1624         bsd_args.name = name;
1625         bsd_args.val = PTRIN(args->optval);
1626         bsd_args.avalsize = PTRIN(args->optlen);
1627
1628         if (name == IPV6_NEXTHOP) {
1629                 error = sys_getsockopt(td, &bsd_args);
1630                 bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.val);
1631         } else
1632                 error = sys_getsockopt(td, &bsd_args);
1633
1634         return (error);
1635 }
1636
1637 /* Argument list sizes for linux_socketcall */
1638
1639 #define LINUX_AL(x) ((x) * sizeof(l_ulong))
1640
1641 static const unsigned char lxs_args[] = {
1642         LINUX_AL(0) /* unused*/,        LINUX_AL(3) /* socket */,
1643         LINUX_AL(3) /* bind */,         LINUX_AL(3) /* connect */,
1644         LINUX_AL(2) /* listen */,       LINUX_AL(3) /* accept */,
1645         LINUX_AL(3) /* getsockname */,  LINUX_AL(3) /* getpeername */,
1646         LINUX_AL(4) /* socketpair */,   LINUX_AL(4) /* send */,
1647         LINUX_AL(4) /* recv */,         LINUX_AL(6) /* sendto */,
1648         LINUX_AL(6) /* recvfrom */,     LINUX_AL(2) /* shutdown */,
1649         LINUX_AL(5) /* setsockopt */,   LINUX_AL(5) /* getsockopt */,
1650         LINUX_AL(3) /* sendmsg */,      LINUX_AL(3) /* recvmsg */,
1651         LINUX_AL(4) /* accept4 */
1652 };
1653
1654 #define LINUX_AL_SIZE   sizeof(lxs_args) / sizeof(lxs_args[0]) - 1
1655
1656 int
1657 linux_socketcall(struct thread *td, struct linux_socketcall_args *args)
1658 {
1659         l_ulong a[6];
1660         void *arg;
1661         int error;
1662
1663         if (args->what < LINUX_SOCKET || args->what > LINUX_AL_SIZE)
1664                 return (EINVAL);
1665         error = copyin(PTRIN(args->args), a, lxs_args[args->what]);
1666         if (error)
1667                 return (error);
1668
1669         arg = a;
1670         switch (args->what) {
1671         case LINUX_SOCKET:
1672                 return (linux_socket(td, arg));
1673         case LINUX_BIND:
1674                 return (linux_bind(td, arg));
1675         case LINUX_CONNECT:
1676                 return (linux_connect(td, arg));
1677         case LINUX_LISTEN:
1678                 return (linux_listen(td, arg));
1679         case LINUX_ACCEPT:
1680                 return (linux_accept(td, arg));
1681         case LINUX_GETSOCKNAME:
1682                 return (linux_getsockname(td, arg));
1683         case LINUX_GETPEERNAME:
1684                 return (linux_getpeername(td, arg));
1685         case LINUX_SOCKETPAIR:
1686                 return (linux_socketpair(td, arg));
1687         case LINUX_SEND:
1688                 return (linux_send(td, arg));
1689         case LINUX_RECV:
1690                 return (linux_recv(td, arg));
1691         case LINUX_SENDTO:
1692                 return (linux_sendto(td, arg));
1693         case LINUX_RECVFROM:
1694                 return (linux_recvfrom(td, arg));
1695         case LINUX_SHUTDOWN:
1696                 return (linux_shutdown(td, arg));
1697         case LINUX_SETSOCKOPT:
1698                 return (linux_setsockopt(td, arg));
1699         case LINUX_GETSOCKOPT:
1700                 return (linux_getsockopt(td, arg));
1701         case LINUX_SENDMSG:
1702                 return (linux_sendmsg(td, arg));
1703         case LINUX_RECVMSG:
1704                 return (linux_recvmsg(td, arg));
1705         case LINUX_ACCEPT4:
1706                 return (linux_accept4(td, arg));
1707         }
1708
1709         uprintf("LINUX: 'socket' typ=%d not implemented\n", args->what);
1710         return (ENOSYS);
1711 }