dect
/
libpcap
Archived
13
0
Fork 0

Support OpenBSD's "addr1", "addr2", "addr3", and "addr4" link-layer

address types for 802.11.

Support the OpenBSD names for some of the 802.11 frame types.

Support OpenBSD's "dir" keyword for 802.11 frame directions.
This commit is contained in:
guy 2007-11-18 02:03:52 +00:00
parent 70727eb8d2
commit 740fb4355d
5 changed files with 223 additions and 56 deletions

View File

@ -21,7 +21,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.301 2007-11-10 21:53:05 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.302 2007-11-18 02:03:52 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -68,6 +68,7 @@ static const char rcsid[] _U_ =
#include "nlpid.h" #include "nlpid.h"
#include "llc.h" #include "llc.h"
#include "gencode.h" #include "gencode.h"
#include "ieee80211.h"
#include "atmuni31.h" #include "atmuni31.h"
#include "sunatmpos.h" #include "sunatmpos.h"
#include "ppp.h" #include "ppp.h"
@ -3840,6 +3841,55 @@ gen_wlanhostop(eaddr, dir)
gen_and(b1, b0); gen_and(b1, b0);
return b0; return b0;
/*
* XXX - add RA, TA, and BSSID keywords?
*/
case Q_ADDR1:
return (gen_bcmp(OR_LINK, 4, 6, eaddr));
case Q_ADDR2:
/*
* 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);
b1 = gen_bcmp(OR_LINK, 10, 6, eaddr);
gen_and(b2, b1);
return b1;
case Q_ADDR3:
/*
* Not present in control frames.
*/
b0 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
IEEE80211_FC0_TYPE_MASK);
gen_not(b0);
b1 = gen_bcmp(OR_LINK, 16, 6, eaddr);
gen_and(b0, b1);
return b1;
case Q_ADDR4:
/*
* Present only if the direction mask has both "From DS"
* and "To DS" set. Neither control frames nor management
* frames should have both of those set, so we don't
* check the frame type.
*/
b0 = gen_mcmp(OR_LINK, 1, BPF_B,
IEEE80211_FC1_DIR_DSTODS, IEEE80211_FC1_DIR_MASK);
b1 = gen_bcmp(OR_LINK, 24, 6, eaddr);
gen_and(b0, b1);
return b1;
case Q_AND: case Q_AND:
b0 = gen_wlanhostop(eaddr, Q_SRC); b0 = gen_wlanhostop(eaddr, Q_SRC);
b1 = gen_wlanhostop(eaddr, Q_DST); b1 = gen_wlanhostop(eaddr, Q_DST);
@ -7290,6 +7340,31 @@ gen_p80211_type(int type, int mask)
bpf_error("802.11 link-layer types supported only on 802.11"); bpf_error("802.11 link-layer types supported only on 802.11");
/* NOTREACHED */ /* NOTREACHED */
} }
return (b0);
}
struct block *
gen_p80211_fcdir(int fcdir)
{
struct block *b0;
switch (linktype) {
case DLT_IEEE802_11:
case DLT_IEEE802_11_RADIO_AVS:
case DLT_IEEE802_11_RADIO:
case DLT_PRISM_HEADER:
break;
default:
bpf_error("frame direction supported only with 802.11 headers");
/* NOTREACHED */
}
b0 = gen_mcmp(OR_LINK, 1, BPF_B, (bpf_int32)fcdir,
(bpf_u_int32)IEEE80211_FC1_DIR_MASK);
return (b0); return (b0);
} }

View File

