Homepage GitHub

UAVCAN v1 Wireshark plugin

Hey all,

I’ve made a simple wireshark dissector for UAVCAN/CAN v1.

It supports both CAN2.0B and CAN FD transport using SocketCAN in Linux.
People can use SLCAND to use UART based adapters.

Current features of the dissector is:

  • CAN ID decoding
  • Tail byte decoding
  • Message reassembly
  • Basic static message decoding
  • Very basic error checking

Current messages with static port identifier can be decoded:

  • Heartbeat 1.0
  • Access 1.0
  • List 1.0
  • NodeIDAllocationData 1.0
  • NodeIDAllocationData 2.0

I didn’t verified for correctness, but it does check the toggle-bit in multi-frame transfers. Furthermore I’m not planning to include to all the public_regulated_data_types. If people are interested we can take a look to get it into upstream Wireshark.

It’s located here https://github.com/PetervdPerk-NXP/wireshark
The code for the dissector itself is here:

1 Like

Hey Peter,

This is great. I’ve been also thinking that it would be nice to have a dissector for Wireshark. I think if there is an opportunity to have these changes upstreamed, that would be great, but I would like to add a few comments on this.

First things first: in the column “protocol” it says “UAVCAN”, but I think what you mean is “UAVCAN/CAN” because as you know there is no “CAN” in “UAVCAN”. One may want to leverage Wireshark for UAVCAN/UDP or UAVCAN/anything-else in which case having distinctive names for different transport layers would be helpful. There are also comments in the source code that seem to say “UAVCAN” where “UAVCAN/CAN” would be more correct:

Second, would you consider perhaps extracting the DSDL dissector from the UAVCAN/CAN layer in order to allow people to use it with other transports? Observe that UAVCAN/CAN is the transport layer whereas DSDL is the presentation layer that can also sit on top of UAVCAN/UDP, so from the standpoint of architecture and plain reusability it makes sense to separate it.

Although that said, I am not sure if it makes much sense to dissect DSDL in the first place (whether as part of the transport layer or from a separate dissector) because DSDL is too abstract for a tool like Wireshark. For purposes of comparison, you wouldn’t use Wireshark to parse an RPC-XML payload, too, because the tool is not built for debugging the application layer and simply lacks the necessary UX rigging for the job. Also, as I wrote recently in the documentation for Yakut, giving the standard data types too much of special treatment may set dangerous precedents:

A question one is likely to ask here is: Why don’t you ship precompiled regulated DSDL together with the tool? Indeed, that would be trivial to do, but we avoid that on purpose to emphasize our commitment to supporting vendor-specific and regulated DSDL at the same level. In the past we used to give regulated namespaces special treatment, which caused our users to acquire misconceptions about the purpose of DSDL. Specifically, there have been forks of the standard namespace extended with vendor-specific types, which is harmful to the ecosystem.

If you feel like your work on the DS-015 integration is dependent on the availability of a decent diagnostic tool, I suggest we channel our efforts in a different direction: extending Yakut (and eventually Yukon, but that is a separate story) with the proper UAVCAN-centric application-layer diagnostic capability – something that you can’t do properly in Wireshark as I just wrote. The plan is simple and we can set it up in no time if you could lend me a hand with a bit of Pythoning here.

Over the last month, I have done the groundwork necessary for performing packet capture and dissection using PyUAVCAN. This foundation does most of the hard work already, but what’s missing is a human-friendly interface on top of it. I am envisioning two additional commands for Yakut for this purpose:

  • yakut capture to read frames from the specified network interface (which, observe, doesn’t need to be SocketCAN! @polaris is planning to finalize his pull request adding support for another CAN backend supporting other hardware + Windows over this weekend). The command would receive raw transport frames from the network, encapsulate them using uavcan.metatransport.*, serialize using UAVCAN/serial, and emit them into stdout. The result is intentionally not human-readable, but it can be piped into a file or into the next command:

  • yakut trace, which reads the UAVCAN/serial encoded stream of encapsulated frames from stdin and feeds that into pyuavcan.transport.Tracer. The output is then deserialized using the data types specified by the user and printed into stdout in our conventional YAML or JSON format (like yakut sub does). Naturally, the data supplied via stdin may come either from the aforementioned yakut capture or from a UAVCAN log file. The latter would close the long- and sorely-missing feature that has been discussed many, many, many, many times already.

