Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request filter for SocketCAN device #1247

Open
CWNE88 opened this issue Dec 6, 2023 · 8 comments
Open

Request filter for SocketCAN device #1247

CWNE88 opened this issue Dec 6, 2023 · 8 comments

Comments

@CWNE88
Copy link

CWNE88 commented Dec 6, 2023

I’d like to set capture filter for CAN ID.
Either specific CAN ID variable, or being able to specify which bytes of the payload to match.
Similar to this for selecting ID 5c2:

ether[2:2] == 0x05c2

That “ether” filter will not work, because the device type is SocketCAN.
However, that above filter does actually work if reading from a captured file.
I would like to be able to filter at the capture stage.

From current code:

case DLT_CAN_SOCKETCAN:
bpf_error(cstate, "CAN link-layer type filtering not implemented");

CAN only has an ID, length, and payload (of up to 8 bytes).
Even if we can only filter with specific bytes, that would be enough.

For instance, something like this maybe:

can[2:2] == 0x05c2

At least that way, we could define what bytes in the packet to filter for the CAN type.

Thanks
Paul.

@infrastation
Copy link
Member

ether[2:2] is the same as link[2:2], although it is not immediately obvious why offline filtering works and online filtering does not. What would be the cheapest piece of hardware to test these code paths and to reproduce the problem?

@CWNE88
Copy link
Author

CWNE88 commented Dec 6, 2023

I did originally try link[2:2] as well, but nothing got captured.
The cheap device I'm using is the isolated (although you probably don't need isolation for a desk test) version of this:
https://www.aliexpress.com/item/1005006032351087.html

@CWNE88
Copy link
Author

CWNE88 commented Dec 6, 2023

I've also just noticed (could be unrelated though) that while doing the capture with Wireshark, an ID sent with 0x0ABC comes up in the packet bytes window correctly at 0abc but in the packet details window it shows as 0x2bc. Lower ID of 0x123 seems fine
Screenshot from 2023-12-06 21-51-11

@CWNE88
Copy link
Author

CWNE88 commented Dec 6, 2023

can-request.pcapng.gz

@infrastation
Copy link
Member

Thank you, with the file post-capture filtering works as expected. I could get the USB dongle, would it need to be connected to something to capture any packets?

The Wireshark decoder uses only the low 11 bits for the ID, so 0x0abc (0b101010111100) becomes 0x2bc (0b001010111100). I am not familiar with the packet format to confirm whether that's the correct behaviour.

@CWNE88
Copy link
Author

CWNE88 commented Dec 6, 2023

Okay, it seems the can ID must be a value that fits within 7 bits, so that explains the Wireshark information.

To set this up, you don't need any other equipment, just the adapter.
Install can-utils to get the cansend command.
When you connect the device, it will come up as can0 (down)

Bring it up with:

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

Send a message with:
cansend can0 123#11223344
where 123 is the ID and 11223344 is the payload (maximum 8 bytes for the payload)

You can run the capture on a different CLI to test filtering.

@infrastation
Copy link
Member

Thank you for the comments, I have ordered a very similar USB dongle and hopefully will be able to reproduce this problem soonish. Meanwhile other developers may want to make additional input.

@infrastation
Copy link
Member

This is how my USB CAN device identifies itself:

ID 1d50:606f OpenMoko, Inc. Geschwister Schneider CAN adapter
Product: candleLight USB to CAN adapter
Manufacturer: bytewerk

On Debian 12/AMD64 the problem seems to reproduce as described, in that link[2:2] = 0x0123 works as expected when reading from a savefile, but during the live capture no packets pass the filter:

# tcpdump -vni can0 'link[2:2] = 0x0123'
tcpdump: listening on can0, link-type CAN_SOCKETCAN (CAN-bus with SocketCAN headers), snapshot length 262144 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel

Without the filter the capture has the packets of interest (which take 2-3 seconds to appear in the capture after the cansend command) plus sometimes other packets. The DLT is CAN_SOCKETCAN in both cases and the filter looks correct:

(000) ldh      [2]
(001) jeq      #0x123           jt 2	jf 3
(002) ret      #262144
(003) ret      #0

This way, on the surface everything looks fine on the user-space side of the capture device, so maybe something could be wrong in the kernel.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

2 participants