void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr) { struct sta_info *sta = ap_get_sta(hapd, addr); if (!sta || !hapd->conf->disassoc_low_ack) return; hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "disconnected due to excessive " "missing ACKs"); hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_DISASSOC_LOW_ACK); if (sta) ap_sta_disassociate(hapd, sta, WLAN_REASON_DISASSOC_LOW_ACK); }
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 int prune_associations(struct hostapd_iface *iface, void *ctx) { struct prune_data *data = ctx; struct sta_info *osta; struct hostapd_data *ohapd; size_t j; for (j = 0; j < iface->num_bss; j++) { ohapd = iface->bss[j]; if (ohapd == data->hapd) continue; osta = ap_get_sta(ohapd, data->addr); if (!osta) continue; ap_sta_disassociate(ohapd, osta, WLAN_REASON_UNSPECIFIED); } return 0; }
int hostapd_ctrl_iface_disassociate(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 DISASSOCIATE %s", txtaddr); if (hwaddr_aton(txtaddr, addr)) return -1; pos = os_strstr(txtaddr, " reason="); if (pos) reason = atoi(pos + 8); pos = os_strstr(txtaddr, " test="); if (pos) { struct ieee80211_mgmt mgmt; int encrypt; if (!hapd->drv_priv || !hapd->driver->send_frame) 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_DISASSOC); 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.disassoc.reason_code = host_to_le16(reason); 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_DISASSOC, atoi(pos + 5), addr); } #endif /* CONFIG_P2P_MANAGER */ if (os_strstr(txtaddr, " tx=0")) hostapd_drv_sta_remove(hapd, addr); else hostapd_drv_sta_disassoc(hapd, addr, reason); sta = ap_get_sta(hapd, addr); if (sta) ap_sta_disassociate(hapd, sta, reason); else if (addr[0] == 0xff) hostapd_free_stas(hapd); return 0; }