Wiki / Hardware

USB-CAN Adapter

A USB interface carrying a real CAN controller and transceiver, so a Linux SocketCAN network device (can0) can sniff, decode and inject frames on a vehicle or industrial CAN bus.

Tapping the bus
ECU ECU CAN_H CAN_L 120Ω 120Ω USB-CAN adapter
The adapter is just another node on a shared differential pair: it sees every frame and can send its own. Termination belongs at the two physical ends of the bus. Enabling the adapter's 120 ohm jumper while tapping mid-bus adds a third terminator and corrupts the signal.

A USB-CAN adapter puts a genuine CAN controller and a CAN transceiver on the end of a USB cable, so your laptop becomes a node on the bus. On Linux the good ones appear as a SocketCAN network interface, usually can0, which means every standard tool (candump, cansend, cangen, Wireshark, python-can, Scapy) works against it with no vendor SDK.

What it is

Two layers matter. The controller builds and arbitrates CAN frames; the transceiver converts the controller's logic-level TX/RX into the differential CAN_H/CAN_L pair on the wire. An adapter without a real transceiver cannot sit on a real bus. Three families you will meet:

Family How Linux sees it Examples
Native SocketCAN over USB (gs_usb) can0 appears on plug-in CANable running candleLight, Innomaker USB-CAN
Serial-line CAN (slcan) a /dev/ttyACM0 you convert with slcand CANable running the slcan firmware, USBtin
Vendor driver can0 via the vendor's kernel module PEAK PCAN-USB, Kvaser

Same hardware, different firmware, is common: a CANable ships either as candleLight (native) or slcan, and reflashing changes how you bring it up.

Bringing the interface up

Native gs_usb device:

sudo ip link set can0 type can bitrate 500000
sudo ip link set up can0

candump -tz can0            # every frame, with timestamps
candump -l can0             # log to candump-<date>.log for later replay
cansend can0 123#DEADBEEF   # 11-bit ID 0x123, 4 data bytes
canplayer -I candump.log    # replay a capture

Serial-line (slcan) device, where -s6 selects 500 kbit/s from the slcan speed table:

sudo slcand -o -c -s6 /dev/ttyACM0 can0
sudo ip link set up can0

For recon on a live vehicle, bring the interface up listen-only first. The controller then acknowledges nothing and cannot disturb the bus:

sudo ip link set can0 type can bitrate 500000 listen-only on

No hardware at all? sudo modprobe vcan plus ip link add dev vcan0 type vcan gives you a virtual bus for replaying logs and testing tooling offline.

Pitfalls

  • An ELM327 is not a CAN adapter. The cheap OBD-II dongles speak an AT-command request/response protocol on top of OBD-II PIDs. They cannot present raw bus traffic properly, they drop frames, and they do not become can0. If the task is sniffing or injection, you need a SocketCAN adapter.
  • Wrong bitrate. The controller sees only error frames, floods the error counters, and goes bus-off, at which point it stops transmitting entirely. Recover by taking the link down and back up, or configure restart-ms 100. Get the bitrate right first: 500 kbit/s and 250 kbit/s are the usual suspects on vehicles, but confirm rather than assume, and a Wiki: logic-analyzer or scope on CAN_H settles it.
  • Termination. The bus wants 120 ohm at each physical end and reads about 60 ohm across CAN_H/CAN_L when powered down and correctly terminated. Do not enable your adapter's termination jumper when tapping into the middle of an already terminated bus.
  • CAN FD is a different frame format. A classic CAN controller on an FD bus will error on FD frames. If the target is FD, the adapter and the ip link configuration both have to be FD-capable (dbitrate, fd on).
  • The OBD-II port is not the whole vehicle. It exposes selected buses, often through a gateway that filters. Interesting traffic frequently lives on a different bus you have to reach behind the dash.
  • Injection has physical consequences. Writing to a bus that controls actuators is not a lab-only action. Bench targets and simulators exist for a reason.

Further reading