scapy.layers.can

A minimal implementation of the CANopen protocol, based on Wireshark dissectors. See https://wiki.wireshark.org/CANopen

class scapy.layers.can.BEFloatSignalField(name, default, start, scaling=1, unit='', offset=0, ndigits=3)[source]

Bases: scapy.fields._ScalingField, scapy.fields.Field[Union[int, float], Union[int, float]]

class scapy.layers.can.BESignedSignalField(name, default, start, size, scaling=1, unit='', offset=0, ndigits=3)[source]

Bases: scapy.fields._ScalingField, scapy.fields.Field[Union[int, float], Union[int, float]]

class scapy.layers.can.BEUnsignedSignalField(name, default, start, size, scaling=1, unit='', offset=0, ndigits=3)[source]

Bases: scapy.fields._ScalingField, scapy.fields.Field[Union[int, float], Union[int, float]]

class scapy.layers.can.CAN(*args, **kargs)[source]

Bases: scapy.base_classes.Gen[scapy.packet.Packet]

A implementation of CAN messages.

Dissection of CAN messages from Wireshark captures and Linux PF_CAN sockets are supported from protocol specification. See https://wiki.wireshark.org/CANopen for further information on the Wireshark dissector. Linux PF_CAN and Wireshark use different endianness for the first 32 bit of a CAN message. This dissector can be configured for both use cases.

Configuration swap-bytes:
Wireshark dissection:
>>> conf.contribs['CAN']['swap-bytes'] = False
PF_CAN Socket dissection:
>>> conf.contribs['CAN']['swap-bytes'] = True

Configuration remove-padding: Linux PF_CAN Sockets always return 16 bytes per CAN frame receive. This implicates that CAN frames get padded from the Linux PF_CAN socket with zeros up to 8 bytes of data. The real length from the CAN frame on the wire is given by the length field. To obtain only the CAN frame from the wire, this additional padding has to be removed. Nevertheless, for corner cases, it might be useful to also get the padding. This can be configuered through the remove-padding configuration.

Truncate CAN frame based on length field:
>>> conf.contribs['CAN']['remove-padding'] = True
Show entire CAN frame received from socket:
>>> conf.contribs['CAN']['remove-padding'] = False
aliastypes
extract_padding(p)[source]
fields_desc
Display RFC-like schema
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|FLAGS|                        IDENTIFIER                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     LENGTH    |                    RESERVED                   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               |              DATA             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                             Fig. CAN                             
CAN fields

flags

FlagsField

<Flag 0 ()>

identifier

XBitField (29 bits)

0

length

FieldLenField

None

reserved

ThreeBytesField

0

data

StrLenField

b''

static inv_endianness(pkt)[source]

Invert the order of the first four bytes of a CAN packet

This method is meant to be used specifically to convert a CAN packet between the pcap format and the SocketCAN format

Parameters

pkt – bytes str of the CAN packet

Returns

bytes str with the first four bytes swapped

post_build(pkt, pay)[source]

Implements the swap-bytes functionality for Packet build.

This is based on a copy of the Packet.self_build default method. The goal is to affect only the CAN layer data and keep under layers (e.g LinuxCooked) unchanged

post_dissect(s)[source]
pre_dissect(s)[source]

Implements the swap-bytes functionality when dissecting

class scapy.layers.can.CandumpReader(filename, interface=None)[source]

Bases: object

A stateful candump reader. Each packet is returned as a CAN packet.

Creates a CandumpReader object

Parameters
  • filename – filename of a candump logfile, compressed or uncompressed, or a already opened file object.

  • interface – Name of a interface, if candump contains messages of multiple interfaces and only one messages from a specific interface are wanted.

close()[source]

Emulation of SuperSocket

dispatch(callback)[source]

Call the specified callback routine for each packet read

This is just a convenience function for the main loop that allows for easy launching of packet processing in a thread.

fileno()[source]

Emulation of SuperSocket

next()[source]

Implements the iterator protocol on a set of packets

Returns

Next readable CAN Packet from the specified file

nonblocking_socket = True
static open(filename)[source]

Open function to handle three types of input data.

If filename of a regular candump log file is provided, this function opens the file and returns the file object. If filename of a gzip compressed candump log file is provided, the required gzip open function is used to obtain the necessary file object, which gets returned. If a fileobject or ByteIO is provided, the filename is gathered for internal use. No further steps are performed on this object.

Parameters

filename – Can be a string, specifying a candump log file or a gzip compressed candump log file. Also already opened file objects are allowed.

