A Rust library to run a USB/IP server to simulate USB devices and share real USB devices over a network.
USB/IP is a network protocol that allows USB devices to be shared between computers over a network. It enables:
- Device simulation: Create virtual USB devices that can be accessed remotely
- Device sharing: Share physical USB devices from one machine to another
- Cross-platform: Works across different operating systems (Linux, etc.)
Install Rust from the official documentation.
git clone https://github.com/jiegec/usbip.git
cd usbip
cargo build --releaseThe examples/ directory contains four example programs:
- hid_keyboard: Simulate a HID keyboard that types something every second
- cdc_acm_serial: Simulate a CDC ACM serial device that receives a character every second
- host: Act as a USB/IP server, sharing physical devices from the host machine to remote clients
- demo: Simulate a HID keyboard and a CDC ACM serial device together (used by the QEMU test)
cargo run --example hid_keyboardOn the client machine (e.g. Linux with USB/IP support):
# List available devices
usbip list -r $remote_ip
# Attach to a device
usbip attach -r $remote_ip -b $bus_idThe simulated devices can be verified against a real Linux kernel booted under
QEMU. The test assembles a minimal initramfs (busybox + usbip tool + the demo
server + the kernel's usbip/vhci/cdc/hid modules), boots it, then uses vhci-hcd
to attach the simulated keyboard and serial device. Inside the guest it confirms
the serial port emits 'a' and that the keyboard generates a KEY_1 input
event.
Run it locally (requires qemu-system-x86, a static busybox, cpio, and the
usbip tool):
./scripts/qemu/run-qemu-test.sh --build --dump-logIt runs under KVM when available and falls back to QEMU TCG otherwise. The
kernel, vmlinuz and module tree used can be overridden via the KERNEL, VMLINUZ
and MODTREE environment variables (useful to reproduce a CI kernel locally).
In CI (scripts/qemu + .github/workflows/qemu.yml) the Ubuntu generic kernel
is installed and booted. This matters because the GitHub runner's Azure kernel
has CONFIG_USB_HID disabled, so it cannot enumerate a simulated USB keyboard;
the generic kernel ships the hid/hid-generic/usbhid modules which are loaded
in the guest so both the serial device and the keyboard are verified.
MIT License - see LICENSE file for details.