usbipd.c 14 KB

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