staticconstchar usbipd_help_string[] = "usage: usbipd [options]\n" "\n" " -4, --ipv4\n" " Bind to IPv4. Default is both.\n" "\n" " -6, --ipv6\n" " Bind to IPv6. Default is both.\n" "\n" " -e, --device\n" " Run in device mode.\n" " Rather than drive an attached device, create\n" " a virtual UDC to bind gadgets to.\n" "\n" " -D, --daemon\n" " Run as a daemon process.\n" "\n" " -d, --debug\n" " Print debugging information.\n" "\n" " -PFILE, --pid FILE\n" " Write process id to FILE.\n" " If no FILE specified, use " DEFAULT_PID_FILE "\n" "\n" " -tPORT, --tcp-port PORT\n" " Listen on TCP/IP port PORT.\n" "\n" " -h, --help\n" " Print this help.\n" "\n" " -v, --version\n" " Show version.\n";
/* * Exclude devices that are already exported to a client from * the exportable device list to avoid: * - import requests for devices that are exported only to * fail the request. * - revealing devices that are imported by a client to * another client.
*/
reply.ndev = 0; /* number of exported devices */
list_for_each(j, &driver->edev_list) {
edev = list_entry(j, struct usbip_exported_device, node); if (edev->status != SDEV_ST_USED)
reply.ndev += 1;
}
info("exportable devices: %d", reply.ndev);
for (i = 0; i < edev->udev.bNumInterfaces; i++) {
dump_usb_interface(&edev->uinf[i]);
memcpy(&pdu_uinf, &edev->uinf[i], sizeof(pdu_uinf));
usbip_net_pack_usb_interface(1, &pdu_uinf);
staticint recv_pdu(int connfd)
{
uint16_t code = OP_UNSPEC; int ret; int status;
ret = usbip_net_recv_op_common(connfd, &code, &status); if (ret < 0) {
dbg("could not receive opcode: %#0x", code); return -1;
}
ret = usbip_refresh_device_list(driver); if (ret < 0) {
dbg("could not refresh device list: %d", ret); return -1;
}
info("received request: %#0x(%d)", code, connfd); switch (code) { case OP_REQ_DEVLIST:
ret = recv_request_devlist(connfd); break; case OP_REQ_IMPORT:
ret = recv_request_import(connfd); break; case OP_REQ_DEVINFO: case OP_REQ_CRYPKEY: default:
err("received an unknown opcode: %#0x", code);
ret = -1;
}
usbip_net_set_reuseaddr(sock);
usbip_net_set_nodelay(sock); /* We use seperate sockets for IPv4 and IPv6
* (see do_standalone_mode()) */
usbip_net_set_v6only(sock);
ret = bind(sock, ai->ai_addr, ai->ai_addrlen); if (ret < 0) {
err("bind: %s: %d (%s)",
ai_buf, errno, strerror(errno));
close(sock); continue;
}
ret = listen(sock, SOMAXCONN); if (ret < 0) {
err("listen: %s: %d (%s)",
ai_buf, errno, strerror(errno));
close(sock); continue;
}
info("listening on %s", ai_buf);
sockfdlist[nsockfd++] = sock;
}
return nsockfd;
}
staticstruct addrinfo *do_getaddrinfo(char *host, int ai_family)
{ struct addrinfo hints, *ai_head; int rc;
staticint do_standalone_mode(int daemonize, int ipv4, int ipv6)
{ struct addrinfo *ai_head; int sockfdlist[MAXSOCKFD]; int nsockfd, family; int i, terminate; struct pollfd *fds; struct timespec timeout;
sigset_t sigmask;
/* * To suppress warnings on systems with bindv6only disabled * (default), we use seperate sockets for IPv6 and IPv4 and set * IPV6_V6ONLY on the IPv6 sockets.
*/ if (ipv4 && ipv6)
family = AF_UNSPEC; elseif (ipv4)
family = AF_INET; else
family = AF_INET6;
ai_head = do_getaddrinfo(NULL, family); if (!ai_head) {
usbip_driver_close(driver); return -1;
}
nsockfd = listen_all_addrinfo(ai_head, sockfdlist, sizeof(sockfdlist) / sizeof(*sockfdlist));
freeaddrinfo(ai_head); if (nsockfd <= 0) {
err("failed to open a listening socket");
usbip_driver_close(driver); return -1;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.