]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Handle DLT_PFLOG on all OSes.
authorGuy Harris <[email protected]>
Sun, 30 Jan 2022 06:30:33 +0000 (22:30 -0800)
committerGuy Harris <[email protected]>
Sun, 30 Jan 2022 06:30:33 +0000 (22:30 -0800)
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.

CMakeLists.txt
Makefile.in
cmakeconfig.h.in
config.h.in
configure
configure.ac
pflog.h [new file with mode: 0644]
print-pflog.c
print.c

index 9de92bdfee58a751d554a2f7e4d55bcc6f25640b..5cd4024e756e1a45ee9ebefd575732d60b9cf453 100644 (file)
@@ -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
index 36122d5bc49db61f61804e16fc0a7f472007d781..40fb1cfc268b10f5ab1e22425e45c27036a94b4e 100644 (file)
@@ -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 \
index 852d15176b8bed2f5846bc5a6e472c6b2fadd7c2..370d39621aac2ee8cbfea215bd7e82f54ba8496a 100644 (file)
 /* 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
 
index bb1a4f6adcfc6cdd42f9874a4030c9e40058bdac..2c64093bb8a69edf29b5e7339ca6c37fbf7bf164 100644 (file)
 /* 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
 
index 4e84a4330d88ba10c117323117668513367f3a54..0308dafba7b364643a7fb0fb9fe905cf7489ce24 100755 (executable)
--- 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
 
index de00be56ec3e36d6c49917d0ee7ab5740765f2ab..0d9782f8eff43f1daf4811219ce9f75318db5aeb 100644 (file)
@@ -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 (file)
index 0000000..0d3f899
--- /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
+};
+
+
+
index eb1b1766db004b1eee92cac81a4655eea924fd42..05b9eb3a3a9b707fa31c09abd3809d4dda477eb5 100644 (file)
  * 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 b1c81dd652decd0e229a386f15e1ddf6ff366aa8..fbb1b3b1085116f10436a405f238e519b886d422 100644 (file)
--- 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