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