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