1 /* 2 * Copyright (c) 2010 Kip Macy. All rights reserved. 3 * Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, this 10 * list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * Derived in part from libplebnet's pn_syscall_wrapper.c. 27 */ 28 29 #include <sys/param.h> 30 #include <sys/limits.h> 31 #include <sys/uio.h> 32 #include <sys/proc.h> 33 #include <sys/syscallsubr.h> 34 #include <sys/module.h> 35 #include <sys/param.h> 36 #include <sys/malloc.h> 37 #include <sys/socketvar.h> 38 #include <sys/event.h> 39 #include <sys/kernel.h> 40 #include <sys/refcount.h> 41 #include <sys/sysctl.h> 42 #include <sys/pcpu.h> 43 #include <sys/select.h> 44 #include <sys/poll.h> 45 #include <sys/event.h> 46 #include <sys/file.h> 47 #include <netinet/in.h> 48 #include <netinet/tcp.h> 49 #include <sys/ttycom.h> 50 #include <sys/filio.h> 51 #include <sys/sysproto.h> 52 #include <sys/fcntl.h> 53 #include <net/route.h> 54 #include <net/route/route_ctl.h> 55 56 #include <net/if.h> 57 #include <sys/sockio.h> 58 59 #include <machine/stdarg.h> 60 61 #include "ff_api.h" 62 #include "ff_host_interface.h" 63 64 /* setsockopt/getsockopt define start */ 65 66 #define LINUX_SOL_SOCKET 1 67 68 #define LINUX_SO_DEBUG 1 69 #define LINUX_SO_REUSEADDR 2 70 #define LINUX_SO_ERROR 4 71 #define LINUX_SO_DONTROUTE 5 72 #define LINUX_SO_BROADCAST 6 73 #define LINUX_SO_SNDBUF 7 74 #define LINUX_SO_RCVBUF 8 75 #define LINUX_SO_KEEPALIVE 9 76 #define LINUX_SO_OOBINLINE 10 77 #define LINUX_SO_LINGER 13 78 #define LINUX_SO_REUSEPORT 15 79 #define LINUX_SO_RCVLOWAT 18 80 #define LINUX_SO_SNDLOWAT 19 81 #define LINUX_SO_RCVTIMEO 20 82 #define LINUX_SO_SNDTIMEO 21 83 #define LINUX_SO_ACCEPTCONN 30 84 #define LINUX_SO_PROTOCOL 38 85 86 87 #define LINUX_IP_TOS 1 88 #define LINUX_IP_TTL 2 89 #define LINUX_IP_HDRINCL 3 90 #define LINUX_IP_OPTIONS 4 91 #define LINUX_IP_RECVTTL 12 92 #define LINUX_IP_RECVTOS 13 93 94 #define LINUX_IP_MULTICAST_IF 32 95 #define LINUX_IP_MULTICAST_TTL 33 96 #define LINUX_IP_MULTICAST_LOOP 34 97 #define LINUX_IP_ADD_MEMBERSHIP 35 98 #define LINUX_IP_DROP_MEMBERSHIP 36 99 100 #define LINUX_IPV6_V6ONLY 26 101 #define LINUX_IPV6_RECVPKTINFO 49 102 103 #define LINUX_TCP_NODELAY 1 104 #define LINUX_TCP_MAXSEG 2 105 #define LINUX_TCP_KEEPIDLE 4 106 #define LINUX_TCP_KEEPINTVL 5 107 #define LINUX_TCP_KEEPCNT 6 108 #define LINUX_TCP_INFO 11 109 #define LINUX_TCP_MD5SIG 14 110 111 /* setsockopt/getsockopt define end */ 112 113 114 /* ioctl define start */ 115 116 #define LINUX_TIOCEXCL 0x540C 117 #define LINUX_TIOCNXCL 0x540D 118 #define LINUX_TIOCSCTTY 0x540E 119 #define LINUX_TIOCGPGRP 0x540F 120 #define LINUX_TIOCSPGRP 0x5410 121 #define LINUX_TIOCOUTQ 0x5411 122 #define LINUX_TIOCSTI 0x5412 123 #define LINUX_TIOCGWINSZ 0x5413 124 #define LINUX_TIOCSWINSZ 0x5414 125 #define LINUX_TIOCMGET 0x5415 126 #define LINUX_TIOCMBIS 0x5416 127 #define LINUX_TIOCMBIC 0x5417 128 #define LINUX_TIOCMSET 0x5418 129 130 #define LINUX_FIONREAD 0x541B 131 #define LINUX_TIOCCONS 0x541D 132 #define LINUX_TIOCPKT 0x5420 133 #define LINUX_FIONBIO 0x5421 134 #define LINUX_TIOCNOTTY 0x5422 135 #define LINUX_TIOCSETD 0x5423 136 #define LINUX_TIOCGETD 0x5424 137 #define LINUX_TIOCSBRK 0x5427 138 #define LINUX_TIOCCBRK 0x5428 139 #define LINUX_TIOCGSID 0x5429 140 141 #define LINUX_FIONCLEX 0x5450 142 #define LINUX_FIOCLEX 0x5451 143 #define LINUX_FIOASYNC 0x5452 144 145 #define LINUX_TIOCPKT_DATA 0 146 #define LINUX_TIOCPKT_FLUSHREAD 1 147 #define LINUX_TIOCPKT_FLUSHWRITE 2 148 #define LINUX_TIOCPKT_STOP 4 149 #define LINUX_TIOCPKT_START 8 150 #define LINUX_TIOCPKT_NOSTOP 16 151 #define LINUX_TIOCPKT_DOSTOP 32 152 #define LINUX_TIOCPKT_IOCTL 64 153 154 #define LINUX_SIOCGIFCONF 0x8912 155 #define LINUX_SIOCGIFFLAGS 0x8913 156 #define LINUX_SIOCSIFFLAGS 0x8914 157 #define LINUX_SIOCGIFADDR 0x8915 158 #define LINUX_SIOCSIFADDR 0x8916 159 #define LINUX_SIOCGIFDSTADDR 0x8917 160 #define LINUX_SIOCSIFDSTADDR 0x8918 161 #define LINUX_SIOCGIFBRDADDR 0x8919 162 #define LINUX_SIOCSIFBRDADDR 0x891a 163 #define LINUX_SIOCGIFNETMASK 0x891b 164 #define LINUX_SIOCSIFNETMASK 0x891c 165 #define LINUX_SIOCGIFMETRIC 0x891d 166 #define LINUX_SIOCSIFMETRIC 0x891e 167 #define LINUX_SIOCGIFMTU 0x8921 168 #define LINUX_SIOCSIFMTU 0x8922 169 #define LINUX_SIOCSIFNAME 0x8923 170 #define LINUX_SIOCADDMULTI 0x8931 171 #define LINUX_SIOCDELMULTI 0x8932 172 #define LINUX_SIOCGIFINDEX 0x8933 173 #define LINUX_SIOCDIFADDR 0x8936 174 175 /* ioctl define end */ 176 177 /* af define start */ 178 179 #define LINUX_AF_INET6 10 180 181 /* af define end */ 182 183 /* msghdr define start */ 184 185 struct linux_msghdr { 186 void *msg_name; /* Address to send to/receive from. */ 187 socklen_t msg_namelen; /* Length of address data. */ 188 189 struct iovec *msg_iov; /* Vector of data to send/receive into. */ 190 size_t msg_iovlen; /* Number of elements in the vector. */ 191 192 void *msg_control; /* Ancillary data (eg BSD filedesc passing). */ 193 size_t msg_controllen; /* Ancillary data buffer length. 194 !! The type should be socklen_t but the 195 definition of the kernel is incompatible 196 with this. */ 197 198 int msg_flags; /* Flags on received message. */ 199 }; 200 201 /* msghdr define end */ 202 203 /* cmsghdr define start */ 204 205 struct linux_cmsghdr 206 { 207 size_t cmsg_len; /* Length of data in cmsg_data plus length 208 of cmsghdr structure. 209 !! The type should be socklen_t but the 210 definition of the kernel is incompatible 211 with this. */ 212 int cmsg_level; /* Originating protocol. */ 213 int cmsg_type; /* Protocol specific type. */ 214 }; 215 216 /* cmsghdr define end */ 217 218 extern int sendit(struct thread *td, int s, struct msghdr *mp, int flags); 219 220 static long 221 linux2freebsd_ioctl(unsigned long request) 222 { 223 switch(request) { 224 case LINUX_TIOCEXCL: 225 return TIOCEXCL; 226 case LINUX_TIOCNXCL: 227 return TIOCNXCL; 228 case LINUX_TIOCSCTTY: 229 return TIOCSCTTY; 230 case LINUX_TIOCGPGRP: 231 return TIOCGPGRP; 232 case LINUX_TIOCSPGRP: 233 return TIOCSPGRP; 234 case LINUX_TIOCOUTQ: 235 return TIOCOUTQ; 236 case LINUX_TIOCSTI: 237 return TIOCSTI; 238 case LINUX_TIOCGWINSZ: 239 return TIOCGWINSZ; 240 case LINUX_TIOCSWINSZ: 241 return TIOCSWINSZ; 242 case LINUX_TIOCMGET: 243 return TIOCMGET; 244 case LINUX_TIOCMBIS: 245 return TIOCMBIS; 246 case LINUX_TIOCMBIC: 247 return TIOCMBIC; 248 case LINUX_TIOCMSET: 249 return TIOCMSET; 250 case LINUX_FIONREAD: 251 return FIONREAD; 252 case LINUX_TIOCCONS: 253 return TIOCCONS; 254 case LINUX_TIOCPKT: 255 return TIOCPKT; 256 case LINUX_FIONBIO: 257 return FIONBIO; 258 case LINUX_TIOCNOTTY: 259 return TIOCNOTTY; 260 case LINUX_TIOCSETD: 261 return TIOCSETD; 262 case LINUX_TIOCGETD: 263 return TIOCGETD; 264 case LINUX_TIOCSBRK: 265 return TIOCSBRK; 266 case LINUX_TIOCCBRK: 267 return TIOCCBRK; 268 case LINUX_TIOCGSID: 269 return TIOCGSID; 270 case LINUX_FIONCLEX: 271 return FIONCLEX; 272 case LINUX_FIOCLEX: 273 return FIOCLEX; 274 case LINUX_FIOASYNC: 275 return FIOASYNC; 276 case LINUX_TIOCPKT_DATA: 277 return TIOCPKT_DATA; 278 case LINUX_TIOCPKT_FLUSHREAD: 279 return TIOCPKT_FLUSHREAD; 280 case LINUX_TIOCPKT_FLUSHWRITE: 281 return TIOCPKT_FLUSHWRITE; 282 case LINUX_TIOCPKT_STOP: 283 return TIOCPKT_STOP; 284 case LINUX_TIOCPKT_START: 285 return TIOCPKT_START; 286 case LINUX_TIOCPKT_NOSTOP: 287 return TIOCPKT_NOSTOP; 288 case LINUX_TIOCPKT_DOSTOP: 289 return TIOCPKT_DOSTOP; 290 case LINUX_TIOCPKT_IOCTL: 291 return TIOCPKT_IOCTL; 292 case LINUX_SIOCGIFCONF: 293 return SIOCGIFCONF; 294 case LINUX_SIOCGIFFLAGS: 295 return SIOCGIFFLAGS; 296 case LINUX_SIOCSIFFLAGS: 297 return SIOCSIFFLAGS; 298 case LINUX_SIOCGIFADDR: 299 return SIOCGIFADDR; 300 case LINUX_SIOCSIFADDR: 301 return SIOCSIFADDR; 302 case LINUX_SIOCGIFDSTADDR: 303 return SIOCGIFDSTADDR; 304 case LINUX_SIOCSIFDSTADDR: 305 return SIOCSIFDSTADDR; 306 case LINUX_SIOCGIFBRDADDR: 307 return SIOCGIFBRDADDR; 308 case LINUX_SIOCSIFBRDADDR: 309 return SIOCSIFBRDADDR; 310 case LINUX_SIOCGIFNETMASK: 311 return SIOCGIFNETMASK; 312 case LINUX_SIOCSIFNETMASK: 313 return SIOCSIFNETMASK; 314 case LINUX_SIOCGIFMETRIC: 315 return SIOCGIFMETRIC; 316 case LINUX_SIOCSIFMETRIC: 317 return SIOCSIFMETRIC; 318 case LINUX_SIOCGIFMTU: 319 return SIOCGIFMTU; 320 case LINUX_SIOCSIFMTU: 321 return SIOCSIFMTU; 322 case LINUX_SIOCSIFNAME: 323 return SIOCSIFNAME; 324 case LINUX_SIOCADDMULTI: 325 return SIOCADDMULTI; 326 case LINUX_SIOCDELMULTI: 327 return SIOCDELMULTI; 328 case LINUX_SIOCGIFINDEX: 329 return SIOCGIFINDEX; 330 case LINUX_SIOCDIFADDR: 331 return SIOCDIFADDR; 332 default: 333 return -1; 334 } 335 } 336 337 static int 338 so_opt_convert(int optname) 339 { 340 switch(optname) { 341 case LINUX_SO_DEBUG: 342 return SO_DEBUG; 343 case LINUX_SO_REUSEADDR: 344 return SO_REUSEADDR; 345 case LINUX_SO_ERROR: 346 return SO_ERROR; 347 case LINUX_SO_DONTROUTE: 348 return SO_DONTROUTE; 349 case LINUX_SO_BROADCAST: 350 return SO_BROADCAST; 351 case LINUX_SO_SNDBUF: 352 return SO_SNDBUF; 353 case LINUX_SO_RCVBUF: 354 return SO_RCVBUF; 355 case LINUX_SO_KEEPALIVE: 356 return SO_KEEPALIVE; 357 case LINUX_SO_OOBINLINE: 358 return SO_OOBINLINE; 359 case LINUX_SO_LINGER: 360 return SO_LINGER; 361 case LINUX_SO_REUSEPORT: 362 return SO_REUSEPORT; 363 case LINUX_SO_RCVLOWAT: 364 return SO_RCVLOWAT; 365 case LINUX_SO_SNDLOWAT: 366 return SO_SNDLOWAT; 367 case LINUX_SO_RCVTIMEO: 368 return SO_RCVTIMEO; 369 case LINUX_SO_SNDTIMEO: 370 return SO_SNDTIMEO; 371 case LINUX_SO_ACCEPTCONN: 372 return SO_ACCEPTCONN; 373 case LINUX_SO_PROTOCOL: 374 return SO_PROTOCOL; 375 default: 376 return -1; 377 } 378 } 379 380 static int 381 ip_opt_convert(int optname) 382 { 383 switch(optname) { 384 case LINUX_IP_TOS: 385 return IP_TOS; 386 case LINUX_IP_TTL: 387 return IP_TTL; 388 case LINUX_IP_HDRINCL: 389 return IP_HDRINCL; 390 case LINUX_IP_OPTIONS: 391 return IP_OPTIONS; 392 case LINUX_IP_MULTICAST_IF: 393 return IP_MULTICAST_IF; 394 case LINUX_IP_MULTICAST_TTL: 395 return IP_MULTICAST_TTL; 396 case LINUX_IP_MULTICAST_LOOP: 397 return IP_MULTICAST_LOOP; 398 case LINUX_IP_ADD_MEMBERSHIP: 399 return IP_ADD_MEMBERSHIP; 400 case LINUX_IP_DROP_MEMBERSHIP: 401 return IP_DROP_MEMBERSHIP; 402 case LINUX_IP_RECVTTL: 403 return IP_RECVTTL; 404 case LINUX_IP_RECVTOS: 405 return IP_RECVTOS; 406 default: 407 return optname; 408 } 409 } 410 411 static int 412 ip6_opt_convert(int optname) 413 { 414 switch(optname) { 415 case LINUX_IPV6_V6ONLY: 416 return IPV6_V6ONLY; 417 case LINUX_IPV6_RECVPKTINFO: 418 return IPV6_RECVPKTINFO; 419 default: 420 return optname; 421 } 422 } 423 424 static int 425 tcp_opt_convert(int optname) 426 { 427 switch(optname) { 428 case LINUX_TCP_NODELAY: 429 return TCP_NODELAY; 430 case LINUX_TCP_MAXSEG: 431 return TCP_MAXSEG; 432 case LINUX_TCP_KEEPIDLE: 433 return TCP_KEEPIDLE; 434 case LINUX_TCP_KEEPINTVL: 435 return TCP_KEEPINTVL; 436 case LINUX_TCP_KEEPCNT: 437 return TCP_KEEPCNT; 438 case LINUX_TCP_INFO: 439 return TCP_INFO; 440 case LINUX_TCP_MD5SIG: 441 return TCP_MD5SIG; 442 default: 443 return -1; 444 } 445 } 446 447 static int 448 ip_opt_convert2linux(int optname) 449 { 450 switch(optname) { 451 case IP_RECVTTL: 452 return LINUX_IP_TTL; // in linux kernel return IP_TTL not IP_RECVTTL 453 case IP_RECVTOS: 454 return LINUX_IP_TOS; // in linux kernel return IP_TOS not IP_RECVTOS 455 default: 456 return optname; 457 } 458 } 459 460 static void 461 freebsd2linux_cmsghdr(struct linux_msghdr *linux_msg) 462 { 463 struct cmsghdr *cmsg; 464 cmsg = CMSG_FIRSTHDR(linux_msg); 465 struct linux_cmsghdr *linux_cmsg = (struct linux_cmsghdr*)cmsg; 466 467 // for multiple cmsghdrs implement for loop 468 // for (; cmsg; cmsg = CMSG_NXTHDR(linux_msg, cmsg)) 469 // { 470 switch (cmsg->cmsg_level) 471 { 472 case IPPROTO_IP: 473 linux_cmsg->cmsg_type = ip_opt_convert2linux(cmsg->cmsg_type); 474 break; 475 default: 476 break; 477 } 478 479 linux_cmsg->cmsg_level = cmsg->cmsg_level; 480 linux_cmsg->cmsg_len = cmsg->cmsg_len + sizeof(struct linux_cmsghdr) - sizeof(struct cmsghdr); 481 // } 482 } 483 484 static int 485 linux2freebsd_opt(int level, int optname) 486 { 487 switch(level) { 488 case SOL_SOCKET: 489 return so_opt_convert(optname); 490 case IPPROTO_IP: 491 return ip_opt_convert(optname); 492 case IPPROTO_IPV6: 493 return ip6_opt_convert(optname); 494 case IPPROTO_TCP: 495 return tcp_opt_convert(optname); 496 default: 497 return -1; 498 } 499 } 500 501 static void 502 linux2freebsd_sockaddr(const struct linux_sockaddr *linux, 503 socklen_t addrlen, struct sockaddr *freebsd) 504 { 505 if (linux == NULL) { 506 return; 507 } 508 509 /* #linux and #freebsd may point to the same address */ 510 freebsd->sa_family = linux->sa_family == LINUX_AF_INET6 ? AF_INET6 : linux->sa_family; 511 freebsd->sa_len = addrlen; 512 513 bcopy(linux->sa_data, freebsd->sa_data, addrlen - sizeof(linux->sa_family)); 514 } 515 516 static void 517 freebsd2linux_sockaddr(struct linux_sockaddr *linux, 518 struct sockaddr *freebsd) 519 { 520 if (linux == NULL) { 521 return; 522 } 523 524 linux->sa_family = freebsd->sa_family == AF_INET6 ? LINUX_AF_INET6 : freebsd->sa_family; 525 526 bcopy(freebsd->sa_data, linux->sa_data, freebsd->sa_len - sizeof(linux->sa_family)); 527 } 528 529 int 530 ff_socket(int domain, int type, int protocol) 531 { 532 int rc; 533 struct socket_args sa; 534 sa.domain = domain == LINUX_AF_INET6 ? AF_INET6 : domain; 535 sa.type = type; 536 sa.protocol = protocol; 537 if ((rc = sys_socket(curthread, &sa))) 538 goto kern_fail; 539 540 return curthread->td_retval[0]; 541 kern_fail: 542 ff_os_errno(rc); 543 return (-1); 544 } 545 546 int 547 ff_getsockopt(int s, int level, int optname, void *optval, 548 socklen_t *optlen) 549 { 550 int rc; 551 if (level == LINUX_SOL_SOCKET) 552 level = SOL_SOCKET; 553 554 optname = linux2freebsd_opt(level, optname); 555 if (optname < 0) { 556 rc = EINVAL; 557 goto kern_fail; 558 } 559 560 if ((rc = kern_getsockopt(curthread, s, level, optname, 561 optval, UIO_USERSPACE, optlen))) 562 goto kern_fail; 563 564 return (rc); 565 566 kern_fail: 567 ff_os_errno(rc); 568 return (-1); 569 } 570 571 int 572 ff_getsockopt_freebsd(int s, int level, int optname, 573 void *optval, socklen_t *optlen) 574 { 575 int rc; 576 577 if ((rc = kern_getsockopt(curthread, s, level, optname, 578 optval, UIO_USERSPACE, optlen))) 579 goto kern_fail; 580 581 return (rc); 582 583 kern_fail: 584 ff_os_errno(rc); 585 return (-1); 586 } 587 588 int 589 ff_setsockopt(int s, int level, int optname, const void *optval, 590 socklen_t optlen) 591 { 592 int rc; 593 594 if (level == LINUX_SOL_SOCKET) 595 level = SOL_SOCKET; 596 597 optname = linux2freebsd_opt(level, optname); 598 if (optname < 0) { 599 rc = EINVAL; 600 goto kern_fail; 601 } 602 603 if ((rc = kern_setsockopt(curthread, s, level, optname, 604 __DECONST(void *, optval), UIO_USERSPACE, optlen))) 605 goto kern_fail; 606 607 return (rc); 608 609 kern_fail: 610 ff_os_errno(rc); 611 return (-1); 612 } 613 614 int 615 ff_setsockopt_freebsd(int s, int level, int optname, 616 const void *optval, socklen_t optlen) 617 { 618 int rc; 619 620 if ((rc = kern_setsockopt(curthread, s, level, optname, 621 __DECONST(void *, optval), UIO_USERSPACE, optlen))) 622 goto kern_fail; 623 624 return (rc); 625 626 kern_fail: 627 ff_os_errno(rc); 628 return (-1); 629 } 630 631 int 632 ff_ioctl(int fd, unsigned long request, ...) 633 { 634 int rc; 635 va_list ap; 636 caddr_t argp; 637 638 long req = linux2freebsd_ioctl(request); 639 if (req < 0) { 640 rc = EINVAL; 641 goto kern_fail; 642 } 643 644 va_start(ap, request); 645 646 argp = va_arg(ap, caddr_t); 647 va_end(ap); 648 if ((rc = kern_ioctl(curthread, fd, req, argp))) 649 goto kern_fail; 650 651 return (rc); 652 653 kern_fail: 654 ff_os_errno(rc); 655 return (-1); 656 } 657 658 int 659 ff_ioctl_freebsd(int fd, unsigned long request, ...) 660 { 661 int rc; 662 va_list ap; 663 caddr_t argp; 664 665 va_start(ap, request); 666 667 argp = va_arg(ap, caddr_t); 668 va_end(ap); 669 if ((rc = kern_ioctl(curthread, fd, request, argp))) 670 goto kern_fail; 671 672 return (rc); 673 674 kern_fail: 675 ff_os_errno(rc); 676 return (-1); 677 } 678 679 int 680 ff_close(int fd) 681 { 682 int rc; 683 684 if ((rc = kern_close(curthread, fd))) 685 goto kern_fail; 686 687 return (rc); 688 kern_fail: 689 ff_os_errno(rc); 690 return (-1); 691 } 692 693 ssize_t 694 ff_read(int fd, void *buf, size_t nbytes) 695 { 696 struct uio auio; 697 struct iovec aiov; 698 int rc; 699 700 if (nbytes > INT_MAX) { 701 rc = EINVAL; 702 goto kern_fail; 703 } 704 705 aiov.iov_base = buf; 706 aiov.iov_len = nbytes; 707 auio.uio_iov = &aiov; 708 auio.uio_iovcnt = 1; 709 auio.uio_resid = nbytes; 710 auio.uio_segflg = UIO_SYSSPACE; 711 if ((rc = kern_readv(curthread, fd, &auio))) 712 goto kern_fail; 713 rc = curthread->td_retval[0]; 714 715 return (rc); 716 kern_fail: 717 ff_os_errno(rc); 718 return (-1); 719 } 720 721 ssize_t 722 ff_readv(int fd, const struct iovec *iov, int iovcnt) 723 { 724 struct uio auio; 725 int rc, len, i; 726 727 len = 0; 728 for (i = 0; i < iovcnt; i++) 729 len += iov[i].iov_len; 730 auio.uio_iov = __DECONST(struct iovec *, iov); 731 auio.uio_iovcnt = iovcnt; 732 auio.uio_resid = len; 733 auio.uio_segflg = UIO_SYSSPACE; 734 735 if ((rc = kern_readv(curthread, fd, &auio))) 736 goto kern_fail; 737 rc = curthread->td_retval[0]; 738 739 return (rc); 740 kern_fail: 741 ff_os_errno(rc); 742 return (-1); 743 } 744 745 ssize_t 746 ff_write(int fd, const void *buf, size_t nbytes) 747 { 748 struct uio auio; 749 struct iovec aiov; 750 int rc; 751 752 if (nbytes > INT_MAX) { 753 rc = EINVAL; 754 goto kern_fail; 755 } 756 757 aiov.iov_base = (void *)(uintptr_t)buf; 758 aiov.iov_len = nbytes; 759 auio.uio_iov = &aiov; 760 auio.uio_iovcnt = 1; 761 auio.uio_resid = nbytes; 762 auio.uio_segflg = UIO_SYSSPACE; 763 if ((rc = kern_writev(curthread, fd, &auio))) 764 goto kern_fail; 765 rc = curthread->td_retval[0]; 766 767 return (rc); 768 kern_fail: 769 ff_os_errno(rc); 770 return (-1); 771 } 772 773 ssize_t 774 ff_writev(int fd, const struct iovec *iov, int iovcnt) 775 { 776 struct uio auio; 777 int i, rc, len; 778 779 len = 0; 780 for (i = 0; i < iovcnt; i++) 781 len += iov[i].iov_len; 782 auio.uio_iov = __DECONST(struct iovec *, iov); 783 auio.uio_iovcnt = iovcnt; 784 auio.uio_resid = len; 785 auio.uio_segflg = UIO_SYSSPACE; 786 if ((rc = kern_writev(curthread, fd, &auio))) 787 goto kern_fail; 788 rc = curthread->td_retval[0]; 789 790 return (rc); 791 kern_fail: 792 ff_os_errno(rc); 793 return (-1); 794 } 795 796 ssize_t 797 ff_send(int s, const void *buf, size_t len, int flags) 798 { 799 return (ff_sendto(s, buf, len, flags, NULL, 0)); 800 } 801 802 ssize_t 803 ff_sendto(int s, const void *buf, size_t len, int flags, 804 const struct linux_sockaddr *to, socklen_t tolen) 805 { 806 struct msghdr msg; 807 struct iovec aiov; 808 int rc; 809 810 struct sockaddr_storage bsdaddr; 811 struct sockaddr *pf = (struct sockaddr *)&bsdaddr; 812 813 if (to) { 814 linux2freebsd_sockaddr(to, tolen, pf); 815 } else { 816 pf = NULL; 817 } 818 819 msg.msg_name = pf; 820 msg.msg_namelen = tolen; 821 msg.msg_iov = &aiov; 822 msg.msg_iovlen = 1; 823 msg.msg_control = 0; 824 aiov.iov_base = __DECONST(void *, buf); 825 aiov.iov_len = len; 826 if ((rc = sendit(curthread, s, &msg, flags))) 827 goto kern_fail; 828 829 rc = curthread->td_retval[0]; 830 831 return (rc); 832 kern_fail: 833 ff_os_errno(rc); 834 return (-1); 835 } 836 837 ssize_t 838 ff_sendmsg(int s, const struct msghdr *msg, int flags) 839 { 840 int rc; 841 struct sockaddr_storage freebsd_sa; 842 void *linux_sa = msg->msg_name; 843 844 if (linux_sa != NULL) { 845 linux2freebsd_sockaddr(linux_sa, 846 sizeof(struct linux_sockaddr), (struct sockaddr *)&freebsd_sa); 847 __DECONST(struct msghdr *, msg)->msg_name = &freebsd_sa; 848 } 849 850 rc = sendit(curthread, s, __DECONST(struct msghdr *, msg), flags); 851 852 __DECONST(struct msghdr *, msg)->msg_name = linux_sa; 853 854 if (rc) 855 goto kern_fail; 856 857 rc = curthread->td_retval[0]; 858 859 return (rc); 860 kern_fail: 861 ff_os_errno(rc); 862 return (-1); 863 } 864 865 866 ssize_t 867 ff_recv(int s, void *buf, size_t len, int flags) 868 { 869 return (ff_recvfrom(s, buf, len, flags, NULL, 0)); 870 } 871 872 ssize_t 873 ff_recvfrom(int s, void *buf, size_t len, int flags, 874 struct linux_sockaddr *from, socklen_t *fromlen) 875 { 876 struct msghdr msg; 877 struct iovec aiov; 878 int rc; 879 struct sockaddr_storage bsdaddr; 880 881 if (fromlen != NULL) 882 msg.msg_namelen = *fromlen; 883 else 884 msg.msg_namelen = 0; 885 886 msg.msg_name = &bsdaddr; 887 msg.msg_iov = &aiov; 888 msg.msg_iovlen = 1; 889 aiov.iov_base = buf; 890 aiov.iov_len = len; 891 msg.msg_control = 0; 892 msg.msg_flags = flags; 893 if ((rc = kern_recvit(curthread, s, &msg, UIO_SYSSPACE, NULL))) 894 goto kern_fail; 895 rc = curthread->td_retval[0]; 896 if (fromlen != NULL) 897 *fromlen = msg.msg_namelen; 898 899 if (from) 900 freebsd2linux_sockaddr(from, (struct sockaddr *)&bsdaddr); 901 902 return (rc); 903 kern_fail: 904 ff_os_errno(rc); 905 return (-1); 906 } 907 908 /* 909 * It is considered here that the upper 4 bytes of 910 * msg->iovlen and msg->msg_controllen in linux_msghdr are 0. 911 */ 912 ssize_t 913 ff_recvmsg(int s, struct msghdr *msg, int flags) 914 { 915 int rc; 916 struct linux_msghdr *linux_msg = (struct linux_msghdr *)msg; 917 918 msg->msg_flags = flags; 919 920 if ((rc = kern_recvit(curthread, s, msg, UIO_SYSSPACE, NULL))) { 921 msg->msg_flags = 0; 922 goto kern_fail; 923 } 924 rc = curthread->td_retval[0]; 925 926 freebsd2linux_sockaddr(linux_msg->msg_name, msg->msg_name); 927 linux_msg->msg_flags = msg->msg_flags; 928 msg->msg_flags = 0; 929 930 if(msg->msg_control) 931 { 932 freebsd2linux_cmsghdr(linux_msg); 933 } 934 935 return (rc); 936 kern_fail: 937 ff_os_errno(rc); 938 return (-1); 939 } 940 941 int 942 ff_fcntl(int fd, int cmd, ...) 943 { 944 int rc; 945 va_list ap; 946 uintptr_t argp; 947 948 va_start(ap, cmd); 949 950 argp = va_arg(ap, uintptr_t); 951 va_end(ap); 952 953 if ((rc = kern_fcntl(curthread, fd, cmd, argp))) 954 goto kern_fail; 955 rc = curthread->td_retval[0]; 956 return (rc); 957 kern_fail: 958 ff_os_errno(rc); 959 return (-1); 960 } 961 962 int 963 ff_accept(int s, struct linux_sockaddr * addr, 964 socklen_t * addrlen) 965 { 966 int rc; 967 struct file *fp; 968 struct sockaddr *pf = NULL; 969 socklen_t socklen = sizeof(struct sockaddr_storage); 970 971 if ((rc = kern_accept(curthread, s, &pf, &socklen, &fp))) 972 goto kern_fail; 973 974 rc = curthread->td_retval[0]; 975 fdrop(fp, curthread); 976 977 if (addr && pf) 978 freebsd2linux_sockaddr(addr, pf); 979 980 if (addrlen) 981 *addrlen = pf->sa_len; 982 983 if(pf != NULL) 984 free(pf, M_SONAME); 985 return (rc); 986 987 kern_fail: 988 if(pf != NULL) 989 free(pf, M_SONAME); 990 ff_os_errno(rc); 991 return (-1); 992 } 993 994 int 995 ff_listen(int s, int backlog) 996 { 997 int rc; 998 struct listen_args la = { 999 .s = s, 1000 .backlog = backlog, 1001 }; 1002 if ((rc = sys_listen(curthread, &la))) 1003 goto kern_fail; 1004 1005 return (rc); 1006 kern_fail: 1007 ff_os_errno(rc); 1008 return (-1); 1009 } 1010 1011 int 1012 ff_bind(int s, const struct linux_sockaddr *addr, socklen_t addrlen) 1013 { 1014 int rc; 1015 struct sockaddr_storage bsdaddr; 1016 linux2freebsd_sockaddr(addr, addrlen, (struct sockaddr *)&bsdaddr); 1017 1018 if ((rc = kern_bindat(curthread, AT_FDCWD, s, (struct sockaddr *)&bsdaddr))) 1019 goto kern_fail; 1020 1021 return (rc); 1022 kern_fail: 1023 ff_os_errno(rc); 1024 return (-1); 1025 } 1026 1027 int 1028 ff_connect(int s, const struct linux_sockaddr *name, socklen_t namelen) 1029 { 1030 int rc; 1031 struct sockaddr_storage bsdaddr; 1032 linux2freebsd_sockaddr(name, namelen, (struct sockaddr *)&bsdaddr); 1033 1034 if ((rc = kern_connectat(curthread, AT_FDCWD, s, (struct sockaddr *)&bsdaddr))) 1035 goto kern_fail; 1036 1037 return (rc); 1038 kern_fail: 1039 ff_os_errno(rc); 1040 return (-1); 1041 } 1042 1043 int 1044 ff_getpeername(int s, struct linux_sockaddr * name, 1045 socklen_t *namelen) 1046 { 1047 int rc; 1048 struct sockaddr *pf = NULL; 1049 1050 if ((rc = kern_getpeername(curthread, s, &pf, namelen))) 1051 goto kern_fail; 1052 1053 if (name && pf) 1054 freebsd2linux_sockaddr(name, pf); 1055 1056 if(pf != NULL) 1057 free(pf, M_SONAME); 1058 return (rc); 1059 1060 kern_fail: 1061 if(pf != NULL) 1062 free(pf, M_SONAME); 1063 ff_os_errno(rc); 1064 return (-1); 1065 } 1066 1067 int 1068 ff_getsockname(int s, struct linux_sockaddr *name, 1069 socklen_t *namelen) 1070 { 1071 int rc; 1072 struct sockaddr *pf = NULL; 1073 1074 if ((rc = kern_getsockname(curthread, s, &pf, namelen))) 1075 goto kern_fail; 1076 1077 if (name && pf) 1078 freebsd2linux_sockaddr(name, pf); 1079 1080 if(pf != NULL) 1081 free(pf, M_SONAME); 1082 return (rc); 1083 1084 kern_fail: 1085 if(pf != NULL) 1086 free(pf, M_SONAME); 1087 ff_os_errno(rc); 1088 return (-1); 1089 } 1090 1091 int 1092 ff_shutdown(int s, int how) 1093 { 1094 int rc; 1095 1096 struct shutdown_args sa = { 1097 .s = s, 1098 .how = how, 1099 }; 1100 if ((rc = sys_shutdown(curthread, &sa))) 1101 goto kern_fail; 1102 1103 return (rc); 1104 kern_fail: 1105 ff_os_errno(rc); 1106 return (-1); 1107 } 1108 1109 int 1110 ff_sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp, 1111 const void *newp, size_t newlen) 1112 { 1113 int rc; 1114 size_t retval; 1115 1116 rc = userland_sysctl(curthread, __DECONST(int *, name), namelen, oldp, oldlenp, 1117 1, __DECONST(void *, newp), newlen, &retval, 0); 1118 if (rc) 1119 goto kern_fail; 1120 if (oldlenp) 1121 *oldlenp = retval; 1122 return (0); 1123 kern_fail: 1124 ff_os_errno(rc); 1125 return (-1); 1126 } 1127 1128 int 1129 ff_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 1130 struct timeval *timeout) 1131 1132 { 1133 int rc; 1134 1135 rc = kern_select(curthread, nfds, readfds, writefds, exceptfds, timeout, 64); 1136 if (rc) 1137 goto kern_fail; 1138 rc = curthread->td_retval[0]; 1139 1140 return (rc); 1141 kern_fail: 1142 ff_os_errno(rc); 1143 return (-1); 1144 1145 } 1146 1147 int 1148 ff_poll(struct pollfd fds[], nfds_t nfds, int timeout) 1149 { 1150 int rc; 1151 struct timespec ts; 1152 ts.tv_sec = 0; 1153 ts.tv_nsec = 0; 1154 if ((rc = kern_poll(curthread, fds, nfds, &ts, NULL))) 1155 goto kern_fail; 1156 rc = curthread->td_retval[0]; 1157 return (rc); 1158 1159 kern_fail: 1160 ff_os_errno(rc); 1161 return (-1); 1162 } 1163 1164 int 1165 ff_kqueue(void) 1166 { 1167 int rc; 1168 if ((rc = kern_kqueue(curthread, 0, NULL))) 1169 goto kern_fail; 1170 1171 rc = curthread->td_retval[0]; 1172 return (rc); 1173 1174 kern_fail: 1175 ff_os_errno(rc); 1176 return (-1); 1177 } 1178 1179 struct sys_kevent_args { 1180 int fd; 1181 const struct kevent *changelist; 1182 int nchanges; 1183 void *eventlist; 1184 int nevents; 1185 const struct timespec *timeout; 1186 void (*do_each)(void **, struct kevent *); 1187 }; 1188 1189 static int 1190 kevent_copyout(void *arg, struct kevent *kevp, int count) 1191 { 1192 int i; 1193 struct kevent *ke; 1194 struct sys_kevent_args *uap; 1195 1196 uap = (struct sys_kevent_args *)arg; 1197 1198 if (!uap->do_each) { 1199 bcopy(kevp, uap->eventlist, count * sizeof *kevp); 1200 uap->eventlist = (void *)((struct kevent *)(uap->eventlist) + count); 1201 1202 } else { 1203 for (ke = kevp, i = 0; i < count; i++, ke++) { 1204 uap->do_each(&(uap->eventlist), ke); 1205 } 1206 } 1207 1208 return (0); 1209 } 1210 1211 /* 1212 * Copy 'count' items from the list pointed to by uap->changelist. 1213 */ 1214 static int 1215 kevent_copyin(void *arg, struct kevent *kevp, int count) 1216 { 1217 struct sys_kevent_args *uap; 1218 1219 uap = (struct sys_kevent_args *)arg; 1220 bcopy(uap->changelist, kevp, count * sizeof *kevp); 1221 1222 uap->changelist += count; 1223 1224 return (0); 1225 } 1226 1227 int 1228 ff_kevent_do_each(int kq, const struct kevent *changelist, int nchanges, 1229 void *eventlist, int nevents, const struct timespec *timeout, 1230 void (*do_each)(void **, struct kevent *)) 1231 { 1232 int rc; 1233 struct timespec ts; 1234 ts.tv_sec = 0; 1235 ts.tv_nsec = 0; 1236 1237 struct sys_kevent_args ska = { 1238 kq, 1239 changelist, 1240 nchanges, 1241 eventlist, 1242 nevents, 1243 &ts, 1244 do_each 1245 }; 1246 1247 struct kevent_copyops k_ops = { 1248 &ska, 1249 kevent_copyout, 1250 kevent_copyin 1251 }; 1252 1253 if ((rc = kern_kevent(curthread, kq, nchanges, nevents, &k_ops, 1254 &ts))) 1255 goto kern_fail; 1256 1257 rc = curthread->td_retval[0]; 1258 return (rc); 1259 kern_fail: 1260 ff_os_errno(rc); 1261 return (-1); 1262 } 1263 1264 int 1265 ff_kevent(int kq, const struct kevent *changelist, int nchanges, 1266 struct kevent *eventlist, int nevents, const struct timespec *timeout) 1267 { 1268 return ff_kevent_do_each(kq, changelist, nchanges, eventlist, nevents, timeout, NULL); 1269 } 1270 1271 int 1272 ff_gettimeofday(struct timeval *tv, struct timezone *tz) 1273 { 1274 long nsec; 1275 ff_get_current_time(&(tv->tv_sec), &nsec); 1276 tv->tv_usec = nsec/1000; 1277 return 0; 1278 } 1279 1280 int 1281 ff_dup(int oldfd) 1282 { 1283 int rc; 1284 struct dup_args da = { 1285 .fd = oldfd, 1286 }; 1287 if ((rc = sys_dup(curthread, &da))) 1288 goto kern_fail; 1289 1290 rc = curthread->td_retval[0]; 1291 1292 return (rc); 1293 kern_fail: 1294 ff_os_errno(rc); 1295 return (-1); 1296 } 1297 1298 int 1299 ff_dup2(int oldfd, int newfd) 1300 { 1301 int rc; 1302 struct dup2_args da = { 1303 .from = oldfd, 1304 .to = newfd 1305 }; 1306 if ((rc = sys_dup2(curthread, &da))) 1307 goto kern_fail; 1308 1309 rc = curthread->td_retval[0]; 1310 1311 return (rc); 1312 kern_fail: 1313 ff_os_errno(rc); 1314 return (-1); 1315 } 1316 1317 int 1318 ff_route_ctl(enum FF_ROUTE_CTL req, enum FF_ROUTE_FLAG flag, 1319 struct linux_sockaddr *dst, struct linux_sockaddr *gw, 1320 struct linux_sockaddr *netmask) 1321 1322 { 1323 struct sockaddr_storage sa_gw, sa_dst, sa_nm; 1324 struct sockaddr *psa_gw, *psa_dst, *psa_nm; 1325 int rtreq, rtflag; 1326 int rc; 1327 struct rt_addrinfo info; 1328 struct rib_cmd_info rci; 1329 1330 switch (req) { 1331 case FF_ROUTE_ADD: 1332 rtreq = RTM_ADD; 1333 break; 1334 case FF_ROUTE_DEL: 1335 rtreq = RTM_DELETE; 1336 break; 1337 case FF_ROUTE_CHANGE: 1338 rtreq = RTM_CHANGE; 1339 break; 1340 default: 1341 rc = EINVAL; 1342 goto kern_fail; 1343 } 1344 1345 switch (flag) { 1346 case FF_RTF_HOST: 1347 rtflag = RTF_HOST; 1348 break; 1349 case FF_RTF_GATEWAY: 1350 rtflag = RTF_GATEWAY; 1351 break; 1352 default: 1353 rc = EINVAL; 1354 goto kern_fail; 1355 }; 1356 1357 bzero((caddr_t)&info, sizeof(info)); 1358 info.rti_flags = rtflag; 1359 1360 if (gw != NULL) { 1361 psa_gw = (struct sockaddr *)&sa_gw; 1362 linux2freebsd_sockaddr(gw, sizeof(*gw), psa_gw); 1363 info.rti_info[RTAX_GATEWAY] = psa_gw; 1364 } else { 1365 psa_gw = NULL; 1366 } 1367 1368 if (dst != NULL) { 1369 psa_dst = (struct sockaddr *)&sa_dst; 1370 linux2freebsd_sockaddr(dst, sizeof(*dst), psa_dst); 1371 info.rti_info[RTAX_DST] = psa_dst; 1372 } else { 1373 psa_dst = NULL; 1374 } 1375 1376 if (netmask != NULL) { 1377 psa_nm = (struct sockaddr *)&sa_nm; 1378 linux2freebsd_sockaddr(netmask, sizeof(*netmask), psa_nm); 1379 info.rti_info[RTAX_NETMASK] = psa_nm; 1380 } else { 1381 psa_nm = NULL; 1382 } 1383 1384 rc = rib_action(RT_DEFAULT_FIB, rtreq, &info, &rci); 1385 1386 if (rc != 0) 1387 goto kern_fail; 1388 1389 return (rc); 1390 1391 kern_fail: 1392 ff_os_errno(rc); 1393 return (-1); 1394 } 1395