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