Skip to content

Commit 9d928eb

Browse files
committed
pflog: byte swap UID and PID headers if necessary.
While we're at it, update comments - pcap files have a link-layer type, but pcapng files don't.
1 parent 3cd5b91 commit 9d928eb

File tree

1 file changed

+77
-7
lines changed

1 file changed

+77
-7
lines changed

pcap-common.c

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#include "pcap/nflog.h"
3535
#include "pcap/can_socketcan.h"
3636

37+
#include "pflog.h"
38+
3739
#include "pcap-common.h"
3840

3941
/*
@@ -1428,12 +1430,76 @@ max_snaplen_for_dlt(int dlt)
14281430
}
14291431
}
14301432

1433+
/*
1434+
* Most versions of the DLT_PFLOG pseudo-header have UID and PID fields
1435+
* that are saved in host byte order.
1436+
*
1437+
* When reading a DLT_PFLOG packet, we need to convert those fields from
1438+
* the byte order of the host that wrote the file to this host's byte
1439+
* order.
1440+
*/
1441+
static void
1442+
swap_pflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
1443+
{
1444+
u_int caplen = hdr->caplen;
1445+
u_int length = hdr->len;
1446+
u_int pfloghdr_length;
1447+
struct pfloghdr *pflhdr = (struct pfloghdr *)buf;
1448+
1449+
if (caplen < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid) ||
1450+
length < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid)) {
1451+
/* Not enough data to have the uid field */
1452+
return;
1453+
}
1454+
1455+
pfloghdr_length = pflhdr->length;
1456+
1457+
if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid)) {
1458+
/* Header doesn't include uid field */
1459+
return;
1460+
}
1461+
pflhdr->uid = SWAPLONG(pflhdr->uid);
1462+
1463+
if (caplen < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid) ||
1464+
length < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid)) {
1465+
/* Not enough data to have the pid field */
1466+
return;
1467+
}
1468+
if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid)) {
1469+
/* Header doesn't include pid field */
1470+
return;
1471+
}
1472+
pflhdr->pid = SWAPLONG(pflhdr->pid);
1473+
1474+
if (caplen < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid) ||
1475+
length < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid)) {
1476+
/* Not enough data to have the rule_uid field */
1477+
return;
1478+
}
1479+
if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid)) {
1480+
/* Header doesn't include rule_uid field */
1481+
return;
1482+
}
1483+
pflhdr->rule_uid = SWAPLONG(pflhdr->rule_uid);
1484+
1485+
if (caplen < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid) ||
1486+
length < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid)) {
1487+
/* Not enough data to have the rule_pid field */
1488+
return;
1489+
}
1490+
if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid)) {
1491+
/* Header doesn't include rule_pid field */
1492+
return;
1493+
}
1494+
pflhdr->rule_pid = SWAPLONG(pflhdr->rule_pid);
1495+
}
1496+
14311497
/*
14321498
* DLT_LINUX_SLL packets with a protocol type of LINUX_SLL_P_CAN or
14331499
* LINUX_SLL_P_CANFD have SocketCAN headers in front of the payload,
14341500
* with the CAN ID being in host byte order.
14351501
*
1436-
* When reading a DLT_LINUX_SLL capture file, we need to check for those
1502+
* When reading a DLT_LINUX_SLL packet, we need to check for those
14371503
* packets and convert the CAN ID from the byte order of the host that
14381504
* wrote the file to this host's byte order.
14391505
*/
@@ -1473,9 +1539,9 @@ swap_linux_sll_header(const struct pcap_pkthdr *hdr, u_char *buf)
14731539
* byte order when capturing (it's supplied directly from a
14741540
* memory-mapped buffer shared by the kernel).
14751541
*
1476-
* When reading a DLT_USB_LINUX or DLT_USB_LINUX_MMAPPED capture file,
1477-
* we need to convert it from the byte order of the host that wrote
1478-
* the file to this host's byte order.
1542+
* When reading a DLT_USB_LINUX or DLT_USB_LINUX_MMAPPED packet, we
1543+
* need to convert it from the byte order of the host that wrote the
1544+
* file to this host's byte order.
14791545
*/
14801546
static void
14811547
swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
@@ -1623,9 +1689,9 @@ swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
16231689
* byte order but the values are either big-endian or are a raw byte
16241690
* sequence that's the same regardless of the host's byte order.
16251691
*
1626-
* When reading a DLT_NFLOG capture file, we need to convert the type
1627-
* and length values from the byte order of the host that wrote the
1628-
* file to the byte order of this host.
1692+
* When reading a DLT_NFLOG packet, we need to convert the type and
1693+
* length values from the byte order of the host that wrote the file
1694+
* to the byte order of this host.
16291695
*/
16301696
static void
16311697
swap_nflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
@@ -1693,6 +1759,10 @@ swap_pseudo_headers(int linktype, struct pcap_pkthdr *hdr, u_char *data)
16931759
*/
16941760
switch (linktype) {
16951761

1762+
case DLT_PFLOG:
1763+
swap_pflog_header(hdr, data);
1764+
break;
1765+
16961766
case DLT_LINUX_SLL:
16971767
swap_linux_sll_header(hdr, data);
16981768
break;

0 commit comments

Comments
 (0)