pflog: Modernize packet parsing

Enable ND_LONGJMP_FROM_TCHECK and remove a 'trunc' label.
Add MAX_PFLOG_HDRLEN and use it for a test.
Use ND_ICHECK_U() in length tests and add an 'invalid' label.

Don't check the truncation with ND_TCHECK_SIZE(hdr), because the
sizeof(hdr) depend on the OS. Use ND_TCHECK_LEN(hdr, hdrlen).
Increment ndo_ll_hdr_len only in non-truncation case.
This commit is contained in:
Francois-Xavier Le Bail 2024-02-16 16:49:02 +01:00 committed by fxlb
parent ac2471df39
commit 83afc68629

View File

@ -27,6 +27,7 @@
#include "netdissect-stdinc.h" #include "netdissect-stdinc.h"
#define ND_LONGJMP_FROM_TCHECK
#include "netdissect.h" #include "netdissect.h"
#include "extract.h" #include "extract.h"
#include "af.h" #include "af.h"
@ -80,6 +81,7 @@ struct pfloghdr {
nd_uint16_t dport; nd_uint16_t dport;
#endif #endif
}; };
#define MAX_PFLOG_HDRLEN 100 /* 61 + 3 + 16 + 16 + 2 + 2 */
/* /*
* Reason values. * Reason values.
@ -252,29 +254,17 @@ pflog_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
ndo->ndo_protocol = "pflog"; ndo->ndo_protocol = "pflog";
/* check length */ /* check length */
if (caplen < sizeof(uint8_t)) { ND_ICHECK_U(length, <, MIN_PFLOG_HDRLEN);
nd_print_trunc(ndo);
ndo->ndo_ll_hdr_len += h->caplen;
return;
}
hdr = (const struct pfloghdr *)p; hdr = (const struct pfloghdr *)p;
hdrlen = GET_U_1(hdr->length); hdrlen = GET_U_1(hdr->length);
if (hdrlen < MIN_PFLOG_HDRLEN) { ND_ICHECK_U(hdrlen, <, MIN_PFLOG_HDRLEN);
ND_PRINT("[pflog: invalid header length!]");
ndo->ndo_ll_hdr_len += hdrlen; /* XXX: not really */
return;
}
hdrlen = roundup2(hdrlen, 4); hdrlen = roundup2(hdrlen, 4);
ND_ICHECK_U(hdrlen, >, MAX_PFLOG_HDRLEN);
if (caplen < hdrlen) {
nd_print_trunc(ndo);
ndo->ndo_ll_hdr_len += hdrlen; /* XXX: true? */
return;
}
/* print what we know */ /* print what we know */
ND_TCHECK_SIZE(hdr); ND_TCHECK_LEN(hdr, hdrlen);
ndo->ndo_ll_hdr_len += hdrlen;
if (ndo->ndo_eflag) if (ndo->ndo_eflag)
pflog_print(ndo, hdr); pflog_print(ndo, hdr);
@ -314,9 +304,8 @@ pflog_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
ND_DEFAULTPRINT(p, caplen); ND_DEFAULTPRINT(p, caplen);
} }
ndo->ndo_ll_hdr_len += hdrlen;
return; return;
trunc:
nd_print_trunc(ndo); invalid:
ndo->ndo_ll_hdr_len += hdrlen; nd_print_invalid(ndo);
} }