From 7a97c46b28b560500e6d971e3ecfabf854b9da64 Mon Sep 17 00:00:00 2001 From: itojun Date: Fri, 25 Jun 2004 12:22:23 +0000 Subject: [PATCH] support format for if_pflog.c (new format only/old format not supported) Peter Postma --- lib/libpcap/Makefile | 4 +- lib/libpcap/gencode.c | 146 +++++++++++++++++++++++++++++++++++++++++- lib/libpcap/gencode.h | 10 ++- lib/libpcap/grammar.y | 47 ++++++++++++-- lib/libpcap/scanner.l | 11 +++- 5 files changed, 207 insertions(+), 11 deletions(-) diff --git a/lib/libpcap/Makefile b/lib/libpcap/Makefile index 8834c322c7b5..5a9568eb642c 100644 --- a/lib/libpcap/Makefile +++ b/lib/libpcap/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.24 2003/08/01 17:03:59 lukem Exp $ +# $NetBSD: Makefile,v 1.25 2004/06/25 12:22:23 itojun Exp $ .include @@ -7,7 +7,7 @@ MAN= pcap.3 WARNS?= 1 -CPPFLAGS+=-I. -I${.CURDIR} -DYYBISON +CPPFLAGS+=-I. -I${.CURDIR} -I${NETBSDSRCDIR}/sys/dist/pf -DYYBISON CPPFLAGS+=-DINET6 CPPFLAGS+=-DHAVE_MALLOC_H=1 -DHAVE_SYS_IOCCOM_H=1 -DHAVE_SYS_SOCKIO_H=1 CPPFLAGS+=-DHAVE_ETHER_HOSTTON=1 -DHAVE_STRERROR=1 -DHAVE_SOCKADDR_SA_LEN=1 diff --git a/lib/libpcap/gencode.c b/lib/libpcap/gencode.c index 12379613cbf6..d533bcca3978 100644 --- a/lib/libpcap/gencode.c +++ b/lib/libpcap/gencode.c @@ -1,4 +1,4 @@ -/* $NetBSD: gencode.c,v 1.33 2002/12/19 16:33:47 hannken Exp $ */ +/* $NetBSD: gencode.c,v 1.34 2004/06/25 12:22:23 itojun Exp $ */ /* * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 @@ -26,7 +26,7 @@ static const char rcsid[] = "@(#) Header: gencode.c,v 1.93 97/06/12 14:22:47 leres Exp (LBL)"; #else -__RCSID("$NetBSD: gencode.c,v 1.33 2002/12/19 16:33:47 hannken Exp $"); +__RCSID("$NetBSD: gencode.c,v 1.34 2004/06/25 12:22:23 itojun Exp $"); #endif #endif @@ -49,6 +49,9 @@ struct rtentry; #include #endif +#include +#include + #include #include #include @@ -74,6 +77,10 @@ struct rtentry; #include "os-proto.h" #endif +#ifdef __NetBSD__ +#include +#endif + #define JMP(c) ((c)|BPF_JMP|BPF_K) /* Locals */ @@ -659,6 +666,11 @@ init_linktype(type) off_nl = 4; return; + case DLT_PFLOG: + off_linktype = 0; + off_nl = PFLOG_HDRLEN; + return; + case DLT_RAW: off_linktype = -1; off_nl = 0; @@ -802,6 +814,20 @@ gen_linktype(proto) return gen_false(); } break; + + case DLT_PFLOG: + 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: /* * XXX should we check for first fragment if the protocol @@ -2988,6 +3014,11 @@ gen_inbound(dir) /* These are okay. */ break; + case DLT_PFLOG: + b0 = gen_cmp(offsetof(struct pfloghdr, dir), BPF_B, + (bpf_int32)((dir == 0) ? PF_IN : PF_OUT)); + break; + default: bpf_error("inbound/outbound not supported on linktype 0x%x\n", linktype); @@ -3001,6 +3032,117 @@ gen_inbound(dir) return (b0); } +/* PF firewall log matched interface */ +struct block * +gen_pf_ifname(char *ifname) +{ + 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\n", linktype); + /* NOTREACHED */ + } + if (strlen(ifname) >= len) { + bpf_error("ifname interface names can only be %d characters\n", + len - 1); + /* NOTREACHED */ + } + 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\n", linktype); + /* NOTREACHED */ + } + if (strlen(ruleset) >= sizeof(((struct pfloghdr *)0)->ruleset)) { + bpf_error("ruleset names can only be %d characters\n", + (int)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) +{ + 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\n", linktype); + /* NOTREACHED */ + } + + 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\n", 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) +{ + 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\n", linktype); + /* NOTREACHED */ + } + + return (b0); +} + +/* PF firewall log action */ +struct block * +gen_pf_action(int action) +{ + 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\n", linktype); + /* NOTREACHED */ + } + + return (b0); +} + struct block * gen_acode(eaddr, q) register const u_char *eaddr; diff --git a/lib/libpcap/gencode.h b/lib/libpcap/gencode.h index 78b990be7047..1d23136e7eda 100644 --- a/lib/libpcap/gencode.h +++ b/lib/libpcap/gencode.h @@ -1,4 +1,4 @@ -/* $NetBSD: gencode.h,v 1.12 2002/12/19 16:33:48 hannken Exp $ */ +/* $NetBSD: gencode.h,v 1.13 2004/06/25 12:22:23 itojun Exp $ */ /* * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 @@ -181,6 +181,14 @@ struct block *gen_multicast(int); struct block *gen_inbound(int); struct block *gen_vlan(int); +struct block *gen_pf_ifname(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); + void bpf_optimize(struct block **); #if __STDC__ __dead void bpf_error(const char *, ...) diff --git a/lib/libpcap/grammar.y b/lib/libpcap/grammar.y index 86fdcb5fedb6..8d2f5dd7f8b2 100644 --- a/lib/libpcap/grammar.y +++ b/lib/libpcap/grammar.y @@ -1,5 +1,5 @@ %{ -/* $NetBSD: grammar.y,v 1.9 2002/12/19 16:33:48 hannken Exp $ */ +/* $NetBSD: grammar.y,v 1.10 2004/06/25 12:22:23 itojun Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 @@ -28,7 +28,7 @@ static const char rcsid[] = "@(#) Header: grammar.y,v 1.56 96/11/02 21:54:55 leres Exp (LBL)"; #else -__RCSID("$NetBSD: grammar.y,v 1.9 2002/12/19 16:33:48 hannken Exp $"); +__RCSID("$NetBSD: grammar.y,v 1.10 2004/06/25 12:22:23 itojun Exp $"); #endif #endif @@ -50,7 +50,10 @@ struct rtentry; #include #endif +#include + #include +#include #include "pcap-int.h" @@ -110,7 +113,7 @@ pcap_parse() %type arth narth %type byteop pname pnum relop irelop %type and or paren not null prog -%type other +%type other pfvar %token DST SRC HOST GATEWAY %token NET MASK PORT LESS GREATER PROTO PROTOCHAIN BYTE @@ -118,6 +121,7 @@ pcap_parse() %token ATALK DECNET LAT SCA MOPRC MOPDL %token TK_BROADCAST TK_MULTICAST %token NUM INBOUND OUTBOUND +%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 @@ -130,7 +134,7 @@ pcap_parse() %type EID %type AID %type HID HID6 -%type NUM +%type NUM action reason %left OR AND %nonassoc '!' @@ -285,7 +289,42 @@ other: pqual TK_BROADCAST { $$ = gen_broadcast($1); } | OUTBOUND { $$ = gen_inbound(1); } | VLAN pnum { $$ = gen_vlan($2); } | VLAN { $$ = gen_vlan(-1); } + | pfvar { $$ = $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); } + ; + +reason: NUM { $$ = $1; } + | ID { const char *reasons[] = PFRES_NAMES; + int i; + for (i = 0; reasons[i]; i++) { + if (strcasecmp($1, reasons[i]) == 0) { + $$ = i; + break; + } + } + if (reasons[i] == NULL) + bpf_error("unknown PF reason"); + } + ; + +action: ID { if (strcasecmp($1, "pass") == 0 || + strcasecmp($1, "accept") == 0) + $$ = PF_PASS; + else if (strcasecmp($1, "drop") == 0 || + strcasecmp($1, "block") == 0) + $$ = PF_DROP; + else + bpf_error("unknown PF action"); + } + ; + relop: '>' { $$ = BPF_JGT; } | GEQ { $$ = BPF_JGE; } | '=' { $$ = BPF_JEQ; } diff --git a/lib/libpcap/scanner.l b/lib/libpcap/scanner.l index 58c3d559f302..032e688e79c5 100644 --- a/lib/libpcap/scanner.l +++ b/lib/libpcap/scanner.l @@ -1,5 +1,5 @@ %{ -/* $NetBSD: scanner.l,v 1.15 2002/12/19 16:33:48 hannken Exp $ */ +/* $NetBSD: scanner.l,v 1.16 2004/06/25 12:22:23 itojun Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 @@ -28,7 +28,7 @@ static const char rcsid[] = "@(#) Header: scanner.l,v 1.56 97/07/21 13:31:50 leres Exp (LBL)"; #else -__RCSID("$NetBSD: scanner.l,v 1.15 2002/12/19 16:33:48 hannken Exp $"); +__RCSID("$NetBSD: scanner.l,v 1.16 2004/06/25 12:22:23 itojun Exp $"); #endif #endif @@ -231,6 +231,13 @@ inbound return INBOUND; outbound return OUTBOUND; vlan return VLAN; +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; + [ \n\t] ; [+\-*/:\[\]!<>()&|=] return yytext[0]; ">=" return GEQ;