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