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