DOC-CAN-002   REV 1.0   2026-06

Controller Area Network
and the Vehicle Bus Stack

From differential signaling and bitwise arbitration to ISO-TP, UDS diagnostics, and socketcan — with reverse-engineering and intrusion-detection crossover

CAN / CAN FD CAN XL Arbitration ISO-TP / UDS J1939 / OBD-II Hands-On Crossover
PREPARED BY
VEHICLE NETWORKS / EMBEDDED

DISTRIBUTION
ENGINEERING — UNRESTRICTED

FORMAT
TECHNICAL REFERENCE
1 Mbps Classic CAN
arbitration ceiling
8 Mbps CAN FD
data-phase burst
2048 B CAN XL
single-frame payload
~$25 CANable adapter
to socketcan

1 — The Bus and Why It Won

CAN is a multi-master, message-oriented serial bus designed by Bosch in 1986 and standardized as ISO 11898. There are no node addresses. A frame carries an identifier that names the message, not a destination, and every node hears every frame and decides in hardware whether to keep it. That single design choice — broadcast plus content filtering — is why one pair of wires can wire up an entire vehicle.

It won because it is cheap, differential, and deterministic. Two wires survive an electrically violent engine bay. Priority is built into the identifier, so the most urgent message always wins the bus without a scheduler. Nearly forty years later it is still the nervous system of almost every car and a vast amount of industrial, agricultural, and marine equipment.

Message-oriented, not address-oriented. A CAN node does not send "to ECU 7." It broadcasts message 0x180 and whoever cares accepts it. Adding a listener requires changing nothing on the sender. This is also why the bus has no built-in notion of who is allowed to say what — the root of its security story in section 8.

2 — Physical Layer

  • Differential pair — CAN_H and CAN_L. A transceiver drives the dominant state (logical 0) by pulling the two lines roughly 2V apart, and the recessive state (logical 1) by letting them relax to the same ~2.5V. Reading the difference rejects common-mode noise picked up equally on both wires.
  • Termination — 120Ω at each physical end of the bus, matching the twisted pair's characteristic impedance. Missing or extra terminators cause reflections and bit errors. A bench bus needs exactly two 120Ω resistors, no more.
  • Topology and rate — a linear bus with short stubs. High-speed CAN (ISO 11898-2) runs to 1 Mbps; low-speed fault-tolerant CAN (ISO 11898-3) trades speed for surviving a shorted or broken wire, used for slow body electronics.
  • Bit timing — each bit is divided into time quanta grouped into sync, propagation, and two phase segments. The sample point (typically 75–87.5% into the bit) is where every node reads the level, and nodes resynchronize their clocks on each recessive-to-dominant edge. Get this wrong and the bus works at short range but fails as you add cable.
3.5V 2.5V 1.5V CAN_H CAN_L ~2V differential RECESSIVE 1 DOMINANT 0 DOMINANT 0 RECESSIVE 1 BUS TOPOLOGY 120Ω 120Ω ECU ECU ECU linear bus · short stubs · 120Ω at each physical end
Fig. 1 — Differential signaling and bus topology. Dominant bits pull CAN_H and CAN_L ~2V apart; recessive lets them rest together. Every node sees the wired-AND of all transmitters, which is the basis of arbitration.

3 — Frame Format and Arbitration

A classic data frame is a fixed sequence of fields. The arbitration field carries the identifier and decides priority. Everything after it is payload and integrity.

SOF 1 IDENTIFIER 11 or 29 bit RTR 1 CONTROL IDE r0 DLC 6 DATA 0–8 B (64 B in FD) CRC 15 + del ACK 2 EOF 7 ARBITRATION FIELD · decides priority lower identifier value wins the bus; bit-stuffing inserted after 5 equal bits
Fig. 2 — Classic CAN data frame. Field widths are indicative, not to scale. The identifier doubles as the priority key, so assigning IDs is assigning a bus schedule.

Arbitration is the elegant part. Because the bus is a wired-AND (dominant always overrides recessive), nodes can transmit at the same time and sort out priority bit by bit without anyone colliding destructively.

  1. Simultaneous start
    Several nodes see the bus idle and begin transmitting on the same Start-of-Frame bit. No coordination, no token.
  2. Identifier, MSB first
    Each node drives its identifier one bit at a time and simultaneously samples what is actually on the bus.
  3. Dominant wins
    A node that drives recessive but reads dominant has just been overruled by a higher-priority frame. It stops transmitting instantly and switches to listening. Its frame is not corrupted; it simply lost.
  4. Winner never notices
    The highest-priority node finishes its frame unaware there was contention. The loser re-arbitrates at the next idle. No retransmission penalty, no backoff timer, fully deterministic.

Two more mechanisms keep the bus honest. Bit stuffing inserts an opposite-polarity bit after five identical bits so receivers can keep their clocks locked. Fault confinement counts transmit and receive errors at each node, demoting a misbehaving node from error-active to error-passive and finally to bus-off, where it removes itself from the bus entirely.

4 — CAN FD and CAN XL

