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