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