Редовно се появява задача за свързване на USB устройство към отдалечен компютър през локална мрежа. Под кат можете да прочетете историята на моите търсения в тази насока и пътя към готовото решение, базирано на open-source проект. с описание на различните препятствия, установени внимателно от различни хора по този път, както и на начините за тяхното преодоляване.
Част първа, историческа
Ако машината е виртуална — всичко това не е сложно. Функционалността за пренос на USB от хоста към виртуалната машина се появи още в VMWare 4.1. Но в моя случай защитният ключ, идентифициран като WIBU-KEY, трябваше да бъде свързван към различни машини по различно време, и не само виртуални.
Първият етап на търсене, през далечната 2009 година, ме доведе до устройството, наречено
Плюсове:
- понякога дори работи
Недостатъци:
- не работи винаги. Да кажем, защитният ключ Guardant Stealth II не може да се разпознае чрез него, показвайки грешка "устройството не може да бъде стартирано".
- Софтуерът за управление (чети — монтиране и демонтиране на USB устройства) е крайно примитивен. Командни ключове, автоматизация — не, не сме чували. Всичко само на ръка. Кошмар.
- Управляващият софтуер търси самото устройство в мрежата с широковещателни запитвания, затова работи само в рамките на един broadcast сегмент на мрежата. Ръчно не може да се посочи IP адрес на устройството. Устройството в друга подсветка? Тогава имате проблем.
- Разработчиците са забравили устройството, изпращането на бъг репорти е безполезно.
Вторият етап настъпи в по-близки времена и ме доведе до темата на статията — . Привлича с отвореност, особено след като момчетата от подписаха драйвера им за Windows, така че сега дори на x64 всичко работи без всякакви трикове, като тестов режим. За което на екипа ReactOS огромно благодаря! Звучи всичко чудесно, да опитаме да разберем, така ли е наистина? За съжаление, самият проект също е забравен, и не е нужно да се разчита на поддръжка — но къде сме ние, имаме изходен код, разберем се!
Част втора, сървърно-линуксова
Сървърът USB/IP, който споделя USB устройства през мрежата, може да се установи само на базирани на Linux OS. Е, какво да правим, линукс така линукс, инсталираме на виртуалка Debian 8 в минимална конфигурация, стандартното движение ръка:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install usbipИнсталирано. Следващото, което интернет казва, е, че трябва да инсталирам модула usbip, но — здравейте, първите препятствия. Такъв модул няма. И всичко това, защото повечето ръководства в мрежата са относно по-старата версия 0.1.x, а в последната 0.2.0 модулите usbip имат различни наименования.
Следователно:
sudo modprobe usbip-core
sudo modprobe usbip-host
sudo lsmod | grep usbipСъщо така, добавяме в /etc/modules следните редове, за да се зареждат автоматично при стартиране на системата:
usbip-core
usbip-host
vhci-hcdСтартираме usbip сървъра:
sudo usbipd -DСлед това вселенският разум ни подсказва, че с usbip идват скриптове, които ни позволяват да управляваме сървъра — да покажем кое устройство ще споделяме в мрежата, да видим статуса и така нататък. Тук ни чака още един инструмент — тези скриптове в версия 0.2.x отново са преименувани. Списък с команди можем да получим с помощта на
sudo usbipЧетейки описанието на командите, става ясно, че за да споделим необходимото USB устройство, usbip иска да знае неговия Bus ID. Уважаеми зрители, на арената идват третите препятствия: този Bus ID, който ще получим lsusb (понеже, изглежда, е най-очевидният път) — не е подходящ! Факт е, че usbip игнорира устройства като USB хъбове. Затова, ще използваме вградената команда:
user@usb-server:~$ sudo usbip list -l
- busid 1-1 (064f:0bd7)
WIBU-Systems AG : BOX/U (064f:0bd7)Забележка: тук и занапред в листингите ще описвам всичко на примера на моя конкретен USB ключ. Имената на вашето устройство и номера VID:PID могат и ще се различават. Моето устройство се казва Wibu-Systems AG: BOX/U, VID 064F, PID 0BD7.
Сега можем да споделим нашето устройство:
user@usb-server:~$ sudo usbip bind --busid=1-1
usbip: info: bind device on busid 1-1: completeУра, другари!
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)Троен ура, другари! Сървърът е споделил устройството в мрежата и можем да го свързваме! Остава само да добавим автозапуска на демона usbip в /etc/rc.local
usbipd -DЧаст трета, клиентска и объркваща
Опитах да свържа споделеното устройство по мрежата към машина с Debian веднага на същия сървър и всичко успешно се свърза:
sudo usbip attach --remote=localhost --busid=1-1Преминаваме към Windows. В моя случай това беше Windows Server 2008R2 Standard Edition. Официалното ръководство изисква първо да инсталирате драйвера. Процедурата е прекрасно описана в приложеното към windows клиента readme, правим всичко както е написано, всичко работи. На XP също работи без никакви трудности.
Разопаковали клиента, опитваме се да монтираме нашия ключ:
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 deviceОй-ой. Нещо не е наред. Използваме уменията на Google. Срещат се откъслечни спомена, че нещо не е наред с константите; при преминаването на версия 0.2.0 в сървърната част, разработчиците променили версията на протокола, а в клиента за Windows забравили да направят същото. Предложеното решение — променете константата в изходния код и прерcompile клиента.
Но не ми се иска да свалям Visual Studio заради тази процедура. Затова имам стария добър Hiew. В изходния код константата е декларирана като двойно слово. Нека потърсим в файла 0x00000106, заменяйки на 0x00000111. Не забравяйте, редът на байтовете е обратно. Резултатът — две съвпадения, патчим:
[usbip.exe]
00000CBC: 06 11
00000E0A: 06 11Ииии… да!
C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
new usb device attached to usbvbus port 1На това можеше да се приключи изложението, но музиката не игра дълго. След перезареждане на сървъра, открих, че устройството на клиента не се монтира!
C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
usbip err: usbip_windows.c: 829 (attach_device) cannot find deviceИ всичко. На това не можа да ми отговори дори всезнаещият Google. Въпреки това, командата за показване на наличните устройства на сървъра показва напълно коректно — ето го, ключа, можете да го монтирате. Опитвам да монтирам от Linux — работи! А ако сега пробвам от Windows? О ужас — това работи!
Последни грабли: нещо не е написано в сървърния код. При споделяне на устройството, то не чете броя на USB описанията. При монтиране на устройството от Linux, това поле се запълва. За съжаление, познанията ми за разработка под Linux са на ниво „make && make install“. Затова проблемът е решен с помощта на доста мръсен хак — добавяне в /etc/rc.local
usbip attach --remote=localhost --busid=1-1
usbip port
usbip detach --port=00Заключителна част
След някои премеждия, това работи. Желаното е получено, сега ключът може да бъде монтиран на всяко РС (и разбира се, също така и демонтиран), включително и извън широковещателния сегмент на мрежата. Ако желаете, можете да го направите с помощта на скрипт от командната обвивка. Радвам се, че удоволствието е напълно безплатно.
Надявам се моят опит да помогне на хабражителите да избегнат тези капани, които останаха на челото ми. Благодаря за вниманието!
Източник: habr.com
