00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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;
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] != 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:
00160 if (acm)
00161 wmm_acm |= BIT(1) | BIT(2);
00162 break;
00163 case 2:
00164 if (acm)
00165 wmm_acm |= BIT(4) | BIT(5);
00166 break;
00167 case 3:
00168 if (acm)
00169 wmm_acm |= BIT(6) | BIT(7);
00170 break;
00171 case 0:
00172 default:
00173 if (acm)
00174 wmm_acm |= BIT(0) | BIT(3);
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
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
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
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
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
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;
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
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;
00446 *pos++ = 0x00;
00447 *pos++ = 0x50;
00448 *pos++ = 0xf2;
00449 *pos++ = 2;
00450 *pos++ = 0;
00451 *pos++ = 1;
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
00575
00576
00577
00578
00579 wpa_s->mlme.state = IEEE80211_ASSOCIATED;
00580
00581 #if 0
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
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
00799
00800
00801
00802
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
00889
00890
00891 wpabuf_put_u8(ric, WLAN_EID_RIC_DATA);
00892 wpabuf_put_u8(ric, 4);
00893 wpabuf_put_u8(ric, 0);
00894 wpabuf_put_u8(ric, 1);
00895
00896 wpabuf_put_le16(ric, 0);
00897
00898
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
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;
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);
01022 tspec->minimum_phy_rate = host_to_le32(6000000);
01023 tspec->surplus_bandwidth_allowance = host_to_le16(0x3000);
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
01072
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
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
01199
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
01215 ieee80211_tx_addts(wpa_s);
01216 }
01217 }
01218
01219
01220
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
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
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;
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
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
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
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
01412
01413
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
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
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
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
01571
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
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
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
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
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
01689 return;
01690 }
01691
01692 #if 0
01693
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
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
01726
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
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
01761
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
01769
01770
01771 #ifdef CONFIG_IEEE80211W
01772
01773
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
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
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
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
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
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
02169 if (local->hw->reset_tsf) {
02170
02171 local->hw->reset_tsf(local->mdev);
02172 }
02173 #endif
02174
02175 wpa_s->mlme.wmm_last_param_set = -1;
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
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
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
02233 #if 0
02234 sta_info_flush(local, NULL);
02235
02236 if (local->hw->reset_tsf) {
02237
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
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
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
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
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
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
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
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
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
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
02405 os_memset(bssid, 0xfe, ETH_ALEN);
02406 #else
02407
02408
02409
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
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
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
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
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
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
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
02502
02503
02504 os_get_time(&now);
02505 #if 0
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
02533
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
02582
02583
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
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
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
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
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
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;
02868
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
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
02928
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;
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
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
03019 if (os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) != 0)
03020 return;
03021
03022 pos = buf + 24 + 6;
03023 if (WPA_GET_BE16(pos) != ETH_P_EAPOL)
03024 return;
03025 pos += 2;
03026
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
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
03137
03138
03139
03140
03141
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
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 }