diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2006-06-27 18:15:00 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2006-06-27 18:15:00 +0000 |
commit | 572fe340a46e8bfdf74116581daf399f2550cb31 (patch) | |
tree | 6062dc6e69bc9ff0bb594de4a06a1b33cb9ca630 /usr.sbin/hostapd/parse.y | |
parent | 9f20fad1da6878ec102e43c6cddc710d56eddc78 (diff) |
add new event rules to match optional elements of radiotap headers:
signal percentage, transmit rate and channel frequency.
ok and hints by jsg@ jmc@
Diffstat (limited to 'usr.sbin/hostapd/parse.y')
-rw-r--r-- | usr.sbin/hostapd/parse.y | 160 |
1 files changed, 156 insertions, 4 deletions
diff --git a/usr.sbin/hostapd/parse.y b/usr.sbin/hostapd/parse.y index 0ac01148b82..8ca6cd902c5 100644 --- a/usr.sbin/hostapd/parse.y +++ b/usr.sbin/hostapd/parse.y @@ -1,7 +1,7 @@ -/* $OpenBSD: parse.y,v 1.23 2006/06/01 22:09:09 reyk Exp $ */ +/* $OpenBSD: parse.y,v 1.24 2006/06/27 18:14:59 reyk Exp $ */ /* - * Copyright (c) 2004, 2005 Reyk Floeter <reyk@openbsd.org> + * Copyright (c) 2004, 2005, 2006 Reyk Floeter <reyk@openbsd.org> * Copyright (c) 2002 - 2005 Henning Brauer <henning@openbsd.org> * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Daniel Hartmeier. All rights reserved. @@ -40,6 +40,9 @@ #include <netinet/if_ether.h> #include <arpa/inet.h> +#include <net80211/ieee80211.h> +#include <net80211/ieee80211_radiotap.h> + #include <ctype.h> #include <errno.h> #include <event.h> @@ -101,6 +104,7 @@ typedef struct { char *string; long val; u_int16_t reason; + enum hostapd_op op; } v; int lineno; } YYSTYPE; @@ -119,12 +123,23 @@ u_int negative; frame.f_flags |= HOSTAPD_FRAME_F_##_m##_TABLE | (negative ? \ HOSTAPD_FRAME_F_##_m##_N : HOSTAPD_FRAME_F_##_m); \ } +#define HOSTAPD_MATCH_RADIOTAP(_x) { \ + if (hostapd_cfg.c_apme_dlt == DLT_IEEE802_11 || \ + (hostapd_cfg.c_apme_dlt == 0 && \ + HOSTAPD_DLT == DLT_IEEE802_11)) { \ + yyerror("option %s requires radiotap headers", #_x); \ + YYERROR; \ + } \ + frame.f_radiotap |= HOSTAPD_RADIOTAP_F(RSSI); \ + frame.f_flags |= HOSTAPD_FRAME_F_##_x; \ +} #define HOSTAPD_IAPP_FLAG(_f) { \ if (negative) \ hostapd_cfg.c_iapp.i_flags &= ~(HOSTAPD_IAPP_F_##_f); \ else \ hostapd_cfg.c_iapp.i_flags |= (HOSTAPD_IAPP_F_##_f); \ } + %} %token MODE INTERFACE IAPP HOSTAP MULTICAST BROADCAST SET SEC USEC @@ -134,7 +149,7 @@ u_int negative; %token ERROR CONST TABLE NODE DELETE ADD LOG VERBOSE LIMIT QUICK SKIP %token REASON UNSPECIFIED EXPIRE LEAVE ASSOC TOOMANY NOT AUTHED ASSOCED %token RESERVED RSN REQUIRED INCONSISTENT IE INVALID MIC FAILURE OPEN -%token ADDRESS PORT ON NOTIFY TTL INCLUDE ROUTE ROAMING +%token ADDRESS PORT ON NOTIFY TTL INCLUDE ROUTE ROAMING RSSI TXRATE FREQ %token <v.string> STRING %token <v.val> VALUE %type <v.val> number @@ -144,6 +159,10 @@ u_int negative; %type <v.string> table %type <v.string> string %type <v.authalg> authalg +%type <v.op> unaryop +%type <v.val> percent +%type <v.val> txrate +%type <v.val> freq %% @@ -410,7 +429,7 @@ nodeopt : DELETE frmmatch : ANY | frm frmmatchtype frmmatchdir frmmatchfrom frmmatchto - frmmatchbssid + frmmatchbssid frmmatchrtap ; frm : /* empty */ @@ -710,6 +729,42 @@ frmmatchbssid : /* any */ } ; +frmmatchrtap : /* empty */ + | frmmatchrtap_l + ; + +frmmatchrtap_l : frmmatchrtap_l frmmatchrtapopt + | frmmatchrtapopt + ; + +frmmatchrtapopt : RSSI unaryop percent + { + if (($2 == HOSTAPD_OP_GT && $3 == 100) || + ($2 == HOSTAPD_OP_LE && $3 == 100) || + ($2 == HOSTAPD_OP_LT && $3 == 0) || + ($2 == HOSTAPD_OP_GE && $3 == 0)) { + yyerror("absurd unary comparison"); + YYERROR; + } + + frame.f_rssi_op = $2; + frame.f_rssi = $3; + HOSTAPD_MATCH_RADIOTAP(RSSI); + } + | TXRATE unaryop txrate + { + frame.f_txrate_op = $2; + frame.f_txrate = $3; + HOSTAPD_MATCH_RADIOTAP(RATE); + } + | FREQ unaryop freq + { + frame.f_chan_op = $2; + frame.f_chan = $3; + HOSTAPD_MATCH_RADIOTAP(CHANNEL); + } + ; + frmmatchaddr : ANY { $$.flags = 0; @@ -997,6 +1052,100 @@ not : /* empty */ } ; +unaryop : /* any */ + { + $$ = HOSTAPD_OP_EQ; + } + | '=' + { + $$ = HOSTAPD_OP_EQ; + } + | '==' + { + $$ = HOSTAPD_OP_EQ; + } + | '!' + { + $$ = HOSTAPD_OP_NE; + } + | '!' '=' + { + $$ = HOSTAPD_OP_NE; + } + | '<' '=' + { + $$ = HOSTAPD_OP_LE; + } + | '<' + { + $$ = HOSTAPD_OP_LT; + } + | '>' '=' + { + $$ = HOSTAPD_OP_GE; + } + | '>' + { + $$ = HOSTAPD_OP_GT; + } + ; + +percent : STRING + { + double val; + char *cp; + + val = strtod($1, &cp); + if (cp == NULL || strcmp(cp, "%") != 0 || + val < 0 || val > 100) { + yyerror("invalid percentage: %s", $1); + free($1); + YYERROR; + } + free($1); + $$ = val; + } + ; + +txrate : STRING + { + double val; + char *cp; + + val = strtod($1, &cp) * 2; + if (cp == NULL || strcasecmp(cp, "mb") != 0 || + val != (int)val) { + yyerror("invalid rate: %s", $1); + free($1); + YYERROR; + } + free($1); + $$ = val; + } + ; + +freq : STRING + { + double val; + char *cp; + + val = strtod($1, &cp); + if (cp != NULL) { + if (strcasecmp(cp, "ghz") == 0) { + $$ = val * 1000; + } else if (strcasecmp(cp, "mhz") == 0) { + $$ = val; + } else + cp = NULL; + } + if (cp == NULL) { + yyerror("invalid frequency: %s", $1); + free($1); + YYERROR; + } + free($1); + } + ; %% /* @@ -1040,6 +1189,7 @@ lookup(char *token) { "expire", EXPIRE }, { "failure", FAILURE }, { "frame", FRAME }, + { "freq", FREQ }, { "from", FROM }, { "handle", HANDLE }, { "hostap", HOSTAP }, @@ -1083,12 +1233,14 @@ lookup(char *token) { "rsn", RSN }, { "sec", SEC }, { "set", SET }, + { "signal", RSSI }, { "skip", SKIP }, { "subtype", SUBTYPE }, { "table", TABLE }, { "to", TO }, { "toomany", TOOMANY }, { "ttl", TTL }, + { "txrate", TXRATE }, { "type", TYPE }, { "unspecified", UNSPECIFIED }, { "usec", USEC }, |