]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add BSSID and reason code (if available) to disconnect event
authorJouni Malinen <j@w1.fi>
Sun, 11 Apr 2010 18:25:15 +0000 (21:25 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 11 Apr 2010 18:25:15 +0000 (21:25 +0300)
This adds more details into the CTRL-EVENT-DISCONNECTED event to
make it easier to figure out which network was disconnected in some
race conditions and to what could have been the reason for
disconnection. The reason code is currently only available with
the nl80211 driver wrapper.

src/drivers/driver.h
src/drivers/driver_nl80211.c
wpa_supplicant/events.c

index 5b614f605938be387542d1104b0f257c13ebe6af..fa49da454e83ab58b47b5eced07fcbd9424827ad 100644 (file)
@@ -2140,6 +2140,12 @@ union wpa_event_data {
                 * addr - Station address (for AP mode)
                 */
                const u8 *addr;
+
+               /**
+                * reason_code - Reason Code (host byte order) used in
+                *      Deauthentication frame
+                */
+               u16 reason_code;
        } disassoc_info;
 
        /**
@@ -2150,6 +2156,12 @@ union wpa_event_data {
                 * addr - Station address (for AP mode)
                 */
                const u8 *addr;
+
+               /**
+                * reason_code - Reason Code (host byte order) used in
+                *      Deauthentication frame
+                */
+               u16 reason_code;
        } deauth_info;
 
        /**
index cbed985306a631c09ccf192edd6048ade94a83db..6ea2999c70ae99df767e8557ebf4af9722b3f753 100644 (file)
@@ -660,6 +660,37 @@ static void mlme_event_action_tx_status(struct wpa_driver_nl80211_data *drv,
 }
 
 
+static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
+                                      enum wpa_event_type type,
+                                      const u8 *frame, size_t len)
+{
+       const struct ieee80211_mgmt *mgmt;
+       union wpa_event_data event;
+       const u8 *bssid = NULL;
+       u16 reason_code = 0;
+
+       drv->associated = 0;
+       os_memset(&event, 0, sizeof(event));
+
+       mgmt = (const struct ieee80211_mgmt *) frame;
+       if (len >= 24)
+               bssid = mgmt->bssid;
+       /* Note: Same offset for Reason Code in both frame subtypes */
+       if (len >= 24 + sizeof(mgmt->u.deauth))
+               reason_code = le_to_host16(mgmt->u.deauth.reason_code);
+
+       if (type == EVENT_DISASSOC) {
+               event.disassoc_info.addr = bssid;
+               event.disassoc_info.reason_code = reason_code;
+       } else {
+               event.deauth_info.addr = bssid;
+               event.deauth_info.reason_code = reason_code;
+       }
+
+       wpa_supplicant_event(drv->ctx, type, &event);
+}
+
+
 static void mlme_event(struct wpa_driver_nl80211_data *drv,
                       enum nl80211_commands cmd, struct nlattr *frame,
                       struct nlattr *addr, struct nlattr *timed_out,
@@ -689,12 +720,12 @@ static void mlme_event(struct wpa_driver_nl80211_data *drv,
                mlme_event_assoc(drv, nla_data(frame), nla_len(frame));
                break;
        case NL80211_CMD_DEAUTHENTICATE:
-               drv->associated = 0;
-               wpa_supplicant_event(drv->ctx, EVENT_DEAUTH, NULL);
+               mlme_event_deauth_disassoc(drv, EVENT_DEAUTH,
+                                          nla_data(frame), nla_len(frame));
                break;
        case NL80211_CMD_DISASSOCIATE:
-               drv->associated = 0;
-               wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
+               mlme_event_deauth_disassoc(drv, EVENT_DISASSOC,
+                                          nla_data(frame), nla_len(frame));
                break;
        case NL80211_CMD_ACTION:
                mlme_event_action(drv, freq, nla_data(frame), nla_len(frame));
@@ -895,6 +926,7 @@ static int process_event(struct nl_msg *msg, void *arg)
        struct wpa_driver_nl80211_data *drv = arg;
        struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
        struct nlattr *tb[NL80211_ATTR_MAX + 1];
+       union wpa_event_data data;
 
        nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
                  genlmsg_attrlen(gnlh, 0), NULL);
@@ -968,7 +1000,11 @@ static int process_event(struct nl_msg *msg, void *arg)
                        break;
                }
                drv->associated = 0;
-               wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
+               os_memset(&data, 0, sizeof(data));
+               if (tb[NL80211_ATTR_REASON_CODE])
+                       data.disassoc_info.reason_code =
+                               nla_get_u16(tb[NL80211_ATTR_REASON_CODE]);
+               wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, &data);
                break;
        case NL80211_CMD_MICHAEL_MIC_FAILURE:
                mlme_event_michael_mic_failure(drv, tb);
index 67a164afd7e812275a41369e257bf03bf3accb9f..2f3a303c467cda73991967a3e86a628c1734ed9a 100644 (file)
@@ -1264,7 +1264,8 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
 }
 
 
-static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s)
+static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
+                                         u16 reason_code)
 {
        const u8 *bssid;
 #ifdef CONFIG_SME
@@ -1298,9 +1299,11 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s)
                bssid = wpa_s->pending_bssid;
        wpa_blacklist_add(wpa_s, bssid);
        wpa_sm_notify_disassoc(wpa_s->wpa);
-       wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - "
-               "remove keys");
+       wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR
+               " reason=%d",
+               MAC2STR(bssid), reason_code);
        if (wpa_supplicant_dynamic_keys(wpa_s)) {
+               wpa_printf(MSG_DEBUG, "Disconnect event - remove keys");
                wpa_s->keys_cleared = 0;
                wpa_clear_keys(wpa_s, wpa_s->bssid);
        }
@@ -1578,6 +1581,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                          union wpa_event_data *data)
 {
        struct wpa_supplicant *wpa_s = ctx;
+       u16 reason_code = 0;
 
        switch (event) {
        case EVENT_AUTH:
@@ -1595,12 +1599,17 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                        break;
                }
 #endif /* CONFIG_AP */
+               if (data)
+                       reason_code = data->deauth_info.reason_code;
                if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
                        sme_event_disassoc(wpa_s, data);
                /* fall through */
        case EVENT_DEAUTH:
-               if (event == EVENT_DEAUTH)
+               if (event == EVENT_DEAUTH) {
                        wpa_printf(MSG_DEBUG, "Deauthentication notification");
+                       if (data)
+                               reason_code = data->deauth_info.reason_code;
+               }
 #ifdef CONFIG_AP
                if (wpa_s->ap_iface && data) {
                        hostapd_notif_disassoc(wpa_s->ap_iface->bss[0],
@@ -1608,7 +1617,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                        break;
                }
 #endif /* CONFIG_AP */
-               wpa_supplicant_event_disassoc(wpa_s);
+               wpa_supplicant_event_disassoc(wpa_s, reason_code);
                break;
        case EVENT_MICHAEL_MIC_FAILURE:
                wpa_supplicant_event_michael_mic_failure(wpa_s, data);