The task of connecting a USB device to a remote PC via a local network regularly arises. Under the cut, the history of my searches in this direction is set out, and the path to a ready-made solution based on an open-source project with a description of the obstacles carefully set by various people on this path, as well as ways to bypass them.
Part One, Historical
If the machine is virtual - all this is easy. The functionality of USB forwarding from a host to a virtual machine appeared in VMWare 4.1. But in my case, the security key, recognizable as WIBU-KEY, had to be connected at different times to different machines, and not only virtual ones.
The first round of search in the distant 2009 led me to a piece of iron called
Pros:
- sometimes it even works
Cons:
- does not always work. Suppose the Guardant Stealth II protection key does not start through it, swearing with the error “device cannot be started”.
- Management software (read - mounting and unmounting USB devices) is pathetic to the extreme. Command line switches, automation - no, have not heard. Everything is just by hand. Nightmare.
- the control software searches for the piece of iron itself in the network by broadcasting, so this only works within one broadcast network segment. You cannot specify the IP address of the piece of iron by hand. A piece of iron in other subnet? Then you have a problem.
- developers scored on the device, it is useless to send bug reports.
The second round happened in times not so distant, and led me to the topic of the article - . Attracts with openness, especially since the guys from signed the driver for them Windows, so now everything works even on x64 without any workarounds like test mode. Huge thanks to the ReactOS team for that! It all sounds great, let's try it out to see if it's actually true. Unfortunately, the project itself has been abandoned, and support is hard to come by—but we're still working on it, the source code is there, we'll figure it out!
Part two, server-linux
A USB/IP server that shares USB devices over a network can only be set up in Linux-based OS. Well, Linux is Linux, so let's install it on a virtual machine. Debian 8 in minimum configuration, standard hand movement:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install usbipSettled. Further, the Internet suggests that you would need to download the usbip module, but - hello, the first rake. There is no such module. And all because most of the manuals on the network refer to the older branch 0.1.x, and in the latest 0.2.0 the usbip modules have different names.
Therefore:
sudo modprobe usbip-core
sudo modprobe usbip-host
sudo lsmod | grep usbipWell, let's add the following lines to /etc/modules to load them automatically at system startup:
usbip-core
usbip-host
vhci-hcdLet's start the usbip server:
sudo usbipd -DFurther, the universal mind tells us that usbip comes with scripts that allow us to manage the server - show which device it will share over the network, see the status, and so on. Here another garden tool awaits us - these scripts in the 0.2.x branch, again, have been renamed. You can get a list of commands with
sudo usbipAfter reading the description of the commands, it becomes clear that in order to share the required USB device, usbip wants to know its Bus ID. Dear viewers, rake number three is in the arena: the Bus ID that will give us lsusb (it would seem the most obvious way) - it does not suit her! The fact is that usbip ignores hardware like USB hubs. Therefore, we will use the built-in command:
user@usb-server:~$ sudo usbip list -l
- busid 1-1 (064f:0bd7)
WIBU-Systems AG : BOX/U (064f:0bd7)Note: hereinafter in the listings I will describe everything using the example of my specific USB key. Your hardware name and VID:PID pair can and will differ. Mine is called Wibu-Systems AG: BOX/U, VID 064F, PID 0BD7.
Now we can share our device:
user@usb-server:~$ sudo usbip bind --busid=1-1
usbip: info: bind device on busid 1-1: completeCheers, comrades!
user@usb-server:~$ sudo usbip list -r localhost
Exportable USB devices
======================
- localhost
1-1: WIBU-Systems AG : BOX/U (064f:0bd7)
: /sys/devices/pci0000:00/0000:00:11.0/0000:02:00.0/usb1/1-1
: Vendor Specific Class / unknown subclass / unknown protocol (ff/00/ff)Three cheers, comrades! The server shared the piece of iron over the network, and we can connect it! It remains only to add the autostart of the usbip daemon to /etc/rc.local
usbipd -DPart three, client-side and confusing
Connect the shared device to the machine running the network Debian I tried it right away on the same server, and everything connected perfectly:
sudo usbip attach --remote=localhost --busid=1-1Go to WindowsIn my case it was Windows Server 2008R2 Standard Edition. The official manual asks to install the driver first. The procedure is well described in the readme included with the Windows client; we followed the instructions and everything worked fine. It also works without any issues on XP.
After unpacking the client, we try to mount our key:
C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
usbip err: usbip_network.c: 121 (usbip_recv_op_common) recv op_common, -1
usbip err: usbip_windows.c: 756 (query_interface0) recv op_common
usbip err: usbip_windows.c: 829 (attach_device) cannot find deviceOh oh. Something went wrong. We use the skill of Google. There are fragmentary mentions that something is wrong with the constants; in the server part, the developers changed the protocol version when switching to version 0.2.0, but they forgot to do this in the Win client. The proposed solution is to change the constant in the source code and rebuild the client.
But I really don’t want to download Visual Studio for the sake of this procedure. But I have a good old Hiew. In the source code, the constant is declared as a double word. Let's look in the file for 0x00000106, replacing it with 0x00000111. Remember, byte order is reversed. The result is two matches, patch:
[usbip.exe]
00000CBC: 06 11
00000E0A: 06 11Eeeee... yes!
C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
new usb device attached to usbvbus port 1This could have ended the presentation, but the music did not play for long. After rebooting the server, I found that the device on the client is not mounted!
C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
usbip err: usbip_windows.c: 829 (attach_device) cannot find deviceAnd that's it. Even the all-knowing Google couldn't answer this. Meanwhile, the command to display devices available on the server shows it quite correctly—here it is, the key, you can mount it. I'm trying to mount it from under Linux - It works! And if we try it from under Windows? Oh, horror – it works!
The last problem: something is missing in the server code. When sharing a device, it doesn't read the number of USB descriptors from it. And when mounting a device from under Linux, this field is filled in. Unfortunately, with the development under Linux I'm familiar with "make && make install." So the problem was solved with a rather dirty hack—adding it to /etc/rc.local
usbip attach --remote=localhost --busid=1-1
usbip port
usbip detach --port=00Part final
After some fiddling, it works. The desired result has been obtained, now the key can be mounted to any PC (and unmounted, of course, too), including those outside the broadcast network segment. If you want, you can do it using a shell script. What is nice - the pleasure is absolutely free.
I hope that my experience will help habrazhiteli to get around the rake that imprinted on my forehead. Thank you for your attention!
Source: habr.com
