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 status = ST_OK;
 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                status = usbip_export_device(edev, sockfd);
 137                if (status < 0)
 138                        status = ST_NA;
 139        } else {
 140                info("requested device not found: %s", req.busid);
 141                status = ST_NODEV;
 142        }
 143
 144        rc = usbip_net_send_op_common(sockfd, OP_REP_IMPORT, status);
 145        if (rc < 0) {
 146                dbg("usbip_net_send_op_common failed: %#0x", OP_REP_IMPORT);
 147                return -1;
 148        }
 149
 150        if (status) {
 151                dbg("import request busid %s: failed", req.busid);
 152                return -1;
 153        }
 154
 155        memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev));
 156        usbip_net_pack_usb_device(1, &pdu_udev);
 157
 158        rc = usbip_net_send(sockfd, &pdu_udev, sizeof(pdu_udev));
 159        if (rc < 0) {
 160                dbg("usbip_net_send failed: devinfo");
 161                return -1;
 162        }
 163
 164        dbg("import request busid %s: complete", req.busid);
 165
 166        return 0;
 167}
 168
 169static int send_reply_devlist(int connfd)
 170{
 171        struct usbip_exported_device *edev;
 172        struct usbip_usb_device pdu_udev;
 173        struct usbip_usb_interface pdu_uinf;
 174        struct op_devlist_reply reply;
 175        struct list_head *j;
 176        int rc, i;
 177
 178        /*
 179         * Exclude devices that are already exported to a client from
 180         * the exportable device list to avoid:
 181         *      - import requests for devices that are exported only to
 182         *        fail the request.
 183         *      - revealing devices that are imported by a client to
 184         *        another client.
 185         */
 186
 187        reply.ndev = 0;
 188        /* number of exported devices */
 189        list_for_each(j, &driver->edev_list) {
 190                edev = list_entry(j, struct usbip_exported_device, node);
 191                if (edev->status != SDEV_ST_USED)
 192                        reply.ndev += 1;
 193        }
 194        info("exportable devices: %d", reply.ndev);
 195
 196        rc = usbip_net_send_op_common(connfd, OP_REP_DEVLIST, ST_OK);
 197        if (rc < 0) {
 198                dbg("usbip_net_send_op_common failed: %#0x", OP_REP_DEVLIST);
 199                return -1;
 200        }
 201        PACK_OP_DEVLIST_REPLY(1, &reply);
 202
 203        rc = usbip_net_send(connfd, &reply, sizeof(reply));
 204        if (rc < 0) {
 205                dbg("usbip_net_send failed: %#0x", OP_REP_DEVLIST);
 206                return -1;
 207        }
 208
 209        list_for_each(j, &driver->edev_list) {
 210                edev = list_entry(j, struct usbip_exported_device, node);
 211                if (edev->status == SDEV_ST_USED)
 212                        continue;
 213
 214                dump_usb_device(&edev->udev);
 215                memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev));
 216                usbip_net_pack_usb_device(1, &pdu_udev);
 217
 218                rc = usbip_net_send(connfd, &pdu_udev, sizeof(pdu_udev));
 219                if (rc < 0) {
 220                        dbg("usbip_net_send failed: pdu_udev");
 221                        return -1;
 222                }
 223
 224                for (i = 0; i < edev->udev.bNumInterfaces; i++) {
 225                        dump_usb_interface(&edev->uinf[i]);
 226                        memcpy(&pdu_uinf, &edev->uinf[i], sizeof(pdu_uinf));
 227                        usbip_net_pack_usb_interface(1, &pdu_uinf);
 228
 229                        rc = usbip_net_send(connfd, &pdu_uinf,
 230                                        sizeof(pdu_uinf));
 231                        if (rc < 0) {
 232                                err("usbip_net_send failed: pdu_uinf");
 233                                return -1;
 234                        }
 235                }
 236        }
 237
 238        return 0;
 239}
 240
 241static int recv_request_devlist(int connfd)
 242{
 243        struct op_devlist_request req;
 244        int rc;
 245
 246        memset(&req, 0, sizeof(req));
 247
 248        rc = usbip_net_recv(connfd, &req, sizeof(req));
 249        if (rc < 0) {
 250                dbg("usbip_net_recv failed: devlist request");
 251                return -1;
 252        }
 253
 254        rc = send_reply_devlist(connfd);
 255        if (rc < 0) {
 256                dbg("send_reply_devlist failed");
 257                return -1;
 258        }
 259
 260        return 0;
 261}
 262
 263static int recv_pdu(int connfd)
 264{
 265        uint16_t code = OP_UNSPEC;
 266        int ret;
 267        int status;
 268
 269        ret = usbip_net_recv_op_common(connfd, &code, &status);
 270        if (ret < 0) {
 271                dbg("could not receive opcode: %#0x", code);
 272                return -1;
 273        }
 274
 275        ret = usbip_refresh_device_list(driver);
 276        if (ret < 0) {
 277                dbg("could not refresh device list: %d", ret);
 278                return -1;
 279        }
 280
 281        info("received request: %#0x(%d)", code, connfd);
 282        switch (code) {
 283        case OP_REQ_DEVLIST:
 284                ret = recv_request_devlist(connfd);
 285                break;
 286        case OP_REQ_IMPORT:
 287                ret = recv_request_import(connfd);
 288                break;
 289        case OP_REQ_DEVINFO:
 290        case OP_REQ_CRYPKEY:
 291        default:
 292                err("received an unknown opcode: %#0x", code);
 293                ret = -1;
 294        }
 295
 296        if (ret == 0)
 297                info("request %#0x(%d): complete", code, connfd);
 298        else
 299                info("request %#0x(%d): failed", code, connfd);
 300
 301        return ret;
 302}
 303
 304#ifdef HAVE_LIBWRAP
 305static int tcpd_auth(int connfd)
 306{
 307        struct request_info request;
 308        int rc;
 309
 310        request_init(&request, RQ_DAEMON, PROGNAME, RQ_FILE, connfd, 0);
 311        fromhost(&request);
 312        rc = hosts_access(&request);
 313        if (rc == 0)
 314                return -1;
 315
 316        return 0;
 317}
 318#endif
 319
 320static int do_accept(int listenfd)
 321{
 322        int connfd;
 323        struct sockaddr_storage ss;
 324        socklen_t len = sizeof(ss);
 325        char host[NI_MAXHOST], port[NI_MAXSERV];
 326        int rc;
 327
 328        memset(&ss, 0, sizeof(ss));
 329
 330        connfd = accept(listenfd, (struct sockaddr *)&ss, &len);
 331        if (connfd < 0) {
 332                err("failed to accept connection");
 333                return -1;
 334        }
 335
 336        rc = getnameinfo((struct sockaddr *)&ss, len, host, sizeof(host),
 337                         port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
 338        if (rc)
 339                err("getnameinfo: %s", gai_strerror(rc));
 340
 341#ifdef HAVE_LIBWRAP
 342        rc = tcpd_auth(connfd);
 343        if (rc < 0) {
 344                info("denied access from %s", host);
 345                close(connfd);
 346                return -1;
 347        }
 348#endif
 349        info("connection from %s:%s", host, port);
 350
 351        return connfd;
 352}
 353
 354int process_request(int listenfd)
 355{
 356        pid_t childpid;
 357        int connfd;
 358
 359        connfd = do_accept(listenfd);
 360        if (connfd < 0)
 361                return -1;
 362        childpid = fork();
 363        if (childpid == 0) {
 364                close(listenfd);
 365                recv_pdu(connfd);
 366                exit(0);
 367        }
 368        close(connfd);
 369        return 0;
 370}
 371
 372static void addrinfo_to_text(struct addrinfo *ai, char buf[],
 373                             const size_t buf_size)
 374{
 375        char hbuf[NI_MAXHOST];
 376        char sbuf[NI_MAXSERV];
 377        int rc;
 378
 379        buf[0] = '\0';
 380
 381        rc = getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf),
 382                         sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV);
 383        if (rc)
 384                err("getnameinfo: %s", gai_strerror(rc));
 385
 386        snprintf(buf, buf_size, "%s:%s", hbuf, sbuf);
 387}
 388
 389static int listen_all_addrinfo(struct addrinfo *ai_head, int sockfdlist[],
 390                             int maxsockfd)
 391{
 392        struct addrinfo *ai;
 393        int ret, nsockfd = 0;
 394        const size_t ai_buf_size = NI_MAXHOST + NI_MAXSERV + 2;
 395        char ai_buf[ai_buf_size];
 396
 397        for (ai = ai_head; ai && nsockfd < maxsockfd; ai = ai->ai_next) {
 398                int sock;
 399
 400                addrinfo_to_text(ai, ai_buf, ai_buf_size);
 401                dbg("opening %s", ai_buf);
 402                sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
 403                if (sock < 0) {
 404                        err("socket: %s: %d (%s)",
 405                            ai_buf, errno, strerror(errno));
 406                        continue;
 407                }
 408
 409                usbip_net_set_reuseaddr(sock);
 410                usbip_net_set_nodelay(sock);
 411                /* We use seperate sockets for IPv4 and IPv6
 412                 * (see do_standalone_mode()) */
 413                usbip_net_set_v6only(sock);
 414
 415                ret = bind(sock, ai->ai_addr, ai->ai_addrlen);
 416                if (ret < 0) {
 417                        err("bind: %s: %d (%s)",
 418                            ai_buf, errno, strerror(errno));
 419                        close(sock);
 420                        continue;
 421                }
 422
 423                ret = listen(sock, SOMAXCONN);
 424                if (ret < 0) {
 425                        err("listen: %s: %d (%s)",
 426                            ai_buf, errno, strerror(errno));
 427                        close(sock);
 428                        continue;
 429                }
 430
 431                info("listening on %s", ai_buf);
 432                sockfdlist[nsockfd++] = sock;
 433        }
 434
 435        return nsockfd;
 436}
 437
 438static struct addrinfo *do_getaddrinfo(char *host, int ai_family)
 439{
 440        struct addrinfo hints, *ai_head;
 441        int rc;
 442
 443        memset(&hints, 0, sizeof(hints));
 444        hints.ai_family   = ai_family;
 445        hints.ai_socktype = SOCK_STREAM;
 446        hints.ai_flags    = AI_PASSIVE;
 447
 448        rc = getaddrinfo(host, usbip_port_string, &hints, &ai_head);
 449        if (rc) {
 450                err("failed to get a network address %s: %s", usbip_port_string,
 451                    gai_strerror(rc));
 452                return NULL;
 453        }
 454
 455        return ai_head;
 456}
 457
 458static void signal_handler(int i)
 459{
 460        dbg("received '%s' signal", strsignal(i));
 461}
 462
 463static void set_signal(void)
 464{
 465        struct sigaction act;
 466
 467        memset(&act, 0, sizeof(act));
 468        act.sa_handler = signal_handler;
 469        sigemptyset(&act.sa_mask);
 470        sigaction(SIGTERM, &act, NULL);
 471        sigaction(SIGINT, &act, NULL);
 472        act.sa_handler = SIG_IGN;
 473        sigaction(SIGCHLD, &act, NULL);
 474}
 475
 476static const char *pid_file;
 477
 478static void write_pid_file(void)
 479{
 480        if (pid_file) {
 481                dbg("creating pid file %s", pid_file);
 482                FILE *fp;
 483
 484                fp = fopen(pid_file, "w");
 485                if (!fp) {
 486                        err("pid_file: %s: %d (%s)",
 487                            pid_file, errno, strerror(errno));
 488                        return;
 489                }
 490                fprintf(fp, "%d\n", getpid());
 491                fclose(fp);
 492        }
 493}
 494
 495static void remove_pid_file(void)
 496{
 497        if (pid_file) {
 498                dbg("removing pid file %s", pid_file);
 499                unlink(pid_file);
 500        }
 501}
 502
 503static int do_standalone_mode(int daemonize, int ipv4, int ipv6)
 504{
 505        struct addrinfo *ai_head;
 506        int sockfdlist[MAXSOCKFD];
 507        int nsockfd, family;
 508        int i, terminate;
 509        struct pollfd *fds;
 510        struct timespec timeout;
 511        sigset_t sigmask;
 512
 513        if (usbip_driver_open(driver))
 514                return -1;
 515
 516        if (daemonize) {
 517                if (daemon(0, 0) < 0) {
 518                        err("daemonizing failed: %s", strerror(errno));
 519                        usbip_driver_close(driver);
 520                        return -1;
 521                }
 522                umask(0);
 523                usbip_use_syslog = 1;
 524        }
 525        set_signal();
 526        write_pid_file();
 527
 528        info("starting " PROGNAME " (%s)", usbip_version_string);
 529
 530        /*
 531         * To suppress warnings on systems with bindv6only disabled
 532         * (default), we use seperate sockets for IPv6 and IPv4 and set
 533         * IPV6_V6ONLY on the IPv6 sockets.
 534         */
 535        if (ipv4 && ipv6)
 536                family = AF_UNSPEC;
 537        else if (ipv4)
 538                family = AF_INET;
 539        else
 540                family = AF_INET6;
 541
 542        ai_head = do_getaddrinfo(NULL, family);
 543        if (!ai_head) {
 544                usbip_driver_close(driver);
 545                return -1;
 546        }
 547        nsockfd = listen_all_addrinfo(ai_head, sockfdlist,
 548                sizeof(sockfdlist) / sizeof(*sockfdlist));
 549        freeaddrinfo(ai_head);
 550        if (nsockfd <= 0) {
 551                err("failed to open a listening socket");
 552                usbip_driver_close(driver);
 553                return -1;
 554        }
 555
 556        dbg("listening on %d address%s", nsockfd, (nsockfd == 1) ? "" : "es");
 557
 558        fds = calloc(nsockfd, sizeof(struct pollfd));
 559        for (i = 0; i < nsockfd; i++) {
 560                fds[i].fd = sockfdlist[i];
 561                fds[i].events = POLLIN;
 562        }
 563        timeout.tv_sec = MAIN_LOOP_TIMEOUT;
 564        timeout.tv_nsec = 0;
 565
 566        sigfillset(&sigmask);
 567        sigdelset(&sigmask, SIGTERM);
 568        sigdelset(&sigmask, SIGINT);
 569
 570        terminate = 0;
 571        while (!terminate) {
 572                int r;
 573
 574                r = ppoll(fds, nsockfd, &timeout, &sigmask);
 575                if (r < 0) {
 576                        dbg("%s", strerror(errno));
 577                        terminate = 1;
 578                } else if (r) {
 579                        for (i = 0; i < nsockfd; i++) {
 580                                if (fds[i].revents & POLLIN) {
 581                                        dbg("read event on fd[%d]=%d",
 582                                            i, sockfdlist[i]);
 583                                        process_request(sockfdlist[i]);
 584                                }
 585                        }
 586                } else {
 587                        dbg("heartbeat timeout on ppoll()");
 588                }
 589        }
 590
 591        info("shutting down " PROGNAME);
 592        free(fds);
 593        usbip_driver_close(driver);
 594
 595        return 0;
 596}
 597
 598int main(int argc, char *argv[])
 599{
 600        static const struct option longopts[] = {
 601                { "ipv4",     no_argument,       NULL, '4' },
 602                { "ipv6",     no_argument,       NULL, '6' },
 603                { "daemon",   no_argument,       NULL, 'D' },
 604                { "daemon",   no_argument,       NULL, 'D' },
 605                { "debug",    no_argument,       NULL, 'd' },
 606                { "device",   no_argument,       NULL, 'e' },
 607                { "pid",      optional_argument, NULL, 'P' },
 608                { "tcp-port", required_argument, NULL, 't' },
 609                { "help",     no_argument,       NULL, 'h' },
 610                { "version",  no_argument,       NULL, 'v' },
 611                { NULL,       0,                 NULL,  0  }
 612        };
 613
 614        enum {
 615                cmd_standalone_mode = 1,
 616                cmd_help,
 617                cmd_version
 618        } cmd;
 619
 620        int daemonize = 0;
 621        int ipv4 = 0, ipv6 = 0;
 622        int opt, rc = -1;
 623
 624        pid_file = NULL;
 625
 626        usbip_use_stderr = 1;
 627        usbip_use_syslog = 0;
 628
 629        if (geteuid() != 0)
 630                err("not running as root?");
 631
 632        cmd = cmd_standalone_mode;
 633        driver = &host_driver;
 634        for (;;) {
 635                opt = getopt_long(argc, argv, "46DdeP::t:hv", longopts, NULL);
 636
 637                if (opt == -1)
 638                        break;
 639
 640                switch (opt) {
 641                case '4':
 642                        ipv4 = 1;
 643                        break;
 644                case '6':
 645                        ipv6 = 1;
 646                        break;
 647                case 'D':
 648                        daemonize = 1;
 649                        break;
 650                case 'd':
 651                        usbip_use_debug = 1;
 652                        break;
 653                case 'h':
 654                        cmd = cmd_help;
 655                        break;
 656                case 'P':
 657                        pid_file = optarg ? optarg : DEFAULT_PID_FILE;
 658                        break;
 659                case 't':
 660                        usbip_setup_port_number(optarg);
 661                        break;
 662                case 'v':
 663                        cmd = cmd_version;
 664                        break;
 665                case 'e':
 666                        driver = &device_driver;
 667                        break;
 668                case '?':
 669                        usbipd_help();
 670                default:
 671                        goto err_out;
 672                }
 673        }
 674
 675        if (!ipv4 && !ipv6)
 676                ipv4 = ipv6 = 1;
 677
 678        switch (cmd) {
 679        case cmd_standalone_mode:
 680                rc = do_standalone_mode(daemonize, ipv4, ipv6);
 681                remove_pid_file();
 682                break;
 683        case cmd_version:
 684                printf(PROGNAME " (%s)\n", usbip_version_string);
 685                rc = 0;
 686                break;
 687        case cmd_help:
 688                usbipd_help();
 689                rc = 0;
 690                break;
 691        default:
 692                usbipd_help();
 693                goto err_out;
 694        }
 695
 696err_out:
 697        return (rc > -1 ? EXIT_SUCCESS : EXIT_FAILURE);
 698}
 699