1 /* $NetBSD: linux_socket.c,v 1.15 1996/12/22 23:02:26 fvdl Exp $ */ 2 3 /* 4 * Copyright (c) 1995 Frank van der Linden 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed for the NetBSD Project 18 * by Frank van der Linden 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <sys/param.h> 35 #include <sys/kernel.h> 36 #include <sys/systm.h> 37 #include <sys/buf.h> 38 #include <sys/malloc.h> 39 #include <sys/ioctl.h> 40 #include <sys/tty.h> 41 #include <sys/file.h> 42 #include <sys/filedesc.h> 43 #include <sys/select.h> 44 #include <sys/socket.h> 45 #include <sys/socketvar.h> 46 #include <net/if.h> 47 #include <netinet/in.h> 48 #include <netinet/tcp.h> 49 #include <sys/mount.h> 50 #include <sys/proc.h> 51 #include <sys/vnode.h> 52 #include <sys/device.h> 53 54 #include <sys/syscallargs.h> 55 56 #include <compat/linux/linux_types.h> 57 #include <compat/linux/linux_util.h> 58 #include <compat/linux/linux_signal.h> 59 #include <compat/linux/linux_syscallargs.h> 60 #include <compat/linux/linux_ioctl.h> 61 #include <compat/linux/linux_socket.h> 62 #include <compat/linux/linux_socketcall.h> 63 #include <compat/linux/linux_sockio.h> 64 65 /* 66 * All the calls in this file are entered via one common system 67 * call in Linux, represented here by linux_socketcall() 68 * Arguments for the various calls are on the user stack. A pointer 69 * to them is the only thing that is passed. It is up to the various 70 * calls to copy them in themselves. To make it look better, they 71 * are copied to structures. 72 */ 73 74 int linux_to_bsd_domain __P((int)); 75 int linux_socket __P((struct proc *, struct linux_socket_args *, register_t *)); 76 int linux_bind __P((struct proc *, struct linux_bind_args *, register_t *)); 77 int linux_connect __P((struct proc *, struct linux_connect_args *, 78 register_t *)); 79 int linux_listen __P((struct proc *, struct linux_listen_args *, register_t *)); 80 int linux_accept __P((struct proc *, struct linux_accept_args *, register_t *)); 81 int linux_getsockname __P((struct proc *, struct linux_getsockname_args *, 82 register_t *)); 83 int linux_getpeername __P((struct proc *, struct linux_getpeername_args *, 84 register_t *)); 85 int linux_socketpair __P((struct proc *, struct linux_socketpair_args *, 86 register_t *)); 87 int linux_send __P((struct proc *, struct linux_send_args *, register_t *)); 88 int linux_recv __P((struct proc *, struct linux_recv_args *, register_t *)); 89 int linux_sendto __P((struct proc *, struct linux_sendto_args *, register_t *)); 90 int linux_recvfrom __P((struct proc *, struct linux_recvfrom_args *, 91 register_t *)); 92 int linux_shutdown __P((struct proc *, struct linux_shutdown_args *, 93 register_t *)); 94 int linux_to_bsd_sopt_level __P((int)); 95 int linux_to_bsd_so_sockopt __P((int)); 96 int linux_to_bsd_ip_sockopt __P((int)); 97 int linux_to_bsd_tcp_sockopt __P((int)); 98 int linux_to_bsd_udp_sockopt __P((int)); 99 int linux_setsockopt __P((struct proc *, struct linux_setsockopt_args *, 100 register_t *)); 101 int linux_getsockopt __P((struct proc *, struct linux_getsockopt_args *, 102 register_t *)); 103 104 /* 105 * Convert between Linux and BSD socket domain values 106 */ 107 int 108 linux_to_bsd_domain(ldom) 109 int ldom; 110 { 111 112 switch (ldom) { 113 case LINUX_AF_UNSPEC: 114 return AF_UNSPEC; 115 case LINUX_AF_UNIX: 116 return AF_LOCAL; 117 case LINUX_AF_INET: 118 return AF_INET; 119 case LINUX_AF_AX25: 120 return AF_CCITT; 121 case LINUX_AF_IPX: 122 return AF_IPX; 123 case LINUX_AF_APPLETALK: 124 return AF_APPLETALK; 125 default: 126 return -1; 127 } 128 } 129 130 int 131 linux_socket(p, uap, retval) 132 struct proc *p; 133 struct linux_socket_args /* { 134 syscallarg(int) domain; 135 syscallarg(int) type; 136 syscallarg(int) protocol; 137 } */ *uap; 138 register_t *retval; 139 { 140 struct linux_socket_args lsa; 141 struct sys_socket_args bsa; 142 int error; 143 144 if ((error = copyin((caddr_t) uap, (caddr_t) &lsa, sizeof lsa))) 145 return error; 146 147 SCARG(&bsa, protocol) = lsa.protocol; 148 SCARG(&bsa, type) = lsa.type; 149 SCARG(&bsa, domain) = linux_to_bsd_domain(lsa.domain); 150 if (SCARG(&bsa, domain) == -1) 151 return EINVAL; 152 return sys_socket(p, &bsa, retval); 153 } 154 155 int 156 linux_bind(p, uap, retval) 157 struct proc *p; 158 struct linux_bind_args /* { 159 syscallarg(int) s; 160 syscallarg(struct sockaddr *) name; 161 syscallarg(int) namelen; 162 } */ *uap; 163 register_t *retval; 164 { 165 struct linux_bind_args lba; 166 struct sys_bind_args bba; 167 int error; 168 169 if ((error = copyin((caddr_t) uap, (caddr_t) &lba, sizeof lba))) 170 return error; 171 172 SCARG(&bba, s) = lba.s; 173 SCARG(&bba, name) = (void *) lba.name; 174 SCARG(&bba, namelen) = lba.namelen; 175 176 return sys_bind(p, &bba, retval); 177 } 178 179 int 180 linux_connect(p, uap, retval) 181 struct proc *p; 182 struct linux_connect_args /* { 183 syscallarg(int) s; 184 syscallarg(struct sockaddr *) name; 185 syscallarg(int) namelen; 186 } */ *uap; 187 register_t *retval; 188 { 189 struct linux_connect_args lca; 190 struct sys_connect_args bca; 191 int error; 192 193 if ((error = copyin((caddr_t) uap, (caddr_t) &lca, sizeof lca))) 194 return error; 195 196 SCARG(&bca, s) = lca.s; 197 SCARG(&bca, name) = (void *) lca.name; 198 SCARG(&bca, namelen) = lca.namelen; 199 200 return sys_connect(p, &bca, retval); 201 } 202 203 int 204 linux_listen(p, uap, retval) 205 struct proc *p; 206 struct linux_listen_args /* { 207 syscallarg(int) s; 208 syscallarg(int) backlog; 209 } */ *uap; 210 register_t *retval; 211 { 212 struct linux_listen_args lla; 213 struct sys_listen_args bla; 214 int error; 215 216 if ((error = copyin((caddr_t) uap, (caddr_t) &lla, sizeof lla))) 217 return error; 218 219 SCARG(&bla, s) = lla.s; 220 SCARG(&bla, backlog) = lla.backlog; 221 222 return sys_listen(p, &bla, retval); 223 } 224 225 int 226 linux_accept(p, uap, retval) 227 struct proc *p; 228 struct linux_accept_args /* { 229 syscallarg(int) s; 230 syscallarg(struct sockaddr *) addr; 231 syscallarg(int *) namelen; 232 } */ *uap; 233 register_t *retval; 234 { 235 struct linux_accept_args laa; 236 struct compat_43_sys_accept_args baa; 237 int error; 238 239 if ((error = copyin((caddr_t) uap, (caddr_t) &laa, sizeof laa))) 240 return error; 241 242 SCARG(&baa, s) = laa.s; 243 SCARG(&baa, name) = (caddr_t) laa.addr; 244 SCARG(&baa, anamelen) = laa.namelen; 245 246 return compat_43_sys_accept(p, &baa, retval); 247 } 248 249 int 250 linux_getsockname(p, uap, retval) 251 struct proc *p; 252 struct linux_getsockname_args /* { 253 syscallarg(int) s; 254 syscallarg(struct sockaddr *) addr; 255 syscallarg(int *) namelen; 256 } */ *uap; 257 register_t *retval; 258 { 259 struct linux_getsockname_args lga; 260 struct compat_43_sys_getsockname_args bga; 261 int error; 262 263 if ((error = copyin((caddr_t) uap, (caddr_t) &lga, sizeof lga))) 264 return error; 265 266 SCARG(&bga, fdec) = lga.s; 267 SCARG(&bga, asa) = (caddr_t) lga.addr; 268 SCARG(&bga, alen) = lga.namelen; 269 270 return compat_43_sys_getsockname(p, &bga, retval); 271 } 272 273 int 274 linux_getpeername(p, uap, retval) 275 struct proc *p; 276 struct linux_getpeername_args /* { 277 syscallarg(int) s; 278 syscallarg(struct sockaddr *) addr; 279 syscallarg(int *) namelen; 280 } */ *uap; 281 register_t *retval; 282 { 283 struct linux_getpeername_args lga; 284 struct compat_43_sys_getpeername_args bga; 285 int error; 286 287 if ((error = copyin((caddr_t) uap, (caddr_t) &lga, sizeof lga))) 288 return error; 289 290 SCARG(&bga, fdes) = lga.s; 291 SCARG(&bga, asa) = (caddr_t) lga.addr; 292 SCARG(&bga, alen) = lga.namelen; 293 294 return compat_43_sys_getpeername(p, &bga, retval); 295 } 296 297 int 298 linux_socketpair(p, uap, retval) 299 struct proc *p; 300 struct linux_socketpair_args /* { 301 syscallarg(int) domain; 302 syscallarg(int) type; 303 syscallarg(int) protocol; 304 syscallarg(int *) rsv; 305 } */ *uap; 306 register_t *retval; 307 { 308 struct linux_socketpair_args lsa; 309 struct sys_socketpair_args bsa; 310 int error; 311 312 if ((error = copyin((caddr_t) uap, &lsa, sizeof lsa))) 313 return error; 314 315 SCARG(&bsa, domain) = linux_to_bsd_domain(lsa.domain); 316 if (SCARG(&bsa, domain) == -1) 317 return EINVAL; 318 SCARG(&bsa, type) = lsa.type; 319 SCARG(&bsa, protocol) = lsa.protocol; 320 SCARG(&bsa, rsv) = lsa.rsv; 321 322 return sys_socketpair(p, &bsa, retval); 323 } 324 325 int 326 linux_send(p, uap, retval) 327 struct proc *p; 328 struct linux_send_args /* { 329 syscallarg(int) s; 330 syscallarg(void *) msg; 331 syscallarg(int) len; 332 syscallarg(int) flags; 333 } */ *uap; 334 register_t *retval; 335 { 336 struct linux_send_args lsa; 337 struct compat_43_sys_send_args bsa; 338 int error; 339 340 if ((error = copyin((caddr_t) uap, (caddr_t) &lsa, sizeof lsa))) 341 return error; 342 343 SCARG(&bsa, s) = lsa.s; 344 SCARG(&bsa, buf) = lsa.msg; 345 SCARG(&bsa, len) = lsa.len; 346 SCARG(&bsa, flags) = lsa.flags; 347 348 return compat_43_sys_send(p, &bsa, retval); 349 } 350 351 int 352 linux_recv(p, uap, retval) 353 struct proc *p; 354 struct linux_recv_args /* { 355 syscallarg(int) s; 356 syscallarg(void *) msg; 357 syscallarg(int) len; 358 syscallarg(int) flags; 359 } */ *uap; 360 register_t *retval; 361 { 362 struct linux_recv_args lra; 363 struct compat_43_sys_recv_args bra; 364 int error; 365 366 if ((error = copyin((caddr_t) uap, (caddr_t) &lra, sizeof lra))) 367 return error; 368 369 SCARG(&bra, s) = lra.s; 370 SCARG(&bra, buf) = lra.msg; 371 SCARG(&bra, len) = lra.len; 372 SCARG(&bra, flags) = lra.flags; 373 374 return compat_43_sys_recv(p, &bra, retval); 375 } 376 377 int 378 linux_sendto(p, uap, retval) 379 struct proc *p; 380 struct linux_sendto_args /* { 381 syscallarg(int) s; 382 syscallarg(void *) msg; 383 syscallarg(int) len; 384 syscallarg(int) flags; 385 syscallarg(sockaddr *) to; 386 syscallarg(int) tolen; 387 } */ *uap; 388 register_t *retval; 389 { 390 struct linux_sendto_args lsa; 391 struct sys_sendto_args bsa; 392 int error; 393 394 if ((error = copyin((caddr_t) uap, (caddr_t) &lsa, sizeof lsa))) 395 return error; 396 397 SCARG(&bsa, s) = lsa.s; 398 SCARG(&bsa, buf) = lsa.msg; 399 SCARG(&bsa, len) = lsa.len; 400 SCARG(&bsa, flags) = lsa.flags; 401 SCARG(&bsa, to) = (void *) lsa.to; 402 SCARG(&bsa, tolen) = lsa.tolen; 403 404 return sys_sendto(p, &bsa, retval); 405 } 406 407 int 408 linux_recvfrom(p, uap, retval) 409 struct proc *p; 410 struct linux_recvfrom_args /* { 411 syscallarg(int) s; 412 syscallarg(void *) buf; 413 syscallarg(int) len; 414 syscallarg(int) flags; 415 syscallarg(struct sockaddr *) from; 416 syscallarg(int *) fromlen; 417 } */ *uap; 418 register_t *retval; 419 { 420 struct linux_recvfrom_args lra; 421 struct compat_43_sys_recvfrom_args bra; 422 int error; 423 424 if ((error = copyin((caddr_t) uap, (caddr_t) &lra, sizeof lra))) 425 return error; 426 427 SCARG(&bra, s) = lra.s; 428 SCARG(&bra, buf) = lra.buf; 429 SCARG(&bra, len) = lra.len; 430 SCARG(&bra, flags) = lra.flags; 431 SCARG(&bra, from) = (caddr_t) lra.from; 432 SCARG(&bra, fromlenaddr) = lra.fromlen; 433 434 return compat_43_sys_recvfrom(p, &bra, retval); 435 } 436 437 int 438 linux_shutdown(p, uap, retval) 439 struct proc *p; 440 struct linux_shutdown_args /* { 441 syscallarg(int) s; 442 syscallarg(int) how; 443 } */ *uap; 444 register_t *retval; 445 { 446 struct linux_shutdown_args lsa; 447 struct sys_shutdown_args bsa; 448 int error; 449 450 if ((error = copyin((caddr_t) uap, (caddr_t) &lsa, sizeof lsa))) 451 return error; 452 453 SCARG(&bsa, s) = lsa.s; 454 SCARG(&bsa, how) = lsa.how; 455 456 return sys_shutdown(p, &bsa, retval); 457 } 458 459 /* 460 * Convert socket option level from Linux to NetBSD value. Only SOL_SOCKET 461 * is different, the rest matches IPPROTO_* on both systems. 462 */ 463 int 464 linux_to_bsd_sopt_level(llevel) 465 int llevel; 466 { 467 468 switch (llevel) { 469 case LINUX_SOL_SOCKET: 470 return SOL_SOCKET; 471 case LINUX_SOL_IP: 472 return IPPROTO_IP; 473 case LINUX_SOL_TCP: 474 return IPPROTO_TCP; 475 case LINUX_SOL_UDP: 476 return IPPROTO_UDP; 477 default: 478 return -1; 479 } 480 } 481 482 /* 483 * Convert Linux socket level socket option numbers to NetBSD values. 484 */ 485 int 486 linux_to_bsd_so_sockopt(lopt) 487 int lopt; 488 { 489 490 switch (lopt) { 491 case LINUX_SO_DEBUG: 492 return SO_DEBUG; 493 case LINUX_SO_REUSEADDR: 494 return SO_REUSEADDR; 495 case LINUX_SO_TYPE: 496 return SO_TYPE; 497 case LINUX_SO_ERROR: 498 return SO_ERROR; 499 case LINUX_SO_DONTROUTE: 500 return SO_DONTROUTE; 501 case LINUX_SO_BROADCAST: 502 return SO_BROADCAST; 503 case LINUX_SO_SNDBUF: 504 return SO_SNDBUF; 505 case LINUX_SO_RCVBUF: 506 return SO_RCVBUF; 507 case LINUX_SO_KEEPALIVE: 508 return SO_KEEPALIVE; 509 case LINUX_SO_OOBINLINE: 510 return SO_OOBINLINE; 511 case LINUX_SO_LINGER: 512 return SO_LINGER; 513 case LINUX_SO_PRIORITY: 514 case LINUX_SO_NO_CHECK: 515 default: 516 return -1; 517 } 518 } 519 520 /* 521 * Convert Linux IP level socket option number to NetBSD values. 522 */ 523 int 524 linux_to_bsd_ip_sockopt(lopt) 525 int lopt; 526 { 527 528 switch (lopt) { 529 case LINUX_IP_TOS: 530 return IP_TOS; 531 case LINUX_IP_TTL: 532 return IP_TTL; 533 case LINUX_IP_MULTICAST_TTL: 534 return IP_MULTICAST_TTL; 535 case LINUX_IP_MULTICAST_LOOP: 536 return IP_MULTICAST_LOOP; 537 case LINUX_IP_MULTICAST_IF: 538 return IP_MULTICAST_IF; 539 case LINUX_IP_ADD_MEMBERSHIP: 540 return IP_ADD_MEMBERSHIP; 541 case LINUX_IP_DROP_MEMBERSHIP: 542 return IP_DROP_MEMBERSHIP; 543 default: 544 return -1; 545 } 546 } 547 548 /* 549 * Convert Linux TCP level socket option number to NetBSD values. 550 */ 551 int 552 linux_to_bsd_tcp_sockopt(lopt) 553 int lopt; 554 { 555 556 switch (lopt) { 557 case LINUX_TCP_NODELAY: 558 return TCP_NODELAY; 559 case LINUX_TCP_MAXSEG: 560 return TCP_MAXSEG; 561 default: 562 return -1; 563 } 564 } 565 566 /* 567 * Convert Linux UDP level socket option number to NetBSD values. 568 */ 569 int 570 linux_to_bsd_udp_sockopt(lopt) 571 int lopt; 572 { 573 574 switch (lopt) { 575 default: 576 return -1; 577 } 578 } 579 580 /* 581 * Another reasonably straightforward function: setsockopt(2). 582 * The level and option numbers are converted; the values passed 583 * are not (yet) converted, the ones currently implemented don't 584 * need conversion, as they are the same on both systems. 585 */ 586 int 587 linux_setsockopt(p, uap, retval) 588 struct proc *p; 589 struct linux_setsockopt_args /* { 590 syscallarg(int) s; 591 syscallarg(int) level; 592 syscallarg(int) optname; 593 syscallarg(void *) optval; 594 syscallarg(int) optlen; 595 } */ *uap; 596 register_t *retval; 597 { 598 struct linux_setsockopt_args lsa; 599 struct sys_setsockopt_args bsa; 600 int error, name; 601 602 if ((error = copyin((caddr_t) uap, (caddr_t) &lsa, sizeof lsa))) 603 return error; 604 605 SCARG(&bsa, s) = lsa.s; 606 SCARG(&bsa, level) = linux_to_bsd_sopt_level(lsa.level); 607 SCARG(&bsa, val) = lsa.optval; 608 SCARG(&bsa, valsize) = lsa.optlen; 609 610 switch (SCARG(&bsa, level)) { 611 case SOL_SOCKET: 612 name = linux_to_bsd_so_sockopt(lsa.optname); 613 break; 614 case IPPROTO_IP: 615 name = linux_to_bsd_ip_sockopt(lsa.optname); 616 break; 617 case IPPROTO_TCP: 618 name = linux_to_bsd_tcp_sockopt(lsa.optname); 619 break; 620 case IPPROTO_UDP: 621 name = linux_to_bsd_udp_sockopt(lsa.optname); 622 break; 623 default: 624 return EINVAL; 625 } 626 627 if (name == -1) 628 return EINVAL; 629 SCARG(&bsa, name) = name; 630 631 return sys_setsockopt(p, &bsa, retval); 632 } 633 634 /* 635 * getsockopt(2) is very much the same as setsockopt(2) (see above) 636 */ 637 int 638 linux_getsockopt(p, uap, retval) 639 struct proc *p; 640 struct linux_getsockopt_args /* { 641 syscallarg(int) s; 642 syscallarg(int) level; 643 syscallarg(int) optname; 644 syscallarg(void *) optval; 645 syscallarg(int) *optlen; 646 } */ *uap; 647 register_t *retval; 648 { 649 struct linux_getsockopt_args lga; 650 struct sys_getsockopt_args bga; 651 int error, name; 652 653 if ((error = copyin((caddr_t) uap, (caddr_t) &lga, sizeof lga))) 654 return error; 655 656 SCARG(&bga, s) = lga.s; 657 SCARG(&bga, level) = linux_to_bsd_sopt_level(lga.level); 658 SCARG(&bga, val) = lga.optval; 659 SCARG(&bga, avalsize) = lga.optlen; 660 661 switch (SCARG(&bga, level)) { 662 case SOL_SOCKET: 663 name = linux_to_bsd_so_sockopt(lga.optname); 664 break; 665 case IPPROTO_IP: 666 name = linux_to_bsd_ip_sockopt(lga.optname); 667 break; 668 case IPPROTO_TCP: 669 name = linux_to_bsd_tcp_sockopt(lga.optname); 670 break; 671 case IPPROTO_UDP: 672 name = linux_to_bsd_udp_sockopt(lga.optname); 673 break; 674 default: 675 return EINVAL; 676 } 677 678 if (name == -1) 679 return EINVAL; 680 SCARG(&bga, name) = name; 681 682 return sys_getsockopt(p, &bga, retval); 683 } 684 685 /* 686 * Entry point to all Linux socket calls. Just check which call to 687 * make and take appropriate action. 688 */ 689 int 690 linux_sys_socketcall(p, v, retval) 691 struct proc *p; 692 void *v; 693 register_t *retval; 694 { 695 struct linux_sys_socketcall_args /* { 696 syscallarg(int) what; 697 syscallarg(void *) args; 698 } */ *uap = v; 699 700 switch (SCARG(uap, what)) { 701 case LINUX_SYS_socket: 702 return linux_socket(p, SCARG(uap, args), retval); 703 case LINUX_SYS_bind: 704 return linux_bind(p, SCARG(uap, args), retval); 705 case LINUX_SYS_connect: 706 return linux_connect(p, SCARG(uap, args), retval); 707 case LINUX_SYS_listen: 708 return linux_listen(p, SCARG(uap, args), retval); 709 case LINUX_SYS_accept: 710 return linux_accept(p, SCARG(uap, args), retval); 711 case LINUX_SYS_getsockname: 712 return linux_getsockname(p, SCARG(uap, args), retval); 713 case LINUX_SYS_getpeername: 714 return linux_getpeername(p, SCARG(uap, args), retval); 715 case LINUX_SYS_socketpair: 716 return linux_socketpair(p, SCARG(uap, args), retval); 717 case LINUX_SYS_send: 718 return linux_send(p, SCARG(uap, args), retval); 719 case LINUX_SYS_recv: 720 return linux_recv(p, SCARG(uap, args), retval); 721 case LINUX_SYS_sendto: 722 return linux_sendto(p, SCARG(uap, args), retval); 723 case LINUX_SYS_recvfrom: 724 return linux_recvfrom(p, SCARG(uap, args), retval); 725 case LINUX_SYS_shutdown: 726 return linux_shutdown(p, SCARG(uap, args), retval); 727 case LINUX_SYS_setsockopt: 728 return linux_setsockopt(p, SCARG(uap, args), retval); 729 case LINUX_SYS_getsockopt: 730 return linux_getsockopt(p, SCARG(uap, args), retval); 731 default: 732 return ENOSYS; 733 } 734 } 735 736 int 737 linux_ioctl_socket(p, uap, retval) 738 register struct proc *p; 739 register struct linux_sys_ioctl_args /* { 740 syscallarg(int) fd; 741 syscallarg(u_long) com; 742 syscallarg(caddr_t) data; 743 } */ *uap; 744 register_t *retval; 745 { 746 u_long com; 747 struct sys_ioctl_args ia; 748 749 com = SCARG(uap, com); 750 retval[0] = 0; 751 752 switch (com) { 753 case LINUX_SIOCGIFCONF: 754 SCARG(&ia, com) = OSIOCGIFCONF; 755 break; 756 case LINUX_SIOCGIFFLAGS: 757 SCARG(&ia, com) = SIOCGIFFLAGS; 758 break; 759 case LINUX_SIOCGIFADDR: 760 SCARG(&ia, com) = OSIOCGIFADDR; 761 break; 762 case LINUX_SIOCGIFDSTADDR: 763 SCARG(&ia, com) = OSIOCGIFDSTADDR; 764 break; 765 case LINUX_SIOCGIFBRDADDR: 766 SCARG(&ia, com) = OSIOCGIFBRDADDR; 767 break; 768 case LINUX_SIOCGIFNETMASK: 769 SCARG(&ia, com) = OSIOCGIFNETMASK; 770 break; 771 case LINUX_SIOCADDMULTI: 772 SCARG(&ia, com) = SIOCADDMULTI; 773 break; 774 case LINUX_SIOCDELMULTI: 775 SCARG(&ia, com) = SIOCDELMULTI; 776 break; 777 default: 778 return EINVAL; 779 } 780 781 SCARG(&ia, fd) = SCARG(uap, fd); 782 SCARG(&ia, data) = SCARG(uap, data); 783 return sys_ioctl(p, &ia, retval); 784 } 785