static void ieee80211_tkip_countermeasures_start(struct hostapd_data *hapd) { struct sta_info *sta; hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "TKIP countermeasures initiated"); wpa_auth_countermeasures_start(hapd->wpa_auth); hapd->tkip_countermeasures = 1; hostapd_drv_set_countermeasures(hapd, 1); wpa_gtk_rekey(hapd->wpa_auth); eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop, hapd, NULL); eloop_register_timeout(60, 0, ieee80211_tkip_countermeasures_stop, hapd, NULL); while ((sta = hapd->sta_list)) { sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_ADMIN_RESET; if (sta->flags & WLAN_STA_AUTH) { mlme_deauthenticate_indication( hapd, sta, WLAN_REASON_MICHAEL_MIC_FAILURE); } hostapd_drv_sta_deauth(hapd, sta->addr, WLAN_REASON_MICHAEL_MIC_FAILURE); ap_sta_cancel_priority(hapd, sta); ap_free_sta(hapd, sta); } }
static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx) { struct hostapd_data *hapd = eloop_ctx; struct sta_info *sta = timeout_ctx; u8 addr[ETH_ALEN]; if (!(sta->flags & WLAN_STA_AUTH)) { if (sta->flags & WLAN_STA_GAS) { wpa_printf(MSG_DEBUG, "GAS: Remove temporary STA " "entry " MACSTR, MAC2STR(sta->addr)); ap_free_sta(hapd, sta); } return; } mlme_deauthenticate_indication(hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "deauthenticated due to " "session timeout"); sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_SESSION_TIMEOUT; os_memcpy(addr, sta->addr, ETH_ALEN); ap_free_sta(hapd, sta); hostapd_drv_sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID); }
static void handle_deauth(struct hostapd_data *hapd, const struct ieee80211_mgmt *mgmt, size_t len) { struct sta_info *sta; if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.deauth)) { printf("handle_deauth - too short payload (len=%lu)\n", (unsigned long) len); return; } wpa_printf(MSG_DEBUG, "deauthentication: STA=" MACSTR " reason_code=%d", MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code)); sta = ap_get_sta(hapd, mgmt->sa); if (sta == NULL) { printf("Station " MACSTR " trying to deauthenticate, but it " "is not authenticated.\n", MAC2STR(mgmt->sa)); return; } sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR, MAC2STR(sta->addr)); wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "deauthenticated"); mlme_deauthenticate_indication( hapd, sta, le_to_host16(mgmt->u.deauth.reason_code)); sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); ap_free_sta(hapd, sta); }
static void ap_sta_deauth_cb_timeout(void *eloop_ctx, void *timeout_ctx) { struct hostapd_data *hapd = eloop_ctx; struct sta_info *sta = timeout_ctx; ap_sta_remove(hapd, sta); mlme_deauthenticate_indication(hapd, sta, sta->deauth_reason); }
static void ap_sta_deauth_cb_timeout(void *eloop_ctx, void *timeout_ctx) { struct hostapd_data *hapd = eloop_ctx; struct sta_info *sta = timeout_ctx; wpa_printf(MSG_DEBUG, "%s: Deauthentication callback for STA " MACSTR, hapd->conf->iface, MAC2STR(sta->addr)); ap_sta_remove(hapd, sta); mlme_deauthenticate_indication(hapd, sta, sta->deauth_reason); }
void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta, u16 reason) { wpa_printf(MSG_DEBUG, "%s: deauthenticate STA " MACSTR, hapd->conf->iface, MAC2STR(sta->addr)); sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); ap_sta_remove(hapd, sta); sta->timeout_next = STA_REMOVE; eloop_cancel_timeout(ap_handle_timer, hapd, sta); eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0, ap_handle_timer, hapd, sta); accounting_sta_stop(hapd, sta); /*ieee802_1x_free_station(sta);*/ mlme_deauthenticate_indication(hapd, sta, reason); }
void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta, u16 reason) { HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "%s: deauthenticate STA " MACSTR "\n", hapd->conf->iface, MAC2STR(sta->addr)); sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); if (!ap_sta_in_other_bss(hapd, sta, WLAN_STA_ASSOC)) ap_sta_remove(hapd, sta); sta->timeout_next = STA_REMOVE; eloop_cancel_timeout(ap_handle_timer, hapd, sta); eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0, ap_handle_timer, hapd, sta); accounting_sta_stop(hapd, sta); ieee802_1x_free_station(sta); mlme_deauthenticate_indication(hapd, sta, reason); }
void hostapd_free_stas(struct hostapd_data *hapd) { struct sta_info *sta, *prev; sta = hapd->sta_list; while (sta) { prev = sta; if (sta->flags & WLAN_STA_AUTH) { mlme_deauthenticate_indication( hapd, sta, WLAN_REASON_UNSPECIFIED); } sta = sta->next; printf("Removing station " MACSTR "\n", MAC2STR(prev->addr)); ap_free_sta(hapd, prev); } }
static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx) { struct hostapd_data *hapd = eloop_ctx; struct sta_info *sta = timeout_ctx; u8 addr[ETH_ALEN]; if (!(sta->flags & WLAN_STA_AUTH)) return; mlme_deauthenticate_indication(hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "deauthenticated due to " "session timeout"); sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_SESSION_TIMEOUT; os_memcpy(addr, sta->addr, ETH_ALEN); ap_free_sta(hapd, sta); hapd->drv.sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID); }
/** * ap_handle_timer - Per STA timer handler * @eloop_ctx: struct hostapd_data * * @timeout_ctx: struct sta_info * * * This function is called to check station activity and to remove inactive * stations. */ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx) { struct hostapd_data *hapd = eloop_ctx; struct sta_info *sta = timeout_ctx; unsigned long next_time = 0; wpa_printf(MSG_DEBUG, "%s: " MACSTR " flags=0x%x timeout_next=%d", __func__, MAC2STR(sta->addr), sta->flags, sta->timeout_next); if (sta->timeout_next == STA_REMOVE) { hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "deauthenticated due to " "local deauth request"); ap_free_sta(hapd, sta); return; } if ((sta->flags & WLAN_STA_ASSOC) && (sta->timeout_next == STA_NULLFUNC || sta->timeout_next == STA_DISASSOC)) { int inactive_sec; /* * Add random value to timeout so that we don't end up bouncing * all stations at the same time if we have lots of associated * stations that are idle (but keep re-associating). */ int fuzz = os_random() % 20; inactive_sec = hostapd_drv_get_inact_sec(hapd, sta->addr); if (inactive_sec == -1) { wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Check inactivity: Could not " "get station info from kernel driver for " MACSTR, MAC2STR(sta->addr)); /* * The driver may not support this functionality. * Anyway, try again after the next inactivity timeout, * but do not disconnect the station now. */ next_time = hapd->conf->ap_max_inactivity + fuzz; } else if (inactive_sec < hapd->conf->ap_max_inactivity && sta->flags & WLAN_STA_ASSOC) { /* station activity detected; reset timeout state */ wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " has been active %is ago", MAC2STR(sta->addr), inactive_sec); sta->timeout_next = STA_NULLFUNC; next_time = hapd->conf->ap_max_inactivity + fuzz - inactive_sec; } else { wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " has been " "inactive too long: %d sec, max allowed: %d", MAC2STR(sta->addr), inactive_sec, hapd->conf->ap_max_inactivity); if (hapd->conf->skip_inactivity_poll) sta->timeout_next = STA_DISASSOC; } } if ((sta->flags & WLAN_STA_ASSOC) && sta->timeout_next == STA_DISASSOC && !(sta->flags & WLAN_STA_PENDING_POLL) && !hapd->conf->skip_inactivity_poll) { wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " has ACKed data poll", MAC2STR(sta->addr)); /* data nullfunc frame poll did not produce TX errors; assume * station ACKed it */ sta->timeout_next = STA_NULLFUNC; next_time = hapd->conf->ap_max_inactivity; } if (next_time) { wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout " "for " MACSTR " (%lu seconds)", __func__, MAC2STR(sta->addr), next_time); eloop_register_timeout(next_time, 0, ap_handle_timer, hapd, sta); return; } if (sta->timeout_next == STA_NULLFUNC && (sta->flags & WLAN_STA_ASSOC)) { wpa_printf(MSG_DEBUG, " Polling STA"); sta->flags |= WLAN_STA_PENDING_POLL; hostapd_drv_poll_client(hapd, hapd->own_addr, sta->addr, sta->flags & WLAN_STA_WMM); } else if (sta->timeout_next != STA_REMOVE) { int deauth = sta->timeout_next == STA_DEAUTH; wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "Timeout, sending %s info to STA " MACSTR, deauth ? "deauthentication" : "disassociation", MAC2STR(sta->addr)); if (deauth) { hostapd_drv_sta_deauth( hapd, sta->addr, WLAN_REASON_PREV_AUTH_NOT_VALID); } else { hostapd_drv_sta_disassoc( hapd, sta->addr, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); } } switch (sta->timeout_next) { case STA_NULLFUNC: sta->timeout_next = STA_DISASSOC; wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout " "for " MACSTR " (%d seconds - AP_DISASSOC_DELAY)", __func__, MAC2STR(sta->addr), AP_DISASSOC_DELAY); eloop_register_timeout(AP_DISASSOC_DELAY, 0, ap_handle_timer, hapd, sta); break; case STA_DISASSOC: ap_sta_set_authorized(hapd, sta, 0); sta->flags &= ~WLAN_STA_ASSOC; ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); if (!sta->acct_terminate_cause) sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT; accounting_sta_stop(hapd, sta); ieee802_1x_free_station(sta); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "disassociated due to " "inactivity"); sta->timeout_next = STA_DEAUTH; wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout " "for " MACSTR " (%d seconds - AP_DEAUTH_DELAY)", __func__, MAC2STR(sta->addr), AP_DEAUTH_DELAY); eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer, hapd, sta); mlme_disassociate_indication( hapd, sta, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); break; case STA_DEAUTH: case STA_REMOVE: hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "deauthenticated due to " "inactivity (timer DEAUTH/REMOVE)"); if (!sta->acct_terminate_cause) sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT; mlme_deauthenticate_indication( hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID); ap_free_sta(hapd, sta); break; } }
/** * ap_handle_timer - Per STA timer handler * @eloop_ctx: struct hostapd_data * * @timeout_ctx: struct sta_info * * * This function is called to check station activity and to remove inactive * stations. */ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx) { struct hostapd_data *hapd = eloop_ctx; struct sta_info *sta = timeout_ctx; unsigned long next_time = 0; if (sta->timeout_next == STA_REMOVE) { hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "deauthenticated due to " "local deauth request"); ap_free_sta(hapd, sta); return; } if ((sta->flags & WLAN_STA_ASSOC) && (sta->timeout_next == STA_NULLFUNC || sta->timeout_next == STA_DISASSOC)) { int inactive_sec; inactive_sec = hostapd_drv_get_inact_sec(hapd, sta->addr); if (inactive_sec == -1) { wpa_msg(hapd, MSG_DEBUG, "Check inactivity: Could not " "get station info rom kernel driver for " MACSTR, MAC2STR(sta->addr)); } else if (inactive_sec < hapd->conf->ap_max_inactivity && sta->flags & WLAN_STA_ASSOC) { /* station activity detected; reset timeout state */ wpa_msg(hapd, MSG_DEBUG, "Station " MACSTR " has been " "active %is ago", MAC2STR(sta->addr), inactive_sec); sta->timeout_next = STA_NULLFUNC; next_time = hapd->conf->ap_max_inactivity - inactive_sec; } else { wpa_msg(hapd, MSG_DEBUG, "Station " MACSTR " has been " "inactive too long: %d sec, max allowed: %d", MAC2STR(sta->addr), inactive_sec, hapd->conf->ap_max_inactivity); } } if ((sta->flags & WLAN_STA_ASSOC) && sta->timeout_next == STA_DISASSOC && !(sta->flags & WLAN_STA_PENDING_POLL)) { wpa_msg(hapd, MSG_DEBUG, "Station " MACSTR " has ACKed data " "poll", MAC2STR(sta->addr)); /* data nullfunc frame poll did not produce TX errors; assume * station ACKed it */ sta->timeout_next = STA_NULLFUNC; next_time = hapd->conf->ap_max_inactivity; } if (next_time) { eloop_register_timeout(next_time, 0, ap_handle_timer, hapd, sta); return; } if (sta->timeout_next == STA_NULLFUNC && (sta->flags & WLAN_STA_ASSOC)) { #ifndef CONFIG_NATIVE_WINDOWS /* send data frame to poll STA and check whether this frame * is ACKed */ struct { struct ieee80211_hdr hdr; u16 qos_ctl; } STRUCT_PACKED nulldata; int size = sizeof(struct ieee80211_hdr); wpa_printf(MSG_DEBUG, " Polling STA with data frame"); sta->flags |= WLAN_STA_PENDING_POLL; os_memset(&nulldata, 0, sizeof(nulldata)); if (hapd->driver && os_strcmp(hapd->driver->name, "hostap") == 0) { /* * WLAN_FC_STYPE_NULLFUNC would be more appropriate, * but it is apparently not retried so TX Exc events * are not received for it. */ nulldata.hdr.frame_control = IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_DATA); } else { if (sta->flags & WLAN_STA_WMM) { nulldata.hdr.frame_control = IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_QOS_NULL); size = sizeof(nulldata); } else nulldata.hdr.frame_control = IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_NULLFUNC); } nulldata.hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS); os_memcpy(nulldata.hdr.IEEE80211_DA_FROMDS, sta->addr, ETH_ALEN); os_memcpy(nulldata.hdr.IEEE80211_BSSID_FROMDS, hapd->own_addr, ETH_ALEN); os_memcpy(nulldata.hdr.IEEE80211_SA_FROMDS, hapd->own_addr, ETH_ALEN); if (hostapd_drv_send_mlme(hapd, &nulldata, size) < 0) perror("ap_handle_timer: send"); #endif /* CONFIG_NATIVE_WINDOWS */ } else if (sta->timeout_next != STA_REMOVE) { int deauth = sta->timeout_next == STA_DEAUTH; wpa_printf(MSG_DEBUG, "Sending %s info to STA " MACSTR, deauth ? "deauthentication" : "disassociation", MAC2STR(sta->addr)); if (deauth) { hostapd_drv_sta_deauth( hapd, sta->addr, WLAN_REASON_PREV_AUTH_NOT_VALID); } else { hostapd_drv_sta_disassoc( hapd, sta->addr, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); } } switch (sta->timeout_next) { case STA_NULLFUNC: sta->timeout_next = STA_DISASSOC; eloop_register_timeout(AP_DISASSOC_DELAY, 0, ap_handle_timer, hapd, sta); break; case STA_DISASSOC: sta->flags &= ~WLAN_STA_ASSOC; ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); if (!sta->acct_terminate_cause) sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT; accounting_sta_stop(hapd, sta); ieee802_1x_free_station(sta); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "disassociated due to " "inactivity"); sta->timeout_next = STA_DEAUTH; eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer, hapd, sta); mlme_disassociate_indication( hapd, sta, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); break; case STA_DEAUTH: case STA_REMOVE: hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "deauthenticated due to " "inactivity"); if (!sta->acct_terminate_cause) sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT; mlme_deauthenticate_indication( hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID); ap_free_sta(hapd, sta); break; } }
void ap_handle_timer(void *eloop_ctx, void *timeout_ctx) { struct hostapd_data *hapd = eloop_ctx; struct sta_info *sta = timeout_ctx; unsigned long next_time = 0; if (sta->timeout_next == STA_REMOVE) { hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "deauthenticated due to " "local deauth request"); ap_free_sta(hapd, sta); return; } if ((sta->flags & WLAN_STA_ASSOC) && (sta->timeout_next == STA_NULLFUNC || sta->timeout_next == STA_DISASSOC)) { int inactive_sec; HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Checking STA " MACSTR " inactivity:\n", MAC2STR(sta->addr)); inactive_sec = hostapd_get_inact_sec(hapd, sta->addr); if (inactive_sec == -1) { printf(" Could not get station info from kernel " "driver for " MACSTR ".\n", MAC2STR(sta->addr)); } else if (inactive_sec < hapd->conf->ap_max_inactivity && sta->flags & WLAN_STA_ASSOC) { /* station activity detected; reset timeout state */ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " Station has been active\n"); sta->timeout_next = STA_NULLFUNC; next_time = hapd->conf->ap_max_inactivity - inactive_sec; } } if ((sta->flags & WLAN_STA_ASSOC) && sta->timeout_next == STA_DISASSOC && !(sta->flags & WLAN_STA_PENDING_POLL)) { HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " Station has ACKed data poll\n"); /* data nullfunc frame poll did not produce TX errors; assume * station ACKed it */ sta->timeout_next = STA_NULLFUNC; next_time = hapd->conf->ap_max_inactivity; } if (next_time) { eloop_register_timeout(next_time, 0, ap_handle_timer, hapd, sta); return; } if (sta->timeout_next == STA_NULLFUNC && (sta->flags & WLAN_STA_ASSOC)) { /* send data frame to poll STA and check whether this frame * is ACKed */ struct ieee80211_hdr hdr; HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " Polling STA with data frame\n"); sta->flags |= WLAN_STA_PENDING_POLL; #ifndef CONFIG_NATIVE_WINDOWS /* FIX: WLAN_FC_STYPE_NULLFUNC would be more appropriate, but * it is apparently not retried so TX Exc events are not * received for it */ memset(&hdr, 0, sizeof(hdr)); hdr.frame_control = IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_DATA); hdr.frame_control |= host_to_le16(BIT(1)); hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS); memcpy(hdr.IEEE80211_DA_FROMDS, sta->addr, ETH_ALEN); memcpy(hdr.IEEE80211_BSSID_FROMDS, hapd->own_addr, ETH_ALEN); memcpy(hdr.IEEE80211_SA_FROMDS, hapd->own_addr, ETH_ALEN); if (hostapd_send_mgmt_frame(hapd, &hdr, sizeof(hdr), 0) < 0) perror("ap_handle_timer: send"); #endif /* CONFIG_NATIVE_WINDOWS */ } else if (sta->timeout_next != STA_REMOVE) { int deauth = sta->timeout_next == STA_DEAUTH; printf(" Sending %s info to STA " MACSTR "\n", deauth ? "deauthentication" : "disassociation", MAC2STR(sta->addr)); if (deauth) { hostapd_sta_deauth(hapd, sta->addr, WLAN_REASON_PREV_AUTH_NOT_VALID); } else { hostapd_sta_disassoc( hapd, sta->addr, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); } } switch (sta->timeout_next) { case STA_NULLFUNC: sta->timeout_next = STA_DISASSOC; eloop_register_timeout(AP_DISASSOC_DELAY, 0, ap_handle_timer, hapd, sta); break; case STA_DISASSOC: sta->flags &= ~WLAN_STA_ASSOC; ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); if (!sta->acct_terminate_cause) sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT; accounting_sta_stop(hapd, sta); ieee802_1x_free_station(sta); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "disassociated due to " "inactivity"); sta->timeout_next = STA_DEAUTH; eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer, hapd, sta); mlme_disassociate_indication( hapd, sta, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); break; case STA_DEAUTH: case STA_REMOVE: hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "deauthenticated due to " "inactivity"); if (!sta->acct_terminate_cause) sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT; mlme_deauthenticate_indication( hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID); ap_free_sta(hapd, sta); break; } }