Home | History | Annotate | Download | only in ap
      1 /*
      2  * hostapd / Station table
      3  * Copyright (c) 2002-2013, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "utils/includes.h"
     10 
     11 #include "utils/common.h"
     12 #include "utils/eloop.h"
     13 #include "common/ieee802_11_defs.h"
     14 #include "common/wpa_ctrl.h"
     15 #include "common/sae.h"
     16 #include "radius/radius.h"
     17 #include "radius/radius_client.h"
     18 #include "p2p/p2p.h"
     19 #include "hostapd.h"
     20 #include "accounting.h"
     21 #include "ieee802_1x.h"
     22 #include "ieee802_11.h"
     23 #include "ieee802_11_auth.h"
     24 #include "wpa_auth.h"
     25 #include "preauth_auth.h"
     26 #include "ap_config.h"
     27 #include "beacon.h"
     28 #include "ap_mlme.h"
     29 #include "vlan_init.h"
     30 #include "p2p_hostapd.h"
     31 #include "ap_drv_ops.h"
     32 #include "gas_serv.h"
     33 #include "wnm_ap.h"
     34 #include "sta_info.h"
     35 
     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 static void ap_handle_session_warning_timer(void *eloop_ctx, void *timeout_ctx);
     40 static void ap_sta_deauth_cb_timeout(void *eloop_ctx, void *timeout_ctx);
     41 static void ap_sta_disassoc_cb_timeout(void *eloop_ctx, void *timeout_ctx);
     42 #ifdef CONFIG_IEEE80211W
     43 static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx);
     44 #endif /* CONFIG_IEEE80211W */
     45 static int ap_sta_remove(struct hostapd_data *hapd, struct sta_info *sta);
     46 
     47 int ap_for_each_sta(struct hostapd_data *hapd,
     48 		    int (*cb)(struct hostapd_data *hapd, struct sta_info *sta,
     49 			      void *ctx),
     50 		    void *ctx)
     51 {
     52 	struct sta_info *sta;
     53 
     54 	for (sta = hapd->sta_list; sta; sta = sta->next) {
     55 		if (cb(hapd, sta, ctx))
     56 			return 1;
     57 	}
     58 
     59 	return 0;
     60 }
     61 
     62 
     63 struct sta_info * ap_get_sta(struct hostapd_data *hapd, const u8 *sta)
     64 {
     65 	struct sta_info *s;
     66 
     67 	s = hapd->sta_hash[STA_HASH(sta)];
     68 	while (s != NULL && os_memcmp(s->addr, sta, 6) != 0)
     69 		s = s->hnext;
     70 	return s;
     71 }
     72 
     73 
     74 #ifdef CONFIG_P2P
     75 struct sta_info * ap_get_sta_p2p(struct hostapd_data *hapd, const u8 *addr)
     76 {
     77 	struct sta_info *sta;
     78 
     79 	for (sta = hapd->sta_list; sta; sta = sta->next) {
     80 		const u8 *p2p_dev_addr;
     81 
     82 		if (sta->p2p_ie == NULL)
     83 			continue;
     84 
     85 		p2p_dev_addr = p2p_get_go_dev_addr(sta->p2p_ie);
     86 		if (p2p_dev_addr == NULL)
     87 			continue;
     88 
     89 		if (os_memcmp(p2p_dev_addr, addr, ETH_ALEN) == 0)
     90 			return sta;
     91 	}
     92 
     93 	return NULL;
     94 }
     95 #endif /* CONFIG_P2P */
     96 
     97 
     98 static void ap_sta_list_del(struct hostapd_data *hapd, struct sta_info *sta)
     99 {
    100 	struct sta_info *tmp;
    101 
    102 	if (hapd->sta_list == sta) {
    103 		hapd->sta_list = sta->next;
    104 		return;
    105 	}
    106 
    107 	tmp = hapd->sta_list;
    108 	while (tmp != NULL && tmp->next != sta)
    109 		tmp = tmp->next;
    110 	if (tmp == NULL) {
    111 		wpa_printf(MSG_DEBUG, "Could not remove STA " MACSTR " from "
    112 			   "list.", MAC2STR(sta->addr));
    113 	} else
    114 		tmp->next = sta->next;
    115 }
    116 
    117 
    118 void ap_sta_hash_add(struct hostapd_data *hapd, struct sta_info *sta)
    119 {
    120 	sta->hnext = hapd->sta_hash[STA_HASH(sta->addr)];
    121 	hapd->sta_hash[STA_HASH(sta->addr)] = sta;
    122 }
    123 
    124 
    125 static void ap_sta_hash_del(struct hostapd_data *hapd, struct sta_info *sta)
    126 {
    127 	struct sta_info *s;
    128 
    129 	s = hapd->sta_hash[STA_HASH(sta->addr)];
    130 	if (s == NULL) return;
    131 	if (os_memcmp(s->addr, sta->addr, 6) == 0) {
    132 		hapd->sta_hash[STA_HASH(sta->addr)] = s->hnext;
    133 		return;
    134 	}
    135 
    136 	while (s->hnext != NULL &&
    137 	       os_memcmp(s->hnext->addr, sta->addr, ETH_ALEN) != 0)
    138 		s = s->hnext;
    139 	if (s->hnext != NULL)
    140 		s->hnext = s->hnext->hnext;
    141 	else
    142 		wpa_printf(MSG_DEBUG, "AP: could not remove STA " MACSTR
    143 			   " from hash table", MAC2STR(sta->addr));
    144 }
    145 
    146 
    147 void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
    148 {
    149 	int set_beacon = 0;
    150 
    151 	accounting_sta_stop(hapd, sta);
    152 
    153 	/* just in case */
    154 	ap_sta_set_authorized(hapd, sta, 0);
    155 
    156 	if (sta->flags & WLAN_STA_WDS)
    157 		hostapd_set_wds_sta(hapd, NULL, sta->addr, sta->aid, 0);
    158 
    159 	if (!hapd->iface->driver_ap_teardown &&
    160 	    !(sta->flags & WLAN_STA_PREAUTH))
    161 		hostapd_drv_sta_remove(hapd, sta->addr);
    162 
    163 	ap_sta_hash_del(hapd, sta);
    164 	ap_sta_list_del(hapd, sta);
    165 
    166 	if (sta->aid > 0)
    167 		hapd->sta_aid[(sta->aid - 1) / 32] &=
    168 			~BIT((sta->aid - 1) % 32);
    169 
    170 	hapd->num_sta--;
    171 	if (sta->nonerp_set) {
    172 		sta->nonerp_set = 0;
    173 		hapd->iface->num_sta_non_erp--;
    174 		if (hapd->iface->num_sta_non_erp == 0)
    175 			set_beacon++;
    176 	}
    177 
    178 	if (sta->no_short_slot_time_set) {
    179 		sta->no_short_slot_time_set = 0;
    180 		hapd->iface->num_sta_no_short_slot_time--;
    181 		if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
    182 		    && hapd->iface->num_sta_no_short_slot_time == 0)
    183 			set_beacon++;
    184 	}
    185 
    186 	if (sta->no_short_preamble_set) {
    187 		sta->no_short_preamble_set = 0;
    188 		hapd->iface->num_sta_no_short_preamble--;
    189 		if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
    190 		    && hapd->iface->num_sta_no_short_preamble == 0)
    191 			set_beacon++;
    192 	}
    193 
    194 	if (sta->no_ht_gf_set) {
    195 		sta->no_ht_gf_set = 0;
    196 		hapd->iface->num_sta_ht_no_gf--;
    197 	}
    198 
    199 	if (sta->no_ht_set) {
    200 		sta->no_ht_set = 0;
    201 		hapd->iface->num_sta_no_ht--;
    202 	}
    203 
    204 	if (sta->ht_20mhz_set) {
    205 		sta->ht_20mhz_set = 0;
    206 		hapd->iface->num_sta_ht_20mhz--;
    207 	}
    208 
    209 #ifdef CONFIG_IEEE80211N
    210 	ht40_intolerant_remove(hapd->iface, sta);
    211 #endif /* CONFIG_IEEE80211N */
    212 
    213 #ifdef CONFIG_P2P
    214 	if (sta->no_p2p_set) {
    215 		sta->no_p2p_set = 0;
    216 		hapd->num_sta_no_p2p--;
    217 		if (hapd->num_sta_no_p2p == 0)
    218 			hostapd_p2p_non_p2p_sta_disconnected(hapd);
    219 	}
    220 #endif /* CONFIG_P2P */
    221 
    222 #if defined(NEED_AP_MLME) && defined(CONFIG_IEEE80211N)
    223 	if (hostapd_ht_operation_update(hapd->iface) > 0)
    224 		set_beacon++;
    225 #endif /* NEED_AP_MLME && CONFIG_IEEE80211N */
    226 
    227 	if (set_beacon)
    228 		ieee802_11_set_beacons(hapd->iface);
    229 
    230 	wpa_printf(MSG_DEBUG, "%s: cancel ap_handle_timer for " MACSTR,
    231 		   __func__, MAC2STR(sta->addr));
    232 	eloop_cancel_timeout(ap_handle_timer, hapd, sta);
    233 	eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
    234 	eloop_cancel_timeout(ap_handle_session_warning_timer, hapd, sta);
    235 	eloop_cancel_timeout(ap_sta_deauth_cb_timeout, hapd, sta);
    236 	eloop_cancel_timeout(ap_sta_disassoc_cb_timeout, hapd, sta);
    237 
    238 	ieee802_1x_free_station(sta);
    239 	wpa_auth_sta_deinit(sta->wpa_sm);
    240 	rsn_preauth_free_station(hapd, sta);
    241 #ifndef CONFIG_NO_RADIUS
    242 	if (hapd->radius)
    243 		radius_client_flush_auth(hapd->radius, sta->addr);
    244 #endif /* CONFIG_NO_RADIUS */
    245 
    246 	os_free(sta->challenge);
    247 
    248 #ifdef CONFIG_IEEE80211W
    249 	os_free(sta->sa_query_trans_id);
    250 	eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
    251 #endif /* CONFIG_IEEE80211W */
    252 
    253 #ifdef CONFIG_P2P
    254 	p2p_group_notif_disassoc(hapd->p2p_group, sta->addr);
    255 #endif /* CONFIG_P2P */
    256 
    257 #ifdef CONFIG_INTERWORKING
    258 	if (sta->gas_dialog) {
    259 		int i;
    260 		for (i = 0; i < GAS_DIALOG_MAX; i++)
    261 			gas_serv_dialog_clear(&sta->gas_dialog[i]);
    262 		os_free(sta->gas_dialog);
    263 	}
    264 #endif /* CONFIG_INTERWORKING */
    265 
    266 	wpabuf_free(sta->wps_ie);
    267 	wpabuf_free(sta->p2p_ie);
    268 	wpabuf_free(sta->hs20_ie);
    269 
    270 	os_free(sta->ht_capabilities);
    271 	os_free(sta->vht_capabilities);
    272 	hostapd_free_psk_list(sta->psk);
    273 	os_free(sta->identity);
    274 	os_free(sta->radius_cui);
    275 	os_free(sta->remediation_url);
    276 	wpabuf_free(sta->hs20_deauth_req);
    277 	os_free(sta->hs20_session_info_url);
    278 
    279 #ifdef CONFIG_SAE
    280 	sae_clear_data(sta->sae);
    281 	os_free(sta->sae);
    282 #endif /* CONFIG_SAE */
    283 
    284 	os_free(sta);
    285 }
    286 
    287 
    288 void hostapd_free_stas(struct hostapd_data *hapd)
    289 {
    290 	struct sta_info *sta, *prev;
    291 
    292 	sta = hapd->sta_list;
    293 
    294 	while (sta) {
    295 		prev = sta;
    296 		if (sta->flags & WLAN_STA_AUTH) {
    297 			mlme_deauthenticate_indication(
    298 				hapd, sta, WLAN_REASON_UNSPECIFIED);
    299 		}
    300 		sta = sta->next;
    301 		wpa_printf(MSG_DEBUG, "Removing station " MACSTR,
    302 			   MAC2STR(prev->addr));
    303 		ap_free_sta(hapd, prev);
    304 	}
    305 }
    306 
    307 
    308 /**
    309  * ap_handle_timer - Per STA timer handler
    310  * @eloop_ctx: struct hostapd_data *
    311  * @timeout_ctx: struct sta_info *
    312  *
    313  * This function is called to check station activity and to remove inactive
    314  * stations.
    315  */
    316 void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
    317 {
    318 	struct hostapd_data *hapd = eloop_ctx;
    319 	struct sta_info *sta = timeout_ctx;
    320 	unsigned long next_time = 0;
    321 	int reason;
    322 
    323 	wpa_printf(MSG_DEBUG, "%s: " MACSTR " flags=0x%x timeout_next=%d",
    324 		   __func__, MAC2STR(sta->addr), sta->flags,
    325 		   sta->timeout_next);
    326 	if (sta->timeout_next == STA_REMOVE) {
    327 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    328 			       HOSTAPD_LEVEL_INFO, "deauthenticated due to "
    329 			       "local deauth request");
    330 		ap_free_sta(hapd, sta);
    331 		return;
    332 	}
    333 
    334 	if ((sta->flags & WLAN_STA_ASSOC) &&
    335 	    (sta->timeout_next == STA_NULLFUNC ||
    336 	     sta->timeout_next == STA_DISASSOC)) {
    337 		int inactive_sec;
    338 		/*
    339 		 * Add random value to timeout so that we don't end up bouncing
    340 		 * all stations at the same time if we have lots of associated
    341 		 * stations that are idle (but keep re-associating).
    342 		 */
    343 		int fuzz = os_random() % 20;
    344 		inactive_sec = hostapd_drv_get_inact_sec(hapd, sta->addr);
    345 		if (inactive_sec == -1) {
    346 			wpa_msg(hapd->msg_ctx, MSG_DEBUG,
    347 				"Check inactivity: Could not "
    348 				"get station info from kernel driver for "
    349 				MACSTR, MAC2STR(sta->addr));
    350 			/*
    351 			 * The driver may not support this functionality.
    352 			 * Anyway, try again after the next inactivity timeout,
    353 			 * but do not disconnect the station now.
    354 			 */
    355 			next_time = hapd->conf->ap_max_inactivity + fuzz;
    356 		} else if (inactive_sec < hapd->conf->ap_max_inactivity &&
    357 			   sta->flags & WLAN_STA_ASSOC) {
    358 			/* station activity detected; reset timeout state */
    359 			wpa_msg(hapd->msg_ctx, MSG_DEBUG,
    360 				"Station " MACSTR " has been active %is ago",
    361 				MAC2STR(sta->addr), inactive_sec);
    362 			sta->timeout_next = STA_NULLFUNC;
    363 			next_time = hapd->conf->ap_max_inactivity + fuzz -
    364 				inactive_sec;
    365 		} else {
    366 			wpa_msg(hapd->msg_ctx, MSG_DEBUG,
    367 				"Station " MACSTR " has been "
    368 				"inactive too long: %d sec, max allowed: %d",
    369 				MAC2STR(sta->addr), inactive_sec,
    370 				hapd->conf->ap_max_inactivity);
    371 
    372 			if (hapd->conf->skip_inactivity_poll)
    373 				sta->timeout_next = STA_DISASSOC;
    374 		}
    375 	}
    376 
    377 	if ((sta->flags & WLAN_STA_ASSOC) &&
    378 	    sta->timeout_next == STA_DISASSOC &&
    379 	    !(sta->flags & WLAN_STA_PENDING_POLL) &&
    380 	    !hapd->conf->skip_inactivity_poll) {
    381 		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR
    382 			" has ACKed data poll", MAC2STR(sta->addr));
    383 		/* data nullfunc frame poll did not produce TX errors; assume
    384 		 * station ACKed it */
    385 		sta->timeout_next = STA_NULLFUNC;
    386 		next_time = hapd->conf->ap_max_inactivity;
    387 	}
    388 
    389 	if (next_time) {
    390 		wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout "
    391 			   "for " MACSTR " (%lu seconds)",
    392 			   __func__, MAC2STR(sta->addr), next_time);
    393 		eloop_register_timeout(next_time, 0, ap_handle_timer, hapd,
    394 				       sta);
    395 		return;
    396 	}
    397 
    398 	if (sta->timeout_next == STA_NULLFUNC &&
    399 	    (sta->flags & WLAN_STA_ASSOC)) {
    400 		wpa_printf(MSG_DEBUG, "  Polling STA");
    401 		sta->flags |= WLAN_STA_PENDING_POLL;
    402 		hostapd_drv_poll_client(hapd, hapd->own_addr, sta->addr,
    403 					sta->flags & WLAN_STA_WMM);
    404 	} else if (sta->timeout_next != STA_REMOVE) {
    405 		int deauth = sta->timeout_next == STA_DEAUTH;
    406 
    407 		wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
    408 			"Timeout, sending %s info to STA " MACSTR,
    409 			deauth ? "deauthentication" : "disassociation",
    410 			MAC2STR(sta->addr));
    411 
    412 		if (deauth) {
    413 			hostapd_drv_sta_deauth(
    414 				hapd, sta->addr,
    415 				WLAN_REASON_PREV_AUTH_NOT_VALID);
    416 		} else {
    417 			reason = (sta->timeout_next == STA_DISASSOC) ?
    418 				WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY :
    419 				WLAN_REASON_PREV_AUTH_NOT_VALID;
    420 
    421 			hostapd_drv_sta_disassoc(hapd, sta->addr, reason);
    422 		}
    423 	}
    424 
    425 	switch (sta->timeout_next) {
    426 	case STA_NULLFUNC:
    427 		sta->timeout_next = STA_DISASSOC;
    428 		wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout "
    429 			   "for " MACSTR " (%d seconds - AP_DISASSOC_DELAY)",
    430 			   __func__, MAC2STR(sta->addr), AP_DISASSOC_DELAY);
    431 		eloop_register_timeout(AP_DISASSOC_DELAY, 0, ap_handle_timer,
    432 				       hapd, sta);
    433 		break;
    434 	case STA_DISASSOC:
    435 	case STA_DISASSOC_FROM_CLI:
    436 		ap_sta_set_authorized(hapd, sta, 0);
    437 		sta->flags &= ~WLAN_STA_ASSOC;
    438 		ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
    439 		if (!sta->acct_terminate_cause)
    440 			sta->acct_terminate_cause =
    441 				RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT;
    442 		accounting_sta_stop(hapd, sta);
    443 		ieee802_1x_free_station(sta);
    444 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    445 			       HOSTAPD_LEVEL_INFO, "disassociated due to "
    446 			       "inactivity");
    447 		reason = (sta->timeout_next == STA_DISASSOC) ?
    448 			WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY :
    449 			WLAN_REASON_PREV_AUTH_NOT_VALID;
    450 		sta->timeout_next = STA_DEAUTH;
    451 		wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout "
    452 			   "for " MACSTR " (%d seconds - AP_DEAUTH_DELAY)",
    453 			   __func__, MAC2STR(sta->addr), AP_DEAUTH_DELAY);
    454 		eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
    455 				       hapd, sta);
    456 		mlme_disassociate_indication(hapd, sta, reason);
    457 		break;
    458 	case STA_DEAUTH:
    459 	case STA_REMOVE:
    460 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    461 			       HOSTAPD_LEVEL_INFO, "deauthenticated due to "
    462 			       "inactivity (timer DEAUTH/REMOVE)");
    463 		if (!sta->acct_terminate_cause)
    464 			sta->acct_terminate_cause =
    465 				RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT;
    466 		mlme_deauthenticate_indication(
    467 			hapd, sta,
    468 			WLAN_REASON_PREV_AUTH_NOT_VALID);
    469 		ap_free_sta(hapd, sta);
    470 		break;
    471 	}
    472 }
    473 
    474 
    475 static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx)
    476 {
    477 	struct hostapd_data *hapd = eloop_ctx;
    478 	struct sta_info *sta = timeout_ctx;
    479 
    480 	if (!(sta->flags & WLAN_STA_AUTH)) {
    481 		if (sta->flags & WLAN_STA_GAS) {
    482 			wpa_printf(MSG_DEBUG, "GAS: Remove temporary STA "
    483 				   "entry " MACSTR, MAC2STR(sta->addr));
    484 			ap_free_sta(hapd, sta);
    485 		}
    486 		return;
    487 	}
    488 
    489 	hostapd_drv_sta_deauth(hapd, sta->addr,
    490 			       WLAN_REASON_PREV_AUTH_NOT_VALID);
    491 	mlme_deauthenticate_indication(hapd, sta,
    492 				       WLAN_REASON_PREV_AUTH_NOT_VALID);
    493 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    494 		       HOSTAPD_LEVEL_INFO, "deauthenticated due to "
    495 		       "session timeout");
    496 	sta->acct_terminate_cause =
    497 		RADIUS_ACCT_TERMINATE_CAUSE_SESSION_TIMEOUT;
    498 	ap_free_sta(hapd, sta);
    499 }
    500 
    501 
    502 void ap_sta_replenish_timeout(struct hostapd_data *hapd, struct sta_info *sta,
    503 			      u32 session_timeout)
    504 {
    505 	if (eloop_replenish_timeout(session_timeout, 0,
    506 				    ap_handle_session_timer, hapd, sta) == 1) {
    507 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    508 			       HOSTAPD_LEVEL_DEBUG, "setting session timeout "
    509 			       "to %d seconds", session_timeout);
    510 	}
    511 }
    512 
    513 
    514 void ap_sta_session_timeout(struct hostapd_data *hapd, struct sta_info *sta,
    515 			    u32 session_timeout)
    516 {
    517 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    518 		       HOSTAPD_LEVEL_DEBUG, "setting session timeout to %d "
    519 		       "seconds", session_timeout);
    520 	eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
    521 	eloop_register_timeout(session_timeout, 0, ap_handle_session_timer,
    522 			       hapd, sta);
    523 }
    524 
    525 
    526 void ap_sta_no_session_timeout(struct hostapd_data *hapd, struct sta_info *sta)
    527 {
    528 	eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
    529 }
    530 
    531 
    532 static void ap_handle_session_warning_timer(void *eloop_ctx, void *timeout_ctx)
    533 {
    534 #ifdef CONFIG_WNM
    535 	struct hostapd_data *hapd = eloop_ctx;
    536 	struct sta_info *sta = timeout_ctx;
    537 
    538 	wpa_printf(MSG_DEBUG, "WNM: Session warning time reached for " MACSTR,
    539 		   MAC2STR(sta->addr));
    540 	if (sta->hs20_session_info_url == NULL)
    541 		return;
    542 
    543 	wnm_send_ess_disassoc_imminent(hapd, sta, sta->hs20_session_info_url,
    544 				       sta->hs20_disassoc_timer);
    545 #endif /* CONFIG_WNM */
    546 }
    547 
    548 
    549 void ap_sta_session_warning_timeout(struct hostapd_data *hapd,
    550 				    struct sta_info *sta, int warning_time)
    551 {
    552 	eloop_cancel_timeout(ap_handle_session_warning_timer, hapd, sta);
    553 	eloop_register_timeout(warning_time, 0, ap_handle_session_warning_timer,
    554 			       hapd, sta);
    555 }
    556 
    557 
    558 struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
    559 {
    560 	struct sta_info *sta;
    561 
    562 	sta = ap_get_sta(hapd, addr);
    563 	if (sta)
    564 		return sta;
    565 
    566 	wpa_printf(MSG_DEBUG, "  New STA");
    567 	if (hapd->num_sta >= hapd->conf->max_num_sta) {
    568 		/* FIX: might try to remove some old STAs first? */
    569 		wpa_printf(MSG_DEBUG, "no more room for new STAs (%d/%d)",
    570 			   hapd->num_sta, hapd->conf->max_num_sta);
    571 		return NULL;
    572 	}
    573 
    574 	sta = os_zalloc(sizeof(struct sta_info));
    575 	if (sta == NULL) {
    576 		wpa_printf(MSG_ERROR, "malloc failed");
    577 		return NULL;
    578 	}
    579 	sta->acct_interim_interval = hapd->conf->acct_interim_interval;
    580 	accounting_sta_get_id(hapd, sta);
    581 
    582 	if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) {
    583 		wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout "
    584 			   "for " MACSTR " (%d seconds - ap_max_inactivity)",
    585 			   __func__, MAC2STR(addr),
    586 			   hapd->conf->ap_max_inactivity);
    587 		eloop_register_timeout(hapd->conf->ap_max_inactivity, 0,
    588 				       ap_handle_timer, hapd, sta);
    589 	}
    590 
    591 	/* initialize STA info data */
    592 	os_memcpy(sta->addr, addr, ETH_ALEN);
    593 	sta->next = hapd->sta_list;
    594 	hapd->sta_list = sta;
    595 	hapd->num_sta++;
    596 	ap_sta_hash_add(hapd, sta);
    597 	sta->ssid = &hapd->conf->ssid;
    598 	ap_sta_remove_in_other_bss(hapd, sta);
    599 
    600 	return sta;
    601 }
    602 
    603 
    604 static int ap_sta_remove(struct hostapd_data *hapd, struct sta_info *sta)
    605 {
    606 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
    607 
    608 	wpa_printf(MSG_DEBUG, "Removing STA " MACSTR " from kernel driver",
    609 		   MAC2STR(sta->addr));
    610 	if (hostapd_drv_sta_remove(hapd, sta->addr) &&
    611 	    sta->flags & WLAN_STA_ASSOC) {
    612 		wpa_printf(MSG_DEBUG, "Could not remove station " MACSTR
    613 			   " from kernel driver.", MAC2STR(sta->addr));
    614 		return -1;
    615 	}
    616 	return 0;
    617 }
    618 
    619 
    620 static void ap_sta_remove_in_other_bss(struct hostapd_data *hapd,
    621 				       struct sta_info *sta)
    622 {
    623 	struct hostapd_iface *iface = hapd->iface;
    624 	size_t i;
    625 
    626 	for (i = 0; i < iface->num_bss; i++) {
    627 		struct hostapd_data *bss = iface->bss[i];
    628 		struct sta_info *sta2;
    629 		/* bss should always be set during operation, but it may be
    630 		 * NULL during reconfiguration. Assume the STA is not
    631 		 * associated to another BSS in that case to avoid NULL pointer
    632 		 * dereferences. */
    633 		if (bss == hapd || bss == NULL)
    634 			continue;
    635 		sta2 = ap_get_sta(bss, sta->addr);
    636 		if (!sta2)
    637 			continue;
    638 
    639 		ap_sta_disconnect(bss, sta2, sta2->addr,
    640 				  WLAN_REASON_PREV_AUTH_NOT_VALID);
    641 	}
    642 }
    643 
    644 
    645 static void ap_sta_disassoc_cb_timeout(void *eloop_ctx, void *timeout_ctx)
    646 {
    647 	struct hostapd_data *hapd = eloop_ctx;
    648 	struct sta_info *sta = timeout_ctx;
    649 
    650 	ap_sta_remove(hapd, sta);
    651 	mlme_disassociate_indication(hapd, sta, sta->disassoc_reason);
    652 }
    653 
    654 
    655 void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta,
    656 			 u16 reason)
    657 {
    658 	wpa_printf(MSG_DEBUG, "%s: disassociate STA " MACSTR,
    659 		   hapd->conf->iface, MAC2STR(sta->addr));
    660 	sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK);
    661 	ap_sta_set_authorized(hapd, sta, 0);
    662 	sta->timeout_next = STA_DEAUTH;
    663 	wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout "
    664 		   "for " MACSTR " (%d seconds - "
    665 		   "AP_MAX_INACTIVITY_AFTER_DISASSOC)",
    666 		   __func__, MAC2STR(sta->addr),
    667 		   AP_MAX_INACTIVITY_AFTER_DISASSOC);
    668 	eloop_cancel_timeout(ap_handle_timer, hapd, sta);
    669 	eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DISASSOC, 0,
    670 			       ap_handle_timer, hapd, sta);
    671 	accounting_sta_stop(hapd, sta);
    672 	ieee802_1x_free_station(sta);
    673 
    674 	sta->disassoc_reason = reason;
    675 	sta->flags |= WLAN_STA_PENDING_DISASSOC_CB;
    676 	eloop_cancel_timeout(ap_sta_disassoc_cb_timeout, hapd, sta);
    677 	eloop_register_timeout(hapd->iface->drv_flags &
    678 			       WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS ? 2 : 0, 0,
    679 			       ap_sta_disassoc_cb_timeout, hapd, sta);
    680 }
    681 
    682 
    683 static void ap_sta_deauth_cb_timeout(void *eloop_ctx, void *timeout_ctx)
    684 {
    685 	struct hostapd_data *hapd = eloop_ctx;
    686 	struct sta_info *sta = timeout_ctx;
    687 
    688 	ap_sta_remove(hapd, sta);
    689 	mlme_deauthenticate_indication(hapd, sta, sta->deauth_reason);
    690 }
    691 
    692 
    693 void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
    694 			   u16 reason)
    695 {
    696 	wpa_printf(MSG_DEBUG, "%s: deauthenticate STA " MACSTR,
    697 		   hapd->conf->iface, MAC2STR(sta->addr));
    698 	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
    699 	ap_sta_set_authorized(hapd, sta, 0);
    700 	sta->timeout_next = STA_REMOVE;
    701 	wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout "
    702 		   "for " MACSTR " (%d seconds - "
    703 		   "AP_MAX_INACTIVITY_AFTER_DEAUTH)",
    704 		   __func__, MAC2STR(sta->addr),
    705 		   AP_MAX_INACTIVITY_AFTER_DEAUTH);
    706 	eloop_cancel_timeout(ap_handle_timer, hapd, sta);
    707 	eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0,
    708 			       ap_handle_timer, hapd, sta);
    709 	accounting_sta_stop(hapd, sta);
    710 	ieee802_1x_free_station(sta);
    711 
    712 	sta->deauth_reason = reason;
    713 	sta->flags |= WLAN_STA_PENDING_DEAUTH_CB;
    714 	eloop_cancel_timeout(ap_sta_deauth_cb_timeout, hapd, sta);
    715 	eloop_register_timeout(hapd->iface->drv_flags &
    716 			       WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS ? 2 : 0, 0,
    717 			       ap_sta_deauth_cb_timeout, hapd, sta);
    718 }
    719 
    720 
    721 #ifdef CONFIG_WPS
    722 int ap_sta_wps_cancel(struct hostapd_data *hapd,
    723 		      struct sta_info *sta, void *ctx)
    724 {
    725 	if (sta && (sta->flags & WLAN_STA_WPS)) {
    726 		ap_sta_deauthenticate(hapd, sta,
    727 				      WLAN_REASON_PREV_AUTH_NOT_VALID);
    728 		wpa_printf(MSG_DEBUG, "WPS: %s: Deauth sta=" MACSTR,
    729 			   __func__, MAC2STR(sta->addr));
    730 		return 1;
    731 	}
    732 
    733 	return 0;
    734 }
    735 #endif /* CONFIG_WPS */
    736 
    737 
    738 int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta,
    739 		     int old_vlanid)
    740 {
    741 #ifndef CONFIG_NO_VLAN
    742 	const char *iface;
    743 	struct hostapd_vlan *vlan = NULL;
    744 	int ret;
    745 
    746 	/*
    747 	 * Do not proceed furthur if the vlan id remains same. We do not want
    748 	 * duplicate dynamic vlan entries.
    749 	 */
    750 	if (sta->vlan_id == old_vlanid)
    751 		return 0;
    752 
    753 	/*
    754 	 * During 1x reauth, if the vlan id changes, then remove the old id and
    755 	 * proceed furthur to add the new one.
    756 	 */
    757 	if (old_vlanid > 0)
    758 		vlan_remove_dynamic(hapd, old_vlanid);
    759 
    760 	iface = hapd->conf->iface;
    761 	if (sta->ssid->vlan[0])
    762 		iface = sta->ssid->vlan;
    763 
    764 	if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED)
    765 		sta->vlan_id = 0;
    766 	else if (sta->vlan_id > 0) {
    767 		struct hostapd_vlan *wildcard_vlan = NULL;
    768 		vlan = hapd->conf->vlan;
    769 		while (vlan) {
    770 			if (vlan->vlan_id == sta->vlan_id)
    771 				break;
    772 			if (vlan->vlan_id == VLAN_ID_WILDCARD)
    773 				wildcard_vlan = vlan;
    774 			vlan = vlan->next;
    775 		}
    776 		if (!vlan)
    777 			vlan = wildcard_vlan;
    778 		if (vlan)
    779 			iface = vlan->ifname;
    780 	}
    781 
    782 	if (sta->vlan_id > 0 && vlan == NULL) {
    783 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    784 			       HOSTAPD_LEVEL_DEBUG, "could not find VLAN for "
    785 			       "binding station to (vlan_id=%d)",
    786 			       sta->vlan_id);
    787 		return -1;
    788 	} else if (sta->vlan_id > 0 && vlan->vlan_id == VLAN_ID_WILDCARD) {
    789 		vlan = vlan_add_dynamic(hapd, vlan, sta->vlan_id);
    790 		if (vlan == NULL) {
    791 			hostapd_logger(hapd, sta->addr,
    792 				       HOSTAPD_MODULE_IEEE80211,
    793 				       HOSTAPD_LEVEL_DEBUG, "could not add "
    794 				       "dynamic VLAN interface for vlan_id=%d",
    795 				       sta->vlan_id);
    796 			return -1;
    797 		}
    798 
    799 		iface = vlan->ifname;
    800 		if (vlan_setup_encryption_dyn(hapd, sta->ssid, iface) != 0) {
    801 			hostapd_logger(hapd, sta->addr,
    802 				       HOSTAPD_MODULE_IEEE80211,
    803 				       HOSTAPD_LEVEL_DEBUG, "could not "
    804 				       "configure encryption for dynamic VLAN "
    805 				       "interface for vlan_id=%d",
    806 				       sta->vlan_id);
    807 		}
    808 
    809 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    810 			       HOSTAPD_LEVEL_DEBUG, "added new dynamic VLAN "
    811 			       "interface '%s'", iface);
    812 	} else if (vlan && vlan->vlan_id == sta->vlan_id) {
    813 		if (sta->vlan_id > 0) {
    814 			vlan->dynamic_vlan++;
    815 			hostapd_logger(hapd, sta->addr,
    816 				       HOSTAPD_MODULE_IEEE80211,
    817 				       HOSTAPD_LEVEL_DEBUG, "updated existing "
    818 				       "dynamic VLAN interface '%s'", iface);
    819 		}
    820 
    821 		/*
    822 		 * Update encryption configuration for statically generated
    823 		 * VLAN interface. This is only used for static WEP
    824 		 * configuration for the case where hostapd did not yet know
    825 		 * which keys are to be used when the interface was added.
    826 		 */
    827 		if (vlan_setup_encryption_dyn(hapd, sta->ssid, iface) != 0) {
    828 			hostapd_logger(hapd, sta->addr,
    829 				       HOSTAPD_MODULE_IEEE80211,
    830 				       HOSTAPD_LEVEL_DEBUG, "could not "
    831 				       "configure encryption for VLAN "
    832 				       "interface for vlan_id=%d",
    833 				       sta->vlan_id);
    834 		}
    835 	}
    836 
    837 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    838 		       HOSTAPD_LEVEL_DEBUG, "binding station to interface "
    839 		       "'%s'", iface);
    840 
    841 	if (wpa_auth_sta_set_vlan(sta->wpa_sm, sta->vlan_id) < 0)
    842 		wpa_printf(MSG_INFO, "Failed to update VLAN-ID for WPA");
    843 
    844 	ret = hostapd_drv_set_sta_vlan(iface, hapd, sta->addr, sta->vlan_id);
    845 	if (ret < 0) {
    846 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    847 			       HOSTAPD_LEVEL_DEBUG, "could not bind the STA "
    848 			       "entry to vlan_id=%d", sta->vlan_id);
    849 	}
    850 	return ret;
    851 #else /* CONFIG_NO_VLAN */
    852 	return 0;
    853 #endif /* CONFIG_NO_VLAN */
    854 }
    855 
    856 
    857 #ifdef CONFIG_IEEE80211W
    858 
    859 int ap_check_sa_query_timeout(struct hostapd_data *hapd, struct sta_info *sta)
    860 {
    861 	u32 tu;
    862 	struct os_reltime now, passed;
    863 	os_get_reltime(&now);
    864 	os_reltime_sub(&now, &sta->sa_query_start, &passed);
    865 	tu = (passed.sec * 1000000 + passed.usec) / 1024;
    866 	if (hapd->conf->assoc_sa_query_max_timeout < tu) {
    867 		hostapd_logger(hapd, sta->addr,
    868 			       HOSTAPD_MODULE_IEEE80211,
    869 			       HOSTAPD_LEVEL_DEBUG,
    870 			       "association SA Query timed out");
    871 		sta->sa_query_timed_out = 1;
    872 		os_free(sta->sa_query_trans_id);
    873 		sta->sa_query_trans_id = NULL;
    874 		sta->sa_query_count = 0;
    875 		eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
    876 		return 1;
    877 	}
    878 
    879 	return 0;
    880 }
    881 
    882 
    883 static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx)
    884 {
    885 	struct hostapd_data *hapd = eloop_ctx;
    886 	struct sta_info *sta = timeout_ctx;
    887 	unsigned int timeout, sec, usec;
    888 	u8 *trans_id, *nbuf;
    889 
    890 	if (sta->sa_query_count > 0 &&
    891 	    ap_check_sa_query_timeout(hapd, sta))
    892 		return;
    893 
    894 	nbuf = os_realloc_array(sta->sa_query_trans_id,
    895 				sta->sa_query_count + 1,
    896 				WLAN_SA_QUERY_TR_ID_LEN);
    897 	if (nbuf == NULL)
    898 		return;
    899 	if (sta->sa_query_count == 0) {
    900 		/* Starting a new SA Query procedure */
    901 		os_get_reltime(&sta->sa_query_start);
    902 	}
    903 	trans_id = nbuf + sta->sa_query_count * WLAN_SA_QUERY_TR_ID_LEN;
    904 	sta->sa_query_trans_id = nbuf;
    905 	sta->sa_query_count++;
    906 
    907 	os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN);
    908 
    909 	timeout = hapd->conf->assoc_sa_query_retry_timeout;
    910 	sec = ((timeout / 1000) * 1024) / 1000;
    911 	usec = (timeout % 1000) * 1024;
    912 	eloop_register_timeout(sec, usec, ap_sa_query_timer, hapd, sta);
    913 
    914 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    915 		       HOSTAPD_LEVEL_DEBUG,
    916 		       "association SA Query attempt %d", sta->sa_query_count);
    917 
    918 	ieee802_11_send_sa_query_req(hapd, sta->addr, trans_id);
    919 }
    920 
    921 
    922 void ap_sta_start_sa_query(struct hostapd_data *hapd, struct sta_info *sta)
    923 {
    924 	ap_sa_query_timer(hapd, sta);
    925 }
    926 
    927 
    928 void ap_sta_stop_sa_query(struct hostapd_data *hapd, struct sta_info *sta)
    929 {
    930 	eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
    931 	os_free(sta->sa_query_trans_id);
    932 	sta->sa_query_trans_id = NULL;
    933 	sta->sa_query_count = 0;
    934 }
    935 
    936 #endif /* CONFIG_IEEE80211W */
    937 
    938 
    939 void ap_sta_set_authorized(struct hostapd_data *hapd, struct sta_info *sta,
    940 			   int authorized)
    941 {
    942 	const u8 *dev_addr = NULL;
    943 	char buf[100];
    944 #ifdef CONFIG_P2P
    945 	u8 addr[ETH_ALEN];
    946 	u8 ip_addr_buf[4];
    947 #endif /* CONFIG_P2P */
    948 
    949 	if (!!authorized == !!(sta->flags & WLAN_STA_AUTHORIZED))
    950 		return;
    951 
    952 #ifdef CONFIG_P2P
    953 	if (hapd->p2p_group == NULL) {
    954 		if (sta->p2p_ie != NULL &&
    955 		    p2p_parse_dev_addr_in_p2p_ie(sta->p2p_ie, addr) == 0)
    956 			dev_addr = addr;
    957 	} else
    958 		dev_addr = p2p_group_get_dev_addr(hapd->p2p_group, sta->addr);
    959 
    960 	if (dev_addr)
    961 		os_snprintf(buf, sizeof(buf), MACSTR " p2p_dev_addr=" MACSTR,
    962 			    MAC2STR(sta->addr), MAC2STR(dev_addr));
    963 	else
    964 #endif /* CONFIG_P2P */
    965 		os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(sta->addr));
    966 
    967 	if (authorized) {
    968 		char ip_addr[100];
    969 		ip_addr[0] = '\0';
    970 #ifdef CONFIG_P2P
    971 		if (wpa_auth_get_ip_addr(sta->wpa_sm, ip_addr_buf) == 0) {
    972 			os_snprintf(ip_addr, sizeof(ip_addr),
    973 				    " ip_addr=%u.%u.%u.%u",
    974 				    ip_addr_buf[0], ip_addr_buf[1],
    975 				    ip_addr_buf[2], ip_addr_buf[3]);
    976 		}
    977 #endif /* CONFIG_P2P */
    978 
    979 		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s",
    980 			buf, ip_addr);
    981 
    982 		if (hapd->msg_ctx_parent &&
    983 		    hapd->msg_ctx_parent != hapd->msg_ctx)
    984 			wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO,
    985 					  AP_STA_CONNECTED "%s%s",
    986 					  buf, ip_addr);
    987 
    988 		sta->flags |= WLAN_STA_AUTHORIZED;
    989 	} else {
    990 		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf);
    991 
    992 		if (hapd->msg_ctx_parent &&
    993 		    hapd->msg_ctx_parent != hapd->msg_ctx)
    994 			wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO,
    995 					  AP_STA_DISCONNECTED "%s", buf);
    996 
    997 		sta->flags &= ~WLAN_STA_AUTHORIZED;
    998 	}
    999 
   1000 	if (hapd->sta_authorized_cb)
   1001 		hapd->sta_authorized_cb(hapd->sta_authorized_cb_ctx,
   1002 					sta->addr, authorized, dev_addr);
   1003 }
   1004 
   1005 
   1006 void ap_sta_disconnect(struct hostapd_data *hapd, struct sta_info *sta,
   1007 		       const u8 *addr, u16 reason)
   1008 {
   1009 
   1010 	if (sta == NULL && addr)
   1011 		sta = ap_get_sta(hapd, addr);
   1012 
   1013 	if (addr)
   1014 		hostapd_drv_sta_deauth(hapd, addr, reason);
   1015 
   1016 	if (sta == NULL)
   1017 		return;
   1018 	ap_sta_set_authorized(hapd, sta, 0);
   1019 	wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
   1020 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
   1021 	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
   1022 	wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout "
   1023 		   "for " MACSTR " (%d seconds - "
   1024 		   "AP_MAX_INACTIVITY_AFTER_DEAUTH)",
   1025 		   __func__, MAC2STR(sta->addr),
   1026 		   AP_MAX_INACTIVITY_AFTER_DEAUTH);
   1027 	eloop_cancel_timeout(ap_handle_timer, hapd, sta);
   1028 	eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0,
   1029 			       ap_handle_timer, hapd, sta);
   1030 	sta->timeout_next = STA_REMOVE;
   1031 
   1032 	sta->deauth_reason = reason;
   1033 	sta->flags |= WLAN_STA_PENDING_DEAUTH_CB;
   1034 	eloop_cancel_timeout(ap_sta_deauth_cb_timeout, hapd, sta);
   1035 	eloop_register_timeout(hapd->iface->drv_flags &
   1036 			       WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS ? 2 : 0, 0,
   1037 			       ap_sta_deauth_cb_timeout, hapd, sta);
   1038 }
   1039 
   1040 
   1041 void ap_sta_deauth_cb(struct hostapd_data *hapd, struct sta_info *sta)
   1042 {
   1043 	if (!(sta->flags & WLAN_STA_PENDING_DEAUTH_CB)) {
   1044 		wpa_printf(MSG_DEBUG, "Ignore deauth cb for test frame");
   1045 		return;
   1046 	}
   1047 	sta->flags &= ~WLAN_STA_PENDING_DEAUTH_CB;
   1048 	eloop_cancel_timeout(ap_sta_deauth_cb_timeout, hapd, sta);
   1049 	ap_sta_deauth_cb_timeout(hapd, sta);
   1050 }
   1051 
   1052 
   1053 void ap_sta_disassoc_cb(struct hostapd_data *hapd, struct sta_info *sta)
   1054 {
   1055 	if (!(sta->flags & WLAN_STA_PENDING_DISASSOC_CB)) {
   1056 		wpa_printf(MSG_DEBUG, "Ignore disassoc cb for test frame");
   1057 		return;
   1058 	}
   1059 	sta->flags &= ~WLAN_STA_PENDING_DISASSOC_CB;
   1060 	eloop_cancel_timeout(ap_sta_disassoc_cb_timeout, hapd, sta);
   1061 	ap_sta_disassoc_cb_timeout(hapd, sta);
   1062 }
   1063 
   1064 
   1065 int ap_sta_flags_txt(u32 flags, char *buf, size_t buflen)
   1066 {
   1067 	int res;
   1068 
   1069 	buf[0] = '\0';
   1070 	res = os_snprintf(buf, buflen, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
   1071 			  (flags & WLAN_STA_AUTH ? "[AUTH]" : ""),
   1072 			  (flags & WLAN_STA_ASSOC ? "[ASSOC]" : ""),
   1073 			  (flags & WLAN_STA_AUTHORIZED ? "[AUTHORIZED]" : ""),
   1074 			  (flags & WLAN_STA_PENDING_POLL ? "[PENDING_POLL" :
   1075 			   ""),
   1076 			  (flags & WLAN_STA_SHORT_PREAMBLE ?
   1077 			   "[SHORT_PREAMBLE]" : ""),
   1078 			  (flags & WLAN_STA_PREAUTH ? "[PREAUTH]" : ""),
   1079 			  (flags & WLAN_STA_WMM ? "[WMM]" : ""),
   1080 			  (flags & WLAN_STA_MFP ? "[MFP]" : ""),
   1081 			  (flags & WLAN_STA_WPS ? "[WPS]" : ""),
   1082 			  (flags & WLAN_STA_MAYBE_WPS ? "[MAYBE_WPS]" : ""),
   1083 			  (flags & WLAN_STA_WDS ? "[WDS]" : ""),
   1084 			  (flags & WLAN_STA_NONERP ? "[NonERP]" : ""),
   1085 			  (flags & WLAN_STA_WPS2 ? "[WPS2]" : ""),
   1086 			  (flags & WLAN_STA_GAS ? "[GAS]" : ""),
   1087 			  (flags & WLAN_STA_VHT ? "[VHT]" : ""),
   1088 			  (flags & WLAN_STA_WNM_SLEEP_MODE ?
   1089 			   "[WNM_SLEEP_MODE]" : ""));
   1090 
   1091 	return res;
   1092 }
   1093