|
34 | 34 | #include "pcap/nflog.h" |
35 | 35 | #include "pcap/can_socketcan.h" |
36 | 36 |
|
| 37 | +#include "pflog.h" |
| 38 | + |
37 | 39 | #include "pcap-common.h" |
38 | 40 |
|
39 | 41 | /* |
@@ -1428,12 +1430,76 @@ max_snaplen_for_dlt(int dlt) |
1428 | 1430 | } |
1429 | 1431 | } |
1430 | 1432 |
|
| 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 | + |
1431 | 1497 | /* |
1432 | 1498 | * DLT_LINUX_SLL packets with a protocol type of LINUX_SLL_P_CAN or |
1433 | 1499 | * LINUX_SLL_P_CANFD have SocketCAN headers in front of the payload, |
1434 | 1500 | * with the CAN ID being in host byte order. |
1435 | 1501 | * |
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 |
1437 | 1503 | * packets and convert the CAN ID from the byte order of the host that |
1438 | 1504 | * wrote the file to this host's byte order. |
1439 | 1505 | */ |
@@ -1473,9 +1539,9 @@ swap_linux_sll_header(const struct pcap_pkthdr *hdr, u_char *buf) |
1473 | 1539 | * byte order when capturing (it's supplied directly from a |
1474 | 1540 | * memory-mapped buffer shared by the kernel). |
1475 | 1541 | * |
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. |
1479 | 1545 | */ |
1480 | 1546 | static void |
1481 | 1547 | 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, |
1623 | 1689 | * byte order but the values are either big-endian or are a raw byte |
1624 | 1690 | * sequence that's the same regardless of the host's byte order. |
1625 | 1691 | * |
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. |
1629 | 1695 | */ |
1630 | 1696 | static void |
1631 | 1697 | 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) |
1693 | 1759 | */ |
1694 | 1760 | switch (linktype) { |
1695 | 1761 |
|
| 1762 | + case DLT_PFLOG: |
| 1763 | + swap_pflog_header(hdr, data); |
| 1764 | + break; |
| 1765 | + |
1696 | 1766 | case DLT_LINUX_SLL: |
1697 | 1767 | swap_linux_sll_header(hdr, data); |
1698 | 1768 | break; |
|
0 commit comments