summaryrefslogtreecommitdiff
path: root/usr.sbin/hostapd/parse.y
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2006-06-27 18:15:00 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2006-06-27 18:15:00 +0000
commit572fe340a46e8bfdf74116581daf399f2550cb31 (patch)
tree6062dc6e69bc9ff0bb594de4a06a1b33cb9ca630 /usr.sbin/hostapd/parse.y
parent9f20fad1da6878ec102e43c6cddc710d56eddc78 (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.y160
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 },