$search
00001 /* 00002 * hostapd / IEEE 802.11 Management 00003 * Copyright (c) 2002-2010, 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 #ifndef CONFIG_NATIVE_WINDOWS 00018 00019 #include "utils/common.h" 00020 #include "utils/eloop.h" 00021 #include "crypto/crypto.h" 00022 #include "drivers/driver.h" 00023 #include "common/ieee802_11_defs.h" 00024 #include "common/ieee802_11_common.h" 00025 #include "common/wpa_ctrl.h" 00026 #include "radius/radius.h" 00027 #include "radius/radius_client.h" 00028 #include "hostapd.h" 00029 #include "beacon.h" 00030 #include "ieee802_11_auth.h" 00031 #include "sta_info.h" 00032 #include "ieee802_1x.h" 00033 #include "wpa_auth.h" 00034 #include "wmm.h" 00035 #include "ap_list.h" 00036 #include "accounting.h" 00037 #include "ap_config.h" 00038 #include "ap_mlme.h" 00039 #include "ieee802_11.h" 00040 00041 00042 u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid) 00043 { 00044 u8 *pos = eid; 00045 int i, num, count; 00046 00047 if (hapd->iface->current_rates == NULL) 00048 return eid; 00049 00050 *pos++ = WLAN_EID_SUPP_RATES; 00051 num = hapd->iface->num_rates; 00052 if (num > 8) { 00053 /* rest of the rates are encoded in Extended supported 00054 * rates element */ 00055 num = 8; 00056 } 00057 00058 *pos++ = num; 00059 count = 0; 00060 for (i = 0, count = 0; i < hapd->iface->num_rates && count < num; 00061 i++) { 00062 count++; 00063 *pos = hapd->iface->current_rates[i].rate / 5; 00064 if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC) 00065 *pos |= 0x80; 00066 pos++; 00067 } 00068 00069 return pos; 00070 } 00071 00072 00073 u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid) 00074 { 00075 u8 *pos = eid; 00076 int i, num, count; 00077 00078 if (hapd->iface->current_rates == NULL) 00079 return eid; 00080 00081 num = hapd->iface->num_rates; 00082 if (num <= 8) 00083 return eid; 00084 num -= 8; 00085 00086 *pos++ = WLAN_EID_EXT_SUPP_RATES; 00087 *pos++ = num; 00088 count = 0; 00089 for (i = 0, count = 0; i < hapd->iface->num_rates && count < num + 8; 00090 i++) { 00091 count++; 00092 if (count <= 8) 00093 continue; /* already in SuppRates IE */ 00094 *pos = hapd->iface->current_rates[i].rate / 5; 00095 if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC) 00096 *pos |= 0x80; 00097 pos++; 00098 } 00099 00100 return pos; 00101 } 00102 00103 00104 u16 hostapd_own_capab_info(struct hostapd_data *hapd, struct sta_info *sta, 00105 int probe) 00106 { 00107 int capab = WLAN_CAPABILITY_ESS; 00108 int privacy; 00109 00110 if (hapd->iface->num_sta_no_short_preamble == 0 && 00111 hapd->iconf->preamble == SHORT_PREAMBLE) 00112 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE; 00113 00114 privacy = hapd->conf->ssid.wep.keys_set; 00115 00116 if (hapd->conf->ieee802_1x && 00117 (hapd->conf->default_wep_key_len || 00118 hapd->conf->individual_wep_key_len)) 00119 privacy = 1; 00120 00121 if (hapd->conf->wpa) 00122 privacy = 1; 00123 00124 if (sta) { 00125 int policy, def_klen; 00126 if (probe && sta->ssid_probe) { 00127 policy = sta->ssid_probe->security_policy; 00128 def_klen = sta->ssid_probe->wep.default_len; 00129 } else { 00130 policy = sta->ssid->security_policy; 00131 def_klen = sta->ssid->wep.default_len; 00132 } 00133 privacy = policy != SECURITY_PLAINTEXT; 00134 if (policy == SECURITY_IEEE_802_1X && def_klen == 0) 00135 privacy = 0; 00136 } 00137 00138 if (privacy) 00139 capab |= WLAN_CAPABILITY_PRIVACY; 00140 00141 if (hapd->iface->current_mode && 00142 hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G && 00143 hapd->iface->num_sta_no_short_slot_time == 0) 00144 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME; 00145 00146 return capab; 00147 } 00148 00149 00150 #ifdef CONFIG_IEEE80211W 00151 static u8 * hostapd_eid_assoc_comeback_time(struct hostapd_data *hapd, 00152 struct sta_info *sta, u8 *eid) 00153 { 00154 u8 *pos = eid; 00155 u32 timeout, tu; 00156 struct os_time now, passed; 00157 00158 *pos++ = WLAN_EID_TIMEOUT_INTERVAL; 00159 *pos++ = 5; 00160 *pos++ = WLAN_TIMEOUT_ASSOC_COMEBACK; 00161 os_get_time(&now); 00162 os_time_sub(&now, &sta->sa_query_start, &passed); 00163 tu = (passed.sec * 1000000 + passed.usec) / 1024; 00164 if (hapd->conf->assoc_sa_query_max_timeout > tu) 00165 timeout = hapd->conf->assoc_sa_query_max_timeout - tu; 00166 else 00167 timeout = 0; 00168 if (timeout < hapd->conf->assoc_sa_query_max_timeout) 00169 timeout++; /* add some extra time for local timers */ 00170 WPA_PUT_LE32(pos, timeout); 00171 pos += 4; 00172 00173 return pos; 00174 } 00175 #endif /* CONFIG_IEEE80211W */ 00176 00177 00178 void ieee802_11_print_ssid(char *buf, const u8 *ssid, u8 len) 00179 { 00180 int i; 00181 if (len > HOSTAPD_MAX_SSID_LEN) 00182 len = HOSTAPD_MAX_SSID_LEN; 00183 for (i = 0; i < len; i++) { 00184 if (ssid[i] >= 32 && ssid[i] < 127) 00185 buf[i] = ssid[i]; 00186 else 00187 buf[i] = '.'; 00188 } 00189 buf[len] = '\0'; 00190 } 00191 00192 00199 void ieee802_11_send_deauth(struct hostapd_data *hapd, const u8 *addr, 00200 u16 reason) 00201 { 00202 struct ieee80211_mgmt mgmt; 00203 00204 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, 00205 HOSTAPD_LEVEL_DEBUG, 00206 "deauthenticate - reason %d", reason); 00207 os_memset(&mgmt, 0, sizeof(mgmt)); 00208 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 00209 WLAN_FC_STYPE_DEAUTH); 00210 os_memcpy(mgmt.da, addr, ETH_ALEN); 00211 os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN); 00212 os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN); 00213 mgmt.u.deauth.reason_code = host_to_le16(reason); 00214 if (hapd->drv.send_mgmt_frame(hapd, &mgmt, IEEE80211_HDRLEN + 00215 sizeof(mgmt.u.deauth)) < 0) 00216 perror("ieee802_11_send_deauth: send"); 00217 } 00218 00219 00220 static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta, 00221 u16 auth_transaction, const u8 *challenge, 00222 int iswep) 00223 { 00224 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00225 HOSTAPD_LEVEL_DEBUG, 00226 "authentication (shared key, transaction %d)", 00227 auth_transaction); 00228 00229 if (auth_transaction == 1) { 00230 if (!sta->challenge) { 00231 /* Generate a pseudo-random challenge */ 00232 u8 key[8]; 00233 time_t now; 00234 int r; 00235 sta->challenge = os_zalloc(WLAN_AUTH_CHALLENGE_LEN); 00236 if (sta->challenge == NULL) 00237 return WLAN_STATUS_UNSPECIFIED_FAILURE; 00238 00239 now = time(NULL); 00240 r = random(); 00241 os_memcpy(key, &now, 4); 00242 os_memcpy(key + 4, &r, 4); 00243 rc4_skip(key, sizeof(key), 0, 00244 sta->challenge, WLAN_AUTH_CHALLENGE_LEN); 00245 } 00246 return 0; 00247 } 00248 00249 if (auth_transaction != 3) 00250 return WLAN_STATUS_UNSPECIFIED_FAILURE; 00251 00252 /* Transaction 3 */ 00253 if (!iswep || !sta->challenge || !challenge || 00254 os_memcmp(sta->challenge, challenge, WLAN_AUTH_CHALLENGE_LEN)) { 00255 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00256 HOSTAPD_LEVEL_INFO, 00257 "shared key authentication - invalid " 00258 "challenge-response"); 00259 return WLAN_STATUS_CHALLENGE_FAIL; 00260 } 00261 00262 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00263 HOSTAPD_LEVEL_DEBUG, 00264 "authentication OK (shared key)"); 00265 #ifdef IEEE80211_REQUIRE_AUTH_ACK 00266 /* Station will be marked authenticated if it ACKs the 00267 * authentication reply. */ 00268 #else 00269 sta->flags |= WLAN_STA_AUTH; 00270 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH); 00271 #endif 00272 os_free(sta->challenge); 00273 sta->challenge = NULL; 00274 00275 return 0; 00276 } 00277 00278 00279 static void send_auth_reply(struct hostapd_data *hapd, 00280 const u8 *dst, const u8 *bssid, 00281 u16 auth_alg, u16 auth_transaction, u16 resp, 00282 const u8 *ies, size_t ies_len) 00283 { 00284 struct ieee80211_mgmt *reply; 00285 u8 *buf; 00286 size_t rlen; 00287 00288 rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth) + ies_len; 00289 buf = os_zalloc(rlen); 00290 if (buf == NULL) 00291 return; 00292 00293 reply = (struct ieee80211_mgmt *) buf; 00294 reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 00295 WLAN_FC_STYPE_AUTH); 00296 os_memcpy(reply->da, dst, ETH_ALEN); 00297 os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN); 00298 os_memcpy(reply->bssid, bssid, ETH_ALEN); 00299 00300 reply->u.auth.auth_alg = host_to_le16(auth_alg); 00301 reply->u.auth.auth_transaction = host_to_le16(auth_transaction); 00302 reply->u.auth.status_code = host_to_le16(resp); 00303 00304 if (ies && ies_len) 00305 os_memcpy(reply->u.auth.variable, ies, ies_len); 00306 00307 wpa_printf(MSG_DEBUG, "authentication reply: STA=" MACSTR 00308 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)", 00309 MAC2STR(dst), auth_alg, auth_transaction, 00310 resp, (unsigned long) ies_len); 00311 if (hapd->drv.send_mgmt_frame(hapd, reply, rlen) < 0) 00312 perror("send_auth_reply: send"); 00313 00314 os_free(buf); 00315 } 00316 00317 00318 #ifdef CONFIG_IEEE80211R 00319 static void handle_auth_ft_finish(void *ctx, const u8 *dst, const u8 *bssid, 00320 u16 auth_transaction, u16 status, 00321 const u8 *ies, size_t ies_len) 00322 { 00323 struct hostapd_data *hapd = ctx; 00324 struct sta_info *sta; 00325 00326 send_auth_reply(hapd, dst, bssid, WLAN_AUTH_FT, auth_transaction, 00327 status, ies, ies_len); 00328 00329 if (status != WLAN_STATUS_SUCCESS) 00330 return; 00331 00332 sta = ap_get_sta(hapd, dst); 00333 if (sta == NULL) 00334 return; 00335 00336 hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211, 00337 HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)"); 00338 sta->flags |= WLAN_STA_AUTH; 00339 mlme_authenticate_indication(hapd, sta); 00340 } 00341 #endif /* CONFIG_IEEE80211R */ 00342 00343 00344 static void handle_auth(struct hostapd_data *hapd, 00345 const struct ieee80211_mgmt *mgmt, size_t len) 00346 { 00347 u16 auth_alg, auth_transaction, status_code; 00348 u16 resp = WLAN_STATUS_SUCCESS; 00349 struct sta_info *sta = NULL; 00350 int res; 00351 u16 fc; 00352 const u8 *challenge = NULL; 00353 u32 session_timeout, acct_interim_interval; 00354 int vlan_id = 0; 00355 u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN]; 00356 size_t resp_ies_len = 0; 00357 00358 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { 00359 printf("handle_auth - too short payload (len=%lu)\n", 00360 (unsigned long) len); 00361 return; 00362 } 00363 00364 auth_alg = le_to_host16(mgmt->u.auth.auth_alg); 00365 auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction); 00366 status_code = le_to_host16(mgmt->u.auth.status_code); 00367 fc = le_to_host16(mgmt->frame_control); 00368 00369 if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) + 00370 2 + WLAN_AUTH_CHALLENGE_LEN && 00371 mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE && 00372 mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN) 00373 challenge = &mgmt->u.auth.variable[2]; 00374 00375 wpa_printf(MSG_DEBUG, "authentication: STA=" MACSTR " auth_alg=%d " 00376 "auth_transaction=%d status_code=%d wep=%d%s", 00377 MAC2STR(mgmt->sa), auth_alg, auth_transaction, 00378 status_code, !!(fc & WLAN_FC_ISWEP), 00379 challenge ? " challenge" : ""); 00380 00381 if (hapd->tkip_countermeasures) { 00382 resp = WLAN_REASON_MICHAEL_MIC_FAILURE; 00383 goto fail; 00384 } 00385 00386 if (!(((hapd->conf->auth_algs & WPA_AUTH_ALG_OPEN) && 00387 auth_alg == WLAN_AUTH_OPEN) || 00388 #ifdef CONFIG_IEEE80211R 00389 (hapd->conf->wpa && 00390 (hapd->conf->wpa_key_mgmt & 00391 (WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_FT_PSK)) && 00392 auth_alg == WLAN_AUTH_FT) || 00393 #endif /* CONFIG_IEEE80211R */ 00394 ((hapd->conf->auth_algs & WPA_AUTH_ALG_SHARED) && 00395 auth_alg == WLAN_AUTH_SHARED_KEY))) { 00396 printf("Unsupported authentication algorithm (%d)\n", 00397 auth_alg); 00398 resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG; 00399 goto fail; 00400 } 00401 00402 if (!(auth_transaction == 1 || 00403 (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) { 00404 printf("Unknown authentication transaction number (%d)\n", 00405 auth_transaction); 00406 resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION; 00407 goto fail; 00408 } 00409 00410 if (os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) { 00411 printf("Station " MACSTR " not allowed to authenticate.\n", 00412 MAC2STR(mgmt->sa)); 00413 resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 00414 goto fail; 00415 } 00416 00417 res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len, 00418 &session_timeout, 00419 &acct_interim_interval, &vlan_id); 00420 if (res == HOSTAPD_ACL_REJECT) { 00421 printf("Station " MACSTR " not allowed to authenticate.\n", 00422 MAC2STR(mgmt->sa)); 00423 resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 00424 goto fail; 00425 } 00426 if (res == HOSTAPD_ACL_PENDING) { 00427 wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR 00428 " waiting for an external authentication", 00429 MAC2STR(mgmt->sa)); 00430 /* Authentication code will re-send the authentication frame 00431 * after it has received (and cached) information from the 00432 * external source. */ 00433 return; 00434 } 00435 00436 sta = ap_sta_add(hapd, mgmt->sa); 00437 if (!sta) { 00438 resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 00439 goto fail; 00440 } 00441 00442 if (vlan_id > 0) { 00443 if (hostapd_get_vlan_id_ifname(hapd->conf->vlan, 00444 vlan_id) == NULL) { 00445 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS, 00446 HOSTAPD_LEVEL_INFO, "Invalid VLAN ID " 00447 "%d received from RADIUS server", 00448 vlan_id); 00449 resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 00450 goto fail; 00451 } 00452 sta->vlan_id = vlan_id; 00453 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS, 00454 HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id); 00455 } 00456 00457 sta->flags &= ~WLAN_STA_PREAUTH; 00458 ieee802_1x_notify_pre_auth(sta->eapol_sm, 0); 00459 00460 if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval) 00461 sta->acct_interim_interval = acct_interim_interval; 00462 if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT) 00463 ap_sta_session_timeout(hapd, sta, session_timeout); 00464 else 00465 ap_sta_no_session_timeout(hapd, sta); 00466 00467 switch (auth_alg) { 00468 case WLAN_AUTH_OPEN: 00469 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00470 HOSTAPD_LEVEL_DEBUG, 00471 "authentication OK (open system)"); 00472 #ifdef IEEE80211_REQUIRE_AUTH_ACK 00473 /* Station will be marked authenticated if it ACKs the 00474 * authentication reply. */ 00475 #else 00476 sta->flags |= WLAN_STA_AUTH; 00477 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH); 00478 sta->auth_alg = WLAN_AUTH_OPEN; 00479 mlme_authenticate_indication(hapd, sta); 00480 #endif 00481 break; 00482 case WLAN_AUTH_SHARED_KEY: 00483 resp = auth_shared_key(hapd, sta, auth_transaction, challenge, 00484 fc & WLAN_FC_ISWEP); 00485 sta->auth_alg = WLAN_AUTH_SHARED_KEY; 00486 mlme_authenticate_indication(hapd, sta); 00487 if (sta->challenge && auth_transaction == 1) { 00488 resp_ies[0] = WLAN_EID_CHALLENGE; 00489 resp_ies[1] = WLAN_AUTH_CHALLENGE_LEN; 00490 os_memcpy(resp_ies + 2, sta->challenge, 00491 WLAN_AUTH_CHALLENGE_LEN); 00492 resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN; 00493 } 00494 break; 00495 #ifdef CONFIG_IEEE80211R 00496 case WLAN_AUTH_FT: 00497 sta->auth_alg = WLAN_AUTH_FT; 00498 if (sta->wpa_sm == NULL) 00499 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, 00500 sta->addr); 00501 if (sta->wpa_sm == NULL) { 00502 wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA " 00503 "state machine"); 00504 resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 00505 goto fail; 00506 } 00507 wpa_ft_process_auth(sta->wpa_sm, mgmt->bssid, 00508 auth_transaction, mgmt->u.auth.variable, 00509 len - IEEE80211_HDRLEN - 00510 sizeof(mgmt->u.auth), 00511 handle_auth_ft_finish, hapd); 00512 /* handle_auth_ft_finish() callback will complete auth. */ 00513 return; 00514 #endif /* CONFIG_IEEE80211R */ 00515 } 00516 00517 fail: 00518 send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg, 00519 auth_transaction + 1, resp, resp_ies, resp_ies_len); 00520 } 00521 00522 00523 static int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta) 00524 { 00525 int i, j = 32, aid; 00526 00527 /* get a unique AID */ 00528 if (sta->aid > 0) { 00529 wpa_printf(MSG_DEBUG, " old AID %d", sta->aid); 00530 return 0; 00531 } 00532 00533 for (i = 0; i < AID_WORDS; i++) { 00534 if (hapd->sta_aid[i] == (u32) -1) 00535 continue; 00536 for (j = 0; j < 32; j++) { 00537 if (!(hapd->sta_aid[i] & BIT(j))) 00538 break; 00539 } 00540 if (j < 32) 00541 break; 00542 } 00543 if (j == 32) 00544 return -1; 00545 aid = i * 32 + j + 1; 00546 if (aid > 2007) 00547 return -1; 00548 00549 sta->aid = aid; 00550 hapd->sta_aid[i] |= BIT(j); 00551 wpa_printf(MSG_DEBUG, " new AID %d", sta->aid); 00552 return 0; 00553 } 00554 00555 00556 static u16 check_ssid(struct hostapd_data *hapd, struct sta_info *sta, 00557 const u8 *ssid_ie, size_t ssid_ie_len) 00558 { 00559 if (ssid_ie == NULL) 00560 return WLAN_STATUS_UNSPECIFIED_FAILURE; 00561 00562 if (ssid_ie_len != hapd->conf->ssid.ssid_len || 00563 os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0) { 00564 char ssid_txt[33]; 00565 ieee802_11_print_ssid(ssid_txt, ssid_ie, ssid_ie_len); 00566 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00567 HOSTAPD_LEVEL_INFO, 00568 "Station tried to associate with unknown SSID " 00569 "'%s'", ssid_txt); 00570 return WLAN_STATUS_UNSPECIFIED_FAILURE; 00571 } 00572 00573 return WLAN_STATUS_SUCCESS; 00574 } 00575 00576 00577 static u16 check_wmm(struct hostapd_data *hapd, struct sta_info *sta, 00578 const u8 *wmm_ie, size_t wmm_ie_len) 00579 { 00580 sta->flags &= ~WLAN_STA_WMM; 00581 if (wmm_ie && hapd->conf->wmm_enabled) { 00582 if (hostapd_eid_wmm_valid(hapd, wmm_ie, wmm_ie_len)) 00583 hostapd_logger(hapd, sta->addr, 00584 HOSTAPD_MODULE_WPA, 00585 HOSTAPD_LEVEL_DEBUG, 00586 "invalid WMM element in association " 00587 "request"); 00588 else 00589 sta->flags |= WLAN_STA_WMM; 00590 } 00591 return WLAN_STATUS_SUCCESS; 00592 } 00593 00594 00595 static u16 copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta, 00596 struct ieee802_11_elems *elems) 00597 { 00598 if (!elems->supp_rates) { 00599 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00600 HOSTAPD_LEVEL_DEBUG, 00601 "No supported rates element in AssocReq"); 00602 return WLAN_STATUS_UNSPECIFIED_FAILURE; 00603 } 00604 00605 if (elems->supp_rates_len > sizeof(sta->supported_rates)) { 00606 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00607 HOSTAPD_LEVEL_DEBUG, 00608 "Invalid supported rates element length %d", 00609 elems->supp_rates_len); 00610 return WLAN_STATUS_UNSPECIFIED_FAILURE; 00611 } 00612 00613 os_memset(sta->supported_rates, 0, sizeof(sta->supported_rates)); 00614 os_memcpy(sta->supported_rates, elems->supp_rates, 00615 elems->supp_rates_len); 00616 sta->supported_rates_len = elems->supp_rates_len; 00617 00618 if (elems->ext_supp_rates) { 00619 if (elems->supp_rates_len + elems->ext_supp_rates_len > 00620 sizeof(sta->supported_rates)) { 00621 hostapd_logger(hapd, sta->addr, 00622 HOSTAPD_MODULE_IEEE80211, 00623 HOSTAPD_LEVEL_DEBUG, 00624 "Invalid supported rates element length" 00625 " %d+%d", elems->supp_rates_len, 00626 elems->ext_supp_rates_len); 00627 return WLAN_STATUS_UNSPECIFIED_FAILURE; 00628 } 00629 00630 os_memcpy(sta->supported_rates + elems->supp_rates_len, 00631 elems->ext_supp_rates, elems->ext_supp_rates_len); 00632 sta->supported_rates_len += elems->ext_supp_rates_len; 00633 } 00634 00635 return WLAN_STATUS_SUCCESS; 00636 } 00637 00638 00639 static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, 00640 const u8 *ies, size_t ies_len, int reassoc) 00641 { 00642 struct ieee802_11_elems elems; 00643 u16 resp; 00644 const u8 *wpa_ie; 00645 size_t wpa_ie_len; 00646 00647 if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) { 00648 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00649 HOSTAPD_LEVEL_INFO, "Station sent an invalid " 00650 "association request"); 00651 return WLAN_STATUS_UNSPECIFIED_FAILURE; 00652 } 00653 00654 resp = check_ssid(hapd, sta, elems.ssid, elems.ssid_len); 00655 if (resp != WLAN_STATUS_SUCCESS) 00656 return resp; 00657 resp = check_wmm(hapd, sta, elems.wmm, elems.wmm_len); 00658 if (resp != WLAN_STATUS_SUCCESS) 00659 return resp; 00660 resp = copy_supp_rates(hapd, sta, &elems); 00661 if (resp != WLAN_STATUS_SUCCESS) 00662 return resp; 00663 #ifdef CONFIG_IEEE80211N 00664 resp = copy_sta_ht_capab(sta, elems.ht_capabilities, 00665 elems.ht_capabilities_len); 00666 if (resp != WLAN_STATUS_SUCCESS) 00667 return resp; 00668 #endif /* CONFIG_IEEE80211N */ 00669 00670 if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems.rsn_ie) { 00671 wpa_ie = elems.rsn_ie; 00672 wpa_ie_len = elems.rsn_ie_len; 00673 } else if ((hapd->conf->wpa & WPA_PROTO_WPA) && 00674 elems.wpa_ie) { 00675 wpa_ie = elems.wpa_ie; 00676 wpa_ie_len = elems.wpa_ie_len; 00677 } else { 00678 wpa_ie = NULL; 00679 wpa_ie_len = 0; 00680 } 00681 00682 #ifdef CONFIG_WPS 00683 sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS); 00684 if (hapd->conf->wps_state && elems.wps_ie) { 00685 wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)Association " 00686 "Request - assume WPS is used"); 00687 sta->flags |= WLAN_STA_WPS; 00688 wpabuf_free(sta->wps_ie); 00689 sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4, 00690 elems.wps_ie_len - 4); 00691 wpa_ie = NULL; 00692 wpa_ie_len = 0; 00693 } else if (hapd->conf->wps_state && wpa_ie == NULL) { 00694 wpa_printf(MSG_DEBUG, "STA did not include WPA/RSN IE in " 00695 "(Re)Association Request - possible WPS use"); 00696 sta->flags |= WLAN_STA_MAYBE_WPS; 00697 } else 00698 #endif /* CONFIG_WPS */ 00699 if (hapd->conf->wpa && wpa_ie == NULL) { 00700 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 00701 HOSTAPD_LEVEL_INFO, 00702 "No WPA/RSN IE in association request"); 00703 return WLAN_STATUS_INVALID_IE; 00704 } 00705 00706 if (hapd->conf->wpa && wpa_ie) { 00707 int res; 00708 wpa_ie -= 2; 00709 wpa_ie_len += 2; 00710 if (sta->wpa_sm == NULL) 00711 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, 00712 sta->addr); 00713 if (sta->wpa_sm == NULL) { 00714 wpa_printf(MSG_WARNING, "Failed to initialize WPA " 00715 "state machine"); 00716 return WLAN_STATUS_UNSPECIFIED_FAILURE; 00717 } 00718 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, 00719 wpa_ie, wpa_ie_len, 00720 elems.mdie, elems.mdie_len); 00721 if (res == WPA_INVALID_GROUP) 00722 resp = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; 00723 else if (res == WPA_INVALID_PAIRWISE) 00724 resp = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; 00725 else if (res == WPA_INVALID_AKMP) 00726 resp = WLAN_STATUS_AKMP_NOT_VALID; 00727 else if (res == WPA_ALLOC_FAIL) 00728 resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 00729 #ifdef CONFIG_IEEE80211W 00730 else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION) 00731 resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION; 00732 else if (res == WPA_INVALID_MGMT_GROUP_CIPHER) 00733 resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION; 00734 #endif /* CONFIG_IEEE80211W */ 00735 else if (res == WPA_INVALID_MDIE) 00736 resp = WLAN_STATUS_INVALID_MDIE; 00737 else if (res != WPA_IE_OK) 00738 resp = WLAN_STATUS_INVALID_IE; 00739 if (resp != WLAN_STATUS_SUCCESS) 00740 return resp; 00741 #ifdef CONFIG_IEEE80211W 00742 if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out && 00743 sta->sa_query_count > 0) 00744 ap_check_sa_query_timeout(hapd, sta); 00745 if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out && 00746 (!reassoc || sta->auth_alg != WLAN_AUTH_FT)) { 00747 /* 00748 * STA has already been associated with MFP and SA 00749 * Query timeout has not been reached. Reject the 00750 * association attempt temporarily and start SA Query, 00751 * if one is not pending. 00752 */ 00753 00754 if (sta->sa_query_count == 0) 00755 ap_sta_start_sa_query(hapd, sta); 00756 00757 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY; 00758 } 00759 00760 if (wpa_auth_uses_mfp(sta->wpa_sm)) 00761 sta->flags |= WLAN_STA_MFP; 00762 else 00763 sta->flags &= ~WLAN_STA_MFP; 00764 #endif /* CONFIG_IEEE80211W */ 00765 00766 #ifdef CONFIG_IEEE80211R 00767 if (sta->auth_alg == WLAN_AUTH_FT) { 00768 if (!reassoc) { 00769 wpa_printf(MSG_DEBUG, "FT: " MACSTR " tried " 00770 "to use association (not " 00771 "re-association) with FT auth_alg", 00772 MAC2STR(sta->addr)); 00773 return WLAN_STATUS_UNSPECIFIED_FAILURE; 00774 } 00775 00776 resp = wpa_ft_validate_reassoc(sta->wpa_sm, ies, 00777 ies_len); 00778 if (resp != WLAN_STATUS_SUCCESS) 00779 return resp; 00780 } 00781 #endif /* CONFIG_IEEE80211R */ 00782 00783 #ifdef CONFIG_IEEE80211N 00784 if ((sta->flags & WLAN_STA_HT) && 00785 wpa_auth_get_pairwise(sta->wpa_sm) == WPA_CIPHER_TKIP) { 00786 hostapd_logger(hapd, sta->addr, 00787 HOSTAPD_MODULE_IEEE80211, 00788 HOSTAPD_LEVEL_INFO, 00789 "Station tried to use TKIP with HT " 00790 "association"); 00791 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; 00792 } 00793 #endif /* CONFIG_IEEE80211N */ 00794 } else 00795 wpa_auth_sta_no_wpa(sta->wpa_sm); 00796 00797 return WLAN_STATUS_SUCCESS; 00798 } 00799 00800 00801 static void send_deauth(struct hostapd_data *hapd, const u8 *addr, 00802 u16 reason_code) 00803 { 00804 int send_len; 00805 struct ieee80211_mgmt reply; 00806 00807 os_memset(&reply, 0, sizeof(reply)); 00808 reply.frame_control = 00809 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH); 00810 os_memcpy(reply.da, addr, ETH_ALEN); 00811 os_memcpy(reply.sa, hapd->own_addr, ETH_ALEN); 00812 os_memcpy(reply.bssid, hapd->own_addr, ETH_ALEN); 00813 00814 send_len = IEEE80211_HDRLEN + sizeof(reply.u.deauth); 00815 reply.u.deauth.reason_code = host_to_le16(reason_code); 00816 00817 if (hapd->drv.send_mgmt_frame(hapd, &reply, send_len) < 0) 00818 wpa_printf(MSG_INFO, "Failed to send deauth: %s", 00819 strerror(errno)); 00820 } 00821 00822 00823 static void send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta, 00824 u16 status_code, int reassoc, const u8 *ies, 00825 size_t ies_len) 00826 { 00827 int send_len; 00828 u8 buf[sizeof(struct ieee80211_mgmt) + 1024]; 00829 struct ieee80211_mgmt *reply; 00830 u8 *p; 00831 00832 os_memset(buf, 0, sizeof(buf)); 00833 reply = (struct ieee80211_mgmt *) buf; 00834 reply->frame_control = 00835 IEEE80211_FC(WLAN_FC_TYPE_MGMT, 00836 (reassoc ? WLAN_FC_STYPE_REASSOC_RESP : 00837 WLAN_FC_STYPE_ASSOC_RESP)); 00838 os_memcpy(reply->da, sta->addr, ETH_ALEN); 00839 os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN); 00840 os_memcpy(reply->bssid, hapd->own_addr, ETH_ALEN); 00841 00842 send_len = IEEE80211_HDRLEN; 00843 send_len += sizeof(reply->u.assoc_resp); 00844 reply->u.assoc_resp.capab_info = 00845 host_to_le16(hostapd_own_capab_info(hapd, sta, 0)); 00846 reply->u.assoc_resp.status_code = host_to_le16(status_code); 00847 reply->u.assoc_resp.aid = host_to_le16((sta ? sta->aid : 0) 00848 | BIT(14) | BIT(15)); 00849 /* Supported rates */ 00850 p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable); 00851 /* Extended supported rates */ 00852 p = hostapd_eid_ext_supp_rates(hapd, p); 00853 if (sta->flags & WLAN_STA_WMM) 00854 p = hostapd_eid_wmm(hapd, p); 00855 00856 #ifdef CONFIG_IEEE80211N 00857 p = hostapd_eid_ht_capabilities(hapd, p); 00858 p = hostapd_eid_ht_operation(hapd, p); 00859 #endif /* CONFIG_IEEE80211N */ 00860 00861 #ifdef CONFIG_IEEE80211R 00862 if (status_code == WLAN_STATUS_SUCCESS) { 00863 /* IEEE 802.11r: Mobility Domain Information, Fast BSS 00864 * Transition Information, RSN, [RIC Response] */ 00865 p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, p, 00866 buf + sizeof(buf) - p, 00867 sta->auth_alg, ies, ies_len); 00868 } 00869 #endif /* CONFIG_IEEE80211R */ 00870 00871 #ifdef CONFIG_IEEE80211W 00872 if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) 00873 p = hostapd_eid_assoc_comeback_time(hapd, sta, p); 00874 #endif /* CONFIG_IEEE80211W */ 00875 00876 send_len += p - reply->u.assoc_resp.variable; 00877 00878 if (hapd->drv.send_mgmt_frame(hapd, reply, send_len) < 0) 00879 wpa_printf(MSG_INFO, "Failed to send assoc resp: %s", 00880 strerror(errno)); 00881 } 00882 00883 00884 static void handle_assoc(struct hostapd_data *hapd, 00885 const struct ieee80211_mgmt *mgmt, size_t len, 00886 int reassoc) 00887 { 00888 u16 capab_info, listen_interval; 00889 u16 resp = WLAN_STATUS_SUCCESS; 00890 const u8 *pos; 00891 int left, i; 00892 struct sta_info *sta; 00893 00894 if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) : 00895 sizeof(mgmt->u.assoc_req))) { 00896 printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)" 00897 "\n", reassoc, (unsigned long) len); 00898 return; 00899 } 00900 00901 if (reassoc) { 00902 capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info); 00903 listen_interval = le_to_host16( 00904 mgmt->u.reassoc_req.listen_interval); 00905 wpa_printf(MSG_DEBUG, "reassociation request: STA=" MACSTR 00906 " capab_info=0x%02x listen_interval=%d current_ap=" 00907 MACSTR, 00908 MAC2STR(mgmt->sa), capab_info, listen_interval, 00909 MAC2STR(mgmt->u.reassoc_req.current_ap)); 00910 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req)); 00911 pos = mgmt->u.reassoc_req.variable; 00912 } else { 00913 capab_info = le_to_host16(mgmt->u.assoc_req.capab_info); 00914 listen_interval = le_to_host16( 00915 mgmt->u.assoc_req.listen_interval); 00916 wpa_printf(MSG_DEBUG, "association request: STA=" MACSTR 00917 " capab_info=0x%02x listen_interval=%d", 00918 MAC2STR(mgmt->sa), capab_info, listen_interval); 00919 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req)); 00920 pos = mgmt->u.assoc_req.variable; 00921 } 00922 00923 sta = ap_get_sta(hapd, mgmt->sa); 00924 #ifdef CONFIG_IEEE80211R 00925 if (sta && sta->auth_alg == WLAN_AUTH_FT && 00926 (sta->flags & WLAN_STA_AUTH) == 0) { 00927 wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate " 00928 "prior to authentication since it is using " 00929 "over-the-DS FT", MAC2STR(mgmt->sa)); 00930 } else 00931 #endif /* CONFIG_IEEE80211R */ 00932 if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) { 00933 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 00934 HOSTAPD_LEVEL_INFO, "Station tried to " 00935 "associate before authentication " 00936 "(aid=%d flags=0x%x)", 00937 sta ? sta->aid : -1, 00938 sta ? sta->flags : 0); 00939 send_deauth(hapd, mgmt->sa, 00940 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA); 00941 return; 00942 } 00943 00944 if (hapd->tkip_countermeasures) { 00945 resp = WLAN_REASON_MICHAEL_MIC_FAILURE; 00946 goto fail; 00947 } 00948 00949 if (listen_interval > hapd->conf->max_listen_interval) { 00950 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 00951 HOSTAPD_LEVEL_DEBUG, 00952 "Too large Listen Interval (%d)", 00953 listen_interval); 00954 resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE; 00955 goto fail; 00956 } 00957 00958 /* followed by SSID and Supported rates; and HT capabilities if 802.11n 00959 * is used */ 00960 resp = check_assoc_ies(hapd, sta, pos, left, reassoc); 00961 if (resp != WLAN_STATUS_SUCCESS) 00962 goto fail; 00963 00964 if (hostapd_get_aid(hapd, sta) < 0) { 00965 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 00966 HOSTAPD_LEVEL_INFO, "No room for more AIDs"); 00967 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; 00968 goto fail; 00969 } 00970 00971 sta->capability = capab_info; 00972 sta->listen_interval = listen_interval; 00973 00974 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) 00975 sta->flags |= WLAN_STA_NONERP; 00976 for (i = 0; i < sta->supported_rates_len; i++) { 00977 if ((sta->supported_rates[i] & 0x7f) > 22) { 00978 sta->flags &= ~WLAN_STA_NONERP; 00979 break; 00980 } 00981 } 00982 if (sta->flags & WLAN_STA_NONERP && !sta->nonerp_set) { 00983 sta->nonerp_set = 1; 00984 hapd->iface->num_sta_non_erp++; 00985 if (hapd->iface->num_sta_non_erp == 1) 00986 ieee802_11_set_beacons(hapd->iface); 00987 } 00988 00989 if (!(sta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) && 00990 !sta->no_short_slot_time_set) { 00991 sta->no_short_slot_time_set = 1; 00992 hapd->iface->num_sta_no_short_slot_time++; 00993 if (hapd->iface->current_mode->mode == 00994 HOSTAPD_MODE_IEEE80211G && 00995 hapd->iface->num_sta_no_short_slot_time == 1) 00996 ieee802_11_set_beacons(hapd->iface); 00997 } 00998 00999 if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 01000 sta->flags |= WLAN_STA_SHORT_PREAMBLE; 01001 else 01002 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE; 01003 01004 if (!(sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && 01005 !sta->no_short_preamble_set) { 01006 sta->no_short_preamble_set = 1; 01007 hapd->iface->num_sta_no_short_preamble++; 01008 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G 01009 && hapd->iface->num_sta_no_short_preamble == 1) 01010 ieee802_11_set_beacons(hapd->iface); 01011 } 01012 01013 #ifdef CONFIG_IEEE80211N 01014 update_ht_state(hapd, sta); 01015 #endif /* CONFIG_IEEE80211N */ 01016 01017 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 01018 HOSTAPD_LEVEL_DEBUG, 01019 "association OK (aid %d)", sta->aid); 01020 /* Station will be marked associated, after it acknowledges AssocResp 01021 */ 01022 01023 #ifdef CONFIG_IEEE80211W 01024 if ((sta->flags & WLAN_STA_MFP) && sta->sa_query_timed_out) { 01025 wpa_printf(MSG_DEBUG, "Allowing %sassociation after timed out " 01026 "SA Query procedure", reassoc ? "re" : ""); 01027 /* TODO: Send a protected Disassociate frame to the STA using 01028 * the old key and Reason Code "Previous Authentication no 01029 * longer valid". Make sure this is only sent protected since 01030 * unprotected frame would be received by the STA that is now 01031 * trying to associate. 01032 */ 01033 } 01034 #endif /* CONFIG_IEEE80211W */ 01035 01036 if (reassoc) { 01037 os_memcpy(sta->previous_ap, mgmt->u.reassoc_req.current_ap, 01038 ETH_ALEN); 01039 } 01040 01041 if (sta->last_assoc_req) 01042 os_free(sta->last_assoc_req); 01043 sta->last_assoc_req = os_malloc(len); 01044 if (sta->last_assoc_req) 01045 os_memcpy(sta->last_assoc_req, mgmt, len); 01046 01047 /* Make sure that the previously registered inactivity timer will not 01048 * remove the STA immediately. */ 01049 sta->timeout_next = STA_NULLFUNC; 01050 01051 fail: 01052 send_assoc_resp(hapd, sta, resp, reassoc, pos, left); 01053 } 01054 01055 01056 static void handle_disassoc(struct hostapd_data *hapd, 01057 const struct ieee80211_mgmt *mgmt, size_t len) 01058 { 01059 struct sta_info *sta; 01060 01061 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) { 01062 printf("handle_disassoc - too short payload (len=%lu)\n", 01063 (unsigned long) len); 01064 return; 01065 } 01066 01067 wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d", 01068 MAC2STR(mgmt->sa), 01069 le_to_host16(mgmt->u.disassoc.reason_code)); 01070 01071 sta = ap_get_sta(hapd, mgmt->sa); 01072 if (sta == NULL) { 01073 printf("Station " MACSTR " trying to disassociate, but it " 01074 "is not associated.\n", MAC2STR(mgmt->sa)); 01075 return; 01076 } 01077 01078 sta->flags &= ~WLAN_STA_ASSOC; 01079 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR, 01080 MAC2STR(sta->addr)); 01081 wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC); 01082 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 01083 HOSTAPD_LEVEL_INFO, "disassociated"); 01084 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; 01085 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); 01086 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA 01087 * authenticated. */ 01088 accounting_sta_stop(hapd, sta); 01089 ieee802_1x_free_station(sta); 01090 hapd->drv.sta_remove(hapd, sta->addr); 01091 01092 if (sta->timeout_next == STA_NULLFUNC || 01093 sta->timeout_next == STA_DISASSOC) { 01094 sta->timeout_next = STA_DEAUTH; 01095 eloop_cancel_timeout(ap_handle_timer, hapd, sta); 01096 eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer, 01097 hapd, sta); 01098 } 01099 01100 mlme_disassociate_indication( 01101 hapd, sta, le_to_host16(mgmt->u.disassoc.reason_code)); 01102 } 01103 01104 01105 static void handle_deauth(struct hostapd_data *hapd, 01106 const struct ieee80211_mgmt *mgmt, size_t len) 01107 { 01108 struct sta_info *sta; 01109 01110 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.deauth)) { 01111 printf("handle_deauth - too short payload (len=%lu)\n", 01112 (unsigned long) len); 01113 return; 01114 } 01115 01116 wpa_printf(MSG_DEBUG, "deauthentication: STA=" MACSTR 01117 " reason_code=%d", 01118 MAC2STR(mgmt->sa), 01119 le_to_host16(mgmt->u.deauth.reason_code)); 01120 01121 sta = ap_get_sta(hapd, mgmt->sa); 01122 if (sta == NULL) { 01123 printf("Station " MACSTR " trying to deauthenticate, but it " 01124 "is not authenticated.\n", MAC2STR(mgmt->sa)); 01125 return; 01126 } 01127 01128 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); 01129 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR, 01130 MAC2STR(sta->addr)); 01131 wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH); 01132 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 01133 HOSTAPD_LEVEL_DEBUG, "deauthenticated"); 01134 mlme_deauthenticate_indication( 01135 hapd, sta, le_to_host16(mgmt->u.deauth.reason_code)); 01136 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; 01137 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); 01138 ap_free_sta(hapd, sta); 01139 } 01140 01141 01142 static void handle_beacon(struct hostapd_data *hapd, 01143 const struct ieee80211_mgmt *mgmt, size_t len, 01144 struct hostapd_frame_info *fi) 01145 { 01146 struct ieee802_11_elems elems; 01147 01148 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.beacon)) { 01149 printf("handle_beacon - too short payload (len=%lu)\n", 01150 (unsigned long) len); 01151 return; 01152 } 01153 01154 (void) ieee802_11_parse_elems(mgmt->u.beacon.variable, 01155 len - (IEEE80211_HDRLEN + 01156 sizeof(mgmt->u.beacon)), &elems, 01157 0); 01158 01159 ap_list_process_beacon(hapd->iface, mgmt, &elems, fi); 01160 } 01161 01162 01163 #ifdef CONFIG_IEEE80211W 01164 01165 /* MLME-SAQuery.request */ 01166 void ieee802_11_send_sa_query_req(struct hostapd_data *hapd, 01167 const u8 *addr, const u8 *trans_id) 01168 { 01169 struct ieee80211_mgmt mgmt; 01170 u8 *end; 01171 01172 wpa_printf(MSG_DEBUG, "IEEE 802.11: Sending SA Query Request to " 01173 MACSTR, MAC2STR(addr)); 01174 wpa_hexdump(MSG_DEBUG, "IEEE 802.11: SA Query Transaction ID", 01175 trans_id, WLAN_SA_QUERY_TR_ID_LEN); 01176 01177 os_memset(&mgmt, 0, sizeof(mgmt)); 01178 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 01179 WLAN_FC_STYPE_ACTION); 01180 os_memcpy(mgmt.da, addr, ETH_ALEN); 01181 os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN); 01182 os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN); 01183 mgmt.u.action.category = WLAN_ACTION_SA_QUERY; 01184 mgmt.u.action.u.sa_query_req.action = WLAN_SA_QUERY_REQUEST; 01185 os_memcpy(mgmt.u.action.u.sa_query_req.trans_id, trans_id, 01186 WLAN_SA_QUERY_TR_ID_LEN); 01187 end = mgmt.u.action.u.sa_query_req.trans_id + WLAN_SA_QUERY_TR_ID_LEN; 01188 if (hapd->drv.send_mgmt_frame(hapd, &mgmt, end - (u8 *) &mgmt) < 0) 01189 perror("ieee802_11_send_sa_query_req: send"); 01190 } 01191 01192 01193 static void hostapd_sa_query_request(struct hostapd_data *hapd, 01194 const struct ieee80211_mgmt *mgmt) 01195 { 01196 struct sta_info *sta; 01197 struct ieee80211_mgmt resp; 01198 u8 *end; 01199 01200 wpa_printf(MSG_DEBUG, "IEEE 802.11: Received SA Query Request from " 01201 MACSTR, MAC2STR(mgmt->sa)); 01202 wpa_hexdump(MSG_DEBUG, "IEEE 802.11: SA Query Transaction ID", 01203 mgmt->u.action.u.sa_query_resp.trans_id, 01204 WLAN_SA_QUERY_TR_ID_LEN); 01205 01206 sta = ap_get_sta(hapd, mgmt->sa); 01207 if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) { 01208 wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignore SA Query Request " 01209 "from unassociated STA " MACSTR, MAC2STR(mgmt->sa)); 01210 return; 01211 } 01212 01213 wpa_printf(MSG_DEBUG, "IEEE 802.11: Sending SA Query Response to " 01214 MACSTR, MAC2STR(mgmt->sa)); 01215 01216 os_memset(&resp, 0, sizeof(resp)); 01217 resp.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 01218 WLAN_FC_STYPE_ACTION); 01219 os_memcpy(resp.da, mgmt->sa, ETH_ALEN); 01220 os_memcpy(resp.sa, hapd->own_addr, ETH_ALEN); 01221 os_memcpy(resp.bssid, hapd->own_addr, ETH_ALEN); 01222 resp.u.action.category = WLAN_ACTION_SA_QUERY; 01223 resp.u.action.u.sa_query_req.action = WLAN_SA_QUERY_RESPONSE; 01224 os_memcpy(resp.u.action.u.sa_query_req.trans_id, 01225 mgmt->u.action.u.sa_query_req.trans_id, 01226 WLAN_SA_QUERY_TR_ID_LEN); 01227 end = resp.u.action.u.sa_query_req.trans_id + WLAN_SA_QUERY_TR_ID_LEN; 01228 if (hapd->drv.send_mgmt_frame(hapd, &resp, end - (u8 *) &resp) < 0) 01229 perror("hostapd_sa_query_request: send"); 01230 } 01231 01232 01233 static void hostapd_sa_query_action(struct hostapd_data *hapd, 01234 const struct ieee80211_mgmt *mgmt, 01235 size_t len) 01236 { 01237 struct sta_info *sta; 01238 const u8 *end; 01239 int i; 01240 01241 end = mgmt->u.action.u.sa_query_resp.trans_id + 01242 WLAN_SA_QUERY_TR_ID_LEN; 01243 if (((u8 *) mgmt) + len < end) { 01244 wpa_printf(MSG_DEBUG, "IEEE 802.11: Too short SA Query Action " 01245 "frame (len=%lu)", (unsigned long) len); 01246 return; 01247 } 01248 01249 if (mgmt->u.action.u.sa_query_resp.action == WLAN_SA_QUERY_REQUEST) { 01250 hostapd_sa_query_request(hapd, mgmt); 01251 return; 01252 } 01253 01254 if (mgmt->u.action.u.sa_query_resp.action != WLAN_SA_QUERY_RESPONSE) { 01255 wpa_printf(MSG_DEBUG, "IEEE 802.11: Unexpected SA Query " 01256 "Action %d", mgmt->u.action.u.sa_query_resp.action); 01257 return; 01258 } 01259 01260 wpa_printf(MSG_DEBUG, "IEEE 802.11: Received SA Query Response from " 01261 MACSTR, MAC2STR(mgmt->sa)); 01262 wpa_hexdump(MSG_DEBUG, "IEEE 802.11: SA Query Transaction ID", 01263 mgmt->u.action.u.sa_query_resp.trans_id, 01264 WLAN_SA_QUERY_TR_ID_LEN); 01265 01266 /* MLME-SAQuery.confirm */ 01267 01268 sta = ap_get_sta(hapd, mgmt->sa); 01269 if (sta == NULL || sta->sa_query_trans_id == NULL) { 01270 wpa_printf(MSG_DEBUG, "IEEE 802.11: No matching STA with " 01271 "pending SA Query request found"); 01272 return; 01273 } 01274 01275 for (i = 0; i < sta->sa_query_count; i++) { 01276 if (os_memcmp(sta->sa_query_trans_id + 01277 i * WLAN_SA_QUERY_TR_ID_LEN, 01278 mgmt->u.action.u.sa_query_resp.trans_id, 01279 WLAN_SA_QUERY_TR_ID_LEN) == 0) 01280 break; 01281 } 01282 01283 if (i >= sta->sa_query_count) { 01284 wpa_printf(MSG_DEBUG, "IEEE 802.11: No matching SA Query " 01285 "transaction identifier found"); 01286 return; 01287 } 01288 01289 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 01290 HOSTAPD_LEVEL_DEBUG, 01291 "Reply to pending SA Query received"); 01292 ap_sta_stop_sa_query(hapd, sta); 01293 } 01294 01295 01296 static int robust_action_frame(u8 category) 01297 { 01298 return category != WLAN_ACTION_PUBLIC && 01299 category != WLAN_ACTION_HT; 01300 } 01301 #endif /* CONFIG_IEEE80211W */ 01302 01303 01304 static void handle_action(struct hostapd_data *hapd, 01305 const struct ieee80211_mgmt *mgmt, size_t len) 01306 { 01307 struct sta_info *sta; 01308 01309 if (len < IEEE80211_HDRLEN + 1) { 01310 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 01311 HOSTAPD_LEVEL_DEBUG, 01312 "handle_action - too short payload (len=%lu)", 01313 (unsigned long) len); 01314 return; 01315 } 01316 01317 sta = ap_get_sta(hapd, mgmt->sa); 01318 #ifdef CONFIG_IEEE80211W 01319 if (sta && (sta->flags & WLAN_STA_MFP) && 01320 !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP) && 01321 robust_action_frame(mgmt->u.action.category))) { 01322 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 01323 HOSTAPD_LEVEL_DEBUG, 01324 "Dropped unprotected Robust Action frame from " 01325 "an MFP STA"); 01326 return; 01327 } 01328 #endif /* CONFIG_IEEE80211W */ 01329 01330 switch (mgmt->u.action.category) { 01331 #ifdef CONFIG_IEEE80211R 01332 case WLAN_ACTION_FT: 01333 { 01334 if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) { 01335 wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored FT Action " 01336 "frame from unassociated STA " MACSTR, 01337 MAC2STR(mgmt->sa)); 01338 return; 01339 } 01340 01341 if (wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action, 01342 len - IEEE80211_HDRLEN)) 01343 break; 01344 01345 return; 01346 } 01347 #endif /* CONFIG_IEEE80211R */ 01348 case WLAN_ACTION_WMM: 01349 hostapd_wmm_action(hapd, mgmt, len); 01350 return; 01351 #ifdef CONFIG_IEEE80211W 01352 case WLAN_ACTION_SA_QUERY: 01353 hostapd_sa_query_action(hapd, mgmt, len); 01354 return; 01355 #endif /* CONFIG_IEEE80211W */ 01356 case WLAN_ACTION_PUBLIC: 01357 if (hapd->public_action_cb) { 01358 hapd->public_action_cb(hapd->public_action_cb_ctx, 01359 (u8 *) mgmt, len, 01360 hapd->iface->freq); 01361 return; 01362 } 01363 break; 01364 } 01365 01366 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 01367 HOSTAPD_LEVEL_DEBUG, 01368 "handle_action - unknown action category %d or invalid " 01369 "frame", 01370 mgmt->u.action.category); 01371 if (!(mgmt->da[0] & 0x01) && !(mgmt->u.action.category & 0x80) && 01372 !(mgmt->sa[0] & 0x01)) { 01373 struct ieee80211_mgmt *resp; 01374 01375 /* 01376 * IEEE 802.11-REVma/D9.0 - 7.3.1.11 01377 * Return the Action frame to the source without change 01378 * except that MSB of the Category set to 1. 01379 */ 01380 wpa_printf(MSG_DEBUG, "IEEE 802.11: Return unknown Action " 01381 "frame back to sender"); 01382 resp = os_malloc(len); 01383 if (resp == NULL) 01384 return; 01385 os_memcpy(resp, mgmt, len); 01386 os_memcpy(resp->da, resp->sa, ETH_ALEN); 01387 os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN); 01388 os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN); 01389 resp->u.action.category |= 0x80; 01390 01391 hapd->drv.send_mgmt_frame(hapd, resp, len); 01392 os_free(resp); 01393 } 01394 } 01395 01396 01410 void ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len, 01411 struct hostapd_frame_info *fi) 01412 { 01413 struct ieee80211_mgmt *mgmt; 01414 int broadcast; 01415 u16 fc, stype; 01416 01417 mgmt = (struct ieee80211_mgmt *) buf; 01418 fc = le_to_host16(mgmt->frame_control); 01419 stype = WLAN_FC_GET_STYPE(fc); 01420 01421 if (stype == WLAN_FC_STYPE_BEACON) { 01422 handle_beacon(hapd, mgmt, len, fi); 01423 return; 01424 } 01425 01426 broadcast = mgmt->bssid[0] == 0xff && mgmt->bssid[1] == 0xff && 01427 mgmt->bssid[2] == 0xff && mgmt->bssid[3] == 0xff && 01428 mgmt->bssid[4] == 0xff && mgmt->bssid[5] == 0xff; 01429 01430 if (!broadcast && 01431 os_memcmp(mgmt->bssid, hapd->own_addr, ETH_ALEN) != 0) { 01432 printf("MGMT: BSSID=" MACSTR " not our address\n", 01433 MAC2STR(mgmt->bssid)); 01434 return; 01435 } 01436 01437 01438 if (stype == WLAN_FC_STYPE_PROBE_REQ) { 01439 handle_probe_req(hapd, mgmt, len); 01440 return; 01441 } 01442 01443 if (os_memcmp(mgmt->da, hapd->own_addr, ETH_ALEN) != 0) { 01444 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 01445 HOSTAPD_LEVEL_DEBUG, 01446 "MGMT: DA=" MACSTR " not our address", 01447 MAC2STR(mgmt->da)); 01448 return; 01449 } 01450 01451 switch (stype) { 01452 case WLAN_FC_STYPE_AUTH: 01453 wpa_printf(MSG_DEBUG, "mgmt::auth"); 01454 handle_auth(hapd, mgmt, len); 01455 break; 01456 case WLAN_FC_STYPE_ASSOC_REQ: 01457 wpa_printf(MSG_DEBUG, "mgmt::assoc_req"); 01458 handle_assoc(hapd, mgmt, len, 0); 01459 break; 01460 case WLAN_FC_STYPE_REASSOC_REQ: 01461 wpa_printf(MSG_DEBUG, "mgmt::reassoc_req"); 01462 handle_assoc(hapd, mgmt, len, 1); 01463 break; 01464 case WLAN_FC_STYPE_DISASSOC: 01465 wpa_printf(MSG_DEBUG, "mgmt::disassoc"); 01466 handle_disassoc(hapd, mgmt, len); 01467 break; 01468 case WLAN_FC_STYPE_DEAUTH: 01469 wpa_printf(MSG_DEBUG, "mgmt::deauth"); 01470 handle_deauth(hapd, mgmt, len); 01471 break; 01472 case WLAN_FC_STYPE_ACTION: 01473 wpa_printf(MSG_DEBUG, "mgmt::action"); 01474 handle_action(hapd, mgmt, len); 01475 break; 01476 default: 01477 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 01478 HOSTAPD_LEVEL_DEBUG, 01479 "unknown mgmt frame subtype %d", stype); 01480 break; 01481 } 01482 } 01483 01484 01485 static void handle_auth_cb(struct hostapd_data *hapd, 01486 const struct ieee80211_mgmt *mgmt, 01487 size_t len, int ok) 01488 { 01489 u16 auth_alg, auth_transaction, status_code; 01490 struct sta_info *sta; 01491 01492 if (!ok) { 01493 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211, 01494 HOSTAPD_LEVEL_NOTICE, 01495 "did not acknowledge authentication response"); 01496 return; 01497 } 01498 01499 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { 01500 printf("handle_auth_cb - too short payload (len=%lu)\n", 01501 (unsigned long) len); 01502 return; 01503 } 01504 01505 auth_alg = le_to_host16(mgmt->u.auth.auth_alg); 01506 auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction); 01507 status_code = le_to_host16(mgmt->u.auth.status_code); 01508 01509 sta = ap_get_sta(hapd, mgmt->da); 01510 if (!sta) { 01511 printf("handle_auth_cb: STA " MACSTR " not found\n", 01512 MAC2STR(mgmt->da)); 01513 return; 01514 } 01515 01516 if (status_code == WLAN_STATUS_SUCCESS && 01517 ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) || 01518 (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) { 01519 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 01520 HOSTAPD_LEVEL_INFO, "authenticated"); 01521 sta->flags |= WLAN_STA_AUTH; 01522 } 01523 } 01524 01525 01526 static void handle_assoc_cb(struct hostapd_data *hapd, 01527 const struct ieee80211_mgmt *mgmt, 01528 size_t len, int reassoc, int ok) 01529 { 01530 u16 status; 01531 struct sta_info *sta; 01532 int new_assoc = 1; 01533 struct ieee80211_ht_capabilities ht_cap; 01534 01535 if (!ok) { 01536 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211, 01537 HOSTAPD_LEVEL_DEBUG, 01538 "did not acknowledge association response"); 01539 return; 01540 } 01541 01542 if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) : 01543 sizeof(mgmt->u.assoc_resp))) { 01544 printf("handle_assoc_cb(reassoc=%d) - too short payload " 01545 "(len=%lu)\n", reassoc, (unsigned long) len); 01546 return; 01547 } 01548 01549 if (reassoc) 01550 status = le_to_host16(mgmt->u.reassoc_resp.status_code); 01551 else 01552 status = le_to_host16(mgmt->u.assoc_resp.status_code); 01553 01554 sta = ap_get_sta(hapd, mgmt->da); 01555 if (!sta) { 01556 printf("handle_assoc_cb: STA " MACSTR " not found\n", 01557 MAC2STR(mgmt->da)); 01558 return; 01559 } 01560 01561 if (status != WLAN_STATUS_SUCCESS) 01562 goto fail; 01563 01564 /* Stop previous accounting session, if one is started, and allocate 01565 * new session id for the new session. */ 01566 accounting_sta_stop(hapd, sta); 01567 01568 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 01569 HOSTAPD_LEVEL_INFO, 01570 "associated (aid %d)", 01571 sta->aid); 01572 01573 if (sta->flags & WLAN_STA_ASSOC) 01574 new_assoc = 0; 01575 sta->flags |= WLAN_STA_ASSOC; 01576 if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa) || 01577 sta->auth_alg == WLAN_AUTH_FT) { 01578 /* 01579 * Open, static WEP, or FT protocol; no separate authorization 01580 * step. 01581 */ 01582 sta->flags |= WLAN_STA_AUTHORIZED; 01583 wpa_msg(hapd->msg_ctx, MSG_INFO, 01584 AP_STA_CONNECTED MACSTR, MAC2STR(sta->addr)); 01585 } 01586 01587 if (reassoc) 01588 mlme_reassociate_indication(hapd, sta); 01589 else 01590 mlme_associate_indication(hapd, sta); 01591 01592 #ifdef CONFIG_IEEE80211W 01593 sta->sa_query_timed_out = 0; 01594 #endif /* CONFIG_IEEE80211W */ 01595 01596 /* 01597 * Remove the STA entry in order to make sure the STA PS state gets 01598 * cleared and configuration gets updated in case of reassociation back 01599 * to the same AP. 01600 */ 01601 hapd->drv.sta_remove(hapd, sta->addr); 01602 01603 #ifdef CONFIG_IEEE80211N 01604 if (sta->flags & WLAN_STA_HT) 01605 hostapd_get_ht_capab(hapd, sta->ht_capabilities, &ht_cap); 01606 #endif /* CONFIG_IEEE80211N */ 01607 01608 if (hapd->drv.sta_add(hapd, sta->addr, sta->aid, sta->capability, 01609 sta->supported_rates, sta->supported_rates_len, 01610 sta->listen_interval, 01611 sta->flags & WLAN_STA_HT ? &ht_cap : NULL)) { 01612 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 01613 HOSTAPD_LEVEL_NOTICE, 01614 "Could not add STA to kernel driver"); 01615 } 01616 01617 if (sta->eapol_sm == NULL) { 01618 /* 01619 * This STA does not use RADIUS server for EAP authentication, 01620 * so bind it to the selected VLAN interface now, since the 01621 * interface selection is not going to change anymore. 01622 */ 01623 if (ap_sta_bind_vlan(hapd, sta, 0) < 0) 01624 goto fail; 01625 } else if (sta->vlan_id) { 01626 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */ 01627 if (ap_sta_bind_vlan(hapd, sta, 0) < 0) 01628 goto fail; 01629 } 01630 01631 hapd->drv.set_sta_flags(hapd, sta); 01632 01633 if (sta->auth_alg == WLAN_AUTH_FT) 01634 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT); 01635 else 01636 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC); 01637 hapd->new_assoc_sta_cb(hapd, sta, !new_assoc); 01638 01639 ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); 01640 01641 fail: 01642 /* Copy of the association request is not needed anymore */ 01643 if (sta->last_assoc_req) { 01644 os_free(sta->last_assoc_req); 01645 sta->last_assoc_req = NULL; 01646 } 01647 } 01648 01649 01659 void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len, 01660 u16 stype, int ok) 01661 { 01662 const struct ieee80211_mgmt *mgmt; 01663 mgmt = (const struct ieee80211_mgmt *) buf; 01664 01665 switch (stype) { 01666 case WLAN_FC_STYPE_AUTH: 01667 wpa_printf(MSG_DEBUG, "mgmt::auth cb"); 01668 handle_auth_cb(hapd, mgmt, len, ok); 01669 break; 01670 case WLAN_FC_STYPE_ASSOC_RESP: 01671 wpa_printf(MSG_DEBUG, "mgmt::assoc_resp cb"); 01672 handle_assoc_cb(hapd, mgmt, len, 0, ok); 01673 break; 01674 case WLAN_FC_STYPE_REASSOC_RESP: 01675 wpa_printf(MSG_DEBUG, "mgmt::reassoc_resp cb"); 01676 handle_assoc_cb(hapd, mgmt, len, 1, ok); 01677 break; 01678 case WLAN_FC_STYPE_PROBE_RESP: 01679 wpa_printf(MSG_DEBUG, "mgmt::proberesp cb"); 01680 break; 01681 case WLAN_FC_STYPE_DEAUTH: 01682 /* ignore */ 01683 break; 01684 case WLAN_FC_STYPE_ACTION: 01685 wpa_printf(MSG_DEBUG, "mgmt::action cb"); 01686 break; 01687 default: 01688 printf("unknown mgmt cb frame subtype %d\n", stype); 01689 break; 01690 } 01691 } 01692 01693 01694 int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen) 01695 { 01696 /* TODO */ 01697 return 0; 01698 } 01699 01700 01701 int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta, 01702 char *buf, size_t buflen) 01703 { 01704 /* TODO */ 01705 return 0; 01706 } 01707 01708 01709 void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr, 01710 const u8 *buf, size_t len, int ack) 01711 { 01712 struct sta_info *sta; 01713 struct hostapd_iface *iface = hapd->iface; 01714 01715 sta = ap_get_sta(hapd, addr); 01716 if (sta == NULL && iface->num_bss > 1) { 01717 size_t j; 01718 for (j = 0; j < iface->num_bss; j++) { 01719 hapd = iface->bss[j]; 01720 sta = ap_get_sta(hapd, addr); 01721 if (sta) 01722 break; 01723 } 01724 } 01725 if (sta == NULL) 01726 return; 01727 if (sta->flags & WLAN_STA_PENDING_POLL) { 01728 wpa_printf(MSG_DEBUG, "STA " MACSTR " %s pending " 01729 "activity poll", MAC2STR(sta->addr), 01730 ack ? "ACKed" : "did not ACK"); 01731 if (ack) 01732 sta->flags &= ~WLAN_STA_PENDING_POLL; 01733 } 01734 01735 ieee802_1x_tx_status(hapd, sta, buf, len, ack); 01736 } 01737 01738 01739 void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src, 01740 int wds) 01741 { 01742 struct sta_info *sta; 01743 01744 sta = ap_get_sta(hapd, src); 01745 if (sta && (sta->flags & WLAN_STA_ASSOC)) { 01746 if (wds && !(sta->flags & WLAN_STA_WDS)) { 01747 wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for " 01748 "STA " MACSTR " (aid %u)", 01749 MAC2STR(sta->addr), sta->aid); 01750 sta->flags |= WLAN_STA_WDS; 01751 hapd->drv.set_wds_sta(hapd, sta->addr, sta->aid, 1); 01752 } 01753 return; 01754 } 01755 01756 wpa_printf(MSG_DEBUG, "Data/PS-poll frame from not associated STA " 01757 MACSTR, MAC2STR(src)); 01758 if (sta && (sta->flags & WLAN_STA_AUTH)) 01759 hapd->drv.sta_disassoc( 01760 hapd, src, 01761 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); 01762 else 01763 hapd->drv.sta_deauth( 01764 hapd, src, 01765 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); 01766 } 01767 01768 01769 #endif /* CONFIG_NATIVE_WINDOWS */