aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/drivers/driver.h12
-rw-r--r--src/drivers/driver_nl80211.c13
-rw-r--r--wpa_supplicant/events.c26
3 files changed, 40 insertions, 11 deletions
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 53d1c25..d72c83b 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1,6 +1,6 @@
/*
* Driver interface definition
- * Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -3028,6 +3028,11 @@ union wpa_event_data {
* ie_len - Length of ie buffer in octets
*/
size_t ie_len;
+
+ /**
+ * locally_generated - Whether the frame was locally generated
+ */
+ int locally_generated;
} disassoc_info;
/**
@@ -3054,6 +3059,11 @@ union wpa_event_data {
* ie_len - Length of ie buffer in octets
*/
size_t ie_len;
+
+ /**
+ * locally_generated - Whether the frame was locally generated
+ */
+ int locally_generated;
} deauth_info;
/**
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index d407b0f..6af8cc9 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1,6 +1,6 @@
/*
* Driver interaction with Linux nl80211/cfg80211
- * Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
* Copyright (c) 2003-2004, Instant802 Networks, Inc.
* Copyright (c) 2005-2006, Devicescape Software, Inc.
* Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
@@ -1151,7 +1151,8 @@ static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
- struct nlattr *reason, struct nlattr *addr)
+ struct nlattr *reason, struct nlattr *addr,
+ struct nlattr *by_ap)
{
union wpa_event_data data;
@@ -1169,6 +1170,7 @@ static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
os_memset(&data, 0, sizeof(data));
if (reason)
data.disassoc_info.reason_code = nla_get_u16(reason);
+ data.disassoc_info.locally_generated = by_ap == NULL;
wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, &data);
}
@@ -1309,6 +1311,8 @@ static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
reason_code = le_to_host16(mgmt->u.deauth.reason_code);
if (type == EVENT_DISASSOC) {
+ event.disassoc_info.locally_generated =
+ !os_memcmp(mgmt->sa, drv->first_bss.addr, ETH_ALEN);
event.disassoc_info.addr = bssid;
event.disassoc_info.reason_code = reason_code;
if (frame + len > mgmt->u.disassoc.variable) {
@@ -1317,6 +1321,8 @@ static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
mgmt->u.disassoc.variable;
}
} else {
+ event.deauth_info.locally_generated =
+ !os_memcmp(mgmt->sa, drv->first_bss.addr, ETH_ALEN);
event.deauth_info.addr = bssid;
event.deauth_info.reason_code = reason_code;
if (frame + len > mgmt->u.deauth.variable) {
@@ -2083,7 +2089,8 @@ static void do_process_drv_event(struct wpa_driver_nl80211_data *drv,
break;
case NL80211_CMD_DISCONNECT:
mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
- tb[NL80211_ATTR_MAC]);
+ tb[NL80211_ATTR_MAC],
+ tb[NL80211_ATTR_DISCONNECTED_BY_AP]);
break;
case NL80211_CMD_MICHAEL_MIC_FAILURE:
mlme_event_michael_mic_failure(drv, tb);
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 7913666..c6538c9 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1,6 +1,6 @@
/*
* WPA Supplicant - Driver event processing
- * Copyright (c) 2003-2011, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -1543,7 +1543,8 @@ static int disconnect_reason_recoverable(u16 reason_code)
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
- u16 reason_code)
+ u16 reason_code,
+ int locally_generated)
{
const u8 *bssid;
int authenticating;
@@ -1579,6 +1580,7 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
if (wpa_s->wpa_state == WPA_COMPLETED &&
wpa_s->current_ssid &&
wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
+ !locally_generated &&
disconnect_reason_recoverable(reason_code)) {
/*
* It looks like the AP has dropped association with
@@ -1991,6 +1993,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
{
struct wpa_supplicant *wpa_s = ctx;
u16 reason_code = 0;
+ int locally_generated = 0;
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED &&
event != EVENT_INTERFACE_ENABLED &&
@@ -2032,8 +2035,10 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
case EVENT_DISASSOC:
wpa_dbg(wpa_s, MSG_DEBUG, "Disassociation notification");
if (data) {
- wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u",
- data->disassoc_info.reason_code);
+ wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u%s",
+ data->disassoc_info.reason_code,
+ data->disassoc_info.locally_generated ?
+ " (locally generated)" : "");
if (data->disassoc_info.addr)
wpa_dbg(wpa_s, MSG_DEBUG, " * address " MACSTR,
MAC2STR(data->disassoc_info.addr));
@@ -2052,6 +2057,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
#endif /* CONFIG_AP */
if (data) {
reason_code = data->disassoc_info.reason_code;
+ locally_generated =
+ data->disassoc_info.locally_generated;
wpa_hexdump(MSG_DEBUG, "Disassociation frame IE(s)",
data->disassoc_info.ie,
data->disassoc_info.ie_len);
@@ -2071,8 +2078,12 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
"Deauthentication notification");
if (data) {
reason_code = data->deauth_info.reason_code;
- wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u",
- data->deauth_info.reason_code);
+ locally_generated =
+ data->deauth_info.locally_generated;
+ wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u%s",
+ data->deauth_info.reason_code,
+ data->deauth_info.locally_generated ?
+ " (locally generated)" : "");
if (data->deauth_info.addr) {
wpa_dbg(wpa_s, MSG_DEBUG, " * address "
MACSTR,
@@ -2104,7 +2115,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
break;
}
#endif /* CONFIG_AP */
- wpa_supplicant_event_disassoc(wpa_s, reason_code);
+ wpa_supplicant_event_disassoc(wpa_s, reason_code,
+ locally_generated);
break;
case EVENT_MICHAEL_MIC_FAILURE:
wpa_supplicant_event_michael_mic_failure(wpa_s, data);