Classic CAN's 8-byte payload and 1 Mbps ceiling became the bottleneck as ECUs multiplied. The two successors keep the arbitration model and extend the data phase.

VariantMax payloadMax data rateStandardNotes
Classic CAN8 bytes1 MbpsISO 11898-1The 1986 original. Universal, slow, tiny frames.
CAN FD64 bytes~8 Mbps (data)ISO 11898-1:2015Arbitrate slow for compatibility, then switch rate (BRS) for the payload.
CAN XL2048 bytes~10–20 MbpsCiA 610 / ISO 11898-1SDU type field tunnels Ethernet and higher protocols. Needs SIC XL transceivers.

CAN FD is the workhorse upgrade: the slow arbitration phase stays bit-compatible with classic CAN so mixed buses work, then the bit-rate switch accelerates only the data and CRC fields. Bigger payloads also cut per-byte overhead, which matters when flashing firmware. CAN XL goes further, carrying up to 2048 bytes and an SDU type that lets a CAN frame transport an Ethernet frame, positioning CAN as the edge bus under a zonal Ethernet backbone (section 9).

5 — Higher-Layer Protocols

CAN itself is only layers 1 and 2: wires and frames. Anything meaningful — diagnostics, firmware, sensor meaning — is a higher-layer protocol riding on top of the same frames.

ProtocolLayer / roleDomainKey idea
ISO-TPTransport (ISO 15765-2)Diagnostics transportSegments up to 4095 bytes across many frames with flow control.
UDSDiagnostics (ISO 14229)Every modern ECURead data, run routines, flash firmware, seed/key security.
OBD-IIEmissions (ISO 15031 / J1979)Legally mandated portStandardized PIDs any scan tool can read.
J1939Application (SAE)Trucks, buses, ag, marine29-bit PGN/SPN at 250–500 kbps; self-describing parameters.
CANopenApplication (CiA 301)Industrial / roboticsObject dictionary with PDO (real-time) and SDO (config) messaging.

6 — ISO-TP and UDS

A single CAN frame holds at most 8 bytes (64 in FD). To move a 17-byte VIN or a megabyte of firmware, ISO-TP segments the message and the receiver paces it with flow control. The first byte of each frame is a Protocol Control Information byte whose high nibble names the frame type.

  • Single Frame (0) — the whole message fits in one frame; the low nibble is the length.
  • First Frame (1) — opens a multi-frame transfer and declares the total length (up to 4095).
  • Consecutive Frame (2) — carries 7 payload bytes each, tagged with a rolling 4-bit sequence number.
  • Flow Control (3) — sent by the receiver: clear-to-send / wait / overflow, plus block size and STmin (the minimum gap it can tolerate between frames).
// iso-tp read of a 20-byte response. tester sends on 0x7E0, ecu replies on 0x7E8 TX 7E0 [8] 03 22 F1 90 00 00 00 00 // single frame, len 3: uds 0x22 readDataByIdentifier, did 0xF190 RX 7E8 [8] 10 14 62 F1 90 31 47 31 // first frame: total len 0x014=20, 0x62 = 0x22+0x40 positive resp TX 7E0 [8] 30 00 00 00 00 00 00 00 // flow control: clear-to-send, block size 0, stmin 0 RX 7E8 [8] 21 4A 54 33 38 32 4D 38 // consecutive frame, sequence 1 RX 7E8 [8] 22 35 30 30 30 30 30 30 // consecutive frame, sequence 2

On top of ISO-TP sits UDS. A request is a one-byte service ID plus parameters; a success reply echoes the service ID plus 0x40. A failure returns 0x7F, the service, and a negative response code. The same handful of services covers reading sensors, clearing trouble codes, unlocking protected functions, and reflashing the ECU.

// uds security access: seed/key unlock before protected services (service 0x27) TX 7E0 02 27 01 // requestSeed, security level 0x01 RX 7E8 06 67 01 A1 B2 C3 D4 // positive 0x67, seed = A1B2C3D4 TX 7E0 06 27 02 5E 9F 11 8C // sendKey (level+1), key derived from seed by secret algorithm RX 7E8 02 67 02 // positive: access granted, protected services now unlocked RX 7E8 03 7F 27 35 // or negative: 0x7F, service 0x27, nrc 0x35 invalidKey

Key services worth memorizing: 0x10 DiagnosticSessionControl, 0x22 ReadDataByIdentifier, 0x2E WriteDataByIdentifier, 0x27 SecurityAccess, 0x31 RoutineControl, 0x34/0x36/0x37 the RequestDownload / TransferData / TransferExit firmware-flashing trio, 0x19 ReadDTCInformation, and 0x3E TesterPresent (the keep-alive that stops a session timing out).

7 — socketcan and Hands-On

On Linux, CAN is just another network interface. socketcan presents can0 like a NIC, so the same mental model as Ethernet applies: bring the link up, then capture and inject. A virtual vcan0 interface lets you build and test an entire pipeline with no hardware at all.

