pcap/pcapng: byte-swap the CAN ID field in CAN pseudo-headers for SLL2.

As for LINUX_SLL, so for LINUX_SLL2.
This commit is contained in:
Guy Harris 2022-02-20 10:38:55 -08:00
parent b5d74c69a7
commit c7f84156c0
1 changed files with 52 additions and 1 deletions

View File

@ -1918,11 +1918,14 @@ struct can_socketcan_hdr {
};
/*
* The fake link-layer header of Linux cooked packets.
* CAN fake link-layer headers in Linux cooked packets.
*/
#define LINUX_SLL_PROTOCOL_OFFSET 14 /* protocol */
#define LINUX_SLL_LEN 16 /* length of the header */
#define LINUX_SLL2_PROTOCOL_OFFSET 0 /* protocol */
#define LINUX_SLL2_LEN 20 /* length of the header */
/*
* The protocols we have to check for.
*/
@ -1972,6 +1975,49 @@ pcap_byteswap_linux_sll_pseudoheader(wtap_rec *rec, guint8 *pd)
PBSWAP32((guint8 *)&can_socketcan_phdr->can_id);
}
static void
pcap_byteswap_linux_sll2_pseudoheader(wtap_rec *rec, guint8 *pd)
{
guint packet_size;
guint16 protocol;
struct can_socketcan_hdr *can_socketcan_phdr;
/*
* Minimum of captured and actual length (just in case the
* actual length < the captured length, which Should Never
* Happen).
*/
packet_size = rec->rec_header.packet_header.caplen;
if (packet_size > rec->rec_header.packet_header.len)
packet_size = rec->rec_header.packet_header.len;
if (packet_size < LINUX_SLL2_LEN) {
/* Not enough data to have the protocol */
return;
}
protocol = pntoh16(&pd[LINUX_SLL2_PROTOCOL_OFFSET]);
if (protocol != LINUX_SLL_P_CAN && protocol != LINUX_SLL_P_CANFD) {
/* Not a CAN packet; nothing to fix */
return;
}
/*
* Greasy hack, but we never directly dereference any of
* the fields in *can_socketcan_phdr, we just get offsets
* of and addresses of its members and byte-swap it with a
* byte-at-a-time macro, so it's alignment-safe.
*/
can_socketcan_phdr = (struct can_socketcan_hdr *)(void *)(pd + LINUX_SLL2_LEN);
if (packet_size < LINUX_SLL2_LEN + sizeof(can_socketcan_phdr->can_id)) {
/* Not enough data to have the full CAN ID */
return;
}
PBSWAP32((guint8 *)&can_socketcan_phdr->can_id);
}
static void
pcap_byteswap_linux_usb_pseudoheader(wtap_rec *rec, guint8 *pd,
gboolean header_len_64_bytes)
@ -2373,6 +2419,11 @@ pcap_read_post_process(gboolean is_nokia, int wtap_encap,
pcap_byteswap_linux_sll_pseudoheader(rec, pd);
break;
case WTAP_ENCAP_SLL2:
if (bytes_swapped)
pcap_byteswap_linux_sll2_pseudoheader(rec, pd);
break;
case WTAP_ENCAP_USB_LINUX:
if (bytes_swapped)
pcap_byteswap_linux_usb_pseudoheader(rec, pd, FALSE);