Wireshark-bugs: [Wireshark-bugs] [Bug 12687] SocketCAN dissector does not support CAN FD

Date: Sat, 20 Aug 2016 23:53:20 +0000

Comment # 35 on bug 12687 from
(In reply to Oliver Hartkopp from comment #32)
> (In reply to Michael Mann from comment #30)
> > (In reply to Oliver Hartkopp from comment #29)
> 
> > > The two SLL types are not really relevant for CAN application programmers.
> > > It's a Linux internal thing which only becomes visible when programming
> > > PF_PACKET sockets.
> > > 
> > > For that reason my suggested changes to libpcap make sense to me as they are
> > > using PF_CAN sockets to get the CAN frames - and this would be a reasonable
> > > extension then.
> > 
> > I think I'll leave the SLL support in there for now for the same reason the
> > other SLL types are supported - people may use them, even if it's
> > "internal".  If the flag becomes an issue, we can worry about it then.
> 
> I took a deeper look into libpcap to (hopefully) get behind the concepts.
> 
> libpcap can use PF_PACKET sockets or protocol specific sockets (e.g. PF_CAN)
> to get PDUs. With PF_PACKET sockets you are able to filter for both ETH_P_
> types like ETH_P_CAN and ETH_P_CANFD which would have matching
> LINUX_SLL_P_CAN[FD] types in wireshark.
> 
> BUT in fact CAN interfaces (ARPHRD_CAN = 280) are handled with PF_CAN RAW
> sockets.

They're handled with PF_CAN RAW sockets if the name provided as the interface
name begins with "can" or "vcan", followed by a number.

> The PDUs read from the socket are provided by libpcap as link type
> DLT_CAN_SOCKETCAN ("CAN-bus with SocketCAN headers") to be used e.g. by
> Wireshark which takes this data source and tags it as LINUX_SLL_P_CAN.

No, actually, it doesn't.  It maps LINKTYPE_CAN_SOCKETCAN to
WTAP_ENCAP_SOCKETCAN in libwiretap, and the SocketCAN dissector registers to
handle WTAP_ENCAP_SOCKETCAN in the "wtap_encap" dissector table, so that all
packets with that encapsulation type are handed to it.

(And it now maps LINKTYPE_CAN_SOCKETCAN_BIGENDIAN to
WTAP_ENCAP_SOCKETCAN_BIGENDIAN, and maps LINKTYPE_CAN_SOCKETCAN_HOSTENDIAN to
WTAP_ENCAP_SOCKETCAN_HOSTENDIAN, both of which are handled by the SocketCAN
dissector, as per my other comment.)

The SocketCAN dissector *also* registers to handle LINUX_SLL_P_CAN in the
"sll.ltype" dissector table, so that all packets with an encapsulation type of
WTAP_ENCAP_SLL (Linux "cooked" captures) and a "protocol" type of
LINUX_SLL_P_CAN (= ETH_P_CAN) are handed to it.  It does *not* register for
ETH_P_CANFD packets, and won't see them, in Linux "cooked" captures.

> With CAN FD we now have two options:
> 
> 1. Create a second link type DLT_CANFD_SOCKETCAN and provide a separate data
> source to Wireshark. Additionally libpcap could be moved to use PF_PACKET
> too.

On the topic of "[moving] libpcap to use PF_PACKET [for CAN]":

As indicated, there are several code paths through libpcap that can provide CAN
frames.

>From a quick look at the Linux networking stack, CAN and AF_PACKET division
(once more unto the breach, dear friends, once more...), it appears that the
SocketCAN pseudo-header (struct can_frame and struct canfd_frame) is *not*
treated as a MAC header and is thus *not* stripped if you're receiving packets
from a PF_PACKET/SOCK_DGRAM socket, i.e. from a Linux "cooked" capture.

It appears that CAN interfaces (interfaces with an arphrd type of ARPHRD_CAN)
have names that begin with "can" or "can" followed by a number, so, if it's
possible, with *all* versions of the Linux kernel that support PF_CAN, to bind
either an PF_CAN/SOCK_RAW socket or a PF_PACKET/SOCK_DGRAM or
PF_PACKET/SOCK_RAW socket to one of those devices, and if there's no advantage
to sniffing with a PF_CAN socket, then we might as well just remove
pcap-can-linux.c, and let pcap-linux.c handle CAN interfaces.

Then, if there's a reason why classic CAN and CAN FD frames *from SocketCAN* -
i.e., with a struct can_frame/struct canfd_frame header - should be dissected
differently, then we should probably map ARPHRD_CAN to DLT_LINUX_SLL.  That
way, the capture will be done as a "cooked" capture, meaning that the
"protocol" field of the "cooked" header will be ETH_P_CAN for "classic" CAN
frames and ETH_P_CANFD for CAN FD frames, allowing the dissector to distinguish
between them.

In that case, the SocketCAN dissector would register in the "sll.ltype" table
with the value of ETH_P_CANFD, and the dissector for *that* would pass to the
common dissector code a flag indicating that it's a CAN FD frame, with the
existing dissectors passing a flag indicating that it's a "classic CAN" frame.

On the other hand, if there *isn't* a reason to dissect them differently, we
don't need to worry about distinguishing "classic" CAN frames from CAN FD
frames.

However, that all leaves unanswered the question of what to do about CANUSB
devices.  What would we need to do to pcap-canusb-linux.c?

> 2. Enhance the PDU that contain the current CAN frames to be able to
> transport CAN FD frames too. This kind of tunnelling from libpcap to
> Wireshark is currently done with the CANFD_USE bit - and that's why this bit
> must not show up in the Wiresharks proto bits.

"Currently" presumably meaning "with your changes to pcap-can-linux.c".

CANFD_USE is defined to be 0x04, which, in the CAN ID/flags field, is one of
the CAN ID bits; is that bit guaranteed not to be set in the CAN ID?

> As you can see from our patches option 2 is obviously easy to do.
> But is it the right way to go?


You are receiving this mail because:
  • You are watching all bug changes.