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"
24 #include "accounting.h"
25 #include "ieee802_1x.h"
26 #include "ieee802_11.h"
28 #include "preauth_auth.h"
29 #include "ap_config.h"
32 #include "vlan_init.h"
35 static int ap_sta_in_other_bss(struct hostapd_data
*hapd
,
36 struct sta_info
*sta
, u32 flags
);
37 static void ap_handle_session_timer(void *eloop_ctx
, void *timeout_ctx
);
38 #ifdef CONFIG_IEEE80211W
39 static void ap_sa_query_timer(void *eloop_ctx
, void *timeout_ctx
);
40 #endif /* CONFIG_IEEE80211W */
42 int ap_for_each_sta(struct hostapd_data
*hapd
,
43 int (*cb
)(struct hostapd_data
*hapd
, struct sta_info
*sta
,
49 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
50 if (cb(hapd
, sta
, ctx
))
58 struct sta_info
* ap_get_sta(struct hostapd_data
*hapd
, const u8
*sta
)
62 s
= hapd
->sta_hash
[STA_HASH(sta
)];
63 while (s
!= NULL
&& os_memcmp(s
->addr
, sta
, 6) != 0)
69 static void ap_sta_list_del(struct hostapd_data
*hapd
, struct sta_info
*sta
)
73 if (hapd
->sta_list
== sta
) {
74 hapd
->sta_list
= sta
->next
;
79 while (tmp
!= NULL
&& tmp
->next
!= sta
)
82 wpa_printf(MSG_DEBUG
, "Could not remove STA " MACSTR
" from "
83 "list.", MAC2STR(sta
->addr
));
85 tmp
->next
= sta
->next
;
89 void ap_sta_hash_add(struct hostapd_data
*hapd
, struct sta_info
*sta
)
91 sta
->hnext
= hapd
->sta_hash
[STA_HASH(sta
->addr
)];
92 hapd
->sta_hash
[STA_HASH(sta
->addr
)] = sta
;
96 static void ap_sta_hash_del(struct hostapd_data
*hapd
, struct sta_info
*sta
)
100 s
= hapd
->sta_hash
[STA_HASH(sta
->addr
)];
101 if (s
== NULL
) return;
102 if (os_memcmp(s
->addr
, sta
->addr
, 6) == 0) {
103 hapd
->sta_hash
[STA_HASH(sta
->addr
)] = s
->hnext
;
107 while (s
->hnext
!= NULL
&&
108 os_memcmp(s
->hnext
->addr
, sta
->addr
, ETH_ALEN
) != 0)
110 if (s
->hnext
!= NULL
)
111 s
->hnext
= s
->hnext
->hnext
;
113 wpa_printf(MSG_DEBUG
, "AP: could not remove STA " MACSTR
114 " from hash table", MAC2STR(sta
->addr
));
118 void ap_free_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
)
122 accounting_sta_stop(hapd
, sta
);
124 hapd
->drv
.set_wds_sta(hapd
, sta
->addr
, sta
->aid
, 0);
125 if (!ap_sta_in_other_bss(hapd
, sta
, WLAN_STA_ASSOC
) &&
126 !(sta
->flags
& WLAN_STA_PREAUTH
))
127 hapd
->drv
.sta_remove(hapd
, sta
->addr
);
129 ap_sta_hash_del(hapd
, sta
);
130 ap_sta_list_del(hapd
, sta
);
133 hapd
->sta_aid
[(sta
->aid
- 1) / 32] &=
134 ~BIT((sta
->aid
- 1) % 32);
137 if (sta
->nonerp_set
) {
139 hapd
->iface
->num_sta_non_erp
--;
140 if (hapd
->iface
->num_sta_non_erp
== 0)
144 if (sta
->no_short_slot_time_set
) {
145 sta
->no_short_slot_time_set
= 0;
146 hapd
->iface
->num_sta_no_short_slot_time
--;
147 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
148 && hapd
->iface
->num_sta_no_short_slot_time
== 0)
152 if (sta
->no_short_preamble_set
) {
153 sta
->no_short_preamble_set
= 0;
154 hapd
->iface
->num_sta_no_short_preamble
--;
155 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
156 && hapd
->iface
->num_sta_no_short_preamble
== 0)
160 if (sta
->no_ht_gf_set
) {
161 sta
->no_ht_gf_set
= 0;
162 hapd
->iface
->num_sta_ht_no_gf
--;
165 if (sta
->no_ht_set
) {
167 hapd
->iface
->num_sta_no_ht
--;
170 if (sta
->ht_20mhz_set
) {
171 sta
->ht_20mhz_set
= 0;
172 hapd
->iface
->num_sta_ht_20mhz
--;
175 #if defined(NEED_AP_MLME) && defined(CONFIG_IEEE80211N)
176 if (hostapd_ht_operation_update(hapd
->iface
) > 0)
178 #endif /* NEED_AP_MLME && CONFIG_IEEE80211N */
181 ieee802_11_set_beacons(hapd
->iface
);
183 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
184 eloop_cancel_timeout(ap_handle_session_timer
, hapd
, sta
);
186 ieee802_1x_free_station(sta
);
187 wpa_auth_sta_deinit(sta
->wpa_sm
);
188 rsn_preauth_free_station(hapd
, sta
);
189 #ifndef CONFIG_NO_RADIUS
190 radius_client_flush_auth(hapd
->radius
, sta
->addr
);
191 #endif /* CONFIG_NO_RADIUS */
193 os_free(sta
->last_assoc_req
);
194 os_free(sta
->challenge
);
196 #ifdef CONFIG_IEEE80211W
197 os_free(sta
->sa_query_trans_id
);
198 eloop_cancel_timeout(ap_sa_query_timer
, hapd
, sta
);
199 #endif /* CONFIG_IEEE80211W */
201 wpabuf_free(sta
->wps_ie
);
203 os_free(sta
->ht_capabilities
);
209 void hostapd_free_stas(struct hostapd_data
*hapd
)
211 struct sta_info
*sta
, *prev
;
213 sta
= hapd
->sta_list
;
217 if (sta
->flags
& WLAN_STA_AUTH
) {
218 mlme_deauthenticate_indication(
219 hapd
, sta
, WLAN_REASON_UNSPECIFIED
);
222 wpa_printf(MSG_DEBUG
, "Removing station " MACSTR
,
223 MAC2STR(prev
->addr
));
224 ap_free_sta(hapd
, prev
);
230 * ap_handle_timer - Per STA timer handler
231 * @eloop_ctx: struct hostapd_data *
232 * @timeout_ctx: struct sta_info *
234 * This function is called to check station activity and to remove inactive
237 void ap_handle_timer(void *eloop_ctx
, void *timeout_ctx
)
239 struct hostapd_data
*hapd
= eloop_ctx
;
240 struct sta_info
*sta
= timeout_ctx
;
241 unsigned long next_time
= 0;
243 if (sta
->timeout_next
== STA_REMOVE
) {
244 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
245 HOSTAPD_LEVEL_INFO
, "deauthenticated due to "
246 "local deauth request");
247 ap_free_sta(hapd
, sta
);
251 if ((sta
->flags
& WLAN_STA_ASSOC
) &&
252 (sta
->timeout_next
== STA_NULLFUNC
||
253 sta
->timeout_next
== STA_DISASSOC
)) {
255 wpa_printf(MSG_DEBUG
, "Checking STA " MACSTR
" inactivity:",
257 inactive_sec
= hapd
->drv
.get_inact_sec(hapd
, sta
->addr
);
258 if (inactive_sec
== -1) {
259 wpa_printf(MSG_DEBUG
, "Could not get station info "
260 "from kernel driver for " MACSTR
".",
262 } else if (inactive_sec
< hapd
->conf
->ap_max_inactivity
&&
263 sta
->flags
& WLAN_STA_ASSOC
) {
264 /* station activity detected; reset timeout state */
265 wpa_printf(MSG_DEBUG
, " Station has been active");
266 sta
->timeout_next
= STA_NULLFUNC
;
267 next_time
= hapd
->conf
->ap_max_inactivity
-
272 if ((sta
->flags
& WLAN_STA_ASSOC
) &&
273 sta
->timeout_next
== STA_DISASSOC
&&
274 !(sta
->flags
& WLAN_STA_PENDING_POLL
)) {
275 wpa_printf(MSG_DEBUG
, " Station has ACKed data poll");
276 /* data nullfunc frame poll did not produce TX errors; assume
277 * station ACKed it */
278 sta
->timeout_next
= STA_NULLFUNC
;
279 next_time
= hapd
->conf
->ap_max_inactivity
;
283 eloop_register_timeout(next_time
, 0, ap_handle_timer
, hapd
,
288 if (sta
->timeout_next
== STA_NULLFUNC
&&
289 (sta
->flags
& WLAN_STA_ASSOC
)) {
290 /* send data frame to poll STA and check whether this frame
292 struct ieee80211_hdr hdr
;
294 wpa_printf(MSG_DEBUG
, " Polling STA with data frame");
295 sta
->flags
|= WLAN_STA_PENDING_POLL
;
297 #ifndef CONFIG_NATIVE_WINDOWS
298 os_memset(&hdr
, 0, sizeof(hdr
));
300 os_strcmp(hapd
->driver
->name
, "hostap") == 0) {
302 * WLAN_FC_STYPE_NULLFUNC would be more appropriate,
303 * but it is apparently not retried so TX Exc events
304 * are not received for it.
307 IEEE80211_FC(WLAN_FC_TYPE_DATA
,
311 IEEE80211_FC(WLAN_FC_TYPE_DATA
,
312 WLAN_FC_STYPE_NULLFUNC
);
315 hdr
.frame_control
|= host_to_le16(WLAN_FC_FROMDS
);
316 os_memcpy(hdr
.IEEE80211_DA_FROMDS
, sta
->addr
, ETH_ALEN
);
317 os_memcpy(hdr
.IEEE80211_BSSID_FROMDS
, hapd
->own_addr
,
319 os_memcpy(hdr
.IEEE80211_SA_FROMDS
, hapd
->own_addr
, ETH_ALEN
);
321 if (hapd
->drv
.send_mgmt_frame(hapd
, &hdr
, sizeof(hdr
)) < 0)
322 perror("ap_handle_timer: send");
323 #endif /* CONFIG_NATIVE_WINDOWS */
324 } else if (sta
->timeout_next
!= STA_REMOVE
) {
325 int deauth
= sta
->timeout_next
== STA_DEAUTH
;
327 wpa_printf(MSG_DEBUG
, "Sending %s info to STA " MACSTR
,
328 deauth
? "deauthentication" : "disassociation",
332 hapd
->drv
.sta_deauth(hapd
, sta
->addr
,
333 WLAN_REASON_PREV_AUTH_NOT_VALID
);
335 hapd
->drv
.sta_disassoc(
337 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY
);
341 switch (sta
->timeout_next
) {
343 sta
->timeout_next
= STA_DISASSOC
;
344 eloop_register_timeout(AP_DISASSOC_DELAY
, 0, ap_handle_timer
,
348 sta
->flags
&= ~WLAN_STA_ASSOC
;
349 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
350 if (!sta
->acct_terminate_cause
)
351 sta
->acct_terminate_cause
=
352 RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT
;
353 accounting_sta_stop(hapd
, sta
);
354 ieee802_1x_free_station(sta
);
355 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
356 HOSTAPD_LEVEL_INFO
, "disassociated due to "
358 sta
->timeout_next
= STA_DEAUTH
;
359 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
361 mlme_disassociate_indication(
362 hapd
, sta
, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY
);
366 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
367 HOSTAPD_LEVEL_INFO
, "deauthenticated due to "
369 if (!sta
->acct_terminate_cause
)
370 sta
->acct_terminate_cause
=
371 RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT
;
372 mlme_deauthenticate_indication(
374 WLAN_REASON_PREV_AUTH_NOT_VALID
);
375 ap_free_sta(hapd
, sta
);
381 static void ap_handle_session_timer(void *eloop_ctx
, void *timeout_ctx
)
383 struct hostapd_data
*hapd
= eloop_ctx
;
384 struct sta_info
*sta
= timeout_ctx
;
387 if (!(sta
->flags
& WLAN_STA_AUTH
))
390 mlme_deauthenticate_indication(hapd
, sta
,
391 WLAN_REASON_PREV_AUTH_NOT_VALID
);
392 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
393 HOSTAPD_LEVEL_INFO
, "deauthenticated due to "
395 sta
->acct_terminate_cause
=
396 RADIUS_ACCT_TERMINATE_CAUSE_SESSION_TIMEOUT
;
397 os_memcpy(addr
, sta
->addr
, ETH_ALEN
);
398 ap_free_sta(hapd
, sta
);
399 hapd
->drv
.sta_deauth(hapd
, addr
, WLAN_REASON_PREV_AUTH_NOT_VALID
);
403 void ap_sta_session_timeout(struct hostapd_data
*hapd
, struct sta_info
*sta
,
406 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
407 HOSTAPD_LEVEL_DEBUG
, "setting session timeout to %d "
408 "seconds", session_timeout
);
409 eloop_cancel_timeout(ap_handle_session_timer
, hapd
, sta
);
410 eloop_register_timeout(session_timeout
, 0, ap_handle_session_timer
,
415 void ap_sta_no_session_timeout(struct hostapd_data
*hapd
, struct sta_info
*sta
)
417 eloop_cancel_timeout(ap_handle_session_timer
, hapd
, sta
);
421 struct sta_info
* ap_sta_add(struct hostapd_data
*hapd
, const u8
*addr
)
423 struct sta_info
*sta
;
425 sta
= ap_get_sta(hapd
, addr
);
429 wpa_printf(MSG_DEBUG
, " New STA");
430 if (hapd
->num_sta
>= hapd
->conf
->max_num_sta
) {
431 /* FIX: might try to remove some old STAs first? */
432 wpa_printf(MSG_DEBUG
, "no more room for new STAs (%d/%d)",
433 hapd
->num_sta
, hapd
->conf
->max_num_sta
);
437 sta
= os_zalloc(sizeof(struct sta_info
));
439 wpa_printf(MSG_ERROR
, "malloc failed");
442 sta
->acct_interim_interval
= hapd
->conf
->acct_interim_interval
;
444 /* initialize STA info data */
445 eloop_register_timeout(hapd
->conf
->ap_max_inactivity
, 0,
446 ap_handle_timer
, hapd
, sta
);
447 os_memcpy(sta
->addr
, addr
, ETH_ALEN
);
448 sta
->next
= hapd
->sta_list
;
449 hapd
->sta_list
= sta
;
451 ap_sta_hash_add(hapd
, sta
);
452 sta
->ssid
= &hapd
->conf
->ssid
;
458 static int ap_sta_remove(struct hostapd_data
*hapd
, struct sta_info
*sta
)
460 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
462 wpa_printf(MSG_DEBUG
, "Removing STA " MACSTR
" from kernel driver",
464 if (hapd
->drv
.sta_remove(hapd
, sta
->addr
) &&
465 sta
->flags
& WLAN_STA_ASSOC
) {
466 wpa_printf(MSG_DEBUG
, "Could not remove station " MACSTR
467 " from kernel driver.", MAC2STR(sta
->addr
));
474 static int ap_sta_in_other_bss(struct hostapd_data
*hapd
,
475 struct sta_info
*sta
, u32 flags
)
477 struct hostapd_iface
*iface
= hapd
->iface
;
480 for (i
= 0; i
< iface
->num_bss
; i
++) {
481 struct hostapd_data
*bss
= iface
->bss
[i
];
482 struct sta_info
*sta2
;
483 /* bss should always be set during operation, but it may be
484 * NULL during reconfiguration. Assume the STA is not
485 * associated to another BSS in that case to avoid NULL pointer
487 if (bss
== hapd
|| bss
== NULL
)
489 sta2
= ap_get_sta(bss
, sta
->addr
);
490 if (sta2
&& ((sta2
->flags
& flags
) == flags
))
498 void ap_sta_disassociate(struct hostapd_data
*hapd
, struct sta_info
*sta
,
501 wpa_printf(MSG_DEBUG
, "%s: disassociate STA " MACSTR
,
502 hapd
->conf
->iface
, MAC2STR(sta
->addr
));
503 sta
->flags
&= ~WLAN_STA_ASSOC
;
504 if (!ap_sta_in_other_bss(hapd
, sta
, WLAN_STA_ASSOC
))
505 ap_sta_remove(hapd
, sta
);
506 sta
->timeout_next
= STA_DEAUTH
;
507 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
508 eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DISASSOC
, 0,
509 ap_handle_timer
, hapd
, sta
);
510 accounting_sta_stop(hapd
, sta
);
511 ieee802_1x_free_station(sta
);
513 mlme_disassociate_indication(hapd
, sta
, reason
);
517 void ap_sta_deauthenticate(struct hostapd_data
*hapd
, struct sta_info
*sta
,
520 wpa_printf(MSG_DEBUG
, "%s: deauthenticate STA " MACSTR
,
521 hapd
->conf
->iface
, MAC2STR(sta
->addr
));
522 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
);
523 if (!ap_sta_in_other_bss(hapd
, sta
, WLAN_STA_ASSOC
))
524 ap_sta_remove(hapd
, sta
);
525 sta
->timeout_next
= STA_REMOVE
;
526 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
527 eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH
, 0,
528 ap_handle_timer
, hapd
, sta
);
529 accounting_sta_stop(hapd
, sta
);
530 ieee802_1x_free_station(sta
);
532 mlme_deauthenticate_indication(hapd
, sta
, reason
);
536 int ap_sta_bind_vlan(struct hostapd_data
*hapd
, struct sta_info
*sta
,
539 #ifndef CONFIG_NO_VLAN
541 struct hostapd_vlan
*vlan
= NULL
;
544 * Do not proceed furthur if the vlan id remains same. We do not want
545 * duplicate dynamic vlan entries.
547 if (sta
->vlan_id
== old_vlanid
)
551 * During 1x reauth, if the vlan id changes, then remove the old id and
552 * proceed furthur to add the new one.
555 vlan_remove_dynamic(hapd
, old_vlanid
);
557 iface
= hapd
->conf
->iface
;
558 if (sta
->ssid
->vlan
[0])
559 iface
= sta
->ssid
->vlan
;
561 if (sta
->ssid
->dynamic_vlan
== DYNAMIC_VLAN_DISABLED
)
563 else if (sta
->vlan_id
> 0) {
564 vlan
= hapd
->conf
->vlan
;
566 if (vlan
->vlan_id
== sta
->vlan_id
||
567 vlan
->vlan_id
== VLAN_ID_WILDCARD
) {
568 iface
= vlan
->ifname
;
575 if (sta
->vlan_id
> 0 && vlan
== NULL
) {
576 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
577 HOSTAPD_LEVEL_DEBUG
, "could not find VLAN for "
578 "binding station to (vlan_id=%d)",
581 } else if (sta
->vlan_id
> 0 && vlan
->vlan_id
== VLAN_ID_WILDCARD
) {
582 vlan
= vlan_add_dynamic(hapd
, vlan
, sta
->vlan_id
);
584 hostapd_logger(hapd
, sta
->addr
,
585 HOSTAPD_MODULE_IEEE80211
,
586 HOSTAPD_LEVEL_DEBUG
, "could not add "
587 "dynamic VLAN interface for vlan_id=%d",
592 iface
= vlan
->ifname
;
593 if (vlan_setup_encryption_dyn(hapd
, sta
->ssid
, iface
) != 0) {
594 hostapd_logger(hapd
, sta
->addr
,
595 HOSTAPD_MODULE_IEEE80211
,
596 HOSTAPD_LEVEL_DEBUG
, "could not "
597 "configure encryption for dynamic VLAN "
598 "interface for vlan_id=%d",
602 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
603 HOSTAPD_LEVEL_DEBUG
, "added new dynamic VLAN "
604 "interface '%s'", iface
);
605 } else if (vlan
&& vlan
->vlan_id
== sta
->vlan_id
) {
606 if (sta
->vlan_id
> 0) {
607 vlan
->dynamic_vlan
++;
608 hostapd_logger(hapd
, sta
->addr
,
609 HOSTAPD_MODULE_IEEE80211
,
610 HOSTAPD_LEVEL_DEBUG
, "updated existing "
611 "dynamic VLAN interface '%s'", iface
);
615 * Update encryption configuration for statically generated
616 * VLAN interface. This is only used for static WEP
617 * configuration for the case where hostapd did not yet know
618 * which keys are to be used when the interface was added.
620 if (vlan_setup_encryption_dyn(hapd
, sta
->ssid
, iface
) != 0) {
621 hostapd_logger(hapd
, sta
->addr
,
622 HOSTAPD_MODULE_IEEE80211
,
623 HOSTAPD_LEVEL_DEBUG
, "could not "
624 "configure encryption for VLAN "
625 "interface for vlan_id=%d",
630 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
631 HOSTAPD_LEVEL_DEBUG
, "binding station to interface "
634 if (wpa_auth_sta_set_vlan(sta
->wpa_sm
, sta
->vlan_id
) < 0)
635 wpa_printf(MSG_INFO
, "Failed to update VLAN-ID for WPA");
637 return hapd
->drv
.set_sta_vlan(iface
, hapd
, sta
->addr
, sta
->vlan_id
);
638 #else /* CONFIG_NO_VLAN */
640 #endif /* CONFIG_NO_VLAN */
644 #ifdef CONFIG_IEEE80211W
646 int ap_check_sa_query_timeout(struct hostapd_data
*hapd
, struct sta_info
*sta
)
649 struct os_time now
, passed
;
651 os_time_sub(&now
, &sta
->sa_query_start
, &passed
);
652 tu
= (passed
.sec
* 1000000 + passed
.usec
) / 1024;
653 if (hapd
->conf
->assoc_sa_query_max_timeout
< tu
) {
654 hostapd_logger(hapd
, sta
->addr
,
655 HOSTAPD_MODULE_IEEE80211
,
657 "association SA Query timed out");
658 sta
->sa_query_timed_out
= 1;
659 os_free(sta
->sa_query_trans_id
);
660 sta
->sa_query_trans_id
= NULL
;
661 sta
->sa_query_count
= 0;
662 eloop_cancel_timeout(ap_sa_query_timer
, hapd
, sta
);
670 static void ap_sa_query_timer(void *eloop_ctx
, void *timeout_ctx
)
672 struct hostapd_data
*hapd
= eloop_ctx
;
673 struct sta_info
*sta
= timeout_ctx
;
674 unsigned int timeout
, sec
, usec
;
677 if (sta
->sa_query_count
> 0 &&
678 ap_check_sa_query_timeout(hapd
, sta
))
681 nbuf
= os_realloc(sta
->sa_query_trans_id
,
682 (sta
->sa_query_count
+ 1) * WLAN_SA_QUERY_TR_ID_LEN
);
685 if (sta
->sa_query_count
== 0) {
686 /* Starting a new SA Query procedure */
687 os_get_time(&sta
->sa_query_start
);
689 trans_id
= nbuf
+ sta
->sa_query_count
* WLAN_SA_QUERY_TR_ID_LEN
;
690 sta
->sa_query_trans_id
= nbuf
;
691 sta
->sa_query_count
++;
693 os_get_random(trans_id
, WLAN_SA_QUERY_TR_ID_LEN
);
695 timeout
= hapd
->conf
->assoc_sa_query_retry_timeout
;
696 sec
= ((timeout
/ 1000) * 1024) / 1000;
697 usec
= (timeout
% 1000) * 1024;
698 eloop_register_timeout(sec
, usec
, ap_sa_query_timer
, hapd
, sta
);
700 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
702 "association SA Query attempt %d", sta
->sa_query_count
);
705 ieee802_11_send_sa_query_req(hapd
, sta
->addr
, trans_id
);
706 #endif /* NEED_AP_MLME */
710 void ap_sta_start_sa_query(struct hostapd_data
*hapd
, struct sta_info
*sta
)
712 ap_sa_query_timer(hapd
, sta
);
716 void ap_sta_stop_sa_query(struct hostapd_data
*hapd
, struct sta_info
*sta
)
718 eloop_cancel_timeout(ap_sa_query_timer
, hapd
, sta
);
719 os_free(sta
->sa_query_trans_id
);
720 sta
->sa_query_trans_id
= NULL
;
721 sta
->sa_query_count
= 0;
724 #endif /* CONFIG_IEEE80211W */
727 void ap_sta_disconnect(struct hostapd_data
*hapd
, struct sta_info
*sta
,
728 const u8
*addr
, u16 reason
)
731 if (sta
== NULL
&& addr
)
732 sta
= ap_get_sta(hapd
, addr
);
735 hapd
->drv
.sta_deauth(hapd
, addr
, reason
);
739 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
| WLAN_STA_AUTHORIZED
);
740 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
741 eloop_register_timeout(0, 0, ap_handle_timer
, hapd
, sta
);
742 sta
->timeout_next
= STA_REMOVE
;