/* Simple client to get the exported devices * from a USBIP server. * * If it doesn't return something... run it again... * It has been noted that sometimes the USBIP server doesn't responde */ #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { char *host; char port[5] = "3240"; struct addrinfo *res, *res0; int save_errno, error; int s; if (argc == 2) { host = argv[1]; if ((error = getaddrinfo(host, port, NULL, &res0))) errx(1, "getaddrinfo: %s", gai_strerror(error)); for (res = res0; res; res = res->ai_next) { if (s = socket(PF_INET, SOCK_STREAM, 0) < 0) continue; if (connect(s, res->ai_addr, res->ai_addrlen) == 0) break; save_errno = errno; close(s); errno = save_errno; s = -1; } freeaddrinfo(res0); if (s > -1) { struct usbip_op_req_devlist exported_list_req; struct usbip_op_rep_devlist exported_list_rep; int r; exported_list_req.version = htons(USBIP_VERSION); exported_list_req.command = htons(USBIP_OP_REQ_DEVLIST); exported_list_req.status = 0; /* XXX - This probably should do a write_exact and read_exact like * the test USBIP client does. */ r = write(s,&exported_list_req,sizeof(struct usbip_op_req_devlist)); printf("WRITE R; %d\n",r); r = read(s,&exported_list_rep,sizeof(struct usbip_op_rep_devlist)); printf("READ R: %d\n", r); if (r > 0) { uint32_t rep_status; uint32_t rep_numdevices; rep_status = ntohl(exported_list_rep.status); rep_numdevices = ntohl(exported_list_rep.numdevices); printf("\tVERSION: %04x\n",ntohs(exported_list_rep.version)); printf("\tREPLYCODE: %04x\n",ntohs(exported_list_rep.replycode)); printf("\tSTATUS: %08x\n",rep_status); printf("\tNUMDEVICES: %08x\n",rep_numdevices); /* XXX - sometimes junk to returned.... but that is likely due to not using * an exact read and write... */ if (rep_status == 0) { if (rep_numdevices > 0) { struct usbip_exported_devices dev; for(int n = rep_numdevices; n > 0; n--) { memset(&dev,0,sizeof(dev)); /* XXX - same here... should probably do read_exact */ r = read(s,&dev,sizeof(dev)); if (r > 0) { printf("\t\tPATH: %s\n",dev.path); printf("\t\tBUSID: %s\n",dev.busid); printf("\t\tBUSNUM: %08x\n",ntohl(dev.busnum)); printf("\t\tDEVNUM: %08x\n",ntohl(dev.devnum)); printf("\t\tSPEED: %08x\n",ntohl(dev.speed)); printf("\t\tIDVENDOR: %04x\n",ntohs(dev.idVendor)); printf("\t\tPRODUCT: %04x\n",ntohs(dev.idProduct)); printf("\t\tBCDDEVICE: %04x\n",ntohs(dev.bcdDevice)); printf("\t\tBDEVICECLASS: %02x\n",dev.bDeviceClass); printf("\t\tBDEVICESUBCLASS: %02x\n",dev.bDeviceSubClass); printf("\t\tBDEVICEPROTOCOL: %02x\n",dev.bDeviceProtocol); printf("\t\tBCONFIGURATIONVALUE: %02x\n",dev.bConfigurationValue); printf("\t\tBNUMCONFIGURATIONS: %02x\n",dev.bNumConfigurations); printf("\t\tBNUMINTERFACES: %02x\n\n",dev.bNumInterfaces); } else { printf("Zero read for r on dev: %d\n",n); break; } } } else { printf("Zero devices exported\n"); } } else { printf("Error: Status of request was; %d\n", rep_status); } } close(s); } else { errx(1, "getaddrinfo: %d %s", errno, gai_strerror(error)); } } else { printf("get_export_list IP\n"); exit(1); } }