]> 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, 20 Mar 2022 01:37:42 +0000 (18:37 -0700)
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.

(cherry picked from commit fe762c04a6d3bbf7f1a21ebf825075e2fb201acc)

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 7a4acec76ad023fdaca372debea21790ec11912c..775ff4b74e533546cf73b87d69cd529f2694ac7d 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 86bac6e4e67a62becc3a1ca09b8f829ec08ad335..c4f636c169fdbe0a5bb497f2d13feb9447d616a0 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 \
@@ -305,6 +306,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 6bec1150926ad9b22221c7cd6d525ec79d613ba2..439038a6688cd25d730c68639cd81645f19c9d59 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 2bf8211fb7827bc026d5b47638e98e21de6c66bc..8811e665b5f4d031aba741e4b4f6db0947230347 100755 (executable)
--- a/configure
+++ b/configure
@@ -4180,42 +4180,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 679707177e9b8ea6b7b1d3d99b245c1b2094ff8c..f7e70cc919b8158c198a6f7f18a3c6beb73163f5 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 bfc35d9c938f0c726a9de140d34b7bcd13e400d8..84aae66c95dfad4e91622038327db974b8e6539f 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