Skip to content

Commit 2757ddc

Browse files
committed
Improve handling of DLT_PFLOG when generating filter code.
Don't rely on the OS's pflog include files to give the pflog header length; instead, fetch it from the length field of the header, and round up to a multiple of 4. That way, it'll handle headers for OSes other than the one for which we're compiling code, and will handle different header lengths for any given OS if, for example, a new version of the OS adds more fields to the end. Don't rely on the OS's pflog include files to define direction types, reason types, action types, or the layout of the header; instead, define them ourselves in a header of our own, with #ifs to select the ones that are only on some platforms. That way, it'll handle some fields and field values (the ones common to all OSes with pflog) on all OSes, even ones without pflog. This should also clean up the FreeBSD build issues reported in #1074, as we no longer include <net/if_pflog.h>.
1 parent 1a09124 commit 2757ddc

File tree

7 files changed

+132
-249
lines changed

7 files changed

+132
-249
lines changed

CMakeLists.txt

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -382,25 +382,6 @@ if(NOT WIN32)
382382
check_include_file(sys/select.h HAVE_SYS_SELECT_H)
383383

384384
check_include_file(netpacket/packet.h HAVE_NETPACKET_PACKET_H)
385-
check_include_files("sys/types.h;sys/socket.h;net/if.h;net/pfvar.h" HAVE_NET_PFVAR_H)
386-
if(HAVE_NET_PFVAR_H)
387-
#
388-
# Check for various PF actions.
389-
#
390-
check_c_source_compiles(
391-
"#include <sys/types.h>
392-
#include <sys/socket.h>
393-
#include <net/if.h>
394-
#include <net/pfvar.h>
395-
396-
int
397-
main(void)
398-
{
399-
return PF_NAT+PF_NONAT+PF_BINAT+PF_NOBINAT+PF_RDR+PF_NORDR;
400-
}
401-
"
402-
HAVE_PF_NAT_THROUGH_PF_NORDR)
403-
endif(HAVE_NET_PFVAR_H)
404385
check_include_file(netinet/if_ether.h HAVE_NETINET_IF_ETHER_H)
405386
endif(NOT WIN32)
406387

Makefile.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ HDR = $(PUBHDR) \
149149
pcap-int.h \
150150
pcap-rpcap.h \
151151
pcap-types.h \
152+
pflog.h \
152153
portability.h \
153154
ppp.h \
154155
rpcap-protocol.h \

config.h.in

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,6 @@
132132
/* Define to 1 if you have the <net/pfilt.h> header file. */
133133
#undef HAVE_NET_PFILT_H
134134

135-
/* Define to 1 if you have the <net/pfvar.h> header file. */
136-
#undef HAVE_NET_PFVAR_H
137-
138135
/* Define to 1 if you have the <net/raw.h> header file. */
139136
#undef HAVE_NET_RAW_H
140137

@@ -144,9 +141,6 @@
144141
/* if there's an os_proto.h for this platform, to use additional prototypes */
145142
#undef HAVE_OS_PROTO_H
146143

147-
/* define if net/pfvar.h defines PF_NAT through PF_NORDR */
148-
#undef HAVE_PF_NAT_THROUGH_PF_NORDR
149-
150144
/* Define to 1 if you have a POSIX-style `strerror_r' function. */
151145
#undef HAVE_POSIX_STRERROR_R
152146