Returns

A opened file object for further use.

read_all(count=- 1)[source]

Read a specific number or all packets from a candump file.

Parameters

count – Specify a specific number of packets to be read. All packets can be read by count=-1.

Returns

A PacketList object containing read CAN messages

read_packet(size=16)[source]

Read a packet from the specified file.

This function will raise EOFError when no more packets are available.

Parameters

size – Not used. Just here to follow the function signature for SuperSocket emulation.

Returns

A single packet read from the file or None if filters apply

recv(size=16)[source]

Emulation of SuperSocket

static select(sockets, remain=None)[source]

Emulation of SuperSocket

class scapy.layers.can.LEFloatSignalField(name, default, start, scaling=1, unit='', offset=0, ndigits=3)[source]

Bases: scapy.fields._ScalingField, scapy.fields.Field[Union[int, float], Union[int, float]]

class scapy.layers.can.LESignedSignalField(name, default, start, size, scaling=1, unit='', offset=0, ndigits=3)[source]

Bases: scapy.fields._ScalingField, scapy.fields.Field[Union[int, float], Union[int, float]]

class scapy.layers.can.LEUnsignedSignalField(name, default, start, size, scaling=1, unit='', offset=0, ndigits=3)[source]

Bases: scapy.fields._ScalingField, scapy.fields.Field[Union[int, float], Union[int, float]]

class scapy.layers.can.SignalField(name, default, start, size, scaling=1, unit='', offset=0, ndigits=3, fmt='B')[source]

Bases: scapy.fields._ScalingField, scapy.fields.Field[Union[int, float], Union[int, float]]

SignalField is a base class for signal data, usually transmitted from CAN messages in automotive applications. Most vehicle manufacturers describe their vehicle internal signals by so called data base CAN (DBC) files. All necessary functions to easily create Scapy dissectors similar to signal descriptions from DBC files are provided by this base class.

SignalField instances should only be used together with SignalPacket classes since SignalPackets enforce length checks for CAN messages.

addfield(pkt, s, val)[source]
getfield(pkt, s)[source]
i2len(pkt, x)[source]
randval()[source]
size
start
class scapy.layers.can.SignalHeader(*args, **kargs)[source]

Bases: scapy.base_classes.Gen[scapy.packet.Packet]

Special implementation of a CAN Packet to allow dynamic binding.

This class can be provided to CANSockets as basecls.

Example

>>> class floatSignals(SignalPacket):
>>>     fields_desc = [
>>>         LEFloatSignalField("floatSignal2", default=0, start=32),
>>>         BEFloatSignalField("floatSignal1", default=0, start=7)]
>>>
>>> bind_layers(SignalHeader, floatSignals, identifier=0x321)
>>>
>>> dbc_sock = CANSocket("can0", basecls=SignalHeader)

All CAN messages received from this dbc_sock CANSocket will be interpreted as SignalHeader. Through Scapys bind_layers mechanism, all CAN messages with CAN identifier 0x321 will interpret the payload bytes of these CAN messages as floatSignals packet.

aliastypes
extract_padding(s)[source]
fields_desc
Display RFC-like schema
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|FLAGS|                        IDENTIFIER                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     LENGTH    |                    RESERVED                   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               |
+-+-+-+-+-+-+-+-+

                        Fig. SignalHeader                         
SignalHeader fields

flags

FlagsField

<Flag 0 ()>

identifier

XBitField (29 bits)

0

length

LenField

None

reserved

ThreeBytesField

0

class scapy.layers.can.SignalPacket(*args, **kargs)[source]

Bases: scapy.base_classes.Gen[scapy.packet.Packet]

Special implementation of Packet.

This class enforces the correct wirelen of a CAN message for signal transmitting in automotive applications. Furthermore, the dissection order of SignalFields in fields_desc is deduced by the start index of a field.

aliastypes
post_dissect(s)[source]

SignalFields can be dissected on packets with unordered fields.

The order of SignalFields is defined from the start parameter. After a build, the consumed bytes of the length of all SignalFields have to be removed from the SignalPacket.

pre_dissect(s)[source]
scapy.layers.can.rdcandump(filename, count=- 1, interface=None)[source]

Read a candump log file and return a packet list.

Parameters
  • filename – Filename of the file to read from. Also gzip files are accepted.

  • count – Read only <count> packets. Specify -1 to read all packets.

  • interface – Return only packets from a specified interface

Returns

A PacketList object containing the read files