$search
00001 /* 00002 * WPA Supplicant - Client mode MLME 00003 * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> 00004 * Copyright (c) 2004, Instant802 Networks, Inc. 00005 * Copyright (c) 2005-2006, Devicescape Software, Inc. 00006 * 00007 * This program is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License version 2 as 00009 * published by the Free Software Foundation. 00010 * 00011 * Alternatively, this software may be distributed under the terms of BSD 00012 * license. 00013 * 00014 * See README and COPYING for more details. 00015 */ 00016 00017 #include "includes.h" 00018 00019 #include "common.h" 00020 #include "eloop.h" 00021 #include "config_ssid.h" 00022 #include "wpa_supplicant_i.h" 00023 #include "notify.h" 00024 #include "driver_i.h" 00025 #include "rsn_supp/wpa.h" 00026 #include "common/ieee802_11_defs.h" 00027 #include "common/ieee802_11_common.h" 00028 #include "mlme.h" 00029 00030 00031 /* Timeouts and intervals in milliseconds */ 00032 #define IEEE80211_AUTH_TIMEOUT (200) 00033 #define IEEE80211_AUTH_MAX_TRIES 3 00034 #define IEEE80211_ASSOC_TIMEOUT (200) 00035 #define IEEE80211_ASSOC_MAX_TRIES 3 00036 #define IEEE80211_MONITORING_INTERVAL (2000) 00037 #define IEEE80211_PROBE_INTERVAL (60000) 00038 #define IEEE80211_RETRY_AUTH_INTERVAL (1000) 00039 #define IEEE80211_SCAN_INTERVAL (2000) 00040 #define IEEE80211_SCAN_INTERVAL_SLOW (15000) 00041 #define IEEE80211_IBSS_JOIN_TIMEOUT (20000) 00042 00043 #define IEEE80211_PROBE_DELAY (33) 00044 #define IEEE80211_CHANNEL_TIME (33) 00045 #define IEEE80211_PASSIVE_CHANNEL_TIME (200) 00046 #define IEEE80211_SCAN_RESULT_EXPIRE (10000) 00047 #define IEEE80211_IBSS_MERGE_INTERVAL (30000) 00048 #define IEEE80211_IBSS_INACTIVITY_LIMIT (60000) 00049 00050 #define IEEE80211_IBSS_MAX_STA_ENTRIES 128 00051 00052 00053 #define IEEE80211_FC(type, stype) host_to_le16((type << 2) | (stype << 4)) 00054 00055 00056 struct ieee80211_sta_bss { 00057 struct ieee80211_sta_bss *next; 00058 struct ieee80211_sta_bss *hnext; 00059 00060 u8 bssid[ETH_ALEN]; 00061 u8 ssid[MAX_SSID_LEN]; 00062 size_t ssid_len; 00063 u16 capability; /* host byte order */ 00064 int hw_mode; 00065 int channel; 00066 int freq; 00067 int rssi; 00068 u8 *ie; 00069 size_t ie_len; 00070 u8 *wpa_ie; 00071 size_t wpa_ie_len; 00072 u8 *rsn_ie; 00073 size_t rsn_ie_len; 00074 u8 *wmm_ie; 00075 size_t wmm_ie_len; 00076 u8 *mdie; 00077 size_t mdie_len; 00078 #define IEEE80211_MAX_SUPP_RATES 32 00079 u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; 00080 size_t supp_rates_len; 00081 int beacon_int; 00082 u64 timestamp; 00083 00084 int probe_resp; 00085 struct os_time last_update; 00086 }; 00087 00088 00089 static void ieee80211_send_probe_req(struct wpa_supplicant *wpa_s, 00090 const u8 *dst, 00091 const u8 *ssid, size_t ssid_len); 00092 static struct ieee80211_sta_bss * 00093 ieee80211_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid); 00094 static int ieee80211_sta_find_ibss(struct wpa_supplicant *wpa_s); 00095 static int ieee80211_sta_wep_configured(struct wpa_supplicant *wpa_s); 00096 static void ieee80211_sta_timer(void *eloop_ctx, void *timeout_ctx); 00097 static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx); 00098 static void ieee80211_build_tspec(struct wpabuf *buf); 00099 static int ieee80211_sta_set_probe_req_ie(struct wpa_supplicant *wpa_s, 00100 const u8 *ies, size_t ies_len); 00101 00102 00103 static int ieee80211_sta_set_channel(struct wpa_supplicant *wpa_s, 00104 enum hostapd_hw_mode phymode, int chan, 00105 int freq) 00106 { 00107 size_t i; 00108 struct hostapd_hw_modes *mode; 00109 00110 for (i = 0; i < wpa_s->mlme.num_modes; i++) { 00111 mode = &wpa_s->mlme.modes[i]; 00112 if (mode->mode == phymode) { 00113 wpa_s->mlme.curr_rates = mode->rates; 00114 wpa_s->mlme.num_curr_rates = mode->num_rates; 00115 break; 00116 } 00117 } 00118 00119 return wpa_drv_set_channel(wpa_s, phymode, chan, freq); 00120 } 00121 00122 00123 static int ecw2cw(int ecw) 00124 { 00125 int cw = 1; 00126 while (ecw > 0) { 00127 cw <<= 1; 00128 ecw--; 00129 } 00130 return cw - 1; 00131 } 00132 00133 00134 static void ieee80211_sta_wmm_params(struct wpa_supplicant *wpa_s, 00135 const u8 *wmm_param, size_t wmm_param_len) 00136 { 00137 size_t left; 00138 int count; 00139 const u8 *pos; 00140 u8 wmm_acm; 00141 00142 if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) 00143 return; 00144 count = wmm_param[6] & 0x0f; 00145 if (count == wpa_s->mlme.wmm_last_param_set) 00146 return; 00147 wpa_s->mlme.wmm_last_param_set = count; 00148 00149 pos = wmm_param + 8; 00150 left = wmm_param_len - 8; 00151 00152 wmm_acm = 0; 00153 for (; left >= 4; left -= 4, pos += 4) { 00154 int aci = (pos[0] >> 5) & 0x03; 00155 int acm = (pos[0] >> 4) & 0x01; 00156 int aifs, cw_max, cw_min, burst_time; 00157 00158 switch (aci) { 00159 case 1: /* AC_BK */ 00160 if (acm) 00161 wmm_acm |= BIT(1) | BIT(2); /* BK/- */ 00162 break; 00163 case 2: /* AC_VI */ 00164 if (acm) 00165 wmm_acm |= BIT(4) | BIT(5); /* CL/VI */ 00166 break; 00167 case 3: /* AC_VO */ 00168 if (acm) 00169 wmm_acm |= BIT(6) | BIT(7); /* VO/NC */ 00170 break; 00171 case 0: /* AC_BE */ 00172 default: 00173 if (acm) 00174 wmm_acm |= BIT(0) | BIT(3); /* BE/EE */ 00175 break; 00176 } 00177 00178 aifs = pos[0] & 0x0f; 00179 cw_max = ecw2cw((pos[1] & 0xf0) >> 4); 00180 cw_min = ecw2cw(pos[1] & 0x0f); 00181 /* TXOP is in units of 32 usec; burst_time in 0.1 ms */ 00182 burst_time = (pos[2] | (pos[3] << 8)) * 32 / 100; 00183 wpa_printf(MSG_DEBUG, "MLME: WMM aci=%d acm=%d aifs=%d " 00184 "cWmin=%d cWmax=%d burst=%d", 00185 aci, acm, aifs, cw_min, cw_max, burst_time); 00186 /* TODO: driver configuration */ 00187 } 00188 } 00189 00190 00191 static void ieee80211_set_associated(struct wpa_supplicant *wpa_s, int assoc) 00192 { 00193 if (wpa_s->mlme.associated == assoc && !assoc) 00194 return; 00195 00196 wpa_s->mlme.associated = assoc; 00197 00198 if (assoc) { 00199 union wpa_event_data data; 00200 os_memset(&data, 0, sizeof(data)); 00201 wpa_s->mlme.prev_bssid_set = 1; 00202 os_memcpy(wpa_s->mlme.prev_bssid, wpa_s->bssid, ETH_ALEN); 00203 data.assoc_info.req_ies = wpa_s->mlme.assocreq_ies; 00204 data.assoc_info.req_ies_len = wpa_s->mlme.assocreq_ies_len; 00205 data.assoc_info.resp_ies = wpa_s->mlme.assocresp_ies; 00206 data.assoc_info.resp_ies_len = wpa_s->mlme.assocresp_ies_len; 00207 data.assoc_info.freq = wpa_s->mlme.freq; 00208 wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data); 00209 } else { 00210 wpa_supplicant_event(wpa_s, EVENT_DISASSOC, NULL); 00211 } 00212 os_get_time(&wpa_s->mlme.last_probe); 00213 } 00214 00215 00216 static int ieee80211_sta_tx(struct wpa_supplicant *wpa_s, const u8 *buf, 00217 size_t len) 00218 { 00219 return wpa_drv_send_mlme(wpa_s, buf, len); 00220 } 00221 00222 00223 static void ieee80211_send_auth(struct wpa_supplicant *wpa_s, 00224 int transaction, const u8 *extra, 00225 size_t extra_len, int encrypt) 00226 { 00227 u8 *buf; 00228 size_t len; 00229 struct ieee80211_mgmt *mgmt; 00230 00231 buf = os_malloc(sizeof(*mgmt) + 6 + extra_len); 00232 if (buf == NULL) { 00233 wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for " 00234 "auth frame"); 00235 return; 00236 } 00237 00238 mgmt = (struct ieee80211_mgmt *) buf; 00239 len = 24 + 6; 00240 os_memset(mgmt, 0, 24 + 6); 00241 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 00242 WLAN_FC_STYPE_AUTH); 00243 if (encrypt) 00244 mgmt->frame_control |= host_to_le16(WLAN_FC_ISWEP); 00245 os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN); 00246 os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 00247 os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN); 00248 mgmt->u.auth.auth_alg = host_to_le16(wpa_s->mlme.auth_alg); 00249 mgmt->u.auth.auth_transaction = host_to_le16(transaction); 00250 wpa_s->mlme.auth_transaction = transaction + 1; 00251 mgmt->u.auth.status_code = host_to_le16(0); 00252 if (extra) { 00253 os_memcpy(buf + len, extra, extra_len); 00254 len += extra_len; 00255 } 00256 00257 ieee80211_sta_tx(wpa_s, buf, len); 00258 os_free(buf); 00259 } 00260 00261 00262 static void ieee80211_reschedule_timer(struct wpa_supplicant *wpa_s, int ms) 00263 { 00264 eloop_cancel_timeout(ieee80211_sta_timer, wpa_s, NULL); 00265 eloop_register_timeout(ms / 1000, 1000 * (ms % 1000), 00266 ieee80211_sta_timer, wpa_s, NULL); 00267 } 00268 00269 00270 static void ieee80211_authenticate(struct wpa_supplicant *wpa_s) 00271 { 00272 u8 *extra; 00273 size_t extra_len; 00274 00275 wpa_s->mlme.auth_tries++; 00276 if (wpa_s->mlme.auth_tries > IEEE80211_AUTH_MAX_TRIES) { 00277 wpa_printf(MSG_DEBUG, "MLME: authentication with AP " MACSTR 00278 " timed out", MAC2STR(wpa_s->bssid)); 00279 return; 00280 } 00281 00282 wpa_s->mlme.state = IEEE80211_AUTHENTICATE; 00283 wpa_printf(MSG_DEBUG, "MLME: authenticate with AP " MACSTR, 00284 MAC2STR(wpa_s->bssid)); 00285 00286 extra = NULL; 00287 extra_len = 0; 00288 00289 #ifdef CONFIG_IEEE80211R 00290 if ((wpa_s->mlme.key_mgmt == KEY_MGMT_FT_802_1X || 00291 wpa_s->mlme.key_mgmt == KEY_MGMT_FT_PSK) && 00292 wpa_s->mlme.ft_ies) { 00293 struct ieee80211_sta_bss *bss; 00294 struct rsn_mdie *mdie = NULL; 00295 bss = ieee80211_bss_get(wpa_s, wpa_s->bssid); 00296 if (bss && bss->mdie_len >= 2 + sizeof(*mdie)) 00297 mdie = (struct rsn_mdie *) (bss->mdie + 2); 00298 if (mdie && 00299 os_memcmp(mdie->mobility_domain, wpa_s->mlme.current_md, 00300 MOBILITY_DOMAIN_ID_LEN) == 0) { 00301 wpa_printf(MSG_DEBUG, "MLME: Trying to use FT " 00302 "over-the-air"); 00303 wpa_s->mlme.auth_alg = WLAN_AUTH_FT; 00304 extra = wpa_s->mlme.ft_ies; 00305 extra_len = wpa_s->mlme.ft_ies_len; 00306 } 00307 } 00308 #endif /* CONFIG_IEEE80211R */ 00309 00310 ieee80211_send_auth(wpa_s, 1, extra, extra_len, 0); 00311 00312 ieee80211_reschedule_timer(wpa_s, IEEE80211_AUTH_TIMEOUT); 00313 } 00314 00315 00316 static void ieee80211_send_assoc(struct wpa_supplicant *wpa_s) 00317 { 00318 struct ieee80211_mgmt *mgmt; 00319 u8 *pos, *ies, *buf; 00320 int i, len; 00321 u16 capab; 00322 struct ieee80211_sta_bss *bss; 00323 int wmm = 0; 00324 size_t blen, buflen; 00325 00326 if (wpa_s->mlme.curr_rates == NULL) { 00327 wpa_printf(MSG_DEBUG, "MLME: curr_rates not set for assoc"); 00328 return; 00329 } 00330 00331 buflen = sizeof(*mgmt) + 200 + wpa_s->mlme.extra_ie_len + 00332 wpa_s->mlme.ssid_len; 00333 #ifdef CONFIG_IEEE80211R 00334 if (wpa_s->mlme.ft_ies) 00335 buflen += wpa_s->mlme.ft_ies_len; 00336 #endif /* CONFIG_IEEE80211R */ 00337 buf = os_malloc(buflen); 00338 if (buf == NULL) { 00339 wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for " 00340 "assoc frame"); 00341 return; 00342 } 00343 blen = 0; 00344 00345 capab = wpa_s->mlme.capab; 00346 if (wpa_s->mlme.phymode == HOSTAPD_MODE_IEEE80211G) { 00347 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME | 00348 WLAN_CAPABILITY_SHORT_PREAMBLE; 00349 } 00350 bss = ieee80211_bss_get(wpa_s, wpa_s->bssid); 00351 if (bss) { 00352 if (bss->capability & WLAN_CAPABILITY_PRIVACY) 00353 capab |= WLAN_CAPABILITY_PRIVACY; 00354 if (bss->wmm_ie) { 00355 wmm = 1; 00356 } 00357 } 00358 00359 mgmt = (struct ieee80211_mgmt *) buf; 00360 blen += 24; 00361 os_memset(mgmt, 0, 24); 00362 os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN); 00363 os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 00364 os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN); 00365 00366 if (wpa_s->mlme.prev_bssid_set) { 00367 blen += 10; 00368 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 00369 WLAN_FC_STYPE_REASSOC_REQ); 00370 mgmt->u.reassoc_req.capab_info = host_to_le16(capab); 00371 mgmt->u.reassoc_req.listen_interval = host_to_le16(1); 00372 os_memcpy(mgmt->u.reassoc_req.current_ap, 00373 wpa_s->mlme.prev_bssid, 00374 ETH_ALEN); 00375 } else { 00376 blen += 4; 00377 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 00378 WLAN_FC_STYPE_ASSOC_REQ); 00379 mgmt->u.assoc_req.capab_info = host_to_le16(capab); 00380 mgmt->u.assoc_req.listen_interval = host_to_le16(1); 00381 } 00382 00383 /* SSID */ 00384 ies = pos = buf + blen; 00385 blen += 2 + wpa_s->mlme.ssid_len; 00386 *pos++ = WLAN_EID_SSID; 00387 *pos++ = wpa_s->mlme.ssid_len; 00388 os_memcpy(pos, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len); 00389 00390 len = wpa_s->mlme.num_curr_rates; 00391 if (len > 8) 00392 len = 8; 00393 pos = buf + blen; 00394 blen += len + 2; 00395 *pos++ = WLAN_EID_SUPP_RATES; 00396 *pos++ = len; 00397 for (i = 0; i < len; i++) 00398 *pos++ = (u8) (wpa_s->mlme.curr_rates[i] / 5); 00399 00400 if (wpa_s->mlme.num_curr_rates > len) { 00401 pos = buf + blen; 00402 blen += wpa_s->mlme.num_curr_rates - len + 2; 00403 *pos++ = WLAN_EID_EXT_SUPP_RATES; 00404 *pos++ = wpa_s->mlme.num_curr_rates - len; 00405 for (i = len; i < wpa_s->mlme.num_curr_rates; i++) 00406 *pos++ = (u8) (wpa_s->mlme.curr_rates[i] / 5); 00407 } 00408 00409 if (wpa_s->mlme.extra_ie && wpa_s->mlme.auth_alg != WLAN_AUTH_FT) { 00410 pos = buf + blen; 00411 blen += wpa_s->mlme.extra_ie_len; 00412 os_memcpy(pos, wpa_s->mlme.extra_ie, wpa_s->mlme.extra_ie_len); 00413 } 00414 00415 #ifdef CONFIG_IEEE80211R 00416 if ((wpa_s->mlme.key_mgmt == KEY_MGMT_FT_802_1X || 00417 wpa_s->mlme.key_mgmt == KEY_MGMT_FT_PSK) && 00418 wpa_s->mlme.auth_alg != WLAN_AUTH_FT && 00419 bss && bss->mdie && 00420 bss->mdie_len >= 2 + sizeof(struct rsn_mdie) && 00421 bss->mdie[1] >= sizeof(struct rsn_mdie)) { 00422 pos = buf + blen; 00423 blen += 2 + sizeof(struct rsn_mdie); 00424 *pos++ = WLAN_EID_MOBILITY_DOMAIN; 00425 *pos++ = sizeof(struct rsn_mdie); 00426 os_memcpy(pos, bss->mdie + 2, MOBILITY_DOMAIN_ID_LEN); 00427 pos += MOBILITY_DOMAIN_ID_LEN; 00428 *pos++ = 0; /* FIX: copy from the target AP's MDIE */ 00429 } 00430 00431 if ((wpa_s->mlme.key_mgmt == KEY_MGMT_FT_802_1X || 00432 wpa_s->mlme.key_mgmt == KEY_MGMT_FT_PSK) && 00433 wpa_s->mlme.auth_alg == WLAN_AUTH_FT && wpa_s->mlme.ft_ies) { 00434 pos = buf + blen; 00435 os_memcpy(pos, wpa_s->mlme.ft_ies, wpa_s->mlme.ft_ies_len); 00436 pos += wpa_s->mlme.ft_ies_len; 00437 blen += wpa_s->mlme.ft_ies_len; 00438 } 00439 #endif /* CONFIG_IEEE80211R */ 00440 00441 if (wmm && wpa_s->mlme.wmm_enabled) { 00442 pos = buf + blen; 00443 blen += 9; 00444 *pos++ = WLAN_EID_VENDOR_SPECIFIC; 00445 *pos++ = 7; /* len */ 00446 *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */ 00447 *pos++ = 0x50; 00448 *pos++ = 0xf2; 00449 *pos++ = 2; /* WMM */ 00450 *pos++ = 0; /* WMM info */ 00451 *pos++ = 1; /* WMM ver */ 00452 *pos++ = 0; 00453 } 00454 00455 os_free(wpa_s->mlme.assocreq_ies); 00456 wpa_s->mlme.assocreq_ies_len = (buf + blen) - ies; 00457 wpa_s->mlme.assocreq_ies = os_malloc(wpa_s->mlme.assocreq_ies_len); 00458 if (wpa_s->mlme.assocreq_ies) { 00459 os_memcpy(wpa_s->mlme.assocreq_ies, ies, 00460 wpa_s->mlme.assocreq_ies_len); 00461 } 00462 00463 ieee80211_sta_tx(wpa_s, buf, blen); 00464 os_free(buf); 00465 } 00466 00467 00468 static void ieee80211_send_deauth(struct wpa_supplicant *wpa_s, u16 reason) 00469 { 00470 u8 *buf; 00471 size_t len; 00472 struct ieee80211_mgmt *mgmt; 00473 00474 buf = os_zalloc(sizeof(*mgmt)); 00475 if (buf == NULL) { 00476 wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for " 00477 "deauth frame"); 00478 return; 00479 } 00480 00481 mgmt = (struct ieee80211_mgmt *) buf; 00482 len = 24; 00483 os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN); 00484 os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 00485 os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN); 00486 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 00487 WLAN_FC_STYPE_DEAUTH); 00488 len += 2; 00489 mgmt->u.deauth.reason_code = host_to_le16(reason); 00490 00491 ieee80211_sta_tx(wpa_s, buf, len); 00492 os_free(buf); 00493 } 00494 00495 00496 static void ieee80211_send_disassoc(struct wpa_supplicant *wpa_s, u16 reason) 00497 { 00498 u8 *buf; 00499 size_t len; 00500 struct ieee80211_mgmt *mgmt; 00501 00502 buf = os_zalloc(sizeof(*mgmt)); 00503 if (buf == NULL) { 00504 wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for " 00505 "disassoc frame"); 00506 return; 00507 } 00508 00509 mgmt = (struct ieee80211_mgmt *) buf; 00510 len = 24; 00511 os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN); 00512 os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 00513 os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN); 00514 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 00515 WLAN_FC_STYPE_DISASSOC); 00516 len += 2; 00517 mgmt->u.disassoc.reason_code = host_to_le16(reason); 00518 00519 ieee80211_sta_tx(wpa_s, buf, len); 00520 os_free(buf); 00521 } 00522 00523 00524 static int ieee80211_privacy_mismatch(struct wpa_supplicant *wpa_s) 00525 { 00526 struct ieee80211_sta_bss *bss; 00527 int res = 0; 00528 00529 if (wpa_s->mlme.mixed_cell || 00530 wpa_s->mlme.key_mgmt != KEY_MGMT_NONE) 00531 return 0; 00532 00533 bss = ieee80211_bss_get(wpa_s, wpa_s->bssid); 00534 if (bss == NULL) 00535 return 0; 00536 00537 if (ieee80211_sta_wep_configured(wpa_s) != 00538 !!(bss->capability & WLAN_CAPABILITY_PRIVACY)) 00539 res = 1; 00540 00541 return res; 00542 } 00543 00544 00545 static void ieee80211_associate(struct wpa_supplicant *wpa_s) 00546 { 00547 wpa_s->mlme.assoc_tries++; 00548 if (wpa_s->mlme.assoc_tries > IEEE80211_ASSOC_MAX_TRIES) { 00549 wpa_printf(MSG_DEBUG, "MLME: association with AP " MACSTR 00550 " timed out", MAC2STR(wpa_s->bssid)); 00551 return; 00552 } 00553 00554 wpa_s->mlme.state = IEEE80211_ASSOCIATE; 00555 wpa_printf(MSG_DEBUG, "MLME: associate with AP " MACSTR, 00556 MAC2STR(wpa_s->bssid)); 00557 if (ieee80211_privacy_mismatch(wpa_s)) { 00558 wpa_printf(MSG_DEBUG, "MLME: mismatch in privacy " 00559 "configuration and mixed-cell disabled - abort " 00560 "association"); 00561 return; 00562 } 00563 00564 ieee80211_send_assoc(wpa_s); 00565 00566 ieee80211_reschedule_timer(wpa_s, IEEE80211_ASSOC_TIMEOUT); 00567 } 00568 00569 00570 static void ieee80211_associated(struct wpa_supplicant *wpa_s) 00571 { 00572 int disassoc; 00573 00574 /* TODO: start monitoring current AP signal quality and number of 00575 * missed beacons. Scan other channels every now and then and search 00576 * for better APs. */ 00577 /* TODO: remove expired BSSes */ 00578 00579 wpa_s->mlme.state = IEEE80211_ASSOCIATED; 00580 00581 #if 0 /* FIX */ 00582 sta = sta_info_get(local, wpa_s->bssid); 00583 if (sta == NULL) { 00584 wpa_printf(MSG_DEBUG "MLME: No STA entry for own AP " MACSTR, 00585 MAC2STR(wpa_s->bssid)); 00586 disassoc = 1; 00587 } else { 00588 disassoc = 0; 00589 if (time_after(jiffies, 00590 sta->last_rx + IEEE80211_MONITORING_INTERVAL)) { 00591 if (wpa_s->mlme.probereq_poll) { 00592 wpa_printf(MSG_DEBUG "MLME: No ProbeResp from " 00593 "current AP " MACSTR " - assume " 00594 "out of range", 00595 MAC2STR(wpa_s->bssid)); 00596 disassoc = 1; 00597 } else { 00598 ieee80211_send_probe_req( 00599 wpa_s->bssid, 00600 wpa_s->mlme.scan_ssid, 00601 wpa_s->mlme.scan_ssid_len); 00602 wpa_s->mlme.probereq_poll = 1; 00603 } 00604 } else { 00605 wpa_s->mlme.probereq_poll = 0; 00606 if (time_after(jiffies, wpa_s->mlme.last_probe + 00607 IEEE80211_PROBE_INTERVAL)) { 00608 wpa_s->mlme.last_probe = jiffies; 00609 ieee80211_send_probe_req(wpa_s->bssid, 00610 wpa_s->mlme.ssid, 00611 wpa_s->mlme.ssid_len); 00612 } 00613 } 00614 sta_info_release(local, sta); 00615 } 00616 #else 00617 disassoc = 0; 00618 #endif 00619 if (disassoc) { 00620 wpa_supplicant_event(wpa_s, EVENT_DISASSOC, NULL); 00621 ieee80211_reschedule_timer(wpa_s, 00622 IEEE80211_MONITORING_INTERVAL + 00623 30000); 00624 } else { 00625 ieee80211_reschedule_timer(wpa_s, 00626 IEEE80211_MONITORING_INTERVAL); 00627 } 00628 } 00629 00630 00631 static void ieee80211_send_probe_req(struct wpa_supplicant *wpa_s, 00632 const u8 *dst, 00633 const u8 *ssid, size_t ssid_len) 00634 { 00635 u8 *buf; 00636 size_t len; 00637 struct ieee80211_mgmt *mgmt; 00638 u8 *pos, *supp_rates; 00639 u8 *esupp_rates = NULL; 00640 int i; 00641 00642 buf = os_malloc(sizeof(*mgmt) + 200 + wpa_s->mlme.extra_probe_ie_len); 00643 if (buf == NULL) { 00644 wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for " 00645 "probe request"); 00646 return; 00647 } 00648 00649 mgmt = (struct ieee80211_mgmt *) buf; 00650 len = 24; 00651 os_memset(mgmt, 0, 24); 00652 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 00653 WLAN_FC_STYPE_PROBE_REQ); 00654 os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 00655 if (dst) { 00656 os_memcpy(mgmt->da, dst, ETH_ALEN); 00657 os_memcpy(mgmt->bssid, dst, ETH_ALEN); 00658 } else { 00659 os_memset(mgmt->da, 0xff, ETH_ALEN); 00660 os_memset(mgmt->bssid, 0xff, ETH_ALEN); 00661 } 00662 pos = buf + len; 00663 len += 2 + ssid_len; 00664 *pos++ = WLAN_EID_SSID; 00665 *pos++ = ssid_len; 00666 os_memcpy(pos, ssid, ssid_len); 00667 00668 supp_rates = buf + len; 00669 len += 2; 00670 supp_rates[0] = WLAN_EID_SUPP_RATES; 00671 supp_rates[1] = 0; 00672 for (i = 0; i < wpa_s->mlme.num_curr_rates; i++) { 00673 if (esupp_rates) { 00674 pos = buf + len; 00675 len++; 00676 esupp_rates[1]++; 00677 } else if (supp_rates[1] == 8) { 00678 esupp_rates = pos; 00679 esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES; 00680 esupp_rates[1] = 1; 00681 pos = &esupp_rates[2]; 00682 len += 3; 00683 } else { 00684 pos = buf + len; 00685 len++; 00686 supp_rates[1]++; 00687 } 00688 *pos++ = wpa_s->mlme.curr_rates[i] / 5; 00689 } 00690 00691 if (wpa_s->mlme.extra_probe_ie) { 00692 os_memcpy(pos, wpa_s->mlme.extra_probe_ie, 00693 wpa_s->mlme.extra_probe_ie_len); 00694 len += wpa_s->mlme.extra_probe_ie_len; 00695 } 00696 00697 ieee80211_sta_tx(wpa_s, buf, len); 00698 os_free(buf); 00699 } 00700 00701 00702 static int ieee80211_sta_wep_configured(struct wpa_supplicant *wpa_s) 00703 { 00704 #if 0 /* FIX */ 00705 if (sdata == NULL || sdata->default_key == NULL || 00706 sdata->default_key->alg != ALG_WEP) 00707 return 0; 00708 return 1; 00709 #else 00710 return 0; 00711 #endif 00712 } 00713 00714 00715 static void ieee80211_auth_completed(struct wpa_supplicant *wpa_s) 00716 { 00717 wpa_printf(MSG_DEBUG, "MLME: authenticated"); 00718 wpa_s->mlme.authenticated = 1; 00719 ieee80211_associate(wpa_s); 00720 } 00721 00722 00723 static void ieee80211_auth_challenge(struct wpa_supplicant *wpa_s, 00724 struct ieee80211_mgmt *mgmt, 00725 size_t len, 00726 struct ieee80211_rx_status *rx_status) 00727 { 00728 u8 *pos; 00729 struct ieee802_11_elems elems; 00730 00731 wpa_printf(MSG_DEBUG, "MLME: replying to auth challenge"); 00732 pos = mgmt->u.auth.variable; 00733 if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems, 0) 00734 == ParseFailed) { 00735 wpa_printf(MSG_DEBUG, "MLME: failed to parse Auth(challenge)"); 00736 return; 00737 } 00738 if (elems.challenge == NULL) { 00739 wpa_printf(MSG_DEBUG, "MLME: no challenge IE in shared key " 00740 "auth frame"); 00741 return; 00742 } 00743 ieee80211_send_auth(wpa_s, 3, elems.challenge - 2, 00744 elems.challenge_len + 2, 1); 00745 } 00746 00747 00748 static void ieee80211_rx_mgmt_auth(struct wpa_supplicant *wpa_s, 00749 struct ieee80211_mgmt *mgmt, 00750 size_t len, 00751 struct ieee80211_rx_status *rx_status) 00752 { 00753 struct wpa_ssid *ssid = wpa_s->current_ssid; 00754 u16 auth_alg, auth_transaction, status_code; 00755 int adhoc; 00756 00757 adhoc = ssid && ssid->mode == WPAS_MODE_IBSS; 00758 00759 if (wpa_s->mlme.state != IEEE80211_AUTHENTICATE && !adhoc) { 00760 wpa_printf(MSG_DEBUG, "MLME: authentication frame received " 00761 "from " MACSTR ", but not in authenticate state - " 00762 "ignored", MAC2STR(mgmt->sa)); 00763 return; 00764 } 00765 00766 if (len < 24 + 6) { 00767 wpa_printf(MSG_DEBUG, "MLME: too short (%lu) authentication " 00768 "frame received from " MACSTR " - ignored", 00769 (unsigned long) len, MAC2STR(mgmt->sa)); 00770 return; 00771 } 00772 00773 if (!adhoc && os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) { 00774 wpa_printf(MSG_DEBUG, "MLME: authentication frame received " 00775 "from unknown AP (SA=" MACSTR " BSSID=" MACSTR 00776 ") - ignored", 00777 MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid)); 00778 return; 00779 } 00780 00781 if (adhoc && os_memcmp(wpa_s->bssid, mgmt->bssid, ETH_ALEN) != 0) { 00782 wpa_printf(MSG_DEBUG, "MLME: authentication frame received " 00783 "from unknown BSSID (SA=" MACSTR " BSSID=" MACSTR 00784 ") - ignored", 00785 MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid)); 00786 return; 00787 } 00788 00789 auth_alg = le_to_host16(mgmt->u.auth.auth_alg); 00790 auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction); 00791 status_code = le_to_host16(mgmt->u.auth.status_code); 00792 00793 wpa_printf(MSG_DEBUG, "MLME: RX authentication from " MACSTR 00794 " (alg=%d transaction=%d status=%d)", 00795 MAC2STR(mgmt->sa), auth_alg, auth_transaction, status_code); 00796 00797 if (adhoc) { 00798 /* IEEE 802.11 standard does not require authentication in IBSS 00799 * networks and most implementations do not seem to use it. 00800 * However, try to reply to authentication attempts if someone 00801 * has actually implemented this. 00802 * TODO: Could implement shared key authentication. */ 00803 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) { 00804 wpa_printf(MSG_DEBUG, "MLME: unexpected IBSS " 00805 "authentication frame (alg=%d " 00806 "transaction=%d)", 00807 auth_alg, auth_transaction); 00808 return; 00809 } 00810 ieee80211_send_auth(wpa_s, 2, NULL, 0, 0); 00811 } 00812 00813 if (auth_alg != wpa_s->mlme.auth_alg || 00814 auth_transaction != wpa_s->mlme.auth_transaction) { 00815 wpa_printf(MSG_DEBUG, "MLME: unexpected authentication frame " 00816 "(alg=%d transaction=%d)", 00817 auth_alg, auth_transaction); 00818 return; 00819 } 00820 00821 if (status_code != WLAN_STATUS_SUCCESS) { 00822 wpa_printf(MSG_DEBUG, "MLME: AP denied authentication " 00823 "(auth_alg=%d code=%d)", wpa_s->mlme.auth_alg, 00824 status_code); 00825 if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) { 00826 const int num_algs = 3; 00827 u8 algs[num_algs]; 00828 int i, pos; 00829 algs[0] = algs[1] = algs[2] = 0xff; 00830 if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_OPEN) 00831 algs[0] = WLAN_AUTH_OPEN; 00832 if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_SHARED) 00833 algs[1] = WLAN_AUTH_SHARED_KEY; 00834 if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_LEAP) 00835 algs[2] = WLAN_AUTH_LEAP; 00836 if (wpa_s->mlme.auth_alg == WLAN_AUTH_OPEN) 00837 pos = 0; 00838 else if (wpa_s->mlme.auth_alg == WLAN_AUTH_SHARED_KEY) 00839 pos = 1; 00840 else 00841 pos = 2; 00842 for (i = 0; i < num_algs; i++) { 00843 pos++; 00844 if (pos >= num_algs) 00845 pos = 0; 00846 if (algs[pos] == wpa_s->mlme.auth_alg || 00847 algs[pos] == 0xff) 00848 continue; 00849 if (algs[pos] == WLAN_AUTH_SHARED_KEY && 00850 !ieee80211_sta_wep_configured(wpa_s)) 00851 continue; 00852 wpa_s->mlme.auth_alg = algs[pos]; 00853 wpa_printf(MSG_DEBUG, "MLME: set auth_alg=%d " 00854 "for next try", 00855 wpa_s->mlme.auth_alg); 00856 break; 00857 } 00858 } 00859 return; 00860 } 00861 00862 switch (wpa_s->mlme.auth_alg) { 00863 case WLAN_AUTH_OPEN: 00864 case WLAN_AUTH_LEAP: 00865 ieee80211_auth_completed(wpa_s); 00866 break; 00867 case WLAN_AUTH_SHARED_KEY: 00868 if (wpa_s->mlme.auth_transaction == 4) 00869 ieee80211_auth_completed(wpa_s); 00870 else 00871 ieee80211_auth_challenge(wpa_s, mgmt, len, 00872 rx_status); 00873 break; 00874 #ifdef CONFIG_IEEE80211R 00875 case WLAN_AUTH_FT: 00876 { 00877 union wpa_event_data data; 00878 struct wpabuf *ric = NULL; 00879 os_memset(&data, 0, sizeof(data)); 00880 data.ft_ies.ies = mgmt->u.auth.variable; 00881 data.ft_ies.ies_len = len - 00882 (mgmt->u.auth.variable - (u8 *) mgmt); 00883 os_memcpy(data.ft_ies.target_ap, wpa_s->bssid, ETH_ALEN); 00884 if (os_strcmp(wpa_s->driver->name, "test") == 0 && 00885 wpa_s->mlme.wmm_enabled) { 00886 ric = wpabuf_alloc(200); 00887 if (ric) { 00888 /* Build simple RIC-Request: RDIE | TSPEC */ 00889 00890 /* RIC Data (RDIE) */ 00891 wpabuf_put_u8(ric, WLAN_EID_RIC_DATA); 00892 wpabuf_put_u8(ric, 4); 00893 wpabuf_put_u8(ric, 0); /* RDIE Identifier */ 00894 wpabuf_put_u8(ric, 1); /* Resource Descriptor 00895 * Count */ 00896 wpabuf_put_le16(ric, 0); /* Status Code */ 00897 00898 /* WMM TSPEC */ 00899 ieee80211_build_tspec(ric); 00900 00901 data.ft_ies.ric_ies = wpabuf_head(ric); 00902 data.ft_ies.ric_ies_len = wpabuf_len(ric); 00903 } 00904 } 00905 00906 wpa_supplicant_event(wpa_s, EVENT_FT_RESPONSE, &data); 00907 wpabuf_free(ric); 00908 ieee80211_auth_completed(wpa_s); 00909 break; 00910 } 00911 #endif /* CONFIG_IEEE80211R */ 00912 } 00913 } 00914 00915 00916 static void ieee80211_rx_mgmt_deauth(struct wpa_supplicant *wpa_s, 00917 struct ieee80211_mgmt *mgmt, 00918 size_t len, 00919 struct ieee80211_rx_status *rx_status) 00920 { 00921 u16 reason_code; 00922 00923 if (len < 24 + 2) { 00924 wpa_printf(MSG_DEBUG, "MLME: too short (%lu) deauthentication " 00925 "frame received from " MACSTR " - ignored", 00926 (unsigned long) len, MAC2STR(mgmt->sa)); 00927 return; 00928 } 00929 00930 if (os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) { 00931 wpa_printf(MSG_DEBUG, "MLME: deauthentication frame received " 00932 "from unknown AP (SA=" MACSTR " BSSID=" MACSTR 00933 ") - ignored", 00934 MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid)); 00935 return; 00936 } 00937 00938 reason_code = le_to_host16(mgmt->u.deauth.reason_code); 00939 00940 wpa_printf(MSG_DEBUG, "MLME: RX deauthentication from " MACSTR 00941 " (reason=%d)", MAC2STR(mgmt->sa), reason_code); 00942 00943 if (wpa_s->mlme.authenticated) 00944 wpa_printf(MSG_DEBUG, "MLME: deauthenticated"); 00945 00946 if (wpa_s->mlme.state == IEEE80211_AUTHENTICATE || 00947 wpa_s->mlme.state == IEEE80211_ASSOCIATE || 00948 wpa_s->mlme.state == IEEE80211_ASSOCIATED) { 00949 wpa_s->mlme.state = IEEE80211_AUTHENTICATE; 00950 ieee80211_reschedule_timer(wpa_s, 00951 IEEE80211_RETRY_AUTH_INTERVAL); 00952 } 00953 00954 ieee80211_set_associated(wpa_s, 0); 00955 wpa_s->mlme.authenticated = 0; 00956 } 00957 00958 00959 static void ieee80211_rx_mgmt_disassoc(struct wpa_supplicant *wpa_s, 00960 struct ieee80211_mgmt *mgmt, 00961 size_t len, 00962 struct ieee80211_rx_status *rx_status) 00963 { 00964 u16 reason_code; 00965 00966 if (len < 24 + 2) { 00967 wpa_printf(MSG_DEBUG, "MLME: too short (%lu) disassociation " 00968 "frame received from " MACSTR " - ignored", 00969 (unsigned long) len, MAC2STR(mgmt->sa)); 00970 return; 00971 } 00972 00973 if (os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) { 00974 wpa_printf(MSG_DEBUG, "MLME: disassociation frame received " 00975 "from unknown AP (SA=" MACSTR " BSSID=" MACSTR 00976 ") - ignored", 00977 MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid)); 00978 return; 00979 } 00980 00981 reason_code = le_to_host16(mgmt->u.disassoc.reason_code); 00982 00983 wpa_printf(MSG_DEBUG, "MLME: RX disassociation from " MACSTR 00984 " (reason=%d)", MAC2STR(mgmt->sa), reason_code); 00985 00986 if (wpa_s->mlme.associated) 00987 wpa_printf(MSG_DEBUG, "MLME: disassociated"); 00988 00989 if (wpa_s->mlme.state == IEEE80211_ASSOCIATED) { 00990 wpa_s->mlme.state = IEEE80211_ASSOCIATE; 00991 ieee80211_reschedule_timer(wpa_s, 00992 IEEE80211_RETRY_AUTH_INTERVAL); 00993 } 00994 00995 ieee80211_set_associated(wpa_s, 0); 00996 } 00997 00998 00999 static void ieee80211_build_tspec(struct wpabuf *buf) 01000 { 01001 struct wmm_tspec_element *tspec; 01002 int tid, up; 01003 01004 tspec = wpabuf_put(buf, sizeof(*tspec)); 01005 tspec->eid = WLAN_EID_VENDOR_SPECIFIC; 01006 tspec->length = sizeof(*tspec) - 2; 01007 tspec->oui[0] = 0x00; 01008 tspec->oui[1] = 0x50; 01009 tspec->oui[2] = 0xf2; 01010 tspec->oui_type = 2; 01011 tspec->oui_subtype = 2; 01012 tspec->version = 1; 01013 01014 tid = 1; 01015 up = 6; /* Voice */ 01016 tspec->ts_info[0] = (tid << 1) | 01017 (WMM_TSPEC_DIRECTION_BI_DIRECTIONAL << 5) | 01018 BIT(7); 01019 tspec->ts_info[1] = up << 3; 01020 tspec->nominal_msdu_size = host_to_le16(1530); 01021 tspec->mean_data_rate = host_to_le32(128000); /* bits per second */ 01022 tspec->minimum_phy_rate = host_to_le32(6000000); 01023 tspec->surplus_bandwidth_allowance = host_to_le16(0x3000); /* 150% */ 01024 } 01025 01026 01027 static void ieee80211_tx_addts(struct wpa_supplicant *wpa_s) 01028 { 01029 struct wpabuf *buf; 01030 struct ieee80211_mgmt *mgmt; 01031 size_t alen; 01032 01033 wpa_printf(MSG_DEBUG, "MLME: Send ADDTS Request for Voice TSPEC"); 01034 mgmt = NULL; 01035 alen = mgmt->u.action.u.wmm_action.variable - (u8 *) mgmt; 01036 01037 buf = wpabuf_alloc(alen + sizeof(struct wmm_tspec_element)); 01038 if (buf == NULL) 01039 return; 01040 01041 mgmt = wpabuf_put(buf, alen); 01042 os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN); 01043 os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 01044 os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN); 01045 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 01046 WLAN_FC_STYPE_ACTION); 01047 mgmt->u.action.category = WLAN_ACTION_WMM; 01048 mgmt->u.action.u.wmm_action.action_code = WMM_ACTION_CODE_ADDTS_REQ; 01049 mgmt->u.action.u.wmm_action.dialog_token = 1; 01050 mgmt->u.action.u.wmm_action.status_code = 0; 01051 01052 ieee80211_build_tspec(buf); 01053 01054 ieee80211_sta_tx(wpa_s, wpabuf_head(buf), wpabuf_len(buf)); 01055 wpabuf_free(buf); 01056 } 01057 01058 01059 static void ieee80211_rx_mgmt_assoc_resp(struct wpa_supplicant *wpa_s, 01060 struct ieee80211_mgmt *mgmt, 01061 size_t len, 01062 struct ieee80211_rx_status *rx_status, 01063 int reassoc) 01064 { 01065 u8 rates[32]; 01066 size_t rates_len; 01067 u16 capab_info, status_code, aid; 01068 struct ieee802_11_elems elems; 01069 u8 *pos; 01070 01071 /* AssocResp and ReassocResp have identical structure, so process both 01072 * of them in this function. */ 01073 01074 if (wpa_s->mlme.state != IEEE80211_ASSOCIATE) { 01075 wpa_printf(MSG_DEBUG, "MLME: association frame received from " 01076 MACSTR ", but not in associate state - ignored", 01077 MAC2STR(mgmt->sa)); 01078 return; 01079 } 01080 01081 if (len < 24 + 6) { 01082 wpa_printf(MSG_DEBUG, "MLME: too short (%lu) association " 01083 "frame received from " MACSTR " - ignored", 01084 (unsigned long) len, MAC2STR(mgmt->sa)); 01085 return; 01086 } 01087 01088 if (os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) { 01089 wpa_printf(MSG_DEBUG, "MLME: association frame received from " 01090 "unknown AP (SA=" MACSTR " BSSID=" MACSTR ") - " 01091 "ignored", MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid)); 01092 return; 01093 } 01094 01095 capab_info = le_to_host16(mgmt->u.assoc_resp.capab_info); 01096 status_code = le_to_host16(mgmt->u.assoc_resp.status_code); 01097 aid = le_to_host16(mgmt->u.assoc_resp.aid); 01098 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) 01099 wpa_printf(MSG_DEBUG, "MLME: invalid aid value %d; bits 15:14 " 01100 "not set", aid); 01101 aid &= ~(BIT(15) | BIT(14)); 01102 01103 wpa_printf(MSG_DEBUG, "MLME: RX %sssocResp from " MACSTR 01104 " (capab=0x%x status=%d aid=%d)", 01105 reassoc ? "Rea" : "A", MAC2STR(mgmt->sa), 01106 capab_info, status_code, aid); 01107 01108 pos = mgmt->u.assoc_resp.variable; 01109 if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems, 0) 01110 == ParseFailed) { 01111 wpa_printf(MSG_DEBUG, "MLME: failed to parse AssocResp"); 01112 return; 01113 } 01114 01115 if (status_code != WLAN_STATUS_SUCCESS) { 01116 wpa_printf(MSG_DEBUG, "MLME: AP denied association (code=%d)", 01117 status_code); 01118 #ifdef CONFIG_IEEE80211W 01119 if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY && 01120 elems.timeout_int && elems.timeout_int_len == 5 && 01121 elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) { 01122 u32 tu, ms; 01123 tu = WPA_GET_LE32(elems.timeout_int + 1); 01124 ms = tu * 1024 / 1000; 01125 wpa_printf(MSG_DEBUG, "MLME: AP rejected association " 01126 "temporarily; comeback duration %u TU " 01127 "(%u ms)", tu, ms); 01128 if (ms > IEEE80211_ASSOC_TIMEOUT) { 01129 wpa_printf(MSG_DEBUG, "MLME: Update timer " 01130 "based on comeback duration"); 01131 ieee80211_reschedule_timer(wpa_s, ms); 01132 } 01133 } 01134 #endif /* CONFIG_IEEE80211W */ 01135 return; 01136 } 01137 01138 if (elems.supp_rates == NULL) { 01139 wpa_printf(MSG_DEBUG, "MLME: no SuppRates element in " 01140 "AssocResp"); 01141 return; 01142 } 01143 01144 if (wpa_s->mlme.auth_alg == WLAN_AUTH_FT) { 01145 if (!reassoc) { 01146 wpa_printf(MSG_DEBUG, "MLME: AP tried to use " 01147 "association, not reassociation, response " 01148 "with FT"); 01149 return; 01150 } 01151 if (wpa_ft_validate_reassoc_resp( 01152 wpa_s->wpa, pos, len - (pos - (u8 *) mgmt), 01153 mgmt->sa) < 0) { 01154 wpa_printf(MSG_DEBUG, "MLME: FT validation of Reassoc" 01155 "Resp failed"); 01156 return; 01157 } 01158 } else if (wpa_sm_set_ft_params(wpa_s->wpa, pos, 01159 len - (pos - (u8 *) mgmt)) < 0) 01160 return; 01161 01162 wpa_printf(MSG_DEBUG, "MLME: associated"); 01163 wpa_s->mlme.aid = aid; 01164 wpa_s->mlme.ap_capab = capab_info; 01165 01166 os_free(wpa_s->mlme.assocresp_ies); 01167 wpa_s->mlme.assocresp_ies_len = len - (pos - (u8 *) mgmt); 01168 wpa_s->mlme.assocresp_ies = os_malloc(wpa_s->mlme.assocresp_ies_len); 01169 if (wpa_s->mlme.assocresp_ies) { 01170 os_memcpy(wpa_s->mlme.assocresp_ies, pos, 01171 wpa_s->mlme.assocresp_ies_len); 01172 } 01173 01174 ieee80211_set_associated(wpa_s, 1); 01175 01176 rates_len = elems.supp_rates_len; 01177 if (rates_len > sizeof(rates)) 01178 rates_len = sizeof(rates); 01179 os_memcpy(rates, elems.supp_rates, rates_len); 01180 if (elems.ext_supp_rates) { 01181 size_t _len = elems.ext_supp_rates_len; 01182 if (_len > sizeof(rates) - rates_len) 01183 _len = sizeof(rates) - rates_len; 01184 os_memcpy(rates + rates_len, elems.ext_supp_rates, _len); 01185 rates_len += _len; 01186 } 01187 01188 if (wpa_drv_set_bssid(wpa_s, wpa_s->bssid) < 0) { 01189 wpa_printf(MSG_DEBUG, "MLME: failed to set BSSID for the " 01190 "netstack"); 01191 } 01192 if (wpa_drv_set_ssid(wpa_s, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len) < 01193 0) { 01194 wpa_printf(MSG_DEBUG, "MLME: failed to set SSID for the " 01195 "netstack"); 01196 } 01197 01198 /* Remove STA entry before adding a new one just in case to avoid 01199 * problems with existing configuration (e.g., keys). */ 01200 wpa_drv_mlme_remove_sta(wpa_s, wpa_s->bssid); 01201 if (wpa_drv_mlme_add_sta(wpa_s, wpa_s->bssid, rates, rates_len) < 0) { 01202 wpa_printf(MSG_DEBUG, "MLME: failed to add STA entry to the " 01203 "netstack"); 01204 } 01205 01206 if (elems.wmm && wpa_s->mlme.wmm_enabled) 01207 ieee80211_sta_wmm_params(wpa_s, elems.wmm, elems.wmm_len); 01208 01209 ieee80211_associated(wpa_s); 01210 01211 if (wpa_s->mlme.auth_alg != WLAN_AUTH_FT && 01212 os_strcmp(wpa_s->driver->name, "test") == 0 && 01213 elems.wmm && wpa_s->mlme.wmm_enabled) { 01214 /* Test WMM-AC - send ADDTS for WMM TSPEC */ 01215 ieee80211_tx_addts(wpa_s); 01216 } 01217 } 01218 01219 01220 /* Caller must hold local->sta_bss_lock */ 01221 static void __ieee80211_bss_hash_add(struct wpa_supplicant *wpa_s, 01222 struct ieee80211_sta_bss *bss) 01223 { 01224 bss->hnext = wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)]; 01225 wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)] = bss; 01226 } 01227 01228 01229 /* Caller must hold local->sta_bss_lock */ 01230 static void __ieee80211_bss_hash_del(struct wpa_supplicant *wpa_s, 01231 struct ieee80211_sta_bss *bss) 01232 { 01233 struct ieee80211_sta_bss *b, *prev = NULL; 01234 b = wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)]; 01235 while (b) { 01236 if (b == bss) { 01237 if (prev == NULL) { 01238 wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)] 01239 = bss->hnext; 01240 } else { 01241 prev->hnext = bss->hnext; 01242 } 01243 break; 01244 } 01245 prev = b; 01246 b = b->hnext; 01247 } 01248 } 01249 01250 01251 static struct ieee80211_sta_bss * 01252 ieee80211_bss_add(struct wpa_supplicant *wpa_s, const u8 *bssid) 01253 { 01254 struct ieee80211_sta_bss *bss; 01255 01256 bss = os_zalloc(sizeof(*bss)); 01257 if (bss == NULL) 01258 return NULL; 01259 os_memcpy(bss->bssid, bssid, ETH_ALEN); 01260 01261 /* TODO: order by RSSI? */ 01262 bss->next = wpa_s->mlme.sta_bss_list; 01263 wpa_s->mlme.sta_bss_list = bss; 01264 __ieee80211_bss_hash_add(wpa_s, bss); 01265 return bss; 01266 } 01267 01268 01269 static struct ieee80211_sta_bss * 01270 ieee80211_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid) 01271 { 01272 struct ieee80211_sta_bss *bss; 01273 01274 bss = wpa_s->mlme.sta_bss_hash[STA_HASH(bssid)]; 01275 while (bss) { 01276 if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0) 01277 break; 01278 bss = bss->hnext; 01279 } 01280 return bss; 01281 } 01282 01283 01284 static void ieee80211_bss_free(struct wpa_supplicant *wpa_s, 01285 struct ieee80211_sta_bss *bss) 01286 { 01287 __ieee80211_bss_hash_del(wpa_s, bss); 01288 os_free(bss->ie); 01289 os_free(bss->wpa_ie); 01290 os_free(bss->rsn_ie); 01291 os_free(bss->wmm_ie); 01292 os_free(bss->mdie); 01293 os_free(bss); 01294 } 01295 01296 01297 static void ieee80211_bss_list_deinit(struct wpa_supplicant *wpa_s) 01298 { 01299 struct ieee80211_sta_bss *bss, *prev; 01300 01301 bss = wpa_s->mlme.sta_bss_list; 01302 wpa_s->mlme.sta_bss_list = NULL; 01303 while (bss) { 01304 prev = bss; 01305 bss = bss->next; 01306 ieee80211_bss_free(wpa_s, prev); 01307 } 01308 } 01309 01310 01311 static void ieee80211_bss_info(struct wpa_supplicant *wpa_s, 01312 struct ieee80211_mgmt *mgmt, 01313 size_t len, 01314 struct ieee80211_rx_status *rx_status, 01315 int beacon) 01316 { 01317 struct ieee802_11_elems elems; 01318 size_t baselen; 01319 int channel, invalid = 0, clen; 01320 struct ieee80211_sta_bss *bss; 01321 u64 timestamp; 01322 u8 *pos, *ie_pos; 01323 size_t ie_len; 01324 01325 if (!beacon && os_memcmp(mgmt->da, wpa_s->own_addr, ETH_ALEN)) 01326 return; /* ignore ProbeResp to foreign address */ 01327 01328 #if 0 01329 wpa_printf(MSG_MSGDUMP, "MLME: RX %s from " MACSTR " to " MACSTR, 01330 beacon ? "Beacon" : "Probe Response", 01331 MAC2STR(mgmt->sa), MAC2STR(mgmt->da)); 01332 #endif 01333 01334 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; 01335 if (baselen > len) 01336 return; 01337 01338 pos = mgmt->u.beacon.timestamp; 01339 timestamp = WPA_GET_LE64(pos); 01340 01341 #if 0 /* FIX */ 01342 if (local->conf.mode == IW_MODE_ADHOC && beacon && 01343 os_memcmp(mgmt->bssid, local->bssid, ETH_ALEN) == 0) { 01344 #ifdef IEEE80211_IBSS_DEBUG 01345 static unsigned long last_tsf_debug = 0; 01346 u64 tsf; 01347 if (local->hw->get_tsf) 01348 tsf = local->hw->get_tsf(local->mdev); 01349 else 01350 tsf = -1LLU; 01351 if (time_after(jiffies, last_tsf_debug + 5 * HZ)) { 01352 wpa_printf(MSG_DEBUG, "RX beacon SA=" MACSTR " BSSID=" 01353 MACSTR " TSF=0x%llx BCN=0x%llx diff=%lld " 01354 "@%ld", 01355 MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid), 01356 tsf, timestamp, tsf - timestamp, jiffies); 01357 last_tsf_debug = jiffies; 01358 } 01359 #endif /* IEEE80211_IBSS_DEBUG */ 01360 } 01361 #endif 01362 01363 ie_pos = mgmt->u.beacon.variable; 01364 ie_len = len - baselen; 01365 if (ieee802_11_parse_elems(ie_pos, ie_len, &elems, 0) == ParseFailed) 01366 invalid = 1; 01367 01368 #if 0 /* FIX */ 01369 if (local->conf.mode == IW_MODE_ADHOC && elems.supp_rates && 01370 os_memcmp(mgmt->bssid, local->bssid, ETH_ALEN) == 0 && 01371 (sta = sta_info_get(local, mgmt->sa))) { 01372 struct ieee80211_rate *rates; 01373 size_t num_rates; 01374 u32 supp_rates, prev_rates; 01375 int i, j, oper_mode; 01376 01377 rates = local->curr_rates; 01378 num_rates = local->num_curr_rates; 01379 oper_mode = wpa_s->mlme.sta_scanning ? 01380 local->scan_oper_phymode : local->conf.phymode; 01381 for (i = 0; i < local->hw->num_modes; i++) { 01382 struct ieee80211_hw_modes *mode = &local->hw->modes[i]; 01383 if (oper_mode == mode->mode) { 01384 rates = mode->rates; 01385 num_rates = mode->num_rates; 01386 break; 01387 } 01388 } 01389 01390 supp_rates = 0; 01391 for (i = 0; i < elems.supp_rates_len + 01392 elems.ext_supp_rates_len; i++) { 01393 u8 rate = 0; 01394 int own_rate; 01395 if (i < elems.supp_rates_len) 01396 rate = elems.supp_rates[i]; 01397 else if (elems.ext_supp_rates) 01398 rate = elems.ext_supp_rates 01399 [i - elems.supp_rates_len]; 01400 own_rate = 5 * (rate & 0x7f); 01401 if (oper_mode == MODE_ATHEROS_TURBO) 01402 own_rate *= 2; 01403 for (j = 0; j < num_rates; j++) 01404 if (rates[j].rate == own_rate) 01405 supp_rates |= BIT(j); 01406 } 01407 01408 prev_rates = sta->supp_rates; 01409 sta->supp_rates &= supp_rates; 01410 if (sta->supp_rates == 0) { 01411 /* No matching rates - this should not really happen. 01412 * Make sure that at least one rate is marked 01413 * supported to avoid issues with TX rate ctrl. */ 01414 sta->supp_rates = wpa_s->mlme.supp_rates_bits; 01415 } 01416 if (sta->supp_rates != prev_rates) { 01417 wpa_printf(MSG_DEBUG, "MLME: updated supp_rates set " 01418 "for " MACSTR " based on beacon info " 01419 "(0x%x & 0x%x -> 0x%x)", 01420 MAC2STR(sta->addr), prev_rates, 01421 supp_rates, sta->supp_rates); 01422 } 01423 sta_info_release(local, sta); 01424 } 01425 #endif 01426 01427 if (elems.ssid == NULL) 01428 return; 01429 01430 if (elems.ds_params && elems.ds_params_len == 1) 01431 channel = elems.ds_params[0]; 01432 else 01433 channel = rx_status->channel; 01434 01435 bss = ieee80211_bss_get(wpa_s, mgmt->bssid); 01436 if (bss == NULL) { 01437 bss = ieee80211_bss_add(wpa_s, mgmt->bssid); 01438 if (bss == NULL) 01439 return; 01440 } else { 01441 #if 0 01442 /* TODO: order by RSSI? */ 01443 spin_lock_bh(&local->sta_bss_lock); 01444 list_move_tail(&bss->list, &local->sta_bss_list); 01445 spin_unlock_bh(&local->sta_bss_lock); 01446 #endif 01447 } 01448 01449 if (bss->probe_resp && beacon) { 01450 /* Do not allow beacon to override data from Probe Response. */ 01451 return; 01452 } 01453 01454 bss->beacon_int = le_to_host16(mgmt->u.beacon.beacon_int); 01455 bss->capability = le_to_host16(mgmt->u.beacon.capab_info); 01456 01457 if (bss->ie == NULL || bss->ie_len < ie_len) { 01458 os_free(bss->ie); 01459 bss->ie = os_malloc(ie_len); 01460 } 01461 if (bss->ie) { 01462 os_memcpy(bss->ie, ie_pos, ie_len); 01463 bss->ie_len = ie_len; 01464 } 01465 01466 if (elems.ssid && elems.ssid_len <= MAX_SSID_LEN) { 01467 os_memcpy(bss->ssid, elems.ssid, elems.ssid_len); 01468 bss->ssid_len = elems.ssid_len; 01469 } 01470 01471 bss->supp_rates_len = 0; 01472 if (elems.supp_rates) { 01473 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; 01474 if (clen > elems.supp_rates_len) 01475 clen = elems.supp_rates_len; 01476 os_memcpy(&bss->supp_rates[bss->supp_rates_len], 01477 elems.supp_rates, clen); 01478 bss->supp_rates_len += clen; 01479 } 01480 if (elems.ext_supp_rates) { 01481 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; 01482 if (clen > elems.ext_supp_rates_len) 01483 clen = elems.ext_supp_rates_len; 01484 os_memcpy(&bss->supp_rates[bss->supp_rates_len], 01485 elems.ext_supp_rates, clen); 01486 bss->supp_rates_len += clen; 01487 } 01488 01489 if (elems.wpa_ie && 01490 (bss->wpa_ie == NULL || bss->wpa_ie_len != elems.wpa_ie_len || 01491 os_memcmp(bss->wpa_ie, elems.wpa_ie, elems.wpa_ie_len))) { 01492 os_free(bss->wpa_ie); 01493 bss->wpa_ie = os_malloc(elems.wpa_ie_len + 2); 01494 if (bss->wpa_ie) { 01495 os_memcpy(bss->wpa_ie, elems.wpa_ie - 2, 01496 elems.wpa_ie_len + 2); 01497 bss->wpa_ie_len = elems.wpa_ie_len + 2; 01498 } else 01499 bss->wpa_ie_len = 0; 01500 } else if (!elems.wpa_ie && bss->wpa_ie) { 01501 os_free(bss->wpa_ie); 01502 bss->wpa_ie = NULL; 01503 bss->wpa_ie_len = 0; 01504 } 01505 01506 if (elems.rsn_ie && 01507 (bss->rsn_ie == NULL || bss->rsn_ie_len != elems.rsn_ie_len || 01508 os_memcmp(bss->rsn_ie, elems.rsn_ie, elems.rsn_ie_len))) { 01509 os_free(bss->rsn_ie); 01510 bss->rsn_ie = os_malloc(elems.rsn_ie_len + 2); 01511 if (bss->rsn_ie) { 01512 os_memcpy(bss->rsn_ie, elems.rsn_ie - 2, 01513 elems.rsn_ie_len + 2); 01514 bss->rsn_ie_len = elems.rsn_ie_len + 2; 01515 } else 01516 bss->rsn_ie_len = 0; 01517 } else if (!elems.rsn_ie && bss->rsn_ie) { 01518 os_free(bss->rsn_ie); 01519 bss->rsn_ie = NULL; 01520 bss->rsn_ie_len = 0; 01521 } 01522 01523 if (elems.wmm && 01524 (bss->wmm_ie == NULL || bss->wmm_ie_len != elems.wmm_len || 01525 os_memcmp(bss->wmm_ie, elems.wmm, elems.wmm_len))) { 01526 os_free(bss->wmm_ie); 01527 bss->wmm_ie = os_malloc(elems.wmm_len + 2); 01528 if (bss->wmm_ie) { 01529 os_memcpy(bss->wmm_ie, elems.wmm - 2, 01530 elems.wmm_len + 2); 01531 bss->wmm_ie_len = elems.wmm_len + 2; 01532 } else 01533 bss->wmm_ie_len = 0; 01534 } else if (!elems.wmm && bss->wmm_ie) { 01535 os_free(bss->wmm_ie); 01536 bss->wmm_ie = NULL; 01537 bss->wmm_ie_len = 0; 01538 } 01539 01540 #ifdef CONFIG_IEEE80211R 01541 if (elems.mdie && 01542 (bss->mdie == NULL || bss->mdie_len != elems.mdie_len || 01543 os_memcmp(bss->mdie, elems.mdie, elems.mdie_len))) { 01544 os_free(bss->mdie); 01545 bss->mdie = os_malloc(elems.mdie_len + 2); 01546 if (bss->mdie) { 01547 os_memcpy(bss->mdie, elems.mdie - 2, 01548 elems.mdie_len + 2); 01549 bss->mdie_len = elems.mdie_len + 2; 01550 } else 01551 bss->mdie_len = 0; 01552 } else if (!elems.mdie && bss->mdie) { 01553 os_free(bss->mdie); 01554 bss->mdie = NULL; 01555 bss->mdie_len = 0; 01556 } 01557 #endif /* CONFIG_IEEE80211R */ 01558 01559 bss->hw_mode = wpa_s->mlme.phymode; 01560 bss->channel = channel; 01561 bss->freq = wpa_s->mlme.freq; 01562 if (channel != wpa_s->mlme.channel && 01563 (wpa_s->mlme.phymode == HOSTAPD_MODE_IEEE80211G || 01564 wpa_s->mlme.phymode == HOSTAPD_MODE_IEEE80211B) && 01565 channel >= 1 && channel <= 14) { 01566 static const int freq_list[] = { 01567 2412, 2417, 2422, 2427, 2432, 2437, 2442, 01568 2447, 2452, 2457, 2462, 2467, 2472, 2484 01569 }; 01570 /* IEEE 802.11g/b mode can receive packets from neighboring 01571 * channels, so map the channel into frequency. */ 01572 bss->freq = freq_list[channel - 1]; 01573 } 01574 bss->timestamp = timestamp; 01575 os_get_time(&bss->last_update); 01576 bss->rssi = rx_status->ssi; 01577 if (!beacon) 01578 bss->probe_resp++; 01579 } 01580 01581 01582 static void ieee80211_rx_mgmt_probe_resp(struct wpa_supplicant *wpa_s, 01583 struct ieee80211_mgmt *mgmt, 01584 size_t len, 01585 struct ieee80211_rx_status *rx_status) 01586 { 01587 ieee80211_bss_info(wpa_s, mgmt, len, rx_status, 0); 01588 } 01589 01590 01591 static void ieee80211_rx_mgmt_beacon(struct wpa_supplicant *wpa_s, 01592 struct ieee80211_mgmt *mgmt, 01593 size_t len, 01594 struct ieee80211_rx_status *rx_status) 01595 { 01596 int use_protection; 01597 size_t baselen; 01598 struct ieee802_11_elems elems; 01599 01600 ieee80211_bss_info(wpa_s, mgmt, len, rx_status, 1); 01601 01602 if (!wpa_s->mlme.associated || 01603 os_memcmp(wpa_s->bssid, mgmt->bssid, ETH_ALEN) != 0) 01604 return; 01605 01606 /* Process beacon from the current BSS */ 01607 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; 01608 if (baselen > len) 01609 return; 01610 01611 if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, 01612 &elems, 0) == ParseFailed) 01613 return; 01614 01615 use_protection = 0; 01616 if (elems.erp_info && elems.erp_info_len >= 1) { 01617 use_protection = 01618 (elems.erp_info[0] & ERP_INFO_USE_PROTECTION) != 0; 01619 } 01620 01621 if (use_protection != !!wpa_s->mlme.use_protection) { 01622 wpa_printf(MSG_DEBUG, "MLME: CTS protection %s (BSSID=" MACSTR 01623 ")", 01624 use_protection ? "enabled" : "disabled", 01625 MAC2STR(wpa_s->bssid)); 01626 wpa_s->mlme.use_protection = use_protection ? 1 : 0; 01627 wpa_s->mlme.cts_protect_erp_frames = use_protection; 01628 } 01629 01630 if (elems.wmm && wpa_s->mlme.wmm_enabled) { 01631 ieee80211_sta_wmm_params(wpa_s, elems.wmm, 01632 elems.wmm_len); 01633 } 01634 } 01635 01636 01637 static void ieee80211_rx_mgmt_probe_req(struct wpa_supplicant *wpa_s, 01638 struct ieee80211_mgmt *mgmt, 01639 size_t len, 01640 struct ieee80211_rx_status *rx_status) 01641 { 01642 int tx_last_beacon, adhoc; 01643 #if 0 /* FIX */ 01644 struct ieee80211_mgmt *resp; 01645 #endif 01646 u8 *pos, *end; 01647 struct wpa_ssid *ssid = wpa_s->current_ssid; 01648 01649 adhoc = ssid && ssid->mode == WPAS_MODE_IBSS; 01650 01651 if (!adhoc || wpa_s->mlme.state != IEEE80211_IBSS_JOINED || 01652 len < 24 + 2 || wpa_s->mlme.probe_resp == NULL) 01653 return; 01654 01655 #if 0 /* FIX */ 01656 if (local->hw->tx_last_beacon) 01657 tx_last_beacon = local->hw->tx_last_beacon(local->mdev); 01658 else 01659 #endif 01660 tx_last_beacon = 1; 01661 01662 #ifdef IEEE80211_IBSS_DEBUG 01663 wpa_printf(MSG_DEBUG, "MLME: RX ProbeReq SA=" MACSTR " DA=" MACSTR 01664 " BSSID=" MACSTR " (tx_last_beacon=%d)", 01665 MAC2STR(mgmt->sa), MAC2STR(mgmt->da), 01666 MAC2STR(mgmt->bssid), tx_last_beacon); 01667 #endif /* IEEE80211_IBSS_DEBUG */ 01668 01669 if (!tx_last_beacon) 01670 return; 01671 01672 if (os_memcmp(mgmt->bssid, wpa_s->bssid, ETH_ALEN) != 0 && 01673 os_memcmp(mgmt->bssid, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0) 01674 return; 01675 01676 end = ((u8 *) mgmt) + len; 01677 pos = mgmt->u.probe_req.variable; 01678 if (pos[0] != WLAN_EID_SSID || 01679 pos + 2 + pos[1] > end) { 01680 wpa_printf(MSG_DEBUG, "MLME: Invalid SSID IE in ProbeReq from " 01681 MACSTR, MAC2STR(mgmt->sa)); 01682 return; 01683 } 01684 if (pos[1] != 0 && 01685 (pos[1] != wpa_s->mlme.ssid_len || 01686 os_memcmp(pos + 2, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len) != 0)) 01687 { 01688 /* Ignore ProbeReq for foreign SSID */ 01689 return; 01690 } 01691 01692 #if 0 /* FIX */ 01693 /* Reply with ProbeResp */ 01694 skb = skb_copy(wpa_s->mlme.probe_resp, GFP_ATOMIC); 01695 if (skb == NULL) 01696 return; 01697 01698 resp = (struct ieee80211_mgmt *) skb->data; 01699 os_memcpy(resp->da, mgmt->sa, ETH_ALEN); 01700 #ifdef IEEE80211_IBSS_DEBUG 01701 wpa_printf(MSG_DEBUG, "MLME: Sending ProbeResp to " MACSTR, 01702 MAC2STR(resp->da)); 01703 #endif /* IEEE80211_IBSS_DEBUG */ 01704 ieee80211_sta_tx(wpa_s, skb, 0, 1); 01705 #endif 01706 } 01707 01708 01709 #ifdef CONFIG_IEEE80211R 01710 static void ieee80211_rx_mgmt_ft_action(struct wpa_supplicant *wpa_s, 01711 struct ieee80211_mgmt *mgmt, 01712 size_t len, 01713 struct ieee80211_rx_status *rx_status) 01714 { 01715 union wpa_event_data data; 01716 u16 status; 01717 u8 *sta_addr, *target_ap_addr; 01718 01719 if (len < 24 + 1 + sizeof(mgmt->u.action.u.ft_action_resp)) { 01720 wpa_printf(MSG_DEBUG, "MLME: Too short FT Action frame"); 01721 return; 01722 } 01723 01724 /* 01725 * Only FT Action Response is needed for now since reservation 01726 * protocol is not supported. 01727 */ 01728 if (mgmt->u.action.u.ft_action_resp.action != 2) { 01729 wpa_printf(MSG_DEBUG, "MLME: Unexpected FT Action %d", 01730 mgmt->u.action.u.ft_action_resp.action); 01731 return; 01732 } 01733 01734 status = le_to_host16(mgmt->u.action.u.ft_action_resp.status_code); 01735 sta_addr = mgmt->u.action.u.ft_action_resp.sta_addr; 01736 target_ap_addr = mgmt->u.action.u.ft_action_resp.target_ap_addr; 01737 wpa_printf(MSG_DEBUG, "MLME: Received FT Action Response: STA " MACSTR 01738 " TargetAP " MACSTR " Status Code %d", 01739 MAC2STR(sta_addr), MAC2STR(target_ap_addr), status); 01740 if (os_memcmp(sta_addr, wpa_s->own_addr, ETH_ALEN) != 0) { 01741 wpa_printf(MSG_DEBUG, "MLME: Foreign STA Address " MACSTR 01742 " in FT Action Response", MAC2STR(sta_addr)); 01743 return; 01744 } 01745 01746 if (status) { 01747 wpa_printf(MSG_DEBUG, "MLME: FT Action Response indicates " 01748 "failure (status code %d)", status); 01749 /* TODO: report error to FT code(?) */ 01750 return; 01751 } 01752 01753 os_memset(&data, 0, sizeof(data)); 01754 data.ft_ies.ies = mgmt->u.action.u.ft_action_resp.variable; 01755 data.ft_ies.ies_len = len - (mgmt->u.action.u.ft_action_resp.variable - 01756 (u8 *) mgmt); 01757 data.ft_ies.ft_action = 1; 01758 os_memcpy(data.ft_ies.target_ap, target_ap_addr, ETH_ALEN); 01759 wpa_supplicant_event(wpa_s, EVENT_FT_RESPONSE, &data); 01760 /* TODO: should only re-associate, if EVENT_FT_RESPONSE was processed 01761 * successfully */ 01762 wpa_s->mlme.prev_bssid_set = 1; 01763 wpa_s->mlme.auth_alg = WLAN_AUTH_FT; 01764 os_memcpy(wpa_s->mlme.prev_bssid, wpa_s->bssid, ETH_ALEN); 01765 os_memcpy(wpa_s->bssid, target_ap_addr, ETH_ALEN); 01766 ieee80211_associate(wpa_s); 01767 } 01768 #endif /* CONFIG_IEEE80211R */ 01769 01770 01771 #ifdef CONFIG_IEEE80211W 01772 01773 /* MLME-SAQuery.response */ 01774 static int ieee80211_sta_send_sa_query_resp(struct wpa_supplicant *wpa_s, 01775 const u8 *addr, const u8 *trans_id) 01776 { 01777 struct ieee80211_mgmt *mgmt; 01778 int res; 01779 size_t len; 01780 01781 mgmt = os_zalloc(sizeof(*mgmt)); 01782 if (mgmt == NULL) { 01783 wpa_printf(MSG_DEBUG, "MLME: Failed to allocate buffer for " 01784 "SA Query action frame"); 01785 return -1; 01786 } 01787 01788 len = 24; 01789 os_memcpy(mgmt->da, addr, ETH_ALEN); 01790 os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 01791 os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN); 01792 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 01793 WLAN_FC_STYPE_ACTION); 01794 mgmt->u.action.category = WLAN_ACTION_SA_QUERY; 01795 mgmt->u.action.u.sa_query_resp.action = WLAN_SA_QUERY_RESPONSE; 01796 os_memcpy(mgmt->u.action.u.sa_query_resp.trans_id, trans_id, 01797 WLAN_SA_QUERY_TR_ID_LEN); 01798 len += 1 + sizeof(mgmt->u.action.u.sa_query_resp); 01799 01800 res = ieee80211_sta_tx(wpa_s, (u8 *) mgmt, len); 01801 os_free(mgmt); 01802 01803 return res; 01804 } 01805 01806 01807 static void ieee80211_rx_mgmt_sa_query_action( 01808 struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len, 01809 struct ieee80211_rx_status *rx_status) 01810 { 01811 if (len < 24 + 1 + sizeof(mgmt->u.action.u.sa_query_req)) { 01812 wpa_printf(MSG_DEBUG, "MLME: Too short SA Query Action frame"); 01813 return; 01814 } 01815 01816 if (mgmt->u.action.u.sa_query_req.action != WLAN_SA_QUERY_REQUEST) { 01817 wpa_printf(MSG_DEBUG, "MLME: Unexpected SA Query Action %d", 01818 mgmt->u.action.u.sa_query_req.action); 01819 return; 01820 } 01821 01822 if (os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) != 0) { 01823 wpa_printf(MSG_DEBUG, "MLME: Ignore SA Query from unknown " 01824 "source " MACSTR, MAC2STR(mgmt->sa)); 01825 return; 01826 } 01827 01828 if (wpa_s->mlme.state == IEEE80211_ASSOCIATE) { 01829 wpa_printf(MSG_DEBUG, "MLME: Ignore SA query request during " 01830 "association process"); 01831 return; 01832 } 01833 01834 wpa_printf(MSG_DEBUG, "MLME: Replying to SA Query request"); 01835 ieee80211_sta_send_sa_query_resp(wpa_s, mgmt->sa, mgmt->u.action.u. 01836 sa_query_req.trans_id); 01837 } 01838 01839 #endif /* CONFIG_IEEE80211W */ 01840 01841 01842 static void dump_tspec(struct wmm_tspec_element *tspec) 01843 { 01844 int up, psb, dir, tid; 01845 u16 val; 01846 01847 up = (tspec->ts_info[1] >> 3) & 0x07; 01848 psb = (tspec->ts_info[1] >> 2) & 0x01; 01849 dir = (tspec->ts_info[0] >> 5) & 0x03; 01850 tid = (tspec->ts_info[0] >> 1) & 0x0f; 01851 wpa_printf(MSG_DEBUG, "WMM: TS Info: UP=%d PSB=%d Direction=%d TID=%d", 01852 up, psb, dir, tid); 01853 val = le_to_host16(tspec->nominal_msdu_size); 01854 wpa_printf(MSG_DEBUG, "WMM: Nominal MSDU Size: %d%s", 01855 val & 0x7fff, val & 0x8000 ? " (fixed)" : ""); 01856 wpa_printf(MSG_DEBUG, "WMM: Mean Data Rate: %u bps", 01857 le_to_host32(tspec->mean_data_rate)); 01858 wpa_printf(MSG_DEBUG, "WMM: Minimum PHY Rate: %u bps", 01859 le_to_host32(tspec->minimum_phy_rate)); 01860 val = le_to_host16(tspec->surplus_bandwidth_allowance); 01861 wpa_printf(MSG_DEBUG, "WMM: Surplus Bandwidth Allowance: %u.%04u", 01862 val >> 13, 10000 * (val & 0x1fff) / 0x2000); 01863 val = le_to_host16(tspec->medium_time); 01864 wpa_printf(MSG_DEBUG, "WMM: Medium Time: %u (= %u usec/sec)", 01865 val, 32 * val); 01866 } 01867 01868 01869 static int is_wmm_tspec(const u8 *ie, size_t len) 01870 { 01871 const struct wmm_tspec_element *tspec; 01872 01873 if (len < sizeof(*tspec)) 01874 return 0; 01875 01876 tspec = (const struct wmm_tspec_element *) ie; 01877 if (tspec->eid != WLAN_EID_VENDOR_SPECIFIC || 01878 tspec->length < sizeof(*tspec) - 2 || 01879 tspec->oui[0] != 0x00 || tspec->oui[1] != 0x50 || 01880 tspec->oui[2] != 0xf2 || tspec->oui_type != 2 || 01881 tspec->oui_subtype != 2 || tspec->version != 1) 01882 return 0; 01883 01884 return 1; 01885 } 01886 01887 01888 static void ieee80211_rx_addts_resp( 01889 struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len, 01890 size_t var_len) 01891 { 01892 struct wmm_tspec_element *tspec; 01893 01894 wpa_printf(MSG_DEBUG, "WMM: Received ADDTS Response"); 01895 wpa_hexdump(MSG_MSGDUMP, "WMM: ADDTS Response IE(s)", 01896 mgmt->u.action.u.wmm_action.variable, var_len); 01897 if (!is_wmm_tspec(mgmt->u.action.u.wmm_action.variable, var_len)) 01898 return; 01899 tspec = (struct wmm_tspec_element *) 01900 mgmt->u.action.u.wmm_action.variable; 01901 dump_tspec(tspec); 01902 } 01903 01904 01905 static void ieee80211_rx_delts( 01906 struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len, 01907 size_t var_len) 01908 { 01909 struct wmm_tspec_element *tspec; 01910 01911 wpa_printf(MSG_DEBUG, "WMM: Received DELTS"); 01912 wpa_hexdump(MSG_MSGDUMP, "WMM: DELTS IE(s)", 01913 mgmt->u.action.u.wmm_action.variable, var_len); 01914 if (!is_wmm_tspec(mgmt->u.action.u.wmm_action.variable, var_len)) 01915 return; 01916 tspec = (struct wmm_tspec_element *) 01917 mgmt->u.action.u.wmm_action.variable; 01918 dump_tspec(tspec); 01919 } 01920 01921 01922 static void ieee80211_rx_mgmt_wmm_action( 01923 struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len, 01924 struct ieee80211_rx_status *rx_status) 01925 { 01926 size_t alen; 01927 01928 alen = mgmt->u.action.u.wmm_action.variable - (u8 *) mgmt; 01929 if (len < alen) { 01930 wpa_printf(MSG_DEBUG, "WMM: Received Action frame too short"); 01931 return; 01932 } 01933 01934 wpa_printf(MSG_DEBUG, "WMM: Received Action frame: Action Code %d, " 01935 "Dialog Token %d, Status Code %d", 01936 mgmt->u.action.u.wmm_action.action_code, 01937 mgmt->u.action.u.wmm_action.dialog_token, 01938 mgmt->u.action.u.wmm_action.status_code); 01939 01940 switch (mgmt->u.action.u.wmm_action.action_code) { 01941 case WMM_ACTION_CODE_ADDTS_RESP: 01942 ieee80211_rx_addts_resp(wpa_s, mgmt, len, len - alen); 01943 break; 01944 case WMM_ACTION_CODE_DELTS: 01945 ieee80211_rx_delts(wpa_s, mgmt, len, len - alen); 01946 break; 01947 default: 01948 wpa_printf(MSG_DEBUG, "WMM: Unsupported Action Code %d", 01949 mgmt->u.action.u.wmm_action.action_code); 01950 break; 01951 } 01952 } 01953 01954 01955 static void ieee80211_rx_mgmt_action(struct wpa_supplicant *wpa_s, 01956 struct ieee80211_mgmt *mgmt, 01957 size_t len, 01958 struct ieee80211_rx_status *rx_status) 01959 { 01960 wpa_printf(MSG_DEBUG, "MLME: received Action frame"); 01961 01962 if (len < 25) 01963 return; 01964 01965 switch (mgmt->u.action.category) { 01966 #ifdef CONFIG_IEEE80211R 01967 case WLAN_ACTION_FT: 01968 ieee80211_rx_mgmt_ft_action(wpa_s, mgmt, len, rx_status); 01969 break; 01970 #endif /* CONFIG_IEEE80211R */ 01971 #ifdef CONFIG_IEEE80211W 01972 case WLAN_ACTION_SA_QUERY: 01973 ieee80211_rx_mgmt_sa_query_action(wpa_s, mgmt, len, rx_status); 01974 break; 01975 #endif /* CONFIG_IEEE80211W */ 01976 case WLAN_ACTION_WMM: 01977 ieee80211_rx_mgmt_wmm_action(wpa_s, mgmt, len, rx_status); 01978 break; 01979 case WLAN_ACTION_PUBLIC: 01980 if (wpa_s->mlme.public_action_cb) { 01981 wpa_s->mlme.public_action_cb( 01982 wpa_s->mlme.public_action_cb_ctx, 01983 (u8 *) mgmt, len, rx_status->freq); 01984 return; 01985 } 01986 break; 01987 default: 01988 wpa_printf(MSG_DEBUG, "MLME: unknown Action Category %d", 01989 mgmt->u.action.category); 01990 break; 01991 } 01992 } 01993 01994 01995 static void ieee80211_sta_rx_mgmt(struct wpa_supplicant *wpa_s, 01996 const u8 *buf, size_t len, 01997 struct ieee80211_rx_status *rx_status) 01998 { 01999 struct ieee80211_mgmt *mgmt; 02000 u16 fc; 02001 02002 if (len < 24) 02003 return; 02004 02005 mgmt = (struct ieee80211_mgmt *) buf; 02006 fc = le_to_host16(mgmt->frame_control); 02007 02008 switch (WLAN_FC_GET_STYPE(fc)) { 02009 case WLAN_FC_STYPE_PROBE_REQ: 02010 ieee80211_rx_mgmt_probe_req(wpa_s, mgmt, len, rx_status); 02011 break; 02012 case WLAN_FC_STYPE_PROBE_RESP: 02013 ieee80211_rx_mgmt_probe_resp(wpa_s, mgmt, len, rx_status); 02014 break; 02015 case WLAN_FC_STYPE_BEACON: 02016 ieee80211_rx_mgmt_beacon(wpa_s, mgmt, len, rx_status); 02017 break; 02018 case WLAN_FC_STYPE_AUTH: 02019 ieee80211_rx_mgmt_auth(wpa_s, mgmt, len, rx_status); 02020 break; 02021 case WLAN_FC_STYPE_ASSOC_RESP: 02022 ieee80211_rx_mgmt_assoc_resp(wpa_s, mgmt, len, rx_status, 0); 02023 break; 02024 case WLAN_FC_STYPE_REASSOC_RESP: 02025 ieee80211_rx_mgmt_assoc_resp(wpa_s, mgmt, len, rx_status, 1); 02026 break; 02027 case WLAN_FC_STYPE_DEAUTH: 02028 ieee80211_rx_mgmt_deauth(wpa_s, mgmt, len, rx_status); 02029 break; 02030 case WLAN_FC_STYPE_DISASSOC: 02031 ieee80211_rx_mgmt_disassoc(wpa_s, mgmt, len, rx_status); 02032 break; 02033 case WLAN_FC_STYPE_ACTION: 02034 ieee80211_rx_mgmt_action(wpa_s, mgmt, len, rx_status); 02035 break; 02036 default: 02037 wpa_printf(MSG_DEBUG, "MLME: received unknown management " 02038 "frame - stype=%d", WLAN_FC_GET_STYPE(fc)); 02039 break; 02040 } 02041 } 02042 02043 02044 static void ieee80211_sta_rx_scan(struct wpa_supplicant *wpa_s, 02045 const u8 *buf, size_t len, 02046 struct ieee80211_rx_status *rx_status) 02047 { 02048 struct ieee80211_mgmt *mgmt; 02049 u16 fc; 02050 02051 if (len < 24) 02052 return; 02053 02054 mgmt = (struct ieee80211_mgmt *) buf; 02055 fc = le_to_host16(mgmt->frame_control); 02056 02057 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT) { 02058 if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) { 02059 ieee80211_rx_mgmt_probe_resp(wpa_s, mgmt, 02060 len, rx_status); 02061 } else if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) { 02062 ieee80211_rx_mgmt_beacon(wpa_s, mgmt, len, rx_status); 02063 } 02064 } 02065 } 02066 02067 02068 static int ieee80211_sta_active_ibss(struct wpa_supplicant *wpa_s) 02069 { 02070 int active = 0; 02071 02072 #if 0 /* FIX */ 02073 list_for_each(ptr, &local->sta_list) { 02074 sta = list_entry(ptr, struct sta_info, list); 02075 if (sta->dev == dev && 02076 time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL, 02077 jiffies)) { 02078 active++; 02079 break; 02080 } 02081 } 02082 #endif 02083 02084 return active; 02085 } 02086 02087 02088 static void ieee80211_sta_expire(struct wpa_supplicant *wpa_s) 02089 { 02090 #if 0 /* FIX */ 02091 list_for_each_safe(ptr, n, &local->sta_list) { 02092 sta = list_entry(ptr, struct sta_info, list); 02093 if (time_after(jiffies, sta->last_rx + 02094 IEEE80211_IBSS_INACTIVITY_LIMIT)) { 02095 wpa_printf(MSG_DEBUG, "MLME: expiring inactive STA " 02096 MACSTR, MAC2STR(sta->addr)); 02097 sta_info_free(local, sta, 1); 02098 } 02099 } 02100 #endif 02101 } 02102 02103 02104 static void ieee80211_sta_merge_ibss(struct wpa_supplicant *wpa_s) 02105 { 02106 struct wpa_driver_scan_params params; 02107 02108 ieee80211_reschedule_timer(wpa_s, IEEE80211_IBSS_MERGE_INTERVAL); 02109 02110 ieee80211_sta_expire(wpa_s); 02111 if (ieee80211_sta_active_ibss(wpa_s)) 02112 return; 02113 02114 wpa_printf(MSG_DEBUG, "MLME: No active IBSS STAs - trying to scan for " 02115 "other IBSS networks with same SSID (merge)"); 02116 os_memset(¶ms, 0, sizeof(params)); 02117 params.ssids[0].ssid = wpa_s->mlme.ssid; 02118 params.ssids[0].ssid_len = wpa_s->mlme.ssid_len; 02119 params.num_ssids = wpa_s->mlme.ssid_len ? 1 : 0; 02120 ieee80211_sta_req_scan(wpa_s, ¶ms); 02121 } 02122 02123 02124 static void ieee80211_sta_timer(void *eloop_ctx, void *timeout_ctx) 02125 { 02126 struct wpa_supplicant *wpa_s = eloop_ctx; 02127 02128 switch (wpa_s->mlme.state) { 02129 case IEEE80211_DISABLED: 02130 break; 02131 case IEEE80211_AUTHENTICATE: 02132 ieee80211_authenticate(wpa_s); 02133 break; 02134 case IEEE80211_ASSOCIATE: 02135 ieee80211_associate(wpa_s); 02136 break; 02137 case IEEE80211_ASSOCIATED: 02138 ieee80211_associated(wpa_s); 02139 break; 02140 case IEEE80211_IBSS_SEARCH: 02141 ieee80211_sta_find_ibss(wpa_s); 02142 break; 02143 case IEEE80211_IBSS_JOINED: 02144 ieee80211_sta_merge_ibss(wpa_s); 02145 break; 02146 default: 02147 wpa_printf(MSG_DEBUG, "ieee80211_sta_timer: Unknown state %d", 02148 wpa_s->mlme.state); 02149 break; 02150 } 02151 02152 if (ieee80211_privacy_mismatch(wpa_s)) { 02153 wpa_printf(MSG_DEBUG, "MLME: privacy configuration mismatch " 02154 "and mixed-cell disabled - disassociate"); 02155 02156 ieee80211_send_disassoc(wpa_s, WLAN_REASON_UNSPECIFIED); 02157 ieee80211_set_associated(wpa_s, 0); 02158 } 02159 } 02160 02161 02162 static void ieee80211_sta_new_auth(struct wpa_supplicant *wpa_s) 02163 { 02164 struct wpa_ssid *ssid = wpa_s->current_ssid; 02165 if (ssid && ssid->mode != WPAS_MODE_INFRA) 02166 return; 02167 02168 #if 0 /* FIX */ 02169 if (local->hw->reset_tsf) { 02170 /* Reset own TSF to allow time synchronization work. */ 02171 local->hw->reset_tsf(local->mdev); 02172 } 02173 #endif 02174 02175 wpa_s->mlme.wmm_last_param_set = -1; /* allow any WMM update */ 02176 02177 02178 if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_OPEN) 02179 wpa_s->mlme.auth_alg = WLAN_AUTH_OPEN; 02180 else if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_SHARED) 02181 wpa_s->mlme.auth_alg = WLAN_AUTH_SHARED_KEY; 02182 else if (wpa_s->mlme.auth_algs & WPA_AUTH_ALG_LEAP) 02183 wpa_s->mlme.auth_alg = WLAN_AUTH_LEAP; 02184 else 02185 wpa_s->mlme.auth_alg = WLAN_AUTH_OPEN; 02186 wpa_printf(MSG_DEBUG, "MLME: Initial auth_alg=%d", 02187 wpa_s->mlme.auth_alg); 02188 wpa_s->mlme.auth_transaction = -1; 02189 wpa_s->mlme.auth_tries = wpa_s->mlme.assoc_tries = 0; 02190 ieee80211_authenticate(wpa_s); 02191 } 02192 02193 02194 static int ieee80211_ibss_allowed(struct wpa_supplicant *wpa_s) 02195 { 02196 #if 0 /* FIX */ 02197 int m, c; 02198 02199 for (m = 0; m < local->hw->num_modes; m++) { 02200 struct ieee80211_hw_modes *mode = &local->hw->modes[m]; 02201 if (mode->mode != local->conf.phymode) 02202 continue; 02203 for (c = 0; c < mode->num_channels; c++) { 02204 struct ieee80211_channel *chan = &mode->channels[c]; 02205 if (chan->flag & IEEE80211_CHAN_W_SCAN && 02206 chan->chan == local->conf.channel) { 02207 if (chan->flag & IEEE80211_CHAN_W_IBSS) 02208 return 1; 02209 break; 02210 } 02211 } 02212 } 02213 #endif 02214 02215 return 0; 02216 } 02217 02218 02219 static int ieee80211_sta_join_ibss(struct wpa_supplicant *wpa_s, 02220 struct ieee80211_sta_bss *bss) 02221 { 02222 int res = 0, rates, done = 0, bssid_changed; 02223 struct ieee80211_mgmt *mgmt; 02224 #if 0 /* FIX */ 02225 struct ieee80211_tx_control control; 02226 struct ieee80211_rate *rate; 02227 struct rate_control_extra extra; 02228 #endif 02229 u8 *pos, *buf; 02230 size_t len; 02231 02232 /* Remove possible STA entries from other IBSS networks. */ 02233 #if 0 /* FIX */ 02234 sta_info_flush(local, NULL); 02235 02236 if (local->hw->reset_tsf) { 02237 /* Reset own TSF to allow time synchronization work. */ 02238 local->hw->reset_tsf(local->mdev); 02239 } 02240 #endif 02241 bssid_changed = os_memcmp(wpa_s->bssid, bss->bssid, ETH_ALEN); 02242 os_memcpy(wpa_s->bssid, bss->bssid, ETH_ALEN); 02243 if (bssid_changed) 02244 wpas_notify_bssid_changed(wpa_s); 02245 02246 #if 0 /* FIX */ 02247 local->conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10; 02248 02249 sdata->drop_unencrypted = bss->capability & 02250 host_to_le16(WLAN_CAPABILITY_PRIVACY) ? 1 : 0; 02251 #endif 02252 02253 #if 0 /* FIX */ 02254 os_memset(&rq, 0, sizeof(rq)); 02255 rq.m = bss->freq * 100000; 02256 rq.e = 1; 02257 res = ieee80211_ioctl_siwfreq(wpa_s, NULL, &rq, NULL); 02258 #endif 02259 02260 if (!ieee80211_ibss_allowed(wpa_s)) { 02261 #if 0 /* FIX */ 02262 wpa_printf(MSG_DEBUG, "MLME: IBSS not allowed on channel %d " 02263 "(%d MHz)", local->conf.channel, 02264 local->conf.freq); 02265 #endif 02266 return -1; 02267 } 02268 02269 /* Set beacon template based on scan results */ 02270 buf = os_malloc(400); 02271 len = 0; 02272 do { 02273 if (buf == NULL) 02274 break; 02275 02276 mgmt = (struct ieee80211_mgmt *) buf; 02277 len += 24 + sizeof(mgmt->u.beacon); 02278 os_memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); 02279 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 02280 WLAN_FC_STYPE_BEACON); 02281 os_memset(mgmt->da, 0xff, ETH_ALEN); 02282 os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 02283 os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN); 02284 #if 0 /* FIX */ 02285 mgmt->u.beacon.beacon_int = 02286 host_to_le16(local->conf.beacon_int); 02287 #endif 02288 mgmt->u.beacon.capab_info = host_to_le16(bss->capability); 02289 02290 pos = buf + len; 02291 len += 2 + wpa_s->mlme.ssid_len; 02292 *pos++ = WLAN_EID_SSID; 02293 *pos++ = wpa_s->mlme.ssid_len; 02294 os_memcpy(pos, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len); 02295 02296 rates = bss->supp_rates_len; 02297 if (rates > 8) 02298 rates = 8; 02299 pos = buf + len; 02300 len += 2 + rates; 02301 *pos++ = WLAN_EID_SUPP_RATES; 02302 *pos++ = rates; 02303 os_memcpy(pos, bss->supp_rates, rates); 02304 02305 pos = buf + len; 02306 len += 2 + 1; 02307 *pos++ = WLAN_EID_DS_PARAMS; 02308 *pos++ = 1; 02309 *pos++ = bss->channel; 02310 02311 pos = buf + len; 02312 len += 2 + 2; 02313 *pos++ = WLAN_EID_IBSS_PARAMS; 02314 *pos++ = 2; 02315 /* FIX: set ATIM window based on scan results */ 02316 *pos++ = 0; 02317 *pos++ = 0; 02318 02319 if (bss->supp_rates_len > 8) { 02320 rates = bss->supp_rates_len - 8; 02321 pos = buf + len; 02322 len += 2 + rates; 02323 *pos++ = WLAN_EID_EXT_SUPP_RATES; 02324 *pos++ = rates; 02325 os_memcpy(pos, &bss->supp_rates[8], rates); 02326 } 02327 02328 #if 0 /* FIX */ 02329 os_memset(&control, 0, sizeof(control)); 02330 control.pkt_type = PKT_PROBE_RESP; 02331 os_memset(&extra, 0, sizeof(extra)); 02332 extra.endidx = local->num_curr_rates; 02333 rate = rate_control_get_rate(wpa_s, skb, &extra); 02334 if (rate == NULL) { 02335 wpa_printf(MSG_DEBUG, "MLME: Failed to determine TX " 02336 "rate for IBSS beacon"); 02337 break; 02338 } 02339 control.tx_rate = (wpa_s->mlme.short_preamble && 02340 (rate->flags & IEEE80211_RATE_PREAMBLE2)) ? 02341 rate->val2 : rate->val; 02342 control.antenna_sel = local->conf.antenna_sel; 02343 control.power_level = local->conf.power_level; 02344 control.no_ack = 1; 02345 control.retry_limit = 1; 02346 control.rts_cts_duration = 0; 02347 #endif 02348 02349 #if 0 /* FIX */ 02350 wpa_s->mlme.probe_resp = skb_copy(skb, GFP_ATOMIC); 02351 if (wpa_s->mlme.probe_resp) { 02352 mgmt = (struct ieee80211_mgmt *) 02353 wpa_s->mlme.probe_resp->data; 02354 mgmt->frame_control = 02355 IEEE80211_FC(WLAN_FC_TYPE_MGMT, 02356 WLAN_FC_STYPE_PROBE_RESP); 02357 } else { 02358 wpa_printf(MSG_DEBUG, "MLME: Could not allocate " 02359 "ProbeResp template for IBSS"); 02360 } 02361 02362 if (local->hw->beacon_update && 02363 local->hw->beacon_update(wpa_s, skb, &control) == 0) { 02364 wpa_printf(MSG_DEBUG, "MLME: Configured IBSS beacon " 02365 "template based on scan results"); 02366 skb = NULL; 02367 } 02368 02369 rates = 0; 02370 for (i = 0; i < bss->supp_rates_len; i++) { 02371 int rate = (bss->supp_rates[i] & 0x7f) * 5; 02372 if (local->conf.phymode == MODE_ATHEROS_TURBO) 02373 rate *= 2; 02374 for (j = 0; j < local->num_curr_rates; j++) 02375 if (local->curr_rates[j] == rate) 02376 rates |= BIT(j); 02377 } 02378 wpa_s->mlme.supp_rates_bits = rates; 02379 #endif 02380 done = 1; 02381 } while (0); 02382 02383 os_free(buf); 02384 if (!done) { 02385 wpa_printf(MSG_DEBUG, "MLME: Failed to configure IBSS beacon " 02386 "template"); 02387 } 02388 02389 wpa_s->mlme.state = IEEE80211_IBSS_JOINED; 02390 ieee80211_reschedule_timer(wpa_s, IEEE80211_IBSS_MERGE_INTERVAL); 02391 02392 return res; 02393 } 02394 02395 02396 #if 0 /* FIX */ 02397 static int ieee80211_sta_create_ibss(struct wpa_supplicant *wpa_s) 02398 { 02399 struct ieee80211_sta_bss *bss; 02400 u8 bssid[ETH_ALEN], *pos; 02401 int i; 02402 02403 #if 0 02404 /* Easier testing, use fixed BSSID. */ 02405 os_memset(bssid, 0xfe, ETH_ALEN); 02406 #else 02407 /* Generate random, not broadcast, locally administered BSSID. Mix in 02408 * own MAC address to make sure that devices that do not have proper 02409 * random number generator get different BSSID. */ 02410 os_get_random(bssid, ETH_ALEN); 02411 for (i = 0; i < ETH_ALEN; i++) 02412 bssid[i] ^= wpa_s->own_addr[i]; 02413 bssid[0] &= ~0x01; 02414 bssid[0] |= 0x02; 02415 #endif 02416 02417 wpa_printf(MSG_DEBUG, "MLME: Creating new IBSS network, BSSID " 02418 MACSTR "", MAC2STR(bssid)); 02419 02420 bss = ieee80211_bss_add(wpa_s, bssid); 02421 if (bss == NULL) 02422 return -ENOMEM; 02423 02424 #if 0 /* FIX */ 02425 if (local->conf.beacon_int == 0) 02426 local->conf.beacon_int = 100; 02427 bss->beacon_int = local->conf.beacon_int; 02428 bss->hw_mode = local->conf.phymode; 02429 bss->channel = local->conf.channel; 02430 bss->freq = local->conf.freq; 02431 #endif 02432 os_get_time(&bss->last_update); 02433 bss->capability = host_to_le16(WLAN_CAPABILITY_IBSS); 02434 #if 0 /* FIX */ 02435 if (sdata->default_key) { 02436 bss->capability |= host_to_le16(WLAN_CAPABILITY_PRIVACY); 02437 } else 02438 sdata->drop_unencrypted = 0; 02439 bss->supp_rates_len = local->num_curr_rates; 02440 #endif 02441 pos = bss->supp_rates; 02442 #if 0 /* FIX */ 02443 for (i = 0; i < local->num_curr_rates; i++) { 02444 int rate = local->curr_rates[i]; 02445 if (local->conf.phymode == MODE_ATHEROS_TURBO) 02446 rate /= 2; 02447 *pos++ = (u8) (rate / 5); 02448 } 02449 #endif 02450 02451 return ieee80211_sta_join_ibss(wpa_s, bss); 02452 } 02453 #endif 02454 02455 02456 static int ieee80211_sta_find_ibss(struct wpa_supplicant *wpa_s) 02457 { 02458 struct ieee80211_sta_bss *bss; 02459 int found = 0; 02460 u8 bssid[ETH_ALEN]; 02461 int active_ibss; 02462 struct os_time now; 02463 02464 if (wpa_s->mlme.ssid_len == 0) 02465 return -EINVAL; 02466 02467 active_ibss = ieee80211_sta_active_ibss(wpa_s); 02468 #ifdef IEEE80211_IBSS_DEBUG 02469 wpa_printf(MSG_DEBUG, "MLME: sta_find_ibss (active_ibss=%d)", 02470 active_ibss); 02471 #endif /* IEEE80211_IBSS_DEBUG */ 02472 for (bss = wpa_s->mlme.sta_bss_list; bss; bss = bss->next) { 02473 if (wpa_s->mlme.ssid_len != bss->ssid_len || 02474 os_memcmp(wpa_s->mlme.ssid, bss->ssid, bss->ssid_len) != 0 02475 || !(bss->capability & WLAN_CAPABILITY_IBSS)) 02476 continue; 02477 #ifdef IEEE80211_IBSS_DEBUG 02478 wpa_printf(MSG_DEBUG, " bssid=" MACSTR " found", 02479 MAC2STR(bss->bssid)); 02480 #endif /* IEEE80211_IBSS_DEBUG */ 02481 os_memcpy(bssid, bss->bssid, ETH_ALEN); 02482 found = 1; 02483 if (active_ibss || 02484 os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0) 02485 break; 02486 } 02487 02488 #ifdef IEEE80211_IBSS_DEBUG 02489 wpa_printf(MSG_DEBUG, " sta_find_ibss: selected " MACSTR " current " 02490 MACSTR, MAC2STR(bssid), MAC2STR(wpa_s->bssid)); 02491 #endif /* IEEE80211_IBSS_DEBUG */ 02492 if (found && os_memcmp(wpa_s->bssid, bssid, ETH_ALEN) != 0 && 02493 (bss = ieee80211_bss_get(wpa_s, bssid))) { 02494 wpa_printf(MSG_DEBUG, "MLME: Selected IBSS BSSID " MACSTR 02495 " based on configured SSID", 02496 MAC2STR(bssid)); 02497 return ieee80211_sta_join_ibss(wpa_s, bss); 02498 } 02499 #ifdef IEEE80211_IBSS_DEBUG 02500 wpa_printf(MSG_DEBUG, " did not try to join ibss"); 02501 #endif /* IEEE80211_IBSS_DEBUG */ 02502 02503 /* Selected IBSS not found in current scan results - try to scan */ 02504 os_get_time(&now); 02505 #if 0 /* FIX */ 02506 if (wpa_s->mlme.state == IEEE80211_IBSS_JOINED && 02507 !ieee80211_sta_active_ibss(wpa_s)) { 02508 ieee80211_reschedule_timer(wpa_s, 02509 IEEE80211_IBSS_MERGE_INTERVAL); 02510 } else if (time_after(jiffies, wpa_s->mlme.last_scan_completed + 02511 IEEE80211_SCAN_INTERVAL)) { 02512 wpa_printf(MSG_DEBUG, "MLME: Trigger new scan to find an IBSS " 02513 "to join"); 02514 return ieee80211_sta_req_scan(wpa_s->mlme.ssid, 02515 wpa_s->mlme.ssid_len); 02516 } else if (wpa_s->mlme.state != IEEE80211_IBSS_JOINED) { 02517 int interval = IEEE80211_SCAN_INTERVAL; 02518 02519 if (time_after(jiffies, wpa_s->mlme.ibss_join_req + 02520 IEEE80211_IBSS_JOIN_TIMEOUT)) { 02521 if (wpa_s->mlme.create_ibss && 02522 ieee80211_ibss_allowed(wpa_s)) 02523 return ieee80211_sta_create_ibss(wpa_s); 02524 if (wpa_s->mlme.create_ibss) { 02525 wpa_printf(MSG_DEBUG, "MLME: IBSS not allowed " 02526 "on the configured channel %d " 02527 "(%d MHz)", 02528 local->conf.channel, 02529 local->conf.freq); 02530 } 02531 02532 /* No IBSS found - decrease scan interval and continue 02533 * scanning. */ 02534 interval = IEEE80211_SCAN_INTERVAL_SLOW; 02535 } 02536 02537 wpa_s->mlme.state = IEEE80211_IBSS_SEARCH; 02538 ieee80211_reschedule_timer(wpa_s, interval); 02539 return 0; 02540 } 02541 #endif 02542 02543 return 0; 02544 } 02545 02546 02547 int ieee80211_sta_get_ssid(struct wpa_supplicant *wpa_s, u8 *ssid, 02548 size_t *len) 02549 { 02550 os_memcpy(ssid, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len); 02551 *len = wpa_s->mlme.ssid_len; 02552 return 0; 02553 } 02554 02555 02556 int ieee80211_sta_associate(struct wpa_supplicant *wpa_s, 02557 struct wpa_driver_associate_params *params) 02558 { 02559 struct ieee80211_sta_bss *bss; 02560 int bssid_changed; 02561 02562 wpa_s->mlme.bssid_set = 0; 02563 wpa_s->mlme.freq = params->freq; 02564 if (params->bssid) { 02565 bssid_changed = os_memcmp(wpa_s->bssid, params->bssid, 02566 ETH_ALEN); 02567 os_memcpy(wpa_s->bssid, params->bssid, ETH_ALEN); 02568 if (bssid_changed) 02569 wpas_notify_bssid_changed(wpa_s); 02570 02571 if (!is_zero_ether_addr(params->bssid)) 02572 wpa_s->mlme.bssid_set = 1; 02573 bss = ieee80211_bss_get(wpa_s, wpa_s->bssid); 02574 if (bss) { 02575 wpa_s->mlme.phymode = bss->hw_mode; 02576 wpa_s->mlme.channel = bss->channel; 02577 wpa_s->mlme.freq = bss->freq; 02578 } 02579 } 02580 02581 #if 0 /* FIX */ 02582 /* TODO: This should always be done for IBSS, even if IEEE80211_QOS is 02583 * not defined. */ 02584 if (local->hw->conf_tx) { 02585 struct ieee80211_tx_queue_params qparam; 02586 int i; 02587 02588 os_memset(&qparam, 0, sizeof(qparam)); 02589 /* TODO: are these ok defaults for all hw_modes? */ 02590 qparam.aifs = 2; 02591 qparam.cw_min = 02592 local->conf.phymode == MODE_IEEE80211B ? 31 : 15; 02593 qparam.cw_max = 1023; 02594 qparam.burst_time = 0; 02595 for (i = IEEE80211_TX_QUEUE_DATA0; i < NUM_TX_DATA_QUEUES; i++) 02596 { 02597 local->hw->conf_tx(wpa_s, i + IEEE80211_TX_QUEUE_DATA0, 02598 &qparam); 02599 } 02600 /* IBSS uses different parameters for Beacon sending */ 02601 qparam.cw_min++; 02602 qparam.cw_min *= 2; 02603 qparam.cw_min--; 02604 local->hw->conf_tx(wpa_s, IEEE80211_TX_QUEUE_BEACON, &qparam); 02605 } 02606 #endif 02607 02608 if (wpa_s->mlme.ssid_len != params->ssid_len || 02609 os_memcmp(wpa_s->mlme.ssid, params->ssid, params->ssid_len) != 0) 02610 wpa_s->mlme.prev_bssid_set = 0; 02611 os_memcpy(wpa_s->mlme.ssid, params->ssid, params->ssid_len); 02612 os_memset(wpa_s->mlme.ssid + params->ssid_len, 0, 02613 MAX_SSID_LEN - params->ssid_len); 02614 wpa_s->mlme.ssid_len = params->ssid_len; 02615 wpa_s->mlme.ssid_set = 1; 02616 02617 os_free(wpa_s->mlme.extra_ie); 02618 if (params->wpa_ie == NULL || params->wpa_ie_len == 0) { 02619 wpa_s->mlme.extra_ie = NULL; 02620 wpa_s->mlme.extra_ie_len = 0; 02621 } else { 02622 wpa_s->mlme.extra_ie = os_malloc(params->wpa_ie_len); 02623 if (wpa_s->mlme.extra_ie == NULL) { 02624 wpa_s->mlme.extra_ie_len = 0; 02625 return -1; 02626 } 02627 os_memcpy(wpa_s->mlme.extra_ie, params->wpa_ie, 02628 params->wpa_ie_len); 02629 wpa_s->mlme.extra_ie_len = params->wpa_ie_len; 02630 } 02631 02632 wpa_s->mlme.key_mgmt = params->key_mgmt_suite; 02633 02634 ieee80211_sta_set_channel(wpa_s, wpa_s->mlme.phymode, 02635 wpa_s->mlme.channel, wpa_s->mlme.freq); 02636 02637 if (params->mode == WPAS_MODE_IBSS && !wpa_s->mlme.bssid_set) { 02638 os_get_time(&wpa_s->mlme.ibss_join_req); 02639 wpa_s->mlme.state = IEEE80211_IBSS_SEARCH; 02640 return ieee80211_sta_find_ibss(wpa_s); 02641 } 02642 02643 if (wpa_s->mlme.bssid_set) 02644 ieee80211_sta_new_auth(wpa_s); 02645 02646 return 0; 02647 } 02648 02649 02650 static void ieee80211_sta_save_oper_chan(struct wpa_supplicant *wpa_s) 02651 { 02652 wpa_s->mlme.scan_oper_channel = wpa_s->mlme.channel; 02653 wpa_s->mlme.scan_oper_freq = wpa_s->mlme.freq; 02654 wpa_s->mlme.scan_oper_phymode = wpa_s->mlme.phymode; 02655 } 02656 02657 02658 static int ieee80211_sta_restore_oper_chan(struct wpa_supplicant *wpa_s) 02659 { 02660 wpa_s->mlme.channel = wpa_s->mlme.scan_oper_channel; 02661 wpa_s->mlme.freq = wpa_s->mlme.scan_oper_freq; 02662 wpa_s->mlme.phymode = wpa_s->mlme.scan_oper_phymode; 02663 if (wpa_s->mlme.freq == 0) 02664 return 0; 02665 return ieee80211_sta_set_channel(wpa_s, wpa_s->mlme.phymode, 02666 wpa_s->mlme.channel, 02667 wpa_s->mlme.freq); 02668 } 02669 02670 02671 static int ieee80211_active_scan(struct wpa_supplicant *wpa_s) 02672 { 02673 size_t m; 02674 int c; 02675 02676 for (m = 0; m < wpa_s->mlme.num_modes; m++) { 02677 struct hostapd_hw_modes *mode = &wpa_s->mlme.modes[m]; 02678 if ((int) mode->mode != (int) wpa_s->mlme.phymode) 02679 continue; 02680 for (c = 0; c < mode->num_channels; c++) { 02681 struct hostapd_channel_data *chan = &mode->channels[c]; 02682 if (!(chan->flag & HOSTAPD_CHAN_DISABLED) && 02683 chan->chan == wpa_s->mlme.channel) { 02684 if (!(chan->flag & HOSTAPD_CHAN_PASSIVE_SCAN)) 02685 return 1; 02686 break; 02687 } 02688 } 02689 } 02690 02691 return 0; 02692 } 02693 02694 02695 static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx) 02696 { 02697 struct wpa_supplicant *wpa_s = eloop_ctx; 02698 struct hostapd_hw_modes *mode; 02699 struct hostapd_channel_data *chan; 02700 int skip = 0; 02701 int timeout = 0; 02702 struct wpa_ssid *ssid = wpa_s->current_ssid; 02703 int adhoc; 02704 02705 if (!wpa_s->mlme.sta_scanning || wpa_s->mlme.modes == NULL) 02706 return; 02707 02708 adhoc = ssid && ssid->mode == 1; 02709 02710 switch (wpa_s->mlme.scan_state) { 02711 case SCAN_SET_CHANNEL: 02712 mode = &wpa_s->mlme.modes[wpa_s->mlme.scan_hw_mode_idx]; 02713 if (wpa_s->mlme.scan_hw_mode_idx >= 02714 (int) wpa_s->mlme.num_modes || 02715 (wpa_s->mlme.scan_hw_mode_idx + 1 == 02716 (int) wpa_s->mlme.num_modes 02717 && wpa_s->mlme.scan_channel_idx >= mode->num_channels)) { 02718 if (ieee80211_sta_restore_oper_chan(wpa_s)) { 02719 wpa_printf(MSG_DEBUG, "MLME: failed to " 02720 "restore operational channel after " 02721 "scan"); 02722 } 02723 wpa_printf(MSG_DEBUG, "MLME: scan completed"); 02724 wpa_s->mlme.sta_scanning = 0; 02725 os_get_time(&wpa_s->mlme.last_scan_completed); 02726 wpa_supplicant_event(wpa_s, EVENT_SCAN_RESULTS, NULL); 02727 if (adhoc) { 02728 if (!wpa_s->mlme.bssid_set || 02729 (wpa_s->mlme.state == 02730 IEEE80211_IBSS_JOINED && 02731 !ieee80211_sta_active_ibss(wpa_s))) 02732 ieee80211_sta_find_ibss(wpa_s); 02733 } 02734 return; 02735 } 02736 skip = !(wpa_s->mlme.hw_modes & (1 << mode->mode)); 02737 chan = &mode->channels[wpa_s->mlme.scan_channel_idx]; 02738 if ((chan->flag & HOSTAPD_CHAN_DISABLED) || 02739 (adhoc && (chan->flag & HOSTAPD_CHAN_NO_IBSS)) || 02740 (wpa_s->mlme.hw_modes & (1 << HOSTAPD_MODE_IEEE80211G) && 02741 mode->mode == HOSTAPD_MODE_IEEE80211B && 02742 wpa_s->mlme.scan_skip_11b)) 02743 skip = 1; 02744 if (!skip && wpa_s->mlme.scan_freqs) { 02745 int i, found = 0; 02746 for (i = 0; wpa_s->mlme.scan_freqs[i]; i++) { 02747 if (wpa_s->mlme.scan_freqs[i] == chan->freq) { 02748 found = 1; 02749 break; 02750 } 02751 } 02752 if (!found) 02753 skip = 1; 02754 } 02755 02756 if (!skip) { 02757 wpa_printf(MSG_MSGDUMP, 02758 "MLME: scan channel %d (%d MHz)", 02759 chan->chan, chan->freq); 02760 02761 wpa_s->mlme.channel = chan->chan; 02762 wpa_s->mlme.freq = chan->freq; 02763 wpa_s->mlme.phymode = mode->mode; 02764 if (ieee80211_sta_set_channel(wpa_s, mode->mode, 02765 chan->chan, chan->freq)) 02766 { 02767 wpa_printf(MSG_DEBUG, "MLME: failed to set " 02768 "channel %d (%d MHz) for scan", 02769 chan->chan, chan->freq); 02770 skip = 1; 02771 } 02772 } 02773 02774 wpa_s->mlme.scan_channel_idx++; 02775 if (wpa_s->mlme.scan_channel_idx >= 02776 wpa_s->mlme.modes[wpa_s->mlme.scan_hw_mode_idx]. 02777 num_channels) { 02778 wpa_s->mlme.scan_hw_mode_idx++; 02779 wpa_s->mlme.scan_channel_idx = 0; 02780 } 02781 02782 if (skip) { 02783 timeout = 0; 02784 break; 02785 } 02786 02787 timeout = IEEE80211_PROBE_DELAY; 02788 wpa_s->mlme.scan_state = SCAN_SEND_PROBE; 02789 break; 02790 case SCAN_SEND_PROBE: 02791 if (ieee80211_active_scan(wpa_s)) { 02792 ieee80211_send_probe_req(wpa_s, NULL, 02793 wpa_s->mlme.scan_ssid, 02794 wpa_s->mlme.scan_ssid_len); 02795 timeout = IEEE80211_CHANNEL_TIME; 02796 } else { 02797 timeout = IEEE80211_PASSIVE_CHANNEL_TIME; 02798 } 02799 wpa_s->mlme.scan_state = SCAN_SET_CHANNEL; 02800 break; 02801 } 02802 02803 eloop_register_timeout(timeout / 1000, 1000 * (timeout % 1000), 02804 ieee80211_sta_scan_timer, wpa_s, NULL); 02805 } 02806 02807 02808 int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s, 02809 struct wpa_driver_scan_params *params) 02810 { 02811 const u8 *ssid = params->ssids[0].ssid; 02812 size_t ssid_len = params->ssids[0].ssid_len; 02813 02814 if (ssid_len > MAX_SSID_LEN) 02815 return -1; 02816 02817 /* MLME-SCAN.request (page 118) page 144 (11.1.3.1) 02818 * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS 02819 * BSSID: MACAddress 02820 * SSID 02821 * ScanType: ACTIVE, PASSIVE 02822 * ProbeDelay: delay (in microseconds) to be used prior to transmitting 02823 * a Probe frame during active scanning 02824 * ChannelList 02825 * MinChannelTime (>= ProbeDelay), in TU 02826 * MaxChannelTime: (>= MinChannelTime), in TU 02827 */ 02828 02829 /* MLME-SCAN.confirm 02830 * BSSDescriptionSet 02831 * ResultCode: SUCCESS, INVALID_PARAMETERS 02832 */ 02833 02834 /* TODO: if assoc, move to power save mode for the duration of the 02835 * scan */ 02836 02837 if (wpa_s->mlme.sta_scanning) 02838 return -1; 02839 02840 wpa_printf(MSG_DEBUG, "MLME: starting scan"); 02841 02842 ieee80211_sta_set_probe_req_ie(wpa_s, params->extra_ies, 02843 params->extra_ies_len); 02844 02845 os_free(wpa_s->mlme.scan_freqs); 02846 if (params->freqs) { 02847 int i; 02848 for (i = 0; params->freqs[i]; i++) 02849 ; 02850 wpa_s->mlme.scan_freqs = os_malloc((i + 1) * sizeof(int)); 02851 if (wpa_s->mlme.scan_freqs) 02852 os_memcpy(wpa_s->mlme.scan_freqs, params->freqs, 02853 (i + 1) * sizeof(int)); 02854 } else 02855 wpa_s->mlme.scan_freqs = NULL; 02856 02857 ieee80211_sta_save_oper_chan(wpa_s); 02858 02859 wpa_s->mlme.sta_scanning = 1; 02860 /* TODO: stop TX queue? */ 02861 02862 if (ssid) { 02863 wpa_s->mlme.scan_ssid_len = ssid_len; 02864 os_memcpy(wpa_s->mlme.scan_ssid, ssid, ssid_len); 02865 } else 02866 wpa_s->mlme.scan_ssid_len = 0; 02867 wpa_s->mlme.scan_skip_11b = 1; /* FIX: clear this is 11g is not 02868 * supported */ 02869 wpa_s->mlme.scan_state = SCAN_SET_CHANNEL; 02870 wpa_s->mlme.scan_hw_mode_idx = 0; 02871 wpa_s->mlme.scan_channel_idx = 0; 02872 eloop_register_timeout(0, 1, ieee80211_sta_scan_timer, wpa_s, NULL); 02873 02874 return 0; 02875 } 02876 02877 02878 struct wpa_scan_results * 02879 ieee80211_sta_get_scan_results(struct wpa_supplicant *wpa_s) 02880 { 02881 size_t ap_num = 0; 02882 struct wpa_scan_results *res; 02883 struct wpa_scan_res *r; 02884 struct ieee80211_sta_bss *bss; 02885 02886 res = os_zalloc(sizeof(*res)); 02887 for (bss = wpa_s->mlme.sta_bss_list; bss; bss = bss->next) 02888 ap_num++; 02889 res->res = os_zalloc(ap_num * sizeof(struct wpa_scan_res *)); 02890 if (res->res == NULL) { 02891 os_free(res); 02892 return NULL; 02893 } 02894 02895 for (bss = wpa_s->mlme.sta_bss_list; bss; bss = bss->next) { 02896 r = os_zalloc(sizeof(*r) + bss->ie_len); 02897 if (r == NULL) 02898 break; 02899 os_memcpy(r->bssid, bss->bssid, ETH_ALEN); 02900 r->freq = bss->freq; 02901 r->beacon_int = bss->beacon_int; 02902 r->caps = bss->capability; 02903 r->level = bss->rssi; 02904 r->tsf = bss->timestamp; 02905 if (bss->ie) { 02906 r->ie_len = bss->ie_len; 02907 os_memcpy(r + 1, bss->ie, bss->ie_len); 02908 } 02909 02910 res->res[res->num++] = r; 02911 } 02912 02913 return res; 02914 } 02915 02916 02917 #if 0 /* FIX */ 02918 struct sta_info * ieee80211_ibss_add_sta(struct wpa_supplicant *wpa_s, 02919 struct sk_buff *skb, u8 *bssid, 02920 u8 *addr) 02921 { 02922 struct ieee80211_local *local = dev->priv; 02923 struct list_head *ptr; 02924 struct sta_info *sta; 02925 struct wpa_supplicant *sta_dev = NULL; 02926 02927 /* TODO: Could consider removing the least recently used entry and 02928 * allow new one to be added. */ 02929 if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { 02930 if (net_ratelimit()) { 02931 wpa_printf(MSG_DEBUG, "MLME: No room for a new IBSS " 02932 "STA entry " MACSTR, MAC2STR(addr)); 02933 } 02934 return NULL; 02935 } 02936 02937 spin_lock_bh(&local->sub_if_lock); 02938 list_for_each(ptr, &local->sub_if_list) { 02939 sdata = list_entry(ptr, struct ieee80211_sub_if_data, list); 02940 if (sdata->type == IEEE80211_SUB_IF_TYPE_STA && 02941 os_memcmp(bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) { 02942 sta_dev = sdata->dev; 02943 break; 02944 } 02945 } 02946 spin_unlock_bh(&local->sub_if_lock); 02947 02948 if (sta_dev == NULL) 02949 return NULL; 02950 02951 wpa_printf(MSG_DEBUG, "MLME: Adding new IBSS station " MACSTR 02952 " (dev=%s)", MAC2STR(addr), sta_dev->name); 02953 02954 sta = sta_info_add(wpa_s, addr); 02955 if (sta == NULL) { 02956 return NULL; 02957 } 02958 02959 sta->dev = sta_dev; 02960 sta->supp_rates = wpa_s->mlme.supp_rates_bits; 02961 02962 rate_control_rate_init(local, sta); 02963 02964 return sta; /* caller will call sta_info_release() */ 02965 } 02966 #endif 02967 02968 02969 int ieee80211_sta_deauthenticate(struct wpa_supplicant *wpa_s, u16 reason) 02970 { 02971 wpa_printf(MSG_DEBUG, "MLME: deauthenticate(reason=%d)", reason); 02972 02973 ieee80211_send_deauth(wpa_s, reason); 02974 ieee80211_set_associated(wpa_s, 0); 02975 return 0; 02976 } 02977 02978 02979 int ieee80211_sta_disassociate(struct wpa_supplicant *wpa_s, u16 reason) 02980 { 02981 wpa_printf(MSG_DEBUG, "MLME: disassociate(reason=%d)", reason); 02982 02983 if (!wpa_s->mlme.associated) 02984 return -1; 02985 02986 ieee80211_send_disassoc(wpa_s, reason); 02987 ieee80211_set_associated(wpa_s, 0); 02988 return 0; 02989 } 02990 02991 02992 void ieee80211_sta_rx(struct wpa_supplicant *wpa_s, const u8 *buf, size_t len, 02993 struct ieee80211_rx_status *rx_status) 02994 { 02995 struct ieee80211_mgmt *mgmt; 02996 u16 fc; 02997 const u8 *pos; 02998 02999 /* wpa_hexdump(MSG_MSGDUMP, "MLME: Received frame", buf, len); */ 03000 03001 if (wpa_s->mlme.sta_scanning) { 03002 ieee80211_sta_rx_scan(wpa_s, buf, len, rx_status); 03003 return; 03004 } 03005 03006 if (len < 24) 03007 return; 03008 03009 mgmt = (struct ieee80211_mgmt *) buf; 03010 fc = le_to_host16(mgmt->frame_control); 03011 03012 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT) 03013 ieee80211_sta_rx_mgmt(wpa_s, buf, len, rx_status); 03014 else if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) { 03015 if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) != 03016 WLAN_FC_FROMDS) 03017 return; 03018 /* mgmt->sa is actually BSSID for FromDS data frames */ 03019 if (os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) != 0) 03020 return; 03021 /* Skip IEEE 802.11 and LLC headers */ 03022 pos = buf + 24 + 6; 03023 if (WPA_GET_BE16(pos) != ETH_P_EAPOL) 03024 return; 03025 pos += 2; 03026 /* mgmt->bssid is actually BSSID for SA data frames */ 03027 wpa_supplicant_rx_eapol(wpa_s, mgmt->bssid, 03028 pos, buf + len - pos); 03029 } 03030 } 03031 03032 03033 void ieee80211_sta_free_hw_features(struct hostapd_hw_modes *hw_features, 03034 size_t num_hw_features) 03035 { 03036 size_t i; 03037 03038 if (hw_features == NULL) 03039 return; 03040 03041 for (i = 0; i < num_hw_features; i++) { 03042 os_free(hw_features[i].channels); 03043 os_free(hw_features[i].rates); 03044 } 03045 03046 os_free(hw_features); 03047 } 03048 03049 03050 int ieee80211_sta_init(struct wpa_supplicant *wpa_s) 03051 { 03052 u16 num_modes, flags; 03053 03054 wpa_s->mlme.modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, 03055 &flags); 03056 if (wpa_s->mlme.modes == NULL) { 03057 wpa_printf(MSG_ERROR, "MLME: Failed to read supported " 03058 "channels and rates from the driver"); 03059 return -1; 03060 } 03061 03062 wpa_s->mlme.num_modes = num_modes; 03063 03064 wpa_s->mlme.hw_modes = 1 << HOSTAPD_MODE_IEEE80211A; 03065 wpa_s->mlme.hw_modes |= 1 << HOSTAPD_MODE_IEEE80211B; 03066 wpa_s->mlme.hw_modes |= 1 << HOSTAPD_MODE_IEEE80211G; 03067 03068 wpa_s->mlme.wmm_enabled = 1; 03069 03070 return 0; 03071 } 03072 03073 03074 void ieee80211_sta_deinit(struct wpa_supplicant *wpa_s) 03075 { 03076 eloop_cancel_timeout(ieee80211_sta_timer, wpa_s, NULL); 03077 eloop_cancel_timeout(ieee80211_sta_scan_timer, wpa_s, NULL); 03078 os_free(wpa_s->mlme.extra_ie); 03079 wpa_s->mlme.extra_ie = NULL; 03080 os_free(wpa_s->mlme.extra_probe_ie); 03081 wpa_s->mlme.extra_probe_ie = NULL; 03082 os_free(wpa_s->mlme.assocreq_ies); 03083 wpa_s->mlme.assocreq_ies = NULL; 03084 os_free(wpa_s->mlme.assocresp_ies); 03085 wpa_s->mlme.assocresp_ies = NULL; 03086 ieee80211_bss_list_deinit(wpa_s); 03087 ieee80211_sta_free_hw_features(wpa_s->mlme.modes, 03088 wpa_s->mlme.num_modes); 03089 #ifdef CONFIG_IEEE80211R 03090 os_free(wpa_s->mlme.ft_ies); 03091 wpa_s->mlme.ft_ies = NULL; 03092 wpa_s->mlme.ft_ies_len = 0; 03093 #endif /* CONFIG_IEEE80211R */ 03094 03095 os_free(wpa_s->mlme.scan_freqs); 03096 wpa_s->mlme.scan_freqs = NULL; 03097 } 03098 03099 03100 #ifdef CONFIG_IEEE80211R 03101 03102 int ieee80211_sta_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md, 03103 const u8 *ies, size_t ies_len) 03104 { 03105 if (md == NULL) { 03106 wpa_printf(MSG_DEBUG, "MLME: Clear FT mobility domain"); 03107 os_memset(wpa_s->mlme.current_md, 0, MOBILITY_DOMAIN_ID_LEN); 03108 } else { 03109 wpa_printf(MSG_DEBUG, "MLME: Update FT IEs for MD " MACSTR, 03110 MAC2STR(md)); 03111 os_memcpy(wpa_s->mlme.current_md, md, MOBILITY_DOMAIN_ID_LEN); 03112 } 03113 03114 wpa_hexdump(MSG_DEBUG, "MLME: FT IEs", ies, ies_len); 03115 os_free(wpa_s->mlme.ft_ies); 03116 wpa_s->mlme.ft_ies = os_malloc(ies_len); 03117 if (wpa_s->mlme.ft_ies == NULL) 03118 return -1; 03119 os_memcpy(wpa_s->mlme.ft_ies, ies, ies_len); 03120 wpa_s->mlme.ft_ies_len = ies_len; 03121 03122 return 0; 03123 } 03124 03125 03126 int ieee80211_sta_send_ft_action(struct wpa_supplicant *wpa_s, u8 action, 03127 const u8 *target_ap, 03128 const u8 *ies, size_t ies_len) 03129 { 03130 u8 *buf; 03131 size_t len; 03132 struct ieee80211_mgmt *mgmt; 03133 int res; 03134 03135 /* 03136 * Action frame payload: 03137 * Category[1] = 6 (Fast BSS Transition) 03138 * Action[1] = 1 (Fast BSS Transition Request) 03139 * STA Address 03140 * Target AP Address 03141 * FT IEs 03142 */ 03143 03144 buf = os_zalloc(sizeof(*mgmt) + ies_len); 03145 if (buf == NULL) { 03146 wpa_printf(MSG_DEBUG, "MLME: Failed to allocate buffer for " 03147 "FT action frame"); 03148 return -1; 03149 } 03150 03151 mgmt = (struct ieee80211_mgmt *) buf; 03152 len = 24; 03153 os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN); 03154 os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 03155 os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN); 03156 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 03157 WLAN_FC_STYPE_ACTION); 03158 mgmt->u.action.category = WLAN_ACTION_FT; 03159 mgmt->u.action.u.ft_action_req.action = action; 03160 os_memcpy(mgmt->u.action.u.ft_action_req.sta_addr, wpa_s->own_addr, 03161 ETH_ALEN); 03162 os_memcpy(mgmt->u.action.u.ft_action_req.target_ap_addr, target_ap, 03163 ETH_ALEN); 03164 os_memcpy(mgmt->u.action.u.ft_action_req.variable, ies, ies_len); 03165 len += 1 + sizeof(mgmt->u.action.u.ft_action_req) + ies_len; 03166 03167 wpa_printf(MSG_DEBUG, "MLME: Send FT Action Frame: Action=%d " 03168 "Target AP=" MACSTR " body_len=%lu", 03169 action, MAC2STR(target_ap), (unsigned long) ies_len); 03170 03171 res = ieee80211_sta_tx(wpa_s, buf, len); 03172 os_free(buf); 03173 03174 return res; 03175 } 03176 03177 #endif /* CONFIG_IEEE80211R */ 03178 03179 03180 static int ieee80211_sta_set_probe_req_ie(struct wpa_supplicant *wpa_s, 03181 const u8 *ies, size_t ies_len) 03182 { 03183 os_free(wpa_s->mlme.extra_probe_ie); 03184 wpa_s->mlme.extra_probe_ie = NULL; 03185 wpa_s->mlme.extra_probe_ie_len = 0; 03186 03187 if (ies == NULL) 03188 return 0; 03189 03190 wpa_s->mlme.extra_probe_ie = os_malloc(ies_len); 03191 if (wpa_s->mlme.extra_probe_ie == NULL) 03192 return -1; 03193 03194 os_memcpy(wpa_s->mlme.extra_probe_ie, ies, ies_len); 03195 wpa_s->mlme.extra_probe_ie_len = ies_len; 03196 03197 return 0; 03198 }