configure

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5285,55 +5285,6 @@ fi
52855285
52865286
done
52875287
5288-
for ac_header in net/pfvar.h
5289-
do :
5290-
ac_fn_c_check_header_compile "$LINENO" "net/pfvar.h" "ac_cv_header_net_pfvar_h" "#include <sys/types.h>
5291-
#include <sys/socket.h>
5292-
#include <net/if.h>
5293-
"
5294-
if test "x$ac_cv_header_net_pfvar_h" = xyes; then :
5295-
cat >>confdefs.h <<_ACEOF
5296-
#define HAVE_NET_PFVAR_H 1
5297-
_ACEOF
5298-
5299-
fi
5300-
5301-
done
5302-
5303-
if test "$ac_cv_header_net_pfvar_h" = yes; then
5304-
#
5305-
# Check for various PF actions.
5306-
#
5307-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether net/pfvar.h defines PF_NAT through PF_NORDR" >&5
5308-
$as_echo_n "checking whether net/pfvar.h defines PF_NAT through PF_NORDR... " >&6; }
5309-
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
5310-
/* end confdefs.h. */
5311-
#include <sys/types.h>
5312-
#include <sys/socket.h>
5313-
#include <net/if.h>
5314-
#include <net/pfvar.h>
5315-
int
5316-
main ()
5317-
{
5318-
return PF_NAT+PF_NONAT+PF_BINAT+PF_NOBINAT+PF_RDR+PF_NORDR;
5319-
;
5320-
return 0;
5321-
}
5322-
_ACEOF
5323-
if ac_fn_c_try_compile "$LINENO"; then :
5324-
5325-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
5326-
$as_echo "yes" >&6; }
5327-
5328-
$as_echo "#define HAVE_PF_NAT_THROUGH_PF_NORDR 1" >>confdefs.h
5329-
5330-
5331-
else
5332-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
5333-
$as_echo "no" >&6; }
5334-
fi
5335-
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
5336-
fi
53375288
53385289
case "$host_os" in
53395290
haiku*)

configure.ac

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -63,27 +63,6 @@ dnl "AC_LBL_FIXINCLUDES" wouldn't work on some platforms such as Solaris.
6363
dnl
6464
AC_CHECK_HEADERS(sys/ioccom.h sys/sockio.h)
6565
AC_CHECK_HEADERS(netpacket/packet.h)
66-
AC_CHECK_HEADERS(net/pfvar.h, , , [#include <sys/types.h>
67-
#include <sys/socket.h>
68-
#include <net/if.h>])
69-
if test "$ac_cv_header_net_pfvar_h" = yes; then
70-
#
71-
# Check for various PF actions.
72-
#
73-
AC_MSG_CHECKING(whether net/pfvar.h defines PF_NAT through PF_NORDR)
74-
AC_TRY_COMPILE(
75-
[#include <sys/types.h>
76-
#include <sys/socket.h>
77-
#include <net/if.h>
78-
#include <net/pfvar.h>],
79-
[return PF_NAT+PF_NONAT+PF_BINAT+PF_NOBINAT+PF_RDR+PF_NORDR;],
80-
[
81-
AC_MSG_RESULT(yes)
82-
AC_DEFINE(HAVE_PF_NAT_THROUGH_PF_NORDR, 1,
83-
[define if net/pfvar.h defines PF_NAT through PF_NORDR])
84-
],
85-
AC_MSG_RESULT(no))
86-
fi
8766

8867
case "$host_os" in
8968
haiku*)

gencode.c

Lines changed: 61 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -48,20 +48,6 @@
4848
#include "pcap-dos.h"
4949
#endif
5050

51-
#ifdef HAVE_NET_PFVAR_H
52-
/*
53-
* In NetBSD <net/if.h> includes <net/dlt.h>, which is an older version of
54-
* "pcap/dlt.h" with a lower value of DLT_MATCHING_MAX. Include the headers
55-
* below before "pcap-int.h", which eventually includes "pcap/dlt.h", which
56-
* redefines DLT_MATCHING_MAX from what this version of NetBSD has to what
57-
* this version of libpcap has.
58-
*/
59-
#include <sys/socket.h>
60-
#include <net/if.h>
61-
#include <net/pfvar.h>
62-
#include <net/if_pflog.h>
63-
#endif /* HAVE_NET_PFVAR_H */
64-
6551
#include "pcap-int.h"
6652

6753
#include "extract.h"
@@ -73,6 +59,7 @@
7359
#include "ieee80211.h"
7460
#include "atmuni31.h"
7561
#include "sunatmpos.h"
62+
#include "pflog.h"
7663
#include "ppp.h"
7764
#include "pcap/sll.h"
7865
#include "pcap/ipnet.h"
@@ -524,6 +511,7 @@ static inline struct block *gen_false(compiler_state_t *);
524511
static struct block *gen_ether_linktype(compiler_state_t *, bpf_u_int32);
525512
static struct block *gen_ipnet_linktype(compiler_state_t *, bpf_u_int32);
526513
static struct block *gen_linux_sll_linktype(compiler_state_t *, bpf_u_int32);
514+
static struct slist *gen_load_pflog_llprefixlen(compiler_state_t *);
527515
static struct slist *gen_load_prism_llprefixlen(compiler_state_t *);
528516
static struct slist *gen_load_avs_llprefixlen(compiler_state_t *);
529517
static struct slist *gen_load_radiotap_llprefixlen(compiler_state_t *);
@@ -1517,14 +1505,13 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
15171505
cstate->off_nl_nosnap = 0; /* XXX - what does it do with 802.3 packets? */
15181506
break;
15191507

1520-
#ifdef HAVE_NET_PFVAR_H
15211508
case DLT_PFLOG:
15221509
cstate->off_linktype.constant_part = 0;
1523-
cstate->off_linkpl.constant_part = PFLOG_HDRLEN;
1510+
cstate->off_linkpl.constant_part = 0; /* link-layer header is variable-length */
1511+
cstate->off_linkpl.is_variable = 1;
15241512
cstate->off_nl = 0;
15251513
cstate->off_nl_nosnap = 0; /* no 802.2 LLC */
15261514
break;
1527-
#endif
15281515

15291516
case DLT_JUNIPER_MFR:
15301517
case DLT_JUNIPER_MLFR:
@@ -2349,6 +2336,59 @@ gen_linux_sll_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto)
23492336
}
23502337
}
23512338

