bin/116610: [patch] teach tcpdump(1) to cope with the new-style
pflog(4) output
Eygene Ryabinkin
rea-fbsd at codelabs.ru
Mon Sep 24 10:40:04 PDT 2007
>Number: 116610
>Category: bin
>Synopsis: [patch] teach tcpdump(1) to cope with the new-style pflog(4) output
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Sep 24 17:40:02 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator: Eygene Ryabinkin
>Release: FreeBSD 7.0-CURRENT i386
>Organization:
Code Labs
>Environment:
System: FreeBSD XXX 7.0-CURRENT FreeBSD 7.0-CURRENT #10: Wed Sep 12 16:16:49 MSD 2007 root at XXX:/usr/src/sys/i386/compile/XXX i386
>Description:
Version 1.9 of /sys/contrib/pf/net/if_pflog.h (Import of pf from
OpenBSD 4.1) introduced the backwards-incompatible change to the
'struct pfloghdr': the 'dir' and 'pad' members moved far away from
their previous positions.
This is not a problem for the pf itself, but tcpdump is no longer
able to print the packet direction correctly.
>How-To-Repeat:
Spawn tcpdump like 'tcpdump -lvvnetti pflog0' on the 7-CURRENT built
from the sources later than Tue Jul 3 16:16:07 2007 MSD and see
that the link-level header contains weird 'unkn(255)' direction:
"rule 14/0(match): block unkn(255) on uplink".
>Fix:
The following patch will cure the situation. I know that the best
thing that can be done is to commit it to the tcpdump itself, but
a) this is a long process, since it requires tcpdump team to accept
the patch and Someone (TM) to import new tcpdump sources to
FreeBSD;
b) other eyes should see and criticize this patch.
I myself was tested this patch on the 7-CURRENT and 6.2-STABLE.
No regressions were seen yet and tcpdump works like a charm with
the new pflog0 packets showing 'in' and 'out' ;))
--- tcpdump-pflog-v2.patch begins here ---
--- 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)
{
--- tcpdump-pflog-v2.patch ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list