Skip to content

Commit

Permalink
socketcan: put the first field of a CAN XL header in big-endian order.
Browse files Browse the repository at this point in the history
Old CAN XL-unaware versions of libpcap did so, as they thought it was
the CAN ID field.  So that readers of LINKTYPE_CAN_SOCKETCAN files can
handle those captures and fixed captures, we make that field big-endian.
We continue to make the other two multi-byte fields of the CAN XL header
little-endian, as those old versions of libpcap didn't change tham, and
most if not all CAN XL captures were done on little-endian platforms.

(cherry picked from commit eb6cfd8)
  • Loading branch information
guyharris committed Feb 12, 2024
1 parent 5afb02f commit 23904eb
Showing 1 changed file with 35 additions and 26 deletions.
61 changes: 35 additions & 26 deletions pcap-linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -4045,43 +4045,52 @@ static int pcap_handle_packet_mmap(
* This is a CAN XL frame.
*
* DLT_CAN_SOCKETCAN is specified as having
* the Priority ID, payload length, and
* Acceptance Field in little-endian byte
* order, but capturing on a CAN device
* the Priority ID/VCID field in big--
* endian byte order, and the payload length
* and Acceptance Field in little-endian byte
* order. but capturing on a CAN device
* provides them in host byte order.
* Convert them to little-endian byte order.
* Convert them to the appropriate byte
* orders.
*
* The reason we put the first field
* into big-endian byte order is that
* older libpcap code, ignorant of
* CAN XL, treated it as the CAN ID
* field and put it into big-endian
* byte order, and we don't want to
* break code that understands CAN XL
* headers, and treats that field as
* being big-endian.
*
* In addition, the first field of the
* header is currently a 32-bit value,
* the lower 11 bits of which are a
* priority value, but there's a patch
* pending to add a VCID field in the
* upper 16 bits of the 32-bit value.
* So, on a little-endian machine, the
* first 16 bits would be the priority
* and the next 16 bits would be the
* VCID, and, on a big-endian machine,
* the first 16 bits would be the VCID
* and the next 16 bits would be the
* priority.
* The other fields are put in little-
* endian byte order is that older
* libpcap code, ignorant of CAN XL,
* left those fields alone, and the
* processors on which the CAN XL
* frames were captured are likely
* to be little-endian processors.
*/
pcap_can_socketcan_xl_hdr *canxl_hdr = (pcap_can_socketcan_xl_hdr *)bp;

#if __BYTE_ORDER == __LITTLE_ENDIAN
/*
* We're capturing on a little-endian
* machine, so the header is already
* in the correct format.
* machine, so we put the priority/VCID
* field into big-endian byte order, and
* leave the payload length and acceptance
* field in little-endian byte order.
*/
/* Byte-swap priority/VCID. */
canxl_hdr->priority_vcid = SWAPLONG(canxl_hdr->priority_vcid);
#elif __BYTE_ORDER == __BIG_ENDIAN
/*
* We're capturing on a big-endian
* machine, so we want to swap all
* multi-byte values to little-endian.
* machine, so we want to leave the
* priority/VCID field alone, and byte-swap
* the payload length and acceptance
* fields to little-endian.
*/
pcap_can_socketcan_xl_hdr *canxl_hdr = (pcap_can_socketcan_xl_hdr *)bp;

/* Byte-swap priority/VCID. */
canxl_hdr->priority_vcid = SWAPLONG(canxl_hdr->priority_vcid);

/* Byte-swap the payload length */
canxl_hdr->payload_length = SWAPSHORT(canxl_hdr->payload_length);

Expand Down

0 comments on commit 23904eb

Please sign in to comment.