2339+
/*
2340+
* Load a value relative to the beginning of the link-layer header after the
2341+
* pflog header.
2342+
*/
2343+
static struct slist *
2344+
gen_load_pflog_llprefixlen(compiler_state_t *cstate)
2345+
{
2346+
struct slist *s1, *s2;
2347+
2348+
/*
2349+
* Generate code to load the length of the pflog header into
2350+
* the register assigned to hold that length, if one has been
2351+
* assigned. (If one hasn't been assigned, no code we've
2352+
* generated uses that prefix, so we don't need to generate any
2353+
* code to load it.)
2354+
*/
2355+
if (cstate->off_linkpl.reg != -1) {
2356+
/*
2357+
* The length is in the first byte of the header.
2358+
*/
2359+
s1 = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS);
2360+
s1->s.k = 0;
2361+
2362+
/*
2363+
* Round it up to a multiple of 4.
2364+
* Add 3, and clear the lower 2 bits.
2365+
*/
2366+
s2 = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_K);
2367+
s2->s.k = 3;
2368+
sappend(s1, s2);
2369+
s2 = new_stmt(cstate, BPF_ALU|BPF_AND|BPF_K);
2370+
s2->s.k = 0xfffffffe;
2371+
sappend(s1, s2);
2372+
2373+
/*
2374+
* Now allocate a register to hold that value and store
2375+
* it.
2376+
*/
2377+
s2 = new_stmt(cstate, BPF_ST);
2378+
s2->s.k = cstate->off_linkpl.reg;
2379+
sappend(s1, s2);
2380+
2381+
/*
2382+
* Now move it into the X register.
2383+
*/
2384+
s2 = new_stmt(cstate, BPF_MISC|BPF_TAX);
2385+
sappend(s1, s2);
2386+
2387+
return (s1);
2388+
} else
2389+
return (NULL);
2390+
}
2391+
23522392
static struct slist *
23532393
gen_load_prism_llprefixlen(compiler_state_t *cstate)
23542394
{
@@ -2936,6 +2976,10 @@ insert_compute_vloffsets(compiler_state_t *cstate, struct block *b)
29362976
case DLT_PPI:
29372977
s = gen_load_802_11_header_len(cstate, s, b->stmts);
29382978
break;
2979+
2980+
case DLT_PFLOG:
2981+
s = gen_load_pflog_llprefixlen(cstate);
2982+
break;
29392983
}
29402984

29412985
/*
@@ -3401,7 +3445,6 @@ gen_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto)
34013445
return gen_false(cstate);
34023446
}
34033447

3404-
#ifdef HAVE_NET_PFVAR_H
34053448
case DLT_PFLOG:
34063449
/*
34073450
* af field is host byte order in contrast to the rest of
@@ -3416,7 +3459,6 @@ gen_linktype(compiler_state_t *cstate, bpf_u_int32 ll_proto)
34163459
else
34173460
return gen_false(cstate);
34183461
/*NOTREACHED*/
3419-
#endif /* HAVE_NET_PFVAR_H */
34203462

