Taming USB / IP

    The task of connecting a USB device to a remote PC via a local network regularly arises. Under the cat is the story of my searches in this direction, and the path to a turnkey solution based on the open-source USB / IP project with a description of the obstacles carefully set by various people on this path, as well as ways to get around them.

    Part One, Historical


    If the machine is virtual - all this is easy. The USB forwarding functionality from the host to the virtual machine appeared in VMWare 4.1. But in my case, the security key, recognized as WIBU-KEY, had to be connected to different machines at different times, and not just virtual ones.
    The first round of search back in 2009 led me to a piece of iron called TrendNet TU2-NU4
    Pros:

    • sometimes it even works

    Minuses:

    • does not always work. Suppose the Guardant Stealth II security key does not start through it, swearing with the error “the device cannot be started”.
    • Management software (read - mounting and unmounting USB devices) is miserable to the extreme. Command line keys, automation - no, not heard. Everything is just hands. Nightmare.
    • the control software is looking for the hardware itself in the network by broadcasting, so this only works within the same broadcast segment of the network. It is impossible to specify the IP address of the piece of iron by hand. A piece of iron in another subnet? Then you have a problem.
    • developers have scored on the device, sending bug reports is useless.

    The second round happened in times not so distant, and led me to the topic of the article - USB / IP project . It attracts with openness, especially since the guys from ReactOS signed them a driver for Windows, so now even on x64 everything works without any crutches like a test mode. For which many thanks to the ReactOS team! Everything sounds beautiful, try to feel it, is it really so? Unfortunately, the project itself is also abandoned, and you can’t count on support - but where ours didn’t disappear, the source is, we’ll figure it out!

    Part Two, Server-Linux


    A USB / IP server that shares USB devices over a network can only be raised on a Linux-based OS. Well, Linux, so Linux, install on a Debian 8 virtual machine in a minimal configuration, standard hand movement:

    sudo apt-get update
    sudo apt-get upgrade
    sudo apt-get install usbip

    Established. Further, the Internet tells you to load the usbip module, but - hello, first rake. There is no such module. And this is because most manuals on the network relate to the older branch 0.1.x, and at least 0.2.0 the usbip modules have different names.

    Therefore:

    sudo modprobe usbip-core
    sudo modprobe usbip-host
    sudo lsmod | grep usbip

    Well, add such lines to / etc / modules to load them automatically at system startup:

    usbip-core
    usbip-host
    vhci-hcd

    Launch the usbip server:
    sudo usbipd -D

    Further, the global mind tells us that complete with usbip are scripts that allow us to manage the server - show which device it will share on the network, see the status, and so on. Another garden tool awaits us here - these scripts in the 0.2.x branch are, again, renamed. You can get a list of commands using

    sudo usbip

    After 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 in the arena: the Bus ID that will give us lsusb (it would seem the most obvious way) is not suitable for her! The fact is that gadgets like USB hubs are ignored by usbip. 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 my specific USB key as an example. Your name of a piece of iron and pair VID: PID 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: complete

    Hooray, 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 autostart of the usbip daemon to /etc/rc.local

    usbipd -D

    Part Three, Client and Confusing


    I tried to connect the shared device over the network to a machine running Debian immediately on the same server, and everything connected perfectly:

    sudo usbip attach --remote=localhost --busid=1-1

    We pass to Windows. In my case, it was Windows Server 2008R2 Standard Edition. The official manual asks you to install the driver first. The procedure is beautifully described in the readme attached to the windows client, we do everything as it is written, everything turns out. On XP it also works without any difficulties.

    After unpacking the client, we try to mount our key:

    C:\Program Files\USB-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 device

    Oh oh. Something went wrong. We use the skill of Google. There are fragmentary references that there is something wrong with the constants, in the server side the developers changed the protocol version when switching to version 0.2.0, but they forgot to do this in the client under Win. The proposed solution is to change the constant in the source 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, the constant is declared as a double word. Let's look in the file 0x00000106, replacing it with 0x00000111. Do not forget the reverse byte order. The result is two matches, patch:

    [usbip.exe]
    00000CBC: 06 11
    00000E0A: 06 11

    III ... yes!

    C:\Program Files\USB-IP>usbip -a %server-ip% 1-1
    new usb device attached to usbvbus port 1

    This could finish the presentation, but the music did not play for long. Rebooting the server, I found that the device is not mounted on the client!

    C:\Program Files\USB-IP>usbip -a %server-ip% 1-1
    usbip err: usbip_windows.c: 829 (attach_device) cannot find device

    And that’s it. Even the all-knowing Google could not answer this. And at the same time, the command to display the devices available on the server shows correctly - here you can mount the key. I try to mount from under Linux - it works! And if now try from under Windows? Oh horror - it works!

    Rake last: something in the server code is not added there. When sharing a device, it does not read from it the number of USB descriptors. And when mounting the device from under Linux, this field is filled. Unfortunately, I am familiar with Linux development at the level of “make && make install”. Therefore, the problem was solved with a rather dirty hack - by adding to /etc/rc.local

    usbip attach --remote=localhost --busid=1-1
    usbip port
    usbip detach --port=00

    The final part


    After some ordeal, it works. The desired is received, now the key can be mounted on any PC (and unmount, of course, too), including - outside the broadcast network segment. If you want, you can do this using a shell script. What is nice - the pleasure is absolutely free.
    I hope that my experience will help the hawkers to get around the rake that is imprinted on my forehead. Thanks for attention!

    Also popular now: