2 * hostapd / Station table
3 * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
15 #include "utils/includes.h"
17 #include "utils/common.h"
18 #include "utils/eloop.h"
19 #include "common/ieee802_11_defs.h"
20 #include "radius/radius.h"
21 #include "radius/radius_client.h"
22 #include "drivers/driver.h"
25 #include "accounting.h"
26 #include "ieee802_1x.h"
27 #include "ieee802_11.h"
29 #include "preauth_auth.h"
30 #include "ap_config.h"
33 #include "vlan_init.h"
36 static void ap_sta_remove_in_other_bss(struct hostapd_data *hapd,
37 struct sta_info *sta);
38 static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx);
39 #ifdef CONFIG_IEEE80211W
40 static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx);
41 #endif /* CONFIG_IEEE80211W */
43 int ap_for_each_sta(struct hostapd_data *hapd,
44 int (*cb)(struct hostapd_data *hapd, struct sta_info *sta,
50 for (sta = hapd->sta_list; sta; sta = sta->next) {
51 if (cb(hapd, sta, ctx))
59 struct sta_info * ap_get_sta(struct hostapd_data *hapd, const u8 *sta)
63 s = hapd->sta_hash[STA_HASH(sta)];
64 while (s != NULL && os_memcmp(s->addr, sta, 6) != 0)
70 static void ap_sta_list_del(struct hostapd_data *hapd, struct sta_info *sta)
74 if (hapd->sta_list == sta) {
75 hapd->sta_list = sta->next;
80 while (tmp != NULL && tmp->next != sta)
83 wpa_printf(MSG_DEBUG, "Could not remove STA " MACSTR " from "
84 "list.", MAC2STR(sta->addr));
86 tmp->next = sta->next;
90 void ap_sta_hash_add(struct hostapd_data *hapd, struct sta_info *sta)
92 sta->hnext = hapd->sta_hash[STA_HASH(sta->addr)];
93 hapd->sta_hash[STA_HASH(sta->addr)] = sta;
97 static void ap_sta_hash_del(struct hostapd_data *hapd, struct sta_info *sta)
101 s = hapd->sta_hash[STA_HASH(sta->addr)];
102 if (s == NULL) return;
103 if (os_memcmp(s->addr, sta->addr, 6) == 0) {
104 hapd->sta_hash[STA_HASH(sta->addr)] = s->hnext;
108 while (s->hnext != NULL &&
109 os_memcmp(s->hnext->addr, sta->addr, ETH_ALEN) != 0)
111 if (s->hnext != NULL)
112 s->hnext = s->hnext->hnext;
114 wpa_printf(MSG_DEBUG, "AP: could not remove STA " MACSTR
115 " from hash table", MAC2STR(sta->addr));
119 void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
123 accounting_sta_stop(hapd, sta);
125 if (sta->flags & WLAN_STA_WDS)
126 hapd->drv.set_wds_sta(hapd, sta->addr, sta->aid, 0);
128 if (!(sta->flags & WLAN_STA_PREAUTH))
129 hapd->drv.sta_remove(hapd, sta->addr);
131 ap_sta_hash_del(hapd, sta);
132 ap_sta_list_del(hapd, sta);
135 hapd->sta_aid[(sta->aid - 1) / 32] &=
136 ~BIT((sta->aid - 1) % 32);
139 if (sta->nonerp_set) {
141 hapd->iface->num_sta_non_erp--;
142 if (hapd->iface->num_sta_non_erp == 0)
146 if (sta->no_short_slot_time_set) {
147 sta->no_short_slot_time_set = 0;
148 hapd->iface->num_sta_no_short_slot_time--;
149 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
150 && hapd->iface->num_sta_no_short_slot_time == 0)
154 if (sta->no_short_preamble_set) {
155 sta->no_short_preamble_set = 0;
156 hapd->iface->num_sta_no_short_preamble--;
157 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
158 && hapd->iface->num_sta_no_short_preamble == 0)
162 if (sta->no_ht_gf_set) {
163 sta->no_ht_gf_set = 0;
164 hapd->iface->num_sta_ht_no_gf--;
167 if (sta->no_ht_set) {
169 hapd->iface->num_sta_no_ht--;
172 if (sta->ht_20mhz_set) {
173 sta->ht_20mhz_set = 0;
174 hapd->iface->num_sta_ht_20mhz--;
177 #if defined(NEED_AP_MLME) && defined(CONFIG_IEEE80211N)
178 if (hostapd_ht_operation_update(hapd->iface) > 0)
180 #endif /* NEED_AP_MLME && CONFIG_IEEE80211N */
183 ieee802_11_set_beacons(hapd->iface);
185 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
186 eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
188 ieee802_1x_free_station(sta);
189 wpa_auth_sta_deinit(sta->wpa_sm);
190 rsn_preauth_free_station(hapd, sta);
191 #ifndef CONFIG_NO_RADIUS
192 radius_client_flush_auth(hapd->radius, sta->addr);
193 #endif /* CONFIG_NO_RADIUS */
195 os_free(sta->last_assoc_req);
196 os_free(sta->challenge);
198 #ifdef CONFIG_IEEE80211W
199 os_free(sta->sa_query_trans_id);
200 eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
201 #endif /* CONFIG_IEEE80211W */
204 p2p_group_notif_disassoc(hapd->p2p_group, sta->addr);
205 #endif /* CONFIG_P2P */
207 wpabuf_free(sta->wps_ie);
208 wpabuf_free(sta->p2p_ie);
210 os_free(sta->ht_capabilities);
216 void hostapd_free_stas(struct hostapd_data *hapd)
218 struct sta_info *sta, *prev;
220 sta = hapd->sta_list;
224 if (sta->flags & WLAN_STA_AUTH) {
225 mlme_deauthenticate_indication(
226 hapd, sta, WLAN_REASON_UNSPECIFIED);
229 wpa_printf(MSG_DEBUG, "Removing station " MACSTR,
230 MAC2STR(prev->addr));
231 ap_free_sta(hapd, prev);
237 * ap_handle_timer - Per STA timer handler
238 * @eloop_ctx: struct hostapd_data *
239 * @timeout_ctx: struct sta_info *
241 * This function is called to check station activity and to remove inactive
244 void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
246 struct hostapd_data *hapd = eloop_ctx;
247 struct sta_info *sta = timeout_ctx;
248 unsigned long next_time = 0;
250 if (sta->timeout_next == STA_REMOVE) {
251 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
252 HOSTAPD_LEVEL_INFO, "deauthenticated due to "
253 "local deauth request");
254 ap_free_sta(hapd, sta);
258 if ((sta->flags & WLAN_STA_ASSOC) &&
259 (sta->timeout_next == STA_NULLFUNC ||
260 sta->timeout_next == STA_DISASSOC)) {
262 wpa_printf(MSG_DEBUG, "Checking STA " MACSTR " inactivity:",
264 inactive_sec = hapd->drv.get_inact_sec(hapd, sta->addr);
265 if (inactive_sec == -1) {
266 wpa_printf(MSG_DEBUG, "Could not get station info "
267 "from kernel driver for " MACSTR ".",
269 } else if (inactive_sec < hapd->conf->ap_max_inactivity &&
270 sta->flags & WLAN_STA_ASSOC) {
271 /* station activity detected; reset timeout state */
272 wpa_printf(MSG_DEBUG, " Station has been active");
273 sta->timeout_next = STA_NULLFUNC;
274 next_time = hapd->conf->ap_max_inactivity -
279 if ((sta->flags & WLAN_STA_ASSOC) &&
280 sta->timeout_next == STA_DISASSOC &&
281 !(sta->flags & WLAN_STA_PENDING_POLL)) {
282 wpa_printf(MSG_DEBUG, " Station has ACKed data poll");
283 /* data nullfunc frame poll did not produce TX errors; assume
284 * station ACKed it */
285 sta->timeout_next = STA_NULLFUNC;
286 next_time = hapd->conf->ap_max_inactivity;
290 eloop_register_timeout(next_time, 0, ap_handle_timer, hapd,
295 if (sta->timeout_next == STA_NULLFUNC &&
296 (sta->flags & WLAN_STA_ASSOC)) {
297 #ifndef CONFIG_NATIVE_WINDOWS
298 /* send data frame to poll STA and check whether this frame
300 struct ieee80211_hdr hdr;
302 wpa_printf(MSG_DEBUG, " Polling STA with data frame");
303 sta->flags |= WLAN_STA_PENDING_POLL;
305 os_memset(&hdr, 0, sizeof(hdr));
307 os_strcmp(hapd->driver->name, "hostap") == 0) {
309 * WLAN_FC_STYPE_NULLFUNC would be more appropriate,
310 * but it is apparently not retried so TX Exc events
311 * are not received for it.
314 IEEE80211_FC(WLAN_FC_TYPE_DATA,
318 IEEE80211_FC(WLAN_FC_TYPE_DATA,
319 WLAN_FC_STYPE_NULLFUNC);
322 hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS);
323 os_memcpy(hdr.IEEE80211_DA_FROMDS, sta->addr, ETH_ALEN);
324 os_memcpy(hdr.IEEE80211_BSSID_FROMDS, hapd->own_addr,
326 os_memcpy(hdr.IEEE80211_SA_FROMDS, hapd->own_addr, ETH_ALEN);
328 if (hapd->drv.send_mgmt_frame(hapd, &hdr, sizeof(hdr)) < 0)
329 perror("ap_handle_timer: send");
330 #endif /* CONFIG_NATIVE_WINDOWS */
331 } else if (sta->timeout_next != STA_REMOVE) {
332 int deauth = sta->timeout_next == STA_DEAUTH;
334 wpa_printf(MSG_DEBUG, "Sending %s info to STA " MACSTR,
335 deauth ? "deauthentication" : "disassociation",
339 hapd->drv.sta_deauth(hapd, sta->addr,
340 WLAN_REASON_PREV_AUTH_NOT_VALID);
342 hapd->drv.sta_disassoc(
344 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
348 switch (sta->timeout_next) {
350 sta->timeout_next = STA_DISASSOC;
351 eloop_register_timeout(AP_DISASSOC_DELAY, 0, ap_handle_timer,
355 sta->flags &= ~WLAN_STA_ASSOC;
356 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
357 if (!sta->acct_terminate_cause)
358 sta->acct_terminate_cause =
359 RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT;
360 accounting_sta_stop(hapd, sta);
361 ieee802_1x_free_station(sta);
362 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
363 HOSTAPD_LEVEL_INFO, "disassociated due to "
365 sta->timeout_next = STA_DEAUTH;
366 eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
368 mlme_disassociate_indication(
369 hapd, sta, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
373 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
374 HOSTAPD_LEVEL_INFO, "deauthenticated due to "
376 if (!sta->acct_terminate_cause)
377 sta->acct_terminate_cause =
378 RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT;
379 mlme_deauthenticate_indication(
381 WLAN_REASON_PREV_AUTH_NOT_VALID);
382 ap_free_sta(hapd, sta);
388 static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx)
390 struct hostapd_data *hapd = eloop_ctx;
391 struct sta_info *sta = timeout_ctx;
394 if (!(sta->flags & WLAN_STA_AUTH))
397 mlme_deauthenticate_indication(hapd, sta,
398 WLAN_REASON_PREV_AUTH_NOT_VALID);
399 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
400 HOSTAPD_LEVEL_INFO, "deauthenticated due to "
402 sta->acct_terminate_cause =
403 RADIUS_ACCT_TERMINATE_CAUSE_SESSION_TIMEOUT;
404 os_memcpy(addr, sta->addr, ETH_ALEN);
405 ap_free_sta(hapd, sta);
406 hapd->drv.sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
410 void ap_sta_session_timeout(struct hostapd_data *hapd, struct sta_info *sta,
413 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
414 HOSTAPD_LEVEL_DEBUG, "setting session timeout to %d "
415 "seconds", session_timeout);
416 eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
417 eloop_register_timeout(session_timeout, 0, ap_handle_session_timer,
422 void ap_sta_no_session_timeout(struct hostapd_data *hapd, struct sta_info *sta)
424 eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
428 struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
430 struct sta_info *sta;
432 sta = ap_get_sta(hapd, addr);
436 wpa_printf(MSG_DEBUG, " New STA");
437 if (hapd->num_sta >= hapd->conf->max_num_sta) {
438 /* FIX: might try to remove some old STAs first? */
439 wpa_printf(MSG_DEBUG, "no more room for new STAs (%d/%d)",
440 hapd->num_sta, hapd->conf->max_num_sta);
444 sta = os_zalloc(sizeof(struct sta_info));
446 wpa_printf(MSG_ERROR, "malloc failed");
449 sta->acct_interim_interval = hapd->conf->acct_interim_interval;
451 /* initialize STA info data */
452 eloop_register_timeout(hapd->conf->ap_max_inactivity, 0,
453 ap_handle_timer, hapd, sta);
454 os_memcpy(sta->addr, addr, ETH_ALEN);
455 sta->next = hapd->sta_list;
456 hapd->sta_list = sta;
458 ap_sta_hash_add(hapd, sta);
459 sta->ssid = &hapd->conf->ssid;
460 ap_sta_remove_in_other_bss(hapd, sta);
466 static int ap_sta_remove(struct hostapd_data *hapd, struct sta_info *sta)
468 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
470 wpa_printf(MSG_DEBUG, "Removing STA " MACSTR " from kernel driver",
472 if (hapd->drv.sta_remove(hapd, sta->addr) &&
473 sta->flags & WLAN_STA_ASSOC) {
474 wpa_printf(MSG_DEBUG, "Could not remove station " MACSTR
475 " from kernel driver.", MAC2STR(sta->addr));
482 static void ap_sta_remove_in_other_bss(struct hostapd_data *hapd,
483 struct sta_info *sta)
485 struct hostapd_iface *iface = hapd->iface;
488 for (i = 0; i < iface->num_bss; i++) {
489 struct hostapd_data *bss = iface->bss[i];
490 struct sta_info *sta2;
491 /* bss should always be set during operation, but it may be
492 * NULL during reconfiguration. Assume the STA is not
493 * associated to another BSS in that case to avoid NULL pointer
495 if (bss == hapd || bss == NULL)
497 sta2 = ap_get_sta(bss, sta->addr);
501 ap_sta_disconnect(bss, sta2, sta2->addr,
502 WLAN_REASON_PREV_AUTH_NOT_VALID);
507 void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta,
510 wpa_printf(MSG_DEBUG, "%s: disassociate STA " MACSTR,
511 hapd->conf->iface, MAC2STR(sta->addr));
512 sta->flags &= ~WLAN_STA_ASSOC;
513 ap_sta_remove(hapd, sta);
514 sta->timeout_next = STA_DEAUTH;
515 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
516 eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DISASSOC, 0,
517 ap_handle_timer, hapd, sta);
518 accounting_sta_stop(hapd, sta);
519 ieee802_1x_free_station(sta);
521 mlme_disassociate_indication(hapd, sta, reason);
525 void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
528 wpa_printf(MSG_DEBUG, "%s: deauthenticate STA " MACSTR,
529 hapd->conf->iface, MAC2STR(sta->addr));
530 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
531 ap_sta_remove(hapd, sta);
532 sta->timeout_next = STA_REMOVE;
533 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
534 eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0,
535 ap_handle_timer, hapd, sta);
536 accounting_sta_stop(hapd, sta);
537 ieee802_1x_free_station(sta);
539 mlme_deauthenticate_indication(hapd, sta, reason);
543 int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta,
546 #ifndef CONFIG_NO_VLAN
548 struct hostapd_vlan *vlan = NULL;
552 * Do not proceed furthur if the vlan id remains same. We do not want
553 * duplicate dynamic vlan entries.
555 if (sta->vlan_id == old_vlanid)
559 * During 1x reauth, if the vlan id changes, then remove the old id and
560 * proceed furthur to add the new one.
563 vlan_remove_dynamic(hapd, old_vlanid);
565 iface = hapd->conf->iface;
566 if (sta->ssid->vlan[0])
567 iface = sta->ssid->vlan;
569 if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED)
571 else if (sta->vlan_id > 0) {
572 vlan = hapd->conf->vlan;
574 if (vlan->vlan_id == sta->vlan_id ||
575 vlan->vlan_id == VLAN_ID_WILDCARD) {
576 iface = vlan->ifname;
583 if (sta->vlan_id > 0 && vlan == NULL) {
584 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
585 HOSTAPD_LEVEL_DEBUG, "could not find VLAN for "
586 "binding station to (vlan_id=%d)",
589 } else if (sta->vlan_id > 0 && vlan->vlan_id == VLAN_ID_WILDCARD) {
590 vlan = vlan_add_dynamic(hapd, vlan, sta->vlan_id);
592 hostapd_logger(hapd, sta->addr,
593 HOSTAPD_MODULE_IEEE80211,
594 HOSTAPD_LEVEL_DEBUG, "could not add "
595 "dynamic VLAN interface for vlan_id=%d",
600 iface = vlan->ifname;
601 if (vlan_setup_encryption_dyn(hapd, sta->ssid, iface) != 0) {
602 hostapd_logger(hapd, sta->addr,
603 HOSTAPD_MODULE_IEEE80211,
604 HOSTAPD_LEVEL_DEBUG, "could not "
605 "configure encryption for dynamic VLAN "
606 "interface for vlan_id=%d",
610 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
611 HOSTAPD_LEVEL_DEBUG, "added new dynamic VLAN "
612 "interface '%s'", iface);
613 } else if (vlan && vlan->vlan_id == sta->vlan_id) {
614 if (sta->vlan_id > 0) {
615 vlan->dynamic_vlan++;
616 hostapd_logger(hapd, sta->addr,
617 HOSTAPD_MODULE_IEEE80211,
618 HOSTAPD_LEVEL_DEBUG, "updated existing "
619 "dynamic VLAN interface '%s'", iface);
623 * Update encryption configuration for statically generated
624 * VLAN interface. This is only used for static WEP
625 * configuration for the case where hostapd did not yet know
626 * which keys are to be used when the interface was added.
628 if (vlan_setup_encryption_dyn(hapd, sta->ssid, iface) != 0) {
629 hostapd_logger(hapd, sta->addr,
630 HOSTAPD_MODULE_IEEE80211,
631 HOSTAPD_LEVEL_DEBUG, "could not "
632 "configure encryption for VLAN "
633 "interface for vlan_id=%d",
638 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
639 HOSTAPD_LEVEL_DEBUG, "binding station to interface "
642 if (wpa_auth_sta_set_vlan(sta->wpa_sm, sta->vlan_id) < 0)
643 wpa_printf(MSG_INFO, "Failed to update VLAN-ID for WPA");
645 ret = hapd->drv.set_sta_vlan(iface, hapd, sta->addr, sta->vlan_id);
647 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
648 HOSTAPD_LEVEL_DEBUG, "could not bind the STA "
649 "entry to vlan_id=%d", sta->vlan_id);
652 #else /* CONFIG_NO_VLAN */
654 #endif /* CONFIG_NO_VLAN */
658 #ifdef CONFIG_IEEE80211W
660 int ap_check_sa_query_timeout(struct hostapd_data *hapd, struct sta_info *sta)
663 struct os_time now, passed;
665 os_time_sub(&now, &sta->sa_query_start, &passed);
666 tu = (passed.sec * 1000000 + passed.usec) / 1024;
667 if (hapd->conf->assoc_sa_query_max_timeout < tu) {
668 hostapd_logger(hapd, sta->addr,
669 HOSTAPD_MODULE_IEEE80211,
671 "association SA Query timed out");
672 sta->sa_query_timed_out = 1;
673 os_free(sta->sa_query_trans_id);
674 sta->sa_query_trans_id = NULL;
675 sta->sa_query_count = 0;
676 eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
684 static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx)
686 struct hostapd_data *hapd = eloop_ctx;
687 struct sta_info *sta = timeout_ctx;
688 unsigned int timeout, sec, usec;
691 if (sta->sa_query_count > 0 &&
692 ap_check_sa_query_timeout(hapd, sta))
695 nbuf = os_realloc(sta->sa_query_trans_id,
696 (sta->sa_query_count + 1) * WLAN_SA_QUERY_TR_ID_LEN);
699 if (sta->sa_query_count == 0) {
700 /* Starting a new SA Query procedure */
701 os_get_time(&sta->sa_query_start);
703 trans_id = nbuf + sta->sa_query_count * WLAN_SA_QUERY_TR_ID_LEN;
704 sta->sa_query_trans_id = nbuf;
705 sta->sa_query_count++;
707 os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN);
709 timeout = hapd->conf->assoc_sa_query_retry_timeout;
710 sec = ((timeout / 1000) * 1024) / 1000;
711 usec = (timeout % 1000) * 1024;
712 eloop_register_timeout(sec, usec, ap_sa_query_timer, hapd, sta);
714 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
716 "association SA Query attempt %d", sta->sa_query_count);
719 ieee802_11_send_sa_query_req(hapd, sta->addr, trans_id);
720 #endif /* NEED_AP_MLME */
724 void ap_sta_start_sa_query(struct hostapd_data *hapd, struct sta_info *sta)
726 ap_sa_query_timer(hapd, sta);
730 void ap_sta_stop_sa_query(struct hostapd_data *hapd, struct sta_info *sta)
732 eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
733 os_free(sta->sa_query_trans_id);
734 sta->sa_query_trans_id = NULL;
735 sta->sa_query_count = 0;
738 #endif /* CONFIG_IEEE80211W */
741 void ap_sta_disconnect(struct hostapd_data *hapd, struct sta_info *sta,
742 const u8 *addr, u16 reason)
745 if (sta == NULL && addr)
746 sta = ap_get_sta(hapd, addr);
749 hapd->drv.sta_deauth(hapd, addr, reason);
753 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_AUTHORIZED);
754 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
755 eloop_register_timeout(0, 0, ap_handle_timer, hapd, sta);
756 sta->timeout_next = STA_REMOVE;