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