diff --git a/src/common/nl80211_copy.h b/src/common/nl80211_copy.h index dc9d9ec5d..7ae6e12e3 100644 --- a/src/common/nl80211_copy.h +++ b/src/common/nl80211_copy.h @@ -203,8 +203,12 @@ * frame, i.e., it was for the local STA and was received in correct * state. This is similar to MLME-AUTHENTICATE.confirm primitive in the * MLME SAP interface (kernel providing MLME, userspace SME). The - * included NL80211_ATTR_FRAME attribute contains the management frame - * (including both the header and frame body, but not FCS). + * included %NL80211_ATTR_FRAME attribute contains the management frame + * (including both the header and frame body, but not FCS). This event is + * also used to indicate if the authentication attempt timed out. In that + * case the %NL80211_ATTR_FRAME attribute is replaced with a + * %NL80211_ATTR_TIMED_OUT flag (and %NL80211_ATTR_MAC to indicate which + * pending authentication timed out). * @NL80211_CMD_ASSOCIATE: association request and notification; like * NL80211_CMD_AUTHENTICATE but for Association and Reassociation * (similar to MLME-ASSOCIATE.request, MLME-REASSOCIATE.request, @@ -485,6 +489,9 @@ enum nl80211_commands { * @NL80211_ATTR_FREQ_FIXED: a flag indicating the IBSS should not try to look * for other networks on different channels * + * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this + * is used, e.g., with %NL80211_CMD_AUTHENTICATE event + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -585,6 +592,8 @@ enum nl80211_attrs { NL80211_ATTR_WIPHY_FRAG_THRESHOLD, NL80211_ATTR_WIPHY_RTS_THRESHOLD, + NL80211_ATTR_TIMED_OUT, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 930e464a9..943d61c2a 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1497,7 +1497,17 @@ typedef enum wpa_event_type { * rejected by the AP. Information about authentication result is * included in union wpa_event_data::assoc_reject. */ - EVENT_ASSOC_REJECT + EVENT_ASSOC_REJECT, + + /** + * EVENT_AUTH_TIMED_OUT - Authentication timed out + */ + EVENT_AUTH_TIMED_OUT, + + /** + * EVENT_ASSOC_TIMED_OUT - Association timed out + */ + EVENT_ASSOC_TIMED_OUT } wpa_event_type; @@ -1675,6 +1685,10 @@ union wpa_event_data { */ u16 status_code; } assoc_reject; + + struct timeout_event { + u8 addr[ETH_ALEN]; + } timeout_event; }; /** diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index d2855e237..51e03465c 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -740,9 +740,40 @@ static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv, } -static void mlme_event(struct wpa_driver_nl80211_data *drv, - enum nl80211_commands cmd, struct nlattr *frame) +static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv, + enum nl80211_commands cmd, struct nlattr *addr) { + union wpa_event_data event; + enum wpa_event_type ev; + + if (nla_len(addr) != ETH_ALEN) + return; + + wpa_printf(MSG_DEBUG, "nl80211: MLME event %d; timeout with " MACSTR, + cmd, MAC2STR((u8 *) nla_data(addr))); + + if (cmd == NL80211_CMD_AUTHENTICATE) + ev = EVENT_AUTH_TIMED_OUT; + else if (cmd == NL80211_CMD_ASSOCIATE) + ev = EVENT_ASSOC_TIMED_OUT; + else + return; + + os_memset(&event, 0, sizeof(event)); + os_memcpy(event.timeout_event.addr, nla_data(addr), ETH_ALEN); + wpa_supplicant_event(drv->ctx, ev, &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) +{ + if (timed_out && addr) { + mlme_timeout_event(drv, cmd, addr); + return; + } + if (frame == NULL) { wpa_printf(MSG_DEBUG, "nl80211: MLME event %d without frame " "data", cmd); @@ -861,7 +892,8 @@ static int process_event(struct nl_msg *msg, void *arg) case NL80211_CMD_ASSOCIATE: case NL80211_CMD_DEAUTHENTICATE: case NL80211_CMD_DISASSOCIATE: - mlme_event(drv, gnlh->cmd, tb[NL80211_ATTR_FRAME]); + mlme_event(drv, gnlh->cmd, tb[NL80211_ATTR_FRAME], + tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT]); break; #endif /* HOSTAPD */ case NL80211_CMD_MICHAEL_MIC_FAILURE: diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 1fb1d2d61..56c57fb78 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1229,6 +1229,12 @@ void wpa_supplicant_event(void *ctx, wpa_event_type event, case EVENT_ASSOC_REJECT: sme_event_assoc_reject(wpa_s, data); break; + case EVENT_AUTH_TIMED_OUT: + sme_event_auth_timed_out(wpa_s, data); + break; + case EVENT_ASSOC_TIMED_OUT: + sme_event_assoc_timed_out(wpa_s, data); + break; default: wpa_printf(MSG_INFO, "Unknown event %d", event); break; diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 87b6b9598..0d729efff 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -361,3 +361,20 @@ void sme_event_assoc_reject(struct wpa_supplicant *wpa_s, */ wpa_supplicant_req_scan(wpa_s, 5, 0); } + + +void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) +{ + wpa_printf(MSG_DEBUG, "SME: Authentication timed out"); + wpa_supplicant_req_scan(wpa_s, 5, 0); +} + + +void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) +{ + wpa_printf(MSG_DEBUG, "SME: Association timed out"); + wpa_supplicant_mark_disassoc(wpa_s); + wpa_supplicant_req_scan(wpa_s, 5, 0); +} diff --git a/wpa_supplicant/sme.h b/wpa_supplicant/sme.h index 566e417d1..278004185 100644 --- a/wpa_supplicant/sme.h +++ b/wpa_supplicant/sme.h @@ -24,6 +24,10 @@ int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md, const u8 *ies, size_t ies_len); void sme_event_assoc_reject(struct wpa_supplicant *wpa_s, union wpa_event_data *data); +void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s, + union wpa_event_data *data); +void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s, + union wpa_event_data *data); #else /* CONFIG_SME */ @@ -50,6 +54,16 @@ static inline void sme_event_assoc_reject(struct wpa_supplicant *wpa_s, { } +static inline void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) +{ +} + +static inline void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) +{ +} + #endif /* CONFIG_SME */ #endif /* SME_H */