root/tools/usb/usbip/src/usbipd.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. usbipd_help
  2. recv_request_import
  3. send_reply_devlist
  4. recv_request_devlist
  5. recv_pdu
  6. tcpd_auth
  7. do_accept
  8. process_request
  9. addrinfo_to_text
  10. listen_all_addrinfo
  11. do_getaddrinfo
  12. signal_handler
  13. set_signal
  14. write_pid_file
  15. remove_pid_file
  16. do_standalone_mode
  17. main

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

/* [<][>][^][v][top][bottom][index][help] */