int hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd, const char *txtaddr) { u8 addr[ETH_ALEN]; struct sta_info *sta; const char *pos; u16 reason = WLAN_REASON_PREV_AUTH_NOT_VALID; wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "CTRL_IFACE DEAUTHENTICATE %s", txtaddr); if (hwaddr_aton(txtaddr, addr)) return -1; pos = os_strstr(txtaddr, " test="); if (pos) { struct ieee80211_mgmt mgmt; int encrypt; if (hapd->driver->send_frame == NULL) return -1; pos += 6; encrypt = atoi(pos); os_memset(&mgmt, 0, sizeof(mgmt)); mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH); os_memcpy(mgmt.da, addr, ETH_ALEN); os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN); os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN); mgmt.u.deauth.reason_code = host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID); if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt, IEEE80211_HDRLEN + sizeof(mgmt.u.deauth), encrypt) < 0) return -1; return 0; } #ifdef CONFIG_P2P_MANAGER pos = os_strstr(txtaddr, " p2p="); if (pos) { return p2p_manager_disconnect(hapd, WLAN_FC_STYPE_DEAUTH, atoi(pos + 5), addr); } #endif /* CONFIG_P2P_MANAGER */ pos = os_strstr(txtaddr, " reason="); if (pos) reason = atoi(pos + 8); hostapd_drv_sta_deauth(hapd, addr, reason); sta = ap_get_sta(hapd, addr); if (sta) ap_sta_deauthenticate(hapd, sta, reason); else if (addr[0] == 0xff) hostapd_free_stas(hapd); return 0; }
int ap_sta_wps_cancel(struct hostapd_data *hapd, struct sta_info *sta, void *ctx) { if (sta && (sta->flags & WLAN_STA_WPS)) { ap_sta_deauthenticate(hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID); wpa_printf(MSG_DEBUG, "WPS: %s: Deauth sta=" MACSTR, __func__, MAC2STR(sta->addr)); return 1; } return 0; }
int ap_ctrl_iface_deauthenticate(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 DEAUTHENTICATE %s", txtaddr); if (hwaddr_aton(txtaddr, addr)) return -1; hostapd_drv_sta_deauth(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_deauthenticate(wpa_s->ap_iface->bss[0], sta, WLAN_REASON_PREV_AUTH_NOT_VALID); return 0; }
static int hostapd_config_reload_sta(struct hostapd_data *hapd, struct sta_info *sta, void *data) { struct hostapd_config_change *change = data; struct hostapd_bss_config *newbss, *oldbss; int deauth = 0; u8 reason = WLAN_REASON_PREV_AUTH_NOT_VALID; newbss = change->newbss; oldbss = change->oldbss; hapd = change->hapd; if (sta->ssid == &oldbss->ssid) { sta->ssid = &newbss->ssid; if (newbss->ssid.ssid_len != oldbss->ssid.ssid_len || memcmp(newbss->ssid.ssid, oldbss->ssid.ssid, newbss->ssid.ssid_len) != 0) { /* main SSID was changed - kick STA out */ deauth++; } } sta->ssid_probe = sta->ssid; /* * If MAC ACL configuration has changed, deauthenticate stations that * have been removed from accepted list or have been added to denied * list. If external RADIUS server is used for ACL, all stations are * deauthenticated and they will need to authenticate again. This * limits sudden load on the RADIUS server since the verification will * be done over the time needed for the STAs to reauthenticate * themselves. */ if (change->mac_acl_changed && (newbss->macaddr_acl == USE_EXTERNAL_RADIUS_AUTH || !hostapd_allowed_address(hapd, sta->addr, NULL, 0, NULL, NULL, NULL))) deauth++; if (newbss->ieee802_1x != oldbss->ieee802_1x && sta->ssid == &hapd->conf->ssid) deauth++; if (newbss->wpa != oldbss->wpa) deauth++; if (!newbss->wme_enabled && (sta->flags & WLAN_STA_WME)) deauth++; if (newbss->auth_algs != oldbss->auth_algs && ((sta->auth_alg == WLAN_AUTH_OPEN && !(newbss->auth_algs & HOSTAPD_AUTH_OPEN)) || (sta->auth_alg == WLAN_AUTH_SHARED_KEY && !(newbss->auth_algs & HOSTAPD_AUTH_SHARED_KEY)))) deauth++; if (change->num_sta_remove > 0) { deauth++; reason = WLAN_REASON_DISASSOC_AP_BUSY; } if (deauth) { HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "STA " MACSTR " deauthenticated during config reloading " "(reason=%d)\n", MAC2STR(sta->addr), reason); ieee802_11_send_deauth(hapd, sta->addr, reason); ap_sta_deauthenticate(hapd, sta, reason); change->num_sta_remove--; } return 0; }