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 #ifdef INET6 550 INIT_VNET_INET6(curvnet); 551 #endif 552 struct socket_args /* { 553 int domain; 554 int type; 555 int protocol; 556 } */ bsd_args; 557 int retval_socket; 558 559 bsd_args.protocol = args->protocol; 560 bsd_args.type = args->type; 561 bsd_args.domain = linux_to_bsd_domain(args->domain); 562 if (bsd_args.domain == -1) 563 return (EINVAL); 564 565 retval_socket = socket(td, &bsd_args); 566 if (bsd_args.type == SOCK_RAW 567 && (bsd_args.protocol == IPPROTO_RAW || bsd_args.protocol == 0) 568 && bsd_args.domain == AF_INET 569 && retval_socket >= 0) { 570 /* It's a raw IP socket: set the IP_HDRINCL option. */ 571 int hdrincl; 572 573 hdrincl = 1; 574 /* We ignore any error returned by kern_setsockopt() */ 575 kern_setsockopt(td, td->td_retval[0], IPPROTO_IP, IP_HDRINCL, 576 &hdrincl, UIO_SYSSPACE, sizeof(hdrincl)); 577 } 578 #ifdef INET6 579 /* 580 * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by 581 * default and some apps depend on this. So, set V6ONLY to 0 582 * for Linux apps if the sysctl value is set to 1. 583 */ 584 if (bsd_args.domain == PF_INET6 && retval_socket >= 0 585 #ifndef KLD_MODULE 586 /* 587 * XXX: Avoid undefined symbol error with an IPv4 only 588 * kernel. 589 */ 590 && V_ip6_v6only 591 #endif 592 ) { 593 int v6only; 594 595 v6only = 0; 596 /* We ignore any error returned by setsockopt() */ 597 kern_setsockopt(td, td->td_retval[0], IPPROTO_IPV6, IPV6_V6ONLY, 598 &v6only, UIO_SYSSPACE, sizeof(v6only)); 599 } 600 #endif 601 602 return (retval_socket); 603 } 604 605 struct linux_bind_args { 606 int s; 607 l_uintptr_t name; 608 int namelen; 609 }; 610 611 static int 612 linux_bind(struct thread *td, struct linux_bind_args *args) 613 { 614 struct sockaddr *sa; 615 int error; 616 617 error = linux_getsockaddr(&sa, PTRIN(args->name), 618 args->namelen); 619 if (error) 620 return (error); 621 622 error = kern_bind(td, args->s, sa); 623 free(sa, M_SONAME); 624 if (error == EADDRNOTAVAIL && args->namelen != sizeof(struct sockaddr_in)) 625 return (EINVAL); 626 return (error); 627 } 628 629 struct linux_connect_args { 630 int s; 631 l_uintptr_t name; 632 int namelen; 633 }; 634 int linux_connect(struct thread *, struct linux_connect_args *); 635 636 int 637 linux_connect(struct thread *td, struct linux_connect_args *args) 638 { 639 struct socket *so; 640 struct sockaddr *sa; 641 u_int fflag; 642 int error; 643 644 error = linux_getsockaddr(&sa, (struct osockaddr *)PTRIN(args->name), 645 args->namelen); 646 if (error) 647 return (error); 648 649 error = kern_connect(td, args->s, sa); 650 free(sa, M_SONAME); 651 if (error != EISCONN) 652 return (error); 653 654 /* 655 * Linux doesn't return EISCONN the first time it occurs, 656 * when on a non-blocking socket. Instead it returns the 657 * error getsockopt(SOL_SOCKET, SO_ERROR) would return on BSD. 658 * 659 * XXXRW: Instead of using fgetsock(), check that it is a 660 * socket and use the file descriptor reference instead of 661 * creating a new one. 662 */ 663 error = fgetsock(td, args->s, &so, &fflag); 664 if (error == 0) { 665 error = EISCONN; 666 if (fflag & FNONBLOCK) { 667 SOCK_LOCK(so); 668 if (so->so_emuldata == 0) 669 error = so->so_error; 670 so->so_emuldata = (void *)1; 671 SOCK_UNLOCK(so); 672 } 673 fputsock(so); 674 } 675 return (error); 676 } 677 678 struct linux_listen_args { 679 int s; 680 int backlog; 681 }; 682 683 static int 684 linux_listen(struct thread *td, struct linux_listen_args *args) 685 { 686 struct listen_args /* { 687 int s; 688 int backlog; 689 } */ bsd_args; 690 691 bsd_args.s = args->s; 692 bsd_args.backlog = args->backlog; 693 return (listen(td, &bsd_args)); 694 } 695 696 struct linux_accept_args { 697 int s; 698 l_uintptr_t addr; 699 l_uintptr_t namelen; 700 }; 701 702 static int 703 linux_accept(struct thread *td, struct linux_accept_args *args) 704 { 705 struct accept_args /* { 706 int s; 707 struct sockaddr * __restrict name; 708 socklen_t * __restrict anamelen; 709 } */ bsd_args; 710 int error, fd; 711 712 bsd_args.s = args->s; 713 /* XXX: */ 714 bsd_args.name = (struct sockaddr * __restrict)PTRIN(args->addr); 715 bsd_args.anamelen = PTRIN(args->namelen);/* XXX */ 716 error = accept(td, &bsd_args); 717 bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.name); 718 if (error) { 719 if (error == EFAULT && args->namelen != sizeof(struct sockaddr_in)) 720 return (EINVAL); 721 return (error); 722 } 723 if (args->addr) { 724 error = linux_sa_put(PTRIN(args->addr)); 725 if (error) { 726 (void)kern_close(td, td->td_retval[0]); 727 return (error); 728 } 729 } 730 731 /* 732 * linux appears not to copy flags from the parent socket to the 733 * accepted one, so we must clear the flags in the new descriptor. 734 * Ignore any errors, because we already have an open fd. 735 */ 736 fd = td->td_retval[0]; 737 (void)kern_fcntl(td, fd, F_SETFL, 0); 738 td->td_retval[0] = fd; 739 return (0); 740 } 741 742 struct linux_getsockname_args { 743 int s; 744 l_uintptr_t addr; 745 l_uintptr_t namelen; 746 }; 747 748 static int 749 linux_getsockname(struct thread *td, struct linux_getsockname_args *args) 750 { 751 struct getsockname_args /* { 752 int fdes; 753 struct sockaddr * __restrict asa; 754 socklen_t * __restrict alen; 755 } */ bsd_args; 756 int error; 757 758 bsd_args.fdes = args->s; 759 /* XXX: */ 760 bsd_args.asa = (struct sockaddr * __restrict)PTRIN(args->addr); 761 bsd_args.alen = PTRIN(args->namelen); /* XXX */ 762 error = getsockname(td, &bsd_args); 763 bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.asa); 764 if (error) 765 return (error); 766 error = linux_sa_put(PTRIN(args->addr)); 767 if (error) 768 return (error); 769 return (0); 770 } 771 772 struct linux_getpeername_args { 773 int s; 774 l_uintptr_t addr; 775 l_uintptr_t namelen; 776 }; 777 778 static int 779 linux_getpeername(struct thread *td, struct linux_getpeername_args *args) 780 { 781 struct getpeername_args /* { 782 int fdes; 783 caddr_t asa; 784 int *alen; 785 } */ bsd_args; 786 int error; 787 788 bsd_args.fdes = args->s; 789 bsd_args.asa = (struct sockaddr *)PTRIN(args->addr); 790 bsd_args.alen = (int *)PTRIN(args->namelen); 791 error = getpeername(td, &bsd_args); 792 bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.asa); 793 if (error) 794 return (error); 795 error = linux_sa_put(PTRIN(args->addr)); 796 if (error) 797 return (error); 798 return (0); 799 } 800 801 struct linux_socketpair_args { 802 int domain; 803 int type; 804 int protocol; 805 l_uintptr_t rsv; 806 }; 807 808 static int 809 linux_socketpair(struct thread *td, struct linux_socketpair_args *args) 810 { 811 struct socketpair_args /* { 812 int domain; 813 int type; 814 int protocol; 815 int *rsv; 816 } */ bsd_args; 817 818 bsd_args.domain = linux_to_bsd_domain(args->domain); 819 if (bsd_args.domain == -1) 820 return (EINVAL); 821 822 bsd_args.type = args->type; 823 bsd_args.protocol = args->protocol; 824 bsd_args.rsv = (int *)PTRIN(args->rsv); 825 return (socketpair(td, &bsd_args)); 826 } 827 828 struct linux_send_args { 829 int s; 830 l_uintptr_t msg; 831 int len; 832 int flags; 833 }; 834 835 static int 836 linux_send(struct thread *td, struct linux_send_args *args) 837 { 838 struct sendto_args /* { 839 int s; 840 caddr_t buf; 841 int len; 842 int flags; 843 caddr_t to; 844 int tolen; 845 } */ bsd_args; 846 847 bsd_args.s = args->s; 848 bsd_args.buf = (caddr_t)PTRIN(args->msg); 849 bsd_args.len = args->len; 850 bsd_args.flags = args->flags; 851 bsd_args.to = NULL; 852 bsd_args.tolen = 0; 853 return sendto(td, &bsd_args); 854 } 855 856 struct linux_recv_args { 857 int s; 858 l_uintptr_t msg; 859 int len; 860 int flags; 861 }; 862 863 static int 864 linux_recv(struct thread *td, struct linux_recv_args *args) 865 { 866 struct recvfrom_args /* { 867 int s; 868 caddr_t buf; 869 int len; 870 int flags; 871 struct sockaddr *from; 872 socklen_t fromlenaddr; 873 } */ bsd_args; 874 875 bsd_args.s = args->s; 876 bsd_args.buf = (caddr_t)PTRIN(args->msg); 877 bsd_args.len = args->len; 878 bsd_args.flags = args->flags; 879 bsd_args.from = NULL; 880 bsd_args.fromlenaddr = 0; 881 return (recvfrom(td, &bsd_args)); 882 } 883 884 static int 885 linux_sendto(struct thread *td, struct linux_sendto_args *args) 886 { 887 struct msghdr msg; 888 struct iovec aiov; 889 int error; 890 891 if (linux_check_hdrincl(td, args->s) == 0) 892 /* IP_HDRINCL set, tweak the packet before sending */ 893 return (linux_sendto_hdrincl(td, args)); 894 895 msg.msg_name = PTRIN(args->to); 896 msg.msg_namelen = args->tolen; 897 msg.msg_iov = &aiov; 898 msg.msg_iovlen = 1; 899 msg.msg_control = NULL; 900 msg.msg_flags = 0; 901 aiov.iov_base = PTRIN(args->msg); 902 aiov.iov_len = args->len; 903 error = linux_sendit(td, args->s, &msg, args->flags, UIO_USERSPACE); 904 return (error); 905 } 906 907 struct linux_recvfrom_args { 908 int s; 909 l_uintptr_t buf; 910 int len; 911 int flags; 912 l_uintptr_t from; 913 l_uintptr_t fromlen; 914 }; 915 916 static int 917 linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args) 918 { 919 struct recvfrom_args /* { 920 int s; 921 caddr_t buf; 922 size_t len; 923 int flags; 924 struct sockaddr * __restrict from; 925 socklen_t * __restrict fromlenaddr; 926 } */ bsd_args; 927 size_t len; 928 int error; 929 930 if ((error = copyin(PTRIN(args->fromlen), &len, sizeof(size_t)))) 931 return (error); 932 933 bsd_args.s = args->s; 934 bsd_args.buf = PTRIN(args->buf); 935 bsd_args.len = args->len; 936 bsd_args.flags = linux_to_bsd_msg_flags(args->flags); 937 /* XXX: */ 938 bsd_args.from = (struct sockaddr * __restrict)PTRIN(args->from); 939 bsd_args.fromlenaddr = PTRIN(args->fromlen);/* XXX */ 940 941 linux_to_bsd_sockaddr((struct sockaddr *)bsd_args.from, len); 942 error = recvfrom(td, &bsd_args); 943 bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.from); 944 945 if (error) 946 return (error); 947 if (args->from) { 948 error = linux_sa_put((struct osockaddr *) 949 PTRIN(args->from)); 950 if (error) 951 return (error); 952 } 953 return (0); 954 } 955 956 struct linux_sendmsg_args { 957 int s; 958 l_uintptr_t msg; 959 int flags; 960 }; 961 962 static int 963 linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args) 964 { 965 struct msghdr msg; 966 struct iovec *iov; 967 int error; 968 969 /* XXXTJR sendmsg is broken on amd64 */ 970 971 error = copyin(PTRIN(args->msg), &msg, sizeof(msg)); 972 if (error) 973 return (error); 974 975 /* 976 * Some Linux applications (ping) define a non-NULL control data 977 * pointer, but a msg_controllen of 0, which is not allowed in the 978 * FreeBSD system call interface. NULL the msg_control pointer in 979 * order to handle this case. This should be checked, but allows the 980 * Linux ping to work. 981 */ 982 if (msg.msg_control != NULL && msg.msg_controllen == 0) 983 msg.msg_control = NULL; 984 error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); 985 if (error) 986 return (error); 987 msg.msg_iov = iov; 988 msg.msg_flags = 0; 989 error = linux_sendit(td, args->s, &msg, args->flags, UIO_USERSPACE); 990 free(iov, M_IOV); 991 return (error); 992 } 993 994 struct linux_recvmsg_args { 995 int s; 996 l_uintptr_t msg; 997 int flags; 998 }; 999 1000 static int 1001 linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args) 1002 { 1003 struct recvmsg_args /* { 1004 int s; 1005 struct msghdr *msg; 1006 int flags; 1007 } */ bsd_args; 1008 struct msghdr msg; 1009 struct cmsghdr *cmsg; 1010 int error; 1011 1012 /* XXXTJR recvmsg is broken on amd64 */ 1013 1014 if ((error = copyin(PTRIN(args->msg), &msg, sizeof (msg)))) 1015 return (error); 1016 1017 bsd_args.s = args->s; 1018 bsd_args.msg = PTRIN(args->msg); 1019 bsd_args.flags = linux_to_bsd_msg_flags(args->flags); 1020 if (msg.msg_name) { 1021 linux_to_bsd_sockaddr((struct sockaddr *)msg.msg_name, 1022 msg.msg_namelen); 1023 error = recvmsg(td, &bsd_args); 1024 bsd_to_linux_sockaddr((struct sockaddr *)msg.msg_name); 1025 } else 1026 error = recvmsg(td, &bsd_args); 1027 if (error) 1028 return (error); 1029 1030 if (bsd_args.msg->msg_control != NULL && 1031 bsd_args.msg->msg_controllen > 0) { 1032 cmsg = (struct cmsghdr*)bsd_args.msg->msg_control; 1033 cmsg->cmsg_level = bsd_to_linux_sockopt_level(cmsg->cmsg_level); 1034 } 1035 1036 error = copyin(PTRIN(args->msg), &msg, sizeof(msg)); 1037 if (error) 1038 return (error); 1039 if (msg.msg_name && msg.msg_namelen > 2) 1040 error = linux_sa_put(msg.msg_name); 1041 return (error); 1042 } 1043 1044 struct linux_shutdown_args { 1045 int s; 1046 int how; 1047 }; 1048 1049 static int 1050 linux_shutdown(struct thread *td, struct linux_shutdown_args *args) 1051 { 1052 struct shutdown_args /* { 1053 int s; 1054 int how; 1055 } */ bsd_args; 1056 1057 bsd_args.s = args->s; 1058 bsd_args.how = args->how; 1059 return (shutdown(td, &bsd_args)); 1060 } 1061 1062 struct linux_setsockopt_args { 1063 int s; 1064 int level; 1065 int optname; 1066 l_uintptr_t optval; 1067 int optlen; 1068 }; 1069 1070 static int 1071 linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args) 1072 { 1073 struct setsockopt_args /* { 1074 int s; 1075 int level; 1076 int name; 1077 caddr_t val; 1078 int valsize; 1079 } */ bsd_args; 1080 int error, name; 1081 1082 bsd_args.s = args->s; 1083 bsd_args.level = linux_to_bsd_sockopt_level(args->level); 1084 switch (bsd_args.level) { 1085 case SOL_SOCKET: 1086 name = linux_to_bsd_so_sockopt(args->optname); 1087 break; 1088 case IPPROTO_IP: 1089 name = linux_to_bsd_ip_sockopt(args->optname); 1090 break; 1091 case IPPROTO_TCP: 1092 /* Linux TCP option values match BSD's */ 1093 name = args->optname; 1094 break; 1095 default: 1096 name = -1; 1097 break; 1098 } 1099 if (name == -1) 1100 return (ENOPROTOOPT); 1101 1102 bsd_args.name = name; 1103 bsd_args.val = PTRIN(args->optval); 1104 bsd_args.valsize = args->optlen; 1105 1106 if (name == IPV6_NEXTHOP) { 1107 linux_to_bsd_sockaddr((struct sockaddr *)bsd_args.val, 1108 bsd_args.valsize); 1109 error = setsockopt(td, &bsd_args); 1110 bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.val); 1111 } else 1112 error = setsockopt(td, &bsd_args); 1113 1114 return (error); 1115 } 1116 1117 struct linux_getsockopt_args { 1118 int s; 1119 int level; 1120 int optname; 1121 l_uintptr_t optval; 1122 l_uintptr_t optlen; 1123 }; 1124 1125 static int 1126 linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) 1127 { 1128 struct getsockopt_args /* { 1129 int s; 1130 int level; 1131 int name; 1132 caddr_t val; 1133 int *avalsize; 1134 } */ bsd_args; 1135 int error, name; 1136 1137 bsd_args.s = args->s; 1138 bsd_args.level = linux_to_bsd_sockopt_level(args->level); 1139 switch (bsd_args.level) { 1140 case SOL_SOCKET: 1141 name = linux_to_bsd_so_sockopt(args->optname); 1142 break; 1143 case IPPROTO_IP: 1144 name = linux_to_bsd_ip_sockopt(args->optname); 1145 break; 1146 case IPPROTO_TCP: 1147 /* Linux TCP option values match BSD's */ 1148 name = args->optname; 1149 break; 1150 default: 1151 name = -1; 1152 break; 1153 } 1154 if (name == -1) 1155 return (EINVAL); 1156 1157 bsd_args.name = name; 1158 bsd_args.val = PTRIN(args->optval); 1159 bsd_args.avalsize = PTRIN(args->optlen); 1160 1161 if (name == IPV6_NEXTHOP) { 1162 error = getsockopt(td, &bsd_args); 1163 bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.val); 1164 } else 1165 error = getsockopt(td, &bsd_args); 1166 1167 return (error); 1168 } 1169 1170 int 1171 linux_socketcall(struct thread *td, struct linux_socketcall_args *args) 1172 { 1173 void *arg = (void *)(intptr_t)args->args; 1174 1175 switch (args->what) { 1176 case LINUX_SOCKET: 1177 return (linux_socket(td, arg)); 1178 case LINUX_BIND: 1179 return (linux_bind(td, arg)); 1180 case LINUX_CONNECT: 1181 return (linux_connect(td, arg)); 1182 case LINUX_LISTEN: 1183 return (linux_listen(td, arg)); 1184 case LINUX_ACCEPT: 1185 return (linux_accept(td, arg)); 1186 case LINUX_GETSOCKNAME: 1187 return (linux_getsockname(td, arg)); 1188 case LINUX_GETPEERNAME: 1189 return (linux_getpeername(td, arg)); 1190 case LINUX_SOCKETPAIR: 1191 return (linux_socketpair(td, arg)); 1192 case LINUX_SEND: 1193 return (linux_send(td, arg)); 1194 case LINUX_RECV: 1195 return (linux_recv(td, arg)); 1196 case LINUX_SENDTO: 1197 return (linux_sendto(td, arg)); 1198 case LINUX_RECVFROM: 1199 return (linux_recvfrom(td, arg)); 1200 case LINUX_SHUTDOWN: 1201 return (linux_shutdown(td, arg)); 1202 case LINUX_SETSOCKOPT: 1203 return (linux_setsockopt(td, arg)); 1204 case LINUX_GETSOCKOPT: 1205 return (linux_getsockopt(td, arg)); 1206 case LINUX_SENDMSG: 1207 return (linux_sendmsg(td, arg)); 1208 case LINUX_RECVMSG: 1209 return (linux_recvmsg(td, arg)); 1210 } 1211 1212 uprintf("LINUX: 'socket' typ=%d not implemented\n", args->what); 1213 return (ENOSYS); 1214 } 1215