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                ret = bind(sock, ai->ai_addr, ai->ai_addrlen);
 402                if (ret < 0) {
 403                        err("bind: %s: %d (%s)",
 404                            ai_buf, errno, strerror(errno));
 405                        close(sock);
 406                        continue;
 407                }
 408
 409                ret = listen(sock, SOMAXCONN);
 410                if (ret < 0) {
 411                        err("listen: %s: %d (%s)",
 412                            ai_buf, errno, strerror(errno));
 413                        close(sock);
 414                        continue;
 415                }
 416
 417                info("listening on %s", ai_buf);
 418                sockfdlist[nsockfd++] = sock;
 419        }
 420
 421        return nsockfd;
 422}
 423
 424static struct addrinfo *do_getaddrinfo(char *host, int ai_family)
 425{
 426        struct addrinfo hints, *ai_head;
 427        int rc;
 428
 429        memset(&hints, 0, sizeof(hints));
 430        hints.ai_family   = ai_family;
 431        hints.ai_socktype = SOCK_STREAM;
 432        hints.ai_flags    = AI_PASSIVE;
 433
 434        rc = getaddrinfo(host, usbip_port_string, &hints, &ai_head);
 435        if (rc) {
 436                err("failed to get a network address %s: %s", usbip_port_string,
 437                    gai_strerror(rc));
 438                return NULL;
 439        }
 440
 441        return ai_head;
 442}
 443
 444static void signal_handler(int i)
 445{
 446        dbg("received '%s' signal", strsignal(i));
 447}
 448
 449static void set_signal(void)
 450{
 451        struct sigaction act;
 452
 453        memset(&act, 0, sizeof(act));
 454        act.sa_handler = signal_handler;
 455        sigemptyset(&act.sa_mask);
 456        sigaction(SIGTERM, &act, NULL);
 457        sigaction(SIGINT, &act, NULL);
 458        act.sa_handler = SIG_IGN;
 459        sigaction(SIGCHLD, &act, NULL);
 460}
 461
 462static const char *pid_file;
 463
 464static void write_pid_file(void)
 465{
 466        if (pid_file) {
 467                dbg("creating pid file %s", pid_file);
 468                FILE *fp;
 469
 470                fp = fopen(pid_file, "w");
 471                if (!fp) {
 472                        err("pid_file: %s: %d (%s)",
 473                            pid_file, errno, strerror(errno));
 474                        return;
 475                }
 476                fprintf(fp, "%d\n", getpid());
 477                fclose(fp);
 478        }
 479}
 480
 481static void remove_pid_file(void)
 482{
 483        if (pid_file) {
 484                dbg("removing pid file %s", pid_file);
 485                unlink(pid_file);
 486        }
 487}
 488
 489static int do_standalone_mode(int daemonize, int ipv4, int ipv6)
 490{
 491        struct addrinfo *ai_head;
 492        int sockfdlist[MAXSOCKFD];
 493        int nsockfd, family;
 494        int i, terminate;
 495        struct pollfd *fds;
 496        struct timespec timeout;
 497        sigset_t sigmask;
 498
 499        if (usbip_driver_open(driver))
 500                return -1;
 501
 502        if (daemonize) {
 503                if (daemon(0, 0) < 0) {
 504                        err("daemonizing failed: %s", strerror(errno));
 505                        usbip_driver_close(driver);
 506                        return -1;
 507                }
 508                umask(0);
 509                usbip_use_syslog = 1;
 510        }
 511        set_signal();
 512        write_pid_file();
 513
 514        info("starting " PROGNAME " (%s)", usbip_version_string);
 515
 516        /*
 517         * To suppress warnings on systems with bindv6only disabled
 518         * (default), we use seperate sockets for IPv6 and IPv4 and set
 519         * IPV6_V6ONLY on the IPv6 sockets.
 520         */
 521        if (ipv4 && ipv6)
 522                family = AF_UNSPEC;
 523        else if (ipv4)
 524                family = AF_INET;
 525        else
 526                family = AF_INET6;
 527
 528        ai_head = do_getaddrinfo(NULL, family);
 529        if (!ai_head) {
 530                usbip_driver_close(driver);
 531                return -1;
 532        }
 533        nsockfd = listen_all_addrinfo(ai_head, sockfdlist,
 534                sizeof(sockfdlist) / sizeof(*sockfdlist));
 535        freeaddrinfo(ai_head);
 536        if (nsockfd <= 0) {
 537                err("failed to open a listening socket");
 538                usbip_driver_close(driver);
 539                return -1;
 540        }
 541
 542        dbg("listening on %d address%s", nsockfd, (nsockfd == 1) ? "" : "es");
 543
 544        fds = calloc(nsockfd, sizeof(struct pollfd));
 545        for (i = 0; i < nsockfd; i++) {
 546                fds[i].fd = sockfdlist[i];
 547                fds[i].events = POLLIN;
 548        }
 549        timeout.tv_sec = MAIN_LOOP_TIMEOUT;
 550        timeout.tv_nsec = 0;
 551
 552        sigfillset(&sigmask);
 553        sigdelset(&sigmask, SIGTERM);
 554        sigdelset(&sigmask, SIGINT);
 555
 556        terminate = 0;
 557        while (!terminate) {
 558                int r;
 559
 560                r = ppoll(fds, nsockfd, &timeout, &sigmask);
 561                if (r < 0) {
 562                        dbg("%s", strerror(errno));
 563                        terminate = 1;
 564                } else if (r) {
 565                        for (i = 0; i < nsockfd; i++) {
 566                                if (fds[i].revents & POLLIN) {
 567                                        dbg("read event on fd[%d]=%d",
 568                                            i, sockfdlist[i]);
 569                                        process_request(sockfdlist[i]);
 570                                }
 571                        }
 572                } else {
 573                        dbg("heartbeat timeout on ppoll()");
 574                }
 575        }
 576
 577        info("shutting down " PROGNAME);
 578        free(fds);
 579        usbip_driver_close(driver);
 580
 581        return 0;
 582}
 583
 584int main(int argc, char *argv[])
 585{
 586        static const struct option longopts[] = {
 587                { "ipv4",     no_argument,       NULL, '4' },
 588                { "ipv6",     no_argument,       NULL, '6' },
 589                { "daemon",   no_argument,       NULL, 'D' },
 590                { "daemon",   no_argument,       NULL, 'D' },
 591                { "debug",    no_argument,       NULL, 'd' },
 592                { "device",   no_argument,       NULL, 'e' },
 593                { "pid",      optional_argument, NULL, 'P' },
 594                { "tcp-port", required_argument, NULL, 't' },
 595                { "help",     no_argument,       NULL, 'h' },
 596                { "version",  no_argument,       NULL, 'v' },
 597                { NULL,       0,                 NULL,  0  }
 598        };
 599
 600        enum {
 601                cmd_standalone_mode = 1,
 602                cmd_help,
 603                cmd_version
 604        } cmd;
 605
 606        int daemonize = 0;
 607        int ipv4 = 0, ipv6 = 0;
 608        int opt, rc = -1;
 609
 610        pid_file = NULL;
 611
 612        usbip_use_stderr = 1;
 613        usbip_use_syslog = 0;
 614
 615        if (geteuid() != 0)
 616                err("not running as root?");
 617
 618        cmd = cmd_standalone_mode;
 619        driver = &host_driver;
 620        for (;;) {
 621                opt = getopt_long(argc, argv, "46DdeP::t:hv", longopts, NULL);
 622
 623                if (opt == -1)
 624                        break;
 625
 626                switch (opt) {
 627                case '4':
 628                        ipv4 = 1;
 629                        break;
 630                case '6':
 631                        ipv6 = 1;
 632                        break;
 633                case 'D':
 634                        daemonize = 1;
 635                        break;
 636                case 'd':
 637                        usbip_use_debug = 1;
 638                        break;
 639                case 'h':
 640                        cmd = cmd_help;
 641                        break;
 642                case 'P':
 643                        pid_file = optarg ? optarg : DEFAULT_PID_FILE;
 644                        break;
 645                case 't':
 646                        usbip_setup_port_number(optarg);
 647                        break;
 648                case 'v':
 649                        cmd = cmd_version;
 650                        break;
 651                case 'e':
 652                        driver = &device_driver;
 653                        break;
 654                case '?':
 655                        usbipd_help();
 656                default:
 657                        goto err_out;
 658                }
 659        }
 660
 661        if (!ipv4 && !ipv6)
 662                ipv4 = ipv6 = 1;
 663
 664        switch (cmd) {
 665        case cmd_standalone_mode:
 666                rc = do_standalone_mode(daemonize, ipv4, ipv6);
 667                remove_pid_file();
 668                break;
 669        case cmd_version:
 670                printf(PROGNAME " (%s)\n", usbip_version_string);
 671                rc = 0;
 672                break;
 673        case cmd_help:
 674                usbipd_help();
 675                rc = 0;
 676                break;
 677        default:
 678                usbipd_help();
 679                goto err_out;
 680        }
 681
 682err_out:
 683        return (rc > -1 ? EXIT_SUCCESS : EXIT_FAILURE);
 684}
 685