Then, for a real-time capture session, the usage would be roughly as follows:

yakut capture --transport='CAN(something...)' | yakut trace 33.uavcan.si.sample.length.Vector3.1.0 --path=/my/dsdl

The fact that we split the work into two operations (capture and trace) is essential here as it allows us to drastically conserve work by addressing different use cases with a single feature. The resulting log format is not specific to Yakut, since it is just a raw dump of UAVCAN/serial, and as such, it can be supported by standalone on-board data recorders, which is also a commonly requested feature.

The missing bits are fairly minor and can be implemented in a few working days:

  • Implement the capture and tracing functionality for the UAVCAN/CAN transport in PyUAVCAN (currently it is available only for UAVCAN/serial and UAVCAN/UDP). I can do this myself, CAN is an easy transport to implement this for.

  • Merge https://github.com/UAVCAN/public_regulated_data_types/pull/99 (it’s finished already)

  • Add the two commands to Yakut. They will contain very little business logic, mostly related to converting data between different representations using PyUAVCAN.

Would you be inclined to join this effort? I can give you a quick intro to Yakut then. If you choose yes, then I would recommend actually withdrawing the DSDL parser functionality from your Wireshark dissector (keeping the transport dissector intact of course) for the aforementioned reasons.

Hi Pavel,

Good point about the naming, indeed the dissector is for UAVCAN/CAN traffic, I can change the name that’s no problem.

Second, would you consider perhaps extracting the DSDL dissector from the UAVCAN/CAN layer in order to allow people to use it with other transports?

I don’t think we should include DSDL into Wireshark, I think tooling such as PyUAVCAN, yakut or Yukon will do a better job at that. Furthermore in Wireshark everything seems to be quite static whereas for example the public_regulated_data_types repository is bound to change from time to time.

However there’s a reason why I’ve implemented the minimal subset of messages/services (Heartbeat, register and NodeIDAllocation) since I think they are part of the “UAVCAN Standard Message definition” and allows for quick debugging and filtering through Wireshark.

If you feel like your work on the DS-015 integration is dependent on the availability of a decent diagnostic tool, I suggest we channel our efforts in a different direction: extending Yakut (and eventually Yukon, but that is a separate story)

Having more advanced tooling is always a nice to have and thus I don’t want to extent Wireshark dissector any further (it’s already 1200 lines of code anyhow :wink:). Using Wireshark in combination with PyUAVCAN to decode DSDL is currently enough for me now.

That’s my point exactly. You seem to prefer to keep the current limited support of DSDL in place, in which case I would recommend extracting it into a separate dissector to make it reusable with other UAVCAN transports. Would that be possible?

That makes sense, but what I am offering is not related to Wireshark at all and it does not affect your dissector in any way.

I’ve extracted the DSDL decoding from UAVCAN/CAN into packet-uavcan-dsdl.c which in theory can be used with a UAVCAN/UDP dissector.

Furthermore I did some naming/taxonomy fixes regarding UAVCAN/CAN, feel free to test it out.

1 Like

This is great. How difficult would it be to get it into upstream?

Also, seeing GPS in your screenshot reminds me that this PR would benefit from your review:

Didn’t look at the merging process from Wireshark yet (e.g. code-style & QA), but I suppose it shouldn’t be that hard since didn’t had to change core functionality of wireshark.

But first I do want to do some extensive testing of the dissector with more advanced test data.
To fix things like

1 Like