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