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