1 /* $NetBSD: linux_socket.c,v 1.42 2002/11/29 14:32:27 fvdl 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 * XXX Note: Linux CMSG_ALIGN() uses (sizeof(long)-1). For architectures 44 * where our CMSG_ALIGN() differs (like powerpc, sparc, sparc64), the passed 45 * control structure would need to be adjusted accordingly in sendmsg() and 46 * recvmsg(). 47 */ 48 49 #include <sys/cdefs.h> 50 __KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.42 2002/11/29 14:32:27 fvdl Exp $"); 51 52 #if defined(_KERNEL_OPT) 53 #include "opt_inet.h" 54 #endif 55 56 #include <sys/param.h> 57 #include <sys/kernel.h> 58 #include <sys/systm.h> 59 #include <sys/buf.h> 60 #include <sys/malloc.h> 61 #include <sys/ioctl.h> 62 #include <sys/tty.h> 63 #include <sys/file.h> 64 #include <sys/filedesc.h> 65 #include <sys/select.h> 66 #include <sys/socket.h> 67 #include <sys/socketvar.h> 68 #include <net/if.h> 69 #include <net/if_dl.h> 70 #include <net/if_types.h> 71 #include <netinet/in.h> 72 #include <netinet/tcp.h> 73 #include <sys/mount.h> 74 #include <sys/proc.h> 75 #include <sys/vnode.h> 76 #include <sys/device.h> 77 #include <sys/protosw.h> 78 #include <sys/mbuf.h> 79 #include <sys/syslog.h> 80 81 #include <sys/syscallargs.h> 82 83 #ifdef INET6 84 #include <netinet/ip6.h> 85 #include <netinet6/ip6_var.h> 86 #endif 87 88 #include <compat/linux/common/linux_types.h> 89 #include <compat/linux/common/linux_util.h> 90 #include <compat/linux/common/linux_signal.h> 91 #include <compat/linux/common/linux_ioctl.h> 92 #include <compat/linux/common/linux_socket.h> 93 #include <compat/linux/common/linux_socketcall.h> 94 #include <compat/linux/common/linux_sockio.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 __P((int)); 113 static int bsd_to_linux_domain __P((int)); 114 int linux_to_bsd_sopt_level __P((int)); 115 int linux_to_bsd_so_sockopt __P((int)); 116 int linux_to_bsd_ip_sockopt __P((int)); 117 int linux_to_bsd_tcp_sockopt __P((int)); 118 int linux_to_bsd_udp_sockopt __P((int)); 119 int linux_getifhwaddr __P((struct proc *, register_t *, u_int, void *)); 120 static int linux_sa_get __P((struct proc *, caddr_t *sgp, struct sockaddr **sap, 121 const struct osockaddr *osa, int *osalen)); 122 static int linux_sa_put __P((struct osockaddr *osa)); 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 /* 186 * Convert between Linux and BSD socket domain values 187 */ 188 static int 189 linux_to_bsd_domain(ldom) 190 int ldom; 191 { 192 if (ldom < 0 || ldom >= LINUX_AF_MAX) 193 return (-1); 194 195 return linux_to_bsd_domain_[ldom]; 196 } 197 198 /* 199 * Convert between BSD and Linux socket domain values 200 */ 201 static int 202 bsd_to_linux_domain(bdom) 203 int bdom; 204 { 205 if (bdom < 0 || bdom >= AF_MAX) 206 return (-1); 207 208 return bsd_to_linux_domain_[bdom]; 209 } 210 211 int 212 linux_sys_socket(p, v, retval) 213 struct proc *p; 214 void *v; 215 register_t *retval; 216 { 217 struct linux_sys_socket_args /* { 218 syscallarg(int) domain; 219 syscallarg(int) type; 220 syscallarg(int) protocol; 221 } */ *uap = v; 222 struct sys_socket_args bsa; 223 int error; 224 225 SCARG(&bsa, protocol) = SCARG(uap, protocol); 226 SCARG(&bsa, type) = SCARG(uap, type); 227 SCARG(&bsa, domain) = linux_to_bsd_domain(SCARG(uap, domain)); 228 if (SCARG(&bsa, domain) == -1) 229 return EINVAL; 230 error = sys_socket(p, &bsa, retval); 231 232 #ifdef INET6 233 /* 234 * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by 235 * default and some apps depend on this. So, set V6ONLY to 0 236 * for Linux apps if the sysctl value is set to 1. 237 */ 238 if (!error && ip6_v6only && SCARG(&bsa, domain) == PF_INET6) { 239 struct file *fp; 240 241 if (getsock(p->p_fd, *retval, &fp) == 0) { 242 struct mbuf *m; 243 244 m = m_get(M_WAIT, MT_SOOPTS); 245 m->m_len = sizeof(int); 246 *mtod(m, int *) = 0; 247 248 /* ignore error */ 249 (void) sosetopt((struct socket *)fp->f_data, 250 IPPROTO_IPV6, IPV6_V6ONLY, m); 251 252 FILE_UNUSE(fp, p); 253 } 254 } 255 #endif 256 257 return (error); 258 } 259 260 int 261 linux_sys_socketpair(p, v, retval) 262 struct proc *p; 263 void *v; 264 register_t *retval; 265 { 266 struct linux_sys_socketpair_args /* { 267 syscallarg(int) domain; 268 syscallarg(int) type; 269 syscallarg(int) protocol; 270 syscallarg(int *) rsv; 271 } */ *uap = v; 272 struct sys_socketpair_args bsa; 273 274 SCARG(&bsa, domain) = linux_to_bsd_domain(SCARG(uap, domain)); 275 if (SCARG(&bsa, domain) == -1) 276 return EINVAL; 277 SCARG(&bsa, type) = SCARG(uap, type); 278 SCARG(&bsa, protocol) = SCARG(uap, protocol); 279 SCARG(&bsa, rsv) = SCARG(uap, rsv); 280 281 return sys_socketpair(p, &bsa, retval); 282 } 283 284 int 285 linux_sys_sendto(p, v, retval) 286 struct proc *p; 287 void *v; 288 register_t *retval; 289 { 290 struct linux_sys_sendto_args /* { 291 syscallarg(int) s; 292 syscallarg(void *) msg; 293 syscallarg(int) len; 294 syscallarg(int) flags; 295 syscallarg(struct osockaddr *) to; 296 syscallarg(int) tolen; 297 } */ *uap = v; 298 struct sys_sendto_args bsa; 299 int tolen; 300 301 SCARG(&bsa, s) = SCARG(uap, s); 302 SCARG(&bsa, buf) = SCARG(uap, msg); 303 SCARG(&bsa, len) = (size_t) SCARG(uap, len); 304 SCARG(&bsa, flags) = SCARG(uap, flags); 305 tolen = SCARG(uap, tolen); 306 if (SCARG(uap, to)) { 307 struct sockaddr *sa; 308 int error; 309 caddr_t sg = stackgap_init(p, 0); 310 311 if ((error = linux_sa_get(p, &sg, &sa, SCARG(uap, to), &tolen))) 312 return (error); 313 314 SCARG(&bsa, to) = sa; 315 } else 316 SCARG(&bsa, to) = NULL; 317 SCARG(&bsa, tolen) = tolen; 318 319 return (sys_sendto(p, &bsa, retval)); 320 } 321 322 int 323 linux_sys_sendmsg(p, v, retval) 324 struct proc *p; 325 void *v; 326 register_t *retval; 327 { 328 struct linux_sys_sendmsg_args /* { 329 syscallarg(int) s; 330 syscallarg(struct msghdr *) msg; 331 syscallarg(u_int) flags; 332 } */ *uap = v; 333 struct msghdr msg; 334 int error; 335 struct sys_sendmsg_args bsa; 336 struct msghdr *nmsg = NULL; 337 338 error = copyin(SCARG(uap, msg), (caddr_t)&msg, sizeof(msg)); 339 if (error) 340 return (error); 341 342 if (msg.msg_name) { 343 struct sockaddr *sa; 344 caddr_t sg = stackgap_init(p, 0); 345 346 nmsg = (struct msghdr *) stackgap_alloc(p, &sg, 347 sizeof(struct msghdr)); 348 if (!nmsg) 349 return (ENOMEM); 350 351 error = linux_sa_get(p, &sg, &sa, 352 (struct osockaddr *) msg.msg_name, &msg.msg_namelen); 353 if (error) 354 return (error); 355 356 msg.msg_name = (struct sockaddr *) sa; 357 if ((error = copyout(&msg, nmsg, sizeof(struct msghdr)))) 358 return (error); 359 } 360 361 /* 362 * XXX handle different alignment of cmsg data on architectures where 363 * the Linux alignment is different (powerpc, sparc, sparc64). 364 */ 365 366 SCARG(&bsa, s) = SCARG(uap, s); 367 SCARG(&bsa, msg) = nmsg; 368 SCARG(&bsa, flags) = SCARG(uap, flags); 369 370 if ((error = sys_sendmsg(p, &bsa, retval))) 371 return (error); 372 373 return (0); 374 } 375 376 377 int 378 linux_sys_recvfrom(p, v, retval) 379 struct proc *p; 380 void *v; 381 register_t *retval; 382 { 383 struct linux_sys_recvfrom_args /* { 384 syscallarg(int) s; 385 syscallarg(void *) buf; 386 syscallarg(int) len; 387 syscallarg(int) flags; 388 syscallarg(struct osockaddr *) from; 389 syscallarg(int *) fromlenaddr; 390 } */ *uap = v; 391 int error; 392 struct sys_recvfrom_args bra; 393 394 SCARG(&bra, s) = SCARG(uap, s); 395 SCARG(&bra, buf) = SCARG(uap, buf); 396 SCARG(&bra, len) = SCARG(uap, len); 397 SCARG(&bra, flags) = SCARG(uap, flags); 398 SCARG(&bra, from) = (struct sockaddr *) SCARG(uap, from); 399 SCARG(&bra, fromlenaddr) = SCARG(uap, fromlenaddr); 400 401 if ((error = sys_recvfrom(p, &bra, retval))) 402 return (error); 403 404 if (SCARG(uap, from) && (error = linux_sa_put(SCARG(uap, from)))) 405 return (error); 406 407 return (0); 408 } 409 410 int 411 linux_sys_recvmsg(p, v, retval) 412 struct proc *p; 413 void *v; 414 register_t *retval; 415 { 416 struct linux_sys_recvmsg_args /* { 417 syscallarg(int) s; 418 syscallarg(struct msghdr *) msg; 419 syscallarg(u_int) flags; 420 } */ *uap = v; 421 struct msghdr msg; 422 int error; 423 424 if ((error = sys_recvmsg(p, v, retval))) 425 return (error); 426 427 error = copyin((caddr_t)SCARG(uap, msg), (caddr_t)&msg, 428 sizeof(msg)); 429 430 if (!error && msg.msg_name && msg.msg_namelen > 2) 431 error = linux_sa_put(msg.msg_name); 432 433 /* 434 * XXX handle different alignment of cmsg data on architectures where 435 * the Linux alignment is different (powerpc, sparc, sparc64). 436 */ 437 438 return (error); 439 } 440 441 /* 442 * Convert socket option level from Linux to NetBSD value. Only SOL_SOCKET 443 * is different, the rest matches IPPROTO_* on both systems. 444 */ 445 int 446 linux_to_bsd_sopt_level(llevel) 447 int llevel; 448 { 449 450 switch (llevel) { 451 case LINUX_SOL_SOCKET: 452 return SOL_SOCKET; 453 case LINUX_SOL_IP: 454 return IPPROTO_IP; 455 case LINUX_SOL_TCP: 456 return IPPROTO_TCP; 457 case LINUX_SOL_UDP: 458 return IPPROTO_UDP; 459 default: 460 return -1; 461 } 462 } 463 464 /* 465 * Convert Linux socket level socket option numbers to NetBSD values. 466 */ 467 int 468 linux_to_bsd_so_sockopt(lopt) 469 int lopt; 470 { 471 472 switch (lopt) { 473 case LINUX_SO_DEBUG: 474 return SO_DEBUG; 475 case LINUX_SO_REUSEADDR: 476 /* 477 * Linux does not implement SO_REUSEPORT, but allows reuse of a 478 * host:port pair through SO_REUSEADDR even if the address is not a 479 * multicast-address. Effectively, this means that we should use 480 * SO_REUSEPORT to allow Linux applications to not exit with 481 * EADDRINUSE 482 */ 483 return SO_REUSEPORT; 484 case LINUX_SO_TYPE: 485 return SO_TYPE; 486 case LINUX_SO_ERROR: 487 return SO_ERROR; 488 case LINUX_SO_DONTROUTE: 489 return SO_DONTROUTE; 490 case LINUX_SO_BROADCAST: 491 return SO_BROADCAST; 492 case LINUX_SO_SNDBUF: 493 return SO_SNDBUF; 494 case LINUX_SO_RCVBUF: 495 return SO_RCVBUF; 496 case LINUX_SO_KEEPALIVE: 497 return SO_KEEPALIVE; 498 case LINUX_SO_OOBINLINE: 499 return SO_OOBINLINE; 500 case LINUX_SO_LINGER: 501 return SO_LINGER; 502 case LINUX_SO_PRIORITY: 503 case LINUX_SO_NO_CHECK: 504 default: 505 return -1; 506 } 507 } 508 509 /* 510 * Convert Linux IP level socket option number to NetBSD values. 511 */ 512 int 513 linux_to_bsd_ip_sockopt(lopt) 514 int lopt; 515 { 516 517 switch (lopt) { 518 case LINUX_IP_TOS: 519 return IP_TOS; 520 case LINUX_IP_TTL: 521 return IP_TTL; 522 case LINUX_IP_MULTICAST_TTL: 523 return IP_MULTICAST_TTL; 524 case LINUX_IP_MULTICAST_LOOP: 525 return IP_MULTICAST_LOOP; 526 case LINUX_IP_MULTICAST_IF: 527 return IP_MULTICAST_IF; 528 case LINUX_IP_ADD_MEMBERSHIP: 529 return IP_ADD_MEMBERSHIP; 530 case LINUX_IP_DROP_MEMBERSHIP: 531 return IP_DROP_MEMBERSHIP; 532 default: 533 return -1; 534 } 535 } 536 537 /* 538 * Convert Linux TCP level socket option number to NetBSD values. 539 */ 540 int 541 linux_to_bsd_tcp_sockopt(lopt) 542 int lopt; 543 { 544 545 switch (lopt) { 546 case LINUX_TCP_NODELAY: 547 return TCP_NODELAY; 548 case LINUX_TCP_MAXSEG: 549 return TCP_MAXSEG; 550 default: 551 return -1; 552 } 553 } 554 555 /* 556 * Convert Linux UDP level socket option number to NetBSD values. 557 */ 558 int 559 linux_to_bsd_udp_sockopt(lopt) 560 int lopt; 561 { 562 563 switch (lopt) { 564 default: 565 return -1; 566 } 567 } 568 569 /* 570 * Another reasonably straightforward function: setsockopt(2). 571 * The level and option numbers are converted; the values passed 572 * are not (yet) converted, the ones currently implemented don't 573 * need conversion, as they are the same on both systems. 574 */ 575 int 576 linux_sys_setsockopt(p, v, retval) 577 struct proc *p; 578 void *v; 579 register_t *retval; 580 { 581 struct linux_sys_setsockopt_args /* { 582 syscallarg(int) s; 583 syscallarg(int) level; 584 syscallarg(int) optname; 585 syscallarg(void *) optval; 586 syscallarg(int) optlen; 587 } */ *uap = v; 588 struct sys_setsockopt_args bsa; 589 int name; 590 591 SCARG(&bsa, s) = SCARG(uap, s); 592 SCARG(&bsa, level) = linux_to_bsd_sopt_level(SCARG(uap, level)); 593 SCARG(&bsa, val) = SCARG(uap, optval); 594 SCARG(&bsa, valsize) = SCARG(uap, optlen); 595 596 switch (SCARG(&bsa, level)) { 597 case SOL_SOCKET: 598 name = linux_to_bsd_so_sockopt(SCARG(uap, optname)); 599 break; 600 case IPPROTO_IP: 601 name = linux_to_bsd_ip_sockopt(SCARG(uap, optname)); 602 break; 603 case IPPROTO_TCP: 604 name = linux_to_bsd_tcp_sockopt(SCARG(uap, optname)); 605 break; 606 case IPPROTO_UDP: 607 name = linux_to_bsd_udp_sockopt(SCARG(uap, optname)); 608 break; 609 default: 610 return EINVAL; 611 } 612 613 if (name == -1) 614 return EINVAL; 615 SCARG(&bsa, name) = name; 616 617 return sys_setsockopt(p, &bsa, retval); 618 } 619 620 /* 621 * getsockopt(2) is very much the same as setsockopt(2) (see above) 622 */ 623 int 624 linux_sys_getsockopt(p, v, retval) 625 struct proc *p; 626 void *v; 627 register_t *retval; 628 { 629 struct linux_sys_getsockopt_args /* { 630 syscallarg(int) s; 631 syscallarg(int) level; 632 syscallarg(int) optname; 633 syscallarg(void *) optval; 634 syscallarg(int *) optlen; 635 } */ *uap = v; 636 struct sys_getsockopt_args bga; 637 int name; 638 639 SCARG(&bga, s) = SCARG(uap, s); 640 SCARG(&bga, level) = linux_to_bsd_sopt_level(SCARG(uap, level)); 641 SCARG(&bga, val) = SCARG(uap, optval); 642 SCARG(&bga, avalsize) = SCARG(uap, optlen); 643 644 switch (SCARG(&bga, level)) { 645 case SOL_SOCKET: 646 name = linux_to_bsd_so_sockopt(SCARG(uap, optname)); 647 break; 648 case IPPROTO_IP: 649 name = linux_to_bsd_ip_sockopt(SCARG(uap, optname)); 650 break; 651 case IPPROTO_TCP: 652 name = linux_to_bsd_tcp_sockopt(SCARG(uap, optname)); 653 break; 654 case IPPROTO_UDP: 655 name = linux_to_bsd_udp_sockopt(SCARG(uap, optname)); 656 break; 657 default: 658 return EINVAL; 659 } 660 661 if (name == -1) 662 return EINVAL; 663 SCARG(&bga, name) = name; 664 665 return sys_getsockopt(p, &bga, retval); 666 } 667 668 #define IF_NAME_LEN 16 669 670 int 671 linux_getifhwaddr(p, retval, fd, data) 672 struct proc *p; 673 register_t *retval; 674 u_int fd; 675 void *data; 676 { 677 /* Not the full structure, just enough to map what we do here */ 678 struct linux_ifreq { 679 char if_name[IF_NAME_LEN]; 680 struct osockaddr hwaddr; 681 } lreq; 682 struct filedesc *fdp; 683 struct file *fp; 684 struct ifaddr *ifa; 685 struct ifnet *ifp; 686 struct sockaddr_dl *sadl; 687 int error, found; 688 int index, ifnum; 689 690 /* 691 * We can't emulate this ioctl by calling sys_ioctl() to run 692 * SIOCGIFCONF, because the user buffer is not of the right 693 * type to take those results. We can't use kernel buffers to 694 * receive the results, as the implementation of sys_ioctl() 695 * and ifconf() [which implements SIOCGIFCONF] use 696 * copyin()/copyout() which will fail on kernel addresses. 697 * 698 * So, we must duplicate code from sys_ioctl() and ifconf(). Ugh. 699 */ 700 701 fdp = p->p_fd; 702 if ((fp = fd_getfile(fdp, fd)) == NULL) 703 return (EBADF); 704 705 FILE_USE(fp); 706 if ((fp->f_flag & (FREAD | FWRITE)) == 0) { 707 error = EBADF; 708 goto out; 709 } 710 711 error = copyin(data, (caddr_t)&lreq, sizeof(lreq)); 712 if (error) 713 goto out; 714 lreq.if_name[IF_NAME_LEN-1] = '\0'; /* just in case */ 715 716 /* 717 * Try real interface name first, then fake "ethX" 718 */ 719 for (ifp = ifnet.tqh_first, found = 0; 720 ifp != 0 && !found; 721 ifp = ifp->if_list.tqe_next) { 722 if (strcmp(lreq.if_name, ifp->if_xname)) 723 /* not this interface */ 724 continue; 725 found=1; 726 if ((ifa = ifp->if_addrlist.tqh_first) != 0) { 727 for (; ifa != 0; ifa = ifa->ifa_list.tqe_next) { 728 sadl = (struct sockaddr_dl *)ifa->ifa_addr; 729 /* only return ethernet addresses */ 730 /* XXX what about FDDI, etc. ? */ 731 if (sadl->sdl_family != AF_LINK || 732 sadl->sdl_type != IFT_ETHER) 733 continue; 734 memcpy((caddr_t)&lreq.hwaddr.sa_data, 735 LLADDR(sadl), 736 MIN(sadl->sdl_alen, 737 sizeof(lreq.hwaddr.sa_data))); 738 lreq.hwaddr.sa_family = 739 sadl->sdl_family; 740 error = copyout((caddr_t)&lreq, data, 741 sizeof(lreq)); 742 goto out; 743 } 744 } else { 745 error = ENODEV; 746 goto out; 747 } 748 } 749 750 if (strncmp(lreq.if_name, "eth", 3) == 0) { 751 for (ifnum = 0, index = 3; 752 lreq.if_name[index] != '\0' && index < IF_NAME_LEN; 753 index++) { 754 ifnum *= 10; 755 ifnum += lreq.if_name[index] - '0'; 756 } 757 758 error = EINVAL; /* in case we don't find one */ 759 for (ifp = ifnet.tqh_first, found = 0; 760 ifp != 0 && !found; 761 ifp = ifp->if_list.tqe_next) { 762 memcpy(lreq.if_name, ifp->if_xname, 763 MIN(IF_NAME_LEN, IFNAMSIZ)); 764 if ((ifa = ifp->if_addrlist.tqh_first) == 0) 765 /* no addresses on this interface */ 766 continue; 767 else 768 for (; ifa != 0; ifa = ifa->ifa_list.tqe_next) { 769 sadl = (struct sockaddr_dl *)ifa->ifa_addr; 770 /* only return ethernet addresses */ 771 /* XXX what about FDDI, etc. ? */ 772 if (sadl->sdl_family != AF_LINK || 773 sadl->sdl_type != IFT_ETHER) 774 continue; 775 if (ifnum--) 776 /* not the reqested iface */ 777 continue; 778 memcpy((caddr_t)&lreq.hwaddr.sa_data, 779 LLADDR(sadl), 780 MIN(sadl->sdl_alen, 781 sizeof(lreq.hwaddr.sa_data))); 782 lreq.hwaddr.sa_family = 783 sadl->sdl_family; 784 error = copyout((caddr_t)&lreq, data, 785 sizeof(lreq)); 786 found = 1; 787 break; 788 } 789 } 790 } else { 791 /* unknown interface, not even an "eth*" name */ 792 error = ENODEV; 793 } 794 795 out: 796 FILE_UNUSE(fp, p); 797 return error; 798 } 799 #undef IF_NAME_LEN 800 801 int 802 linux_ioctl_socket(p, uap, retval) 803 struct proc *p; 804 struct linux_sys_ioctl_args /* { 805 syscallarg(int) fd; 806 syscallarg(u_long) com; 807 syscallarg(caddr_t) data; 808 } */ *uap; 809 register_t *retval; 810 { 811 u_long com; 812 int error = 0, isdev = 0, dosys = 1; 813 struct sys_ioctl_args ia; 814 struct file *fp; 815 struct filedesc *fdp; 816 struct vnode *vp; 817 int (*ioctlf) __P((struct file *, u_long, caddr_t, struct proc *)); 818 struct ioctl_pt pt; 819 820 fdp = p->p_fd; 821 if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL) 822 return (EBADF); 823 824 FILE_USE(fp); 825 826 if (fp->f_type == DTYPE_VNODE) { 827 vp = (struct vnode *)fp->f_data; 828 isdev = vp->v_type == VCHR; 829 } 830 831 /* 832 * Don't try to interpret socket ioctl calls that are done 833 * on a device filedescriptor, just pass them through, to 834 * emulate Linux behaviour. Use PTIOCLINUX so that the 835 * device will only handle these if it's prepared to do 836 * so, to avoid unexpected things from happening. 837 */ 838 if (isdev) { 839 dosys = 0; 840 ioctlf = fp->f_ops->fo_ioctl; 841 pt.com = SCARG(uap, com); 842 pt.data = SCARG(uap, data); 843 error = ioctlf(fp, PTIOCLINUX, (caddr_t)&pt, p); 844 /* 845 * XXX hack: if the function returns EJUSTRETURN, 846 * it has stuffed a sysctl return value in pt.data. 847 */ 848 if (error == EJUSTRETURN) { 849 retval[0] = (register_t)pt.data; 850 error = 0; 851 } 852 goto out; 853 } 854 855 com = SCARG(uap, com); 856 retval[0] = 0; 857 858 switch (com) { 859 case LINUX_SIOCGIFCONF: 860 SCARG(&ia, com) = OSIOCGIFCONF; 861 break; 862 case LINUX_SIOCGIFFLAGS: 863 SCARG(&ia, com) = SIOCGIFFLAGS; 864 break; 865 case LINUX_SIOCSIFFLAGS: 866 SCARG(&ia, com) = SIOCSIFFLAGS; 867 break; 868 case LINUX_SIOCGIFADDR: 869 SCARG(&ia, com) = OSIOCGIFADDR; 870 break; 871 case LINUX_SIOCGIFDSTADDR: 872 SCARG(&ia, com) = OSIOCGIFDSTADDR; 873 break; 874 case LINUX_SIOCGIFBRDADDR: 875 SCARG(&ia, com) = OSIOCGIFBRDADDR; 876 break; 877 case LINUX_SIOCGIFNETMASK: 878 SCARG(&ia, com) = OSIOCGIFNETMASK; 879 break; 880 case LINUX_SIOCADDMULTI: 881 SCARG(&ia, com) = SIOCADDMULTI; 882 break; 883 case LINUX_SIOCDELMULTI: 884 SCARG(&ia, com) = SIOCDELMULTI; 885 break; 886 case LINUX_SIOCGIFHWADDR: 887 error = linux_getifhwaddr(p, retval, SCARG(uap, fd), 888 SCARG(uap, data)); 889 dosys = 0; 890 break; 891 default: 892 error = EINVAL; 893 } 894 895 out: 896 FILE_UNUSE(fp, p); 897 898 if (error ==0 && dosys) { 899 SCARG(&ia, fd) = SCARG(uap, fd); 900 SCARG(&ia, data) = SCARG(uap, data); 901 error = sys_ioctl(p, &ia, retval); 902 } 903 904 return error; 905 } 906 907 int 908 linux_sys_connect(p, v, retval) 909 struct proc *p; 910 void *v; 911 register_t *retval; 912 { 913 struct linux_sys_connect_args /* { 914 syscallarg(int) s; 915 syscallarg(const struct sockaddr *) name; 916 syscallarg(int) namelen; 917 } */ *uap = v; 918 int error; 919 struct sockaddr *sa; 920 struct sys_connect_args bca; 921 caddr_t sg = stackgap_init(p, 0); 922 int namlen; 923 924 namlen = SCARG(uap, namelen); 925 error = linux_sa_get(p, &sg, &sa, SCARG(uap, name), &namlen); 926 if (error) 927 return (error); 928 929 SCARG(&bca, s) = SCARG(uap, s); 930 SCARG(&bca, name) = sa; 931 SCARG(&bca, namelen) = (unsigned int) namlen; 932 933 error = sys_connect(p, &bca, retval); 934 935 if (error == EISCONN) { 936 struct file *fp; 937 struct socket *so; 938 int s, state, prflags; 939 940 /* getsock() will use the descriptor for us */ 941 if (getsock(p->p_fd, SCARG(uap, s), &fp) != 0) 942 return EISCONN; 943 944 s = splsoftnet(); 945 so = (struct socket *)fp->f_data; 946 state = so->so_state; 947 prflags = so->so_proto->pr_flags; 948 splx(s); 949 FILE_UNUSE(fp, p); 950 /* 951 * We should only let this call succeed once per 952 * non-blocking connect; however we don't have 953 * a convenient place to keep that state.. 954 */ 955 if ((state & SS_NBIO) && (state & SS_ISCONNECTED) && 956 (prflags & PR_CONNREQUIRED)) 957 return 0; 958 } 959 960 return (error); 961 } 962 963 int 964 linux_sys_bind(p, v, retval) 965 struct proc *p; 966 void *v; 967 register_t *retval; 968 { 969 struct linux_sys_bind_args /* { 970 syscallarg(int) s; 971 syscallarg(const struct osockaddr *) name; 972 syscallarg(int) namelen; 973 } */ *uap = v; 974 int error, namlen; 975 struct sys_bind_args bsa; 976 977 namlen = SCARG(uap, namelen); 978 SCARG(&bsa, s) = SCARG(uap, s); 979 if (SCARG(uap, name)) { 980 struct sockaddr *sa; 981 caddr_t sg = stackgap_init(p, 0); 982 983 error = linux_sa_get(p, &sg, &sa, SCARG(uap, name), &namlen); 984 if (error) 985 return (error); 986 987 SCARG(&bsa, name) = sa; 988 } else 989 SCARG(&bsa, name) = NULL; 990 SCARG(&bsa, namelen) = namlen; 991 992 return (sys_bind(p, &bsa, retval)); 993 } 994 995 int 996 linux_sys_getsockname(p, v, retval) 997 struct proc *p; 998 void *v; 999 register_t *retval; 1000 { 1001 struct linux_sys_getsockname_args /* { 1002 syscallarg(int) fdes; 1003 syscallarg(caddr_t) asa; 1004 syscallarg(int *) alen; 1005 } */ *uap = v; 1006 int error; 1007 1008 if ((error = sys_getsockname(p, uap, retval)) != 0) 1009 return (error); 1010 1011 if ((error = linux_sa_put((struct osockaddr *)SCARG(uap, asa)))) 1012 return (error); 1013 1014 return (0); 1015 } 1016 1017 int 1018 linux_sys_getpeername(p, v, retval) 1019 struct proc *p; 1020 void *v; 1021 register_t *retval; 1022 { 1023 struct sys_getpeername_args /* { 1024 syscallarg(int) fdes; 1025 syscallarg(caddr_t) asa; 1026 syscallarg(int *) alen; 1027 } */ *uap = v; 1028 int error; 1029 1030 if ((error = sys_getpeername(p, uap, retval)) != 0) 1031 return (error); 1032 1033 if ((error = linux_sa_put((struct osockaddr *)SCARG(uap, asa)))) 1034 return (error); 1035 1036 return (0); 1037 } 1038 1039 /* 1040 * Copy the osockaddr structure pointed to by osa to kernel, adjust 1041 * family and convert to sockaddr, allocate stackgap and put the 1042 * the converted structure there, address on stackgap returned in sap. 1043 */ 1044 static int 1045 linux_sa_get(p, sgp, sap, osa, osalen) 1046 struct proc *p; 1047 caddr_t *sgp; 1048 struct sockaddr **sap; 1049 const struct osockaddr *osa; 1050 int *osalen; 1051 { 1052 int error=0, bdom; 1053 struct sockaddr *sa, *usa; 1054 struct osockaddr *kosa = (struct osockaddr *) &sa; 1055 int alloclen; 1056 #ifdef INET6 1057 int oldv6size; 1058 struct sockaddr_in6 *sin6; 1059 #endif 1060 1061 if (*osalen < 2 || *osalen > UCHAR_MAX || !osa) { 1062 DPRINTF(("bad osa=%p osalen=%d\n", osa, *osalen)); 1063 return (EINVAL); 1064 } 1065 1066 alloclen = *osalen; 1067 #ifdef INET6 1068 oldv6size = 0; 1069 /* 1070 * Check for old (pre-RFC2553) sockaddr_in6. We may accept it 1071 * if it's a v4-mapped address, so reserve the proper space 1072 * for it. 1073 */ 1074 if (alloclen == sizeof (struct sockaddr_in6) - sizeof (u_int32_t)) { 1075 alloclen = sizeof (struct sockaddr_in6); 1076 oldv6size = 1; 1077 } 1078 #endif 1079 1080 kosa = (struct osockaddr *) malloc(alloclen, M_TEMP, M_WAITOK); 1081 1082 if ((error = copyin(osa, (caddr_t) kosa, *osalen))) { 1083 DPRINTF(("error copying osa %d\n", error)); 1084 goto out; 1085 } 1086 1087 bdom = linux_to_bsd_domain(kosa->sa_family); 1088 if (bdom == -1) { 1089 DPRINTF(("bad linux family=%d\n", kosa->sa_family)); 1090 error = EINVAL; 1091 goto out; 1092 } 1093 1094 #ifdef INET6 1095 /* 1096 * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6, 1097 * which lacks the scope id compared with RFC2553 one. If we detect 1098 * the situation, reject the address and write a message to system log. 1099 * 1100 * Still accept addresses for which the scope id is not used. 1101 */ 1102 if (oldv6size && bdom == AF_INET6) { 1103 sin6 = (struct sockaddr_in6 *)kosa; 1104 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) || 1105 (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) && 1106 !IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) && 1107 !IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) && 1108 !IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) && 1109 !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) { 1110 sin6->sin6_scope_id = 0; 1111 } else { 1112 struct proc *p = curproc; /* XXX */ 1113 int uid = p->p_cred && p->p_ucred ? 1114 p->p_ucred->cr_uid : -1; 1115 1116 log(LOG_DEBUG, 1117 "pid %d (%s), uid %d: obsolete pre-RFC2553 " 1118 "sockaddr_in6 rejected", 1119 p->p_pid, p->p_comm, uid); 1120 error = EINVAL; 1121 goto out; 1122 } 1123 } else 1124 #endif 1125 if (bdom == AF_INET) { 1126 alloclen = sizeof(struct sockaddr_in); 1127 } 1128 1129 sa = (struct sockaddr *) kosa; 1130 sa->sa_family = bdom; 1131 sa->sa_len = alloclen; 1132 #ifdef DEBUG_LINUX 1133 DPRINTF(("family %d, len = %d [ ", sa->sa_family, sa->sa_len)); 1134 for (bdom = 0; bdom < sizeof(sa->sa_data); bdom++) 1135 DPRINTF(("%02x ", sa->sa_data[bdom])); 1136 DPRINTF(("\n")); 1137 #endif 1138 1139 usa = (struct sockaddr *) stackgap_alloc(p, sgp, alloclen); 1140 if (!usa) { 1141 error = ENOMEM; 1142 goto out; 1143 } 1144 1145 if ((error = copyout(sa, usa, alloclen))) { 1146 DPRINTF(("error copying out socket %d\n", error)); 1147 goto out; 1148 } 1149 1150 *sap = usa; 1151 1152 out: 1153 *osalen = alloclen; 1154 free(kosa, M_TEMP); 1155 return (error); 1156 } 1157 1158 static int 1159 linux_sa_put(osa) 1160 struct osockaddr *osa; 1161 { 1162 struct sockaddr sa; 1163 struct osockaddr *kosa; 1164 int error, bdom, len; 1165 1166 /* 1167 * Only read/write the sockaddr family and length part, the rest is 1168 * not changed. 1169 */ 1170 len = sizeof(sa.sa_len) + sizeof(sa.sa_family); 1171 1172 error = copyin((caddr_t) osa, (caddr_t) &sa, len); 1173 if (error) 1174 return (error); 1175 1176 bdom = bsd_to_linux_domain(sa.sa_family); 1177 if (bdom == -1) 1178 return (EINVAL); 1179 1180 /* Note: we convert from sockaddr to osockaddr here, too */ 1181 kosa = (struct osockaddr *) &sa; 1182 kosa->sa_family = bdom; 1183 error = copyout(kosa, osa, len); 1184 if (error) 1185 return (error); 1186 1187 return (0); 1188 } 1189 1190 int 1191 linux_sys_recv(p, v, retval) 1192 struct proc *p; 1193 void *v; 1194 register_t *retval; 1195 { 1196 struct linux_sys_recv_args /* { 1197 syscallarg(int) s; 1198 syscallarg(void *) buf; 1199 syscallarg(int) len; 1200 syscallarg(int) flags; 1201 } */ *uap = v; 1202 struct sys_recvfrom_args bra; 1203 1204 1205 SCARG(&bra, s) = SCARG(uap, s); 1206 SCARG(&bra, buf) = SCARG(uap, buf); 1207 SCARG(&bra, len) = (size_t) SCARG(uap, len); 1208 SCARG(&bra, flags) = SCARG(uap, flags); 1209 SCARG(&bra, from) = NULL; 1210 SCARG(&bra, fromlenaddr) = NULL; 1211 1212 return (sys_recvfrom(p, &bra, retval)); 1213 } 1214 1215 int 1216 linux_sys_send(p, v, retval) 1217 struct proc *p; 1218 void *v; 1219 register_t *retval; 1220 { 1221 struct linux_sys_send_args /* { 1222 syscallarg(int) s; 1223 syscallarg(caddr_t) buf; 1224 syscallarg(int) len; 1225 syscallarg(int) flags; 1226 } */ *uap = v; 1227 struct sys_sendto_args bsa; 1228 1229 SCARG(&bsa, s) = SCARG(uap, s); 1230 SCARG(&bsa, buf) = SCARG(uap, buf); 1231 SCARG(&bsa, len) = SCARG(uap, len); 1232 SCARG(&bsa, flags) = SCARG(uap, flags); 1233 SCARG(&bsa, to) = NULL; 1234 SCARG(&bsa, tolen) = 0; 1235 1236 return (sys_sendto(p, &bsa, retval)); 1237 } 1238 1239 int 1240 linux_sys_accept(p, v, retval) 1241 struct proc *p; 1242 void *v; 1243 register_t *retval; 1244 { 1245 struct linux_sys_accept_args /* { 1246 syscallarg(int) s; 1247 syscallarg(struct osockaddr *) name; 1248 syscallarg(int *) anamelen; 1249 } */ *uap = v; 1250 int error; 1251 struct sys_accept_args baa; 1252 1253 SCARG(&baa, s) = SCARG(uap, s); 1254 SCARG(&baa, name) = (struct sockaddr *) SCARG(uap, name); 1255 SCARG(&baa, anamelen) = (unsigned int *) SCARG(uap, anamelen); 1256 1257 if ((error = sys_accept(p, &baa, retval))) 1258 return (error); 1259 1260 if (SCARG(uap, name) && (error = linux_sa_put(SCARG(uap, name)))) 1261 return (error); 1262 1263 return (0); 1264 } 1265