Редовно възниква задачата за свързване на USB устройство към отдалечен ПК през локалната мрежа. Под заглавието е изложена историята на моите търсения в тази посока и пътят към готовото решение, основано на open-source проект. с описание на различни препятствия, поставени от различни хора по пътя, както и начини да ги заобиколим.
Част първа, историческа
Ако машината е виртуална — всичко това не е сложно. Функционалността за пробив на USB от хоста в виртуалната машина се появи още в VMWare 4.1. Но в моя случай защитният ключ, разпознаващ се като WIBU-KEY, трябваше да се свързва с различни машини, и не само виртуални.
Първият етап на търсенето ми в далечната 2009-а година ме доведе до устройство, наречено
Предимства:
- понякога дори работи
Минуси:
- не работи винаги. Например, защитният ключ Guardant Stealth II не се разпознава през него, и показва грешка „устройството не може да бъде стартирано“.
- Програмата за управление (чети — монтиране и демонтиране на USB устройства) е крайно бедна. Команди за управление от терминал, автоматизация — не, не са чували. Всичко само на ръка. Кошмар.
- управляващият софтуер търси самото устройство в мрежата чрез широковещание, затова работи само в рамките на един broadcast сегмент на мрежата. Невъзможно е да се зададе IP адрес на устройството ръчно. Устройството в друга подсетка? Тогава имате проблем.
- разработчиците не се занимават с устройството, изпращането на бъг репорти е безполезно.
Вторият етап се случи в не толкова далечни времена, и ме доведе до темата на статията — . Привлекателен е с откритостта си, особено след като хората от подписаха им драйвера за Windows, така че сега дори и на x64 всичко работи без никакви заобикалки като тестов режим. За което голямо благодаря на екипа на ReactOS! Звучи всичко красиво, ще опитаме да видим дали това е истината? За съжаление, самият проект също е натрупал забавяния, и не можем да разчитаме на поддръжка — но къде сме ние, винаги можем да се справим, кодът е наличен!
Част втора, свързана със сървърите и Linux
Сървърът USB/IP, който споделя USB устройства през мрежата, може да бъде инсталиран само в Linux-базирани операционни системи. Е, какво да правим, инсталираме на виртуалка 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 (изглежда, очевидният път) — не е подходящ! Работата е там, че хардуерът като USB хъбове usbip игнорира. Затова, ще използваме вградената команда:
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) не може да намери устройствотоОй-ой. Нещо не е наред. Използваме умението на Google. Срещат се разпръснати споменавания, че нещо не е наред с константите, в сървърната част разработчиците промениха версията на протокола при преминаването на версия 0.2.0, а в клиента под Win забравили да го направят. Предложението е — сменете константата в изходния код и пререблете клиента.
Но наистина не ми се иска да изтеглям Visual Studio за тази процедура. Затова имам стария добър Hiew. В изходния код константата е обявена като двойно число. Нека потърсим в файла 0x00000106, заменяйки с 0x00000111. Не забравяйте, редът на байтовете е обратен. Резултатът — две съвпадения, патчваме:
[usbip.exe]
00000CBC: 06 11
00000E0A: 06 11Ииии… да!
C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
нов USB устройство прикрепено към usbvbus порт 1На това можеше да се приключи изложението, но музиката не игра дълго. След като рестартирах сървъра, открих, че устройството на клиента не се монтира!
C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
usbip err: usbip_windows.c: 829 (attach_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