// bring up a real interface at 500 kbit/s, then watch and inject $ sudo ip link set can0 up type can bitrate 500000 $ candump can0 // dump every frame on the bus, live $ cansend can0 123#DEADBEEF // inject one frame, id 0x123 $ cansniffer can0 // group by id, highlight changing bytes // no hardware? loop back on a virtual bus $ sudo modprobe vcan && sudo ip link add dev vcan0 type vcan && sudo ip link set vcan0 up

The raw bus is hex. A DBC database maps arbitration IDs and bit ranges to named signals with scale and offset, turning 0x0C8 1A F0 into EngineRPM = 832.5. python-can reads the bus and cantools applies the DBC.

// decode live can traffic to engineering units with a dbc import can, cantools db = cantools.database.load_file("vehicle.dbc") bus = can.Bus("can0", interface="socketcan") for msg in bus: try: signals = db.decode_message(msg.arbitration_id, msg.data) except KeyError: continue // id not described in this dbc print(signals) // {'EngineRPM': 832.5, 'VehicleSpeed': 0.0}
  • USB adapters — a CANable or other slcan dongle is roughly $25 and shows up as can0. PEAK PCAN-USB is the pricier professional option with rock-solid drivers.
  • Raspberry Pi + MCP2515 — an SPI CAN controller HAT turns a Pi into a logger or gateway for under $15 in parts. The mainline kernel driver exposes it as socketcan directly.
  • Where to tap — the OBD-II port exposes at least one CAN bus on pins 6 and 14. Beyond that, vehicles split into many isolated buses behind a gateway, so a single port rarely sees everything.

8 — Reverse Engineering and Security

The uncomfortable truth: classic CAN has no authentication and no encryption. Any node can transmit any identifier, and every node believes it. Physical access to a bus, often through the OBD-II port, is close to full control. Security was simply not a 1986 design goal.

  • Sniff and identify — run cansniffer, actuate one control (a turn signal, a window), and watch which ID and bytes change. Repeat to hand-build a DBC. This is most of practical CAN reverse engineering.
  • Replay and spoof — capture a frame and re-send it; the receiving ECU cannot tell the difference. Nearly every CAN attack reduces to this, because nothing on the bus proves who sent a frame.
  • Bus-off attack — an adversary node deliberately induces bit errors during a victim's transmission, driving the victim's error counter to bus-off so it silently drops off the network. A denial-of-service that needs no spoofing, only timing.
  • Voltage fingerprinting IDS — defenders profile each ECU's analog voltage signature, which depends on transceiver hardware and is hard to mimic, then flag frames whose claimed ID does not match the measured transmitter. Effective, but it needs extra taps on CAN_H/CAN_L and is itself attackable by voltage corruption.
  • SecOC — AUTOSAR Secure Onboard Communication appends a truncated MAC and a freshness value (a counter or timestamp) to critical frames, giving authentication and replay protection where bus bandwidth allows. The cryptographic answer to a bus that never had one.
No authentication, by design. Gateways, message filtering, intrusion detection, and SecOC are all retrofits onto a protocol whose whole appeal was that any node could broadcast freely. Treat every classic-CAN segment as a trust domain: anything on it can impersonate anything else on it.

9 — Where CAN Connects

CAN is not being replaced so much as demoted to the edge. Modern vehicles are moving to a zonal architecture: a few location-based controllers gather their local CAN, CAN FD, and LIN buses and aggregate them onto an automotive Ethernet backbone.

  • Automotive Ethernet — single-pair 100BASE-T1 and 1000BASE-T1 for the backbone, 10BASE-T1S multidrop for cheaper segments, with TSN adding the bounded latency that classic Ethernet lacks. This is the same determinism story as the avionics fabrics in the real-time inference reference.
  • Zonal gateways — instead of one bus per function snaking across the car, zone controllers translate between local CAN and the Ethernet core, cutting wiring mass and giving a natural place to enforce security policy.
  • The crossover — a car's CAN edge is the consumer-accessible analog of the F-35's IEEE 1394b vehicle bus feeding the Integrated Core Processor: a deterministic, low-bandwidth bus carrying actuators and slow sensors under a high-bandwidth fused backbone. Same shape, very different budget. See the companion document, Real-Time Sensor Fusion and Inference Architectures.

References

[ISO 11898-1]ISO 11898-1:2015 — Road vehicles, Controller Area Network, Part 1: Data link layer and physical signalling (Classic and FD)
[ISO 11898-2]ISO 11898-2:2016 — High-speed medium access unit (physical layer)
[CiA 610]CAN in Automation — CiA 610 series, CAN XL specification and test plans. can-cia.org
[ISO 15765-2]ISO 15765-2 — Diagnostic communication over CAN (ISO-TP): segmentation, flow control, reassembly
[ISO 14229]ISO 14229-1 — Unified Diagnostic Services (UDS) specification and requirements
[SAE J1939]SAE J1939 — Serial control and communications heavy-duty vehicle network
[SocketCAN]Linux kernel SocketCAN documentation. kernel.org
[python-can]python-can and cantools. python-can.readthedocs.io
[Bus-off]Silently Disabling ECUs and Enabling Blind Attacks on the CAN Bus — arXiv:2201.06362
[SecOC]AUTOSAR — Specification of Secure Onboard Communication (SecOC)