From ca2f760a13ec98f423d71fbe0b6ab5e19deb65c1 Mon Sep 17 00:00:00 2001 From: fenner Date: Sun, 28 Mar 2004 21:45:30 +0000 Subject: [PATCH] Handle the new OpenBSD pf format (DLT 117), which is now being used by other systems as they adopt pf. Don't bother trying to be backwards compatible with DLT 17. --- gencode.c | 134 +++++++++++++++++++++++++++++++++++++++++++---------- gencode.h | 4 +- grammar.y | 7 ++- pcap-bpf.h | 14 ++++-- pcap.3 | 41 +++++++++------- pf.h | 33 +++++++++++-- scanner.l | 4 +- 7 files changed, 181 insertions(+), 56 deletions(-) diff --git a/gencode.c b/gencode.c index 0fbe416..07210a5 100644 --- a/gencode.c +++ b/gencode.c @@ -21,7 +21,7 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.193.2.6 2004-03-17 19:05:20 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.193.2.7 2004-03-28 21:45:30 fenner Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -71,6 +71,9 @@ static const char rcsid[] _U_ = #include "sll.h" #include "arcnet.h" #include "pf.h" +#ifndef offsetof +#define offsetof(s, e) ((size_t)&((s *)0)->e) +#endif #ifdef INET6 #ifndef WIN32 #include /* for "struct addrinfo" */ @@ -746,12 +749,6 @@ init_linktype(type) off_nl_nosnap = 12; /* no 802.2 LLC */ return; - case DLT_PFLOG: - off_linktype = 0; - off_nl = 28; - off_nl_nosnap = 28; /* no 802.2 LLC */ - return; - case DLT_PPP: case DLT_C_HDLC: /* BSD/OS Cisco HDLC */ case DLT_PPP_SERIAL: /* NetBSD sync/async serial PPP */ @@ -995,6 +992,21 @@ init_linktype(type) off_nl = -1; off_nl_nosnap = -1; return; + + case DLT_PFLOG: + off_linktype = 0; + /* XXX read from header? */ + off_nl = PFLOG_HDRLEN; + off_nl_nosnap = PFLOG_HDRLEN; + return; + +#ifdef DLT_PFSYNC + case DLT_PFSYNC: + off_linktype = -1; + off_nl = 4; + off_nl_nosnap = 4; + return; +#endif } bpf_error("unknown data link type %d", linktype); /* NOTREACHED */ @@ -1579,7 +1591,6 @@ gen_linktype(proto) case DLT_NULL: case DLT_LOOP: case DLT_ENC: - case DLT_PFLOG: /* * For DLT_NULL, the link-layer header is a 32-bit * word containing an AF_ value in *host* byte order, @@ -1601,8 +1612,6 @@ gen_linktype(proto) * This means that, when reading a capture file, just * checking for our AF_INET6 value won't work if the * capture file came from another OS. - * - * XXX - what's the byte order for DLT_PFLOG? */ switch (proto) { @@ -1645,6 +1654,23 @@ gen_linktype(proto) } return (gen_cmp(0, BPF_W, (bpf_int32)proto)); + case DLT_PFLOG: + /* + * af field is host byte order in contrast to the rest of + * the packet. + */ + if (proto == ETHERTYPE_IP) + return (gen_cmp(offsetof(struct pfloghdr, af), BPF_B, + (bpf_int32)AF_INET)); +#ifdef INET6 + else if (proto == ETHERTYPE_IPV6) + return (gen_cmp(offsetof(struct pfloghdr, af), BPF_B, + (bpf_int32)AF_INET6)); +#endif /* INET6 */ + else + return gen_false(); + break; + case DLT_ARCNET: case DLT_ARCNET_LINUX: /* @@ -5006,7 +5032,7 @@ gen_inbound(dir) break; case DLT_PFLOG: - b0 = gen_cmp(26, BPF_H, + b0 = gen_cmp(offsetof(struct pfloghdr, dir), BPF_B, (bpf_int32)((dir == 0) ? PF_IN : PF_OUT)); break; @@ -5023,52 +5049,110 @@ gen_inbound(dir) struct block * gen_pf_ifname(const char *ifname) { - if (linktype != DLT_PFLOG) { - bpf_error("ifname supported only for DLT_PFLOG"); + struct block *b0; + u_int len, off; + + if (linktype == DLT_PFLOG) { + len = sizeof(((struct pfloghdr *)0)->ifname); + off = offsetof(struct pfloghdr, ifname); + } else { + bpf_error("ifname not supported on linktype 0x%x", linktype); /* NOTREACHED */ } - if (strlen(ifname) >= 16) { - bpf_error("ifname interface names can't be larger than 16 characters"); + if (strlen(ifname) >= len) { + bpf_error("ifname interface names can only be %d characters", + len-1); /* NOTREACHED */ } - return (gen_bcmp(4, strlen(ifname), (const u_char *)ifname)); + b0 = gen_bcmp(off, strlen(ifname), ifname); + return (b0); } +/* PF firewall log matched interface */ +struct block * +gen_pf_ruleset(char *ruleset) +{ + struct block *b0; + + if (linktype != DLT_PFLOG) { + bpf_error("ruleset not supported on linktype 0x%x", linktype); + /* NOTREACHED */ + } + if (strlen(ruleset) >= sizeof(((struct pfloghdr *)0)->ruleset)) { + bpf_error("ruleset names can only be %d characters", + sizeof(((struct pfloghdr *)0)->ruleset) - 1); + /* NOTREACHED */ + } + b0 = gen_bcmp(offsetof(struct pfloghdr, ruleset), + strlen(ruleset), ruleset); + return (b0); +} /* PF firewall log rule number */ struct block * gen_pf_rnr(int rnr) { - if (linktype != DLT_PFLOG) { - bpf_error("rnr supported only for DLT_PFLOG"); + struct block *b0; + + if (linktype == DLT_PFLOG) { + b0 = gen_cmp(offsetof(struct pfloghdr, rulenr), BPF_W, + (bpf_int32)rnr); + } else { + bpf_error("rnr not supported on linktype 0x%x", linktype); /* NOTREACHED */ } - return (gen_cmp(20, BPF_H, (bpf_int32)rnr)); + return (b0); +} + +/* PF firewall log sub-rule number */ +struct block * +gen_pf_srnr(int srnr) +{ + struct block *b0; + + if (linktype != DLT_PFLOG) { + bpf_error("srnr not supported on linktype 0x%x", linktype); + /* NOTREACHED */ + } + + b0 = gen_cmp(offsetof(struct pfloghdr, subrulenr), BPF_W, + (bpf_int32)srnr); + return (b0); } /* PF firewall log reason code */ struct block * gen_pf_reason(int reason) { - if (linktype != DLT_PFLOG) { - bpf_error("reason supported only for DLT_PFLOG"); + struct block *b0; + + if (linktype == DLT_PFLOG) { + b0 = gen_cmp(offsetof(struct pfloghdr, reason), BPF_B, + (bpf_int32)reason); + } else { + bpf_error("reason not supported on linktype 0x%x", linktype); /* NOTREACHED */ } - return (gen_cmp(22, BPF_H, (bpf_int32)reason)); + return (b0); } /* PF firewall log action */ struct block * gen_pf_action(int action) { - if (linktype != DLT_PFLOG) { - bpf_error("action supported only for DLT_PFLOG"); + struct block *b0; + + if (linktype == DLT_PFLOG) { + b0 = gen_cmp(offsetof(struct pfloghdr, action), BPF_B, + (bpf_int32)action); + } else { + bpf_error("action not supported on linktype 0x%x", linktype); /* NOTREACHED */ } - return (gen_cmp(24, BPF_H, (bpf_int32)action)); + return (b0); } struct block * diff --git a/gencode.h b/gencode.h index c3a19a7..b613283 100644 --- a/gencode.h +++ b/gencode.h @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.58 2003-05-02 08:37:44 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.58.2.1 2004-03-28 21:45:31 fenner Exp $ (LBL) */ /* @@ -280,6 +280,8 @@ struct block *gen_atmmulti_abbrev(int type); struct block *gen_pf_ifname(const char *); struct block *gen_pf_rnr(int); +struct block *gen_pf_srnr(int); +struct block *gen_pf_ruleset(char *); struct block *gen_pf_reason(int); struct block *gen_pf_action(int); struct block *gen_pf_dir(int); diff --git a/grammar.y b/grammar.y index b18a2ff..6f0548f 100644 --- a/grammar.y +++ b/grammar.y @@ -22,7 +22,7 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.79.2.2 2003-12-16 05:20:44 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.79.2.3 2004-03-28 21:45:32 fenner Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -49,6 +49,7 @@ struct rtentry; #endif /* WIN32 */ #include +#include #include "pcap-int.h" @@ -120,7 +121,7 @@ pcap_parse() %token ATALK AARP DECNET LAT SCA MOPRC MOPDL %token TK_BROADCAST TK_MULTICAST %token NUM INBOUND OUTBOUND -%token PF_IFNAME PF_RNR PF_REASON PF_ACTION +%token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION %token LINK %token GEQ LEQ NEQ %token ID EID HID HID6 AID @@ -327,7 +328,9 @@ other: pqual TK_BROADCAST { $$ = gen_broadcast($1); } ; pfvar: PF_IFNAME ID { $$ = gen_pf_ifname($2); } + | PF_RSET ID { $$ = gen_pf_ruleset($2); } | PF_RNR NUM { $$ = gen_pf_rnr($2); } + | PF_SRNR NUM { $$ = gen_pf_srnr($2); } | PF_REASON reason { $$ = gen_pf_reason($2); } | PF_ACTION action { $$ = gen_pf_action($2); } ; diff --git a/pcap-bpf.h b/pcap-bpf.h index 45dffad..e98ee55 100644 --- a/pcap-bpf.h +++ b/pcap-bpf.h @@ -37,7 +37,7 @@ * * @(#)bpf.h 7.1 (Berkeley) 5/7/91 * - * @(#) $Header: /tcpdump/master/libpcap/pcap-bpf.h,v 1.9.2.8 2004-03-17 19:05:21 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/pcap-bpf.h,v 1.9.2.9 2004-03-28 21:45:32 fenner Exp $ (LBL) */ /* @@ -167,7 +167,9 @@ struct bpf_version { #endif /* - * 17 is used for DLT_PFLOG in OpenBSD; don't use it for anything else. + * 17 is used for DLT_OLD_PFLOG in OpenBSD; + * OBSOLETE: DLT_PFLOG is 117 in OpenBSD now as well. See below. + * 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else. */ #define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ @@ -281,12 +283,14 @@ struct bpf_version { /* * OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, but that's DLT_LANE8023 * in SuSE 6.3, so we can't use 17 for it in capture-file headers. + * + * XXX: is there a conflict with DLT_PFSYNC 18 as well? */ #ifdef __OpenBSD__ -#define DLT_PFLOG 17 -#else -#define DLT_PFLOG 117 +#define DLT_OLD_PFLOG 17 +#define DLT_PFSYNC 18 #endif +#define DLT_PFLOG 117 /* * Registered for Cisco-internal use. diff --git a/pcap.3 b/pcap.3 index 68cb619..136cc5a 100644 --- a/pcap.3 +++ b/pcap.3 @@ -1,4 +1,4 @@ -.\" @(#) $Header: /tcpdump/master/libpcap/Attic/pcap.3,v 1.51.2.8 2004-02-28 02:52:03 guy Exp $ +.\" @(#) $Header: /tcpdump/master/libpcap/Attic/pcap.3,v 1.51.2.9 2004-03-28 21:45:32 fenner Exp $ .\" .\" Copyright (c) 1994, 1996, 1997 .\" The Regents of the University of California. All rights reserved. @@ -859,11 +859,22 @@ Apple LocalTalk; the packet begins with an AppleTalk LLAP header. OpenBSD pflog; the link layer header contains, in order: .RS 10 .LP -a 4-byte PF_ value, in network byte order; +a 1-byte header length, in host byte order; .LP -a 16-character interface name; +a 4-byte PF_ value, in host byte order; .LP -a 2-byte rule number, in network byte order; +a 2-byte action code, in network byte order, which is one of: +.RS 5 +.TP 5 +0 +passed +.TP 5 +1 +dropped +.TP 5 +2 +scrubbed +.RE .LP a 2-byte reason code, in network byte order, which is one of: .RS 5 @@ -883,23 +894,19 @@ short 4 normalize .TP 5 +5 memory .RE .LP -a 2-byte action code, in network byte order, which is one of: -.RS 5 -.TP 5 -0 -passed -.TP 5 -1 -dropped -.TP 5 -2 -scrubbed -.RE +a 16-character interface name; .LP -a 2-byte direction, in network byte order, which is one of: +a 16-character ruleset name (only meaningful if subrule is set); +.LP +a 4-byte rule number, in network byte order; +.LP +a 4-byte subrule number, in network byte order; +.LP +a 1-byte direction, in network byte order, which is one of: .RS 5 .TP 5 0 diff --git a/pf.h b/pf.h index cec4278..58ec19c 100644 --- a/pf.h +++ b/pf.h @@ -26,13 +26,14 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * @(#) $Header: /tcpdump/master/libpcap/Attic/pf.h,v 1.1 2003-03-11 06:23:54 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/Attic/pf.h,v 1.1.2.1 2004-03-28 21:45:33 fenner Exp $ (LBL) */ -/* from $OpenBSD: pfvar.h,v 1.61 2002/01/11 20:13:11 mickey Exp $ */ - -enum { PF_IN=0, PF_OUT=1 }; -enum { PF_PASS=0, PF_DROP=1, PF_SCRUB=2 }; +/* 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 }; +enum { PF_PASS=0, PF_DROP=1, PF_SCRUB=2, PF_NAT=3, PF_NONAT=4, + PF_BINAT=5, PF_NOBINAT=6, PF_RDR=7, PF_NORDR=8, PF_SYNPROXY_DROP=9 }; /* Reasons code for passing/dropping a packet */ #define PFRES_MATCH 0 /* Explicit match of a rule */ @@ -52,3 +53,25 @@ enum { PF_PASS=0, PF_DROP=1, PF_SCRUB=2 }; "memory", \ NULL \ } + +#define PF_RULESET_NAME_SIZE 16 + +/* from $OpenBSD: if_pflog.h,v 1.9 2003/07/15 20:27:27 dhartmei Exp $ */ + +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif + +struct pfloghdr { + 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; + u_int8_t dir; + u_int8_t pad[3]; +}; +#define PFLOG_HDRLEN sizeof(struct pfloghdr) diff --git a/scanner.l b/scanner.l index ab30a88..c532d4b 100644 --- a/scanner.l +++ b/scanner.l @@ -22,7 +22,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.95.2.2 2003-12-16 05:20:44 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.95.2.3 2004-03-28 21:45:33 fenner Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -277,7 +277,9 @@ connectmsg return CONNECTMSG; metaconnect return METACONNECT; on|ifname return PF_IFNAME; +rset|ruleset return PF_RSET; rnr|rulenum return PF_RNR; +srnr|subrulenum return PF_SRNR; reason return PF_REASON; action return PF_ACTION;