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