Domando USB/IP

A tarefa de conectar um dispositivo USB a um PC remoto por meio de uma rede local surge regularmente. Abaixo do corte, é apresentado o histórico de minhas buscas nessa direção e o caminho para uma solução pronta baseada em um projeto de código aberto USB/IP com uma descrição dos obstáculos cuidadosamente colocados por várias pessoas neste caminho, bem como formas de contorná-los.

Parte um, histórico

Se a máquina for virtual - tudo isso é fácil. A funcionalidade de encaminhamento USB de um host para uma máquina virtual apareceu no VMWare 4.1. Mas, no meu caso, a chave de segurança, reconhecível como WIBU-KEY, teve que ser conectada em momentos diferentes a máquinas diferentes, e não apenas virtuais.
A primeira rodada de busca no distante 2009 me levou a um pedaço de ferro chamado TrendNet TU2-NU4
Prós:

  • às vezes até funciona

Contras:

  • nem sempre funciona. Suponha que a chave de proteção Guardant Stealth II não seja iniciada por ela, jurando com o erro “o dispositivo não pode ser iniciado”.
  • O software de gerenciamento (leia - montagem e desmontagem de dispositivos USB) é patético ao extremo. Interruptores de linha de comando, automação - não, não ouvi. Tudo é apenas à mão. Pesadelo.
  • o software de controle procura o próprio pedaço de ferro na rede por broadcasting, então isso só funciona dentro de um segmento de rede de broadcast. Você não pode especificar o endereço IP do pedaço de ferro manualmente. Um pedaço de ferro em outra sub-rede? Então você tem um problema.
  • desenvolvedores pontuaram no dispositivo, é inútil enviar relatórios de bugs.

A segunda rodada aconteceu em tempos não tão distantes, e me levou ao tema do artigo - Projeto USB/IP. Atrai com franqueza, principalmente porque os caras do ReactOS eles assinaram um driver para Windows, então agora tudo funciona mesmo em x64 sem muletas como um modo de teste. Muito obrigado à equipe ReactOS! Tudo soa lindo, vamos tentar sentir, é mesmo? Infelizmente, o projeto em si também foi abandonado e você não pode contar com o apoio - mas onde o nosso não desapareceu, a fonte está aí, vamos descobrir!

Parte dois, servidor-linux

Um servidor USB/IP que compartilha dispositivos USB em uma rede só pode ser configurado em um sistema operacional baseado em Linux. Bem, Linux é Linux, então instale na máquina virtual Debian 8 na configuração mínima, movimento de mão padrão:

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

Assentou. Além disso, a Internet sugere que você precisaria baixar o módulo usbip, mas - olá, o primeiro rake. Não existe esse módulo. E tudo porque a maioria dos manuais na rede se refere ao ramo antigo 0.1.x, e no último 0.2.0 os módulos usbip têm nomes diferentes.

Portanto:

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

Bem, vamos adicionar as seguintes linhas em /etc/modules para carregá-los automaticamente na inicialização do sistema:

usbip-core
usbip-host
vhci-hcd

Vamos iniciar o servidor usbip:

sudo usbipd -D

Além disso, a mente universal nos diz que o usbip vem com scripts que nos permitem gerenciar o servidor - mostrar qual dispositivo ele compartilhará na rede, ver o status e assim por diante. Aqui, outra ferramenta de jardim nos espera - esses scripts no ramo 0.2.x, novamente, foram renomeados. Você pode obter uma lista de comandos com

sudo usbip

Depois de ler a descrição dos comandos, fica claro que, para compartilhar o dispositivo USB necessário, o usbip deseja saber seu Bus ID. Caros espectadores, o rake número três está na arena: o Bus ID que nos dará lsusb (parece a forma mais óbvia) - não combina com ela! O fato é que usbip ignora hardware como hubs USB. Portanto, usaremos o comando interno:

user@usb-server:~$ sudo usbip list -l
 - busid 1-1 (064f:0bd7)
   WIBU-Systems AG : BOX/U (064f:0bd7)

Nota: a seguir nas listagens vou descrever tudo usando o exemplo da minha chave USB específica. O nome do hardware e o par VID:PID podem e serão diferentes. O meu se chama Wibu-Systems AG: BOX/U, VID 064F, PID 0BD7.

Agora podemos compartilhar nosso dispositivo:

user@usb-server:~$ sudo usbip bind --busid=1-1
usbip: info: bind device on busid 1-1: complete

Felicidades, camaradas!

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)

Três vivas, camaradas! O servidor compartilhou o pedaço de ferro na rede e podemos conectá-lo! Resta apenas adicionar o início automático do daemon usbip a /etc/rc.local

usbipd -D

Parte três, lado do cliente e confuso

Tentei conectar o dispositivo compartilhado pela rede a uma máquina Debian imediatamente no mesmo servidor e tudo se conectou bem:

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

Vamos para o Windows. No meu caso, foi o Windows Server 2008R2 Standard Edition. O guia oficial pede que você instale o driver primeiro. O procedimento está perfeitamente descrito no leia-me anexado ao cliente windows, fazemos tudo como está escrito, dá tudo certo. No XP também funciona sem problemas.

Depois de descompactar o cliente, tentamos montar nossa chave:

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

Ai ai. Algo deu errado. Usamos a habilidade do Google. Existem menções fragmentárias de que algo está errado com as constantes, na parte do servidor, os desenvolvedores alteraram a versão do protocolo ao mudar para a versão 0.2.0, mas se esqueceram de fazer isso no cliente Win. A solução proposta é alterar a constante no código-fonte e reconstruir o cliente.

Mas eu realmente não quero baixar o Visual Studio por causa deste procedimento. Mas eu tenho um bom e velho Hiew. No código-fonte, a constante é declarada como uma palavra dupla. Vamos procurar no arquivo 0x00000106, substituindo-o por 0x00000111. Lembre-se, a ordem dos bytes é invertida. O resultado são duas correspondências, patch:

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

Eeeee... sim!

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

Isso poderia ter encerrado a apresentação, mas a música não tocou por muito tempo. Após reiniciar o servidor, descobri que o dispositivo no cliente não está montado!

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

E é isso. Mesmo o onisciente Google não poderia responder isso para mim. E, ao mesmo tempo, o comando para exibir os dispositivos disponíveis no servidor mostra corretamente - aqui está, a chave, você pode montá-la. Eu tento montar no Linux - funciona! E se agora tentar no Windows? Oh merda - funciona!

O último rake: algo não foi adicionado no código do servidor. Ao compartilhar um dispositivo, ele não lê o número de descritores USB dele. E ao montar o dispositivo no Linux, esse campo é preenchido. Infelizmente, estou familiarizado com o desenvolvimento no Linux no nível “make && make install”. Portanto, o problema é resolvido com um hack bastante sujo - adicionando a /etc/rc.local

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

Parte final

Depois de mexer um pouco, funciona. O resultado desejado foi obtido, agora a chave pode ser montada em qualquer PC (e desmontada, claro, também), inclusive fora do segmento de rede broadcast. Se desejar, você pode fazer isso usando um script de shell. O que é bom - o prazer é absolutamente gratuito.
Espero que minha experiência ajude habrazhiteli a contornar o ancinho que ficou marcado em minha testa. Obrigado pela sua atenção!

Fonte: habr.com

Adicionar um comentário