SocketCAN#
Linux SocketCAN is a set of open-source CAN drivers and a networking stack for Linux. It provides a standard socket interface for userspace applications to interact with the CAN bus, and it is based on the Berkeley socket API. SocketCAN supports multiple CAN controllers and is designed to be compatible with the CAN protocol standard ISO 11898.
The SocketCAN architecture is divided into two parts:
The CAN protocol stack, which runs in kernel space and provides low-level CAN communication, and the socket interface, which runs in user space and provides high-level communication to the applications. The CAN protocol stack is responsible for receiving and transmitting CAN frames, handling errors, and filtering incoming traffic.
The socket interface provides the userspace application with a simple way to interact with the CAN bus, by using standard socket calls such as
bind()
,send()
, andrecv()
.
The SocketCAN also provides a set of utilities for managing and configuring the CAN interfaces, such as can-utils. These utilities allow performing common tasks such as creating and deleting interfaces, setting the bitrate, sending and receiving CAN messages, and viewing the statistics of the interfaces.
Summary
Linux way of using CAN interfaces
Reuses network queues for CAN
SocketCAN provides multi-user access to a shared CAN interface
Part of Linux mainline. Implemented by Oliver Hartkopp [Har11].
Offers Linux sockets to user applications
Provides different socket types:
CAN_RAW
,CAN_BCM
,CAN_ISOTP
CAN_RAW:
Socket for CAN communication.CAN_BCM:
Broadcast-Manager for CAN. Allows to send periodic messages.CAN_ISOTP:
Transport-Layersocket for ISOTP communication. Entire protocol handling is done in kernel space.
Interfaces#
canX:
Real CAN-Interfaces connected to the system.vcanX:
Virtual CAN-Interfaces. Great for testing. Require thevcan
kernel module.slcanX:
Serial Line CAN-Interfaces. Socket wrapper for serial-to-CAN interfaces, supporting the slcan protocol. A/dev/tty
device is turned into a CAN socket.vxcan
Virtual CAN tunnel across network namespaces, used for forwarding traffic to a container.
SocketCAN setup#
All examples use can0
as interface name!
Get interface status
ip a
8: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN \
group default qlen 10
link/can
Increase TX queue (useful on ISOTP communication)
sudo ip link set can0 txqueuelen 4000
Bring up CAN interface and specify baudrate
sudo ip link set dev can0 up type can bitrate 500000
Et voilà
ip a
8: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc \
pfifo_fast state UP group default qlen 4000
link/can
SocketCAN usage from C#
/* Create the socket */
int skt = socket( PF_CAN, SOCK_RAW, CAN_RAW );
/* Locate the interface you wish to use */
struct ifreq ifr;
strcpy(ifr.ifr_name, "can0");
ioctl(skt, SIOCGIFINDEX, &ifr);
/* ifr.ifr_ifindex gets filled
* with that device's index */
/* Select that CAN interface, and bind the socket to it. */
struct sockaddr_can addr;
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
bind( skt, (struct sockaddr*)&addr, sizeof(addr) );
/* Send a message to the CAN bus */
struct can_frame frame;
frame.can_id = 0x123;
strcpy( (char *)frame.data, "foo" );
frame.can_dlc = strlen( (const char *)frame.data );
int bytes_sent = write( skt, &frame, sizeof(frame) );
/* Read a message back from the CAN bus */
int bytes_read = read( skt, &frame, sizeof(frame) );
Filters#
CAN filters consist of an identifier (FILTER-ID) and a mask.
Filtering
(CAN-ID & MASK) == (FILTER-ID & MASK)
Inverted Filtering (Blocking)
(CAN-ID & MASK) != (FILTER-ID & MASK)
can-utils#
Userspace utilities for Linux CAN subsystem (aka SocketCAN)
Installation on Debian-based systems
sudo apt-get install can-utils
Available on Github: linux-can/can-utils.git
candump#
All examples use can0
as the interface name!
Dump all messages to
stdout
candump can0
Dump all messages to a log file
candump can0 -l
Dump with a CAN filter
candump can0,0x123:0x7FF
Dump with a CAN an inverted filter
candump can0,0x123~0x7FF
cansend#
All examples use can0
as the interface name!
Send a CAN message
cansend can0 123#aabb112233445566
Send a CAN message with an extended CAN identifier
cansend can0 1ff46623#aabb112233445566
Further utilities#
cangen:
Generates random CAN traffic (Can be used for fuzzing)cangw:
Creates gateway between CAN networkscanplayer:
Replays a candump log filecansniffer:
Similar to candump but with more options and highlighting of changescanbusload:
Show utilization of CAN buses… and some more …
Also interesting
socketcand:
Socketcand is a daemon that provides access to CAN interfaces on a machine via a network interface.canneloni:
A SocketCAN over Ethernet tunnel GitHub - cannelloni