1 /* $NetBSD: linux_socket.c,v 1.33 2001/07/04 10:24:18 jdolecek 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 258 SCARG(&bsa, s) = SCARG(uap, s); 259 SCARG(&bsa, buf) = SCARG(uap, msg); 260 SCARG(&bsa, len) = (size_t) SCARG(uap, len); 261 SCARG(&bsa, flags) = SCARG(uap, flags); 262 if (SCARG(uap, to)) { 263 struct sockaddr *sa; 264 int error; 265 caddr_t sg = stackgap_init(p->p_emul); 266 267 if ((error = linux_sa_get(&sg, &sa, SCARG(uap, to), 268 SCARG(uap, tolen)))) 269 return (error); 270 271 SCARG(&bsa, to) = sa; 272 } else 273 SCARG(&bsa, to) = NULL; 274 SCARG(&bsa, tolen) = SCARG(uap, tolen); 275 276 return (sys_sendto(p, &bsa, retval)); 277 } 278 279 int 280 linux_sys_sendmsg(p, v, retval) 281 struct proc *p; 282 void *v; 283 register_t *retval; 284 { 285 struct linux_sys_sendmsg_args /* { 286 syscallarg(int) s; 287 syscallarg(struct msghdr *) msg; 288 syscallarg(u_int) flags; 289 } */ *uap = v; 290 struct msghdr msg; 291 int error; 292 struct sys_sendmsg_args bsa; 293 struct msghdr *nmsg = NULL; 294 295 error = copyin(SCARG(uap, msg), (caddr_t)&msg, sizeof(msg)); 296 if (error) 297 return (error); 298 299 if (msg.msg_name) { 300 struct sockaddr *sa; 301 caddr_t sg = stackgap_init(p->p_emul); 302 303 nmsg = (struct msghdr *) stackgap_alloc(&sg, 304 sizeof(struct msghdr)); 305 if (!nmsg) 306 return (ENOMEM); 307 308 error = linux_sa_get(&sg, &sa, 309 (struct osockaddr *) msg.msg_name, msg.msg_namelen); 310 if (error) 311 return (error); 312 313 msg.msg_name = (struct sockaddr *) sa; 314 if ((error = copyout(&msg, nmsg, sizeof(struct msghdr)))) 315 return (error); 316 } 317 318 /* 319 * XXX handle different alignment of cmsg data on architectures where 320 * the Linux alignment is different (powerpc, sparc, sparc64). 321 */ 322 323 SCARG(&bsa, s) = SCARG(uap, s); 324 SCARG(&bsa, msg) = nmsg; 325 SCARG(&bsa, flags) = SCARG(uap, flags); 326 327 if ((error = sys_sendmsg(p, &bsa, retval))) 328 return (error); 329 330 return (0); 331 } 332 333 334 int 335 linux_sys_recvfrom(p, v, retval) 336 struct proc *p; 337 void *v; 338 register_t *retval; 339 { 340 struct linux_sys_recvfrom_args /* { 341 syscallarg(int) s; 342 syscallarg(void *) buf; 343 syscallarg(int) len; 344 syscallarg(int) flags; 345 syscallarg(struct osockaddr *) from; 346 syscallarg(int *) fromlenaddr; 347 } */ *uap = v; 348 int error; 349 struct sys_recvfrom_args bra; 350 351 SCARG(&bra, s) = SCARG(uap, s); 352 SCARG(&bra, buf) = SCARG(uap, buf); 353 SCARG(&bra, len) = SCARG(uap, len); 354 SCARG(&bra, flags) = SCARG(uap, flags); 355 SCARG(&bra, from) = (struct sockaddr *) SCARG(uap, from); 356 SCARG(&bra, fromlenaddr) = SCARG(uap, fromlenaddr); 357 358 if ((error = sys_recvfrom(p, &bra, retval))) 359 return (error); 360 361 if (SCARG(uap, from) && (error = linux_sa_put(SCARG(uap, from)))) 362 return (error); 363 364 return (0); 365 } 366 367 int 368 linux_sys_recvmsg(p, v, retval) 369 struct proc *p; 370 void *v; 371 register_t *retval; 372 { 373 struct linux_sys_recvmsg_args /* { 374 syscallarg(int) s; 375 syscallarg(struct msghdr *) msg; 376 syscallarg(u_int) flags; 377 } */ *uap = v; 378 struct msghdr msg; 379 int error; 380 381 if ((error = sys_recvmsg(p, v, retval))) 382 return (error); 383 384 error = copyin((caddr_t)SCARG(uap, msg), (caddr_t)&msg, 385 sizeof(msg)); 386 387 if (!error && msg.msg_name && msg.msg_namelen > 2) 388 error = linux_sa_put(msg.msg_name); 389 390 /* 391 * XXX handle different alignment of cmsg data on architectures where 392 * the Linux alignment is different (powerpc, sparc, sparc64). 393 */ 394 395 return (error); 396 } 397 398 /* 399 * Convert socket option level from Linux to NetBSD value. Only SOL_SOCKET 400 * is different, the rest matches IPPROTO_* on both systems. 401 */ 402 int 403 linux_to_bsd_sopt_level(llevel) 404 int llevel; 405 { 406 407 switch (llevel) { 408 case LINUX_SOL_SOCKET: 409 return SOL_SOCKET; 410 case LINUX_SOL_IP: 411 return IPPROTO_IP; 412 case LINUX_SOL_TCP: 413 return IPPROTO_TCP; 414 case LINUX_SOL_UDP: 415 return IPPROTO_UDP; 416 default: 417 return -1; 418 } 419 } 420 421 /* 422 * Convert Linux socket level socket option numbers to NetBSD values. 423 */ 424 int 425 linux_to_bsd_so_sockopt(lopt) 426 int lopt; 427 { 428 429 switch (lopt) { 430 case LINUX_SO_DEBUG: 431 return SO_DEBUG; 432 case LINUX_SO_REUSEADDR: 433 return SO_REUSEADDR; 434 case LINUX_SO_TYPE: 435 return SO_TYPE; 436 case LINUX_SO_ERROR: 437 return SO_ERROR; 438 case LINUX_SO_DONTROUTE: 439 return SO_DONTROUTE; 440 case LINUX_SO_BROADCAST: 441 return SO_BROADCAST; 442 case LINUX_SO_SNDBUF: 443 return SO_SNDBUF; 444 case LINUX_SO_RCVBUF: 445 return SO_RCVBUF; 446 case LINUX_SO_KEEPALIVE: 447 return SO_KEEPALIVE; 448 case LINUX_SO_OOBINLINE: 449 return SO_OOBINLINE; 450 case LINUX_SO_LINGER: 451 return SO_LINGER; 452 case LINUX_SO_PRIORITY: 453 case LINUX_SO_NO_CHECK: 454 default: 455 return -1; 456 } 457 } 458 459 /* 460 * Convert Linux IP level socket option number to NetBSD values. 461 */ 462 int 463 linux_to_bsd_ip_sockopt(lopt) 464 int lopt; 465 { 466 467 switch (lopt) { 468 case LINUX_IP_TOS: 469 return IP_TOS; 470 case LINUX_IP_TTL: 471 return IP_TTL; 472 case LINUX_IP_MULTICAST_TTL: 473 return IP_MULTICAST_TTL; 474 case LINUX_IP_MULTICAST_LOOP: 475 return IP_MULTICAST_LOOP; 476 case LINUX_IP_MULTICAST_IF: 477 return IP_MULTICAST_IF; 478 case LINUX_IP_ADD_MEMBERSHIP: 479 return IP_ADD_MEMBERSHIP; 480 case LINUX_IP_DROP_MEMBERSHIP: 481 return IP_DROP_MEMBERSHIP; 482 default: 483 return -1; 484 } 485 } 486 487 /* 488 * Convert Linux TCP level socket option number to NetBSD values. 489 */ 490 int 491 linux_to_bsd_tcp_sockopt(lopt) 492 int lopt; 493 { 494 495 switch (lopt) { 496 case LINUX_TCP_NODELAY: 497 return TCP_NODELAY; 498 case LINUX_TCP_MAXSEG: 499 return TCP_MAXSEG; 500 default: 501 return -1; 502 } 503 } 504 505 /* 506 * Convert Linux UDP level socket option number to NetBSD values. 507 */ 508 int 509 linux_to_bsd_udp_sockopt(lopt) 510 int lopt; 511 { 512 513 switch (lopt) { 514 default: 515 return -1; 516 } 517 } 518 519 /* 520 * Another reasonably straightforward function: setsockopt(2). 521 * The level and option numbers are converted; the values passed 522 * are not (yet) converted, the ones currently implemented don't 523 * need conversion, as they are the same on both systems. 524 */ 525 int 526 linux_sys_setsockopt(p, v, retval) 527 struct proc *p; 528 void *v; 529 register_t *retval; 530 { 531 struct linux_sys_setsockopt_args /* { 532 syscallarg(int) s; 533 syscallarg(int) level; 534 syscallarg(int) optname; 535 syscallarg(void *) optval; 536 syscallarg(int) optlen; 537 } */ *uap = v; 538 struct sys_setsockopt_args bsa; 539 int name; 540 541 SCARG(&bsa, s) = SCARG(uap, s); 542 SCARG(&bsa, level) = linux_to_bsd_sopt_level(SCARG(uap, level)); 543 SCARG(&bsa, val) = SCARG(uap, optval); 544 SCARG(&bsa, valsize) = SCARG(uap, optlen); 545 546 switch (SCARG(&bsa, level)) { 547 case SOL_SOCKET: 548 name = linux_to_bsd_so_sockopt(SCARG(uap, optname)); 549 break; 550 case IPPROTO_IP: 551 name = linux_to_bsd_ip_sockopt(SCARG(uap, optname)); 552 break; 553 case IPPROTO_TCP: 554 name = linux_to_bsd_tcp_sockopt(SCARG(uap, optname)); 555 break; 556 case IPPROTO_UDP: 557 name = linux_to_bsd_udp_sockopt(SCARG(uap, optname)); 558 break; 559 default: 560 return EINVAL; 561 } 562 563 if (name == -1) 564 return EINVAL; 565 SCARG(&bsa, name) = name; 566 567 return sys_setsockopt(p, &bsa, retval); 568 } 569 570 /* 571 * getsockopt(2) is very much the same as setsockopt(2) (see above) 572 */ 573 int 574 linux_sys_getsockopt(p, v, retval) 575 struct proc *p; 576 void *v; 577 register_t *retval; 578 { 579 struct linux_sys_getsockopt_args /* { 580 syscallarg(int) s; 581 syscallarg(int) level; 582 syscallarg(int) optname; 583 syscallarg(void *) optval; 584 syscallarg(int *) optlen; 585 } */ *uap = v; 586 struct sys_getsockopt_args bga; 587 int name; 588 589 SCARG(&bga, s) = SCARG(uap, s); 590 SCARG(&bga, level) = linux_to_bsd_sopt_level(SCARG(uap, level)); 591 SCARG(&bga, val) = SCARG(uap, optval); 592 SCARG(&bga, avalsize) = SCARG(uap, optlen); 593 594 switch (SCARG(&bga, level)) { 595 case SOL_SOCKET: 596 name = linux_to_bsd_so_sockopt(SCARG(uap, optname)); 597 break; 598 case IPPROTO_IP: 599 name = linux_to_bsd_ip_sockopt(SCARG(uap, optname)); 600 break; 601 case IPPROTO_TCP: 602 name = linux_to_bsd_tcp_sockopt(SCARG(uap, optname)); 603 break; 604 case IPPROTO_UDP: 605 name = linux_to_bsd_udp_sockopt(SCARG(uap, optname)); 606 break; 607 default: 608 return EINVAL; 609 } 610 611 if (name == -1) 612 return EINVAL; 613 SCARG(&bga, name) = name; 614 615 return sys_getsockopt(p, &bga, retval); 616 } 617 618 #define IF_NAME_LEN 16 619 620 int 621 linux_getifhwaddr(p, retval, fd, data) 622 struct proc *p; 623 register_t *retval; 624 u_int fd; 625 void *data; 626 { 627 /* Not the full structure, just enough to map what we do here */ 628 struct linux_ifreq { 629 char if_name[IF_NAME_LEN]; 630 struct osockaddr hwaddr; 631 } lreq; 632 struct filedesc *fdp; 633 struct file *fp; 634 struct ifaddr *ifa; 635 struct ifnet *ifp; 636 struct sockaddr_dl *sadl; 637 int error, found; 638 int index, ifnum; 639 640 /* 641 * We can't emulate this ioctl by calling sys_ioctl() to run 642 * SIOCGIFCONF, because the user buffer is not of the right 643 * type to take those results. We can't use kernel buffers to 644 * receive the results, as the implementation of sys_ioctl() 645 * and ifconf() [which implements SIOCGIFCONF] use 646 * copyin()/copyout() which will fail on kernel addresses. 647 * 648 * So, we must duplicate code from sys_ioctl() and ifconf(). Ugh. 649 */ 650 651 fdp = p->p_fd; 652 if ((fp = fd_getfile(fdp, fd)) == NULL) 653 return (EBADF); 654 655 FILE_USE(fp); 656 if ((fp->f_flag & (FREAD | FWRITE)) == 0) { 657 error = EBADF; 658 goto out; 659 } 660 661 error = copyin(data, (caddr_t)&lreq, sizeof(lreq)); 662 if (error) 663 goto out; 664 lreq.if_name[IF_NAME_LEN-1] = '\0'; /* just in case */ 665 666 /* 667 * Try real interface name first, then fake "ethX" 668 */ 669 for (ifp = ifnet.tqh_first, found = 0; 670 ifp != 0 && !found; 671 ifp = ifp->if_list.tqe_next) { 672 if (strcmp(lreq.if_name, ifp->if_xname)) 673 /* not this interface */ 674 continue; 675 found=1; 676 if ((ifa = ifp->if_addrlist.tqh_first) != 0) { 677 for (; ifa != 0; ifa = ifa->ifa_list.tqe_next) { 678 sadl = (struct sockaddr_dl *)ifa->ifa_addr; 679 /* only return ethernet addresses */ 680 /* XXX what about FDDI, etc. ? */ 681 if (sadl->sdl_family != AF_LINK || 682 sadl->sdl_type != IFT_ETHER) 683 continue; 684 memcpy((caddr_t)&lreq.hwaddr.sa_data, 685 LLADDR(sadl), 686 MIN(sadl->sdl_alen, 687 sizeof(lreq.hwaddr.sa_data))); 688 lreq.hwaddr.sa_family = 689 sadl->sdl_family; 690 error = copyout((caddr_t)&lreq, data, 691 sizeof(lreq)); 692 goto out; 693 } 694 } else { 695 error = ENODEV; 696 goto out; 697 } 698 } 699 700 if (strncmp(lreq.if_name, "eth", 3) == 0) { 701 for (ifnum = 0, index = 3; 702 lreq.if_name[index] != '\0' && index < IF_NAME_LEN; 703 index++) { 704 ifnum *= 10; 705 ifnum += lreq.if_name[index] - '0'; 706 } 707 708 error = EINVAL; /* in case we don't find one */ 709 for (ifp = ifnet.tqh_first, found = 0; 710 ifp != 0 && !found; 711 ifp = ifp->if_list.tqe_next) { 712 memcpy(lreq.if_name, ifp->if_xname, 713 MIN(IF_NAME_LEN, IFNAMSIZ)); 714 if ((ifa = ifp->if_addrlist.tqh_first) == 0) 715 /* no addresses on this interface */ 716 continue; 717 else 718 for (; ifa != 0; ifa = ifa->ifa_list.tqe_next) { 719 sadl = (struct sockaddr_dl *)ifa->ifa_addr; 720 /* only return ethernet addresses */ 721 /* XXX what about FDDI, etc. ? */ 722 if (sadl->sdl_family != AF_LINK || 723 sadl->sdl_type != IFT_ETHER) 724 continue; 725 if (ifnum--) 726 /* not the reqested iface */ 727 continue; 728 memcpy((caddr_t)&lreq.hwaddr.sa_data, 729 LLADDR(sadl), 730 MIN(sadl->sdl_alen, 731 sizeof(lreq.hwaddr.sa_data))); 732 lreq.hwaddr.sa_family = 733 sadl->sdl_family; 734 error = copyout((caddr_t)&lreq, data, 735 sizeof(lreq)); 736 found = 1; 737 break; 738 } 739 } 740 } else { 741 /* unknown interface, not even an "eth*" name */ 742 error = ENODEV; 743 } 744 745 out: 746 FILE_UNUSE(fp, p); 747 return error; 748 } 749 #undef IF_NAME_LEN 750 751 int 752 linux_ioctl_socket(p, uap, retval) 753 struct proc *p; 754 struct linux_sys_ioctl_args /* { 755 syscallarg(int) fd; 756 syscallarg(u_long) com; 757 syscallarg(caddr_t) data; 758 } */ *uap; 759 register_t *retval; 760 { 761 u_long com; 762 int error = 0, isdev = 0, dosys = 1; 763 struct sys_ioctl_args ia; 764 struct file *fp; 765 struct filedesc *fdp; 766 struct vnode *vp; 767 int (*ioctlf) __P((struct file *, u_long, caddr_t, struct proc *)); 768 struct ioctl_pt pt; 769 770 fdp = p->p_fd; 771 if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL) 772 return (EBADF); 773 774 FILE_USE(fp); 775 776 if (fp->f_type == DTYPE_VNODE) { 777 vp = (struct vnode *)fp->f_data; 778 isdev = vp->v_type == VCHR; 779 } 780 781 /* 782 * Don't try to interpret socket ioctl calls that are done 783 * on a device filedescriptor, just pass them through, to 784 * emulate Linux behaviour. Use PTIOCLINUX so that the 785 * device will only handle these if it's prepared to do 786 * so, to avoid unexpected things from happening. 787 */ 788 if (isdev) { 789 dosys = 0; 790 ioctlf = fp->f_ops->fo_ioctl; 791 pt.com = SCARG(uap, com); 792 pt.data = SCARG(uap, data); 793 error = ioctlf(fp, PTIOCLINUX, (caddr_t)&pt, p); 794 /* 795 * XXX hack: if the function returns EJUSTRETURN, 796 * it has stuffed a sysctl return value in pt.data. 797 */ 798 if (error == EJUSTRETURN) { 799 retval[0] = (register_t)pt.data; 800 error = 0; 801 } 802 goto out; 803 } 804 805 com = SCARG(uap, com); 806 retval[0] = 0; 807 808 switch (com) { 809 case LINUX_SIOCGIFCONF: 810 SCARG(&ia, com) = OSIOCGIFCONF; 811 break; 812 case LINUX_SIOCGIFFLAGS: 813 SCARG(&ia, com) = SIOCGIFFLAGS; 814 break; 815 case LINUX_SIOCSIFFLAGS: 816 SCARG(&ia, com) = SIOCSIFFLAGS; 817 break; 818 case LINUX_SIOCGIFADDR: 819 SCARG(&ia, com) = OSIOCGIFADDR; 820 break; 821 case LINUX_SIOCGIFDSTADDR: 822 SCARG(&ia, com) = OSIOCGIFDSTADDR; 823 break; 824 case LINUX_SIOCGIFBRDADDR: 825 SCARG(&ia, com) = OSIOCGIFBRDADDR; 826 break; 827 case LINUX_SIOCGIFNETMASK: 828 SCARG(&ia, com) = OSIOCGIFNETMASK; 829 break; 830 case LINUX_SIOCADDMULTI: 831 SCARG(&ia, com) = SIOCADDMULTI; 832 break; 833 case LINUX_SIOCDELMULTI: 834 SCARG(&ia, com) = SIOCDELMULTI; 835 break; 836 case LINUX_SIOCGIFHWADDR: 837 error = linux_getifhwaddr(p, retval, SCARG(uap, fd), 838 SCARG(uap, data)); 839 dosys = 0; 840 break; 841 default: 842 error = EINVAL; 843 } 844 845 out: 846 FILE_UNUSE(fp, p); 847 848 if (error ==0 && dosys) { 849 SCARG(&ia, fd) = SCARG(uap, fd); 850 SCARG(&ia, data) = SCARG(uap, data); 851 error = sys_ioctl(p, &ia, retval); 852 } 853 854 return error; 855 } 856 857 int 858 linux_sys_connect(p, v, retval) 859 struct proc *p; 860 void *v; 861 register_t *retval; 862 { 863 struct linux_sys_connect_args /* { 864 syscallarg(int) s; 865 syscallarg(const struct sockaddr *) name; 866 syscallarg(int) namelen; 867 } */ *uap = v; 868 int error; 869 struct sockaddr *sa; 870 struct sys_connect_args bca; 871 caddr_t sg = stackgap_init(p->p_emul); 872 873 error = linux_sa_get(&sg, &sa, SCARG(uap, name), SCARG(uap, namelen)); 874 if (error) 875 return (error); 876 877 SCARG(&bca, s) = SCARG(uap, s); 878 SCARG(&bca, name) = sa; 879 SCARG(&bca, namelen) = (unsigned int) SCARG(uap, namelen); 880 881 error = sys_connect(p, &bca, retval); 882 883 if (error == EISCONN) { 884 struct file *fp; 885 struct socket *so; 886 int s, state, prflags; 887 888 /* getsock() will use the descriptor for us */ 889 if (getsock(p->p_fd, SCARG(uap, s), &fp) != 0) 890 return EISCONN; 891 892 s = splsoftnet(); 893 so = (struct socket *)fp->f_data; 894 state = so->so_state; 895 prflags = so->so_proto->pr_flags; 896 splx(s); 897 FILE_UNUSE(fp, p); 898 /* 899 * We should only let this call succeed once per 900 * non-blocking connect; however we don't have 901 * a convenient place to keep that state.. 902 */ 903 if ((state & SS_NBIO) && (state & SS_ISCONNECTED) && 904 (prflags & PR_CONNREQUIRED)) 905 return 0; 906 } 907 908 return (error); 909 } 910 911 int 912 linux_sys_bind(p, v, retval) 913 struct proc *p; 914 void *v; 915 register_t *retval; 916 { 917 struct linux_sys_bind_args /* { 918 syscallarg(int) s; 919 syscallarg(const struct osockaddr *) name; 920 syscallarg(int) namelen; 921 } */ *uap = v; 922 int error; 923 struct sys_bind_args bsa; 924 925 SCARG(&bsa, s) = SCARG(uap, s); 926 if (SCARG(uap, name)) { 927 struct sockaddr *sa; 928 caddr_t sg = stackgap_init(p->p_emul); 929 930 error = linux_sa_get(&sg, &sa, SCARG(uap, name), 931 SCARG(uap, namelen)); 932 if (error) 933 return (error); 934 935 SCARG(&bsa, name) = sa; 936 } else 937 SCARG(&bsa, name) = NULL; 938 SCARG(&bsa, namelen) = SCARG(uap, namelen); 939 940 return (sys_bind(p, &bsa, retval)); 941 } 942 943 int 944 linux_sys_getsockname(p, v, retval) 945 struct proc *p; 946 void *v; 947 register_t *retval; 948 { 949 struct linux_sys_getsockname_args /* { 950 syscallarg(int) fdes; 951 syscallarg(caddr_t) asa; 952 syscallarg(int *) alen; 953 } */ *uap = v; 954 int error; 955 956 if ((error = sys_getsockname(p, uap, retval)) != 0) 957 return (error); 958 959 if ((error = linux_sa_put((struct osockaddr *)SCARG(uap, asa)))) 960 return (error); 961 962 return (0); 963 } 964 965 int 966 linux_sys_getpeername(p, v, retval) 967 struct proc *p; 968 void *v; 969 register_t *retval; 970 { 971 struct sys_getpeername_args /* { 972 syscallarg(int) fdes; 973 syscallarg(caddr_t) asa; 974 syscallarg(int *) alen; 975 } */ *uap = v; 976 int error; 977 978 if ((error = sys_getpeername(p, uap, retval)) != 0) 979 return (error); 980 981 if ((error = linux_sa_put((struct osockaddr *)SCARG(uap, asa)))) 982 return (error); 983 984 return (0); 985 } 986 987 /* 988 * Copy the osockaddr structure pointed to by osa to kernel, adjust 989 * family and convert to sockaddr, allocate stackgap and put the 990 * the converted structure there, address on stackgap returned in sap. 991 */ 992 static int 993 linux_sa_get(sgp, sap, osa, osalen) 994 caddr_t *sgp; 995 struct sockaddr **sap; 996 const struct osockaddr *osa; 997 int osalen; 998 { 999 int error=0, bdom; 1000 struct sockaddr *sa, *usa; 1001 struct osockaddr *kosa = (struct osockaddr *) &sa; 1002 1003 if (osalen < 0 || osalen > UCHAR_MAX || !osa) 1004 return (EINVAL); 1005 1006 kosa = (struct osockaddr *) malloc(osalen, M_TEMP, M_WAITOK); 1007 1008 if ((error = copyin(osa, (caddr_t) kosa, osalen))) 1009 goto out; 1010 1011 bdom = linux_to_bsd_domain(kosa->sa_family); 1012 if (bdom == -1) { 1013 error = EINVAL; 1014 goto out; 1015 } 1016 1017 #ifdef INET6 1018 /* 1019 * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6, 1020 * which lacks the scope id compared with RFC2553 one. If we detect 1021 * the situation, reject the address and write a message to system log. 1022 */ 1023 if (bdom == AF_INET6 && osalen < sizeof(struct sockaddr_in6)) { 1024 struct proc *p = curproc; /* XXX */ 1025 int uid = p->p_cred && p->p_ucred ? 1026 p->p_ucred->cr_uid : -1; 1027 1028 log(LOG_DEBUG, 1029 "pid %d (%s), uid %d: obsolete pre-RFC2553 sockaddr_in6 rejected", 1030 p->p_pid, p->p_comm, uid); 1031 error = EINVAL; 1032 goto out; 1033 } 1034 #endif 1035 1036 sa = (struct sockaddr *) kosa; 1037 sa->sa_family = bdom; 1038 sa->sa_len = osalen; 1039 1040 usa = (struct sockaddr *) stackgap_alloc(sgp, osalen); 1041 if (!usa) { 1042 error = ENOMEM; 1043 goto out; 1044 } 1045 1046 if ((error = copyout(sa, usa, osalen))) 1047 goto out; 1048 1049 *sap = usa; 1050 1051 out: 1052 free(kosa, M_TEMP); 1053 return (error); 1054 } 1055 1056 static int 1057 linux_sa_put(osa) 1058 struct osockaddr *osa; 1059 { 1060 struct sockaddr sa; 1061 struct osockaddr *kosa; 1062 int error, bdom, len; 1063 1064 /* 1065 * Only read/write the sockaddr family and length part, the rest is 1066 * not changed. 1067 */ 1068 len = sizeof(sa.sa_len) + sizeof(sa.sa_family); 1069 1070 error = copyin((caddr_t) osa, (caddr_t) &sa, len); 1071 if (error) 1072 return (error); 1073 1074 bdom = bsd_to_linux_domain(sa.sa_family); 1075 if (bdom == -1) 1076 return (EINVAL); 1077 1078 /* Note: we convert from sockaddr to osockaddr here, too */ 1079 kosa = (struct osockaddr *) &sa; 1080 kosa->sa_family = bdom; 1081 error = copyout(kosa, osa, len); 1082 if (error) 1083 return (error); 1084 1085 return (0); 1086 } 1087 1088 int 1089 linux_sys_recv(p, v, retval) 1090 struct proc *p; 1091 void *v; 1092 register_t *retval; 1093 { 1094 struct linux_sys_recv_args /* { 1095 syscallarg(int) s; 1096 syscallarg(void *) buf; 1097 syscallarg(int) len; 1098 syscallarg(int) flags; 1099 } */ *uap = v; 1100 struct sys_recvfrom_args bra; 1101 1102 1103 SCARG(&bra, s) = SCARG(uap, s); 1104 SCARG(&bra, buf) = SCARG(uap, buf); 1105 SCARG(&bra, len) = (size_t) SCARG(uap, len); 1106 SCARG(&bra, flags) = SCARG(uap, flags); 1107 SCARG(&bra, from) = NULL; 1108 SCARG(&bra, fromlenaddr) = NULL; 1109 1110 return (sys_recvfrom(p, &bra, retval)); 1111 } 1112 1113 int 1114 linux_sys_send(p, v, retval) 1115 struct proc *p; 1116 void *v; 1117 register_t *retval; 1118 { 1119 struct linux_sys_send_args /* { 1120 syscallarg(int) s; 1121 syscallarg(caddr_t) buf; 1122 syscallarg(int) len; 1123 syscallarg(int) flags; 1124 } */ *uap = v; 1125 struct sys_sendto_args bsa; 1126 1127 SCARG(&bsa, s) = SCARG(uap, s); 1128 SCARG(&bsa, buf) = SCARG(uap, buf); 1129 SCARG(&bsa, len) = SCARG(uap, len); 1130 SCARG(&bsa, flags) = SCARG(uap, flags); 1131 SCARG(&bsa, to) = NULL; 1132 SCARG(&bsa, tolen) = 0; 1133 1134 return (sys_sendto(p, &bsa, retval)); 1135 } 1136 1137 int 1138 linux_sys_accept(p, v, retval) 1139 struct proc *p; 1140 void *v; 1141 register_t *retval; 1142 { 1143 struct linux_sys_accept_args /* { 1144 syscallarg(int) s; 1145 syscallarg(struct osockaddr *) name; 1146 syscallarg(int *) anamelen; 1147 } */ *uap = v; 1148 int error; 1149 struct sys_accept_args baa; 1150 1151 SCARG(&baa, s) = SCARG(uap, s); 1152 SCARG(&baa, name) = (struct sockaddr *) SCARG(uap, name); 1153 SCARG(&baa, anamelen) = (unsigned int *) SCARG(uap, anamelen); 1154 1155 if ((error = sys_accept(p, &baa, retval))) 1156 return (error); 1157 1158 if (SCARG(uap, name) && (error = linux_sa_put(SCARG(uap, name)))) 1159 return (error); 1160 1161 return (0); 1162 } 1163