1 // SPDX-License-Identifier: GPL-2.0-or-later
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>
11 #include "../config.h"
20 #include <sys/types.h>
22 #include <arpa/inet.h>
23 #include <sys/socket.h>
24 #include <netinet/in.h>
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"
42 #define PROGNAME "usbipd"
45 #define MAIN_LOOP_TIMEOUT 10
47 #define DEFAULT_PID_FILE "/var/run/" PROGNAME ".pid"
49 static const char usbip_version_string
[] = PACKAGE_STRING
;
51 static const char usbipd_help_string
[] =
52 "usage: usbipd [options]\n"
55 " Bind to IPv4. Default is both.\n"
58 " Bind to IPv6. Default is both.\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"
66 " Run as a daemon process.\n"
69 " Print debugging information.\n"
71 " -PFILE, --pid FILE\n"
72 " Write process id to FILE.\n"
73 " If no FILE specified, use " DEFAULT_PID_FILE
"\n"
75 " -tPORT, --tcp-port PORT\n"
76 " Listen on TCP/IP port PORT.\n"
84 static struct usbip_host_driver
*driver
;
86 static void usbipd_help(void)
88 printf("%s\n", usbipd_help_string
);
91 static int recv_request_import(int sockfd
)
93 struct op_import_request req
;
94 struct usbip_exported_device
*edev
;
95 struct usbip_usb_device pdu_udev
;
101 memset(&req
, 0, sizeof(req
));
103 rc
= usbip_net_recv(sockfd
, &req
, sizeof(req
));
105 dbg("usbip_net_recv failed: import request");
108 PACK_OP_IMPORT_REQUEST(0, &req
);
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
);
120 /* should set TCP_NODELAY for usbip */
121 usbip_net_set_nodelay(sockfd
);
123 /* export device needs a TCP/IP socket descriptor */
124 status
= usbip_export_device(edev
, sockfd
);
128 info("requested device not found: %s", req
.busid
);
132 rc
= usbip_net_send_op_common(sockfd
, OP_REP_IMPORT
, status
);
134 dbg("usbip_net_send_op_common failed: %#0x", OP_REP_IMPORT
);
139 dbg("import request busid %s: failed", req
.busid
);
143 memcpy(&pdu_udev
, &edev
->udev
, sizeof(pdu_udev
));
144 usbip_net_pack_usb_device(1, &pdu_udev
);
146 rc
= usbip_net_send(sockfd
, &pdu_udev
, sizeof(pdu_udev
));
148 dbg("usbip_net_send failed: devinfo");
152 dbg("import request busid %s: complete", req
.busid
);
157 static int send_reply_devlist(int connfd
)
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
;
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
171 * - revealing devices that are imported by a client to
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
)
182 info("exportable devices: %d", reply
.ndev
);
184 rc
= usbip_net_send_op_common(connfd
, OP_REP_DEVLIST
, ST_OK
);
186 dbg("usbip_net_send_op_common failed: %#0x", OP_REP_DEVLIST
);
189 PACK_OP_DEVLIST_REPLY(1, &reply
);
191 rc
= usbip_net_send(connfd
, &reply
, sizeof(reply
));
193 dbg("usbip_net_send failed: %#0x", OP_REP_DEVLIST
);
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
)
202 dump_usb_device(&edev
->udev
);
203 memcpy(&pdu_udev
, &edev
->udev
, sizeof(pdu_udev
));
204 usbip_net_pack_usb_device(1, &pdu_udev
);
206 rc
= usbip_net_send(connfd
, &pdu_udev
, sizeof(pdu_udev
));
208 dbg("usbip_net_send failed: pdu_udev");
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
);
217 rc
= usbip_net_send(connfd
, &pdu_uinf
,
220 err("usbip_net_send failed: pdu_uinf");
229 static int recv_request_devlist(int connfd
)
231 struct op_devlist_request req
;
234 memset(&req
, 0, sizeof(req
));
236 rc
= usbip_net_recv(connfd
, &req
, sizeof(req
));
238 dbg("usbip_net_recv failed: devlist request");
242 rc
= send_reply_devlist(connfd
);
244 dbg("send_reply_devlist failed");
251 static int recv_pdu(int connfd
)
253 uint16_t code
= OP_UNSPEC
;
257 ret
= usbip_net_recv_op_common(connfd
, &code
, &status
);
259 dbg("could not receive opcode: %#0x", code
);
263 ret
= usbip_refresh_device_list(driver
);
265 dbg("could not refresh device list: %d", ret
);
269 info("received request: %#0x(%d)", code
, connfd
);
272 ret
= recv_request_devlist(connfd
);
275 ret
= recv_request_import(connfd
);
280 err("received an unknown opcode: %#0x", code
);
285 info("request %#0x(%d): complete", code
, connfd
);
287 info("request %#0x(%d): failed", code
, connfd
);
293 static int tcpd_auth(int connfd
)
295 struct request_info request
;
298 request_init(&request
, RQ_DAEMON
, PROGNAME
, RQ_FILE
, connfd
, 0);
300 rc
= hosts_access(&request
);
308 static int do_accept(int listenfd
)
311 struct sockaddr_storage ss
;
312 socklen_t len
= sizeof(ss
);
313 char host
[NI_MAXHOST
], port
[NI_MAXSERV
];
316 memset(&ss
, 0, sizeof(ss
));
318 connfd
= accept(listenfd
, (struct sockaddr
*)&ss
, &len
);
320 err("failed to accept connection");
324 rc
= getnameinfo((struct sockaddr
*)&ss
, len
, host
, sizeof(host
),
325 port
, sizeof(port
), NI_NUMERICHOST
| NI_NUMERICSERV
);
327 err("getnameinfo: %s", gai_strerror(rc
));
330 rc
= tcpd_auth(connfd
);
332 info("denied access from %s", host
);
337 info("connection from %s:%s", host
, port
);
342 int process_request(int listenfd
)
347 connfd
= do_accept(listenfd
);
360 static void addrinfo_to_text(struct addrinfo
*ai
, char buf
[],
361 const size_t buf_size
)
363 char hbuf
[NI_MAXHOST
];
364 char sbuf
[NI_MAXSERV
];
369 rc
= getnameinfo(ai
->ai_addr
, ai
->ai_addrlen
, hbuf
, sizeof(hbuf
),
370 sbuf
, sizeof(sbuf
), NI_NUMERICHOST
| NI_NUMERICSERV
);
372 err("getnameinfo: %s", gai_strerror(rc
));
374 snprintf(buf
, buf_size
, "%s:%s", hbuf
, sbuf
);
377 static int listen_all_addrinfo(struct addrinfo
*ai_head
, int sockfdlist
[],
381 int ret
, nsockfd
= 0;
382 const size_t ai_buf_size
= NI_MAXHOST
+ NI_MAXSERV
+ 2;
383 char ai_buf
[ai_buf_size
];
385 for (ai
= ai_head
; ai
&& nsockfd
< maxsockfd
; ai
= ai
->ai_next
) {
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
);
392 err("socket: %s: %d (%s)",
393 ai_buf
, errno
, strerror(errno
));
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
);
403 ret
= bind(sock
, ai
->ai_addr
, ai
->ai_addrlen
);
405 err("bind: %s: %d (%s)",
406 ai_buf
, errno
, strerror(errno
));
411 ret
= listen(sock
, SOMAXCONN
);
413 err("listen: %s: %d (%s)",
414 ai_buf
, errno
, strerror(errno
));
419 info("listening on %s", ai_buf
);
420 sockfdlist
[nsockfd
++] = sock
;
426 static struct addrinfo
*do_getaddrinfo(char *host
, int ai_family
)
428 struct addrinfo hints
, *ai_head
;
431 memset(&hints
, 0, sizeof(hints
));
432 hints
.ai_family
= ai_family
;
433 hints
.ai_socktype
= SOCK_STREAM
;
434 hints
.ai_flags
= AI_PASSIVE
;
436 rc
= getaddrinfo(host
, usbip_port_string
, &hints
, &ai_head
);
438 err("failed to get a network address %s: %s", usbip_port_string
,
446 static void signal_handler(int i
)
448 dbg("received '%s' signal", strsignal(i
));
451 static void set_signal(void)
453 struct sigaction act
;
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
);
464 static const char *pid_file
;
466 static void write_pid_file(void)
469 dbg("creating pid file %s", pid_file
);
472 fp
= fopen(pid_file
, "w");
474 err("pid_file: %s: %d (%s)",
475 pid_file
, errno
, strerror(errno
));
478 fprintf(fp
, "%d\n", getpid());
483 static void remove_pid_file(void)
486 dbg("removing pid file %s", pid_file
);
491 static int do_standalone_mode(int daemonize
, int ipv4
, int ipv6
)
493 struct addrinfo
*ai_head
;
494 int sockfdlist
[MAXSOCKFD
];
498 struct timespec timeout
;
501 if (usbip_driver_open(driver
))
505 if (daemon(0, 0) < 0) {
506 err("daemonizing failed: %s", strerror(errno
));
507 usbip_driver_close(driver
);
511 usbip_use_syslog
= 1;
516 info("starting " PROGNAME
" (%s)", usbip_version_string
);
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.
530 ai_head
= do_getaddrinfo(NULL
, family
);
532 usbip_driver_close(driver
);
535 nsockfd
= listen_all_addrinfo(ai_head
, sockfdlist
,
536 sizeof(sockfdlist
) / sizeof(*sockfdlist
));
537 freeaddrinfo(ai_head
);
539 err("failed to open a listening socket");
540 usbip_driver_close(driver
);
544 dbg("listening on %d address%s", nsockfd
, (nsockfd
== 1) ? "" : "es");
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
;
551 timeout
.tv_sec
= MAIN_LOOP_TIMEOUT
;
554 sigfillset(&sigmask
);
555 sigdelset(&sigmask
, SIGTERM
);
556 sigdelset(&sigmask
, SIGINT
);
562 r
= ppoll(fds
, nsockfd
, &timeout
, &sigmask
);
564 dbg("%s", strerror(errno
));
567 for (i
= 0; i
< nsockfd
; i
++) {
568 if (fds
[i
].revents
& POLLIN
) {
569 dbg("read event on fd[%d]=%d",
571 process_request(sockfdlist
[i
]);
575 dbg("heartbeat timeout on ppoll()");
579 info("shutting down " PROGNAME
);
581 usbip_driver_close(driver
);
586 int main(int argc
, char *argv
[])
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' },
603 cmd_standalone_mode
= 1,
609 int ipv4
= 0, ipv6
= 0;
614 usbip_use_stderr
= 1;
615 usbip_use_syslog
= 0;
618 err("not running as root?");
620 cmd
= cmd_standalone_mode
;
621 driver
= &host_driver
;
623 opt
= getopt_long(argc
, argv
, "46DdeP::t:hv", longopts
, NULL
);
645 pid_file
= optarg
? optarg
: DEFAULT_PID_FILE
;
648 usbip_setup_port_number(optarg
);
654 driver
= &device_driver
;
667 case cmd_standalone_mode
:
668 rc
= do_standalone_mode(daemonize
, ipv4
, ipv6
);
672 printf(PROGNAME
" (%s)\n", usbip_version_string
);
685 return (rc
> -1 ? EXIT_SUCCESS
: EXIT_FAILURE
);