34213463
case DLT_ARCNET:
34223464
case DLT_ARCNET_LINUX:
@@ -8307,12 +8349,10 @@ gen_inbound(compiler_state_t *cstate, int dir)
83078349
}
83088350
break;
83098351

8310-
#ifdef HAVE_NET_PFVAR_H
83118352
case DLT_PFLOG:
83128353
b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, dir), BPF_B,
83138354
((dir == 0) ? PF_IN : PF_OUT));
83148355
break;
8315-
#endif
83168356

83178357
case DLT_PPP_PPPD:
83188358
if (dir) {
@@ -8403,7 +8443,6 @@ gen_inbound(compiler_state_t *cstate, int dir)
84038443
return (b0);
84048444
}
84058445

8406-
#ifdef HAVE_NET_PFVAR_H
84078446
/* PF firewall log matched interface */
84088447
struct block *
84098448
gen_pf_ifname(compiler_state_t *cstate, const char *ifname)
@@ -8554,91 +8593,6 @@ gen_pf_action(compiler_state_t *cstate, int action)
85548593
(bpf_u_int32)action);
85558594
return (b0);
85568595
}
8557-
#else /* !HAVE_NET_PFVAR_H */
8558-
struct block *
8559-
gen_pf_ifname(compiler_state_t *cstate, const char *ifname _U_)
8560-
{
8561-
/*
8562-
* Catch errors reported by us and routines below us, and return NULL
8563-
* on an error.
8564-
*/
8565-
if (setjmp(cstate->top_ctx))
8566-
return (NULL);
8567-
8568-
bpf_error(cstate, "libpcap was compiled without pf support");
8569-
/*NOTREACHED*/
8570-
}
8571-
8572-
struct block *
8573-
gen_pf_ruleset(compiler_state_t *cstate, char *ruleset _U_)
8574-
{
8575-
/*
8576-
* Catch errors reported by us and routines below us, and return NULL
8577-
* on an error.
8578-
*/
8579-
if (setjmp(cstate->top_ctx))
8580-
return (NULL);
8581-
8582-
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
8583-
/*NOTREACHED*/
8584-
}
8585-
8586-
struct block *
8587-
gen_pf_rnr(compiler_state_t *cstate, int rnr _U_)
8588-
{
8589-
/*
8590-
* Catch errors reported by us and routines below us, and return NULL
8591-
* on an error.
8592-
*/
8593-
if (setjmp(cstate->top_ctx))
8594-
return (NULL);
8595-
8596-
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
8597-
/*NOTREACHED*/
8598-
}
8599-
8600-
struct block *
8601-
gen_pf_srnr(compiler_state_t *cstate, int srnr _U_)
8602-
{
8603-
/*
8604-
* Catch errors reported by us and routines below us, and return NULL
8605-
* on an error.
8606-
*/
8607-
if (setjmp(cstate->top_ctx))
8608-
return (NULL);
8609-
8610-
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
8611-
/*NOTREACHED*/
8612-
}
8613-
8614-
struct block *
8615-
gen_pf_reason(compiler_state_t *cstate, int reason _U_)
8616-
{
8617-
/*
8618-
* Catch errors reported by us and routines below us, and return NULL
8619-
* on an error.
8620-
*/
8621-
if (setjmp(cstate->top_ctx))
8622-
return (NULL);
8623-
8624-
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
8625-
/*NOTREACHED*/
8626-
}
8627-
8628-
struct block *
8629-
gen_pf_action(compiler_state_t *cstate, int action _U_)
8630-
{
8631-
/*
8632-
* Catch errors reported by us and routines below us, and return NULL
8633-
* on an error.
8634-
*/
8635-
if (setjmp(cstate->top_ctx))
8636-
return (NULL);
8637-
8638-
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
8639-
/*NOTREACHED*/
8640-
}
8641-
#endif /* HAVE_NET_PFVAR_H */
86428596

86438597
/* IEEE 802.11 wireless header */
86448598
struct block *

0 commit comments

Comments
 (0)