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

Date: Sun, 21 Aug 2016 11:46:24 +0000

Comment # 39 on bug 12687 from
(In reply to Guy Harris from comment #35)
> (In reply to Oliver Hartkopp from comment #32)

> > 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.

Which is a weak characteristic!

CAN and CAN FD interfaces are ARPHRD_CAN interfaces which may have any kind of
device names! E.g. control_can, chassis, powertrain, whatever ...

> > 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.

Right. The struct can[fd]_frame is placed in skb->data of the skbuff structure
inside the kernel. There's no MAC nor (IP-)address field which is used by CAN
skbuffs. 

The access with PF_PACKET sockets is described at the end of this comment:

https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=12687#c8

As you can see the CAN ID is always in host byte order as the CAN driver
creates this value based on the register content of the CAN controller.
So struct can[fd]_frame is always completely in host byte order.

> 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,

You can not rely on this naming scheme.

> 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.

YES YES YES :-)

The only advantage of using PF_CAN sockets is that you would have the IFF_ECHO
functionality that sends back sent frames into Linux to get a correct
representation of the CAN traffic on the wire. PF_CAN can do this IFF_ECHO
stuff when the CAN driver does not support this functionality (very few drivers
lack IFF_ECHO support). But this is only relevant when *sending* CAN frames.
For sniffing PF_PACKET is a perfect choice.

> 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.

This looks like 'the right way' to go, IMO.

> 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.

CAN: 0-8 bytes of data, 11/29 bit identifier, RTR capability
CAN FD: 0-64 bytes of data, 11/29 bit identifier, no RTR capability, but BRS
and ESI flags

> 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?

As described in https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=12687#c38
this is a special USB hardware that has nothing to do with SocketCAN / Linux
CAN networking.

See libpcap commit
https://github.com/the-tcpdump-group/libpcap/commit/f3edbb599b8cbcc7e4560000dcba8e992dc11a31

The best solution would be to provide a proper Linux mainline driver for this
single USB device and finally remove this file.

> > 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?

It's not set in the CAN ID field but in the flags field of the struct
canfd_frame. CANFD_USE would be an indicator which is set by user space
applications (e.g. libpcap) - it is nothing which is provided by the CAN
network interface.

When we can properly implement two paths for ETH_P_CAN and ETH_P_CANFD by using
PF_PACKET sockets with bound CAN interfaces (ARPHRD_CAN) this 'hack' would
become obsolete.


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