$search
00001 /* 00002 * hostapd / Station table 00003 * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "utils/includes.h" 00016 00017 #include "utils/common.h" 00018 #include "utils/eloop.h" 00019 #include "common/ieee802_11_defs.h" 00020 #include "radius/radius.h" 00021 #include "radius/radius_client.h" 00022 #include "drivers/driver.h" 00023 #include "hostapd.h" 00024 #include "accounting.h" 00025 #include "ieee802_1x.h" 00026 #include "ieee802_11.h" 00027 #include "wpa_auth.h" 00028 #include "preauth_auth.h" 00029 #include "ap_config.h" 00030 #include "beacon.h" 00031 #include "ap_mlme.h" 00032 #include "vlan_init.h" 00033 #include "sta_info.h" 00034 00035 static void ap_sta_remove_in_other_bss(struct hostapd_data *hapd, 00036 struct sta_info *sta); 00037 static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx); 00038 #ifdef CONFIG_IEEE80211W 00039 static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx); 00040 #endif /* CONFIG_IEEE80211W */ 00041 00042 int ap_for_each_sta(struct hostapd_data *hapd, 00043 int (*cb)(struct hostapd_data *hapd, struct sta_info *sta, 00044 void *ctx), 00045 void *ctx) 00046 { 00047 struct sta_info *sta; 00048 00049 for (sta = hapd->sta_list; sta; sta = sta->next) { 00050 if (cb(hapd, sta, ctx)) 00051 return 1; 00052 } 00053 00054 return 0; 00055 } 00056 00057 00058 struct sta_info * ap_get_sta(struct hostapd_data *hapd, const u8 *sta) 00059 { 00060 struct sta_info *s; 00061 00062 s = hapd->sta_hash[STA_HASH(sta)]; 00063 while (s != NULL && os_memcmp(s->addr, sta, 6) != 0) 00064 s = s->hnext; 00065 return s; 00066 } 00067 00068 00069 static void ap_sta_list_del(struct hostapd_data *hapd, struct sta_info *sta) 00070 { 00071 struct sta_info *tmp; 00072 00073 if (hapd->sta_list == sta) { 00074 hapd->sta_list = sta->next; 00075 return; 00076 } 00077 00078 tmp = hapd->sta_list; 00079 while (tmp != NULL && tmp->next != sta) 00080 tmp = tmp->next; 00081 if (tmp == NULL) { 00082 wpa_printf(MSG_DEBUG, "Could not remove STA " MACSTR " from " 00083 "list.", MAC2STR(sta->addr)); 00084 } else 00085 tmp->next = sta->next; 00086 } 00087 00088 00089 void ap_sta_hash_add(struct hostapd_data *hapd, struct sta_info *sta) 00090 { 00091 sta->hnext = hapd->sta_hash[STA_HASH(sta->addr)]; 00092 hapd->sta_hash[STA_HASH(sta->addr)] = sta; 00093 } 00094 00095 00096 static void ap_sta_hash_del(struct hostapd_data *hapd, struct sta_info *sta) 00097 { 00098 struct sta_info *s; 00099 00100 s = hapd->sta_hash[STA_HASH(sta->addr)]; 00101 if (s == NULL) return; 00102 if (os_memcmp(s->addr, sta->addr, 6) == 0) { 00103 hapd->sta_hash[STA_HASH(sta->addr)] = s->hnext; 00104 return; 00105 } 00106 00107 while (s->hnext != NULL && 00108 os_memcmp(s->hnext->addr, sta->addr, ETH_ALEN) != 0) 00109 s = s->hnext; 00110 if (s->hnext != NULL) 00111 s->hnext = s->hnext->hnext; 00112 else 00113 wpa_printf(MSG_DEBUG, "AP: could not remove STA " MACSTR 00114 " from hash table", MAC2STR(sta->addr)); 00115 } 00116 00117 00118 void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta) 00119 { 00120 int set_beacon = 0; 00121 00122 accounting_sta_stop(hapd, sta); 00123 00124 if (sta->flags & WLAN_STA_WDS) 00125 hapd->drv.set_wds_sta(hapd, sta->addr, sta->aid, 0); 00126 00127 if (!(sta->flags & WLAN_STA_PREAUTH)) 00128 hapd->drv.sta_remove(hapd, sta->addr); 00129 00130 ap_sta_hash_del(hapd, sta); 00131 ap_sta_list_del(hapd, sta); 00132 00133 if (sta->aid > 0) 00134 hapd->sta_aid[(sta->aid - 1) / 32] &= 00135 ~BIT((sta->aid - 1) % 32); 00136 00137 hapd->num_sta--; 00138 if (sta->nonerp_set) { 00139 sta->nonerp_set = 0; 00140 hapd->iface->num_sta_non_erp--; 00141 if (hapd->iface->num_sta_non_erp == 0) 00142 set_beacon++; 00143 } 00144 00145 if (sta->no_short_slot_time_set) { 00146 sta->no_short_slot_time_set = 0; 00147 hapd->iface->num_sta_no_short_slot_time--; 00148 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G 00149 && hapd->iface->num_sta_no_short_slot_time == 0) 00150 set_beacon++; 00151 } 00152 00153 if (sta->no_short_preamble_set) { 00154 sta->no_short_preamble_set = 0; 00155 hapd->iface->num_sta_no_short_preamble--; 00156 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G 00157 && hapd->iface->num_sta_no_short_preamble == 0) 00158 set_beacon++; 00159 } 00160 00161 if (sta->no_ht_gf_set) { 00162 sta->no_ht_gf_set = 0; 00163 hapd->iface->num_sta_ht_no_gf--; 00164 } 00165 00166 if (sta->no_ht_set) { 00167 sta->no_ht_set = 0; 00168 hapd->iface->num_sta_no_ht--; 00169 } 00170 00171 if (sta->ht_20mhz_set) { 00172 sta->ht_20mhz_set = 0; 00173 hapd->iface->num_sta_ht_20mhz--; 00174 } 00175 00176 #if defined(NEED_AP_MLME) && defined(CONFIG_IEEE80211N) 00177 if (hostapd_ht_operation_update(hapd->iface) > 0) 00178 set_beacon++; 00179 #endif /* NEED_AP_MLME && CONFIG_IEEE80211N */ 00180 00181 if (set_beacon) 00182 ieee802_11_set_beacons(hapd->iface); 00183 00184 eloop_cancel_timeout(ap_handle_timer, hapd, sta); 00185 eloop_cancel_timeout(ap_handle_session_timer, hapd, sta); 00186 00187 ieee802_1x_free_station(sta); 00188 wpa_auth_sta_deinit(sta->wpa_sm); 00189 rsn_preauth_free_station(hapd, sta); 00190 #ifndef CONFIG_NO_RADIUS 00191 radius_client_flush_auth(hapd->radius, sta->addr); 00192 #endif /* CONFIG_NO_RADIUS */ 00193 00194 os_free(sta->last_assoc_req); 00195 os_free(sta->challenge); 00196 00197 #ifdef CONFIG_IEEE80211W 00198 os_free(sta->sa_query_trans_id); 00199 eloop_cancel_timeout(ap_sa_query_timer, hapd, sta); 00200 #endif /* CONFIG_IEEE80211W */ 00201 00202 wpabuf_free(sta->wps_ie); 00203 00204 os_free(sta->ht_capabilities); 00205 00206 os_free(sta); 00207 } 00208 00209 00210 void hostapd_free_stas(struct hostapd_data *hapd) 00211 { 00212 struct sta_info *sta, *prev; 00213 00214 sta = hapd->sta_list; 00215 00216 while (sta) { 00217 prev = sta; 00218 if (sta->flags & WLAN_STA_AUTH) { 00219 mlme_deauthenticate_indication( 00220 hapd, sta, WLAN_REASON_UNSPECIFIED); 00221 } 00222 sta = sta->next; 00223 wpa_printf(MSG_DEBUG, "Removing station " MACSTR, 00224 MAC2STR(prev->addr)); 00225 ap_free_sta(hapd, prev); 00226 } 00227 } 00228 00229 00238 void ap_handle_timer(void *eloop_ctx, void *timeout_ctx) 00239 { 00240 struct hostapd_data *hapd = eloop_ctx; 00241 struct sta_info *sta = timeout_ctx; 00242 unsigned long next_time = 0; 00243 00244 if (sta->timeout_next == STA_REMOVE) { 00245 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00246 HOSTAPD_LEVEL_INFO, "deauthenticated due to " 00247 "local deauth request"); 00248 ap_free_sta(hapd, sta); 00249 return; 00250 } 00251 00252 if ((sta->flags & WLAN_STA_ASSOC) && 00253 (sta->timeout_next == STA_NULLFUNC || 00254 sta->timeout_next == STA_DISASSOC)) { 00255 int inactive_sec; 00256 wpa_printf(MSG_DEBUG, "Checking STA " MACSTR " inactivity:", 00257 MAC2STR(sta->addr)); 00258 inactive_sec = hapd->drv.get_inact_sec(hapd, sta->addr); 00259 if (inactive_sec == -1) { 00260 wpa_printf(MSG_DEBUG, "Could not get station info " 00261 "from kernel driver for " MACSTR ".", 00262 MAC2STR(sta->addr)); 00263 } else if (inactive_sec < hapd->conf->ap_max_inactivity && 00264 sta->flags & WLAN_STA_ASSOC) { 00265 /* station activity detected; reset timeout state */ 00266 wpa_printf(MSG_DEBUG, " Station has been active"); 00267 sta->timeout_next = STA_NULLFUNC; 00268 next_time = hapd->conf->ap_max_inactivity - 00269 inactive_sec; 00270 } 00271 } 00272 00273 if ((sta->flags & WLAN_STA_ASSOC) && 00274 sta->timeout_next == STA_DISASSOC && 00275 !(sta->flags & WLAN_STA_PENDING_POLL)) { 00276 wpa_printf(MSG_DEBUG, " Station has ACKed data poll"); 00277 /* data nullfunc frame poll did not produce TX errors; assume 00278 * station ACKed it */ 00279 sta->timeout_next = STA_NULLFUNC; 00280 next_time = hapd->conf->ap_max_inactivity; 00281 } 00282 00283 if (next_time) { 00284 eloop_register_timeout(next_time, 0, ap_handle_timer, hapd, 00285 sta); 00286 return; 00287 } 00288 00289 if (sta->timeout_next == STA_NULLFUNC && 00290 (sta->flags & WLAN_STA_ASSOC)) { 00291 #ifndef CONFIG_NATIVE_WINDOWS 00292 /* send data frame to poll STA and check whether this frame 00293 * is ACKed */ 00294 struct ieee80211_hdr hdr; 00295 00296 wpa_printf(MSG_DEBUG, " Polling STA with data frame"); 00297 sta->flags |= WLAN_STA_PENDING_POLL; 00298 00299 os_memset(&hdr, 0, sizeof(hdr)); 00300 if (hapd->driver && 00301 os_strcmp(hapd->driver->name, "hostap") == 0) { 00302 /* 00303 * WLAN_FC_STYPE_NULLFUNC would be more appropriate, 00304 * but it is apparently not retried so TX Exc events 00305 * are not received for it. 00306 */ 00307 hdr.frame_control = 00308 IEEE80211_FC(WLAN_FC_TYPE_DATA, 00309 WLAN_FC_STYPE_DATA); 00310 } else { 00311 hdr.frame_control = 00312 IEEE80211_FC(WLAN_FC_TYPE_DATA, 00313 WLAN_FC_STYPE_NULLFUNC); 00314 } 00315 00316 hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS); 00317 os_memcpy(hdr.IEEE80211_DA_FROMDS, sta->addr, ETH_ALEN); 00318 os_memcpy(hdr.IEEE80211_BSSID_FROMDS, hapd->own_addr, 00319 ETH_ALEN); 00320 os_memcpy(hdr.IEEE80211_SA_FROMDS, hapd->own_addr, ETH_ALEN); 00321 00322 if (hapd->drv.send_mgmt_frame(hapd, &hdr, sizeof(hdr)) < 0) 00323 perror("ap_handle_timer: send"); 00324 #endif /* CONFIG_NATIVE_WINDOWS */ 00325 } else if (sta->timeout_next != STA_REMOVE) { 00326 int deauth = sta->timeout_next == STA_DEAUTH; 00327 00328 wpa_printf(MSG_DEBUG, "Sending %s info to STA " MACSTR, 00329 deauth ? "deauthentication" : "disassociation", 00330 MAC2STR(sta->addr)); 00331 00332 if (deauth) { 00333 hapd->drv.sta_deauth(hapd, sta->addr, 00334 WLAN_REASON_PREV_AUTH_NOT_VALID); 00335 } else { 00336 hapd->drv.sta_disassoc( 00337 hapd, sta->addr, 00338 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); 00339 } 00340 } 00341 00342 switch (sta->timeout_next) { 00343 case STA_NULLFUNC: 00344 sta->timeout_next = STA_DISASSOC; 00345 eloop_register_timeout(AP_DISASSOC_DELAY, 0, ap_handle_timer, 00346 hapd, sta); 00347 break; 00348 case STA_DISASSOC: 00349 sta->flags &= ~WLAN_STA_ASSOC; 00350 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); 00351 if (!sta->acct_terminate_cause) 00352 sta->acct_terminate_cause = 00353 RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT; 00354 accounting_sta_stop(hapd, sta); 00355 ieee802_1x_free_station(sta); 00356 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00357 HOSTAPD_LEVEL_INFO, "disassociated due to " 00358 "inactivity"); 00359 sta->timeout_next = STA_DEAUTH; 00360 eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer, 00361 hapd, sta); 00362 mlme_disassociate_indication( 00363 hapd, sta, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); 00364 break; 00365 case STA_DEAUTH: 00366 case STA_REMOVE: 00367 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00368 HOSTAPD_LEVEL_INFO, "deauthenticated due to " 00369 "inactivity"); 00370 if (!sta->acct_terminate_cause) 00371 sta->acct_terminate_cause = 00372 RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT; 00373 mlme_deauthenticate_indication( 00374 hapd, sta, 00375 WLAN_REASON_PREV_AUTH_NOT_VALID); 00376 ap_free_sta(hapd, sta); 00377 break; 00378 } 00379 } 00380 00381 00382 static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx) 00383 { 00384 struct hostapd_data *hapd = eloop_ctx; 00385 struct sta_info *sta = timeout_ctx; 00386 u8 addr[ETH_ALEN]; 00387 00388 if (!(sta->flags & WLAN_STA_AUTH)) 00389 return; 00390 00391 mlme_deauthenticate_indication(hapd, sta, 00392 WLAN_REASON_PREV_AUTH_NOT_VALID); 00393 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00394 HOSTAPD_LEVEL_INFO, "deauthenticated due to " 00395 "session timeout"); 00396 sta->acct_terminate_cause = 00397 RADIUS_ACCT_TERMINATE_CAUSE_SESSION_TIMEOUT; 00398 os_memcpy(addr, sta->addr, ETH_ALEN); 00399 ap_free_sta(hapd, sta); 00400 hapd->drv.sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID); 00401 } 00402 00403 00404 void ap_sta_session_timeout(struct hostapd_data *hapd, struct sta_info *sta, 00405 u32 session_timeout) 00406 { 00407 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00408 HOSTAPD_LEVEL_DEBUG, "setting session timeout to %d " 00409 "seconds", session_timeout); 00410 eloop_cancel_timeout(ap_handle_session_timer, hapd, sta); 00411 eloop_register_timeout(session_timeout, 0, ap_handle_session_timer, 00412 hapd, sta); 00413 } 00414 00415 00416 void ap_sta_no_session_timeout(struct hostapd_data *hapd, struct sta_info *sta) 00417 { 00418 eloop_cancel_timeout(ap_handle_session_timer, hapd, sta); 00419 } 00420 00421 00422 struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr) 00423 { 00424 struct sta_info *sta; 00425 00426 sta = ap_get_sta(hapd, addr); 00427 if (sta) 00428 return sta; 00429 00430 wpa_printf(MSG_DEBUG, " New STA"); 00431 if (hapd->num_sta >= hapd->conf->max_num_sta) { 00432 /* FIX: might try to remove some old STAs first? */ 00433 wpa_printf(MSG_DEBUG, "no more room for new STAs (%d/%d)", 00434 hapd->num_sta, hapd->conf->max_num_sta); 00435 return NULL; 00436 } 00437 00438 sta = os_zalloc(sizeof(struct sta_info)); 00439 if (sta == NULL) { 00440 wpa_printf(MSG_ERROR, "malloc failed"); 00441 return NULL; 00442 } 00443 sta->acct_interim_interval = hapd->conf->acct_interim_interval; 00444 00445 /* initialize STA info data */ 00446 eloop_register_timeout(hapd->conf->ap_max_inactivity, 0, 00447 ap_handle_timer, hapd, sta); 00448 os_memcpy(sta->addr, addr, ETH_ALEN); 00449 sta->next = hapd->sta_list; 00450 hapd->sta_list = sta; 00451 hapd->num_sta++; 00452 ap_sta_hash_add(hapd, sta); 00453 sta->ssid = &hapd->conf->ssid; 00454 ap_sta_remove_in_other_bss(hapd, sta); 00455 00456 return sta; 00457 } 00458 00459 00460 static int ap_sta_remove(struct hostapd_data *hapd, struct sta_info *sta) 00461 { 00462 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); 00463 00464 wpa_printf(MSG_DEBUG, "Removing STA " MACSTR " from kernel driver", 00465 MAC2STR(sta->addr)); 00466 if (hapd->drv.sta_remove(hapd, sta->addr) && 00467 sta->flags & WLAN_STA_ASSOC) { 00468 wpa_printf(MSG_DEBUG, "Could not remove station " MACSTR 00469 " from kernel driver.", MAC2STR(sta->addr)); 00470 return -1; 00471 } 00472 return 0; 00473 } 00474 00475 00476 static void ap_sta_remove_in_other_bss(struct hostapd_data *hapd, 00477 struct sta_info *sta) 00478 { 00479 struct hostapd_iface *iface = hapd->iface; 00480 size_t i; 00481 00482 for (i = 0; i < iface->num_bss; i++) { 00483 struct hostapd_data *bss = iface->bss[i]; 00484 struct sta_info *sta2; 00485 /* bss should always be set during operation, but it may be 00486 * NULL during reconfiguration. Assume the STA is not 00487 * associated to another BSS in that case to avoid NULL pointer 00488 * dereferences. */ 00489 if (bss == hapd || bss == NULL) 00490 continue; 00491 sta2 = ap_get_sta(bss, sta->addr); 00492 if (!sta2) 00493 continue; 00494 00495 ap_sta_disconnect(bss, sta2, sta2->addr, 00496 WLAN_REASON_PREV_AUTH_NOT_VALID); 00497 } 00498 } 00499 00500 00501 void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta, 00502 u16 reason) 00503 { 00504 wpa_printf(MSG_DEBUG, "%s: disassociate STA " MACSTR, 00505 hapd->conf->iface, MAC2STR(sta->addr)); 00506 sta->flags &= ~WLAN_STA_ASSOC; 00507 ap_sta_remove(hapd, sta); 00508 sta->timeout_next = STA_DEAUTH; 00509 eloop_cancel_timeout(ap_handle_timer, hapd, sta); 00510 eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DISASSOC, 0, 00511 ap_handle_timer, hapd, sta); 00512 accounting_sta_stop(hapd, sta); 00513 ieee802_1x_free_station(sta); 00514 00515 mlme_disassociate_indication(hapd, sta, reason); 00516 } 00517 00518 00519 void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta, 00520 u16 reason) 00521 { 00522 wpa_printf(MSG_DEBUG, "%s: deauthenticate STA " MACSTR, 00523 hapd->conf->iface, MAC2STR(sta->addr)); 00524 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); 00525 ap_sta_remove(hapd, sta); 00526 sta->timeout_next = STA_REMOVE; 00527 eloop_cancel_timeout(ap_handle_timer, hapd, sta); 00528 eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0, 00529 ap_handle_timer, hapd, sta); 00530 accounting_sta_stop(hapd, sta); 00531 ieee802_1x_free_station(sta); 00532 00533 mlme_deauthenticate_indication(hapd, sta, reason); 00534 } 00535 00536 00537 int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta, 00538 int old_vlanid) 00539 { 00540 #ifndef CONFIG_NO_VLAN 00541 const char *iface; 00542 struct hostapd_vlan *vlan = NULL; 00543 int ret; 00544 00545 /* 00546 * Do not proceed furthur if the vlan id remains same. We do not want 00547 * duplicate dynamic vlan entries. 00548 */ 00549 if (sta->vlan_id == old_vlanid) 00550 return 0; 00551 00552 /* 00553 * During 1x reauth, if the vlan id changes, then remove the old id and 00554 * proceed furthur to add the new one. 00555 */ 00556 if (old_vlanid > 0) 00557 vlan_remove_dynamic(hapd, old_vlanid); 00558 00559 iface = hapd->conf->iface; 00560 if (sta->ssid->vlan[0]) 00561 iface = sta->ssid->vlan; 00562 00563 if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED) 00564 sta->vlan_id = 0; 00565 else if (sta->vlan_id > 0) { 00566 vlan = hapd->conf->vlan; 00567 while (vlan) { 00568 if (vlan->vlan_id == sta->vlan_id || 00569 vlan->vlan_id == VLAN_ID_WILDCARD) { 00570 iface = vlan->ifname; 00571 break; 00572 } 00573 vlan = vlan->next; 00574 } 00575 } 00576 00577 if (sta->vlan_id > 0 && vlan == NULL) { 00578 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00579 HOSTAPD_LEVEL_DEBUG, "could not find VLAN for " 00580 "binding station to (vlan_id=%d)", 00581 sta->vlan_id); 00582 return -1; 00583 } else if (sta->vlan_id > 0 && vlan->vlan_id == VLAN_ID_WILDCARD) { 00584 vlan = vlan_add_dynamic(hapd, vlan, sta->vlan_id); 00585 if (vlan == NULL) { 00586 hostapd_logger(hapd, sta->addr, 00587 HOSTAPD_MODULE_IEEE80211, 00588 HOSTAPD_LEVEL_DEBUG, "could not add " 00589 "dynamic VLAN interface for vlan_id=%d", 00590 sta->vlan_id); 00591 return -1; 00592 } 00593 00594 iface = vlan->ifname; 00595 if (vlan_setup_encryption_dyn(hapd, sta->ssid, iface) != 0) { 00596 hostapd_logger(hapd, sta->addr, 00597 HOSTAPD_MODULE_IEEE80211, 00598 HOSTAPD_LEVEL_DEBUG, "could not " 00599 "configure encryption for dynamic VLAN " 00600 "interface for vlan_id=%d", 00601 sta->vlan_id); 00602 } 00603 00604 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00605 HOSTAPD_LEVEL_DEBUG, "added new dynamic VLAN " 00606 "interface '%s'", iface); 00607 } else if (vlan && vlan->vlan_id == sta->vlan_id) { 00608 if (sta->vlan_id > 0) { 00609 vlan->dynamic_vlan++; 00610 hostapd_logger(hapd, sta->addr, 00611 HOSTAPD_MODULE_IEEE80211, 00612 HOSTAPD_LEVEL_DEBUG, "updated existing " 00613 "dynamic VLAN interface '%s'", iface); 00614 } 00615 00616 /* 00617 * Update encryption configuration for statically generated 00618 * VLAN interface. This is only used for static WEP 00619 * configuration for the case where hostapd did not yet know 00620 * which keys are to be used when the interface was added. 00621 */ 00622 if (vlan_setup_encryption_dyn(hapd, sta->ssid, iface) != 0) { 00623 hostapd_logger(hapd, sta->addr, 00624 HOSTAPD_MODULE_IEEE80211, 00625 HOSTAPD_LEVEL_DEBUG, "could not " 00626 "configure encryption for VLAN " 00627 "interface for vlan_id=%d", 00628 sta->vlan_id); 00629 } 00630 } 00631 00632 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00633 HOSTAPD_LEVEL_DEBUG, "binding station to interface " 00634 "'%s'", iface); 00635 00636 if (wpa_auth_sta_set_vlan(sta->wpa_sm, sta->vlan_id) < 0) 00637 wpa_printf(MSG_INFO, "Failed to update VLAN-ID for WPA"); 00638 00639 ret = hapd->drv.set_sta_vlan(iface, hapd, sta->addr, sta->vlan_id); 00640 if (ret < 0) { 00641 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00642 HOSTAPD_LEVEL_DEBUG, "could not bind the STA " 00643 "entry to vlan_id=%d", sta->vlan_id); 00644 } 00645 return ret; 00646 #else /* CONFIG_NO_VLAN */ 00647 return 0; 00648 #endif /* CONFIG_NO_VLAN */ 00649 } 00650 00651 00652 #ifdef CONFIG_IEEE80211W 00653 00654 int ap_check_sa_query_timeout(struct hostapd_data *hapd, struct sta_info *sta) 00655 { 00656 u32 tu; 00657 struct os_time now, passed; 00658 os_get_time(&now); 00659 os_time_sub(&now, &sta->sa_query_start, &passed); 00660 tu = (passed.sec * 1000000 + passed.usec) / 1024; 00661 if (hapd->conf->assoc_sa_query_max_timeout < tu) { 00662 hostapd_logger(hapd, sta->addr, 00663 HOSTAPD_MODULE_IEEE80211, 00664 HOSTAPD_LEVEL_DEBUG, 00665 "association SA Query timed out"); 00666 sta->sa_query_timed_out = 1; 00667 os_free(sta->sa_query_trans_id); 00668 sta->sa_query_trans_id = NULL; 00669 sta->sa_query_count = 0; 00670 eloop_cancel_timeout(ap_sa_query_timer, hapd, sta); 00671 return 1; 00672 } 00673 00674 return 0; 00675 } 00676 00677 00678 static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx) 00679 { 00680 struct hostapd_data *hapd = eloop_ctx; 00681 struct sta_info *sta = timeout_ctx; 00682 unsigned int timeout, sec, usec; 00683 u8 *trans_id, *nbuf; 00684 00685 if (sta->sa_query_count > 0 && 00686 ap_check_sa_query_timeout(hapd, sta)) 00687 return; 00688 00689 nbuf = os_realloc(sta->sa_query_trans_id, 00690 (sta->sa_query_count + 1) * WLAN_SA_QUERY_TR_ID_LEN); 00691 if (nbuf == NULL) 00692 return; 00693 if (sta->sa_query_count == 0) { 00694 /* Starting a new SA Query procedure */ 00695 os_get_time(&sta->sa_query_start); 00696 } 00697 trans_id = nbuf + sta->sa_query_count * WLAN_SA_QUERY_TR_ID_LEN; 00698 sta->sa_query_trans_id = nbuf; 00699 sta->sa_query_count++; 00700 00701 os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN); 00702 00703 timeout = hapd->conf->assoc_sa_query_retry_timeout; 00704 sec = ((timeout / 1000) * 1024) / 1000; 00705 usec = (timeout % 1000) * 1024; 00706 eloop_register_timeout(sec, usec, ap_sa_query_timer, hapd, sta); 00707 00708 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00709 HOSTAPD_LEVEL_DEBUG, 00710 "association SA Query attempt %d", sta->sa_query_count); 00711 00712 #ifdef NEED_AP_MLME 00713 ieee802_11_send_sa_query_req(hapd, sta->addr, trans_id); 00714 #endif /* NEED_AP_MLME */ 00715 } 00716 00717 00718 void ap_sta_start_sa_query(struct hostapd_data *hapd, struct sta_info *sta) 00719 { 00720 ap_sa_query_timer(hapd, sta); 00721 } 00722 00723 00724 void ap_sta_stop_sa_query(struct hostapd_data *hapd, struct sta_info *sta) 00725 { 00726 eloop_cancel_timeout(ap_sa_query_timer, hapd, sta); 00727 os_free(sta->sa_query_trans_id); 00728 sta->sa_query_trans_id = NULL; 00729 sta->sa_query_count = 0; 00730 } 00731 00732 #endif /* CONFIG_IEEE80211W */ 00733 00734 00735 void ap_sta_disconnect(struct hostapd_data *hapd, struct sta_info *sta, 00736 const u8 *addr, u16 reason) 00737 { 00738 00739 if (sta == NULL && addr) 00740 sta = ap_get_sta(hapd, addr); 00741 00742 if (addr) 00743 hapd->drv.sta_deauth(hapd, addr, reason); 00744 00745 if (sta == NULL) 00746 return; 00747 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_AUTHORIZED); 00748 eloop_cancel_timeout(ap_handle_timer, hapd, sta); 00749 eloop_register_timeout(0, 0, ap_handle_timer, hapd, sta); 00750 sta->timeout_next = STA_REMOVE; 00751 }