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/fcntl.h> 41 #include <sys/file.h> 42 #include <sys/limits.h> 43 #include <sys/lock.h> 44 #include <sys/malloc.h> 45 #include <sys/mutex.h> 46 #include <sys/mbuf.h> 47 #include <sys/socket.h> 48 #include <sys/socketvar.h> 49 #include <sys/syscallsubr.h> 50 #include <sys/uio.h> 51 #include <sys/syslog.h> 52 #include <sys/un.h> 53 54 #include <netinet/in.h> 55 #include <netinet/in_systm.h> 56 #include <netinet/ip.h> 57 #ifdef INET6 58 #include <netinet/ip6.h> 59 #include <netinet6/ip6_var.h> 60 #endif 61 62 #ifdef COMPAT_LINUX32 63 #include <machine/../linux32/linux.h> 64 #include <machine/../linux32/linux32_proto.h> 65 #else 66 #include <machine/../linux/linux.h> 67 #include <machine/../linux/linux_proto.h> 68 #endif 69 #include <compat/linux/linux_socket.h> 70 #include <compat/linux/linux_util.h> 71 72 static int do_sa_get(struct sockaddr **, const struct osockaddr *, int *, 73 struct malloc_type *); 74 static int linux_to_bsd_domain(int); 75 76 /* 77 * Reads a linux sockaddr and does any necessary translation. 78 * Linux sockaddrs don't have a length field, only a family. 79 */ 80 static int 81 linux_getsockaddr(struct sockaddr **sap, const struct osockaddr *osa, int len) 82 { 83 int osalen = len; 84 85 return (do_sa_get(sap, osa, &osalen, M_SONAME)); 86 } 87 88 /* 89 * Copy the osockaddr structure pointed to by osa to kernel, adjust 90 * family and convert to sockaddr. 91 */ 92 static int 93 do_sa_get(struct sockaddr **sap, const struct osockaddr *osa, int *osalen, 94 struct malloc_type *mtype) 95 { 96 int error=0, bdom; 97 struct sockaddr *sa; 98 struct osockaddr *kosa; 99 int alloclen; 100 #ifdef INET6 101 int oldv6size; 102 struct sockaddr_in6 *sin6; 103 #endif 104 105 if (*osalen < 2 || *osalen > UCHAR_MAX || !osa) 106 return (EINVAL); 107 108 alloclen = *osalen; 109 #ifdef INET6 110 oldv6size = 0; 111 /* 112 * Check for old (pre-RFC2553) sockaddr_in6. We may accept it 113 * if it's a v4-mapped address, so reserve the proper space 114 * for it. 115 */ 116 if (alloclen == sizeof (struct sockaddr_in6) - sizeof (u_int32_t)) { 117 alloclen = sizeof (struct sockaddr_in6); 118 oldv6size = 1; 119 } 120 #endif 121 122 MALLOC(kosa, struct osockaddr *, alloclen, mtype, M_WAITOK); 123 124 if ((error = copyin(osa, kosa, *osalen))) 125 goto out; 126 127 bdom = linux_to_bsd_domain(kosa->sa_family); 128 if (bdom == -1) { 129 error = EINVAL; 130 goto out; 131 } 132 133 #ifdef INET6 134 /* 135 * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6, 136 * which lacks the scope id compared with RFC2553 one. If we detect 137 * the situation, reject the address and write a message to system log. 138 * 139 * Still accept addresses for which the scope id is not used. 140 */ 141 if (oldv6size && bdom == AF_INET6) { 142 sin6 = (struct sockaddr_in6 *)kosa; 143 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) || 144 (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) && 145 !IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) && 146 !IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) && 147 !IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) && 148 !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) { 149 sin6->sin6_scope_id = 0; 150 } else { 151 log(LOG_DEBUG, 152 "obsolete pre-RFC2553 sockaddr_in6 rejected\n"); 153 error = EINVAL; 154 goto out; 155 } 156 } else 157 #endif 158 if (bdom == AF_INET) 159 alloclen = sizeof(struct sockaddr_in); 160 161 sa = (struct sockaddr *) kosa; 162 sa->sa_family = bdom; 163 sa->sa_len = alloclen; 164 165 *sap = sa; 166 *osalen = alloclen; 167 return (0); 168 169 out: 170 FREE(kosa, mtype); 171 return (error); 172 } 173 174 static int 175 linux_to_bsd_domain(int domain) 176 { 177 178 switch (domain) { 179 case LINUX_AF_UNSPEC: 180 return (AF_UNSPEC); 181 case LINUX_AF_UNIX: 182 return (AF_LOCAL); 183 case LINUX_AF_INET: 184 return (AF_INET); 185 case LINUX_AF_INET6: 186 return (AF_INET6); 187 case LINUX_AF_AX25: 188 return (AF_CCITT); 189 case LINUX_AF_IPX: 190 return (AF_IPX); 191 case LINUX_AF_APPLETALK: 192 return (AF_APPLETALK); 193 } 194 return (-1); 195 } 196 197 static int 198 bsd_to_linux_domain(int domain) 199 { 200 201 switch (domain) { 202 case AF_UNSPEC: 203 return (LINUX_AF_UNSPEC); 204 case AF_LOCAL: 205 return (LINUX_AF_UNIX); 206 case AF_INET: 207 return (LINUX_AF_INET); 208 case AF_INET6: 209 return (LINUX_AF_INET6); 210 case AF_CCITT: 211 return (LINUX_AF_AX25); 212 case AF_IPX: 213 return (LINUX_AF_IPX); 214 case AF_APPLETALK: 215 return (LINUX_AF_APPLETALK); 216 } 217 return (-1); 218 } 219 220 static int 221 linux_to_bsd_sockopt_level(int level) 222 { 223 224 switch (level) { 225 case LINUX_SOL_SOCKET: 226 return (SOL_SOCKET); 227 } 228 return (level); 229 } 230 231 static int 232 bsd_to_linux_sockopt_level(int level) 233 { 234 235 switch (level) { 236 case SOL_SOCKET: 237 return (LINUX_SOL_SOCKET); 238 } 239 return (level); 240 } 241 242 static int 243 linux_to_bsd_ip_sockopt(int opt) 244 { 245 246 switch (opt) { 247 case LINUX_IP_TOS: 248 return (IP_TOS); 249 case LINUX_IP_TTL: 250 return (IP_TTL); 251 case LINUX_IP_OPTIONS: 252 return (IP_OPTIONS); 253 case LINUX_IP_MULTICAST_IF: 254 return (IP_MULTICAST_IF); 255 case LINUX_IP_MULTICAST_TTL: 256 return (IP_MULTICAST_TTL); 257 case LINUX_IP_MULTICAST_LOOP: 258 return (IP_MULTICAST_LOOP); 259 case LINUX_IP_ADD_MEMBERSHIP: 260 return (IP_ADD_MEMBERSHIP); 261 case LINUX_IP_DROP_MEMBERSHIP: 262 return (IP_DROP_MEMBERSHIP); 263 case LINUX_IP_HDRINCL: 264 return (IP_HDRINCL); 265 } 266 return (-1); 267 } 268 269 static int 270 linux_to_bsd_so_sockopt(int opt) 271 { 272 273 switch (opt) { 274 case LINUX_SO_DEBUG: 275 return (SO_DEBUG); 276 case LINUX_SO_REUSEADDR: 277 return (SO_REUSEADDR); 278 case LINUX_SO_TYPE: 279 return (SO_TYPE); 280 case LINUX_SO_ERROR: 281 return (SO_ERROR); 282 case LINUX_SO_DONTROUTE: 283 return (SO_DONTROUTE); 284 case LINUX_SO_BROADCAST: 285 return (SO_BROADCAST); 286 case LINUX_SO_SNDBUF: 287 return (SO_SNDBUF); 288 case LINUX_SO_RCVBUF: 289 return (SO_RCVBUF); 290 case LINUX_SO_KEEPALIVE: 291 return (SO_KEEPALIVE); 292 case LINUX_SO_OOBINLINE: 293 return (SO_OOBINLINE); 294 case LINUX_SO_LINGER: 295 return (SO_LINGER); 296 case LINUX_SO_PEERCRED: 297 return (LOCAL_PEERCRED); 298 case LINUX_SO_RCVLOWAT: 299 return (SO_RCVLOWAT); 300 case LINUX_SO_SNDLOWAT: 301 return (SO_SNDLOWAT); 302 case LINUX_SO_RCVTIMEO: 303 return (SO_RCVTIMEO); 304 case LINUX_SO_SNDTIMEO: 305 return (SO_SNDTIMEO); 306 case LINUX_SO_TIMESTAMP: 307 return (SO_TIMESTAMP); 308 case LINUX_SO_ACCEPTCONN: 309 return (SO_ACCEPTCONN); 310 } 311 return (-1); 312 } 313 314 static int 315 linux_to_bsd_msg_flags(int flags) 316 { 317 int ret_flags = 0; 318 319 if (flags & LINUX_MSG_OOB) 320 ret_flags |= MSG_OOB; 321 if (flags & LINUX_MSG_PEEK) 322 ret_flags |= MSG_PEEK; 323 if (flags & LINUX_MSG_DONTROUTE) 324 ret_flags |= MSG_DONTROUTE; 325 if (flags & LINUX_MSG_CTRUNC) 326 ret_flags |= MSG_CTRUNC; 327 if (flags & LINUX_MSG_TRUNC) 328 ret_flags |= MSG_TRUNC; 329 if (flags & LINUX_MSG_DONTWAIT) 330 ret_flags |= MSG_DONTWAIT; 331 if (flags & LINUX_MSG_EOR) 332 ret_flags |= MSG_EOR; 333 if (flags & LINUX_MSG_WAITALL) 334 ret_flags |= MSG_WAITALL; 335 if (flags & LINUX_MSG_NOSIGNAL) 336 ret_flags |= MSG_NOSIGNAL; 337 #if 0 /* not handled */ 338 if (flags & LINUX_MSG_PROXY) 339 ; 340 if (flags & LINUX_MSG_FIN) 341 ; 342 if (flags & LINUX_MSG_SYN) 343 ; 344 if (flags & LINUX_MSG_CONFIRM) 345 ; 346 if (flags & LINUX_MSG_RST) 347 ; 348 if (flags & LINUX_MSG_ERRQUEUE) 349 ; 350 #endif 351 return ret_flags; 352 } 353 354 /* 355 * If bsd_to_linux_sockaddr() or linux_to_bsd_sockaddr() faults, then the 356 * native syscall will fault. Thus, we don't really need to check the 357 * return values for these functions. 358 */ 359 360 static int 361 bsd_to_linux_sockaddr(struct sockaddr *arg) 362 { 363 struct sockaddr sa; 364 size_t sa_len = sizeof(struct sockaddr); 365 int error; 366 367 if ((error = copyin(arg, &sa, sa_len))) 368 return (error); 369 370 *(u_short *)&sa = sa.sa_family; 371 372 error = copyout(&sa, arg, sa_len); 373 374 return (error); 375 } 376 377 static int 378 linux_to_bsd_sockaddr(struct sockaddr *arg, int len) 379 { 380 struct sockaddr sa; 381 size_t sa_len = sizeof(struct sockaddr); 382 int error; 383 384 if ((error = copyin(arg, &sa, sa_len))) 385 return (error); 386 387 sa.sa_family = *(sa_family_t *)&sa; 388 sa.sa_len = len; 389 390 error = copyout(&sa, arg, sa_len); 391 392 return (error); 393 } 394 395 396 static int 397 linux_sa_put(struct osockaddr *osa) 398 { 399 struct osockaddr sa; 400 int error, bdom; 401 402 /* 403 * Only read/write the osockaddr family part, the rest is 404 * not changed. 405 */ 406 error = copyin(osa, &sa, sizeof(sa.sa_family)); 407 if (error) 408 return (error); 409 410 bdom = bsd_to_linux_domain(sa.sa_family); 411 if (bdom == -1) 412 return (EINVAL); 413 414 sa.sa_family = bdom; 415 error = copyout(&sa, osa, sizeof(sa.sa_family)); 416 if (error) 417 return (error); 418 419 return (0); 420 } 421 422 static int 423 linux_sendit(struct thread *td, int s, struct msghdr *mp, int flags, 424 enum uio_seg segflg) 425 { 426 struct mbuf *control; 427 struct sockaddr *to; 428 int error; 429 430 if (mp->msg_name != NULL) { 431 error = linux_getsockaddr(&to, mp->msg_name, mp->msg_namelen); 432 if (error) 433 return (error); 434 mp->msg_name = to; 435 } else 436 to = NULL; 437 438 if (mp->msg_control != NULL) { 439 struct cmsghdr *cmsg; 440 441 if (mp->msg_controllen < sizeof(struct cmsghdr)) { 442 error = EINVAL; 443 goto bad; 444 } 445 error = sockargs(&control, mp->msg_control, 446 mp->msg_controllen, MT_CONTROL); 447 if (error) 448 goto bad; 449 450 cmsg = mtod(control, struct cmsghdr *); 451 cmsg->cmsg_level = linux_to_bsd_sockopt_level(cmsg->cmsg_level); 452 } else 453 control = NULL; 454 455 error = kern_sendit(td, s, mp, linux_to_bsd_msg_flags(flags), control, 456 segflg); 457 458 bad: 459 if (to) 460 FREE(to, M_SONAME); 461 return (error); 462 } 463 464 /* Return 0 if IP_HDRINCL is set for the given socket. */ 465 static int 466 linux_check_hdrincl(struct thread *td, int s) 467 { 468 int error, optval, size_val; 469 470 size_val = sizeof(optval); 471 error = kern_getsockopt(td, s, IPPROTO_IP, IP_HDRINCL, 472 &optval, UIO_SYSSPACE, &size_val); 473 if (error) 474 return (error); 475 476 return (optval == 0); 477 } 478 479 struct linux_sendto_args { 480 int s; 481 l_uintptr_t msg; 482 int len; 483 int flags; 484 l_uintptr_t to; 485 int tolen; 486 }; 487 488 /* 489 * Updated sendto() when IP_HDRINCL is set: 490 * tweak endian-dependent fields in the IP packet. 491 */ 492 static int 493 linux_sendto_hdrincl(struct thread *td, struct linux_sendto_args *linux_args) 494 { 495 /* 496 * linux_ip_copysize defines how many bytes we should copy 497 * from the beginning of the IP packet before we customize it for BSD. 498 * It should include all the fields we modify (ip_len and ip_off). 499 */ 500 #define linux_ip_copysize 8 501 502 struct ip *packet; 503 struct msghdr msg; 504 struct iovec aiov[1]; 505 int error; 506 507 /* Check that the packet isn't too big or too small. */ 508 if (linux_args->len < linux_ip_copysize || 509 linux_args->len > IP_MAXPACKET) 510 return (EINVAL); 511 512 packet = (struct ip *)malloc(linux_args->len, M_TEMP, M_WAITOK); 513 514 /* Make kernel copy of the packet to be sent */ 515 if ((error = copyin(PTRIN(linux_args->msg), packet, 516 linux_args->len))) 517 goto goout; 518 519 /* Convert fields from Linux to BSD raw IP socket format */ 520 packet->ip_len = linux_args->len; 521 packet->ip_off = ntohs(packet->ip_off); 522 523 /* Prepare the msghdr and iovec structures describing the new packet */ 524 msg.msg_name = PTRIN(linux_args->to); 525 msg.msg_namelen = linux_args->tolen; 526 msg.msg_iov = aiov; 527 msg.msg_iovlen = 1; 528 msg.msg_control = NULL; 529 msg.msg_flags = 0; 530 aiov[0].iov_base = (char *)packet; 531 aiov[0].iov_len = linux_args->len; 532 error = linux_sendit(td, linux_args->s, &msg, linux_args->flags, 533 UIO_SYSSPACE); 534 goout: 535 free(packet, M_TEMP); 536 return (error); 537 } 538 539 struct linux_socket_args { 540 int domain; 541 int type; 542 int protocol; 543 }; 544 545 static int 546 linux_socket(struct thread *td, struct linux_socket_args *args) 547 { 548 struct linux_socket_args linux_args; 549 struct socket_args /* { 550 int domain; 551 int type; 552 int protocol; 553 } */ bsd_args; 554 int error; 555 int retval_socket; 556 557 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 558 return (error); 559 560 bsd_args.protocol = linux_args.protocol; 561 bsd_args.type = linux_args.type; 562 bsd_args.domain = linux_to_bsd_domain(linux_args.domain); 563 if (bsd_args.domain == -1) 564 return (EINVAL); 565 566 retval_socket = socket(td, &bsd_args); 567 if (bsd_args.type == SOCK_RAW 568 && (bsd_args.protocol == IPPROTO_RAW || bsd_args.protocol == 0) 569 && bsd_args.domain == AF_INET 570 && retval_socket >= 0) { 571 /* It's a raw IP socket: set the IP_HDRINCL option. */ 572 int hdrincl; 573 574 hdrincl = 1; 575 /* We ignore any error returned by kern_setsockopt() */ 576 kern_setsockopt(td, td->td_retval[0], IPPROTO_IP, IP_HDRINCL, 577 &hdrincl, UIO_SYSSPACE, sizeof(hdrincl)); 578 } 579 #ifdef INET6 580 /* 581 * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by 582 * default and some apps depend on this. So, set V6ONLY to 0 583 * for Linux apps if the sysctl value is set to 1. 584 */ 585 if (bsd_args.domain == PF_INET6 && retval_socket >= 0 586 #ifndef KLD_MODULE 587 /* 588 * XXX: Avoid undefined symbol error with an IPv4 only 589 * kernel. 590 */ 591 && ip6_v6only 592 #endif 593 ) { 594 int v6only; 595 596 v6only = 0; 597 /* We ignore any error returned by setsockopt() */ 598 kern_setsockopt(td, td->td_retval[0], IPPROTO_IPV6, IPV6_V6ONLY, 599 &v6only, UIO_SYSSPACE, sizeof(v6only)); 600 } 601 #endif 602 603 return (retval_socket); 604 } 605 606 struct linux_bind_args { 607 int s; 608 l_uintptr_t name; 609 int namelen; 610 }; 611 612 static int 613 linux_bind(struct thread *td, struct linux_bind_args *args) 614 { 615 struct linux_bind_args linux_args; 616 struct sockaddr *sa; 617 int error; 618 619 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 620 return (error); 621 622 error = linux_getsockaddr(&sa, PTRIN(linux_args.name), 623 linux_args.namelen); 624 if (error) 625 return (error); 626 627 error = kern_bind(td, linux_args.s, sa); 628 free(sa, M_SONAME); 629 if (error == EADDRNOTAVAIL && linux_args.namelen != sizeof(struct sockaddr_in)) 630 return (EINVAL); 631 return (error); 632 } 633 634 struct linux_connect_args { 635 int s; 636 l_uintptr_t name; 637 int namelen; 638 }; 639 int linux_connect(struct thread *, struct linux_connect_args *); 640 641 int 642 linux_connect(struct thread *td, struct linux_connect_args *args) 643 { 644 struct linux_connect_args linux_args; 645 struct socket *so; 646 struct sockaddr *sa; 647 u_int fflag; 648 int error; 649 650 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 651 return (error); 652 653 error = linux_getsockaddr(&sa, 654 (struct osockaddr *)PTRIN(linux_args.name), 655 linux_args.namelen); 656 if (error) 657 return (error); 658 659 error = kern_connect(td, linux_args.s, sa); 660 free(sa, M_SONAME); 661 if (error != EISCONN) 662 return (error); 663 664 /* 665 * Linux doesn't return EISCONN the first time it occurs, 666 * when on a non-blocking socket. Instead it returns the 667 * error getsockopt(SOL_SOCKET, SO_ERROR) would return on BSD. 668 * 669 * XXXRW: Instead of using fgetsock(), check that it is a 670 * socket and use the file descriptor reference instead of 671 * creating a new one. 672 */ 673 NET_LOCK_GIANT(); 674 error = fgetsock(td, linux_args.s, &so, &fflag); 675 if (error == 0) { 676 error = EISCONN; 677 if (fflag & FNONBLOCK) { 678 SOCK_LOCK(so); 679 if (so->so_emuldata == 0) 680 error = so->so_error; 681 so->so_emuldata = (void *)1; 682 SOCK_UNLOCK(so); 683 } 684 fputsock(so); 685 } 686 NET_UNLOCK_GIANT(); 687 return (error); 688 } 689 690 struct linux_listen_args { 691 int s; 692 int backlog; 693 }; 694 695 static int 696 linux_listen(struct thread *td, struct linux_listen_args *args) 697 { 698 struct linux_listen_args linux_args; 699 struct listen_args /* { 700 int s; 701 int backlog; 702 } */ bsd_args; 703 int error; 704 705 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 706 return (error); 707 708 bsd_args.s = linux_args.s; 709 bsd_args.backlog = linux_args.backlog; 710 return (listen(td, &bsd_args)); 711 } 712 713 struct linux_accept_args { 714 int s; 715 l_uintptr_t addr; 716 l_uintptr_t namelen; 717 }; 718 719 static int 720 linux_accept(struct thread *td, struct linux_accept_args *args) 721 { 722 struct linux_accept_args linux_args; 723 struct accept_args /* { 724 int s; 725 struct sockaddr * __restrict name; 726 socklen_t * __restrict anamelen; 727 } */ bsd_args; 728 int error, fd; 729 730 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 731 return (error); 732 733 bsd_args.s = linux_args.s; 734 /* XXX: */ 735 bsd_args.name = (struct sockaddr * __restrict)PTRIN(linux_args.addr); 736 bsd_args.anamelen = PTRIN(linux_args.namelen);/* XXX */ 737 error = accept(td, &bsd_args); 738 bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.name); 739 if (error) { 740 if (error == EFAULT && linux_args.namelen != sizeof(struct sockaddr_in)) 741 return (EINVAL); 742 return (error); 743 } 744 if (linux_args.addr) { 745 error = linux_sa_put(PTRIN(linux_args.addr)); 746 if (error) { 747 (void)kern_close(td, td->td_retval[0]); 748 return (error); 749 } 750 } 751 752 /* 753 * linux appears not to copy flags from the parent socket to the 754 * accepted one, so we must clear the flags in the new descriptor. 755 * Ignore any errors, because we already have an open fd. 756 */ 757 fd = td->td_retval[0]; 758 (void)kern_fcntl(td, fd, F_SETFL, 0); 759 td->td_retval[0] = fd; 760 return (0); 761 } 762 763 struct linux_getsockname_args { 764 int s; 765 l_uintptr_t addr; 766 l_uintptr_t namelen; 767 }; 768 769 static int 770 linux_getsockname(struct thread *td, struct linux_getsockname_args *args) 771 { 772 struct linux_getsockname_args linux_args; 773 struct getsockname_args /* { 774 int fdes; 775 struct sockaddr * __restrict asa; 776 socklen_t * __restrict alen; 777 } */ bsd_args; 778 int error; 779 780 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 781 return (error); 782 783 bsd_args.fdes = linux_args.s; 784 /* XXX: */ 785 bsd_args.asa = (struct sockaddr * __restrict)PTRIN(linux_args.addr); 786 bsd_args.alen = PTRIN(linux_args.namelen); /* XXX */ 787 error = getsockname(td, &bsd_args); 788 bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.asa); 789 if (error) 790 return (error); 791 error = linux_sa_put(PTRIN(linux_args.addr)); 792 if (error) 793 return (error); 794 return (0); 795 } 796 797 struct linux_getpeername_args { 798 int s; 799 l_uintptr_t addr; 800 l_uintptr_t namelen; 801 }; 802 803 static int 804 linux_getpeername(struct thread *td, struct linux_getpeername_args *args) 805 { 806 struct linux_getpeername_args linux_args; 807 struct getpeername_args /* { 808 int fdes; 809 caddr_t asa; 810 int *alen; 811 } */ bsd_args; 812 int error; 813 814 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 815 return (error); 816 817 bsd_args.fdes = linux_args.s; 818 bsd_args.asa = (struct sockaddr *)PTRIN(linux_args.addr); 819 bsd_args.alen = (int *)PTRIN(linux_args.namelen); 820 error = getpeername(td, &bsd_args); 821 bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.asa); 822 if (error) 823 return (error); 824 error = linux_sa_put(PTRIN(linux_args.addr)); 825 if (error) 826 return (error); 827 return (0); 828 } 829 830 struct linux_socketpair_args { 831 int domain; 832 int type; 833 int protocol; 834 l_uintptr_t rsv; 835 }; 836 837 static int 838 linux_socketpair(struct thread *td, struct linux_socketpair_args *args) 839 { 840 struct linux_socketpair_args linux_args; 841 struct socketpair_args /* { 842 int domain; 843 int type; 844 int protocol; 845 int *rsv; 846 } */ bsd_args; 847 int error; 848 849 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 850 return (error); 851 852 bsd_args.domain = linux_to_bsd_domain(linux_args.domain); 853 if (bsd_args.domain == -1) 854 return (EINVAL); 855 856 bsd_args.type = linux_args.type; 857 bsd_args.protocol = linux_args.protocol; 858 bsd_args.rsv = (int *)PTRIN(linux_args.rsv); 859 return (socketpair(td, &bsd_args)); 860 } 861 862 struct linux_send_args { 863 int s; 864 l_uintptr_t msg; 865 int len; 866 int flags; 867 }; 868 869 static int 870 linux_send(struct thread *td, struct linux_send_args *args) 871 { 872 struct linux_send_args linux_args; 873 struct sendto_args /* { 874 int s; 875 caddr_t buf; 876 int len; 877 int flags; 878 caddr_t to; 879 int tolen; 880 } */ bsd_args; 881 int error; 882 883 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 884 return (error); 885 886 bsd_args.s = linux_args.s; 887 bsd_args.buf = (caddr_t)PTRIN(linux_args.msg); 888 bsd_args.len = linux_args.len; 889 bsd_args.flags = linux_args.flags; 890 bsd_args.to = NULL; 891 bsd_args.tolen = 0; 892 return sendto(td, &bsd_args); 893 } 894 895 struct linux_recv_args { 896 int s; 897 l_uintptr_t msg; 898 int len; 899 int flags; 900 }; 901 902 static int 903 linux_recv(struct thread *td, struct linux_recv_args *args) 904 { 905 struct linux_recv_args linux_args; 906 struct recvfrom_args /* { 907 int s; 908 caddr_t buf; 909 int len; 910 int flags; 911 struct sockaddr *from; 912 socklen_t fromlenaddr; 913 } */ bsd_args; 914 int error; 915 916 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 917 return (error); 918 919 bsd_args.s = linux_args.s; 920 bsd_args.buf = (caddr_t)PTRIN(linux_args.msg); 921 bsd_args.len = linux_args.len; 922 bsd_args.flags = linux_args.flags; 923 bsd_args.from = NULL; 924 bsd_args.fromlenaddr = 0; 925 return (recvfrom(td, &bsd_args)); 926 } 927 928 static int 929 linux_sendto(struct thread *td, struct linux_sendto_args *args) 930 { 931 struct linux_sendto_args linux_args; 932 struct msghdr msg; 933 struct iovec aiov; 934 int error; 935 936 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 937 return (error); 938 939 if (linux_check_hdrincl(td, linux_args.s) == 0) 940 /* IP_HDRINCL set, tweak the packet before sending */ 941 return (linux_sendto_hdrincl(td, &linux_args)); 942 943 msg.msg_name = PTRIN(linux_args.to); 944 msg.msg_namelen = linux_args.tolen; 945 msg.msg_iov = &aiov; 946 msg.msg_iovlen = 1; 947 msg.msg_control = NULL; 948 msg.msg_flags = 0; 949 aiov.iov_base = PTRIN(linux_args.msg); 950 aiov.iov_len = linux_args.len; 951 error = linux_sendit(td, linux_args.s, &msg, linux_args.flags, 952 UIO_USERSPACE); 953 return (error); 954 } 955 956 struct linux_recvfrom_args { 957 int s; 958 l_uintptr_t buf; 959 int len; 960 int flags; 961 l_uintptr_t from; 962 l_uintptr_t fromlen; 963 }; 964 965 static int 966 linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args) 967 { 968 struct linux_recvfrom_args linux_args; 969 struct recvfrom_args /* { 970 int s; 971 caddr_t buf; 972 size_t len; 973 int flags; 974 struct sockaddr * __restrict from; 975 socklen_t * __restrict fromlenaddr; 976 } */ bsd_args; 977 size_t len; 978 int error; 979 980 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 981 return (error); 982 983 if ((error = copyin(PTRIN(linux_args.fromlen), &len, sizeof(size_t)))) 984 return (error); 985 986 bsd_args.s = linux_args.s; 987 bsd_args.buf = PTRIN(linux_args.buf); 988 bsd_args.len = linux_args.len; 989 bsd_args.flags = linux_to_bsd_msg_flags(linux_args.flags); 990 /* XXX: */ 991 bsd_args.from = (struct sockaddr * __restrict)PTRIN(linux_args.from); 992 bsd_args.fromlenaddr = PTRIN(linux_args.fromlen);/* XXX */ 993 994 linux_to_bsd_sockaddr((struct sockaddr *)bsd_args.from, len); 995 error = recvfrom(td, &bsd_args); 996 bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.from); 997 998 if (error) 999 return (error); 1000 if (linux_args.from) { 1001 error = linux_sa_put((struct osockaddr *) 1002 PTRIN(linux_args.from)); 1003 if (error) 1004 return (error); 1005 } 1006 return (0); 1007 } 1008 1009 struct linux_sendmsg_args { 1010 int s; 1011 l_uintptr_t msg; 1012 int flags; 1013 }; 1014 1015 static int 1016 linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args) 1017 { 1018 struct linux_sendmsg_args linux_args; 1019 struct msghdr msg; 1020 struct iovec *iov; 1021 int error; 1022 1023 /* XXXTJR sendmsg is broken on amd64 */ 1024 1025 error = copyin(args, &linux_args, sizeof(linux_args)); 1026 if (error) 1027 return (error); 1028 error = copyin(PTRIN(linux_args.msg), &msg, sizeof(msg)); 1029 if (error) 1030 return (error); 1031 1032 /* 1033 * Some Linux applications (ping) define a non-NULL control data 1034 * pointer, but a msg_controllen of 0, which is not allowed in the 1035 * FreeBSD system call interface. NULL the msg_control pointer in 1036 * order to handle this case. This should be checked, but allows the 1037 * Linux ping to work. 1038 */ 1039 if (msg.msg_control != NULL && msg.msg_controllen == 0) 1040 msg.msg_control = NULL; 1041 error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); 1042 if (error) 1043 return (error); 1044 msg.msg_iov = iov; 1045 msg.msg_flags = 0; 1046 error = linux_sendit(td, linux_args.s, &msg, linux_args.flags, 1047 UIO_USERSPACE); 1048 free(iov, M_IOV); 1049 return (error); 1050 } 1051 1052 struct linux_recvmsg_args { 1053 int s; 1054 l_uintptr_t msg; 1055 int flags; 1056 }; 1057 1058 static int 1059 linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args) 1060 { 1061 struct linux_recvmsg_args linux_args; 1062 struct recvmsg_args /* { 1063 int s; 1064 struct msghdr *msg; 1065 int flags; 1066 } */ bsd_args; 1067 struct msghdr msg; 1068 struct cmsghdr *cmsg; 1069 int error; 1070 1071 /* XXXTJR recvmsg is broken on amd64 */ 1072 1073 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 1074 return (error); 1075 1076 if ((error = copyin(PTRIN(args->msg), &msg, sizeof (msg)))) 1077 return (error); 1078 1079 bsd_args.s = linux_args.s; 1080 bsd_args.msg = PTRIN(linux_args.msg); 1081 bsd_args.flags = linux_to_bsd_msg_flags(linux_args.flags); 1082 if (msg.msg_name) { 1083 linux_to_bsd_sockaddr((struct sockaddr *)msg.msg_name, 1084 msg.msg_namelen); 1085 error = recvmsg(td, &bsd_args); 1086 bsd_to_linux_sockaddr((struct sockaddr *)msg.msg_name); 1087 } else 1088 error = recvmsg(td, &bsd_args); 1089 if (error) 1090 return (error); 1091 1092 if (bsd_args.msg->msg_control != NULL && 1093 bsd_args.msg->msg_controllen > 0) { 1094 cmsg = (struct cmsghdr*)bsd_args.msg->msg_control; 1095 cmsg->cmsg_level = bsd_to_linux_sockopt_level(cmsg->cmsg_level); 1096 } 1097 1098 error = copyin(PTRIN(linux_args.msg), &msg, sizeof(msg)); 1099 if (error) 1100 return (error); 1101 if (msg.msg_name && msg.msg_namelen > 2) 1102 error = linux_sa_put(msg.msg_name); 1103 return (error); 1104 } 1105 1106 struct linux_shutdown_args { 1107 int s; 1108 int how; 1109 }; 1110 1111 static int 1112 linux_shutdown(struct thread *td, struct linux_shutdown_args *args) 1113 { 1114 struct linux_shutdown_args linux_args; 1115 struct shutdown_args /* { 1116 int s; 1117 int how; 1118 } */ bsd_args; 1119 int error; 1120 1121 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 1122 return (error); 1123 1124 bsd_args.s = linux_args.s; 1125 bsd_args.how = linux_args.how; 1126 return (shutdown(td, &bsd_args)); 1127 } 1128 1129 struct linux_setsockopt_args { 1130 int s; 1131 int level; 1132 int optname; 1133 l_uintptr_t optval; 1134 int optlen; 1135 }; 1136 1137 static int 1138 linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args) 1139 { 1140 struct linux_setsockopt_args linux_args; 1141 struct setsockopt_args /* { 1142 int s; 1143 int level; 1144 int name; 1145 caddr_t val; 1146 int valsize; 1147 } */ bsd_args; 1148 int error, name; 1149 1150 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 1151 return (error); 1152 1153 bsd_args.s = linux_args.s; 1154 bsd_args.level = linux_to_bsd_sockopt_level(linux_args.level); 1155 switch (bsd_args.level) { 1156 case SOL_SOCKET: 1157 name = linux_to_bsd_so_sockopt(linux_args.optname); 1158 break; 1159 case IPPROTO_IP: 1160 name = linux_to_bsd_ip_sockopt(linux_args.optname); 1161 break; 1162 case IPPROTO_TCP: 1163 /* Linux TCP option values match BSD's */ 1164 name = linux_args.optname; 1165 break; 1166 default: 1167 name = -1; 1168 break; 1169 } 1170 if (name == -1) 1171 return (ENOPROTOOPT); 1172 1173 bsd_args.name = name; 1174 bsd_args.val = PTRIN(linux_args.optval); 1175 bsd_args.valsize = linux_args.optlen; 1176 1177 if (name == IPV6_NEXTHOP) { 1178 linux_to_bsd_sockaddr((struct sockaddr *)bsd_args.val, 1179 bsd_args.valsize); 1180 error = setsockopt(td, &bsd_args); 1181 bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.val); 1182 } else 1183 error = setsockopt(td, &bsd_args); 1184 1185 return (error); 1186 } 1187 1188 struct linux_getsockopt_args { 1189 int s; 1190 int level; 1191 int optname; 1192 l_uintptr_t optval; 1193 l_uintptr_t optlen; 1194 }; 1195 1196 static int 1197 linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) 1198 { 1199 struct linux_getsockopt_args linux_args; 1200 struct getsockopt_args /* { 1201 int s; 1202 int level; 1203 int name; 1204 caddr_t val; 1205 int *avalsize; 1206 } */ bsd_args; 1207 int error, name; 1208 1209 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 1210 return (error); 1211 1212 bsd_args.s = linux_args.s; 1213 bsd_args.level = linux_to_bsd_sockopt_level(linux_args.level); 1214 switch (bsd_args.level) { 1215 case SOL_SOCKET: 1216 name = linux_to_bsd_so_sockopt(linux_args.optname); 1217 break; 1218 case IPPROTO_IP: 1219 name = linux_to_bsd_ip_sockopt(linux_args.optname); 1220 break; 1221 case IPPROTO_TCP: 1222 /* Linux TCP option values match BSD's */ 1223 name = linux_args.optname; 1224 break; 1225 default: 1226 name = -1; 1227 break; 1228 } 1229 if (name == -1) 1230 return (EINVAL); 1231 1232 bsd_args.name = name; 1233 bsd_args.val = PTRIN(linux_args.optval); 1234 bsd_args.avalsize = PTRIN(linux_args.optlen); 1235 1236 if (name == IPV6_NEXTHOP) { 1237 error = getsockopt(td, &bsd_args); 1238 bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.val); 1239 } else 1240 error = getsockopt(td, &bsd_args); 1241 1242 return (error); 1243 } 1244 1245 int 1246 linux_socketcall(struct thread *td, struct linux_socketcall_args *args) 1247 { 1248 void *arg = (void *)(intptr_t)args->args; 1249 1250 switch (args->what) { 1251 case LINUX_SOCKET: 1252 return (linux_socket(td, arg)); 1253 case LINUX_BIND: 1254 return (linux_bind(td, arg)); 1255 case LINUX_CONNECT: 1256 return (linux_connect(td, arg)); 1257 case LINUX_LISTEN: 1258 return (linux_listen(td, arg)); 1259 case LINUX_ACCEPT: 1260 return (linux_accept(td, arg)); 1261 case LINUX_GETSOCKNAME: 1262 return (linux_getsockname(td, arg)); 1263 case LINUX_GETPEERNAME: 1264 return (linux_getpeername(td, arg)); 1265 case LINUX_SOCKETPAIR: 1266 return (linux_socketpair(td, arg)); 1267 case LINUX_SEND: 1268 return (linux_send(td, arg)); 1269 case LINUX_RECV: 1270 return (linux_recv(td, arg)); 1271 case LINUX_SENDTO: 1272 return (linux_sendto(td, arg)); 1273 case LINUX_RECVFROM: 1274 return (linux_recvfrom(td, arg)); 1275 case LINUX_SHUTDOWN: 1276 return (linux_shutdown(td, arg)); 1277 case LINUX_SETSOCKOPT: 1278 return (linux_setsockopt(td, arg)); 1279 case LINUX_GETSOCKOPT: 1280 return (linux_getsockopt(td, arg)); 1281 case LINUX_SENDMSG: 1282 return (linux_sendmsg(td, arg)); 1283 case LINUX_RECVMSG: 1284 return (linux_recvmsg(td, arg)); 1285 } 1286 1287 uprintf("LINUX: 'socket' typ=%d not implemented\n", args->what); 1288 return (ENOSYS); 1289 } 1290