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