summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <gharris@sonic.net>2022-01-29 22:30:33 -0800
committerGuy Harris <gharris@sonic.net>2022-01-29 22:30:33 -0800
commitfe762c04a6d3bbf7f1a21ebf825075e2fb201acc (patch)
tree122a84015317023db03bf20ff91d2370eff0b1dd
parent65f4c88d27fa3a333b7f5303c34d8d10999e1d4d (diff)
downloadtcpdump-fe762c04a6d3bbf7f1a21ebf825075e2fb201acc.tar.gz
Handle DLT_PFLOG on all OSes.
Don't pad the pflog header with BPF_WORDALIGN(); round up to a multiple of 4, instead, as that's what all but FreeBSD do, and FreeBSD used to do that and should go back to doing so (kern/261566). 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. That also expands the set of direction, reason, and action codes to what various *BSDs and Darwin support. Also, handle all the different AF_INET6 values in various *BSDs and Darwin.
-rw-r--r--CMakeLists.txt10
-rw-r--r--Makefile.in2
-rw-r--r--cmakeconfig.h.in6
-rw-r--r--config.h.in6
-rwxr-xr-xconfigure36
-rw-r--r--configure.ac12
-rw-r--r--pflog.h157
-rw-r--r--print-pflog.c105
-rw-r--r--print.c2
9 files changed, 223 insertions, 113 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9de92bdf..5cd4024e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -275,15 +275,6 @@ check_include_file(net/if.h HAVE_NET_IF_H)
if(HAVE_RPC_RPC_H)
check_include_files("rpc/rpc.h;rpc/rpcent.h" HAVE_RPC_RPCENT_H)
endif(HAVE_RPC_RPC_H)
-if(NOT WIN32)
- check_include_files("sys/types.h;sys/socket.h;net/if.h;net/pfvar.h" HAVE_NET_PFVAR_H)
- if(HAVE_NET_PFVAR_H)
- check_include_files("sys/types.h;sys/socket.h;net/if.h;net/pfvar.h;net/if_pflog.h" HAVE_NET_IF_PFLOG_H)
- if(HAVE_NET_IF_PFLOG_H)
- set(LOCALSRC print-pflog.c ${LOCALSRC})
- endif(HAVE_NET_IF_PFLOG_H)
- endif(HAVE_NET_PFVAR_H)
-endif(NOT WIN32)
#
# Functions.
@@ -1093,6 +1084,7 @@ set(NETDISSECT_SOURCE_LIST_C
print-ospf.c
print-ospf6.c
print-otv.c
+ print-pflog.c
print-pgm.c
print-pim.c
print-pktap.c
diff --git a/Makefile.in b/Makefile.in
index 36122d5b..40fb1cfc 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -193,6 +193,7 @@ LIBNETDISSECT_SRC=\
print-ospf.c \
print-ospf6.c \
print-otv.c \
+ print-pflog.c \
print-pgm.c \
print-pim.c \
print-pktap.c \
@@ -307,6 +308,7 @@ HDR = \
ospf.h \
oui.h \
pcap-missing.h \
+ pflog.h \
ppp.h \
print.h \
rpc_auth.h \
diff --git a/cmakeconfig.h.in b/cmakeconfig.h.in
index 852d1517..370d3962 100644
--- a/cmakeconfig.h.in
+++ b/cmakeconfig.h.in
@@ -72,12 +72,6 @@
/* Define to 1 if you have the <net/if.h> header file. */
#cmakedefine HAVE_NET_IF_H 1
-/* Define to 1 if you have the <net/if_pflog.h> header file. */
-#cmakedefine HAVE_NET_IF_PFLOG_H 1
-
-/* Define to 1 if you have the <net/pfvar.h> header file. */
-#cmakedefine HAVE_NET_PFVAR_H 1
-
/* Define to 1 if you have the `openat' function. */
#cmakedefine HAVE_OPENAT 1
diff --git a/config.h.in b/config.h.in
index bb1a4f6a..2c64093b 100644
--- a/config.h.in
+++ b/config.h.in
@@ -75,12 +75,6 @@
/* Define to 1 if you have the <net/if.h> header file. */
#undef HAVE_NET_IF_H
-/* Define to 1 if you have the <net/if_pflog.h> header file. */
-#undef HAVE_NET_IF_PFLOG_H
-
-/* Define to 1 if you have the <net/pfvar.h> header file. */
-#undef HAVE_NET_PFVAR_H
-
/* Define to 1 if printf(3) does not support the z length modifier. */
#undef HAVE_NO_PRINTF_Z
diff --git a/configure b/configure
index 4e84a433..0308dafb 100755
--- a/configure
+++ b/configure
@@ -4183,42 +4183,6 @@ fi
done
-for ac_header in net/pfvar.h
-do :
- ac_fn_c_check_header_compile "$LINENO" "net/pfvar.h" "ac_cv_header_net_pfvar_h" "#include <sys/types.h>
-#include <sys/socket.h>
-#include <net/if.h>
-"
-if test "x$ac_cv_header_net_pfvar_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_NET_PFVAR_H 1
-_ACEOF
-
-fi
-
-done
-
-if test "$ac_cv_header_net_pfvar_h" = yes; then
- for ac_header in net/if_pflog.h
-do :
- ac_fn_c_check_header_compile "$LINENO" "net/if_pflog.h" "ac_cv_header_net_if_pflog_h" "#include <sys/types.h>
- #include <sys/socket.h>
- #include <net/if.h>
- #include <net/pfvar.h>
-"
-if test "x$ac_cv_header_net_if_pflog_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_NET_IF_PFLOG_H 1
-_ACEOF
-
-fi
-
-done
-
- if test "$ac_cv_header_net_if_pflog_h" = yes; then
- LOCALSRC="print-pflog.c $LOCALSRC"
- fi
-fi
case "$host_os" in
diff --git a/configure.ac b/configure.ac
index de00be56..0d9782f8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -32,18 +32,6 @@ AC_LBL_C_INIT(V_CCOPT, V_INCLS)
AC_LBL_C_INLINE
AC_CHECK_HEADERS(fcntl.h rpc/rpc.h rpc/rpcent.h net/if.h)
-AC_CHECK_HEADERS(net/pfvar.h, , , [#include <sys/types.h>
-#include <sys/socket.h>
-#include <net/if.h>])
-if test "$ac_cv_header_net_pfvar_h" = yes; then
- AC_CHECK_HEADERS(net/if_pflog.h, , , [#include <sys/types.h>
- #include <sys/socket.h>
- #include <net/if.h>
- #include <net/pfvar.h>])
- if test "$ac_cv_header_net_if_pflog_h" = yes; then
- LOCALSRC="print-pflog.c $LOCALSRC"
- fi
-fi
case "$host_os" in
diff --git a/pflog.h b/pflog.h
new file mode 100644
index 00000000..0d3f899b
--- /dev/null
+++ b/pflog.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * pflog headers, at least as they exist now.
+ */
+#define PFLOG_IFNAMSIZ 16
+#define PFLOG_RULESET_NAME_SIZE 16
+
+/*
+ * Direction values.
+ */
+#define PF_INOUT 0
+#define PF_IN 1
+#define PF_OUT 2
+#if defined(__OpenBSD__)
+#define PF_FWD 3
+#endif
+
+/*
+ * Reason values.
+ */
+#define PFRES_MATCH 0
+#define PFRES_BADOFF 1
+#define PFRES_FRAG 2
+#define PFRES_SHORT 3
+#define PFRES_NORM 4
+#define PFRES_MEMORY 5
+#define PFRES_TS 6
+#define PFRES_CONGEST 7
+#define PFRES_IPOPTIONS 8
+#define PFRES_PROTCKSUM 9
+#define PFRES_BADSTATE 10
+#define PFRES_STATEINS 11
+#define PFRES_MAXSTATES 12
+#define PFRES_SRCLIMIT 13
+#define PFRES_SYNPROXY 14
+#if defined(__FreeBSD__)
+#define PFRES_MAPFAILED 15
+#elif defined(__NetBSD__)
+#define PFRES_STATELOCKED 15
+#elif defined(__OpenBSD__)
+#define PFRES_TRANSLATE 15
+#define PFRES_NOROUTE 16
+#elif defined(__APPLE__)
+#define PFRES_DUMMYNET 15
+#endif
+
+/*
+ * Action vaues.
+ */
+#define PF_PASS 0
+#define PF_DROP 1
+#define PF_SCRUB 2
+#define PF_NOSCRUB 3
+#define PF_NAT 4
+#define PF_NONAT 5
+#define PF_BINAT 6
+#define PF_NOBINAT 7
+#define PF_RDR 8
+#define PF_NORDR 9
+#define PF_SYNPROXY_DROP 10
+#if defined(__FreeBSD__)
+#define PF_DEFER 11
+#elif defined(__OpenBSD__)
+#define PF_DEFER 11
+#define PF_MATCH 12
+#define PF_DIVERT 13
+#define PF_RT 14
+#define PF_AFRT 15
+#elif defined(__APPLE__)
+#define PF_DUMMYNET 11
+#define PF_NODUMMYNET 12
+#define PF_NAT64 13
+#define PF_NONAT64 14
+#endif
+
+struct pf_addr {
+ union {
+ struct in_addr v4;
+ struct in6_addr v6;
+ uint8_t addr8[16];
+ uint16_t addr16[8];
+ uint32_t addr32[4];
+ } pfa; /* 128-bit address */
+#define v4 pfa.v4
+#define v6 pfa.v6
+#define addr8 pfa.addr8
+#define addr16 pfa.addr16
+#define addr32 pfa.addr32
+};
+
+struct pfloghdr {
+ uint8_t length;
+ uint8_t af;
+ uint8_t action;
+ uint8_t reason;
+ char ifname[PFLOG_IFNAMSIZ];
+ char ruleset[PFLOG_RULESET_NAME_SIZE];
+ uint32_t rulenr;
+ uint32_t subrulenr;
+ uint32_t uid;
+ int32_t pid;
+ uint32_t rule_uid;
+ int32_t rule_pid;
+ uint8_t dir;
+#if defined(__OpenBSD__)
+ uint8_t rewritten;
+ uint8_t naf;
+ uint8_t pad[1];
+#else
+ uint8_t pad[3];
+#endif
+#if defined(__FreeBSD__)
+ uint32_t ridentifier;
+ uint8_t reserve;
+ uint8_t pad2[3];
+#elif defined(__OpenBSD__)
+ struct pf_addr saddr;
+ struct pf_addr daddr;
+ uint16_t sport;
+ uint16_t dport;
+#endif
+};
+
+
+
diff --git a/print-pflog.c b/print-pflog.c
index eb1b1766..05b9eb3a 100644
--- a/print-pflog.c
+++ b/print-pflog.c
@@ -19,43 +19,46 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-/* \summary: OpenBSD packet filter log file printer */
+/* \summary: *BSD/Darwin packet filter log file printer */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-#ifndef HAVE_NET_PFVAR_H
-#error "No pf headers available"
-#endif
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <net/pfvar.h>
-#include <net/if_pflog.h>
-
#include "netdissect-stdinc.h"
#include "netdissect.h"
#include "extract.h"
+#include "af.h"
+#include "pflog.h"
static const struct tok pf_reasons[] = {
- { 0, "0(match)" },
- { 1, "1(bad-offset)" },
- { 2, "2(fragment)" },
- { 3, "3(short)" },
- { 4, "4(normalize)" },
- { 5, "5(memory)" },
- { 6, "6(bad-timestamp)" },
- { 7, "7(congestion)" },
- { 8, "8(ip-option)" },
- { 9, "9(proto-cksum)" },
- { 10, "10(state-mismatch)" },
- { 11, "11(state-insert)" },
- { 12, "12(state-limit)" },
- { 13, "13(src-limit)" },
- { 14, "14(synproxy)" },
+ { PFRES_MATCH, "0(match)" },
+ { PFRES_BADOFF, "1(bad-offset)" },
+ { PFRES_FRAG, "2(fragment)" },
+ { PFRES_NORM, "3(short)" },
+ { PFRES_NORM, "4(normalize)" },
+ { PFRES_MEMORY, "5(memory)" },
+ { PFRES_TS, "6(bad-timestamp)" },
+ { PFRES_CONGEST, "7(congestion)" },
+ { PFRES_IPOPTIONS, "8(ip-option)" },
+ { PFRES_PROTCKSUM, "9(proto-cksum)" },
+ { PFRES_BADSTATE, "10(state-mismatch)" },
+ { PFRES_STATEINS, "11(state-insert)" },
+ { PFRES_MAXSTATES, "12(state-limit)" },
+ { PFRES_SRCLIMIT, "13(src-limit)" },
+ { PFRES_SYNPROXY, "14(synproxy)" },
+#if defined(__FreeBSD__)
+ { PFRES_MAPFAILED, "15(map-failed)" },
+#elif defined(__NetBSD__)
+ { PFRES_STATELOCKED, "15(state-locked)" },
+#elif defined(__OpenBSD__)
+ { PFRES_TRANSLATE, "15(translate)" },
+ { PFRES_NOROUTE, "16(no-route)" },
+#elif defined(__APPLE__)
+ { PFRES_DUMMYNET, "15(dummynet)" },
+#endif
{ 0, NULL }
};
@@ -70,6 +73,20 @@ static const struct tok pf_actions[] = {
{ PF_RDR, "rdr" },
{ PF_NORDR, "rdr" },
{ PF_SYNPROXY_DROP, "synproxy-drop" },
+#if defined(__FreeBSD__)
+ { PF_DEFER, "defer" },
+#elif defined(__OpenBSD__)
+ { PF_DEFER, "defer" },
+ { PF_MATCH, "match" },
+ { PF_DIVERT, "divert" },
+ { PF_RT, "rt" },
+ { PF_AFRT, "afrt" },
+#elif defined(__APPLE__)
+ { PF_DUMMYNET, "dummynet" },
+ { PF_NODUMMYNET, "nodummynet" },
+ { PF_NAT64, "nat64" },
+ { PF_NONAT64, "nonat64" },
+#endif
{ 0, NULL }
};
@@ -77,13 +94,12 @@ static const struct tok pf_directions[] = {
{ PF_INOUT, "in/out" },
{ PF_IN, "in" },
{ PF_OUT, "out" },
+#if defined(__OpenBSD__)
+ { PF_FWD, "fwd" },
+#endif
{ 0, NULL }
};
-/* For reading capture files on other systems */
-#define OPENBSD_AF_INET 2
-#define OPENBSD_AF_INET6 24
-
static void
pflog_print(netdissect_options *ndo, const struct pfloghdr *hdr)
{
@@ -104,7 +120,7 @@ pflog_print(netdissect_options *ndo, const struct pfloghdr *hdr)
tok2str(pf_reasons, "unkn(%u)", GET_U_1(&hdr->reason)),
tok2str(pf_actions, "unkn(%u)", GET_U_1(&hdr->action)),
tok2str(pf_directions, "unkn(%u)", GET_U_1(&hdr->dir)));
- nd_printjnp(ndo, (const u_char*)hdr->ifname, IFNAMSIZ);
+ nd_printjnp(ndo, (const u_char*)hdr->ifname, PFLOG_IFNAMSIZ);
ND_PRINT(": ");
}
@@ -133,7 +149,7 @@ pflog_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
ndo->ndo_ll_hdr_len += GET_U_1(&hdr->length); /* XXX: not really */
return;
}
- hdrlen = BPF_WORDALIGN(hdr->length);
+ hdrlen = roundup2(hdr->length, 4);
if (caplen < hdrlen) {
nd_print_trunc(ndo);
@@ -153,23 +169,26 @@ pflog_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
p += hdrlen;
switch (af) {
- case AF_INET:
-#if OPENBSD_AF_INET != AF_INET
- case OPENBSD_AF_INET: /* XXX: read pcap files */
-#endif
+ /*
+ * If there's a system that doesn't use the AF_INET
+ * from 4.2BSD, feel free to add its value to af.h
+ * and use it here.
+ *
+ * Hopefully, there isn't.
+ */
+ case AFNUM_INET:
ip_print(ndo, p, length);
break;
-#if defined(AF_INET6) || defined(OPENBSD_AF_INET6)
-#ifdef AF_INET6
- case AF_INET6:
-#endif /* AF_INET6 */
-#if !defined(AF_INET6) || OPENBSD_AF_INET6 != AF_INET6
- case OPENBSD_AF_INET6: /* XXX: read pcap files */
-#endif /* !defined(AF_INET6) || OPENBSD_AF_INET6 != AF_INET6 */
+ /*
+ * Try all AF_INET6 values for all systems with pflog,
+ * including Darwin.
+ */
+ case BSD_AFNUM_INET6_BSD:
+ case BSD_AFNUM_INET6_FREEBSD:
+ case BSD_AFNUM_INET6_DARWIN:
ip6_print(ndo, p, length);
break;
-#endif /* defined(AF_INET6) || defined(OPENBSD_AF_INET6) */
default:
/* address family not handled, print raw packet */
diff --git a/print.c b/print.c
index b1c81dd6..fbb1b3b1 100644
--- a/print.c
+++ b/print.c
@@ -185,7 +185,7 @@ static const struct printer printers[] = {
#ifdef DLT_LOOP
{ null_if_print, DLT_LOOP },
#endif
-#if defined(DLT_PFLOG) && defined(HAVE_NET_IF_PFLOG_H)
+#ifdef DLT_PFLOG
{ pflog_if_print, DLT_PFLOG },
#endif
#ifdef DLT_PKTAP