Skip to main content

Sniffing CAN traffic and making sense of it

· 5 min read

Plug into a CAN bus and you get a wall of hex: IDs, lengths and data bytes scrolling past faster than you can read them. This post walks through how I capture that traffic on Linux, keep it in a file, and turn it into named signals with a DBC using RemotiveTopology and RemotiveStudio.

What sniffing gives you​

Sniffing means listening to a bus without taking part in it. You see every frame that ECUs send, with timestamps, which is exactly what you want when you're asking questions like "does the BCM actually send the turn signal frame when I flip the stalk?" or "how often does this frame show up?"

What you don't get from the wire is meaning. A CAN frame is an ID and up to 8 bytes (64 for CAN FD). Which bits are vehicle speed, and how to scale them, lives in a signal database such as a DBC. So sniffing is really two jobs: capture the raw frames, then decode them.

Setup: get the bus onto a SocketCAN interface​

Everything below assumes Linux, because it relies on SocketCAN. Once your CAN adapter shows up as a network interface, standard tooling such as candump from can-utils works against it. The RemotiveTopology docs recommend giving the interface a name that matches your architecture rather than can0:

sudo ip link set can0 name drivercan0

That small habit pays off later, when you have three adapters plugged in and need to remember which one is on the driver CAN.

If the traffic you want to look at comes from containers, for example behavioral models in a topology, RemotiveBus can expose it on the host. A vcan network with a host_device creates a virtual CAN interface on the host, so you can sniff simulated traffic with the same tools you use on a real vehicle:

type: vcan
device: mybus
host_device: myhostbus # Name of the virtual CAN interface to create on the host

To go the other way and let containers use a physical bus, use type: can with host_device pointing at the adapter. Note that Docker appends a 0 to the device name inside the container.

Capturing traffic​

With the interface up, start with a live look:

candump drivercan0

Once you've confirmed frames are flowing, log them to a file instead. candump -l writes a candump-<date>.log file in the current directory, in the "CAN dump" format that both RemotiveTopology and RemotiveCloud read. Drive the scenario you care about, then stop it with Ctrl+C.

Before you do anything else with the log, check it with RemotiveCLI. If a colleague needs the capture in another format, the same tool converts between .log, .asc and .blf:

remotive tools can validate candump-2026-09-03_101500.log --print-to-terminal
remotive tools can convert candump-2026-09-03_101500.log drive.blf

Both commands are described in the RemotiveCLI reference.

Making sense of what you captured​

Now for the decoding. In RemotiveTopology, the signal database belongs to a channel in your platform. A DBC doesn't say which bus it describes, so you name the channel yourself (platform docs):

schema: remotive-topology-platform:0.15
channels:
DriverCan:
type: can
database: ../databases/driver_can.dbc

Next, wrap the log in a recording session, and add a recording mapping that connects the interface name in the log to the platform channel:

remotive topology recording-session create -f candump-2026-09-03_101500.log drive.recordingsession.yaml
schema: remotive-recording-mapping:0.1

devices:
drivercan0: DriverCan

If you named the interface the same as the channel, you can skip the mapping: a default mapping from same-name devices is created automatically. Then create an instance for playback, generate it and start it with the UI profile, as described in recordings usage:

remotive topology recording-session instantiate drive.recordingsession.yaml drive.instance.yaml
remotive topology generate -f drive.instance.yaml build
docker compose -f build/<instance>/docker-compose.yml --profile ui up

In RemotiveStudio, the Signal view lists every frame and signal in the DBC, with unit, factor/offset and named values, which is handy for finding the signal you're after. Then build a dashboard with a few panels, with an Open recording panel to play back the log:

  • Frame distribution shows which frames are on the bus and how often. A frame that's missing, or one far more frequent than expected, is often the first clue.
  • Trace is the decoded version of candump: timestamp, frame ID, frame name and raw bytes, with signal values when you expand a row.
  • Time series plots the signals themselves, so you can see that brake pedal position goes up just before vehicle speed goes down.

Other ways to look at the same data​

If you'd rather not set up a platform, you can upload the log to RemotiveCloud, either by drag and drop or with remotive cloud recordings upload. It matches the recording against the signal databases in your project and suggests the best fit. And for Ethernet traffic between containers, including SOME/IP, Edgeshark and Wireshark let you inspect each connection in a running topology.

Whichever route you take, the idea is the same: capture first, keep the raw log, and let the signal database do the decoding. The log stays useful long after the drive is over.

About the author

Ola Nilsson

Builds the RemotiveLabs developer experience, from the docs and this blog to the tools around them. Usually found turning a support question into a guide, a guide into an example, and an example into a test that runs in CI. Has opinions about keyboard shortcuts.