static int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr, const u8 *data, size_t data_len, int encrypt) { struct hostapd_data *hapd = ctx; struct sta_info *sta; u32 flags = 0; sta = ap_get_sta(hapd, addr); if (sta) flags = hostapd_sta_flags_to_drv(sta->flags); return hostapd_drv_hapd_send_eapol(hapd, addr, data, data_len, encrypt, flags); }
int hostapd_ctrl_iface_sta(struct hostapd_data *hapd, const char *txtaddr, char *buf, size_t buflen) { u8 addr[ETH_ALEN]; int ret; if (hwaddr_aton(txtaddr, addr)) { ret = os_snprintf(buf, buflen, "FAIL\n"); if (ret < 0 || (size_t) ret >= buflen) return 0; return ret; } return hostapd_ctrl_iface_sta_mib(hapd, ap_get_sta(hapd, addr), buf, buflen); }
static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src, const u8 *data, size_t data_len) { struct hostapd_iface *iface = hapd->iface; size_t j; for (j = 0; j < iface->num_bss; j++) { if (ap_get_sta(iface->bss[j], src)) { hapd = iface->bss[j]; break; } } ieee802_1x_receive(hapd, src, data, data_len); }
static int hostapd_wpa_auth_get_eapol(void *ctx, const u8 *addr, wpa_eapol_variable var) { struct hostapd_data *hapd = ctx; struct sta_info *sta = ap_get_sta(hapd, addr); if (sta == NULL || sta->eapol_sm == NULL) return -1; switch (var) { case WPA_EAPOL_keyRun: return sta->eapol_sm->keyRun; case WPA_EAPOL_keyAvailable: return sta->eapol_sm->eap_if->eapKeyAvailable; default: return -1; } }
static void handle_read(void *ctx, unsigned char *src_addr, unsigned char *buf, size_t len) { struct bsd_driver_data *drv = ctx; hostapd *hapd = drv->hapd; struct sta_info *sta; sta = ap_get_sta(hapd, src_addr); if (!sta || !(sta->flags & WLAN_STA_ASSOC)) { printf("Data frame from not associated STA %s\n", ether_sprintf(src_addr)); /* XXX cannot happen */ return; } ieee802_1x_receive(hapd, src_addr, buf, len); }
struct auth_sta_info_t * get_sta(struct eloop_data *eloop, unsigned char *mac) { /*释放所有资源*/ struct wapid_interfaces *interfaces = NULL; struct auth_sta_info_t * sta = NULL; if(eloop == NULL) return NULL; interfaces = eloop->vap_user; for(; interfaces; interfaces=interfaces->next){ sta = ap_get_sta(mac, interfaces->wapid); if(sta != NULL) break; } return sta; }
static void rtl871x_handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) { struct rtl871x_driver_data *drv = ctx; struct hostapd_data *hapd = drv->hapd; struct sta_info *sta; sta = ap_get_sta(hapd, src_addr); if (!sta || !(sta->flags & WLAN_STA_ASSOC)) { printf("Data frame from not associated STA %s\n", ether_sprintf(src_addr)); /* XXX cannot happen */ return; } ieee802_1x_receive(hapd, src_addr, buf + sizeof(struct l2_ethhdr), len - sizeof(struct l2_ethhdr)); }
static int hostapd_wpa_auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg, const u8 *addr, int idx, u8 *key, size_t key_len) { struct hostapd_data *hapd = ctx; const char *ifname = hapd->conf->iface; if (vlan_id > 0) { ifname = hostapd_get_vlan_id_ifname(hapd->conf->vlan, vlan_id); if (ifname == NULL) return -1; } #ifdef CONFIG_TESTING_OPTIONS if (addr && !is_broadcast_ether_addr(addr)) { struct sta_info *sta; sta = ap_get_sta(hapd, addr); if (sta) { sta->last_tk_alg = alg; sta->last_tk_key_idx = idx; if (key) os_memcpy(sta->last_tk, key, key_len); sta->last_tk_len = key_len; } #ifdef CONFIG_IEEE80211W } else if (alg == WPA_ALG_IGTK || alg == WPA_ALG_BIP_GMAC_128 || alg == WPA_ALG_BIP_GMAC_256 || alg == WPA_ALG_BIP_CMAC_256) { hapd->last_igtk_alg = alg; hapd->last_igtk_key_idx = idx; if (key) os_memcpy(hapd->last_igtk, key, key_len); hapd->last_igtk_len = key_len; #endif /* CONFIG_IEEE80211W */ } else { hapd->last_gtk_alg = alg; hapd->last_gtk_key_idx = idx; if (key) os_memcpy(hapd->last_gtk, key, key_len); hapd->last_gtk_len = key_len; } #endif /* CONFIG_TESTING_OPTIONS */ return hostapd_drv_set_key(ifname, hapd, alg, addr, idx, 1, NULL, 0, key, key_len); }
static void rtl871x_handle_tx_callback(struct hostapd_data *hapd, u8 *buf, size_t len, int ok) { #if 0 struct ieee80211_hdr *hdr; u16 fc, type, stype; struct sta_info *sta; //printf("%s\n", __func__); hdr = (struct ieee80211_hdr *) buf; fc = le_to_host16(hdr->frame_control); type = WLAN_FC_GET_TYPE(fc); stype = WLAN_FC_GET_STYPE(fc); switch (type) { case WLAN_FC_TYPE_MGMT: //printf("MGMT (TX callback) %s\n", // ok ? "ACK" : "fail"); ieee802_11_mgmt_cb(hapd, buf, len, stype, ok); break; case WLAN_FC_TYPE_CTRL: printf("CTRL (TX callback) %s\n", ok ? "ACK" : "fail"); break; case WLAN_FC_TYPE_DATA: printf("DATA (TX callback) %s\n", ok ? "ACK" : "fail"); sta = ap_get_sta(hapd, hdr->addr1); if (sta && sta->flags & WLAN_STA_PENDING_POLL) { wpa_printf(MSG_DEBUG, "STA " MACSTR " %s pending activity poll", MAC2STR(sta->addr), ok ? "ACKed" : "did not ACK"); if (ok) sta->flags &= ~WLAN_STA_PENDING_POLL; } if (sta) ieee802_1x_tx_status(hapd, sta, buf, len, ok); break; default: printf("unknown TX callback frame type %d\n", type); break; } #endif }
static void handle_disassoc(hostapd *hapd, struct ieee80211_mgmt *mgmt, size_t len) { struct sta_info *sta; if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) { printf("handle_disassoc - too short payload (len=%d)\n", len); return; } HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "disassocation: STA=" MACSTR " reason_code=%d\n", MAC2STR(mgmt->sa), le_to_host16(mgmt->u.disassoc.reason_code)); if (hapd->assoc_ap_state != DO_NOT_ASSOC && memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0) { printf("Assoc AP " MACSTR " sent disassociation " "(reason_code=%d) - try to authenticate\n", MAC2STR(hapd->conf->assoc_ap_addr), le_to_host16(mgmt->u.disassoc.reason_code)); hapd->assoc_ap_state = AUTHENTICATE; ieee802_11_sta_authenticate(hapd, NULL); eloop_register_timeout(0, 500000, ieee802_11_sta_authenticate, hapd, NULL); return; } sta = ap_get_sta(hapd, mgmt->sa); if (sta == NULL) { printf("Station " MACSTR " trying to disassociate, but it " "is not associated.\n", MAC2STR(mgmt->sa)); return; } sta->flags &= ~WLAN_STA_ASSOC; wpa_sm_event(hapd, sta, WPA_DISASSOC); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "disassociated"); sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; ieee802_1x_set_port_enabled(hapd, sta, 0); /* Stop Accounting and IEEE 802.1X sessions, but leave the STA * authenticated. */ accounting_sta_stop(hapd, sta); ieee802_1x_free_station(sta); remove_sta(hapd->driver.data, sta->addr); }
static void handle_disassoc(struct hostapd_data *hapd, const struct ieee80211_mgmt *mgmt, size_t len) { struct sta_info *sta; if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) { printf("handle_disassoc - too short payload (len=%lu)\n", (unsigned long) len); return; } wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d", MAC2STR(mgmt->sa), le_to_host16(mgmt->u.disassoc.reason_code)); sta = ap_get_sta(hapd, mgmt->sa); if (sta == NULL) { printf("Station " MACSTR " trying to disassociate, but it " "is not associated.\n", MAC2STR(mgmt->sa)); return; } sta->flags &= ~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_DISASSOC); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "disassociated"); sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); /* Stop Accounting and IEEE 802.1X sessions, but leave the STA * authenticated. */ accounting_sta_stop(hapd, sta); ieee802_1x_free_station(sta); hapd->drv.sta_remove(hapd, sta->addr); if (sta->timeout_next == STA_NULLFUNC || sta->timeout_next == STA_DISASSOC) { sta->timeout_next = STA_DEAUTH; eloop_cancel_timeout(ap_handle_timer, hapd, sta); eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer, hapd, sta); } mlme_disassociate_indication( hapd, sta, le_to_host16(mgmt->u.disassoc.reason_code)); }
struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr) { struct sta_info *sta; sta = ap_get_sta(hapd, addr); if (sta) return sta; wpa_printf(MSG_DEBUG, " New STA"); if (hapd->num_sta >= hapd->conf->max_num_sta) { /* FIX: might try to remove some old STAs first? */ wpa_printf(MSG_DEBUG, "no more room for new STAs (%d/%d)", hapd->num_sta, hapd->conf->max_num_sta); return NULL; } sta = os_zalloc(sizeof(struct sta_info)); if (sta == NULL) { wpa_printf(MSG_ERROR, "malloc failed"); return NULL; } sta->acct_interim_interval = hapd->conf->acct_interim_interval; accounting_sta_get_id(hapd, sta); if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) { wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout " "for " MACSTR " (%d seconds - ap_max_inactivity)", __func__, MAC2STR(addr), hapd->conf->ap_max_inactivity); eloop_register_timeout(hapd->conf->ap_max_inactivity, 0, ap_handle_timer, hapd, sta); } /* initialize STA info data */ os_memcpy(sta->addr, addr, ETH_ALEN); sta->next = hapd->sta_list; hapd->sta_list = sta; hapd->num_sta++; ap_sta_hash_add(hapd, sta); sta->ssid = &hapd->conf->ssid; ap_sta_remove_in_other_bss(hapd, sta); sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ; dl_list_init(&sta->ip6addr); return sta; }
static int auth_start_ampe(void *ctx, const u8 *addr) { struct mesh_rsn *mesh_rsn = ctx; struct hostapd_data *hapd; struct sta_info *sta; if (mesh_rsn->wpa_s->current_ssid->mode != WPAS_MODE_MESH) return -1; hapd = mesh_rsn->wpa_s->ifmsh->bss[0]; sta = ap_get_sta(hapd, addr); if (sta) eloop_cancel_timeout(mesh_auth_timer, mesh_rsn->wpa_s, sta); mesh_mpm_auth_peer(mesh_rsn->wpa_s, addr); return 0; }
void sta_usk_rekey_handle(u8 *mac, apdata_info *pap) { struct auth_sta_info_t *sta_info; sta_info = ap_get_sta(mac, pap); if(sta_info != NULL) { if(sta_info->rekeying ==1) return; if(sta_info->auth_mode == AUTH_MODE && sta_info->status == MT_AUTHENTICATED) { usk_rekey_handle(sta_info); } } return ; }
static int hostapd_ctrl_iface_sta_next(struct hostapd_data *hapd, const char *txtaddr, char *buf, size_t buflen) { u8 addr[ETH_ALEN]; struct sta_info *sta; int ret; if (hwaddr_aton(txtaddr, addr) || (sta = ap_get_sta(hapd, addr)) == NULL) { ret = snprintf(buf, buflen, "FAIL\n"); if (ret < 0 || (size_t) ret >= buflen) return 0; return ret; } return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen); }
static void hostapd_action_rx(struct hostapd_data *hapd, struct rx_mgmt *drv_mgmt) { struct ieee80211_mgmt *mgmt; struct sta_info *sta; size_t plen __maybe_unused; u16 fc; if (drv_mgmt->frame_len < 24 + 1) return; plen = drv_mgmt->frame_len - 24 - 1; mgmt = (struct ieee80211_mgmt *) drv_mgmt->frame; fc = le_to_host16(mgmt->frame_control); if (WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ACTION) return; /* handled by the driver */ wpa_printf(MSG_DEBUG, "RX_ACTION cat %d action plen %d", mgmt->u.action.category, (int) plen); sta = ap_get_sta(hapd, mgmt->sa); if (sta == NULL) { wpa_printf(MSG_DEBUG, "%s: station not found", __func__); return; } #ifdef CONFIG_IEEE80211R if (mgmt->u.action.category == WLAN_ACTION_FT) { const u8 *payload = drv_mgmt->frame + 24 + 1; wpa_ft_action_rx(sta->wpa_sm, payload, plen); } #endif /* CONFIG_IEEE80211R */ #ifdef CONFIG_IEEE80211W if (mgmt->u.action.category == WLAN_ACTION_SA_QUERY && plen >= 4) { ieee802_11_sa_query_action( hapd, mgmt->sa, mgmt->u.action.u.sa_query_resp.action, mgmt->u.action.u.sa_query_resp.trans_id); } #endif /* CONFIG_IEEE80211W */ #ifdef CONFIG_WNM if (mgmt->u.action.category == WLAN_ACTION_WNM) { ieee802_11_rx_wnm_action_ap(hapd, mgmt, drv_mgmt->frame_len); } #endif /* CONFIG_WNM */ }
int ap_ctrl_iface_disassociate(struct wpa_supplicant *wpa_s, const char *txtaddr) { u8 addr[ETH_ALEN]; struct sta_info *sta; if (wpa_s->ap_iface == NULL) return -1; wpa_printf(MSG_DEBUG, "CTRL_IFACE DISASSOCIATE %s", txtaddr); if (hwaddr_aton(txtaddr, addr)) return -1; hostapd_drv_sta_disassoc(wpa_s->ap_iface->bss[0], addr, WLAN_REASON_PREV_AUTH_NOT_VALID); sta = ap_get_sta(wpa_s->ap_iface->bss[0], addr); if (sta) ap_sta_disassociate(wpa_s->ap_iface->bss[0], sta, WLAN_REASON_PREV_AUTH_NOT_VALID); return 0; }
static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src, const u8 *data, size_t data_len) { struct hostapd_iface *iface = hapd->iface; struct sta_info *sta; size_t j; for (j = 0; j < iface->num_bss; j++) { sta = ap_get_sta(iface->bss[j], src); if (sta && sta->flags & WLAN_STA_ASSOC) { hapd = iface->bss[j]; break; } } ieee802_1x_receive(hapd, src, data, data_len); }
void ap_sta_disconnect(struct hostapd_data *hapd, struct sta_info *sta, const u8 *addr, u16 reason) { if (sta == NULL && addr) sta = ap_get_sta(hapd, addr); if (addr) hapd->drv.sta_deauth(hapd, addr, reason); if (sta == NULL) return; sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_AUTHORIZED); eloop_cancel_timeout(ap_handle_timer, hapd, sta); eloop_register_timeout(0, 0, ap_handle_timer, hapd, sta); sta->timeout_next = STA_REMOVE; }
struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr) { struct sta_info *sta; sta = ap_get_sta(hapd, addr); if (sta) { printf("sta exists\n"); return sta; } wpa_printf(MSG_DEBUG, " New STA"); printf("New Sta\n"); if (hapd->num_sta >= hapd->conf->max_num_sta) { /* FIX: might try to remove some old STAs first? */ wpa_printf(MSG_DEBUG, "no more room for new STAs (%d/%d)",hapd->num_sta, hapd->conf->max_num_sta); printf("Space problem\n"); return NULL; } sta = os_zalloc(sizeof(struct sta_info)); if (sta == NULL) { wpa_printf(MSG_ERROR, "malloc failed"); printf("malloc problem\n"); return NULL; } sta->acct_interim_interval = hapd->conf->acct_interim_interval; accounting_sta_get_id(hapd, sta); /* initialize STA info data */ wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout " "for " MACSTR " (%d seconds - ap_max_inactivity)", __func__, MAC2STR(addr), hapd->conf->ap_max_inactivity); eloop_register_timeout(hapd->conf->ap_max_inactivity, 0, ap_handle_timer, hapd, sta); os_memcpy(sta->addr, addr, ETH_ALEN); sta->next = hapd->sta_list; hapd->sta_list = sta; hapd->num_sta++; ap_sta_hash_add(hapd, sta); sta->ssid = &hapd->conf->ssid; ap_sta_remove_in_other_bss(hapd, sta); printf("Sta added!!\n"); return sta; }
static void hostapd_notify_auth_ft_finish(void *ctx, const u8 *dst, const u8 *bssid, u16 auth_transaction, u16 status, const u8 *ies, size_t ies_len) { struct hostapd_data *hapd = ctx; struct sta_info *sta; sta = ap_get_sta(hapd, dst); if (sta == NULL) return; hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)"); sta->flags |= WLAN_STA_AUTH; hostapd_sta_auth(hapd, dst, auth_transaction, status, ies, ies_len); }
static void wired_possible_new_sta(struct hostapd_data *hapd, u8 *addr) { struct sta_info *sta; sta = ap_get_sta(hapd, addr); if (sta) return; wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR " - adding a new STA", MAC2STR(addr)); sta = ap_sta_add(hapd, addr); if (sta) { hostapd_new_assoc_sta(hapd, sta, 0); } else { wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR, MAC2STR(addr)); } }
static void hostapd_action_rx(struct hostapd_data *hapd, struct rx_action *action) { struct sta_info *sta; sta = ap_get_sta(hapd, action->sa); if (sta == NULL) { wpa_printf(MSG_DEBUG, "%s: station not found", __func__); return; } #ifdef CONFIG_IEEE80211R if (action->category == WLAN_ACTION_FT) { wpa_printf(MSG_DEBUG, "%s: FT_ACTION length %d", __func__, action->len); wpa_ft_action_rx(sta->wpa_sm, action->data, action->len); } #endif /* CONFIG_IEEE80211R */ }
static void gas_serv_free_dialogs(struct hostapd_data *hapd, const u8 *sta_addr) { struct sta_info *sta; int i; sta = ap_get_sta(hapd, sta_addr); if (sta == NULL || sta->gas_dialog == NULL) return; for (i = 0; i < GAS_DIALOG_MAX; i++) { if (sta->gas_dialog[i].valid) return; } os_free(sta->gas_dialog); sta->gas_dialog = NULL; }
int hostapd_ctrl_iface_signature(struct hostapd_data *hapd, const char *txtaddr, char *buf, size_t buflen) { u8 addr[ETH_ALEN]; struct sta_info *sta; wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "CTRL_IFACE SIGNATURE %s", txtaddr); if (hwaddr_aton(txtaddr, addr)) return -1; sta = ap_get_sta(hapd, addr); if (!sta) return -1; return retrieve_sta_taxonomy(hapd, sta, buf, buflen); }
static const u8 *auth_get_psk(void *ctx, const u8 *addr, const u8 *p2p_dev_addr, const u8 *prev_psk) { struct mesh_rsn *mesh_rsn = ctx; struct hostapd_data *hapd = mesh_rsn->wpa_s->ifmsh->bss[0]; struct sta_info *sta = ap_get_sta(hapd, addr); wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)", __func__, MAC2STR(addr), prev_psk); if (sta && sta->auth_alg == WLAN_AUTH_SAE) { if (!sta->sae || prev_psk) return NULL; return sta->sae->pmk; } return NULL; }
void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr) { struct sta_info *sta; if (addr == NULL) { /* * This could potentially happen with unexpected event from the * driver wrapper. This was seen at least in one case where the * driver ended up reporting a station mode event while hostapd * was running, so better make sure we stop processing such an * event here. */ wpa_printf(MSG_DEBUG, "hostapd_notif_disassoc: Skip event " "with no address"); return; } hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "disassociated"); sta = ap_get_sta(hapd, addr); if (sta == NULL) { wpa_printf(MSG_DEBUG, "Disassociation notification for " "unknown STA " MACSTR, MAC2STR(addr)); return; } if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa) || sta->auth_alg == WLAN_AUTH_FT) { /* * Open, static WEP, or FT protocol; no separate authorization * step. */ wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR, MAC2STR(sta->addr)); } ap_sta_set_authorized(hapd, sta, 0); sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC); 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 int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr) { struct sta_info *sta = ap_get_sta(hapd, addr); if (sta) return 0; wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR " - adding a new STA", MAC2STR(addr)); sta = ap_sta_add(hapd, addr); if (sta) { hostapd_new_assoc_sta(hapd, sta, 0); } else { wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR, MAC2STR(addr)); return -1; } return 0; }
static int madwifi_del_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) { struct hostapd_data *hapd = drv->hapd; struct sta_info *sta; hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "disassociated"); sta = ap_get_sta(hapd, addr); if (sta != NULL) { sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC); sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); ap_free_sta(hapd, sta); } return 0; }
static void handle_deauth(hostapd *hapd, 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; } HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "deauthentication: STA=" MACSTR " reason_code=%d\n", MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code)); if (hapd->assoc_ap_state != DO_NOT_ASSOC && memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0) { printf("Assoc AP " MACSTR " sent deauthentication " "(reason_code=%d) - try to authenticate\n", MAC2STR(hapd->conf->assoc_ap_addr), le_to_host16(mgmt->u.deauth.reason_code)); hapd->assoc_ap_state = AUTHENTICATE; eloop_register_timeout(0, 500000, ieee802_11_sta_authenticate, hapd, NULL); return; } 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_sm_event(hapd, sta, WPA_DEAUTH); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "deauthenticated"); sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; ieee802_1x_set_port_enabled(hapd, sta, 0); ap_free_sta(hapd, sta); }