@ -18,7 +18,7 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* *
* @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.70 2007-06-11 10:04:25 guy Exp $ (LBL) * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.71 2007-11-18 02:03:52 guy Exp $ (LBL)
*/ */
/* /*
@ -132,6 +132,10 @@
#define Q_DST 2 #define Q_DST 2
#define Q_OR 3 #define Q_OR 3
#define Q_AND 4 #define Q_AND 4
#define Q_ADDR1 5
#define Q_ADDR2 6
#define Q_ADDR3 7
#define Q_ADDR4 8
#define Q_DEFAULT 0 #define Q_DEFAULT 0
#define Q_UNDEF 255 #define Q_UNDEF 255
@ -313,6 +317,7 @@ struct block *gen_pf_action(int);
struct block *gen_pf_dir(int); struct block *gen_pf_dir(int);
struct block *gen_p80211_type(int, int); struct block *gen_p80211_type(int, int);
struct block *gen_p80211_fcdir(int);
void bpf_optimize(struct block **); void bpf_optimize(struct block **);
void bpf_error(const char *, ...) void bpf_error(const char *, ...)

182
grammar.y
View File

@ -22,7 +22,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.100 2007-11-14 00:54:35 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.101 2007-11-18 02:03:52 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -68,9 +68,91 @@ struct rtentry;
(q).dir = (d),\ (q).dir = (d),\
(q).addr = (a) (q).addr = (a)
static const char *ieee80211_mgt_names[] = IEEE80211_MGT_SUBTYPE_NAMES; struct tok {
static const char *ieee80211_ctl_names[] = IEEE80211_CTL_SUBTYPE_NAMES; int v; /* value */
static const char *ieee80211_data_names[] = IEEE80211_DATA_SUBTYPE_NAMES; const char *s; /* string */
};
static const struct tok ieee80211_types[] = {
{ IEEE80211_FC0_TYPE_DATA, "data" },
{ IEEE80211_FC0_TYPE_MGT, "mgt" },
{ IEEE80211_FC0_TYPE_MGT, "management" },
{ IEEE80211_FC0_TYPE_CTL, "ctl" },
{ IEEE80211_FC0_TYPE_CTL, "control" },
{ 0, NULL }
};
static const struct tok ieee80211_mgt_subtypes[] = {
{ IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assocreq" },
{ IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assoc-req" },
{ IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assocresp" },
{ IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assoc-resp" },
{ IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassocreq" },
{ IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassoc-req" },
{ IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassocresp" },
{ IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassoc-resp" },
{ IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probereq" },
{ IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probe-req" },
{ IEEE80211_FC0_SUBTYPE_PROBE_RESP, "proberesp" },
{ IEEE80211_FC0_SUBTYPE_PROBE_RESP, "probe-resp" },
{ IEEE80211_FC0_SUBTYPE_BEACON, "beacon" },
{ IEEE80211_FC0_SUBTYPE_ATIM, "atim" },
{ IEEE80211_FC0_SUBTYPE_DISASSOC, "disassoc" },
{ IEEE80211_FC0_SUBTYPE_DISASSOC, "disassociation" },
{ IEEE80211_FC0_SUBTYPE_AUTH, "auth" },
{ IEEE80211_FC0_SUBTYPE_AUTH, "authentication" },
{ IEEE80211_FC0_SUBTYPE_DEAUTH, "deauth" },
{ IEEE80211_FC0_SUBTYPE_DEAUTH, "deauthentication" },
{ 0, NULL }
};
static const struct tok ieee80211_ctl_subtypes[] = {
{ IEEE80211_FC0_SUBTYPE_PS_POLL, "ps-poll" },
{ IEEE80211_FC0_SUBTYPE_RTS, "rts" },
{ IEEE80211_FC0_SUBTYPE_CTS, "cts" },
{ IEEE80211_FC0_SUBTYPE_ACK, "ack" },
{ IEEE80211_FC0_SUBTYPE_CF_END, "cf-end" },
{ IEEE80211_FC0_SUBTYPE_CF_END_ACK, "cf-end-ack" },
{ 0, NULL }
};
static const struct tok ieee80211_data_subtypes[] = {
{ IEEE80211_FC0_SUBTYPE_DATA, "data" },
{ IEEE80211_FC0_SUBTYPE_CF_ACK, "data-cf-ack" },
{ IEEE80211_FC0_SUBTYPE_CF_POLL, "data-cf-poll" },
{ IEEE80211_FC0_SUBTYPE_CF_ACPL, "data-cf-ack-poll" },
{ IEEE80211_FC0_SUBTYPE_NODATA, "null" },
{ IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK, "cf-ack" },
{ IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "cf-poll" },
{ IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "cf-ack-poll" },
{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA, "qos-data" },
{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK, "qos-data-cf-ack" },
{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL, "qos-data-cf-poll" },
{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL, "qos-data-cf-ack-poll" },
{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA, "qos" },
{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "qos-cf-poll" },
{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "qos-cf-ack-poll" },
{ 0, NULL }
};
struct type2tok {
int type;
const struct tok *tok;
};
static const struct type2tok ieee80211_type_subtypes[] = {
{ IEEE80211_FC0_TYPE_MGT, ieee80211_mgt_subtypes },
{ IEEE80211_FC0_TYPE_CTL, ieee80211_ctl_subtypes },
{ IEEE80211_FC0_TYPE_DATA, ieee80211_data_subtypes },
{ 0, NULL }
};
static int
str2tok(const char *str, const struct tok *toks)
{
int i;
for (i = 0; toks[i].s != NULL; i++) {
if (pcap_strcasecmp(toks[i].s, str) == 0)
return (toks[i].v);
}
return (-1);
}
int n_errors = 0; int n_errors = 0;
@ -194,6 +276,7 @@ pfaction_to_num(const char *action)
%token TK_BROADCAST TK_MULTICAST %token TK_BROADCAST TK_MULTICAST
%token NUM INBOUND OUTBOUND %token NUM INBOUND OUTBOUND
%token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION %token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
%token TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4
%token LINK %token LINK
%token GEQ LEQ NEQ %token GEQ LEQ NEQ
%token ID EID HID HID6 AID %token ID EID HID HID6 AID
@ -212,13 +295,12 @@ pfaction_to_num(const char *action)
%token RADIO %token RADIO
%token FISU LSSU MSU %token FISU LSSU MSU
%token SIO OPC DPC SLS %token SIO OPC DPC SLS
%token TYPE SUBTYPE
%type <s> ID %type <s> ID
%type <e> EID %type <e> EID
%type <e> AID %type <e> AID
%type <s> HID HID6 %type <s> HID HID6
%type <i> NUM action reason type subtype type_subtype %type <i> NUM action reason type subtype type_subtype dir
%left OR AND %left OR AND
%nonassoc '!' %nonassoc '!'
@ -355,6 +437,10 @@ dqual: SRC { $$ = Q_SRC; }
| DST OR SRC { $$ = Q_OR; } | DST OR SRC { $$ = Q_OR; }
| SRC AND DST { $$ = Q_AND; } | SRC AND DST { $$ = Q_AND; }
| DST AND SRC { $$ = Q_AND; } | DST AND SRC { $$ = Q_AND; }
| ADDR1 { $$ = Q_ADDR1; }
| ADDR2 { $$ = Q_ADDR2; }
| ADDR3 { $$ = Q_ADDR3; }
| ADDR4 { $$ = Q_ADDR4; }
; ;
/* address type qualifiers */ /* address type qualifiers */
aqual: HOST { $$ = Q_HOST; } aqual: HOST { $$ = Q_HOST; }
@ -441,71 +527,67 @@ p80211: TYPE type SUBTYPE subtype
IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_TYPE_MASK |
IEEE80211_FC0_SUBTYPE_MASK); IEEE80211_FC0_SUBTYPE_MASK);
} }
| DIR dir { $$ = gen_p80211_fcdir($2); }
; ;
type: NUM type: NUM
| ID { const char *names[] = IEEE80211_TYPE_NAMES; | ID { $$ = str2tok($1, ieee80211_types);
int i, lim; if ($$ == -1)
lim = (IEEE80211_FC0_TYPE_MASK >> IEEE80211_FC0_TYPE_SHIFT) + 1;
for (i = 0; i < lim; ++i) {
if (pcap_strcasecmp($1, names[i]) == 0) {
$$ = i << IEEE80211_FC0_TYPE_SHIFT;
break;
}
}
if (i == lim)
bpf_error("unknown 802.11 type name"); bpf_error("unknown 802.11 type name");
} }
; ;
subtype: NUM subtype: NUM
| ID { const char **names; | ID { const struct tok *types = NULL;
int i, lim; int i;
if ($<i>-1 == IEEE80211_FC0_TYPE_MGT) for (i = 0;; i++) {
names = ieee80211_mgt_names; if (ieee80211_type_subtypes[i].tok == NULL) {
else if ($<i>-1 == IEEE80211_FC0_TYPE_CTL) /* Ran out of types */
names = ieee80211_ctl_names; bpf_error("unknown 802.11 type");
else if ($<i>-1 == IEEE80211_FC0_TYPE_DATA) break;
names = ieee80211_data_names; }
else if ($<i>-1 == ieee80211_type_subtypes[i].type) {
bpf_error("unknown 802.11 type"); types = ieee80211_type_subtypes[i].tok;
lim = (IEEE80211_FC0_SUBTYPE_MASK >> IEEE80211_FC0_SUBTYPE_SHIFT) + 1;
for (i = 0; i < lim; ++i) {
if (pcap_strcasecmp($1, names[i]) == 0) {
$$ = i << IEEE80211_FC0_SUBTYPE_SHIFT;
break; break;
} }
} }
if (i == lim)
bpf_error("unknown 802.11 subtype name"); $$ = str2tok($1, types);
if ($$ == -1)
bpf_error("unknown 802.11 subtype name");
} }
; ;
type_subtype: ID { const char **sub_names[] = { type_subtype: ID { int i;
ieee80211_mgt_names, for (i = 0;; i++) {
ieee80211_ctl_names, if (ieee80211_type_subtypes[i].tok == NULL) {
ieee80211_data_names /* Ran out of types */
}; bpf_error("unknown 802.11 type name");
int i, j, lim, sub_lim; break;
sub_lim = sizeof(sub_names) / sizeof(sub_names[0]);
lim = (IEEE80211_FC0_SUBTYPE_MASK >> IEEE80211_FC0_SUBTYPE_SHIFT) + 1;
for (i = 0; i < sub_lim; ++i) {
const char **names = sub_names[i];
for (j = 0; j < lim; ++j) {
if (pcap_strcasecmp($1, names[j]) == 0)
break;
} }
if (j != lim) { $$ = str2tok($1, ieee80211_type_subtypes[i].tok);
$$ = (i << IEEE80211_FC0_TYPE_SHIFT) | if ($$ != -1) {
(j << IEEE80211_FC0_SUBTYPE_SHIFT); $$ |= ieee80211_type_subtypes[i].type;
break; break;
} }
} }
if (i == sub_lim)
bpf_error("unknown 802.11 subtype name");
} }
; ;
dir: NUM
| ID { if (pcap_strcasecmp($1, "nods") == 0)
$$ = IEEE80211_FC1_DIR_NODS;
else if (pcap_strcasecmp($1, "tods") == 0)
$$ = IEEE80211_FC1_DIR_TODS;
else if (pcap_strcasecmp($1, "fromds") == 0)
$$ = IEEE80211_FC1_DIR_FROMDS;
else if (pcap_strcasecmp($1, "dstods") == 0)
$$ = IEEE80211_FC1_DIR_DSTODS;
else
bpf_error("unknown 802.11 direction");
}
;
reason: NUM { $$ = $1; } reason: NUM { $$ = $1; }
| ID { $$ = pfreason_to_num($1); } | ID { $$ = pfreason_to_num($1); }
; ;

View File

@ -74,9 +74,9 @@
#define IEEE80211_FC0_SUBTYPE_CF_POLL 0x20 #define IEEE80211_FC0_SUBTYPE_CF_POLL 0x20
#define IEEE80211_FC0_SUBTYPE_CF_ACPL 0x30 #define IEEE80211_FC0_SUBTYPE_CF_ACPL 0x30
#define IEEE80211_FC0_SUBTYPE_NODATA 0x40 #define IEEE80211_FC0_SUBTYPE_NODATA 0x40
#define IEEE80211_FC0_SUBTYPE_CFACK 0x50 #define IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK 0x50
#define IEEE80211_FC0_SUBTYPE_CFPOLL 0x60 #define IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL 0x60
#define IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK 0x70 #define IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL 0x70
#define IEEE80211_FC0_SUBTYPE_QOS 0x80 #define IEEE80211_FC0_SUBTYPE_QOS 0x80
#define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0 #define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0

View File

@ -22,7 +22,7 @@
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.110 2007-06-11 10:04:25 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.111 2007-11-18 02:03:52 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -249,6 +249,11 @@ gateway return GATEWAY;
type return TYPE; type return TYPE;
subtype return SUBTYPE; subtype return SUBTYPE;
direction|dir return DIR;
address1|addr1 return ADDR1;
address2|addr2 return ADDR2;
address3|addr3 return ADDR3;
address4|addr4 return ADDR4;
less return LESS; less return LESS;
greater return GREATER; greater return GREATER;