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