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