tcpdump mailing list archives

[patch] Teach tcpdump to recognize new OpenBSD pflog packets


From: Eygene Ryabinkin <rea-tcpdump () codelabs ru>
Date: Mon, 24 Sep 2007 22:25:47 +0400

Good day.

OpenBSD 4.1 introduced an incompatible change to their pflog device
packet header: some fields were stuffed into the 'struct pfloghdr'
between 'subrulenr' and 'dir':
    http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/if_pflog.h.diff?r1=1.11&r2=1.12

This broke tcpdump's ability to display the proper direction field
for the pflog interfaces.

The following patch corrects the situation.  It was made and tested
on FreeBSD 6.2-STABLE and 7-CURRENT for the system's tcpdump (3.9.4
with some FreeBSD changes) and for the 3.9.7 on FreeBSD 7-CURRENT
and 6.2-STABLE.  The problem was verified on the FreeBSD 7-CURRENT
for the system's 3.9.4 and 3.9.7.

There is FreeBSD problem report that discuisses the patch,
    http://www.freebsd.org/cgi/query-pr.cgi?pr=116610

The patch itself (needs patch -p2):
-----
--- contrib/tcpdump/pf.h.orig   2007-09-24 19:59:29.000000000 +0400
+++ contrib/tcpdump/pf.h        2007-09-24 20:31:40.000000000 +0400
@@ -29,6 +29,9 @@
  * @(#) $Header: /tcpdump/master/tcpdump/pf.h,v 1.2 2004/04/02 06:36:25 guy Exp $ (LBL)
  */
 
+/* We need offsetof() macro */
+#include <stddef.h>
+
 /*     from $OpenBSD: pfvar.h,v 1.170 2003/08/22 21:50:34 david Exp $ */
 
 enum   { PF_INOUT=0, PF_IN=1, PF_OUT=2 };
@@ -75,3 +78,23 @@
        u_int8_t        pad[3];
 };
 #define PFLOG_HDRLEN           sizeof(struct pfloghdr)
+
+/*     from $OpenBSD: if_pflog.h,v 1.14 2006/10/25 11:27:01 henning Exp $ */
+
+struct pfloghdr_v2 {
+       u_int8_t        length;
+       sa_family_t     af;
+       u_int8_t        action;
+       u_int8_t        reason;
+       char            ifname[IFNAMSIZ];
+       char            ruleset[PF_RULESET_NAME_SIZE];
+       u_int32_t       rulenr;
+       u_int32_t       subrulenr;
+       uid_t           uid;
+       pid_t           pid;
+       uid_t           rule_uid;
+       pid_t           rule_pid;
+       u_int8_t        dir;
+       u_int8_t        pad[3];
+};
+#define PFLOG_HDRV2_LEN                offsetof(struct pfloghdr_v2, pad)
--- contrib/tcpdump/print-pflog.c.orig  2007-09-24 19:10:09.000000000 +0400
+++ contrib/tcpdump/print-pflog.c       2007-09-24 20:30:36.000000000 +0400
@@ -72,25 +72,43 @@
 #define        OPENBSD_AF_INET         2
 #define        OPENBSD_AF_INET6        24
 
+#define __PFLOG_PRINT_HDR(hdr)                                         \
+do {                                                                   \
+       u_int32_t rulenr, subrulenr;                                    \
+                                                                       \
+       rulenr = ntohl((hdr)->rulenr);                                  \
+       subrulenr = ntohl((hdr)->subrulenr);                            \
+       if (subrulenr == (u_int32_t)-1)                                 \
+               printf("rule %u/", rulenr);                             \
+       else                                                            \
+               printf("rule %u.%s.%u/", rulenr, (hdr)->ruleset,        \
+                   subrulenr);                                         \
+                                                                       \
+       printf("%s: %s %s on %s: ",                                     \
+           tok2str(pf_reasons, "unkn(%u)", (hdr)->reason),             \
+           tok2str(pf_actions, "unkn(%u)", (hdr)->action),             \
+           tok2str(pf_directions, "unkn(%u)", (hdr)->dir),             \
+           (hdr)->ifname);                                             \
+} while (0)
+
 static void
 pflog_print(const struct pfloghdr *hdr)
 {
-       u_int32_t rulenr, subrulenr;
+       u_int8_t hdr_version;
+       struct pfloghdr_v2 *v2hdr;
 
-       rulenr = ntohl(hdr->rulenr);
-       subrulenr = ntohl(hdr->subrulenr);
-       if (subrulenr == (u_int32_t)-1)
-               printf("rule %u/", rulenr);
-       else
-               printf("rule %u.%s.%u/", rulenr, hdr->ruleset, subrulenr);
-
-       printf("%s: %s %s on %s: ",
-           tok2str(pf_reasons, "unkn(%u)", hdr->reason),
-           tok2str(pf_actions, "unkn(%u)", hdr->action),
-           tok2str(pf_directions, "unkn(%u)", hdr->dir),
-           hdr->ifname);
+       if (hdr->length == PFLOG_HDRV2_LEN) {
+               hdr_version = 2;
+               v2hdr = (struct pfloghdr_v2 *)hdr;
+               __PFLOG_PRINT_HDR(v2hdr);
+       } else {
+               hdr_version = 1;
+               __PFLOG_PRINT_HDR(hdr);
+       }
 }
 
+#undef __PFLOG_PRINT_HDR
+
 u_int
 pflog_if_print(const struct pcap_pkthdr *h, register const u_char *p)
 {
-----

Comments and suggestions are welcome!
-- 
Eygene
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: