1/* 2 * WPA Supplicant - Client mode MLME 3 * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> 4 * Copyright (c) 2004, Instant802 Networks, Inc. 5 * Copyright (c) 2005-2006, Devicescape Software, Inc. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * Alternatively, this software may be distributed under the terms of BSD 12 * license. 13 * 14 * See README and COPYING for more details. 15 */ 16 17#include "includes.h" 18 19#include "common.h" 20#include "eloop.h" 21#include "config_ssid.h" 22#include "wpa_supplicant_i.h" 23#include "wpa.h" 24#include "drivers/driver.h" 25#include "ieee802_11_defs.h" 26#include "ieee802_11_common.h" 27#include "mlme.h" 28 29 30/* Timeouts and intervals in milliseconds */ 31#define IEEE80211_AUTH_TIMEOUT (200) 32#define IEEE80211_AUTH_MAX_TRIES 3 33#define IEEE80211_ASSOC_TIMEOUT (200) 34#define IEEE80211_ASSOC_MAX_TRIES 3 35#define IEEE80211_MONITORING_INTERVAL (2000) 36#define IEEE80211_PROBE_INTERVAL (60000) 37#define IEEE80211_RETRY_AUTH_INTERVAL (1000) 38#define IEEE80211_SCAN_INTERVAL (2000) 39#define IEEE80211_SCAN_INTERVAL_SLOW (15000) 40#define IEEE80211_IBSS_JOIN_TIMEOUT (20000) 41 42#define IEEE80211_PROBE_DELAY (33) 43#define IEEE80211_CHANNEL_TIME (33) 44#define IEEE80211_PASSIVE_CHANNEL_TIME (200) 45#define IEEE80211_SCAN_RESULT_EXPIRE (10000) 46#define IEEE80211_IBSS_MERGE_INTERVAL (30000) 47#define IEEE80211_IBSS_INACTIVITY_LIMIT (60000) 48 49#define IEEE80211_IBSS_MAX_STA_ENTRIES 128 50 51 52#define IEEE80211_FC(type, stype) host_to_le16((type << 2) | (stype << 4)) 53 54 55struct ieee80211_sta_bss { 56 struct ieee80211_sta_bss *next; 57 struct ieee80211_sta_bss *hnext; 58 59 u8 bssid[ETH_ALEN]; 60 u8 ssid[MAX_SSID_LEN]; 61 size_t ssid_len; 62 u16 capability; /* host byte order */ 63 int hw_mode; 64 int channel; 65 int freq; 66 int rssi; 67 u8 *ie; 68 size_t ie_len; 69 u8 *wpa_ie; 70 size_t wpa_ie_len; 71 u8 *rsn_ie; 72 size_t rsn_ie_len; 73 u8 *wmm_ie; 74 size_t wmm_ie_len; 75 u8 *mdie; 76 size_t mdie_len; 77#define IEEE80211_MAX_SUPP_RATES 32 78 u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; 79 size_t supp_rates_len; 80 int beacon_int; 81 u64 timestamp; 82 83 int probe_resp; 84 struct os_time last_update; 85}; 86 87 88static void ieee80211_send_probe_req(struct wpa_supplicant *wpa_s, 89 const u8 *dst, 90 const u8 *ssid, size_t ssid_len); 91static struct ieee80211_sta_bss * 92ieee80211_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid); 93static int ieee80211_sta_find_ibss(struct wpa_supplicant *wpa_s); 94static int ieee80211_sta_wep_configured(struct wpa_supplicant *wpa_s); 95static void ieee80211_sta_timer(void *eloop_ctx, void *timeout_ctx); 96static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx); 97 98 99static int ieee80211_sta_set_channel(struct wpa_supplicant *wpa_s, 100 wpa_hw_mode phymode, int chan, 101 int freq) 102{ 103 size_t i; 104 struct wpa_hw_modes *mode; 105 106 for (i = 0; i < wpa_s->mlme.num_modes; i++) { 107 mode = &wpa_s->mlme.modes[i]; 108 if (mode->mode == phymode) { 109 wpa_s->mlme.curr_rates = mode->rates; 110 wpa_s->mlme.num_curr_rates = mode->num_rates; 111 break; 112 } 113 } 114 115 return wpa_drv_set_channel(wpa_s, phymode, chan, freq); 116} 117 118 119 120#if 0 /* FIX */ 121static int ecw2cw(int ecw) 122{ 123 int cw = 1; 124 while (ecw > 0) { 125 cw <<= 1; 126 ecw--; 127 } 128 return cw - 1; 129} 130#endif 131 132 133static void ieee80211_sta_wmm_params(struct wpa_supplicant *wpa_s, 134 u8 *wmm_param, size_t wmm_param_len) 135{ 136 size_t left; 137 int count; 138 u8 *pos; 139 140 if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) 141 return; 142 count = wmm_param[6] & 0x0f; 143 if (count == wpa_s->mlme.wmm_last_param_set) 144 return; 145 wpa_s->mlme.wmm_last_param_set = count; 146 147 pos = wmm_param + 8; 148 left = wmm_param_len - 8; 149 150#if 0 /* FIX */ 151 wmm_acm = 0; 152 for (; left >= 4; left -= 4, pos += 4) { 153 int aci = (pos[0] >> 5) & 0x03; 154 int acm = (pos[0] >> 4) & 0x01; 155 int queue; 156 157 switch (aci) { 158 case 1: 159 queue = IEEE80211_TX_QUEUE_DATA3; 160 if (acm) 161 wmm_acm |= BIT(1) | BIT(2); 162 break; 163 case 2: 164 queue = IEEE80211_TX_QUEUE_DATA1; 165 if (acm) 166 wmm_acm |= BIT(4) | BIT(5); 167 break; 168 case 3: 169 queue = IEEE80211_TX_QUEUE_DATA0; 170 if (acm) 171 wmm_acm |= BIT(6) | BIT(7); 172 break; 173 case 0: 174 default: 175 queue = IEEE80211_TX_QUEUE_DATA2; 176 if (acm) 177 wpa_s->mlme.wmm_acm |= BIT(0) | BIT(3); 178 break; 179 } 180 181 params.aifs = pos[0] & 0x0f; 182 params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4); 183 params.cw_min = ecw2cw(pos[1] & 0x0f); 184 /* TXOP is in units of 32 usec; burst_time in 0.1 ms */ 185 params.burst_time = (pos[2] | (pos[3] << 8)) * 32 / 100; 186 wpa_printf(MSG_DEBUG, "MLME: WMM queue=%d aci=%d acm=%d " 187 "aifs=%d cWmin=%d cWmax=%d burst=%d", 188 queue, aci, acm, params.aifs, params.cw_min, 189 params.cw_max, params.burst_time); 190 /* TODO: handle ACM (block TX, fallback to next lowest allowed 191 * AC for now) */ 192 if (local->hw->conf_tx(local->mdev, queue, ¶ms)) { 193 wpa_printf(MSG_DEBUG, "MLME: failed to set TX queue " 194 "parameters for queue %d", queue); 195 } 196 } 197#endif 198} 199 200 201static void ieee80211_set_associated(struct wpa_supplicant *wpa_s, int assoc) 202{ 203 if (wpa_s->mlme.associated == assoc && !assoc) 204 return; 205 206 wpa_s->mlme.associated = assoc; 207 208 if (assoc) { 209 union wpa_event_data data; 210 os_memset(&data, 0, sizeof(data)); 211 wpa_s->mlme.prev_bssid_set = 1; 212 os_memcpy(wpa_s->mlme.prev_bssid, wpa_s->bssid, ETH_ALEN); 213 data.assoc_info.req_ies = wpa_s->mlme.assocreq_ies; 214 data.assoc_info.req_ies_len = wpa_s->mlme.assocreq_ies_len; 215 data.assoc_info.resp_ies = wpa_s->mlme.assocresp_ies; 216 data.assoc_info.resp_ies_len = wpa_s->mlme.assocresp_ies_len; 217 wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data); 218 } else { 219 wpa_supplicant_event(wpa_s, EVENT_DISASSOC, NULL); 220 } 221 os_get_time(&wpa_s->mlme.last_probe); 222} 223 224 225static int ieee80211_sta_tx(struct wpa_supplicant *wpa_s, const u8 *buf, 226 size_t len) 227{ 228 return wpa_drv_send_mlme(wpa_s, buf, len); 229} 230 231 232static void ieee80211_send_auth(struct wpa_supplicant *wpa_s, 233 int transaction, u8 *extra, size_t extra_len, 234 int encrypt) 235{ 236 u8 *buf; 237 size_t len; 238 struct ieee80211_mgmt *mgmt; 239 240 buf = os_malloc(sizeof(*mgmt) + 6 + extra_len); 241 if (buf == NULL) { 242 wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for " 243 "auth frame"); 244 return; 245 } 246 247 mgmt = (struct ieee80211_mgmt *) buf; 248 len = 24 + 6; 249 os_memset(mgmt, 0, 24 + 6); 250 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 251 WLAN_FC_STYPE_AUTH); 252 if (encrypt) 253 mgmt->frame_control |= host_to_le16(WLAN_FC_ISWEP); 254 os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN); 255 os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 256 os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN); 257 mgmt->u.auth.auth_alg = host_to_le16(wpa_s->mlme.auth_alg); 258 mgmt->u.auth.auth_transaction = host_to_le16(transaction); 259 wpa_s->mlme.auth_transaction = transaction + 1; 260 mgmt->u.auth.status_code = host_to_le16(0); 261 if (extra) { 262 os_memcpy(buf + len, extra, extra_len); 263 len += extra_len; 264 } 265 266 ieee80211_sta_tx(wpa_s, buf, len); 267 os_free(buf); 268} 269 270 271static void ieee80211_reschedule_timer(struct wpa_supplicant *wpa_s, int ms) 272{ 273 eloop_cancel_timeout(ieee80211_sta_timer, wpa_s, NULL); 274 eloop_register_timeout(ms / 1000, 1000 * (ms % 1000), 275 ieee80211_sta_timer, wpa_s, NULL); 276} 277 278 279static void ieee80211_authenticate(struct wpa_supplicant *wpa_s) 280{ 281 u8 *extra; 282 size_t extra_len; 283 284 wpa_s->mlme.auth_tries++; 285 if (wpa_s->mlme.auth_tries > IEEE80211_AUTH_MAX_TRIES) { 286 wpa_printf(MSG_DEBUG, "MLME: authentication with AP " MACSTR 287 " timed out", MAC2STR(wpa_s->bssid)); 288 return; 289 } 290 291 wpa_s->mlme.state = IEEE80211_AUTHENTICATE; 292 wpa_printf(MSG_DEBUG, "MLME: authenticate with AP " MACSTR, 293 MAC2STR(wpa_s->bssid)); 294 295 extra = NULL; 296 extra_len = 0; 297 298#ifdef CONFIG_IEEE80211R 299 if ((wpa_s->mlme.key_mgmt == KEY_MGMT_FT_802_1X || 300 wpa_s->mlme.key_mgmt == KEY_MGMT_FT_PSK) && 301 wpa_s->mlme.ft_ies) { 302 struct ieee80211_sta_bss *bss; 303 struct rsn_mdie *mdie = NULL; 304 bss = ieee80211_bss_get(wpa_s, wpa_s->bssid); 305 if (bss && bss->mdie_len >= 2 + sizeof(*mdie)) 306 mdie = (struct rsn_mdie *) (bss->mdie + 2); 307 if (mdie && 308 os_memcmp(mdie->mobility_domain, wpa_s->mlme.current_md, 309 MOBILITY_DOMAIN_ID_LEN) == 0) { 310 wpa_printf(MSG_DEBUG, "MLME: Trying to use FT " 311 "over-the-air"); 312 wpa_s->mlme.auth_alg = WLAN_AUTH_FT; 313 extra = wpa_s->mlme.ft_ies; 314 extra_len = wpa_s->mlme.ft_ies_len; 315 } 316 } 317#endif /* CONFIG_IEEE80211R */ 318 319 ieee80211_send_auth(wpa_s, 1, extra, extra_len, 0); 320 321 ieee80211_reschedule_timer(wpa_s, IEEE80211_AUTH_TIMEOUT); 322} 323 324 325static void ieee80211_send_assoc(struct wpa_supplicant *wpa_s) 326{ 327 struct ieee80211_mgmt *mgmt; 328 u8 *pos, *ies, *buf; 329 int i, len; 330 u16 capab; 331 struct ieee80211_sta_bss *bss; 332 int wmm = 0; 333 size_t blen, buflen; 334 335 if (wpa_s->mlme.curr_rates == NULL) { 336 wpa_printf(MSG_DEBUG, "MLME: curr_rates not set for assoc"); 337 return; 338 } 339 340 buflen = sizeof(*mgmt) + 200 + wpa_s->mlme.extra_ie_len + 341 wpa_s->mlme.ssid_len; 342#ifdef CONFIG_IEEE80211R 343 if (wpa_s->mlme.ft_ies) 344 buflen += wpa_s->mlme.ft_ies_len; 345#endif /* CONFIG_IEEE80211R */ 346 buf = os_malloc(buflen); 347 if (buf == NULL) { 348 wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for " 349 "assoc frame"); 350 return; 351 } 352 blen = 0; 353 354 capab = wpa_s->mlme.capab; 355 if (wpa_s->mlme.phymode == WPA_MODE_IEEE80211G) { 356 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME | 357 WLAN_CAPABILITY_SHORT_PREAMBLE; 358 } 359 bss = ieee80211_bss_get(wpa_s, wpa_s->bssid); 360 if (bss) { 361 if (bss->capability & WLAN_CAPABILITY_PRIVACY) 362 capab |= WLAN_CAPABILITY_PRIVACY; 363 if (bss->wmm_ie) { 364 wmm = 1; 365 } 366 } 367 368 mgmt = (struct ieee80211_mgmt *) buf; 369 blen += 24; 370 os_memset(mgmt, 0, 24); 371 os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN); 372 os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 373 os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN); 374 375 if (wpa_s->mlme.prev_bssid_set) { 376 blen += 10; 377 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 378 WLAN_FC_STYPE_REASSOC_REQ); 379 mgmt->u.reassoc_req.capab_info = host_to_le16(capab); 380 mgmt->u.reassoc_req.listen_interval = host_to_le16(1); 381 os_memcpy(mgmt->u.reassoc_req.current_ap, 382 wpa_s->mlme.prev_bssid, 383 ETH_ALEN); 384 } else { 385 blen += 4; 386 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 387 WLAN_FC_STYPE_ASSOC_REQ); 388 mgmt->u.assoc_req.capab_info = host_to_le16(capab); 389 mgmt->u.assoc_req.listen_interval = host_to_le16(1); 390 } 391 392 /* SSID */ 393 ies = pos = buf + blen; 394 blen += 2 + wpa_s->mlme.ssid_len; 395 *pos++ = WLAN_EID_SSID; 396 *pos++ = wpa_s->mlme.ssid_len; 397 os_memcpy(pos, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len); 398 399 len = wpa_s->mlme.num_curr_rates; 400 if (len > 8) 401 len = 8; 402 pos = buf + blen; 403 blen += len + 2; 404 *pos++ = WLAN_EID_SUPP_RATES; 405 *pos++ = len; 406 for (i = 0; i < len; i++) { 407 int rate = wpa_s->mlme.curr_rates[i].rate; 408 *pos++ = (u8) (rate / 5); 409 } 410 411 if (wpa_s->mlme.num_curr_rates > len) { 412 pos = buf + blen; 413 blen += wpa_s->mlme.num_curr_rates - len + 2; 414 *pos++ = WLAN_EID_EXT_SUPP_RATES; 415 *pos++ = wpa_s->mlme.num_curr_rates - len; 416 for (i = len; i < wpa_s->mlme.num_curr_rates; i++) { 417 int rate = wpa_s->mlme.curr_rates[i].rate; 418 *pos++ = (u8) (rate / 5); 419 } 420 } 421 422 if (wpa_s->mlme.extra_ie && wpa_s->mlme.auth_alg != WLAN_AUTH_FT) { 423 pos = buf + blen; 424 blen += wpa_s->mlme.extra_ie_len; 425 os_memcpy(pos, wpa_s->mlme.extra_ie, wpa_s->mlme.extra_ie_len); 426 } 427 428#ifdef CONFIG_IEEE80211R 429 if ((wpa_s->mlme.key_mgmt == KEY_MGMT_FT_802_1X || 430 wpa_s->mlme.key_mgmt == KEY_MGMT_FT_PSK) && 431 wpa_s->mlme.auth_alg != WLAN_AUTH_FT && 432 bss && bss->mdie && 433 bss->mdie_len >= 2 + sizeof(struct rsn_mdie) && 434 bss->mdie[1] >= sizeof(struct rsn_mdie)) { 435 pos = buf + blen; 436 blen += 2 + sizeof(struct rsn_mdie); 437 *pos++ = WLAN_EID_MOBILITY_DOMAIN; 438 *pos++ = sizeof(struct rsn_mdie); 439 os_memcpy(pos, bss->mdie + 2, MOBILITY_DOMAIN_ID_LEN); 440 pos += MOBILITY_DOMAIN_ID_LEN; 441 *pos++ = 0; /* FIX: copy from the target AP's MDIE */ 442 } 443 444 if ((wpa_s->mlme.key_mgmt == KEY_MGMT_FT_802_1X || 445 wpa_s->mlme.key_mgmt == KEY_MGMT_FT_PSK) && 446 wpa_s->mlme.auth_alg == WLAN_AUTH_FT && wpa_s->mlme.ft_ies) { 447 pos = buf + blen; 448 os_memcpy(pos, wpa_s->mlme.ft_ies, wpa_s->mlme.ft_ies_len); 449 pos += wpa_s->mlme.ft_ies_len; 450 blen += wpa_s->mlme.ft_ies_len; 451 } 452#endif /* CONFIG_IEEE80211R */ 453 454 if (wmm && wpa_s->mlme.wmm_enabled) { 455 pos = buf + blen; 456 blen += 9; 457 *pos++ = WLAN_EID_VENDOR_SPECIFIC; 458 *pos++ = 7; /* len */ 459 *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */ 460 *pos++ = 0x50; 461 *pos++ = 0xf2; 462 *pos++ = 2; /* WMM */ 463 *pos++ = 0; /* WMM info */ 464 *pos++ = 1; /* WMM ver */ 465 *pos++ = 0; 466 } 467 468 os_free(wpa_s->mlme.assocreq_ies); 469 wpa_s->mlme.assocreq_ies_len = (buf + blen) - ies; 470 wpa_s->mlme.assocreq_ies = os_malloc(wpa_s->mlme.assocreq_ies_len); 471 if (wpa_s->mlme.assocreq_ies) { 472 os_memcpy(wpa_s->mlme.assocreq_ies, ies, 473 wpa_s->mlme.assocreq_ies_len); 474 } 475 476 ieee80211_sta_tx(wpa_s, buf, blen); 477 os_free(buf); 478} 479 480 481static void ieee80211_send_deauth(struct wpa_supplicant *wpa_s, u16 reason) 482{ 483 u8 *buf; 484 size_t len; 485 struct ieee80211_mgmt *mgmt; 486 487 buf = os_zalloc(sizeof(*mgmt)); 488 if (buf == NULL) { 489 wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for " 490 "deauth frame"); 491 return; 492 } 493 494 mgmt = (struct ieee80211_mgmt *) buf; 495 len = 24; 496 os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN); 497 os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 498 os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN); 499 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 500 WLAN_FC_STYPE_DEAUTH); 501 len += 2; 502 mgmt->u.deauth.reason_code = host_to_le16(reason); 503 504 ieee80211_sta_tx(wpa_s, buf, len); 505 os_free(buf); 506} 507 508 509static void ieee80211_send_disassoc(struct wpa_supplicant *wpa_s, u16 reason) 510{ 511 u8 *buf; 512 size_t len; 513 struct ieee80211_mgmt *mgmt; 514 515 buf = os_zalloc(sizeof(*mgmt)); 516 if (buf == NULL) { 517 wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for " 518 "disassoc frame"); 519 return; 520 } 521 522 mgmt = (struct ieee80211_mgmt *) buf; 523 len = 24; 524 os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN); 525 os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 526 os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN); 527 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 528 WLAN_FC_STYPE_DISASSOC); 529 len += 2; 530 mgmt->u.disassoc.reason_code = host_to_le16(reason); 531 532 ieee80211_sta_tx(wpa_s, buf, len); 533 os_free(buf); 534} 535 536 537static int ieee80211_privacy_mismatch(struct wpa_supplicant *wpa_s) 538{ 539 struct ieee80211_sta_bss *bss; 540 int res = 0; 541 542 if (wpa_s->mlme.mixed_cell || 543 wpa_s->mlme.key_mgmt != KEY_MGMT_NONE) 544 return 0; 545 546 bss = ieee80211_bss_get(wpa_s, wpa_s->bssid); 547 if (bss == NULL) 548 return 0; 549 550 if (ieee80211_sta_wep_configured(wpa_s) != 551 !!(bss->capability & WLAN_CAPABILITY_PRIVACY)) 552 res = 1; 553 554 return res; 555} 556 557 558static void ieee80211_associate(struct wpa_supplicant *wpa_s) 559{ 560 wpa_s->mlme.assoc_tries++; 561 if (wpa_s->mlme.assoc_tries > IEEE80211_ASSOC_MAX_TRIES) { 562 wpa_printf(MSG_DEBUG, "MLME: association with AP " MACSTR 563 " timed out", MAC2STR(wpa_s->bssid)); 564 return; 565 } 566 567 wpa_s->mlme.state = IEEE80211_ASSOCIATE; 568 wpa_printf(MSG_DEBUG, "MLME: associate with AP " MACSTR, 569 MAC2STR(wpa_s->bssid)); 570 if (ieee80211_privacy_mismatch(wpa_s)) { 571 wpa_printf(MSG_DEBUG, "MLME: mismatch in privacy " 572 "configuration and mixed-cell disabled - abort " 573 "association"); 574 return; 575 } 576 577 ieee80211_send_assoc(wpa_s); 578 579 ieee80211_reschedule_timer(wpa_s, IEEE80211_ASSOC_TIMEOUT); 580} 581 582 583static void ieee80211_associated(struct wpa_supplicant *wpa_s) 584{ 585 int disassoc; 586 587 /* TODO: start monitoring current AP signal quality and number of 588 * missed beacons. Scan other channels every now and then and search 589 * for better APs. */ 590 /* TODO: remove expired BSSes */ 591 592 wpa_s->mlme.state = IEEE80211_ASSOCIATED; 593 594#if 0 /* FIX */ 595 sta = sta_info_get(local, wpa_s->bssid); 596 if (sta == NULL) { 597 wpa_printf(MSG_DEBUG "MLME: No STA entry for own AP " MACSTR, 598 MAC2STR(wpa_s->bssid)); 599 disassoc = 1; 600 } else { 601 disassoc = 0; 602 if (time_after(jiffies, 603 sta->last_rx + IEEE80211_MONITORING_INTERVAL)) { 604 if (wpa_s->mlme.probereq_poll) { 605 wpa_printf(MSG_DEBUG "MLME: No ProbeResp from " 606 "current AP " MACSTR " - assume " 607 "out of range", 608 MAC2STR(wpa_s->bssid)); 609 disassoc = 1; 610 } else { 611 ieee80211_send_probe_req( 612 wpa_s->bssid, 613 wpa_s->mlme.scan_ssid, 614 wpa_s->mlme.scan_ssid_len); 615 wpa_s->mlme.probereq_poll = 1; 616 } 617 } else { 618 wpa_s->mlme.probereq_poll = 0; 619 if (time_after(jiffies, wpa_s->mlme.last_probe + 620 IEEE80211_PROBE_INTERVAL)) { 621 wpa_s->mlme.last_probe = jiffies; 622 ieee80211_send_probe_req(wpa_s->bssid, 623 wpa_s->mlme.ssid, 624 wpa_s->mlme.ssid_len); 625 } 626 } 627 sta_info_release(local, sta); 628 } 629#else 630 disassoc = 0; 631#endif 632 if (disassoc) { 633 wpa_supplicant_event(wpa_s, EVENT_DISASSOC, NULL); 634 ieee80211_reschedule_timer(wpa_s, 635 IEEE80211_MONITORING_INTERVAL + 636 30000); 637 } else { 638 ieee80211_reschedule_timer(wpa_s, 639 IEEE80211_MONITORING_INTERVAL); 640 } 641} 642 643 644static void ieee80211_send_probe_req(struct wpa_supplicant *wpa_s, 645 const u8 *dst, 646 const u8 *ssid, size_t ssid_len) 647{ 648 u8 *buf; 649 size_t len; 650 struct ieee80211_mgmt *mgmt; 651 u8 *pos, *supp_rates; 652 u8 *esupp_rates = NULL; 653 int i; 654 655 buf = os_malloc(sizeof(*mgmt) + 200 + wpa_s->mlme.extra_probe_ie_len); 656 if (buf == NULL) { 657 wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for " 658 "probe request"); 659 return; 660 } 661 662 mgmt = (struct ieee80211_mgmt *) buf; 663 len = 24; 664 os_memset(mgmt, 0, 24); 665 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 666 WLAN_FC_STYPE_PROBE_REQ); 667 os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 668 if (dst) { 669 os_memcpy(mgmt->da, dst, ETH_ALEN); 670 os_memcpy(mgmt->bssid, dst, ETH_ALEN); 671 } else { 672 os_memset(mgmt->da, 0xff, ETH_ALEN); 673 os_memset(mgmt->bssid, 0xff, ETH_ALEN); 674 } 675 pos = buf + len; 676 len += 2 + ssid_len; 677 *pos++ = WLAN_EID_SSID; 678 *pos++ = ssid_len; 679 os_memcpy(pos, ssid, ssid_len); 680 681 supp_rates = buf + len; 682 len += 2; 683 supp_rates[0] = WLAN_EID_SUPP_RATES; 684 supp_rates[1] = 0; 685 for (i = 0; i < wpa_s->mlme.num_curr_rates; i++) { 686 struct wpa_rate_data *rate = &wpa_s->mlme.curr_rates[i]; 687 if (esupp_rates) { 688 pos = buf + len; 689 len++; 690 esupp_rates[1]++; 691 } else if (supp_rates[1] == 8) { 692 esupp_rates = pos; 693 esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES; 694 esupp_rates[1] = 1; 695 pos = &esupp_rates[2]; 696 len += 3; 697 } else { 698 pos = buf + len; 699 len++; 700 supp_rates[1]++; 701 } 702 *pos++ = rate->rate / 5; 703 } 704 705 if (wpa_s->mlme.extra_probe_ie) { 706 os_memcpy(pos, wpa_s->mlme.extra_probe_ie, 707 wpa_s->mlme.extra_probe_ie_len); 708 len += wpa_s->mlme.extra_probe_ie_len; 709 } 710 711 ieee80211_sta_tx(wpa_s, buf, len); 712 os_free(buf); 713} 714 715 716static int ieee80211_sta_wep_configured(struct wpa_supplicant *wpa_s) 717{ 718#if 0 /* FIX */ 719 if (sdata == NULL || sdata->default_key == NULL || 720 sdata->default_key->alg != ALG_WEP) 721 return 0; 722 return 1; 723#else 724 return 0; 725#endif 726} 727 728 729static void ieee80211_auth_completed(struct wpa_supplicant *wpa_s) 730{ 731 wpa_printf(MSG_DEBUG, "MLME: authenticated"); 732 wpa_s->mlme.authenticated = 1; 733 ieee80211_associate(wpa_s); 734} 735 736 737static void ieee80211_auth_challenge(struct wpa_supplicant *wpa_s, 738 struct ieee80211_mgmt *mgmt, 739 size_t len, 740 struct ieee80211_rx_status *rx_status) 741{ 742 u8 *pos; 743 struct ieee802_11_elems elems; 744 745 wpa_printf(MSG_DEBUG, "MLME: replying to auth challenge"); 746 pos = mgmt->u.auth.variable; 747 if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems, 0) 748 == ParseFailed) { 749 wpa_printf(MSG_DEBUG, "MLME: failed to parse Auth(challenge)"); 750 return; 751 } 752 if (elems.challenge == NULL) { 753 wpa_printf(MSG_DEBUG, "MLME: no challenge IE in shared key " 754 "auth frame"); 755 return; 756 } 757 ieee80211_send_auth(wpa_s, 3, elems.challenge - 2, 758 elems.challenge_len + 2, 1); 759} 760 761 762static void ieee80211_rx_mgmt_auth(struct wpa_supplicant *wpa_s, 763 struct ieee80211_mgmt *mgmt, 764 size_t len, 765 struct ieee80211_rx_status *rx_status) 766{ 767 struct wpa_ssid *ssid = wpa_s->current_ssid; 768 u16 auth_alg, auth_transaction, status_code; 769 int adhoc; 770 771 adhoc = ssid && ssid->mode == 1; 772 773 if (wpa_s->mlme.state != IEEE80211_AUTHENTICATE && !adhoc) { 774 wpa_printf(MSG_DEBUG, "MLME: authentication frame received " 775 "from " MACSTR ", but not in authenticate state - " 776 "ignored", MAC2STR(mgmt->sa)); 777 return; 778 } 779 780 if (len < 24 + 6) { 781 wpa_printf(MSG_DEBUG, "MLME: too short (%lu) authentication " 782 "frame received from " MACSTR " - ignored", 783 (unsigned long) len, MAC2STR(mgmt->sa)); 784 return; 785 } 786 787 if (!adhoc && os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) { 788 wpa_printf(MSG_DEBUG, "MLME: authentication frame received " 789 "from unknown AP (SA=" MACSTR " BSSID=" MACSTR 790 ") - ignored", 791 MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid)); 792 return; 793 } 794 795 if (adhoc && os_memcmp(wpa_s->bssid, mgmt->bssid, ETH_ALEN) != 0) { 796 wpa_printf(MSG_DEBUG, "MLME: authentication frame received " 797 "from unknown BSSID (SA=" MACSTR " BSSID=" MACSTR 798 ") - ignored", 799 MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid)); 800 return; 801 } 802 803 auth_alg = le_to_host16(mgmt->u.auth.auth_alg); 804 auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction); 805 status_code = le_to_host16(mgmt->u.auth.status_code); 806 807 wpa_printf(MSG_DEBUG, "MLME: RX authentication from " MACSTR 808 " (alg=%d transaction=%d status=%d)", 809 MAC2STR(mgmt->sa), auth_alg, auth_transaction, status_code); 810 811 if (adhoc) { 812 /* IEEE 802.11 standard does not require authentication in IBSS 813 * networks and most implementations do not seem to use it. 814 * However, try to reply to authentication attempts if someone 815 * has actually implemented this. 816 * TODO: Could implement shared key authentication. */ 817 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) { 818 wpa_printf(MSG_DEBUG, "MLME: unexpected IBSS " 819 "authentication frame (alg=%d " 820 "transaction=%d)", 821 auth_alg, auth_transaction); 822 return; 823 } 824 ieee80211_send_auth(wpa_s, 2, NULL, 0, 0); 825 } 826 827 if (auth_alg != wpa_s->mlme.auth_alg || 828 auth_transaction != wpa_s->mlme.auth_transaction) { 829 wpa_printf(MSG_DEBUG, "MLME: unexpected authentication frame " 830 "(alg=%d transaction=%d)", 831 auth_alg, auth_transaction); 832 return; 833 } 834 835 if (status_code != WLAN_STATUS_SUCCESS) { 836 wpa_printf(MSG_DEBUG, "MLME: AP denied authentication " 837 "(auth_alg=%d code=%d)", wpa_s->mlme.auth_alg, 838 status_code); 839 if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) { 840 const int num_algs = 3; 841 u8 algs[num_algs]; 842 int i, pos; 843 algs[0] = algs[1] = algs[2] = 0xff; 844 if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_OPEN) 845 algs[0] = WLAN_AUTH_OPEN; 846 if (wpa_s->mlme.auth_algs & 847 IEEE80211_AUTH_ALG_SHARED_KEY) 848 algs[1] = WLAN_AUTH_SHARED_KEY; 849 if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_LEAP) 850 algs[2] = WLAN_AUTH_LEAP; 851 if (wpa_s->mlme.auth_alg == WLAN_AUTH_OPEN) 852 pos = 0; 853 else if (wpa_s->mlme.auth_alg == WLAN_AUTH_SHARED_KEY) 854 pos = 1; 855 else 856 pos = 2; 857 for (i = 0; i < num_algs; i++) { 858 pos++; 859 if (pos >= num_algs) 860 pos = 0; 861 if (algs[pos] == wpa_s->mlme.auth_alg || 862 algs[pos] == 0xff) 863 continue; 864 if (algs[pos] == WLAN_AUTH_SHARED_KEY && 865 !ieee80211_sta_wep_configured(wpa_s)) 866 continue; 867 wpa_s->mlme.auth_alg = algs[pos]; 868 wpa_printf(MSG_DEBUG, "MLME: set auth_alg=%d " 869 "for next try", 870 wpa_s->mlme.auth_alg); 871 break; 872 } 873 } 874 return; 875 } 876 877 switch (wpa_s->mlme.auth_alg) { 878 case WLAN_AUTH_OPEN: 879 case WLAN_AUTH_LEAP: 880 ieee80211_auth_completed(wpa_s); 881 break; 882 case WLAN_AUTH_SHARED_KEY: 883 if (wpa_s->mlme.auth_transaction == 4) 884 ieee80211_auth_completed(wpa_s); 885 else 886 ieee80211_auth_challenge(wpa_s, mgmt, len, 887 rx_status); 888 break; 889#ifdef CONFIG_IEEE80211R 890 case WLAN_AUTH_FT: 891 { 892 union wpa_event_data data; 893 os_memset(&data, 0, sizeof(data)); 894 data.ft_ies.ies = mgmt->u.auth.variable; 895 data.ft_ies.ies_len = len - 896 (mgmt->u.auth.variable - (u8 *) mgmt); 897 os_memcpy(data.ft_ies.target_ap, wpa_s->bssid, ETH_ALEN); 898 wpa_supplicant_event(wpa_s, EVENT_FT_RESPONSE, &data); 899 ieee80211_auth_completed(wpa_s); 900 break; 901 } 902#endif /* CONFIG_IEEE80211R */ 903 } 904} 905 906 907static void ieee80211_rx_mgmt_deauth(struct wpa_supplicant *wpa_s, 908 struct ieee80211_mgmt *mgmt, 909 size_t len, 910 struct ieee80211_rx_status *rx_status) 911{ 912 u16 reason_code; 913 914 if (len < 24 + 2) { 915 wpa_printf(MSG_DEBUG, "MLME: too short (%lu) deauthentication " 916 "frame received from " MACSTR " - ignored", 917 (unsigned long) len, MAC2STR(mgmt->sa)); 918 return; 919 } 920 921 if (os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) { 922 wpa_printf(MSG_DEBUG, "MLME: deauthentication frame received " 923 "from unknown AP (SA=" MACSTR " BSSID=" MACSTR 924 ") - ignored", 925 MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid)); 926 return; 927 } 928 929 reason_code = le_to_host16(mgmt->u.deauth.reason_code); 930 931 wpa_printf(MSG_DEBUG, "MLME: RX deauthentication from " MACSTR 932 " (reason=%d)", MAC2STR(mgmt->sa), reason_code); 933 934 if (wpa_s->mlme.authenticated) 935 wpa_printf(MSG_DEBUG, "MLME: deauthenticated"); 936 937 if (wpa_s->mlme.state == IEEE80211_AUTHENTICATE || 938 wpa_s->mlme.state == IEEE80211_ASSOCIATE || 939 wpa_s->mlme.state == IEEE80211_ASSOCIATED) { 940 wpa_s->mlme.state = IEEE80211_AUTHENTICATE; 941 ieee80211_reschedule_timer(wpa_s, 942 IEEE80211_RETRY_AUTH_INTERVAL); 943 } 944 945 ieee80211_set_associated(wpa_s, 0); 946 wpa_s->mlme.authenticated = 0; 947} 948 949 950static void ieee80211_rx_mgmt_disassoc(struct wpa_supplicant *wpa_s, 951 struct ieee80211_mgmt *mgmt, 952 size_t len, 953 struct ieee80211_rx_status *rx_status) 954{ 955 u16 reason_code; 956 957 if (len < 24 + 2) { 958 wpa_printf(MSG_DEBUG, "MLME: too short (%lu) disassociation " 959 "frame received from " MACSTR " - ignored", 960 (unsigned long) len, MAC2STR(mgmt->sa)); 961 return; 962 } 963 964 if (os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) { 965 wpa_printf(MSG_DEBUG, "MLME: disassociation frame received " 966 "from unknown AP (SA=" MACSTR " BSSID=" MACSTR 967 ") - ignored", 968 MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid)); 969 return; 970 } 971 972 reason_code = le_to_host16(mgmt->u.disassoc.reason_code); 973 974 wpa_printf(MSG_DEBUG, "MLME: RX disassociation from " MACSTR 975 " (reason=%d)", MAC2STR(mgmt->sa), reason_code); 976 977 if (wpa_s->mlme.associated) 978 wpa_printf(MSG_DEBUG, "MLME: disassociated"); 979 980 if (wpa_s->mlme.state == IEEE80211_ASSOCIATED) { 981 wpa_s->mlme.state = IEEE80211_ASSOCIATE; 982 ieee80211_reschedule_timer(wpa_s, 983 IEEE80211_RETRY_AUTH_INTERVAL); 984 } 985 986 ieee80211_set_associated(wpa_s, 0); 987} 988 989 990static int ieee80211_ft_assoc_resp(struct wpa_supplicant *wpa_s, 991 struct ieee802_11_elems *elems) 992{ 993#ifdef CONFIG_IEEE80211R 994 const u8 *mobility_domain = NULL; 995 const u8 *r0kh_id = NULL; 996 size_t r0kh_id_len = 0; 997 const u8 *r1kh_id = NULL; 998 struct rsn_ftie *hdr; 999 const u8 *pos, *end; 1000 1001 if (elems->mdie && elems->mdie_len >= MOBILITY_DOMAIN_ID_LEN) 1002 mobility_domain = elems->mdie; 1003 if (elems->ftie && elems->ftie_len >= sizeof(struct rsn_ftie)) { 1004 end = elems->ftie + elems->ftie_len; 1005 hdr = (struct rsn_ftie *) elems->ftie; 1006 pos = (const u8 *) (hdr + 1); 1007 while (pos + 1 < end) { 1008 if (pos + 2 + pos[1] > end) 1009 break; 1010 if (pos[0] == FTIE_SUBELEM_R1KH_ID && 1011 pos[1] == FT_R1KH_ID_LEN) 1012 r1kh_id = pos + 2; 1013 else if (pos[0] == FTIE_SUBELEM_R0KH_ID && 1014 pos[1] >= 1 && pos[1] <= FT_R0KH_ID_MAX_LEN) { 1015 r0kh_id = pos + 2; 1016 r0kh_id_len = pos[1]; 1017 } 1018 pos += 2 + pos[1]; 1019 } 1020 } 1021 return wpa_sm_set_ft_params(wpa_s->wpa, mobility_domain, r0kh_id, 1022 r0kh_id_len, r1kh_id); 1023#else /* CONFIG_IEEE80211R */ 1024 return 0; 1025#endif /* CONFIG_IEEE80211R */ 1026} 1027 1028 1029static void ieee80211_rx_mgmt_assoc_resp(struct wpa_supplicant *wpa_s, 1030 struct ieee80211_mgmt *mgmt, 1031 size_t len, 1032 struct ieee80211_rx_status *rx_status, 1033 int reassoc) 1034{ 1035 u8 rates[32]; 1036 size_t rates_len; 1037 u16 capab_info, status_code, aid; 1038 struct ieee802_11_elems elems; 1039 u8 *pos; 1040 1041 /* AssocResp and ReassocResp have identical structure, so process both 1042 * of them in this function. */ 1043 1044 if (wpa_s->mlme.state != IEEE80211_ASSOCIATE) { 1045 wpa_printf(MSG_DEBUG, "MLME: association frame received from " 1046 MACSTR ", but not in associate state - ignored", 1047 MAC2STR(mgmt->sa)); 1048 return; 1049 } 1050 1051 if (len < 24 + 6) { 1052 wpa_printf(MSG_DEBUG, "MLME: too short (%lu) association " 1053 "frame received from " MACSTR " - ignored", 1054 (unsigned long) len, MAC2STR(mgmt->sa)); 1055 return; 1056 } 1057 1058 if (os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) { 1059 wpa_printf(MSG_DEBUG, "MLME: association frame received from " 1060 "unknown AP (SA=" MACSTR " BSSID=" MACSTR ") - " 1061 "ignored", MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid)); 1062 return; 1063 } 1064 1065 capab_info = le_to_host16(mgmt->u.assoc_resp.capab_info); 1066 status_code = le_to_host16(mgmt->u.assoc_resp.status_code); 1067 aid = le_to_host16(mgmt->u.assoc_resp.aid); 1068 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) 1069 wpa_printf(MSG_DEBUG, "MLME: invalid aid value %d; bits 15:14 " 1070 "not set", aid); 1071 aid &= ~(BIT(15) | BIT(14)); 1072 1073 wpa_printf(MSG_DEBUG, "MLME: RX %sssocResp from " MACSTR 1074 " (capab=0x%x status=%d aid=%d)", 1075 reassoc ? "Rea" : "A", MAC2STR(mgmt->sa), 1076 capab_info, status_code, aid); 1077 1078 pos = mgmt->u.assoc_resp.variable; 1079 if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems, 0) 1080 == ParseFailed) { 1081 wpa_printf(MSG_DEBUG, "MLME: failed to parse AssocResp"); 1082 return; 1083 } 1084 1085 if (status_code != WLAN_STATUS_SUCCESS) { 1086 wpa_printf(MSG_DEBUG, "MLME: AP denied association (code=%d)", 1087 status_code); 1088#ifdef CONFIG_IEEE80211W 1089 if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY && 1090 elems.timeout_int && elems.timeout_int_len == 5 && 1091 elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) { 1092 u32 tu, ms; 1093 tu = WPA_GET_LE32(elems.timeout_int + 1); 1094 ms = tu * 1024 / 1000; 1095 wpa_printf(MSG_DEBUG, "MLME: AP rejected association " 1096 "temporarily; comeback duration %u TU " 1097 "(%u ms)", tu, ms); 1098 if (ms > IEEE80211_ASSOC_TIMEOUT) { 1099 wpa_printf(MSG_DEBUG, "MLME: Update timer " 1100 "based on comeback duration"); 1101 ieee80211_reschedule_timer(wpa_s, ms); 1102 } 1103 } 1104#endif /* CONFIG_IEEE80211W */ 1105 return; 1106 } 1107 1108 if (elems.supp_rates == NULL) { 1109 wpa_printf(MSG_DEBUG, "MLME: no SuppRates element in " 1110 "AssocResp"); 1111 return; 1112 } 1113 1114 if (wpa_s->mlme.auth_alg == WLAN_AUTH_FT) { 1115 if (!reassoc) { 1116 wpa_printf(MSG_DEBUG, "MLME: AP tried to use " 1117 "association, not reassociation, response " 1118 "with FT"); 1119 return; 1120 } 1121 if (wpa_ft_validate_reassoc_resp( 1122 wpa_s->wpa, pos, len - (pos - (u8 *) mgmt), 1123 mgmt->sa) < 0) { 1124 wpa_printf(MSG_DEBUG, "MLME: FT validation of Reassoc" 1125 "Resp failed"); 1126 return; 1127 } 1128 } else if (ieee80211_ft_assoc_resp(wpa_s, &elems) < 0) 1129 return; 1130 1131 wpa_printf(MSG_DEBUG, "MLME: associated"); 1132 wpa_s->mlme.aid = aid; 1133 wpa_s->mlme.ap_capab = capab_info; 1134 1135 os_free(wpa_s->mlme.assocresp_ies); 1136 wpa_s->mlme.assocresp_ies_len = len - (pos - (u8 *) mgmt); 1137 wpa_s->mlme.assocresp_ies = os_malloc(wpa_s->mlme.assocresp_ies_len); 1138 if (wpa_s->mlme.assocresp_ies) { 1139 os_memcpy(wpa_s->mlme.assocresp_ies, pos, 1140 wpa_s->mlme.assocresp_ies_len); 1141 } 1142 1143 ieee80211_set_associated(wpa_s, 1); 1144 1145 rates_len = elems.supp_rates_len; 1146 if (rates_len > sizeof(rates)) 1147 rates_len = sizeof(rates); 1148 os_memcpy(rates, elems.supp_rates, rates_len); 1149 if (elems.ext_supp_rates) { 1150 size_t _len = elems.ext_supp_rates_len; 1151 if (_len > sizeof(rates) - rates_len) 1152 _len = sizeof(rates) - rates_len; 1153 os_memcpy(rates + rates_len, elems.ext_supp_rates, _len); 1154 rates_len += _len; 1155 } 1156 1157 if (wpa_drv_set_bssid(wpa_s, wpa_s->bssid) < 0) { 1158 wpa_printf(MSG_DEBUG, "MLME: failed to set BSSID for the " 1159 "netstack"); 1160 } 1161 if (wpa_drv_set_ssid(wpa_s, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len) < 1162 0) { 1163 wpa_printf(MSG_DEBUG, "MLME: failed to set SSID for the " 1164 "netstack"); 1165 } 1166 1167 /* Remove STA entry before adding a new one just in case to avoid 1168 * problems with existing configuration (e.g., keys). */ 1169 wpa_drv_mlme_remove_sta(wpa_s, wpa_s->bssid); 1170 if (wpa_drv_mlme_add_sta(wpa_s, wpa_s->bssid, rates, rates_len) < 0) { 1171 wpa_printf(MSG_DEBUG, "MLME: failed to add STA entry to the " 1172 "netstack"); 1173 } 1174 1175#if 0 /* FIX? */ 1176 sta->assoc_ap = 1; 1177 1178 if (elems.wmm && wpa_s->mlme.wmm_enabled) { 1179 sta->flags |= WLAN_STA_WMM; 1180 ieee80211_sta_wmm_params(wpa_s, elems.wmm, elems.wmm_len); 1181 } 1182#endif 1183 1184 ieee80211_associated(wpa_s); 1185} 1186 1187 1188/* Caller must hold local->sta_bss_lock */ 1189static void __ieee80211_bss_hash_add(struct wpa_supplicant *wpa_s, 1190 struct ieee80211_sta_bss *bss) 1191{ 1192 bss->hnext = wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)]; 1193 wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)] = bss; 1194} 1195 1196 1197/* Caller must hold local->sta_bss_lock */ 1198static void __ieee80211_bss_hash_del(struct wpa_supplicant *wpa_s, 1199 struct ieee80211_sta_bss *bss) 1200{ 1201 struct ieee80211_sta_bss *b, *prev = NULL; 1202 b = wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)]; 1203 while (b) { 1204 if (b == bss) { 1205 if (prev == NULL) { 1206 wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)] 1207 = bss->hnext; 1208 } else { 1209 prev->hnext = bss->hnext; 1210 } 1211 break; 1212 } 1213 prev = b; 1214 b = b->hnext; 1215 } 1216} 1217 1218 1219static struct ieee80211_sta_bss * 1220ieee80211_bss_add(struct wpa_supplicant *wpa_s, const u8 *bssid) 1221{ 1222 struct ieee80211_sta_bss *bss; 1223 1224 bss = os_zalloc(sizeof(*bss)); 1225 if (bss == NULL) 1226 return NULL; 1227 os_memcpy(bss->bssid, bssid, ETH_ALEN); 1228 1229 /* TODO: order by RSSI? */ 1230 bss->next = wpa_s->mlme.sta_bss_list; 1231 wpa_s->mlme.sta_bss_list = bss; 1232 __ieee80211_bss_hash_add(wpa_s, bss); 1233 return bss; 1234} 1235 1236 1237static struct ieee80211_sta_bss * 1238ieee80211_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid) 1239{ 1240 struct ieee80211_sta_bss *bss; 1241 1242 bss = wpa_s->mlme.sta_bss_hash[STA_HASH(bssid)]; 1243 while (bss) { 1244 if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0) 1245 break; 1246 bss = bss->hnext; 1247 } 1248 return bss; 1249} 1250 1251 1252static void ieee80211_bss_free(struct wpa_supplicant *wpa_s, 1253 struct ieee80211_sta_bss *bss) 1254{ 1255 __ieee80211_bss_hash_del(wpa_s, bss); 1256 os_free(bss->ie); 1257 os_free(bss->wpa_ie); 1258 os_free(bss->rsn_ie); 1259 os_free(bss->wmm_ie); 1260 os_free(bss->mdie); 1261 os_free(bss); 1262} 1263 1264 1265static void ieee80211_bss_list_deinit(struct wpa_supplicant *wpa_s) 1266{ 1267 struct ieee80211_sta_bss *bss, *prev; 1268 1269 bss = wpa_s->mlme.sta_bss_list; 1270 wpa_s->mlme.sta_bss_list = NULL; 1271 while (bss) { 1272 prev = bss; 1273 bss = bss->next; 1274 ieee80211_bss_free(wpa_s, prev); 1275 } 1276} 1277 1278 1279static void ieee80211_bss_info(struct wpa_supplicant *wpa_s, 1280 struct ieee80211_mgmt *mgmt, 1281 size_t len, 1282 struct ieee80211_rx_status *rx_status, 1283 int beacon) 1284{ 1285 struct ieee802_11_elems elems; 1286 size_t baselen; 1287 int channel, invalid = 0, clen; 1288 struct ieee80211_sta_bss *bss; 1289 u64 timestamp; 1290 u8 *pos, *ie_pos; 1291 size_t ie_len; 1292 1293 if (!beacon && os_memcmp(mgmt->da, wpa_s->own_addr, ETH_ALEN)) 1294 return; /* ignore ProbeResp to foreign address */ 1295 1296#if 0 1297 wpa_printf(MSG_MSGDUMP, "MLME: RX %s from " MACSTR " to " MACSTR, 1298 beacon ? "Beacon" : "Probe Response", 1299 MAC2STR(mgmt->sa), MAC2STR(mgmt->da)); 1300#endif 1301 1302 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; 1303 if (baselen > len) 1304 return; 1305 1306 pos = mgmt->u.beacon.timestamp; 1307 timestamp = WPA_GET_LE64(pos); 1308 1309#if 0 /* FIX */ 1310 if (local->conf.mode == IW_MODE_ADHOC && beacon && 1311 os_memcmp(mgmt->bssid, local->bssid, ETH_ALEN) == 0) { 1312#ifdef IEEE80211_IBSS_DEBUG 1313 static unsigned long last_tsf_debug = 0; 1314 u64 tsf; 1315 if (local->hw->get_tsf) 1316 tsf = local->hw->get_tsf(local->mdev); 1317 else 1318 tsf = -1LLU; 1319 if (time_after(jiffies, last_tsf_debug + 5 * HZ)) { 1320 wpa_printf(MSG_DEBUG, "RX beacon SA=" MACSTR " BSSID=" 1321 MACSTR " TSF=0x%llx BCN=0x%llx diff=%lld " 1322 "@%ld", 1323 MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid), 1324 tsf, timestamp, tsf - timestamp, jiffies); 1325 last_tsf_debug = jiffies; 1326 } 1327#endif /* IEEE80211_IBSS_DEBUG */ 1328 } 1329#endif 1330 1331 ie_pos = mgmt->u.beacon.variable; 1332 ie_len = len - baselen; 1333 if (ieee802_11_parse_elems(ie_pos, ie_len, &elems, 0) == ParseFailed) 1334 invalid = 1; 1335 1336#if 0 /* FIX */ 1337 if (local->conf.mode == IW_MODE_ADHOC && elems.supp_rates && 1338 os_memcmp(mgmt->bssid, local->bssid, ETH_ALEN) == 0 && 1339 (sta = sta_info_get(local, mgmt->sa))) { 1340 struct ieee80211_rate *rates; 1341 size_t num_rates; 1342 u32 supp_rates, prev_rates; 1343 int i, j, oper_mode; 1344 1345 rates = local->curr_rates; 1346 num_rates = local->num_curr_rates; 1347 oper_mode = wpa_s->mlme.sta_scanning ? 1348 local->scan_oper_phymode : local->conf.phymode; 1349 for (i = 0; i < local->hw->num_modes; i++) { 1350 struct ieee80211_hw_modes *mode = &local->hw->modes[i]; 1351 if (oper_mode == mode->mode) { 1352 rates = mode->rates; 1353 num_rates = mode->num_rates; 1354 break; 1355 } 1356 } 1357 1358 supp_rates = 0; 1359 for (i = 0; i < elems.supp_rates_len + 1360 elems.ext_supp_rates_len; i++) { 1361 u8 rate = 0; 1362 int own_rate; 1363 if (i < elems.supp_rates_len) 1364 rate = elems.supp_rates[i]; 1365 else if (elems.ext_supp_rates) 1366 rate = elems.ext_supp_rates 1367 [i - elems.supp_rates_len]; 1368 own_rate = 5 * (rate & 0x7f); 1369 if (oper_mode == MODE_ATHEROS_TURBO) 1370 own_rate *= 2; 1371 for (j = 0; j < num_rates; j++) 1372 if (rates[j].rate == own_rate) 1373 supp_rates |= BIT(j); 1374 } 1375 1376 prev_rates = sta->supp_rates; 1377 sta->supp_rates &= supp_rates; 1378 if (sta->supp_rates == 0) { 1379 /* No matching rates - this should not really happen. 1380 * Make sure that at least one rate is marked 1381 * supported to avoid issues with TX rate ctrl. */ 1382 sta->supp_rates = wpa_s->mlme.supp_rates_bits; 1383 } 1384 if (sta->supp_rates != prev_rates) { 1385 wpa_printf(MSG_DEBUG, "MLME: updated supp_rates set " 1386 "for " MACSTR " based on beacon info " 1387 "(0x%x & 0x%x -> 0x%x)", 1388 MAC2STR(sta->addr), prev_rates, 1389 supp_rates, sta->supp_rates); 1390 } 1391 sta_info_release(local, sta); 1392 } 1393#endif 1394 1395 if (elems.ssid == NULL) 1396 return; 1397 1398 if (elems.ds_params && elems.ds_params_len == 1) 1399 channel = elems.ds_params[0]; 1400 else 1401 channel = rx_status->channel; 1402 1403 bss = ieee80211_bss_get(wpa_s, mgmt->bssid); 1404 if (bss == NULL) { 1405 bss = ieee80211_bss_add(wpa_s, mgmt->bssid); 1406 if (bss == NULL) 1407 return; 1408 } else { 1409#if 0 1410 /* TODO: order by RSSI? */ 1411 spin_lock_bh(&local->sta_bss_lock); 1412 list_move_tail(&bss->list, &local->sta_bss_list); 1413 spin_unlock_bh(&local->sta_bss_lock); 1414#endif 1415 } 1416 1417 if (bss->probe_resp && beacon) { 1418 /* Do not allow beacon to override data from Probe Response. */ 1419 return; 1420 } 1421 1422 bss->beacon_int = le_to_host16(mgmt->u.beacon.beacon_int); 1423 bss->capability = le_to_host16(mgmt->u.beacon.capab_info); 1424 1425 if (bss->ie == NULL || bss->ie_len < ie_len) { 1426 os_free(bss->ie); 1427 bss->ie = os_malloc(ie_len); 1428 } 1429 if (bss->ie) { 1430 os_memcpy(bss->ie, ie_pos, ie_len); 1431 bss->ie_len = ie_len; 1432 } 1433 1434 if (elems.ssid && elems.ssid_len <= MAX_SSID_LEN) { 1435 os_memcpy(bss->ssid, elems.ssid, elems.ssid_len); 1436 bss->ssid_len = elems.ssid_len; 1437 } 1438 1439 bss->supp_rates_len = 0; 1440 if (elems.supp_rates) { 1441 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; 1442 if (clen > elems.supp_rates_len) 1443 clen = elems.supp_rates_len; 1444 os_memcpy(&bss->supp_rates[bss->supp_rates_len], 1445 elems.supp_rates, clen); 1446 bss->supp_rates_len += clen; 1447 } 1448 if (elems.ext_supp_rates) { 1449 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; 1450 if (clen > elems.ext_supp_rates_len) 1451 clen = elems.ext_supp_rates_len; 1452 os_memcpy(&bss->supp_rates[bss->supp_rates_len], 1453 elems.ext_supp_rates, clen); 1454 bss->supp_rates_len += clen; 1455 } 1456 1457 if (elems.wpa_ie && 1458 (bss->wpa_ie == NULL || bss->wpa_ie_len != elems.wpa_ie_len || 1459 os_memcmp(bss->wpa_ie, elems.wpa_ie, elems.wpa_ie_len))) { 1460 os_free(bss->wpa_ie); 1461 bss->wpa_ie = os_malloc(elems.wpa_ie_len + 2); 1462 if (bss->wpa_ie) { 1463 os_memcpy(bss->wpa_ie, elems.wpa_ie - 2, 1464 elems.wpa_ie_len + 2); 1465 bss->wpa_ie_len = elems.wpa_ie_len + 2; 1466 } else 1467 bss->wpa_ie_len = 0; 1468 } else if (!elems.wpa_ie && bss->wpa_ie) { 1469 os_free(bss->wpa_ie); 1470 bss->wpa_ie = NULL; 1471 bss->wpa_ie_len = 0; 1472 } 1473 1474 if (elems.rsn_ie && 1475 (bss->rsn_ie == NULL || bss->rsn_ie_len != elems.rsn_ie_len || 1476 os_memcmp(bss->rsn_ie, elems.rsn_ie, elems.rsn_ie_len))) { 1477 os_free(bss->rsn_ie); 1478 bss->rsn_ie = os_malloc(elems.rsn_ie_len + 2); 1479 if (bss->rsn_ie) { 1480 os_memcpy(bss->rsn_ie, elems.rsn_ie - 2, 1481 elems.rsn_ie_len + 2); 1482 bss->rsn_ie_len = elems.rsn_ie_len + 2; 1483 } else 1484 bss->rsn_ie_len = 0; 1485 } else if (!elems.rsn_ie && bss->rsn_ie) { 1486 os_free(bss->rsn_ie); 1487 bss->rsn_ie = NULL; 1488 bss->rsn_ie_len = 0; 1489 } 1490 1491 if (elems.wmm && 1492 (bss->wmm_ie == NULL || bss->wmm_ie_len != elems.wmm_len || 1493 os_memcmp(bss->wmm_ie, elems.wmm, elems.wmm_len))) { 1494 os_free(bss->wmm_ie); 1495 bss->wmm_ie = os_malloc(elems.wmm_len + 2); 1496 if (bss->wmm_ie) { 1497 os_memcpy(bss->wmm_ie, elems.wmm - 2, 1498 elems.wmm_len + 2); 1499 bss->wmm_ie_len = elems.wmm_len + 2; 1500 } else 1501 bss->wmm_ie_len = 0; 1502 } else if (!elems.wmm && bss->wmm_ie) { 1503 os_free(bss->wmm_ie); 1504 bss->wmm_ie = NULL; 1505 bss->wmm_ie_len = 0; 1506 } 1507 1508#ifdef CONFIG_IEEE80211R 1509 if (elems.mdie && 1510 (bss->mdie == NULL || bss->mdie_len != elems.mdie_len || 1511 os_memcmp(bss->mdie, elems.mdie, elems.mdie_len))) { 1512 os_free(bss->mdie); 1513 bss->mdie = os_malloc(elems.mdie_len + 2); 1514 if (bss->mdie) { 1515 os_memcpy(bss->mdie, elems.mdie - 2, 1516 elems.mdie_len + 2); 1517 bss->mdie_len = elems.mdie_len + 2; 1518 } else 1519 bss->mdie_len = 0; 1520 } else if (!elems.mdie && bss->mdie) { 1521 os_free(bss->mdie); 1522 bss->mdie = NULL; 1523 bss->mdie_len = 0; 1524 } 1525#endif /* CONFIG_IEEE80211R */ 1526 1527 bss->hw_mode = wpa_s->mlme.phymode; 1528 bss->channel = channel; 1529 bss->freq = wpa_s->mlme.freq; 1530 if (channel != wpa_s->mlme.channel && 1531 (wpa_s->mlme.phymode == WPA_MODE_IEEE80211G || 1532 wpa_s->mlme.phymode == WPA_MODE_IEEE80211B) && 1533 channel >= 1 && channel <= 14) { 1534 static const int freq_list[] = { 1535 2412, 2417, 2422, 2427, 2432, 2437, 2442, 1536 2447, 2452, 2457, 2462, 2467, 2472, 2484 1537 }; 1538 /* IEEE 802.11g/b mode can receive packets from neighboring 1539 * channels, so map the channel into frequency. */ 1540 bss->freq = freq_list[channel - 1]; 1541 } 1542 bss->timestamp = timestamp; 1543 os_get_time(&bss->last_update); 1544 bss->rssi = rx_status->ssi; 1545 if (!beacon) 1546 bss->probe_resp++; 1547} 1548 1549 1550static void ieee80211_rx_mgmt_probe_resp(struct wpa_supplicant *wpa_s, 1551 struct ieee80211_mgmt *mgmt, 1552 size_t len, 1553 struct ieee80211_rx_status *rx_status) 1554{ 1555 ieee80211_bss_info(wpa_s, mgmt, len, rx_status, 0); 1556} 1557 1558 1559static void ieee80211_rx_mgmt_beacon(struct wpa_supplicant *wpa_s, 1560 struct ieee80211_mgmt *mgmt, 1561 size_t len, 1562 struct ieee80211_rx_status *rx_status) 1563{ 1564 int use_protection; 1565 size_t baselen; 1566 struct ieee802_11_elems elems; 1567 1568 ieee80211_bss_info(wpa_s, mgmt, len, rx_status, 1); 1569 1570 if (!wpa_s->mlme.associated || 1571 os_memcmp(wpa_s->bssid, mgmt->bssid, ETH_ALEN) != 0) 1572 return; 1573 1574 /* Process beacon from the current BSS */ 1575 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; 1576 if (baselen > len) 1577 return; 1578 1579 if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, 1580 &elems, 0) == ParseFailed) 1581 return; 1582 1583 use_protection = 0; 1584 if (elems.erp_info && elems.erp_info_len >= 1) { 1585 use_protection = 1586 (elems.erp_info[0] & ERP_INFO_USE_PROTECTION) != 0; 1587 } 1588 1589 if (use_protection != !!wpa_s->mlme.use_protection) { 1590 wpa_printf(MSG_DEBUG, "MLME: CTS protection %s (BSSID=" MACSTR 1591 ")", 1592 use_protection ? "enabled" : "disabled", 1593 MAC2STR(wpa_s->bssid)); 1594 wpa_s->mlme.use_protection = use_protection ? 1 : 0; 1595 wpa_s->mlme.cts_protect_erp_frames = use_protection; 1596 } 1597 1598 if (elems.wmm && wpa_s->mlme.wmm_enabled) { 1599 ieee80211_sta_wmm_params(wpa_s, elems.wmm, 1600 elems.wmm_len); 1601 } 1602} 1603 1604 1605static void ieee80211_rx_mgmt_probe_req(struct wpa_supplicant *wpa_s, 1606 struct ieee80211_mgmt *mgmt, 1607 size_t len, 1608 struct ieee80211_rx_status *rx_status) 1609{ 1610 int tx_last_beacon, adhoc; 1611#if 0 /* FIX */ 1612 struct ieee80211_mgmt *resp; 1613#endif 1614 u8 *pos, *end; 1615 struct wpa_ssid *ssid = wpa_s->current_ssid; 1616 1617 adhoc = ssid && ssid->mode == 1; 1618 1619 if (!adhoc || wpa_s->mlme.state != IEEE80211_IBSS_JOINED || 1620 len < 24 + 2 || wpa_s->mlme.probe_resp == NULL) 1621 return; 1622 1623#if 0 /* FIX */ 1624 if (local->hw->tx_last_beacon) 1625 tx_last_beacon = local->hw->tx_last_beacon(local->mdev); 1626 else 1627#endif 1628 tx_last_beacon = 1; 1629 1630#ifdef IEEE80211_IBSS_DEBUG 1631 wpa_printf(MSG_DEBUG, "MLME: RX ProbeReq SA=" MACSTR " DA=" MACSTR 1632 " BSSID=" MACSTR " (tx_last_beacon=%d)", 1633 MAC2STR(mgmt->sa), MAC2STR(mgmt->da), 1634 MAC2STR(mgmt->bssid), tx_last_beacon); 1635#endif /* IEEE80211_IBSS_DEBUG */ 1636 1637 if (!tx_last_beacon) 1638 return; 1639 1640 if (os_memcmp(mgmt->bssid, wpa_s->bssid, ETH_ALEN) != 0 && 1641 os_memcmp(mgmt->bssid, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0) 1642 return; 1643 1644 end = ((u8 *) mgmt) + len; 1645 pos = mgmt->u.probe_req.variable; 1646 if (pos[0] != WLAN_EID_SSID || 1647 pos + 2 + pos[1] > end) { 1648 wpa_printf(MSG_DEBUG, "MLME: Invalid SSID IE in ProbeReq from " 1649 MACSTR, MAC2STR(mgmt->sa)); 1650 return; 1651 } 1652 if (pos[1] != 0 && 1653 (pos[1] != wpa_s->mlme.ssid_len || 1654 os_memcmp(pos + 2, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len) != 0)) 1655 { 1656 /* Ignore ProbeReq for foreign SSID */ 1657 return; 1658 } 1659 1660#if 0 /* FIX */ 1661 /* Reply with ProbeResp */ 1662 skb = skb_copy(wpa_s->mlme.probe_resp, GFP_ATOMIC); 1663 if (skb == NULL) 1664 return; 1665 1666 resp = (struct ieee80211_mgmt *) skb->data; 1667 os_memcpy(resp->da, mgmt->sa, ETH_ALEN); 1668#ifdef IEEE80211_IBSS_DEBUG 1669 wpa_printf(MSG_DEBUG, "MLME: Sending ProbeResp to " MACSTR, 1670 MAC2STR(resp->da)); 1671#endif /* IEEE80211_IBSS_DEBUG */ 1672 ieee80211_sta_tx(wpa_s, skb, 0, 1); 1673#endif 1674} 1675 1676 1677#ifdef CONFIG_IEEE80211R 1678static void ieee80211_rx_mgmt_ft_action(struct wpa_supplicant *wpa_s, 1679 struct ieee80211_mgmt *mgmt, 1680 size_t len, 1681 struct ieee80211_rx_status *rx_status) 1682{ 1683 union wpa_event_data data; 1684 u16 status; 1685 u8 *sta_addr, *target_ap_addr; 1686 1687 if (len < 24 + 1 + sizeof(mgmt->u.action.u.ft_action_resp)) { 1688 wpa_printf(MSG_DEBUG, "MLME: Too short FT Action frame"); 1689 return; 1690 } 1691 1692 /* 1693 * Only FT Action Response is needed for now since reservation 1694 * protocol is not supported. 1695 */ 1696 if (mgmt->u.action.u.ft_action_resp.action != 2) { 1697 wpa_printf(MSG_DEBUG, "MLME: Unexpected FT Action %d", 1698 mgmt->u.action.u.ft_action_resp.action); 1699 return; 1700 } 1701 1702 status = le_to_host16(mgmt->u.action.u.ft_action_resp.status_code); 1703 sta_addr = mgmt->u.action.u.ft_action_resp.sta_addr; 1704 target_ap_addr = mgmt->u.action.u.ft_action_resp.target_ap_addr; 1705 wpa_printf(MSG_DEBUG, "MLME: Received FT Action Response: STA " MACSTR 1706 " TargetAP " MACSTR " Status Code %d", 1707 MAC2STR(sta_addr), MAC2STR(target_ap_addr), status); 1708 if (os_memcmp(sta_addr, wpa_s->own_addr, ETH_ALEN) != 0) { 1709 wpa_printf(MSG_DEBUG, "MLME: Foreign STA Address " MACSTR 1710 " in FT Action Response", MAC2STR(sta_addr)); 1711 return; 1712 } 1713 1714 if (status) { 1715 wpa_printf(MSG_DEBUG, "MLME: FT Action Response indicates " 1716 "failure (status code %d)", status); 1717 /* TODO: report error to FT code(?) */ 1718 return; 1719 } 1720 1721 os_memset(&data, 0, sizeof(data)); 1722 data.ft_ies.ies = mgmt->u.action.u.ft_action_resp.variable; 1723 data.ft_ies.ies_len = len - (mgmt->u.action.u.ft_action_resp.variable - 1724 (u8 *) mgmt); 1725 data.ft_ies.ft_action = 1; 1726 os_memcpy(data.ft_ies.target_ap, target_ap_addr, ETH_ALEN); 1727 wpa_supplicant_event(wpa_s, EVENT_FT_RESPONSE, &data); 1728 /* TODO: should only re-associate, if EVENT_FT_RESPONSE was processed 1729 * successfully */ 1730 wpa_s->mlme.prev_bssid_set = 1; 1731 wpa_s->mlme.auth_alg = WLAN_AUTH_FT; 1732 os_memcpy(wpa_s->mlme.prev_bssid, wpa_s->bssid, ETH_ALEN); 1733 os_memcpy(wpa_s->bssid, target_ap_addr, ETH_ALEN); 1734 ieee80211_associate(wpa_s); 1735} 1736#endif /* CONFIG_IEEE80211R */ 1737 1738 1739#ifdef CONFIG_IEEE80211W 1740 1741/* MLME-SAQuery.response */ 1742static int ieee80211_sta_send_sa_query_resp(struct wpa_supplicant *wpa_s, 1743 const u8 *addr, const u8 *trans_id) 1744{ 1745 struct ieee80211_mgmt *mgmt; 1746 int res; 1747 size_t len; 1748 1749 mgmt = os_zalloc(sizeof(*mgmt)); 1750 if (mgmt == NULL) { 1751 wpa_printf(MSG_DEBUG, "MLME: Failed to allocate buffer for " 1752 "SA Query action frame"); 1753 return -1; 1754 } 1755 1756 len = 24; 1757 os_memcpy(mgmt->da, addr, ETH_ALEN); 1758 os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 1759 os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN); 1760 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 1761 WLAN_FC_STYPE_ACTION); 1762 mgmt->u.action.category = WLAN_ACTION_SA_QUERY; 1763 mgmt->u.action.u.sa_query_resp.action = WLAN_SA_QUERY_RESPONSE; 1764 os_memcpy(mgmt->u.action.u.sa_query_resp.trans_id, trans_id, 1765 WLAN_SA_QUERY_TR_ID_LEN); 1766 len += 1 + sizeof(mgmt->u.action.u.sa_query_resp); 1767 1768 res = ieee80211_sta_tx(wpa_s, (u8 *) mgmt, len); 1769 os_free(mgmt); 1770 1771 return res; 1772} 1773 1774 1775static void ieee80211_rx_mgmt_sa_query_action( 1776 struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len, 1777 struct ieee80211_rx_status *rx_status) 1778{ 1779 if (len < 24 + 1 + sizeof(mgmt->u.action.u.sa_query_req)) { 1780 wpa_printf(MSG_DEBUG, "MLME: Too short SA Query Action frame"); 1781 return; 1782 } 1783 1784 if (mgmt->u.action.u.sa_query_req.action != WLAN_SA_QUERY_REQUEST) { 1785 wpa_printf(MSG_DEBUG, "MLME: Unexpected SA Query Action %d", 1786 mgmt->u.action.u.sa_query_req.action); 1787 return; 1788 } 1789 1790 if (os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) != 0) { 1791 wpa_printf(MSG_DEBUG, "MLME: Ignore SA Query from unknown " 1792 "source " MACSTR, MAC2STR(mgmt->sa)); 1793 return; 1794 } 1795 1796 if (wpa_s->mlme.state == IEEE80211_ASSOCIATE) { 1797 wpa_printf(MSG_DEBUG, "MLME: Ignore SA query request during " 1798 "association process"); 1799 return; 1800 } 1801 1802 wpa_printf(MSG_DEBUG, "MLME: Replying to SA Query request"); 1803 ieee80211_sta_send_sa_query_resp(wpa_s, mgmt->sa, mgmt->u.action.u. 1804 sa_query_req.trans_id); 1805} 1806 1807#endif /* CONFIG_IEEE80211W */ 1808 1809 1810static void ieee80211_rx_mgmt_action(struct wpa_supplicant *wpa_s, 1811 struct ieee80211_mgmt *mgmt, 1812 size_t len, 1813 struct ieee80211_rx_status *rx_status) 1814{ 1815 wpa_printf(MSG_DEBUG, "MLME: received Action frame"); 1816 1817 if (len < 25) 1818 return; 1819 1820 switch (mgmt->u.action.category) { 1821#ifdef CONFIG_IEEE80211R 1822 case WLAN_ACTION_FT: 1823 ieee80211_rx_mgmt_ft_action(wpa_s, mgmt, len, rx_status); 1824 break; 1825#endif /* CONFIG_IEEE80211R */ 1826#ifdef CONFIG_IEEE80211W 1827 case WLAN_ACTION_SA_QUERY: 1828 ieee80211_rx_mgmt_sa_query_action(wpa_s, mgmt, len, rx_status); 1829 break; 1830#endif /* CONFIG_IEEE80211W */ 1831 default: 1832 wpa_printf(MSG_DEBUG, "MLME: unknown Action Category %d", 1833 mgmt->u.action.category); 1834 break; 1835 } 1836} 1837 1838 1839static void ieee80211_sta_rx_mgmt(struct wpa_supplicant *wpa_s, 1840 const u8 *buf, size_t len, 1841 struct ieee80211_rx_status *rx_status) 1842{ 1843 struct ieee80211_mgmt *mgmt; 1844 u16 fc; 1845 1846 if (len < 24) 1847 return; 1848 1849 mgmt = (struct ieee80211_mgmt *) buf; 1850 fc = le_to_host16(mgmt->frame_control); 1851 1852 switch (WLAN_FC_GET_STYPE(fc)) { 1853 case WLAN_FC_STYPE_PROBE_REQ: 1854 ieee80211_rx_mgmt_probe_req(wpa_s, mgmt, len, rx_status); 1855 break; 1856 case WLAN_FC_STYPE_PROBE_RESP: 1857 ieee80211_rx_mgmt_probe_resp(wpa_s, mgmt, len, rx_status); 1858 break; 1859 case WLAN_FC_STYPE_BEACON: 1860 ieee80211_rx_mgmt_beacon(wpa_s, mgmt, len, rx_status); 1861 break; 1862 case WLAN_FC_STYPE_AUTH: 1863 ieee80211_rx_mgmt_auth(wpa_s, mgmt, len, rx_status); 1864 break; 1865 case WLAN_FC_STYPE_ASSOC_RESP: 1866 ieee80211_rx_mgmt_assoc_resp(wpa_s, mgmt, len, rx_status, 0); 1867 break; 1868 case WLAN_FC_STYPE_REASSOC_RESP: 1869 ieee80211_rx_mgmt_assoc_resp(wpa_s, mgmt, len, rx_status, 1); 1870 break; 1871 case WLAN_FC_STYPE_DEAUTH: 1872 ieee80211_rx_mgmt_deauth(wpa_s, mgmt, len, rx_status); 1873 break; 1874 case WLAN_FC_STYPE_DISASSOC: 1875 ieee80211_rx_mgmt_disassoc(wpa_s, mgmt, len, rx_status); 1876 break; 1877 case WLAN_FC_STYPE_ACTION: 1878 ieee80211_rx_mgmt_action(wpa_s, mgmt, len, rx_status); 1879 break; 1880 default: 1881 wpa_printf(MSG_DEBUG, "MLME: received unknown management " 1882 "frame - stype=%d", WLAN_FC_GET_STYPE(fc)); 1883 break; 1884 } 1885} 1886 1887 1888static void ieee80211_sta_rx_scan(struct wpa_supplicant *wpa_s, 1889 const u8 *buf, size_t len, 1890 struct ieee80211_rx_status *rx_status) 1891{ 1892 struct ieee80211_mgmt *mgmt; 1893 u16 fc; 1894 1895 if (len < 24) 1896 return; 1897 1898 mgmt = (struct ieee80211_mgmt *) buf; 1899 fc = le_to_host16(mgmt->frame_control); 1900 1901 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT) { 1902 if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) { 1903 ieee80211_rx_mgmt_probe_resp(wpa_s, mgmt, 1904 len, rx_status); 1905 } else if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) { 1906 ieee80211_rx_mgmt_beacon(wpa_s, mgmt, len, rx_status); 1907 } 1908 } 1909} 1910 1911 1912static int ieee80211_sta_active_ibss(struct wpa_supplicant *wpa_s) 1913{ 1914 int active = 0; 1915 1916#if 0 /* FIX */ 1917 list_for_each(ptr, &local->sta_list) { 1918 sta = list_entry(ptr, struct sta_info, list); 1919 if (sta->dev == dev && 1920 time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL, 1921 jiffies)) { 1922 active++; 1923 break; 1924 } 1925 } 1926#endif 1927 1928 return active; 1929} 1930 1931 1932static void ieee80211_sta_expire(struct wpa_supplicant *wpa_s) 1933{ 1934#if 0 /* FIX */ 1935 list_for_each_safe(ptr, n, &local->sta_list) { 1936 sta = list_entry(ptr, struct sta_info, list); 1937 if (time_after(jiffies, sta->last_rx + 1938 IEEE80211_IBSS_INACTIVITY_LIMIT)) { 1939 wpa_printf(MSG_DEBUG, "MLME: expiring inactive STA " 1940 MACSTR, MAC2STR(sta->addr)); 1941 sta_info_free(local, sta, 1); 1942 } 1943 } 1944#endif 1945} 1946 1947 1948static void ieee80211_sta_merge_ibss(struct wpa_supplicant *wpa_s) 1949{ 1950 ieee80211_reschedule_timer(wpa_s, IEEE80211_IBSS_MERGE_INTERVAL); 1951 1952 ieee80211_sta_expire(wpa_s); 1953 if (ieee80211_sta_active_ibss(wpa_s)) 1954 return; 1955 1956 wpa_printf(MSG_DEBUG, "MLME: No active IBSS STAs - trying to scan for " 1957 "other IBSS networks with same SSID (merge)"); 1958 ieee80211_sta_req_scan(wpa_s, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len); 1959} 1960 1961 1962static void ieee80211_sta_timer(void *eloop_ctx, void *timeout_ctx) 1963{ 1964 struct wpa_supplicant *wpa_s = eloop_ctx; 1965 1966 switch (wpa_s->mlme.state) { 1967 case IEEE80211_DISABLED: 1968 break; 1969 case IEEE80211_AUTHENTICATE: 1970 ieee80211_authenticate(wpa_s); 1971 break; 1972 case IEEE80211_ASSOCIATE: 1973 ieee80211_associate(wpa_s); 1974 break; 1975 case IEEE80211_ASSOCIATED: 1976 ieee80211_associated(wpa_s); 1977 break; 1978 case IEEE80211_IBSS_SEARCH: 1979 ieee80211_sta_find_ibss(wpa_s); 1980 break; 1981 case IEEE80211_IBSS_JOINED: 1982 ieee80211_sta_merge_ibss(wpa_s); 1983 break; 1984 default: 1985 wpa_printf(MSG_DEBUG, "ieee80211_sta_timer: Unknown state %d", 1986 wpa_s->mlme.state); 1987 break; 1988 } 1989 1990 if (ieee80211_privacy_mismatch(wpa_s)) { 1991 wpa_printf(MSG_DEBUG, "MLME: privacy configuration mismatch " 1992 "and mixed-cell disabled - disassociate"); 1993 1994 ieee80211_send_disassoc(wpa_s, WLAN_REASON_UNSPECIFIED); 1995 ieee80211_set_associated(wpa_s, 0); 1996 } 1997} 1998 1999 2000static void ieee80211_sta_new_auth(struct wpa_supplicant *wpa_s) 2001{ 2002 struct wpa_ssid *ssid = wpa_s->current_ssid; 2003 if (ssid && ssid->mode != 0) 2004 return; 2005 2006#if 0 /* FIX */ 2007 if (local->hw->reset_tsf) { 2008 /* Reset own TSF to allow time synchronization work. */ 2009 local->hw->reset_tsf(local->mdev); 2010 } 2011#endif 2012 2013 wpa_s->mlme.wmm_last_param_set = -1; /* allow any WMM update */ 2014 2015 2016 if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_OPEN) 2017 wpa_s->mlme.auth_alg = WLAN_AUTH_OPEN; 2018 else if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_SHARED_KEY) 2019 wpa_s->mlme.auth_alg = WLAN_AUTH_SHARED_KEY; 2020 else if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_LEAP) 2021 wpa_s->mlme.auth_alg = WLAN_AUTH_LEAP; 2022 else 2023 wpa_s->mlme.auth_alg = WLAN_AUTH_OPEN; 2024 wpa_printf(MSG_DEBUG, "MLME: Initial auth_alg=%d", 2025 wpa_s->mlme.auth_alg); 2026 wpa_s->mlme.auth_transaction = -1; 2027 wpa_s->mlme.auth_tries = wpa_s->mlme.assoc_tries = 0; 2028 ieee80211_authenticate(wpa_s); 2029} 2030 2031 2032static int ieee80211_ibss_allowed(struct wpa_supplicant *wpa_s) 2033{ 2034#if 0 /* FIX */ 2035 int m, c; 2036 2037 for (m = 0; m < local->hw->num_modes; m++) { 2038 struct ieee80211_hw_modes *mode = &local->hw->modes[m]; 2039 if (mode->mode != local->conf.phymode) 2040 continue; 2041 for (c = 0; c < mode->num_channels; c++) { 2042 struct ieee80211_channel *chan = &mode->channels[c]; 2043 if (chan->flag & IEEE80211_CHAN_W_SCAN && 2044 chan->chan == local->conf.channel) { 2045 if (chan->flag & IEEE80211_CHAN_W_IBSS) 2046 return 1; 2047 break; 2048 } 2049 } 2050 } 2051#endif 2052 2053 return 0; 2054} 2055 2056 2057static int ieee80211_sta_join_ibss(struct wpa_supplicant *wpa_s, 2058 struct ieee80211_sta_bss *bss) 2059{ 2060 int res = 0, rates, done = 0; 2061 struct ieee80211_mgmt *mgmt; 2062#if 0 /* FIX */ 2063 struct ieee80211_tx_control control; 2064 struct ieee80211_rate *rate; 2065 struct rate_control_extra extra; 2066#endif 2067 u8 *pos, *buf; 2068 size_t len; 2069 2070 /* Remove possible STA entries from other IBSS networks. */ 2071#if 0 /* FIX */ 2072 sta_info_flush(local, NULL); 2073 2074 if (local->hw->reset_tsf) { 2075 /* Reset own TSF to allow time synchronization work. */ 2076 local->hw->reset_tsf(local->mdev); 2077 } 2078#endif 2079 os_memcpy(wpa_s->bssid, bss->bssid, ETH_ALEN); 2080 2081#if 0 /* FIX */ 2082 local->conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10; 2083 2084 sdata->drop_unencrypted = bss->capability & 2085 host_to_le16(WLAN_CAPABILITY_PRIVACY) ? 1 : 0; 2086#endif 2087 2088#if 0 /* FIX */ 2089 os_memset(&rq, 0, sizeof(rq)); 2090 rq.m = bss->freq * 100000; 2091 rq.e = 1; 2092 res = ieee80211_ioctl_siwfreq(wpa_s, NULL, &rq, NULL); 2093#endif 2094 2095 if (!ieee80211_ibss_allowed(wpa_s)) { 2096#if 0 /* FIX */ 2097 wpa_printf(MSG_DEBUG, "MLME: IBSS not allowed on channel %d " 2098 "(%d MHz)", local->conf.channel, 2099 local->conf.freq); 2100#endif 2101 return -1; 2102 } 2103 2104 /* Set beacon template based on scan results */ 2105 buf = os_malloc(400); 2106 len = 0; 2107 do { 2108 if (buf == NULL) 2109 break; 2110 2111 mgmt = (struct ieee80211_mgmt *) buf; 2112 len += 24 + sizeof(mgmt->u.beacon); 2113 os_memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); 2114 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 2115 WLAN_FC_STYPE_BEACON); 2116 os_memset(mgmt->da, 0xff, ETH_ALEN); 2117 os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 2118 os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN); 2119#if 0 /* FIX */ 2120 mgmt->u.beacon.beacon_int = 2121 host_to_le16(local->conf.beacon_int); 2122#endif 2123 mgmt->u.beacon.capab_info = host_to_le16(bss->capability); 2124 2125 pos = buf + len; 2126 len += 2 + wpa_s->mlme.ssid_len; 2127 *pos++ = WLAN_EID_SSID; 2128 *pos++ = wpa_s->mlme.ssid_len; 2129 os_memcpy(pos, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len); 2130 2131 rates = bss->supp_rates_len; 2132 if (rates > 8) 2133 rates = 8; 2134 pos = buf + len; 2135 len += 2 + rates; 2136 *pos++ = WLAN_EID_SUPP_RATES; 2137 *pos++ = rates; 2138 os_memcpy(pos, bss->supp_rates, rates); 2139 2140 pos = buf + len; 2141 len += 2 + 1; 2142 *pos++ = WLAN_EID_DS_PARAMS; 2143 *pos++ = 1; 2144 *pos++ = bss->channel; 2145 2146 pos = buf + len; 2147 len += 2 + 2; 2148 *pos++ = WLAN_EID_IBSS_PARAMS; 2149 *pos++ = 2; 2150 /* FIX: set ATIM window based on scan results */ 2151 *pos++ = 0; 2152 *pos++ = 0; 2153 2154 if (bss->supp_rates_len > 8) { 2155 rates = bss->supp_rates_len - 8; 2156 pos = buf + len; 2157 len += 2 + rates; 2158 *pos++ = WLAN_EID_EXT_SUPP_RATES; 2159 *pos++ = rates; 2160 os_memcpy(pos, &bss->supp_rates[8], rates); 2161 } 2162 2163#if 0 /* FIX */ 2164 os_memset(&control, 0, sizeof(control)); 2165 control.pkt_type = PKT_PROBE_RESP; 2166 os_memset(&extra, 0, sizeof(extra)); 2167 extra.endidx = local->num_curr_rates; 2168 rate = rate_control_get_rate(wpa_s, skb, &extra); 2169 if (rate == NULL) { 2170 wpa_printf(MSG_DEBUG, "MLME: Failed to determine TX " 2171 "rate for IBSS beacon"); 2172 break; 2173 } 2174 control.tx_rate = (wpa_s->mlme.short_preamble && 2175 (rate->flags & IEEE80211_RATE_PREAMBLE2)) ? 2176 rate->val2 : rate->val; 2177 control.antenna_sel = local->conf.antenna_sel; 2178 control.power_level = local->conf.power_level; 2179 control.no_ack = 1; 2180 control.retry_limit = 1; 2181 control.rts_cts_duration = 0; 2182#endif 2183 2184#if 0 /* FIX */ 2185 wpa_s->mlme.probe_resp = skb_copy(skb, GFP_ATOMIC); 2186 if (wpa_s->mlme.probe_resp) { 2187 mgmt = (struct ieee80211_mgmt *) 2188 wpa_s->mlme.probe_resp->data; 2189 mgmt->frame_control = 2190 IEEE80211_FC(WLAN_FC_TYPE_MGMT, 2191 WLAN_FC_STYPE_PROBE_RESP); 2192 } else { 2193 wpa_printf(MSG_DEBUG, "MLME: Could not allocate " 2194 "ProbeResp template for IBSS"); 2195 } 2196 2197 if (local->hw->beacon_update && 2198 local->hw->beacon_update(wpa_s, skb, &control) == 0) { 2199 wpa_printf(MSG_DEBUG, "MLME: Configured IBSS beacon " 2200 "template based on scan results"); 2201 skb = NULL; 2202 } 2203 2204 rates = 0; 2205 for (i = 0; i < bss->supp_rates_len; i++) { 2206 int rate = (bss->supp_rates[i] & 0x7f) * 5; 2207 if (local->conf.phymode == MODE_ATHEROS_TURBO) 2208 rate *= 2; 2209 for (j = 0; j < local->num_curr_rates; j++) 2210 if (local->curr_rates[j].rate == rate) 2211 rates |= BIT(j); 2212 } 2213 wpa_s->mlme.supp_rates_bits = rates; 2214#endif 2215 done = 1; 2216 } while (0); 2217 2218 os_free(buf); 2219 if (!done) { 2220 wpa_printf(MSG_DEBUG, "MLME: Failed to configure IBSS beacon " 2221 "template"); 2222 } 2223 2224 wpa_s->mlme.state = IEEE80211_IBSS_JOINED; 2225 ieee80211_reschedule_timer(wpa_s, IEEE80211_IBSS_MERGE_INTERVAL); 2226 2227 return res; 2228} 2229 2230 2231#if 0 /* FIX */ 2232static int ieee80211_sta_create_ibss(struct wpa_supplicant *wpa_s) 2233{ 2234 struct ieee80211_sta_bss *bss; 2235 u8 bssid[ETH_ALEN], *pos; 2236 int i; 2237 2238#if 0 2239 /* Easier testing, use fixed BSSID. */ 2240 os_memset(bssid, 0xfe, ETH_ALEN); 2241#else 2242 /* Generate random, not broadcast, locally administered BSSID. Mix in 2243 * own MAC address to make sure that devices that do not have proper 2244 * random number generator get different BSSID. */ 2245 os_get_random(bssid, ETH_ALEN); 2246 for (i = 0; i < ETH_ALEN; i++) 2247 bssid[i] ^= wpa_s->own_addr[i]; 2248 bssid[0] &= ~0x01; 2249 bssid[0] |= 0x02; 2250#endif 2251 2252 wpa_printf(MSG_DEBUG, "MLME: Creating new IBSS network, BSSID " 2253 MACSTR "", MAC2STR(bssid)); 2254 2255 bss = ieee80211_bss_add(wpa_s, bssid); 2256 if (bss == NULL) 2257 return -ENOMEM; 2258 2259#if 0 /* FIX */ 2260 if (local->conf.beacon_int == 0) 2261 local->conf.beacon_int = 100; 2262 bss->beacon_int = local->conf.beacon_int; 2263 bss->hw_mode = local->conf.phymode; 2264 bss->channel = local->conf.channel; 2265 bss->freq = local->conf.freq; 2266#endif 2267 os_get_time(&bss->last_update); 2268 bss->capability = host_to_le16(WLAN_CAPABILITY_IBSS); 2269#if 0 /* FIX */ 2270 if (sdata->default_key) { 2271 bss->capability |= host_to_le16(WLAN_CAPABILITY_PRIVACY); 2272 } else 2273 sdata->drop_unencrypted = 0; 2274 bss->supp_rates_len = local->num_curr_rates; 2275#endif 2276 pos = bss->supp_rates; 2277#if 0 /* FIX */ 2278 for (i = 0; i < local->num_curr_rates; i++) { 2279 int rate = local->curr_rates[i].rate; 2280 if (local->conf.phymode == MODE_ATHEROS_TURBO) 2281 rate /= 2; 2282 *pos++ = (u8) (rate / 5); 2283 } 2284#endif 2285 2286 return ieee80211_sta_join_ibss(wpa_s, bss); 2287} 2288#endif 2289 2290 2291static int ieee80211_sta_find_ibss(struct wpa_supplicant *wpa_s) 2292{ 2293 struct ieee80211_sta_bss *bss; 2294 int found = 0; 2295 u8 bssid[ETH_ALEN]; 2296 int active_ibss; 2297 struct os_time now; 2298 2299 if (wpa_s->mlme.ssid_len == 0) 2300 return -EINVAL; 2301 2302 active_ibss = ieee80211_sta_active_ibss(wpa_s); 2303#ifdef IEEE80211_IBSS_DEBUG 2304 wpa_printf(MSG_DEBUG, "MLME: sta_find_ibss (active_ibss=%d)", 2305 active_ibss); 2306#endif /* IEEE80211_IBSS_DEBUG */ 2307 for (bss = wpa_s->mlme.sta_bss_list; bss; bss = bss->next) { 2308 if (wpa_s->mlme.ssid_len != bss->ssid_len || 2309 os_memcmp(wpa_s->mlme.ssid, bss->ssid, bss->ssid_len) != 0 2310 || !(bss->capability & WLAN_CAPABILITY_IBSS)) 2311 continue; 2312#ifdef IEEE80211_IBSS_DEBUG 2313 wpa_printf(MSG_DEBUG, " bssid=" MACSTR " found", 2314 MAC2STR(bss->bssid)); 2315#endif /* IEEE80211_IBSS_DEBUG */ 2316 os_memcpy(bssid, bss->bssid, ETH_ALEN); 2317 found = 1; 2318 if (active_ibss || 2319 os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0) 2320 break; 2321 } 2322 2323#ifdef IEEE80211_IBSS_DEBUG 2324 wpa_printf(MSG_DEBUG, " sta_find_ibss: selected " MACSTR " current " 2325 MACSTR, MAC2STR(bssid), MAC2STR(wpa_s->bssid)); 2326#endif /* IEEE80211_IBSS_DEBUG */ 2327 if (found && os_memcmp(wpa_s->bssid, bssid, ETH_ALEN) != 0 && 2328 (bss = ieee80211_bss_get(wpa_s, bssid))) { 2329 wpa_printf(MSG_DEBUG, "MLME: Selected IBSS BSSID " MACSTR 2330 " based on configured SSID", 2331 MAC2STR(bssid)); 2332 return ieee80211_sta_join_ibss(wpa_s, bss); 2333 } 2334#ifdef IEEE80211_IBSS_DEBUG 2335 wpa_printf(MSG_DEBUG, " did not try to join ibss"); 2336#endif /* IEEE80211_IBSS_DEBUG */ 2337 2338 /* Selected IBSS not found in current scan results - try to scan */ 2339 os_get_time(&now); 2340#if 0 /* FIX */ 2341 if (wpa_s->mlme.state == IEEE80211_IBSS_JOINED && 2342 !ieee80211_sta_active_ibss(wpa_s)) { 2343 ieee80211_reschedule_timer(wpa_s, 2344 IEEE80211_IBSS_MERGE_INTERVAL); 2345 } else if (time_after(jiffies, wpa_s->mlme.last_scan_completed + 2346 IEEE80211_SCAN_INTERVAL)) { 2347 wpa_printf(MSG_DEBUG, "MLME: Trigger new scan to find an IBSS " 2348 "to join"); 2349 return ieee80211_sta_req_scan(wpa_s->mlme.ssid, 2350 wpa_s->mlme.ssid_len); 2351 } else if (wpa_s->mlme.state != IEEE80211_IBSS_JOINED) { 2352 int interval = IEEE80211_SCAN_INTERVAL; 2353 2354 if (time_after(jiffies, wpa_s->mlme.ibss_join_req + 2355 IEEE80211_IBSS_JOIN_TIMEOUT)) { 2356 if (wpa_s->mlme.create_ibss && 2357 ieee80211_ibss_allowed(wpa_s)) 2358 return ieee80211_sta_create_ibss(wpa_s); 2359 if (wpa_s->mlme.create_ibss) { 2360 wpa_printf(MSG_DEBUG, "MLME: IBSS not allowed " 2361 "on the configured channel %d " 2362 "(%d MHz)", 2363 local->conf.channel, 2364 local->conf.freq); 2365 } 2366 2367 /* No IBSS found - decrease scan interval and continue 2368 * scanning. */ 2369 interval = IEEE80211_SCAN_INTERVAL_SLOW; 2370 } 2371 2372 wpa_s->mlme.state = IEEE80211_IBSS_SEARCH; 2373 ieee80211_reschedule_timer(wpa_s, interval); 2374 return 0; 2375 } 2376#endif 2377 2378 return 0; 2379} 2380 2381 2382int ieee80211_sta_get_ssid(struct wpa_supplicant *wpa_s, u8 *ssid, 2383 size_t *len) 2384{ 2385 os_memcpy(ssid, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len); 2386 *len = wpa_s->mlme.ssid_len; 2387 return 0; 2388} 2389 2390 2391int ieee80211_sta_associate(struct wpa_supplicant *wpa_s, 2392 struct wpa_driver_associate_params *params) 2393{ 2394 struct ieee80211_sta_bss *bss; 2395 2396 wpa_s->mlme.bssid_set = 0; 2397 wpa_s->mlme.freq = params->freq; 2398 if (params->bssid) { 2399 os_memcpy(wpa_s->bssid, params->bssid, ETH_ALEN); 2400 if (!is_zero_ether_addr(params->bssid)) 2401 wpa_s->mlme.bssid_set = 1; 2402 bss = ieee80211_bss_get(wpa_s, wpa_s->bssid); 2403 if (bss) { 2404 wpa_s->mlme.phymode = bss->hw_mode; 2405 wpa_s->mlme.channel = bss->channel; 2406 wpa_s->mlme.freq = bss->freq; 2407 } 2408 } 2409 2410#if 0 /* FIX */ 2411 /* TODO: This should always be done for IBSS, even if IEEE80211_QOS is 2412 * not defined. */ 2413 if (local->hw->conf_tx) { 2414 struct ieee80211_tx_queue_params qparam; 2415 int i; 2416 2417 os_memset(&qparam, 0, sizeof(qparam)); 2418 /* TODO: are these ok defaults for all hw_modes? */ 2419 qparam.aifs = 2; 2420 qparam.cw_min = 2421 local->conf.phymode == MODE_IEEE80211B ? 31 : 15; 2422 qparam.cw_max = 1023; 2423 qparam.burst_time = 0; 2424 for (i = IEEE80211_TX_QUEUE_DATA0; i < NUM_TX_DATA_QUEUES; i++) 2425 { 2426 local->hw->conf_tx(wpa_s, i + IEEE80211_TX_QUEUE_DATA0, 2427 &qparam); 2428 } 2429 /* IBSS uses different parameters for Beacon sending */ 2430 qparam.cw_min++; 2431 qparam.cw_min *= 2; 2432 qparam.cw_min--; 2433 local->hw->conf_tx(wpa_s, IEEE80211_TX_QUEUE_BEACON, &qparam); 2434 } 2435#endif 2436 2437 if (wpa_s->mlme.ssid_len != params->ssid_len || 2438 os_memcmp(wpa_s->mlme.ssid, params->ssid, params->ssid_len) != 0) 2439 wpa_s->mlme.prev_bssid_set = 0; 2440 os_memcpy(wpa_s->mlme.ssid, params->ssid, params->ssid_len); 2441 os_memset(wpa_s->mlme.ssid + params->ssid_len, 0, 2442 MAX_SSID_LEN - params->ssid_len); 2443 wpa_s->mlme.ssid_len = params->ssid_len; 2444 wpa_s->mlme.ssid_set = 1; 2445 2446 os_free(wpa_s->mlme.extra_ie); 2447 if (params->wpa_ie == NULL || params->wpa_ie_len == 0) { 2448 wpa_s->mlme.extra_ie = NULL; 2449 wpa_s->mlme.extra_ie_len = 0; 2450 } else { 2451 wpa_s->mlme.extra_ie = os_malloc(params->wpa_ie_len); 2452 if (wpa_s->mlme.extra_ie == NULL) { 2453 wpa_s->mlme.extra_ie_len = 0; 2454 return -1; 2455 } 2456 os_memcpy(wpa_s->mlme.extra_ie, params->wpa_ie, 2457 params->wpa_ie_len); 2458 wpa_s->mlme.extra_ie_len = params->wpa_ie_len; 2459 } 2460 2461 wpa_s->mlme.key_mgmt = params->key_mgmt_suite; 2462 2463 ieee80211_sta_set_channel(wpa_s, wpa_s->mlme.phymode, 2464 wpa_s->mlme.channel, wpa_s->mlme.freq); 2465 2466 if (params->mode == 1 && !wpa_s->mlme.bssid_set) { 2467 os_get_time(&wpa_s->mlme.ibss_join_req); 2468 wpa_s->mlme.state = IEEE80211_IBSS_SEARCH; 2469 return ieee80211_sta_find_ibss(wpa_s); 2470 } 2471 2472 if (wpa_s->mlme.bssid_set) 2473 ieee80211_sta_new_auth(wpa_s); 2474 2475 return 0; 2476} 2477 2478 2479static void ieee80211_sta_save_oper_chan(struct wpa_supplicant *wpa_s) 2480{ 2481 wpa_s->mlme.scan_oper_channel = wpa_s->mlme.channel; 2482 wpa_s->mlme.scan_oper_freq = wpa_s->mlme.freq; 2483 wpa_s->mlme.scan_oper_phymode = wpa_s->mlme.phymode; 2484} 2485 2486 2487static int ieee80211_sta_restore_oper_chan(struct wpa_supplicant *wpa_s) 2488{ 2489 wpa_s->mlme.channel = wpa_s->mlme.scan_oper_channel; 2490 wpa_s->mlme.freq = wpa_s->mlme.scan_oper_freq; 2491 wpa_s->mlme.phymode = wpa_s->mlme.scan_oper_phymode; 2492 if (wpa_s->mlme.freq == 0) 2493 return 0; 2494 return ieee80211_sta_set_channel(wpa_s, wpa_s->mlme.phymode, 2495 wpa_s->mlme.channel, 2496 wpa_s->mlme.freq); 2497} 2498 2499 2500static int ieee80211_active_scan(struct wpa_supplicant *wpa_s) 2501{ 2502 size_t m; 2503 int c; 2504 2505 for (m = 0; m < wpa_s->mlme.num_modes; m++) { 2506 struct wpa_hw_modes *mode = &wpa_s->mlme.modes[m]; 2507 if ((int) mode->mode != (int) wpa_s->mlme.phymode) 2508 continue; 2509 for (c = 0; c < mode->num_channels; c++) { 2510 struct wpa_channel_data *chan = &mode->channels[c]; 2511 if (chan->flag & WPA_CHAN_W_SCAN && 2512 chan->chan == wpa_s->mlme.channel) { 2513 if (chan->flag & WPA_CHAN_W_ACTIVE_SCAN) 2514 return 1; 2515 break; 2516 } 2517 } 2518 } 2519 2520 return 0; 2521} 2522 2523 2524static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx) 2525{ 2526 struct wpa_supplicant *wpa_s = eloop_ctx; 2527 struct wpa_hw_modes *mode; 2528 struct wpa_channel_data *chan; 2529 int skip = 0; 2530 int timeout = 0; 2531 struct wpa_ssid *ssid = wpa_s->current_ssid; 2532 int adhoc; 2533 2534 if (!wpa_s->mlme.sta_scanning || wpa_s->mlme.modes == NULL) 2535 return; 2536 2537 adhoc = ssid && ssid->mode == 1; 2538 2539 switch (wpa_s->mlme.scan_state) { 2540 case SCAN_SET_CHANNEL: 2541 mode = &wpa_s->mlme.modes[wpa_s->mlme.scan_hw_mode_idx]; 2542 if (wpa_s->mlme.scan_hw_mode_idx >= 2543 (int) wpa_s->mlme.num_modes || 2544 (wpa_s->mlme.scan_hw_mode_idx + 1 == 2545 (int) wpa_s->mlme.num_modes 2546 && wpa_s->mlme.scan_channel_idx >= mode->num_channels)) { 2547 if (ieee80211_sta_restore_oper_chan(wpa_s)) { 2548 wpa_printf(MSG_DEBUG, "MLME: failed to " 2549 "restore operational channel after " 2550 "scan"); 2551 } 2552 wpa_printf(MSG_DEBUG, "MLME: scan completed"); 2553 wpa_s->mlme.sta_scanning = 0; 2554 os_get_time(&wpa_s->mlme.last_scan_completed); 2555 wpa_supplicant_event(wpa_s, EVENT_SCAN_RESULTS, NULL); 2556 if (adhoc) { 2557 if (!wpa_s->mlme.bssid_set || 2558 (wpa_s->mlme.state == 2559 IEEE80211_IBSS_JOINED && 2560 !ieee80211_sta_active_ibss(wpa_s))) 2561 ieee80211_sta_find_ibss(wpa_s); 2562 } 2563 return; 2564 } 2565 skip = !(wpa_s->mlme.hw_modes & (1 << mode->mode)); 2566 chan = &mode->channels[wpa_s->mlme.scan_channel_idx]; 2567 if (!(chan->flag & WPA_CHAN_W_SCAN) || 2568 (adhoc && !(chan->flag & WPA_CHAN_W_IBSS)) || 2569 (wpa_s->mlme.hw_modes & (1 << WPA_MODE_IEEE80211G) && 2570 mode->mode == WPA_MODE_IEEE80211B && 2571 wpa_s->mlme.scan_skip_11b)) 2572 skip = 1; 2573 2574 if (!skip) { 2575 wpa_printf(MSG_MSGDUMP, 2576 "MLME: scan channel %d (%d MHz)", 2577 chan->chan, chan->freq); 2578 2579 wpa_s->mlme.channel = chan->chan; 2580 wpa_s->mlme.freq = chan->freq; 2581 wpa_s->mlme.phymode = mode->mode; 2582 if (ieee80211_sta_set_channel(wpa_s, mode->mode, 2583 chan->chan, chan->freq)) 2584 { 2585 wpa_printf(MSG_DEBUG, "MLME: failed to set " 2586 "channel %d (%d MHz) for scan", 2587 chan->chan, chan->freq); 2588 skip = 1; 2589 } 2590 } 2591 2592 wpa_s->mlme.scan_channel_idx++; 2593 if (wpa_s->mlme.scan_channel_idx >= 2594 wpa_s->mlme.modes[wpa_s->mlme.scan_hw_mode_idx]. 2595 num_channels) { 2596 wpa_s->mlme.scan_hw_mode_idx++; 2597 wpa_s->mlme.scan_channel_idx = 0; 2598 } 2599 2600 if (skip) { 2601 timeout = 0; 2602 break; 2603 } 2604 2605 timeout = IEEE80211_PROBE_DELAY; 2606 wpa_s->mlme.scan_state = SCAN_SEND_PROBE; 2607 break; 2608 case SCAN_SEND_PROBE: 2609 if (ieee80211_active_scan(wpa_s)) { 2610 ieee80211_send_probe_req(wpa_s, NULL, 2611 wpa_s->mlme.scan_ssid, 2612 wpa_s->mlme.scan_ssid_len); 2613 timeout = IEEE80211_CHANNEL_TIME; 2614 } else { 2615 timeout = IEEE80211_PASSIVE_CHANNEL_TIME; 2616 } 2617 wpa_s->mlme.scan_state = SCAN_SET_CHANNEL; 2618 break; 2619 } 2620 2621 eloop_register_timeout(timeout / 1000, 1000 * (timeout % 1000), 2622 ieee80211_sta_scan_timer, wpa_s, NULL); 2623} 2624 2625 2626int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s, const u8 *ssid, 2627 size_t ssid_len) 2628{ 2629 if (ssid_len > MAX_SSID_LEN) 2630 return -1; 2631 2632 /* MLME-SCAN.request (page 118) page 144 (11.1.3.1) 2633 * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS 2634 * BSSID: MACAddress 2635 * SSID 2636 * ScanType: ACTIVE, PASSIVE 2637 * ProbeDelay: delay (in microseconds) to be used prior to transmitting 2638 * a Probe frame during active scanning 2639 * ChannelList 2640 * MinChannelTime (>= ProbeDelay), in TU 2641 * MaxChannelTime: (>= MinChannelTime), in TU 2642 */ 2643 2644 /* MLME-SCAN.confirm 2645 * BSSDescriptionSet 2646 * ResultCode: SUCCESS, INVALID_PARAMETERS 2647 */ 2648 2649 /* TODO: if assoc, move to power save mode for the duration of the 2650 * scan */ 2651 2652 if (wpa_s->mlme.sta_scanning) 2653 return -1; 2654 2655 wpa_printf(MSG_DEBUG, "MLME: starting scan"); 2656 2657 ieee80211_sta_save_oper_chan(wpa_s); 2658 2659 wpa_s->mlme.sta_scanning = 1; 2660 /* TODO: stop TX queue? */ 2661 2662 if (ssid) { 2663 wpa_s->mlme.scan_ssid_len = ssid_len; 2664 os_memcpy(wpa_s->mlme.scan_ssid, ssid, ssid_len); 2665 } else 2666 wpa_s->mlme.scan_ssid_len = 0; 2667 wpa_s->mlme.scan_skip_11b = 1; /* FIX: clear this is 11g is not 2668 * supported */ 2669 wpa_s->mlme.scan_state = SCAN_SET_CHANNEL; 2670 wpa_s->mlme.scan_hw_mode_idx = 0; 2671 wpa_s->mlme.scan_channel_idx = 0; 2672 eloop_register_timeout(0, 1, ieee80211_sta_scan_timer, wpa_s, NULL); 2673 2674 return 0; 2675} 2676 2677 2678struct wpa_scan_results * 2679ieee80211_sta_get_scan_results(struct wpa_supplicant *wpa_s) 2680{ 2681 size_t ap_num = 0; 2682 struct wpa_scan_results *res; 2683 struct wpa_scan_res *r; 2684 struct ieee80211_sta_bss *bss; 2685 2686 res = os_zalloc(sizeof(*res)); 2687 for (bss = wpa_s->mlme.sta_bss_list; bss; bss = bss->next) 2688 ap_num++; 2689 res->res = os_zalloc(ap_num * sizeof(struct wpa_scan_res *)); 2690 if (res->res == NULL) { 2691 os_free(res); 2692 return NULL; 2693 } 2694 2695 for (bss = wpa_s->mlme.sta_bss_list; bss; bss = bss->next) { 2696 r = os_zalloc(sizeof(*r) + bss->ie_len); 2697 if (r == NULL) 2698 break; 2699 os_memcpy(r->bssid, bss->bssid, ETH_ALEN); 2700 r->freq = bss->freq; 2701 r->beacon_int = bss->beacon_int; 2702 r->caps = bss->capability; 2703 r->level = bss->rssi; 2704 r->tsf = bss->timestamp; 2705 if (bss->ie) { 2706 r->ie_len = bss->ie_len; 2707 os_memcpy(r + 1, bss->ie, bss->ie_len); 2708 } 2709 2710 res->res[res->num++] = r; 2711 } 2712 2713 return res; 2714} 2715 2716 2717#if 0 /* FIX */ 2718struct sta_info * ieee80211_ibss_add_sta(struct wpa_supplicant *wpa_s, 2719 struct sk_buff *skb, u8 *bssid, 2720 u8 *addr) 2721{ 2722 struct ieee80211_local *local = dev->priv; 2723 struct list_head *ptr; 2724 struct sta_info *sta; 2725 struct wpa_supplicant *sta_dev = NULL; 2726 2727 /* TODO: Could consider removing the least recently used entry and 2728 * allow new one to be added. */ 2729 if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { 2730 if (net_ratelimit()) { 2731 wpa_printf(MSG_DEBUG, "MLME: No room for a new IBSS " 2732 "STA entry " MACSTR, MAC2STR(addr)); 2733 } 2734 return NULL; 2735 } 2736 2737 spin_lock_bh(&local->sub_if_lock); 2738 list_for_each(ptr, &local->sub_if_list) { 2739 sdata = list_entry(ptr, struct ieee80211_sub_if_data, list); 2740 if (sdata->type == IEEE80211_SUB_IF_TYPE_STA && 2741 os_memcmp(bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) { 2742 sta_dev = sdata->dev; 2743 break; 2744 } 2745 } 2746 spin_unlock_bh(&local->sub_if_lock); 2747 2748 if (sta_dev == NULL) 2749 return NULL; 2750 2751 wpa_printf(MSG_DEBUG, "MLME: Adding new IBSS station " MACSTR 2752 " (dev=%s)", MAC2STR(addr), sta_dev->name); 2753 2754 sta = sta_info_add(wpa_s, addr); 2755 if (sta == NULL) { 2756 return NULL; 2757 } 2758 2759 sta->dev = sta_dev; 2760 sta->supp_rates = wpa_s->mlme.supp_rates_bits; 2761 2762 rate_control_rate_init(local, sta); 2763 2764 return sta; /* caller will call sta_info_release() */ 2765} 2766#endif 2767 2768 2769int ieee80211_sta_deauthenticate(struct wpa_supplicant *wpa_s, u16 reason) 2770{ 2771 wpa_printf(MSG_DEBUG, "MLME: deauthenticate(reason=%d)", reason); 2772 2773 ieee80211_send_deauth(wpa_s, reason); 2774 ieee80211_set_associated(wpa_s, 0); 2775 return 0; 2776} 2777 2778 2779int ieee80211_sta_disassociate(struct wpa_supplicant *wpa_s, u16 reason) 2780{ 2781 wpa_printf(MSG_DEBUG, "MLME: disassociate(reason=%d)", reason); 2782 2783 if (!wpa_s->mlme.associated) 2784 return -1; 2785 2786 ieee80211_send_disassoc(wpa_s, reason); 2787 ieee80211_set_associated(wpa_s, 0); 2788 return 0; 2789} 2790 2791 2792void ieee80211_sta_rx(struct wpa_supplicant *wpa_s, const u8 *buf, size_t len, 2793 struct ieee80211_rx_status *rx_status) 2794{ 2795 struct ieee80211_mgmt *mgmt; 2796 u16 fc; 2797 const u8 *pos; 2798 2799 /* wpa_hexdump(MSG_MSGDUMP, "MLME: Received frame", buf, len); */ 2800 2801 if (wpa_s->mlme.sta_scanning) { 2802 ieee80211_sta_rx_scan(wpa_s, buf, len, rx_status); 2803 return; 2804 } 2805 2806 if (len < 24) 2807 return; 2808 2809 mgmt = (struct ieee80211_mgmt *) buf; 2810 fc = le_to_host16(mgmt->frame_control); 2811 2812 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT) 2813 ieee80211_sta_rx_mgmt(wpa_s, buf, len, rx_status); 2814 else if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) { 2815 if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) != 2816 WLAN_FC_FROMDS) 2817 return; 2818 /* mgmt->sa is actually BSSID for FromDS data frames */ 2819 if (os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) != 0) 2820 return; 2821 /* Skip IEEE 802.11 and LLC headers */ 2822 pos = buf + 24 + 6; 2823 if (WPA_GET_BE16(pos) != ETH_P_EAPOL) 2824 return; 2825 pos += 2; 2826 /* mgmt->bssid is actually BSSID for SA data frames */ 2827 wpa_supplicant_rx_eapol(wpa_s, mgmt->bssid, 2828 pos, buf + len - pos); 2829 } 2830} 2831 2832 2833void ieee80211_sta_free_hw_features(struct wpa_hw_modes *hw_features, 2834 size_t num_hw_features) 2835{ 2836 size_t i; 2837 2838 if (hw_features == NULL) 2839 return; 2840 2841 for (i = 0; i < num_hw_features; i++) { 2842 os_free(hw_features[i].channels); 2843 os_free(hw_features[i].rates); 2844 } 2845 2846 os_free(hw_features); 2847} 2848 2849 2850int ieee80211_sta_init(struct wpa_supplicant *wpa_s) 2851{ 2852 u16 num_modes, flags; 2853 2854 wpa_s->mlme.modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, 2855 &flags); 2856 if (wpa_s->mlme.modes == NULL) { 2857 wpa_printf(MSG_ERROR, "MLME: Failed to read supported " 2858 "channels and rates from the driver"); 2859 return -1; 2860 } 2861 2862 wpa_s->mlme.num_modes = num_modes; 2863 2864 wpa_s->mlme.hw_modes = 1 << WPA_MODE_IEEE80211A; 2865 wpa_s->mlme.hw_modes |= 1 << WPA_MODE_IEEE80211B; 2866 wpa_s->mlme.hw_modes |= 1 << WPA_MODE_IEEE80211G; 2867 2868 return 0; 2869} 2870 2871 2872void ieee80211_sta_deinit(struct wpa_supplicant *wpa_s) 2873{ 2874 eloop_cancel_timeout(ieee80211_sta_timer, wpa_s, NULL); 2875 eloop_cancel_timeout(ieee80211_sta_scan_timer, wpa_s, NULL); 2876 os_free(wpa_s->mlme.extra_ie); 2877 wpa_s->mlme.extra_ie = NULL; 2878 os_free(wpa_s->mlme.extra_probe_ie); 2879 wpa_s->mlme.extra_probe_ie = NULL; 2880 os_free(wpa_s->mlme.assocreq_ies); 2881 wpa_s->mlme.assocreq_ies = NULL; 2882 os_free(wpa_s->mlme.assocresp_ies); 2883 wpa_s->mlme.assocresp_ies = NULL; 2884 ieee80211_bss_list_deinit(wpa_s); 2885 ieee80211_sta_free_hw_features(wpa_s->mlme.modes, 2886 wpa_s->mlme.num_modes); 2887#ifdef CONFIG_IEEE80211R 2888 os_free(wpa_s->mlme.ft_ies); 2889 wpa_s->mlme.ft_ies = NULL; 2890 wpa_s->mlme.ft_ies_len = 0; 2891#endif /* CONFIG_IEEE80211R */ 2892} 2893 2894 2895#ifdef CONFIG_IEEE80211R 2896 2897int ieee80211_sta_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md, 2898 const u8 *ies, size_t ies_len) 2899{ 2900 if (md == NULL) { 2901 wpa_printf(MSG_DEBUG, "MLME: Clear FT mobility domain"); 2902 os_memset(wpa_s->mlme.current_md, 0, MOBILITY_DOMAIN_ID_LEN); 2903 } else { 2904 wpa_printf(MSG_DEBUG, "MLME: Update FT IEs for MD " MACSTR, 2905 MAC2STR(md)); 2906 os_memcpy(wpa_s->mlme.current_md, md, MOBILITY_DOMAIN_ID_LEN); 2907 } 2908 2909 wpa_hexdump(MSG_DEBUG, "MLME: FT IEs", ies, ies_len); 2910 os_free(wpa_s->mlme.ft_ies); 2911 wpa_s->mlme.ft_ies = os_malloc(ies_len); 2912 if (wpa_s->mlme.ft_ies == NULL) 2913 return -1; 2914 os_memcpy(wpa_s->mlme.ft_ies, ies, ies_len); 2915 wpa_s->mlme.ft_ies_len = ies_len; 2916 2917 return 0; 2918} 2919 2920 2921int ieee80211_sta_send_ft_action(struct wpa_supplicant *wpa_s, u8 action, 2922 const u8 *target_ap, 2923 const u8 *ies, size_t ies_len) 2924{ 2925 u8 *buf; 2926 size_t len; 2927 struct ieee80211_mgmt *mgmt; 2928 int res; 2929 2930 /* 2931 * Action frame payload: 2932 * Category[1] = 6 (Fast BSS Transition) 2933 * Action[1] = 1 (Fast BSS Transition Request) 2934 * STA Address 2935 * Target AP Address 2936 * FT IEs 2937 */ 2938 2939 buf = os_zalloc(sizeof(*mgmt) + ies_len); 2940 if (buf == NULL) { 2941 wpa_printf(MSG_DEBUG, "MLME: Failed to allocate buffer for " 2942 "FT action frame"); 2943 return -1; 2944 } 2945 2946 mgmt = (struct ieee80211_mgmt *) buf; 2947 len = 24; 2948 os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN); 2949 os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 2950 os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN); 2951 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 2952 WLAN_FC_STYPE_ACTION); 2953 mgmt->u.action.category = WLAN_ACTION_FT; 2954 mgmt->u.action.u.ft_action_req.action = action; 2955 os_memcpy(mgmt->u.action.u.ft_action_req.sta_addr, wpa_s->own_addr, 2956 ETH_ALEN); 2957 os_memcpy(mgmt->u.action.u.ft_action_req.target_ap_addr, target_ap, 2958 ETH_ALEN); 2959 os_memcpy(mgmt->u.action.u.ft_action_req.variable, ies, ies_len); 2960 len += 1 + sizeof(mgmt->u.action.u.ft_action_req) + ies_len; 2961 2962 wpa_printf(MSG_DEBUG, "MLME: Send FT Action Frame: Action=%d " 2963 "Target AP=" MACSTR " body_len=%lu", 2964 action, MAC2STR(target_ap), (unsigned long) ies_len); 2965 2966 res = ieee80211_sta_tx(wpa_s, buf, len); 2967 os_free(buf); 2968 2969 return res; 2970} 2971 2972#endif /* CONFIG_IEEE80211R */ 2973 2974 2975int ieee80211_sta_set_probe_req_ie(struct wpa_supplicant *wpa_s, const u8 *ies, 2976 size_t ies_len) 2977{ 2978 os_free(wpa_s->mlme.extra_probe_ie); 2979 wpa_s->mlme.extra_probe_ie = NULL; 2980 wpa_s->mlme.extra_probe_ie_len = 0; 2981 2982 if (ies == NULL) 2983 return 0; 2984 2985 wpa_s->mlme.extra_probe_ie = os_malloc(ies_len); 2986 if (wpa_s->mlme.extra_probe_ie == NULL) 2987 return -1; 2988 2989 os_memcpy(wpa_s->mlme.extra_probe_ie, ies, ies_len); 2990 wpa_s->mlme.extra_probe_ie_len = ies_len; 2991 2992 return 0; 2993} 2994