summaryrefslogtreecommitdiff
path: root/usr.sbin/hostapd
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2005-09-30 16:50:04 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2005-09-30 16:50:04 +0000
commit6bd954e164539db60d4af401780384d6a7c13b39 (patch)
tree1e585148910e904d12c143e07d2fa50b6ada1b27 /usr.sbin/hostapd
parentf90eba61558219c16a257f4788d9167eb3fbd7d6 (diff)
implement a way to match IEEE 802.11 flooding. this will help to detect
known DoS attacks, like de-auth flooding against wireless networks. an example is provided in the manual page. "or could you just got for it?", deraadt@
Diffstat (limited to 'usr.sbin/hostapd')
-rw-r--r--usr.sbin/hostapd/handle.c39
-rw-r--r--usr.sbin/hostapd/hostapd.conf.533
-rw-r--r--usr.sbin/hostapd/hostapd.h6
-rw-r--r--usr.sbin/hostapd/parse.y26
4 files changed, 89 insertions, 15 deletions
diff --git a/usr.sbin/hostapd/handle.c b/usr.sbin/hostapd/handle.c
index 5ce37022dc4..3a2a78734b9 100644
--- a/usr.sbin/hostapd/handle.c
+++ b/usr.sbin/hostapd/handle.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: handle.c,v 1.2 2005/07/04 16:48:55 reyk Exp $ */
+/* $OpenBSD: handle.c,v 1.3 2005/09/30 16:50:03 reyk Exp $ */
/*
* Copyright (c) 2005 Reyk Floeter <reyk@vantronix.net>
@@ -107,7 +107,7 @@ hostapd_handle_frame(struct hostapd_config *cfg, struct hostapd_frame *frame,
u_int8_t *wfrom, *wto, *wbssid;
struct timeval t_now;
u_int32_t flags;
- int offset;
+ int offset, min_rate = 0;
if ((offset = hostapd_apme_offset(cfg, buf, len)) < 0)
return (0);
@@ -116,9 +116,11 @@ hostapd_handle_frame(struct hostapd_config *cfg, struct hostapd_frame *frame,
mh = &frame->f_frame;
flags = frame->f_flags;
+ /* Get timestamp */
+ gettimeofday(&t_now, NULL);
+
/* Handle optional limit */
if (frame->f_limit.tv_sec || frame->f_limit.tv_usec) {
- gettimeofday(&t_now, NULL);
if (timercmp(&t_now, &frame->f_then, <))
return (0);
timeradd(&t_now, &frame->f_limit, &frame->f_then);
@@ -193,10 +195,34 @@ hostapd_handle_frame(struct hostapd_config *cfg, struct hostapd_frame *frame,
if ((flags & HOSTAPD_FRAME_F_M) != 0)
return (0);
+ /* Handle optional minimal rate */
+ if (frame->f_rate && frame->f_rate_intval) {
+ frame->f_rate_delay = t_now.tv_sec - frame->f_last.tv_sec;
+ if (frame->f_rate_delay < frame->f_rate_intval) {
+ frame->f_rate_cnt++;
+ if (frame->f_rate_cnt < frame->f_rate)
+ min_rate = 1;
+ } else {
+ min_rate = 1;
+ frame->f_rate_cnt = 0;
+ }
+ }
+
+ /* Update timestamp for the last match of this event */
+ if (frame->f_rate_cnt == 0 || min_rate == 0)
+ bcopy(&t_now, &frame->f_last, sizeof(struct timeval));
+
+ /* Return if the minimal rate is not reached, yet */
+ if (min_rate)
+ return (0);
+
if (hostapd_handle_action(cfg, frame, wfrom, wto, wbssid, buf,
len) != 0)
return (0);
+ /* Reset minimal rate counter after successfully handled the frame */
+ frame->f_rate_cnt = 0;
+
return ((frame->f_flags & HOSTAPD_FRAME_F_RET_M) >>
HOSTAPD_FRAME_F_RET_S);
}
@@ -228,7 +254,12 @@ hostapd_handle_action(struct hostapd_config *cfg, struct hostapd_frame *frame,
case HOSTAPD_ACTION_LOG:
/* Log frame to syslog/stderr */
- hostapd_printf("%s: ", cfg->c_apme_iface);
+ if (frame->f_rate && frame->f_rate_intval) {
+ hostapd_printf("%s: (rate: %ld/%ld sec) ",
+ cfg->c_apme_iface, frame->f_rate_cnt,
+ frame->f_rate_delay + 1);
+ } else
+ hostapd_printf("%s: ", cfg->c_apme_iface);
hostapd_print_ieee80211(cfg->c_apme_dlt, frame->f_action_flags &
HOSTAPD_ACTION_VERBOSE, buf, len);
diff --git a/usr.sbin/hostapd/hostapd.conf.5 b/usr.sbin/hostapd/hostapd.conf.5
index a606ec91a62..8d032008bac 100644
--- a/usr.sbin/hostapd/hostapd.conf.5
+++ b/usr.sbin/hostapd/hostapd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: hostapd.conf.5,v 1.11 2005/09/29 23:57:00 reyk Exp $
+.\" $OpenBSD: hostapd.conf.5,v 1.12 2005/09/30 16:50:03 reyk Exp $
.\"
.\" Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
.\"
@@ -162,13 +162,14 @@ event rules are single line statements beginning with
the mandatory
.Ic hostap handle
keywords and optional rule options, frame matching,
-a specified action, and a limit:
+a specified action, a limit, and a minimal rate:
.Bd -filled -offset indent
.Ic hostap handle
.Op Ar option
.Op Ar frame
.Op Ar action
.Op Ar limit
+.Op Ar rate
.Ed
.Pp
The optional parts are defined below.
@@ -387,6 +388,10 @@ is
Write informational messages to the local system log (see
.Xr syslogd 8 )
or standard error.
+If the
+.Sx Rule Rate
+has been specified,
+log will print the actual rate.
.It Ic node add | delete Ar lladdr
Add or remove the specified node from the internal kernel
node table.
@@ -408,6 +413,23 @@ to protect
.Xr hostapd 8
against excessive flooding with IEEE 802.11 frames.
For example, beacon frames will be normally received every 100 ms.
+.Ss Rule Rate
+It is possible to tell
+.Xr hostapd 8
+to trigger the action only after a specific
+.Ic rate
+of matched frames.
+.Bd -filled -offset indent
+.Ic rate
+.Ar number
+.Ar /
+.Ar number
+.Ic sec
+.Ed
+.Pp
+This will help to detect excessive flooding of IEEE 802.11 frames.
+For example, de-auth flooding is a DoS (Denial of Service) attack
+against IEEE 802.11 wireless networks.
.Ss Management Frame Subtypes
The
.Ar subtype
@@ -519,6 +541,13 @@ wireless access point to access point communication.
hostap handle type management subtype probe request \\
with log
+# Detect flooding of management frames except beacons.
+# This will detect some possible Denial of Service attacks
+# against the IEEE 802.11 protocol.
+hostap handle skip type management subtype ! beacon \\
+ with log \\
+ rate 100 / 10 sec
+
# Log rogue accesspoints via IAPP, limited to every second,
# and skip further IAPP processing.
hostap handle skip type management subtype beacon bssid !<myess> \\
diff --git a/usr.sbin/hostapd/hostapd.h b/usr.sbin/hostapd/hostapd.h
index 95b88d9c4ae..f57496e8187 100644
--- a/usr.sbin/hostapd/hostapd.h
+++ b/usr.sbin/hostapd/hostapd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hostapd.h,v 1.6 2005/09/09 13:21:13 reyk Exp $ */
+/* $OpenBSD: hostapd.h,v 1.7 2005/09/30 16:50:03 reyk Exp $ */
/*
* Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
@@ -243,7 +243,9 @@ struct hostapd_frame {
HOSTAPD_FRAME_F_BSSID_N)
struct hostapd_table *f_from, *f_to, *f_bssid;
- struct timeval f_limit, f_then;
+ struct timeval f_limit, f_then, f_last;
+ long f_rate, f_rate_intval;
+ long f_rate_cnt, f_rate_delay;
enum hostapd_action f_action;
u_int32_t f_action_flags;
diff --git a/usr.sbin/hostapd/parse.y b/usr.sbin/hostapd/parse.y
index f1a275856d8..31697a4c1b2 100644
--- a/usr.sbin/hostapd/parse.y
+++ b/usr.sbin/hostapd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.10 2005/09/30 14:57:30 reyk Exp $ */
+/* $OpenBSD: parse.y,v 1.11 2005/09/30 16:50:03 reyk Exp $ */
/*
* Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
@@ -119,7 +119,7 @@ u_int negative;
%token MODE INTERFACE IAPP HOSTAP MULTICAST BROADCAST SET SEC USEC
%token HANDLE TYPE SUBTYPE FROM TO BSSID WITH FRAME RADIOTAP NWID PASSIVE
%token MANAGEMENT DATA PROBE BEACON ATIM ANY DS NO DIR RESEND RANDOM
-%token AUTH DEAUTH ASSOC DISASSOC REASSOC REQUEST RESPONSE PCAP
+%token AUTH DEAUTH ASSOC DISASSOC REASSOC REQUEST RESPONSE PCAP RATE
%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
@@ -205,17 +205,15 @@ event : HOSTAP HANDLE
} eventopt frmmatch {
/* IEEE 802.11 raw frame to send as an action */
frame_ieee80211 = &frame.f_action_data.a_frame;
- } action limit {
- struct timeval t_now;
-
+ } action limit rate {
if ((frame_ptr = (struct hostapd_frame *)calloc(1,
sizeof(struct hostapd_frame))) == NULL) {
yyerror("calloc");
YYERROR;
}
- gettimeofday(&t_now, NULL);
- timeradd(&t_now, &frame.f_limit, &frame.f_then);
+ gettimeofday(&frame.f_last, NULL);
+ timeradd(&frame.f_last, &frame.f_limit, &frame.f_then);
bcopy(&frame, frame_ptr, sizeof(struct hostapd_frame));
TAILQ_INSERT_TAIL(&hostapd_cfg.c_frames,
@@ -310,6 +308,19 @@ limit : /* empty */
}
;
+rate : /* empty */
+ | RATE number '/' number SEC
+ {
+ if (!($2 && $4)) {
+ yyerror("invalid rate");
+ YYERROR;
+ }
+
+ frame.f_rate = $2;
+ frame.f_rate_intval = $4;
+ }
+ ;
+
frmmatchtype : /* any */
| TYPE ANY
| TYPE not DATA
@@ -916,6 +927,7 @@ lookup(char *token)
{ "quick", QUICK },
{ "radiotap", RADIOTAP },
{ "random", RANDOM },
+ { "rate", RATE },
{ "reason", REASON },
{ "reassoc", REASSOC },
{ "request", REQUEST },