linux/tools/usb/usbip/src/usbipd.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
   3 *               2005-2007 Takahiro Hirofuchi
   4 * Copyright (C) 2015-2016 Samsung Electronics
   5 *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
   6 *               Krzysztof Opasiak <k.opasiak@samsung.com>
   7 *
   8 * This program is free software: you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation, either version 2 of the License, or
  11 * (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20 */
  21
  22#ifdef HAVE_CONFIG_H
  23#include "../config.h"
  24#endif
  25
  26#define _GNU_SOURCE
  27#include <errno.h>
  28#include <unistd.h>
  29#include <netdb.h>
  30#include <string.h>
  31#include <stdlib.h>
  32#include <sys/types.h>
  33#include <sys/stat.h>
  34#include <arpa/inet.h>
  35#include <sys/socket.h>
  36#include <netinet/in.h>
  37
  38#ifdef HAVE_LIBWRAP
  39#include <tcpd.h>
  40#endif
  41
  42#include <getopt.h>
  43#include <signal.h>
  44#include <poll.h>
  45
  46#include "usbip_host_driver.h"
  47#include "usbip_host_common.h"
  48#include "usbip_device_driver.h"
  49#include "usbip_common.h"
  50#include "usbip_network.h"
  51#include "list.h"
  52
  53#undef  PROGNAME
  54#define PROGNAME "usbipd"
  55#define MAXSOCKFD 20
  56
  57#define MAIN_LOOP_TIMEOUT 10
  58
  59#define DEFAULT_PID_FILE "/var/run/" PROGNAME ".pid"
  60
  61static const char usbip_version_string[] = PACKAGE_STRING;
  62
  63static const char usbipd_help_string[] =
  64        "usage: usbipd [options]\n"
  65        "\n"
  66        "       -4, --ipv4\n"
  67        "               Bind to IPv4. Default is both.\n"
  68        "\n"
  69        "       -6, --ipv6\n"
  70        "               Bind to IPv6. Default is both.\n"
  71        "\n"
  72        "       -e, --device\n"
  73        "               Run in device mode.\n"
  74        "               Rather than drive an attached device, create\n"
  75        "               a virtual UDC to bind gadgets to.\n"
  76        "\n"
  77        "       -D, --daemon\n"
  78        "               Run as a daemon process.\n"
  79        "\n"
  80        "       -d, --debug\n"
  81        "               Print debugging information.\n"
  82        "\n"
  83        "       -PFILE, --pid FILE\n"
  84        "               Write process id to FILE.\n"
  85        "               If no FILE specified, use " DEFAULT_PID_FILE "\n"
  86        "\n"
  87        "       -tPORT, --tcp-port PORT\n"
  88        "               Listen on TCP/IP port PORT.\n"
  89        "\n"
  90        "       -h, --help\n"
  91        "               Print this help.\n"
  92        "\n"
  93        "       -v, --version\n"
  94        "               Show version.\n";
  95
  96static struct usbip_host_driver *driver;
  97
  98static void usbipd_help(void)
  99{
 100        printf("%s\n", usbipd_help_string);
 101}
 102
 103static int recv_request_import(int sockfd)
 104{
 105        struct op_import_request req;
 106        struct usbip_exported_device *edev;
 107        struct usbip_usb_device pdu_udev;
 108        struct list_head *i;
 109        int found = 0;
 110        int error = 0;
 111        int rc;
 112
 113        memset(&req, 0, sizeof(req));
 114
 115        rc = usbip_net_recv(sockfd, &req, sizeof(req));
 116        if (rc < 0) {
 117                dbg("usbip_net_recv failed: import request");
 118                return -1;
 119        }
 120        PACK_OP_IMPORT_REQUEST(0, &req);
 121
 122        list_for_each(i, &driver->edev_list) {
 123                edev = list_entry(i, struct usbip_exported_device, node);
 124                if (!strncmp(req.busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) {
 125                        info("found requested device: %s", req.busid);
 126                        found = 1;
 127                        break;
 128                }
 129        }
 130
 131        if (found) {
 132                /* should set TCP_NODELAY for usbip */
 133                usbip_net_set_nodelay(sockfd);
 134
 135                /* export device needs a TCP/IP socket descriptor */
 136                rc = usbip_export_device(edev, sockfd);
 137                if (rc < 0)
 138                        error = 1;
 139        } else {
 140                info("requested device not found: %s", req.busid);
 141                error = 1;
 142        }
 143
 144        rc = usbip_net_send_op_common(sockfd, OP_REP_IMPORT,
 145                                      (!error ? ST_OK : ST_NA));
 146        if (rc < 0) {
 147                dbg("usbip_net_send_op_common failed: %#0x", OP_REP_IMPORT);
 148                return -1;
 149        }
 150
 151        if (error) {
 152                dbg("import request busid %s: failed", req.busid);
 153                return -1;
 154        }
 155
 156        memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev));
 157        usbip_net_pack_usb_device(1, &pdu_udev);
 158
 159        rc = usbip_net_send(sockfd, &pdu_udev, sizeof(pdu_udev));
 160        if (rc < 0) {
 161                dbg("usbip_net_send failed: devinfo");
 162                return -1;
 163        }
 164
 165        dbg("import request busid %s: complete", req.busid);
 166
 167        return 0;
 168}
 169
 170static int send_reply_devlist(int connfd)
 171{
 172        struct usbip_exported_device *edev;
 173        struct usbip_usb_device pdu_udev;
 174        struct usbip_usb_interface pdu_uinf;
 175        struct op_devlist_reply reply;
 176        struct list_head *j;
 177        int rc, i;
 178
 179        reply.ndev = 0;
 180        /* number of exported devices */
 181        list_for_each(j, &driver->edev_list) {
 182                reply.ndev += 1;
 183        }
 184        info("exportable devices: %d", reply.ndev);
 185
 186        rc = usbip_net_send_op_common(connfd, OP_REP_DEVLIST, ST_OK);
 187        if (rc < 0) {
 188                dbg("usbip_net_send_op_common failed: %#0x", OP_REP_DEVLIST);
 189                return -1;
 190        }
 191        PACK_OP_DEVLIST_REPLY(1, &reply);
 192
 193        rc = usbip_net_send(connfd, &reply, sizeof(reply));
 194        if (rc < 0) {
 195                dbg("usbip_net_send failed: %#0x", OP_REP_DEVLIST);
 196                return -1;
 197        }
 198
 199        list_for_each(j, &driver->edev_list) {
 200                edev = list_entry(j, struct usbip_exported_device, node);
 201                dump_usb_device(&edev->udev);
 202                memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev));
 203                usbip_net_pack_usb_device(1, &pdu_udev);
 204
 205                rc = usbip_net_send(connfd, &pdu_udev, sizeof(pdu_udev));
 206                if (rc < 0) {
 207                        dbg("usbip_net_send failed: pdu_udev");
 208                        return -1;
 209                }
 210
 211                for (i = 0; i < edev->udev.bNumInterfaces; i++) {
 212                        dump_usb_interface(&edev->uinf[i]);
 213                        memcpy(&pdu_uinf, &edev->uinf[i], sizeof(pdu_uinf));
 214                        usbip_net_pack_usb_interface(1, &pdu_uinf);
 215
 216                        rc = usbip_net_send(connfd, &pdu_uinf,
 217                                        sizeof(pdu_uinf));
 218                        if (rc < 0) {
 219                                err("usbip_net_send failed: pdu_uinf");
 220                                return -1;
 221                        }
 222                }
 223        }
 224
 225        return 0;
 226}
 227
 228static int recv_request_devlist(int connfd)
 229{
 230        struct op_devlist_request req;
 231        int rc;
 232
 233        memset(&req, 0, sizeof(req));
 234
 235        rc = usbip_net_recv(connfd, &req, sizeof(req));
 236        if (rc < 0) {
 237                dbg("usbip_net_recv failed: devlist request");
 238                return -1;
 239        }
 240
 241        rc = send_reply_devlist(connfd);
 242        if (rc < 0) {
 243                dbg("send_reply_devlist failed");
 244                return -1;
 245        }
 246
 247        return 0;
 248}
 249
 250static int recv_pdu(int connfd)
 251{
 252        uint16_t code = OP_UNSPEC;
 253        int ret;
 254
 255        ret = usbip_net_recv_op_common(connfd, &code);
 256        if (ret < 0) {
 257                dbg("could not receive opcode: %#0x", code);
 258                return -1;
 259        }
 260
 261        ret = usbip_refresh_device_list(driver);
 262        if (ret < 0) {
 263                dbg("could not refresh device list: %d", ret);
 264                return -1;
 265        }
 266
 267        info("received request: %#0x(%d)", code, connfd);
 268        switch (code) {
 269        case OP_REQ_DEVLIST:
 270                ret = recv_request_devlist(connfd);
 271                break;
 272        case OP_REQ_IMPORT:
 273                ret = recv_request_import(connfd);
 274                break;
 275        case OP_REQ_DEVINFO:
 276        case OP_REQ_CRYPKEY:
 277        default:
 278                err("received an unknown opcode: %#0x", code);
 279                ret = -1;
 280        }
 281
 282        if (ret == 0)
 283                info("request %#0x(%d): complete", code, connfd);
 284        else
 285                info("request %#0x(%d): failed", code, connfd);
 286
 287        return ret;
 288}
 289
 290#ifdef HAVE_LIBWRAP
 291static int tcpd_auth(int connfd)
 292{
 293        struct request_info request;
 294        int rc;
 295
 296        request_init(&request, RQ_DAEMON, PROGNAME, RQ_FILE, connfd, 0);
 297        fromhost(&request);
 298        rc = hosts_access(&request);
 299        if (rc == 0)
 300                return -1;
 301
 302        return 0;
 303}
 304#endif
 305
 306static int do_accept(int listenfd)
 307{
 308        int connfd;
 309        struct sockaddr_storage ss;
 310        socklen_t len = sizeof(ss);
 311        char host[NI_MAXHOST], port[NI_MAXSERV];
 312        int rc;
 313
 314        memset(&ss, 0, sizeof(ss));
 315
 316        connfd = accept(listenfd, (struct sockaddr *)&ss, &len);
 317        if (connfd < 0) {
 318                err("failed to accept connection");
 319                return -1;
 320        }
 321
 322        rc = getnameinfo((struct sockaddr *)&ss, len, host, sizeof(host),
 323                         port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
 324        if (rc)
 325                err("getnameinfo: %s", gai_strerror(rc));
 326
 327#ifdef HAVE_LIBWRAP
 328        rc = tcpd_auth(connfd);
 329        if (rc < 0) {
 330                info("denied access from %s", host);
 331                close(connfd);
 332                return -1;
 333        }
 334#endif
 335        info("connection from %s:%s", host, port);
 336
 337        return connfd;
 338}
 339
 340int process_request(int listenfd)
 341{
 342        pid_t childpid;
 343        int connfd;
 344
 345        connfd = do_accept(listenfd);
 346        if (connfd < 0)
 347                return -1;
 348        childpid = fork();
 349        if (childpid == 0) {
 350                close(listenfd);
 351                recv_pdu(connfd);
 352                exit(0);
 353        }
 354        close(connfd);
 355        return 0;
 356}
 357
 358static void addrinfo_to_text(struct addrinfo *ai, char buf[],
 359                             const size_t buf_size)
 360{
 361        char hbuf[NI_MAXHOST];
 362        char sbuf[NI_MAXSERV];
 363        int rc;
 364
 365        buf[0] = '\0';
 366
 367        rc = getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf),
 368                         sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV);
 369        if (rc)
 370                err("getnameinfo: %s", gai_strerror(rc));
 371
 372        snprintf(buf, buf_size, "%s:%s", hbuf, sbuf);
 373}
 374
 375static int listen_all_addrinfo(struct addrinfo *ai_head, int sockfdlist[],
 376                             int maxsockfd)
 377{
 378        struct addrinfo *ai;
 379        int ret, nsockfd = 0;
 380        const size_t ai_buf_size = NI_MAXHOST + NI_MAXSERV + 2;
 381        char ai_buf[ai_buf_size];
 382
 383        for (ai = ai_head; ai && nsockfd < maxsockfd; ai = ai->ai_next) {
 384                int sock;
 385
 386                addrinfo_to_text(ai, ai_buf, ai_buf_size);
 387                dbg("opening %s", ai_buf);
 388                sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
 389                if (sock < 0) {
 390                        err("socket: %s: %d (%s)",
 391                            ai_buf, errno, strerror(errno));
 392                        continue;
 393                }
 394
 395                usbip_net_set_reuseaddr(sock);
 396                usbip_net_set_nodelay(sock);
 397                /* We use seperate sockets for IPv4 and IPv6
 398                 * (see do_standalone_mode()) */
 399                usbip_net_set_v6only(sock);
 400
 401                if (sock >= FD_SETSIZE) {
 402                        err("FD_SETSIZE: %s: sock=%d, max=%d",
 403                            ai_buf, sock, FD_SETSIZE);
 404                        close(sock);
 405                        continue;
 406                }
 407
 408                ret = bind(sock, ai->ai_addr, ai->ai_addrlen);
 409                if (ret < 0) {
 410                        err("bind: %s: %d (%s)",
 411                            ai_buf, errno, strerror(errno));
 412                        close(sock);
 413                        continue;
 414                }
 415
 416                ret = listen(sock, SOMAXCONN);
 417                if (ret < 0) {
 418                        err("listen: %s: %d (%s)",
 419                            ai_buf, errno, strerror(errno));
 420                        close(sock);
 421                        continue;
 422                }
 423
 424                info("listening on %s", ai_buf);
 425                sockfdlist[nsockfd++] = sock;
 426        }
 427
 428        return nsockfd;
 429}
 430
 431static struct addrinfo *do_getaddrinfo(char *host, int ai_family)
 432{
 433        struct addrinfo hints, *ai_head;
 434        int rc;
 435
 436        memset(&hints, 0, sizeof(hints));
 437        hints.ai_family   = ai_family;
 438        hints.ai_socktype = SOCK_STREAM;
 439        hints.ai_flags    = AI_PASSIVE;
 440
 441        rc = getaddrinfo(host, usbip_port_string, &hints, &ai_head);
 442        if (rc) {
 443                err("failed to get a network address %s: %s", usbip_port_string,
 444                    gai_strerror(rc));
 445                return NULL;
 446        }
 447
 448        return ai_head;
 449}
 450
 451static void signal_handler(int i)
 452{
 453        dbg("received '%s' signal", strsignal(i));
 454}
 455
 456static void set_signal(void)
 457{
 458        struct sigaction act;
 459
 460        memset(&act, 0, sizeof(act));
 461        act.sa_handler = signal_handler;
 462        sigemptyset(&act.sa_mask);
 463        sigaction(SIGTERM, &act, NULL);
 464        sigaction(SIGINT, &act, NULL);
 465        act.sa_handler = SIG_IGN;
 466        sigaction(SIGCLD, &act, NULL);
 467}
 468
 469static const char *pid_file;
 470
 471static void write_pid_file(void)
 472{
 473        if (pid_file) {
 474                dbg("creating pid file %s", pid_file);
 475                FILE *fp;
 476
 477                fp = fopen(pid_file, "w");
 478                if (!fp) {
 479                        err("pid_file: %s: %d (%s)",
 480                            pid_file, errno, strerror(errno));
 481                        return;
 482                }
 483                fprintf(fp, "%d\n", getpid());
 484                fclose(fp);
 485        }
 486}
 487
 488static void remove_pid_file(void)
 489{
 490        if (pid_file) {
 491                dbg("removing pid file %s", pid_file);
 492                unlink(pid_file);
 493        }
 494}
 495
 496static int do_standalone_mode(int daemonize, int ipv4, int ipv6)
 497{
 498        struct addrinfo *ai_head;
 499        int sockfdlist[MAXSOCKFD];
 500        int nsockfd, family;
 501        int i, terminate;
 502        struct pollfd *fds;
 503        struct timespec timeout;
 504        sigset_t sigmask;
 505
 506        if (usbip_driver_open(driver))
 507                return -1;
 508
 509        if (daemonize) {
 510                if (daemon(0, 0) < 0) {
 511                        err("daemonizing failed: %s", strerror(errno));
 512                        usbip_driver_close(driver);
 513                        return -1;
 514                }
 515                umask(0);
 516                usbip_use_syslog = 1;
 517        }
 518        set_signal();
 519        write_pid_file();
 520
 521        info("starting " PROGNAME " (%s)", usbip_version_string);
 522
 523        /*
 524         * To suppress warnings on systems with bindv6only disabled
 525         * (default), we use seperate sockets for IPv6 and IPv4 and set
 526         * IPV6_V6ONLY on the IPv6 sockets.
 527         */
 528        if (ipv4 && ipv6)
 529                family = AF_UNSPEC;
 530        else if (ipv4)
 531                family = AF_INET;
 532        else
 533                family = AF_INET6;
 534
 535        ai_head = do_getaddrinfo(NULL, family);
 536        if (!ai_head) {
 537                usbip_driver_close(driver);
 538                return -1;
 539        }
 540        nsockfd = listen_all_addrinfo(ai_head, sockfdlist,
 541                sizeof(sockfdlist) / sizeof(*sockfdlist));
 542        freeaddrinfo(ai_head);
 543        if (nsockfd <= 0) {
 544                err("failed to open a listening socket");
 545                usbip_driver_close(driver);
 546                return -1;
 547        }
 548
 549        dbg("listening on %d address%s", nsockfd, (nsockfd == 1) ? "" : "es");
 550
 551        fds = calloc(nsockfd, sizeof(struct pollfd));
 552        for (i = 0; i < nsockfd; i++) {
 553                fds[i].fd = sockfdlist[i];
 554                fds[i].events = POLLIN;
 555        }
 556        timeout.tv_sec = MAIN_LOOP_TIMEOUT;
 557        timeout.tv_nsec = 0;
 558
 559        sigfillset(&sigmask);
 560        sigdelset(&sigmask, SIGTERM);
 561        sigdelset(&sigmask, SIGINT);
 562
 563        terminate = 0;
 564        while (!terminate) {
 565                int r;
 566
 567                r = ppoll(fds, nsockfd, &timeout, &sigmask);
 568                if (r < 0) {
 569                        dbg("%s", strerror(errno));
 570                        terminate = 1;
 571                } else if (r) {
 572                        for (i = 0; i < nsockfd; i++) {
 573                                if (fds[i].revents & POLLIN) {
 574                                        dbg("read event on fd[%d]=%d",
 575                                            i, sockfdlist[i]);
 576                                        process_request(sockfdlist[i]);
 577                                }
 578                        }
 579                } else {
 580                        dbg("heartbeat timeout on ppoll()");
 581                }
 582        }
 583
 584        info("shutting down " PROGNAME);
 585        free(fds);
 586        usbip_driver_close(driver);
 587
 588        return 0;
 589}
 590
 591int main(int argc, char *argv[])
 592{
 593        static const struct option longopts[] = {
 594                { "ipv4",     no_argument,       NULL, '4' },
 595                { "ipv6",     no_argument,       NULL, '6' },
 596                { "daemon",   no_argument,       NULL, 'D' },
 597                { "daemon",   no_argument,       NULL, 'D' },
 598                { "debug",    no_argument,       NULL, 'd' },
 599                { "device",   no_argument,       NULL, 'e' },
 600                { "pid",      optional_argument, NULL, 'P' },
 601                { "tcp-port", required_argument, NULL, 't' },
 602                { "help",     no_argument,       NULL, 'h' },
 603                { "version",  no_argument,       NULL, 'v' },
 604                { NULL,       0,                 NULL,  0  }
 605        };
 606
 607        enum {
 608                cmd_standalone_mode = 1,
 609                cmd_help,
 610                cmd_version
 611        } cmd;
 612
 613        int daemonize = 0;
 614        int ipv4 = 0, ipv6 = 0;
 615        int opt, rc = -1;
 616
 617        pid_file = NULL;
 618
 619        usbip_use_stderr = 1;
 620        usbip_use_syslog = 0;
 621
 622        if (geteuid() != 0)
 623                err("not running as root?");
 624
 625        cmd = cmd_standalone_mode;
 626        driver = &host_driver;
 627        for (;;) {
 628                opt = getopt_long(argc, argv, "46DdeP::t:hv", longopts, NULL);
 629
 630                if (opt == -1)
 631                        break;
 632
 633                switch (opt) {
 634                case '4':
 635                        ipv4 = 1;
 636                        break;
 637                case '6':
 638                        ipv6 = 1;
 639                        break;
 640                case 'D':
 641                        daemonize = 1;
 642                        break;
 643                case 'd':
 644                        usbip_use_debug = 1;
 645                        break;
 646                case 'h':
 647                        cmd = cmd_help;
 648                        break;
 649                case 'P':
 650                        pid_file = optarg ? optarg : DEFAULT_PID_FILE;
 651                        break;
 652                case 't':
 653                        usbip_setup_port_number(optarg);
 654                        break;
 655                case 'v':
 656                        cmd = cmd_version;
 657                        break;
 658                case 'e':
 659                        driver = &device_driver;
 660                        break;
 661                case '?':
 662                        usbipd_help();
 663                default:
 664                        goto err_out;
 665                }
 666        }
 667
 668        if (!ipv4 && !ipv6)
 669                ipv4 = ipv6 = 1;
 670
 671        switch (cmd) {
 672        case cmd_standalone_mode:
 673                rc = do_standalone_mode(daemonize, ipv4, ipv6);
 674                remove_pid_file();
 675                break;
 676        case cmd_version:
 677                printf(PROGNAME " (%s)\n", usbip_version_string);
 678                rc = 0;
 679                break;
 680        case cmd_help:
 681                usbipd_help();
 682                rc = 0;
 683                break;
 684        default:
 685                usbipd_help();
 686                goto err_out;
 687        }
 688
 689err_out:
 690        return (rc > -1 ? EXIT_SUCCESS : EXIT_FAILURE);
 691}
 692