From cc7b2f2e42e508114c0b4162e6302e2a91c5b133 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Sat, 3 Jul 2010 13:15:01 -0700 Subject: [PATCH] Add support for "wlan ra" and "wlan ta". The RA field is absent from management frames (addr1 is DA there), and addr1 in other frames. The TA field is absent from management frames (addr2 is SA there), and addr2, if present, in other frames. While we're at it, fix a font glitch in the pcap-filter man page. --- gencode.c | 113 ++++++++++++++++++++++++++++++++++++++++- gencode.h | 2 + grammar.y | 4 +- pcap-filter.manmisc.in | 15 +++++- scanner.l | 2 + 5 files changed, 133 insertions(+), 3 deletions(-) diff --git a/gencode.c b/gencode.c index 908f226..fa68122 100644 --- a/gencode.c +++ b/gencode.c @@ -3801,6 +3801,14 @@ gen_ehostop(eaddr, dir) case Q_ADDR4: bpf_error("'addr4' is only supported on 802.11 with 802.11 headers"); break; + + case Q_RA: + bpf_error("'ra' is only supported on 802.11 with 802.11 headers"); + break; + + case Q_TA: + bpf_error("'ta' is only supported on 802.11 with 802.11 headers"); + break; } abort(); /* NOTREACHED */ @@ -3859,6 +3867,14 @@ gen_fhostop(eaddr, dir) case Q_ADDR4: bpf_error("'addr4' is only supported on 802.11"); break; + + case Q_RA: + bpf_error("'ra' is only supported on 802.11"); + break; + + case Q_TA: + bpf_error("'ta' is only supported on 802.11"); + break; } abort(); /* NOTREACHED */ @@ -3909,6 +3925,14 @@ gen_thostop(eaddr, dir) case Q_ADDR4: bpf_error("'addr4' is only supported on 802.11"); break; + + case Q_RA: + bpf_error("'ra' is only supported on 802.11"); + break; + + case Q_TA: + bpf_error("'ta' is only supported on 802.11"); + break; } abort(); /* NOTREACHED */ @@ -4202,8 +4226,79 @@ gen_wlanhostop(eaddr, dir) gen_and(b1, b0); return b0; + case Q_RA: + /* + * Not present in management frames; addr1 in other + * frames. + */ + + /* + * If the high-order bit of the type value is 0, this + * is a management frame. + * I.e, check "(link[0] & 0x08)". + */ + s = gen_load_a(OR_LINK, 0, BPF_B); + b1 = new_block(JMP(BPF_JSET)); + b1->s.k = 0x08; + b1->stmts = s; + + /* + * Check addr1. + */ + b0 = gen_bcmp(OR_LINK, 4, 6, eaddr); + + /* + * AND that with the check of addr1. + */ + gen_and(b1, b0); + return (b0); + + case Q_TA: + /* + * Not present in management frames; addr2, if present, + * in other frames. + */ + + /* + * Not present in CTS or ACK control frames. + */ + b0 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_TYPE_CTL, + IEEE80211_FC0_TYPE_MASK); + gen_not(b0); + b1 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS, + IEEE80211_FC0_SUBTYPE_MASK); + gen_not(b1); + b2 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_ACK, + IEEE80211_FC0_SUBTYPE_MASK); + gen_not(b2); + gen_and(b1, b2); + gen_or(b0, b2); + + /* + * If the high-order bit of the type value is 0, this + * is a management frame. + * I.e, check "(link[0] & 0x08)". + */ + s = gen_load_a(OR_LINK, 0, BPF_B); + b1 = new_block(JMP(BPF_JSET)); + b1->s.k = 0x08; + b1->stmts = s; + + /* + * AND that with the check for frames other than + * CTS and ACK frames. + */ + gen_and(b1, b2); + + /* + * Check addr2. + */ + b1 = gen_bcmp(OR_LINK, 10, 6, eaddr); + gen_and(b2, b1); + return b1; + /* - * XXX - add RA, TA, and BSSID keywords? + * XXX - add BSSID keyword? */ case Q_ADDR1: return (gen_bcmp(OR_LINK, 4, 6, eaddr)); @@ -4315,6 +4410,14 @@ gen_ipfchostop(eaddr, dir) case Q_ADDR4: bpf_error("'addr4' is only supported on 802.11"); break; + + case Q_RA: + bpf_error("'ra' is only supported on 802.11"); + break; + + case Q_TA: + bpf_error("'ta' is only supported on 802.11"); + break; } abort(); /* NOTREACHED */ @@ -7856,6 +7959,14 @@ gen_ahostop(eaddr, dir) case Q_ADDR4: bpf_error("'addr4' is only supported on 802.11"); break; + + case Q_RA: + bpf_error("'ra' is only supported on 802.11"); + break; + + case Q_TA: + bpf_error("'ta' is only supported on 802.11"); + break; } abort(); /* NOTREACHED */ diff --git a/gencode.h b/gencode.h index e2388b7..4f71003 100644 --- a/gencode.h +++ b/gencode.h @@ -136,6 +136,8 @@ #define Q_ADDR2 6 #define Q_ADDR3 7 #define Q_ADDR4 8 +#define Q_RA 9 +#define Q_TA 10 #define Q_DEFAULT 0 #define Q_UNDEF 255 diff --git a/grammar.y b/grammar.y index 4c52579..cbb9363 100644 --- a/grammar.y +++ b/grammar.y @@ -277,7 +277,7 @@ pfaction_to_num(const char *action) %token TK_BROADCAST TK_MULTICAST %token NUM INBOUND OUTBOUND %token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION -%token TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4 +%token TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA %token LINK %token GEQ LEQ NEQ %token ID EID HID HID6 AID @@ -442,6 +442,8 @@ dqual: SRC { $$ = Q_SRC; } | ADDR2 { $$ = Q_ADDR2; } | ADDR3 { $$ = Q_ADDR3; } | ADDR4 { $$ = Q_ADDR4; } + | RA { $$ = Q_RA; } + | TA { $$ = Q_TA; } ; /* address type qualifiers */ aqual: HOST { $$ = Q_HOST; } diff --git a/pcap-filter.manmisc.in b/pcap-filter.manmisc.in index 6b826e3..d7b4b0a 100644 --- a/pcap-filter.manmisc.in +++ b/pcap-filter.manmisc.in @@ -65,6 +65,8 @@ Possible directions are .BR dst , .BR "src or dst" , .BR "src and dst" , +.BR ra , +.BR ta , .BR addr1 , .BR addr2 , .BR addr3 , @@ -76,6 +78,8 @@ there is no dir qualifier, .B "src or dst" is assumed. The +.BR ra , +.BR ta , .BR addr1 , .BR addr2 , .BR addr3 , @@ -472,6 +476,15 @@ and .B scrub (applies only to packets logged by OpenBSD's or FreeBSD's .BR pf (4)). +.IP "\fBwlan ra \fIehost\fR" +True if the IEEE 802.11 RA is +.IR ehost . +The RA field is used in all frames except for management frames. +.IP "\fBwlan ta \fIehost\fR" +True if the IEEE 802.11 TA is +.IR ehost . +The TA field is used in all frames except for management frames and +CTS (Clear To Send) and ACK (Acknowledgment) control frames. .IP "\fBwlan addr1 \fIehost\fR" True if the first IEEE 802.11 address is .IR ehost . @@ -490,7 +503,7 @@ True if the fourth IEEE 802.11 address, if present, is .IR ehost . The fourth address field is only used for WDS (Wireless Distribution System) frames. -.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR, \fBstp\fR, \fBipx\fR, \fInetbeui\fP" +.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR, \fBstp\fR, \fBipx\fR, \fBnetbeui\fP" Abbreviations for: .in +.5i .nf diff --git a/scanner.l b/scanner.l index 9b3e139..a061a7e 100644 --- a/scanner.l +++ b/scanner.l @@ -273,6 +273,8 @@ address1|addr1 return ADDR1; address2|addr2 return ADDR2; address3|addr3 return ADDR3; address4|addr4 return ADDR4; +ra return RA; +ta return TA; less return LESS; greater return GREATER;