Rename HT Capabilities IE fields to match with IEEE Std 802.11n-2009
[libeap.git] / hostapd / ieee802_11.c
1 /*
2  * hostapd / IEEE 802.11 Management
3  * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
4  * Copyright (c) 2007-2008, Intel Corporation
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * Alternatively, this software may be distributed under the terms of BSD
11  * license.
12  *
13  * See README and COPYING for more details.
14  */
15
16 #include "includes.h"
17
18 #ifndef CONFIG_NATIVE_WINDOWS
19
20 #include <net/if.h>
21
22 #include "eloop.h"
23 #include "hostapd.h"
24 #include "ieee802_11.h"
25 #include "beacon.h"
26 #include "hw_features.h"
27 #include "radius/radius.h"
28 #include "radius/radius_client.h"
29 #include "ieee802_11_auth.h"
30 #include "sta_info.h"
31 #include "crypto.h"
32 #include "ieee802_1x.h"
33 #include "wpa.h"
34 #include "wme.h"
35 #include "ap_list.h"
36 #include "accounting.h"
37 #include "driver_i.h"
38 #include "mlme.h"
39 #include "wpa_ctrl.h"
40
41
42 u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
43 {
44         u8 *pos = eid;
45         int i, num, count;
46
47         if (hapd->iface->current_rates == NULL)
48                 return eid;
49
50         *pos++ = WLAN_EID_SUPP_RATES;
51         num = hapd->iface->num_rates;
52         if (num > 8) {
53                 /* rest of the rates are encoded in Extended supported
54                  * rates element */
55                 num = 8;
56         }
57
58         *pos++ = num;
59         count = 0;
60         for (i = 0, count = 0; i < hapd->iface->num_rates && count < num;
61              i++) {
62                 count++;
63                 *pos = hapd->iface->current_rates[i].rate / 5;
64                 if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
65                         *pos |= 0x80;
66                 pos++;
67         }
68
69         return pos;
70 }
71
72
73 u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid)
74 {
75         u8 *pos = eid;
76         int i, num, count;
77
78         if (hapd->iface->current_rates == NULL)
79                 return eid;
80
81         num = hapd->iface->num_rates;
82         if (num <= 8)
83                 return eid;
84         num -= 8;
85
86         *pos++ = WLAN_EID_EXT_SUPP_RATES;
87         *pos++ = num;
88         count = 0;
89         for (i = 0, count = 0; i < hapd->iface->num_rates && count < num + 8;
90              i++) {
91                 count++;
92                 if (count <= 8)
93                         continue; /* already in SuppRates IE */
94                 *pos = hapd->iface->current_rates[i].rate / 5;
95                 if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
96                         *pos |= 0x80;
97                 pos++;
98         }
99
100         return pos;
101 }
102
103
104 u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid)
105 {
106 #ifdef CONFIG_IEEE80211N
107         struct ieee80211_ht_capabilities *cap;
108         u8 *pos = eid;
109
110         if (!hapd->iconf->ieee80211n)
111                 return eid;
112
113         *pos++ = WLAN_EID_HT_CAP;
114         *pos++ = sizeof(*cap);
115
116         cap = (struct ieee80211_ht_capabilities *) pos;
117         os_memset(cap, 0, sizeof(*cap));
118         cap->ht_capabilities_info = host_to_le16(hapd->iconf->ht_capab);
119
120         /* FIX: from driver */
121         SET_2BIT_U8(&cap->a_mpdu_params,
122                     MAC_HT_PARAM_INFO_MAX_RX_AMPDU_FACTOR_OFFSET,
123                     MAX_RX_AMPDU_FACTOR_64KB);
124
125         os_memcpy(cap->supported_mcs_set, hapd->iface->current_mode->mcs_set,
126                   16);
127
128         /* TODO: ht_extended_capabilities (now fully disabled) */
129         /* TODO: tx_bf_capability_info (now fully disabled) */
130         /* TODO: asel_capabilities (now fully disabled) */
131
132         pos += sizeof(*cap);
133
134         return pos;
135 #else /* CONFIG_IEEE80211N */
136         return eid;
137 #endif /* CONFIG_IEEE80211N */
138 }
139
140
141 u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid)
142 {
143 #ifdef CONFIG_IEEE80211N
144         struct ieee80211_ht_operation *oper;
145         u8 *pos = eid;
146
147         if (!hapd->iconf->ieee80211n)
148                 return eid;
149
150         *pos++ = WLAN_EID_HT_OPERATION;
151         *pos++ = sizeof(*oper);
152
153         oper = (struct ieee80211_ht_operation *) pos;
154         os_memset(oper, 0, sizeof(*oper));
155
156         oper->control_chan = hapd->iconf->channel;
157         oper->operation_mode = host_to_le16(hapd->iface->ht_op_mode);
158         if (hapd->iconf->secondary_channel == 1)
159                 oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE |
160                         HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH;
161         if (hapd->iconf->secondary_channel == -1)
162                 oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW |
163                         HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH;
164
165         pos += sizeof(*oper);
166
167         return pos;
168 #else /* CONFIG_IEEE80211N */
169         return eid;
170 #endif /* CONFIG_IEEE80211N */
171 }
172
173
174 #ifdef CONFIG_IEEE80211N
175
176 /*
177 op_mode
178 Set to 0 (HT pure) under the followign conditions
179         - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
180         - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
181 Set to 1 (HT non-member protection) if there may be non-HT STAs
182         in both the primary and the secondary channel
183 Set to 2 if only HT STAs are associated in BSS,
184         however and at least one 20 MHz HT STA is associated
185 Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
186         (currently non-GF HT station is considered as non-HT STA also)
187 */
188 int hostapd_ht_operation_update(struct hostapd_iface *iface)
189 {
190         u16 cur_op_mode, new_op_mode;
191         int op_mode_changes = 0;
192
193         if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed)
194                 return 0;
195
196         wpa_printf(MSG_DEBUG, "%s current operation mode=0x%X",
197                    __func__, iface->ht_op_mode);
198
199         if (!(iface->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)
200             && iface->num_sta_ht_no_gf) {
201                 iface->ht_op_mode |=
202                         HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
203                 op_mode_changes++;
204         } else if ((iface->ht_op_mode &
205                     HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
206                    iface->num_sta_ht_no_gf == 0) {
207                 iface->ht_op_mode &=
208                         ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
209                 op_mode_changes++;
210         }
211
212         if (!(iface->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
213             (iface->num_sta_no_ht || iface->olbc_ht)) {
214                 iface->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
215                 op_mode_changes++;
216         } else if ((iface->ht_op_mode &
217                     HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
218                    (iface->num_sta_no_ht == 0 && !iface->olbc_ht)) {
219                 iface->ht_op_mode &=
220                         ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
221                 op_mode_changes++;
222         }
223
224         /* Note: currently we switch to the MIXED op mode if HT non-greenfield
225          * station is associated. Probably it's a theoretical case, since
226          * it looks like all known HT STAs support greenfield.
227          */
228         new_op_mode = 0;
229         if (iface->num_sta_no_ht ||
230             (iface->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
231                 new_op_mode = OP_MODE_MIXED;
232         else if ((iface->conf->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)
233                  && iface->num_sta_ht_20mhz)
234                 new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
235         else if (iface->olbc_ht)
236                 new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
237         else
238                 new_op_mode = OP_MODE_PURE;
239
240         cur_op_mode = iface->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
241         if (cur_op_mode != new_op_mode) {
242                 iface->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
243                 iface->ht_op_mode |= new_op_mode;
244                 op_mode_changes++;
245         }
246
247         wpa_printf(MSG_DEBUG, "%s new operation mode=0x%X changes=%d",
248                    __func__, iface->ht_op_mode, op_mode_changes);
249
250         return op_mode_changes;
251 }
252
253 #endif /* CONFIG_IEEE80211N */
254
255
256 u16 hostapd_own_capab_info(struct hostapd_data *hapd, struct sta_info *sta,
257                            int probe)
258 {
259         int capab = WLAN_CAPABILITY_ESS;
260         int privacy;
261
262         if (hapd->iface->num_sta_no_short_preamble == 0 &&
263             hapd->iconf->preamble == SHORT_PREAMBLE)
264                 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
265
266         privacy = hapd->conf->ssid.wep.keys_set;
267
268         if (hapd->conf->ieee802_1x &&
269             (hapd->conf->default_wep_key_len ||
270              hapd->conf->individual_wep_key_len))
271                 privacy = 1;
272
273         if (hapd->conf->wpa)
274                 privacy = 1;
275
276         if (sta) {
277                 int policy, def_klen;
278                 if (probe && sta->ssid_probe) {
279                         policy = sta->ssid_probe->security_policy;
280                         def_klen = sta->ssid_probe->wep.default_len;
281                 } else {
282                         policy = sta->ssid->security_policy;
283                         def_klen = sta->ssid->wep.default_len;
284                 }
285                 privacy = policy != SECURITY_PLAINTEXT;
286                 if (policy == SECURITY_IEEE_802_1X && def_klen == 0)
287                         privacy = 0;
288         }
289
290         if (privacy)
291                 capab |= WLAN_CAPABILITY_PRIVACY;
292
293         if (hapd->iface->current_mode &&
294             hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G &&
295             hapd->iface->num_sta_no_short_slot_time == 0)
296                 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
297
298         return capab;
299 }
300
301
302 #ifdef CONFIG_IEEE80211W
303 static u8 * hostapd_eid_assoc_comeback_time(struct hostapd_data *hapd,
304                                             struct sta_info *sta, u8 *eid)
305 {
306         u8 *pos = eid;
307         u32 timeout, tu;
308         struct os_time now, passed;
309
310         *pos++ = WLAN_EID_TIMEOUT_INTERVAL;
311         *pos++ = 5;
312         *pos++ = WLAN_TIMEOUT_ASSOC_COMEBACK;
313         os_get_time(&now);
314         os_time_sub(&now, &sta->sa_query_start, &passed);
315         tu = (passed.sec * 1000000 + passed.usec) / 1024;
316         if (hapd->conf->assoc_sa_query_max_timeout > tu)
317                 timeout = hapd->conf->assoc_sa_query_max_timeout - tu;
318         else
319                 timeout = 0;
320         if (timeout < hapd->conf->assoc_sa_query_max_timeout)
321                 timeout++; /* add some extra time for local timers */
322         WPA_PUT_LE32(pos, timeout);
323         pos += 4;
324
325         return pos;
326 }
327 #endif /* CONFIG_IEEE80211W */
328
329
330 void ieee802_11_print_ssid(char *buf, const u8 *ssid, u8 len)
331 {
332         int i;
333         if (len > HOSTAPD_MAX_SSID_LEN)
334                 len = HOSTAPD_MAX_SSID_LEN;
335         for (i = 0; i < len; i++) {
336                 if (ssid[i] >= 32 && ssid[i] < 127)
337                         buf[i] = ssid[i];
338                 else
339                         buf[i] = '.';
340         }
341         buf[len] = '\0';
342 }
343
344
345 /**
346  * ieee802_11_send_deauth - Send Deauthentication frame
347  * @hapd: hostapd BSS data
348  * @addr: Address of the destination STA
349  * @reason: Reason code for Deauthentication
350  */
351 void ieee802_11_send_deauth(struct hostapd_data *hapd, u8 *addr, u16 reason)
352 {
353         struct ieee80211_mgmt mgmt;
354
355         hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
356                        HOSTAPD_LEVEL_DEBUG,
357                        "deauthenticate - reason %d", reason);
358         os_memset(&mgmt, 0, sizeof(mgmt));
359         mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
360                                           WLAN_FC_STYPE_DEAUTH);
361         os_memcpy(mgmt.da, addr, ETH_ALEN);
362         os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
363         os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
364         mgmt.u.deauth.reason_code = host_to_le16(reason);
365         if (hostapd_send_mgmt_frame(hapd, &mgmt, IEEE80211_HDRLEN +
366                                     sizeof(mgmt.u.deauth)) < 0)
367                 perror("ieee802_11_send_deauth: send");
368 }
369
370
371 static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta,
372                            u16 auth_transaction, u8 *challenge, int iswep)
373 {
374         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
375                        HOSTAPD_LEVEL_DEBUG,
376                        "authentication (shared key, transaction %d)",
377                        auth_transaction);
378
379         if (auth_transaction == 1) {
380                 if (!sta->challenge) {
381                         /* Generate a pseudo-random challenge */
382                         u8 key[8];
383                         time_t now;
384                         int r;
385                         sta->challenge = os_zalloc(WLAN_AUTH_CHALLENGE_LEN);
386                         if (sta->challenge == NULL)
387                                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
388
389                         now = time(NULL);
390                         r = random();
391                         os_memcpy(key, &now, 4);
392                         os_memcpy(key + 4, &r, 4);
393                         rc4_skip(key, sizeof(key), 0,
394                                  sta->challenge, WLAN_AUTH_CHALLENGE_LEN);
395                 }
396                 return 0;
397         }
398
399         if (auth_transaction != 3)
400                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
401
402         /* Transaction 3 */
403         if (!iswep || !sta->challenge || !challenge ||
404             os_memcmp(sta->challenge, challenge, WLAN_AUTH_CHALLENGE_LEN)) {
405                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
406                                HOSTAPD_LEVEL_INFO,
407                                "shared key authentication - invalid "
408                                "challenge-response");
409                 return WLAN_STATUS_CHALLENGE_FAIL;
410         }
411
412         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
413                        HOSTAPD_LEVEL_DEBUG,
414                        "authentication OK (shared key)");
415 #ifdef IEEE80211_REQUIRE_AUTH_ACK
416         /* Station will be marked authenticated if it ACKs the
417          * authentication reply. */
418 #else
419         sta->flags |= WLAN_STA_AUTH;
420         wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
421 #endif
422         os_free(sta->challenge);
423         sta->challenge = NULL;
424
425         return 0;
426 }
427
428
429 static void send_auth_reply(struct hostapd_data *hapd,
430                             const u8 *dst, const u8 *bssid,
431                             u16 auth_alg, u16 auth_transaction, u16 resp,
432                             const u8 *ies, size_t ies_len)
433 {
434         struct ieee80211_mgmt *reply;
435         u8 *buf;
436         size_t rlen;
437
438         rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth) + ies_len;
439         buf = os_zalloc(rlen);
440         if (buf == NULL)
441                 return;
442
443         reply = (struct ieee80211_mgmt *) buf;
444         reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
445                                             WLAN_FC_STYPE_AUTH);
446         os_memcpy(reply->da, dst, ETH_ALEN);
447         os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
448         os_memcpy(reply->bssid, bssid, ETH_ALEN);
449
450         reply->u.auth.auth_alg = host_to_le16(auth_alg);
451         reply->u.auth.auth_transaction = host_to_le16(auth_transaction);
452         reply->u.auth.status_code = host_to_le16(resp);
453
454         if (ies && ies_len)
455                 os_memcpy(reply->u.auth.variable, ies, ies_len);
456
457         wpa_printf(MSG_DEBUG, "authentication reply: STA=" MACSTR
458                    " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
459                    MAC2STR(dst), auth_alg, auth_transaction,
460                    resp, (unsigned long) ies_len);
461         if (hostapd_send_mgmt_frame(hapd, reply, rlen) < 0)
462                 perror("send_auth_reply: send");
463
464         os_free(buf);
465 }
466
467
468 #ifdef CONFIG_IEEE80211R
469 static void handle_auth_ft_finish(void *ctx, const u8 *dst, const u8 *bssid,
470                                   u16 auth_transaction, u16 status,
471                                   const u8 *ies, size_t ies_len)
472 {
473         struct hostapd_data *hapd = ctx;
474         struct sta_info *sta;
475
476         send_auth_reply(hapd, dst, bssid, WLAN_AUTH_FT, auth_transaction,
477                         status, ies, ies_len);
478
479         if (status != WLAN_STATUS_SUCCESS)
480                 return;
481
482         sta = ap_get_sta(hapd, dst);
483         if (sta == NULL)
484                 return;
485
486         hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
487                        HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
488         sta->flags |= WLAN_STA_AUTH;
489         mlme_authenticate_indication(hapd, sta);
490 }
491 #endif /* CONFIG_IEEE80211R */
492
493
494 static void handle_auth(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
495                         size_t len)
496 {
497         u16 auth_alg, auth_transaction, status_code;
498         u16 resp = WLAN_STATUS_SUCCESS;
499         struct sta_info *sta = NULL;
500         int res;
501         u16 fc;
502         u8 *challenge = NULL;
503         u32 session_timeout, acct_interim_interval;
504         int vlan_id = 0;
505         u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
506         size_t resp_ies_len = 0;
507
508         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
509                 printf("handle_auth - too short payload (len=%lu)\n",
510                        (unsigned long) len);
511                 return;
512         }
513
514         auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
515         auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
516         status_code = le_to_host16(mgmt->u.auth.status_code);
517         fc = le_to_host16(mgmt->frame_control);
518
519         if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) +
520             2 + WLAN_AUTH_CHALLENGE_LEN &&
521             mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE &&
522             mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN)
523                 challenge = &mgmt->u.auth.variable[2];
524
525         wpa_printf(MSG_DEBUG, "authentication: STA=" MACSTR " auth_alg=%d "
526                    "auth_transaction=%d status_code=%d wep=%d%s",
527                    MAC2STR(mgmt->sa), auth_alg, auth_transaction,
528                    status_code, !!(fc & WLAN_FC_ISWEP),
529                    challenge ? " challenge" : "");
530
531         if (hapd->tkip_countermeasures) {
532                 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
533                 goto fail;
534         }
535
536         if (!(((hapd->conf->auth_algs & WPA_AUTH_ALG_OPEN) &&
537                auth_alg == WLAN_AUTH_OPEN) ||
538 #ifdef CONFIG_IEEE80211R
539               (hapd->conf->wpa &&
540                (hapd->conf->wpa_key_mgmt &
541                 (WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_FT_PSK)) &&
542                auth_alg == WLAN_AUTH_FT) ||
543 #endif /* CONFIG_IEEE80211R */
544               ((hapd->conf->auth_algs & WPA_AUTH_ALG_SHARED) &&
545                auth_alg == WLAN_AUTH_SHARED_KEY))) {
546                 printf("Unsupported authentication algorithm (%d)\n",
547                        auth_alg);
548                 resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
549                 goto fail;
550         }
551
552         if (!(auth_transaction == 1 ||
553               (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) {
554                 printf("Unknown authentication transaction number (%d)\n",
555                        auth_transaction);
556                 resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
557                 goto fail;
558         }
559
560         if (os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) {
561                 printf("Station " MACSTR " not allowed to authenticate.\n",
562                        MAC2STR(mgmt->sa));
563                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
564                 goto fail;
565         }
566
567         res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len,
568                                       &session_timeout,
569                                       &acct_interim_interval, &vlan_id);
570         if (res == HOSTAPD_ACL_REJECT) {
571                 printf("Station " MACSTR " not allowed to authenticate.\n",
572                        MAC2STR(mgmt->sa));
573                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
574                 goto fail;
575         }
576         if (res == HOSTAPD_ACL_PENDING) {
577                 wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR
578                            " waiting for an external authentication",
579                            MAC2STR(mgmt->sa));
580                 /* Authentication code will re-send the authentication frame
581                  * after it has received (and cached) information from the
582                  * external source. */
583                 return;
584         }
585
586         sta = ap_sta_add(hapd, mgmt->sa);
587         if (!sta) {
588                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
589                 goto fail;
590         }
591
592         if (vlan_id > 0) {
593                 if (hostapd_get_vlan_id_ifname(hapd->conf->vlan,
594                                                vlan_id) == NULL) {
595                         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
596                                        HOSTAPD_LEVEL_INFO, "Invalid VLAN ID "
597                                        "%d received from RADIUS server",
598                                        vlan_id);
599                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
600                         goto fail;
601                 }
602                 sta->vlan_id = vlan_id;
603                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
604                                HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
605         }
606
607         sta->flags &= ~WLAN_STA_PREAUTH;
608         ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
609
610         if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval)
611                 sta->acct_interim_interval = acct_interim_interval;
612         if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
613                 ap_sta_session_timeout(hapd, sta, session_timeout);
614         else
615                 ap_sta_no_session_timeout(hapd, sta);
616
617         switch (auth_alg) {
618         case WLAN_AUTH_OPEN:
619                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
620                                HOSTAPD_LEVEL_DEBUG,
621                                "authentication OK (open system)");
622 #ifdef IEEE80211_REQUIRE_AUTH_ACK
623                 /* Station will be marked authenticated if it ACKs the
624                  * authentication reply. */
625 #else
626                 sta->flags |= WLAN_STA_AUTH;
627                 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
628                 sta->auth_alg = WLAN_AUTH_OPEN;
629                 mlme_authenticate_indication(hapd, sta);
630 #endif
631                 break;
632         case WLAN_AUTH_SHARED_KEY:
633                 resp = auth_shared_key(hapd, sta, auth_transaction, challenge,
634                                        fc & WLAN_FC_ISWEP);
635                 sta->auth_alg = WLAN_AUTH_SHARED_KEY;
636                 mlme_authenticate_indication(hapd, sta);
637                 if (sta->challenge && auth_transaction == 1) {
638                         resp_ies[0] = WLAN_EID_CHALLENGE;
639                         resp_ies[1] = WLAN_AUTH_CHALLENGE_LEN;
640                         os_memcpy(resp_ies + 2, sta->challenge,
641                                   WLAN_AUTH_CHALLENGE_LEN);
642                         resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN;
643                 }
644                 break;
645 #ifdef CONFIG_IEEE80211R
646         case WLAN_AUTH_FT:
647                 sta->auth_alg = WLAN_AUTH_FT;
648                 if (sta->wpa_sm == NULL)
649                         sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
650                                                         sta->addr);
651                 if (sta->wpa_sm == NULL) {
652                         wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA "
653                                    "state machine");
654                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
655                         goto fail;
656                 }
657                 wpa_ft_process_auth(sta->wpa_sm, mgmt->bssid,
658                                     auth_transaction, mgmt->u.auth.variable,
659                                     len - IEEE80211_HDRLEN -
660                                     sizeof(mgmt->u.auth),
661                                     handle_auth_ft_finish, hapd);
662                 /* handle_auth_ft_finish() callback will complete auth. */
663                 return;
664 #endif /* CONFIG_IEEE80211R */
665         }
666
667  fail:
668         send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg,
669                         auth_transaction + 1, resp, resp_ies, resp_ies_len);
670 }
671
672
673 static int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta)
674 {
675         int i, j = 32, aid;
676
677         /* get a unique AID */
678         if (sta->aid > 0) {
679                 wpa_printf(MSG_DEBUG, "  old AID %d", sta->aid);
680                 return 0;
681         }
682
683         for (i = 0; i < AID_WORDS; i++) {
684                 if (hapd->sta_aid[i] == (u32) -1)
685                         continue;
686                 for (j = 0; j < 32; j++) {
687                         if (!(hapd->sta_aid[i] & BIT(j)))
688                                 break;
689                 }
690                 if (j < 32)
691                         break;
692         }
693         if (j == 32)
694                 return -1;
695         aid = i * 32 + j + 1;
696         if (aid > 2007)
697                 return -1;
698
699         sta->aid = aid;
700         hapd->sta_aid[i] |= BIT(j);
701         wpa_printf(MSG_DEBUG, "  new AID %d", sta->aid);
702         return 0;
703 }
704
705
706 static void handle_assoc(struct hostapd_data *hapd,
707                          struct ieee80211_mgmt *mgmt, size_t len, int reassoc)
708 {
709         u16 capab_info, listen_interval;
710         u16 resp = WLAN_STATUS_SUCCESS;
711         u8 *pos, *wpa_ie;
712         size_t wpa_ie_len;
713         int send_deauth = 0, send_len, left, i;
714         struct sta_info *sta;
715         struct ieee802_11_elems elems;
716         u8 buf[sizeof(struct ieee80211_mgmt) + 1024];
717         struct ieee80211_mgmt *reply;
718
719         if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
720                                       sizeof(mgmt->u.assoc_req))) {
721                 printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
722                        "\n", reassoc, (unsigned long) len);
723                 return;
724         }
725
726         if (reassoc) {
727                 capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info);
728                 listen_interval = le_to_host16(
729                         mgmt->u.reassoc_req.listen_interval);
730                 wpa_printf(MSG_DEBUG, "reassociation request: STA=" MACSTR
731                            " capab_info=0x%02x listen_interval=%d current_ap="
732                            MACSTR,
733                            MAC2STR(mgmt->sa), capab_info, listen_interval,
734                            MAC2STR(mgmt->u.reassoc_req.current_ap));
735                 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req));
736                 pos = mgmt->u.reassoc_req.variable;
737         } else {
738                 capab_info = le_to_host16(mgmt->u.assoc_req.capab_info);
739                 listen_interval = le_to_host16(
740                         mgmt->u.assoc_req.listen_interval);
741                 wpa_printf(MSG_DEBUG, "association request: STA=" MACSTR
742                            " capab_info=0x%02x listen_interval=%d",
743                            MAC2STR(mgmt->sa), capab_info, listen_interval);
744                 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req));
745                 pos = mgmt->u.assoc_req.variable;
746         }
747
748         sta = ap_get_sta(hapd, mgmt->sa);
749 #ifdef CONFIG_IEEE80211R
750         if (sta && sta->auth_alg == WLAN_AUTH_FT &&
751             (sta->flags & WLAN_STA_AUTH) == 0) {
752                 wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate "
753                            "prior to authentication since it is using "
754                            "over-the-DS FT", MAC2STR(mgmt->sa));
755         } else
756 #endif /* CONFIG_IEEE80211R */
757         if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {
758                 printf("STA " MACSTR " trying to associate before "
759                        "authentication\n", MAC2STR(mgmt->sa));
760                 if (sta) {
761                         printf("  sta: addr=" MACSTR " aid=%d flags=0x%04x\n",
762                                MAC2STR(sta->addr), sta->aid, sta->flags);
763                 }
764                 send_deauth = 1;
765                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
766                 goto fail;
767         }
768
769         if (hapd->tkip_countermeasures) {
770                 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
771                 goto fail;
772         }
773
774         if (listen_interval > hapd->conf->max_listen_interval) {
775                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
776                                HOSTAPD_LEVEL_DEBUG,
777                                "Too large Listen Interval (%d)",
778                                listen_interval);
779                 resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
780                 goto fail;
781         }
782
783         sta->capability = capab_info;
784         sta->listen_interval = listen_interval;
785
786         /* followed by SSID and Supported rates; and HT capabilities if 802.11n
787          * is used */
788         if (ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
789             !elems.ssid) {
790                 printf("STA " MACSTR " sent invalid association request\n",
791                        MAC2STR(sta->addr));
792                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
793                 goto fail;
794         }
795
796         if (elems.ssid_len != hapd->conf->ssid.ssid_len ||
797             os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) != 0)
798         {
799                 char ssid_txt[33];
800                 ieee802_11_print_ssid(ssid_txt, elems.ssid, elems.ssid_len);
801                 printf("Station " MACSTR " tried to associate with "
802                        "unknown SSID '%s'\n", MAC2STR(sta->addr), ssid_txt);
803                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
804                 goto fail;
805         }
806
807         sta->flags &= ~WLAN_STA_WMM;
808         if (elems.wmm && hapd->conf->wmm_enabled) {
809                 if (hostapd_eid_wmm_valid(hapd, elems.wmm, elems.wmm_len))
810                         hostapd_logger(hapd, sta->addr,
811                                        HOSTAPD_MODULE_WPA,
812                                        HOSTAPD_LEVEL_DEBUG,
813                                        "invalid WMM element in association "
814                                        "request");
815                 else
816                         sta->flags |= WLAN_STA_WMM;
817         }
818
819         if (!elems.supp_rates) {
820                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
821                                HOSTAPD_LEVEL_DEBUG,
822                                "No supported rates element in AssocReq");
823                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
824                 goto fail;
825         }
826
827         if (elems.supp_rates_len > sizeof(sta->supported_rates)) {
828                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
829                                HOSTAPD_LEVEL_DEBUG,
830                                "Invalid supported rates element length %d",
831                                elems.supp_rates_len);
832                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
833                 goto fail;
834         }
835
836         os_memset(sta->supported_rates, 0, sizeof(sta->supported_rates));
837         os_memcpy(sta->supported_rates, elems.supp_rates,
838                   elems.supp_rates_len);
839         sta->supported_rates_len = elems.supp_rates_len;
840
841         if (elems.ext_supp_rates) {
842                 if (elems.supp_rates_len + elems.ext_supp_rates_len >
843                     sizeof(sta->supported_rates)) {
844                         hostapd_logger(hapd, mgmt->sa,
845                                        HOSTAPD_MODULE_IEEE80211,
846                                        HOSTAPD_LEVEL_DEBUG,
847                                        "Invalid supported rates element length"
848                                        " %d+%d", elems.supp_rates_len,
849                                        elems.ext_supp_rates_len);
850                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
851                         goto fail;
852                 }
853
854                 os_memcpy(sta->supported_rates + elems.supp_rates_len,
855                           elems.ext_supp_rates, elems.ext_supp_rates_len);
856                 sta->supported_rates_len += elems.ext_supp_rates_len;
857         }
858
859 #ifdef CONFIG_IEEE80211N
860         /* save HT capabilities in the sta object */
861         os_memset(&sta->ht_capabilities, 0, sizeof(sta->ht_capabilities));
862         if (elems.ht_capabilities &&
863             elems.ht_capabilities_len >=
864             sizeof(struct ieee80211_ht_capabilities)) {
865                 sta->flags |= WLAN_STA_HT;
866                 sta->ht_capabilities.id = WLAN_EID_HT_CAP;
867                 sta->ht_capabilities.length =
868                         sizeof(struct ieee80211_ht_capabilities);
869                 os_memcpy(&sta->ht_capabilities.data,
870                           elems.ht_capabilities,
871                           sizeof(struct ieee80211_ht_capabilities));
872         } else
873                 sta->flags &= ~WLAN_STA_HT;
874 #endif /* CONFIG_IEEE80211N */
875
876         if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems.rsn_ie) {
877                 wpa_ie = elems.rsn_ie;
878                 wpa_ie_len = elems.rsn_ie_len;
879         } else if ((hapd->conf->wpa & WPA_PROTO_WPA) &&
880                    elems.wpa_ie) {
881                 wpa_ie = elems.wpa_ie;
882                 wpa_ie_len = elems.wpa_ie_len;
883         } else {
884                 wpa_ie = NULL;
885                 wpa_ie_len = 0;
886         }
887 #ifdef CONFIG_WPS
888         sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
889         if (hapd->conf->wps_state && wpa_ie == NULL) {
890                 if (elems.wps_ie) {
891                         wpa_printf(MSG_DEBUG, "STA included WPS IE in "
892                                    "(Re)Association Request - assume WPS is "
893                                    "used");
894                         sta->flags |= WLAN_STA_WPS;
895                         wpabuf_free(sta->wps_ie);
896                         sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4,
897                                                         elems.wps_ie_len - 4);
898                 } else {
899                         wpa_printf(MSG_DEBUG, "STA did not include WPA/RSN IE "
900                                    "in (Re)Association Request - possible WPS "
901                                    "use");
902                         sta->flags |= WLAN_STA_MAYBE_WPS;
903                 }
904         } else
905 #endif /* CONFIG_WPS */
906         if (hapd->conf->wpa && wpa_ie == NULL) {
907                 printf("STA " MACSTR ": No WPA/RSN IE in association "
908                        "request\n", MAC2STR(sta->addr));
909                 resp = WLAN_STATUS_INVALID_IE;
910                 goto fail;
911         }
912
913         if (hapd->conf->wpa && wpa_ie) {
914                 int res;
915                 wpa_ie -= 2;
916                 wpa_ie_len += 2;
917                 if (sta->wpa_sm == NULL)
918                         sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
919                                                         sta->addr);
920                 if (sta->wpa_sm == NULL) {
921                         printf("Failed to initialize WPA state machine\n");
922                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
923                         goto fail;
924                 }
925                 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
926                                           wpa_ie, wpa_ie_len,
927                                           elems.mdie, elems.mdie_len);
928                 if (res == WPA_INVALID_GROUP)
929                         resp = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
930                 else if (res == WPA_INVALID_PAIRWISE)
931                         resp = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
932                 else if (res == WPA_INVALID_AKMP)
933                         resp = WLAN_STATUS_AKMP_NOT_VALID;
934                 else if (res == WPA_ALLOC_FAIL)
935                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
936 #ifdef CONFIG_IEEE80211W
937                 else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION)
938                         resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
939                 else if (res == WPA_INVALID_MGMT_GROUP_CIPHER)
940                         resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
941 #endif /* CONFIG_IEEE80211W */
942                 else if (res == WPA_INVALID_MDIE)
943                         resp = WLAN_STATUS_INVALID_MDIE;
944                 else if (res != WPA_IE_OK)
945                         resp = WLAN_STATUS_INVALID_IE;
946                 if (resp != WLAN_STATUS_SUCCESS)
947                         goto fail;
948 #ifdef CONFIG_IEEE80211W
949                 if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
950                     sta->sa_query_count > 0)
951                         ap_check_sa_query_timeout(hapd, sta);
952                 if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
953                     (!reassoc || sta->auth_alg != WLAN_AUTH_FT)) {
954                         /*
955                          * STA has already been associated with MFP and SA
956                          * Query timeout has not been reached. Reject the
957                          * association attempt temporarily and start SA Query,
958                          * if one is not pending.
959                          */
960
961                         if (sta->sa_query_count == 0)
962                                 ap_sta_start_sa_query(hapd, sta);
963
964                         resp = WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
965                         goto fail;
966                 }
967
968                 if (wpa_auth_uses_mfp(sta->wpa_sm))
969                         sta->flags |= WLAN_STA_MFP;
970                 else
971                         sta->flags &= ~WLAN_STA_MFP;
972 #endif /* CONFIG_IEEE80211W */
973
974 #ifdef CONFIG_IEEE80211R
975                 if (sta->auth_alg == WLAN_AUTH_FT) {
976                         if (!reassoc) {
977                                 wpa_printf(MSG_DEBUG, "FT: " MACSTR " tried "
978                                            "to use association (not "
979                                            "re-association) with FT auth_alg",
980                                            MAC2STR(sta->addr));
981                                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
982                                 goto fail;
983                         }
984
985                         resp = wpa_ft_validate_reassoc(sta->wpa_sm, pos, left);
986                         if (resp != WLAN_STATUS_SUCCESS)
987                                 goto fail;
988                 }
989 #endif /* CONFIG_IEEE80211R */
990 #ifdef CONFIG_IEEE80211N
991                 if ((sta->flags & WLAN_STA_HT) &&
992                     wpa_auth_get_pairwise(sta->wpa_sm) == WPA_CIPHER_TKIP) {
993                         wpa_printf(MSG_DEBUG, "HT: " MACSTR " tried to "
994                                    "use TKIP with HT association",
995                                    MAC2STR(sta->addr));
996                         resp = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
997                         goto fail;
998                 }
999 #endif /* CONFIG_IEEE80211N */
1000         } else
1001                 wpa_auth_sta_no_wpa(sta->wpa_sm);
1002
1003         if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
1004                 sta->flags |= WLAN_STA_NONERP;
1005         for (i = 0; i < sta->supported_rates_len; i++) {
1006                 if ((sta->supported_rates[i] & 0x7f) > 22) {
1007                         sta->flags &= ~WLAN_STA_NONERP;
1008                         break;
1009                 }
1010         }
1011         if (sta->flags & WLAN_STA_NONERP && !sta->nonerp_set) {
1012                 sta->nonerp_set = 1;
1013                 hapd->iface->num_sta_non_erp++;
1014                 if (hapd->iface->num_sta_non_erp == 1)
1015                         ieee802_11_set_beacons(hapd->iface);
1016         }
1017
1018         if (!(sta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) &&
1019             !sta->no_short_slot_time_set) {
1020                 sta->no_short_slot_time_set = 1;
1021                 hapd->iface->num_sta_no_short_slot_time++;
1022                 if (hapd->iface->current_mode->mode ==
1023                     HOSTAPD_MODE_IEEE80211G &&
1024                     hapd->iface->num_sta_no_short_slot_time == 1)
1025                         ieee802_11_set_beacons(hapd->iface);
1026         }
1027
1028         if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1029                 sta->flags |= WLAN_STA_SHORT_PREAMBLE;
1030         else
1031                 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1032
1033         if (!(sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
1034             !sta->no_short_preamble_set) {
1035                 sta->no_short_preamble_set = 1;
1036                 hapd->iface->num_sta_no_short_preamble++;
1037                 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
1038                     && hapd->iface->num_sta_no_short_preamble == 1)
1039                         ieee802_11_set_beacons(hapd->iface);
1040         }
1041
1042 #ifdef CONFIG_IEEE80211N
1043         if (sta->flags & WLAN_STA_HT) {
1044                 u16 ht_capab = le_to_host16(
1045                         sta->ht_capabilities.data.ht_capabilities_info);
1046                 wpa_printf(MSG_DEBUG, "HT: STA " MACSTR " HT Capabilities "
1047                            "Info: 0x%04x", MAC2STR(sta->addr), ht_capab);
1048                 if ((ht_capab & HT_CAP_INFO_GREEN_FIELD) == 0) {
1049                         if (!sta->no_ht_gf_set) {
1050                                 sta->no_ht_gf_set = 1;
1051                                 hapd->iface->num_sta_ht_no_gf++;
1052                         }
1053                         wpa_printf(MSG_DEBUG, "%s STA " MACSTR " - no "
1054                                    "greenfield, num of non-gf stations %d",
1055                                    __func__, MAC2STR(sta->addr),
1056                                    hapd->iface->num_sta_ht_no_gf);
1057                 }
1058                 if ((ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) == 0) {
1059                         if (!sta->ht_20mhz_set) {
1060                                 sta->ht_20mhz_set = 1;
1061                                 hapd->iface->num_sta_ht_20mhz++;
1062                         }
1063                         wpa_printf(MSG_DEBUG, "%s STA " MACSTR " - 20 MHz HT, "
1064                                    "num of 20MHz HT STAs %d",
1065                                    __func__, MAC2STR(sta->addr),
1066                                    hapd->iface->num_sta_ht_20mhz);
1067                 }
1068         } else {
1069                 if (!sta->no_ht_set) {
1070                         sta->no_ht_set = 1;
1071                         hapd->iface->num_sta_no_ht++;
1072                 }
1073                 if (hapd->iconf->ieee80211n) {
1074                         wpa_printf(MSG_DEBUG, "%s STA " MACSTR
1075                                    " - no HT, num of non-HT stations %d",
1076                                    __func__, MAC2STR(sta->addr),
1077                                    hapd->iface->num_sta_no_ht);
1078                 }
1079         }
1080
1081         if (hostapd_ht_operation_update(hapd->iface) > 0)
1082                 ieee802_11_set_beacons(hapd->iface);
1083 #endif /* CONFIG_IEEE80211N */
1084
1085         if (hostapd_get_aid(hapd, sta) < 0) {
1086                 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1087                 wpa_printf(MSG_ERROR, "  no room for more AIDs");
1088                 goto fail;
1089         }
1090
1091         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1092                        HOSTAPD_LEVEL_DEBUG,
1093                        "association OK (aid %d)", sta->aid);
1094         /* Station will be marked associated, after it acknowledges AssocResp
1095          */
1096
1097 #ifdef CONFIG_IEEE80211W
1098         if ((sta->flags & WLAN_STA_MFP) && sta->sa_query_timed_out) {
1099                 wpa_printf(MSG_DEBUG, "Allowing %sassociation after timed out "
1100                            "SA Query procedure", reassoc ? "re" : "");
1101                 /* TODO: Send a protected Disassociate frame to the STA using
1102                  * the old key and Reason Code "Previous Authentication no
1103                  * longer valid". Make sure this is only sent protected since
1104                  * unprotected frame would be received by the STA that is now
1105                  * trying to associate.
1106                  */
1107         }
1108 #endif /* CONFIG_IEEE80211W */
1109
1110         if (reassoc) {
1111                 os_memcpy(sta->previous_ap, mgmt->u.reassoc_req.current_ap,
1112                           ETH_ALEN);
1113         }
1114
1115         if (sta->last_assoc_req)
1116                 os_free(sta->last_assoc_req);
1117         sta->last_assoc_req = os_malloc(len);
1118         if (sta->last_assoc_req)
1119                 os_memcpy(sta->last_assoc_req, mgmt, len);
1120
1121         /* Make sure that the previously registered inactivity timer will not
1122          * remove the STA immediately. */
1123         sta->timeout_next = STA_NULLFUNC;
1124
1125  fail:
1126         os_memset(buf, 0, sizeof(buf));
1127         reply = (struct ieee80211_mgmt *) buf;
1128         reply->frame_control =
1129                 IEEE80211_FC(WLAN_FC_TYPE_MGMT,
1130                              (send_deauth ? WLAN_FC_STYPE_DEAUTH :
1131                               (reassoc ? WLAN_FC_STYPE_REASSOC_RESP :
1132                                WLAN_FC_STYPE_ASSOC_RESP)));
1133         os_memcpy(reply->da, mgmt->sa, ETH_ALEN);
1134         os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
1135         os_memcpy(reply->bssid, mgmt->bssid, ETH_ALEN);
1136
1137         send_len = IEEE80211_HDRLEN;
1138         if (send_deauth) {
1139                 send_len += sizeof(reply->u.deauth);
1140                 reply->u.deauth.reason_code = host_to_le16(resp);
1141         } else {
1142                 u8 *p;
1143                 send_len += sizeof(reply->u.assoc_resp);
1144                 reply->u.assoc_resp.capab_info =
1145                         host_to_le16(hostapd_own_capab_info(hapd, sta, 0));
1146                 reply->u.assoc_resp.status_code = host_to_le16(resp);
1147                 reply->u.assoc_resp.aid = host_to_le16((sta ? sta->aid : 0)
1148                                                        | BIT(14) | BIT(15));
1149                 /* Supported rates */
1150                 p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable);
1151                 /* Extended supported rates */
1152                 p = hostapd_eid_ext_supp_rates(hapd, p);
1153                 if (sta->flags & WLAN_STA_WMM)
1154                         p = hostapd_eid_wmm(hapd, p);
1155
1156                 p = hostapd_eid_ht_capabilities(hapd, p);
1157                 p = hostapd_eid_ht_operation(hapd, p);
1158
1159 #ifdef CONFIG_IEEE80211R
1160                 if (resp == WLAN_STATUS_SUCCESS) {
1161                         /* IEEE 802.11r: Mobility Domain Information, Fast BSS
1162                          * Transition Information, RSN, [RIC Response] */
1163                         p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, p,
1164                                                         buf + sizeof(buf) - p,
1165                                                         sta->auth_alg,
1166                                                         pos, left);
1167                 }
1168 #endif /* CONFIG_IEEE80211R */
1169
1170 #ifdef CONFIG_IEEE80211W
1171                 if (resp == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY)
1172                         p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
1173 #endif /* CONFIG_IEEE80211W */
1174
1175                 send_len += p - reply->u.assoc_resp.variable;
1176         }
1177
1178         if (hostapd_send_mgmt_frame(hapd, reply, send_len) < 0)
1179                 perror("handle_assoc: send");
1180 }
1181
1182
1183 static void handle_disassoc(struct hostapd_data *hapd,
1184                             struct ieee80211_mgmt *mgmt, size_t len)
1185 {
1186         struct sta_info *sta;
1187
1188         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) {
1189                 printf("handle_disassoc - too short payload (len=%lu)\n",
1190                        (unsigned long) len);
1191                 return;
1192         }
1193
1194         wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d",
1195                    MAC2STR(mgmt->sa),
1196                    le_to_host16(mgmt->u.disassoc.reason_code));
1197
1198         sta = ap_get_sta(hapd, mgmt->sa);
1199         if (sta == NULL) {
1200                 printf("Station " MACSTR " trying to disassociate, but it "
1201                        "is not associated.\n", MAC2STR(mgmt->sa));
1202                 return;
1203         }
1204
1205         sta->flags &= ~WLAN_STA_ASSOC;
1206         wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
1207                 MAC2STR(sta->addr));
1208         wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
1209         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1210                        HOSTAPD_LEVEL_INFO, "disassociated");
1211         sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
1212         ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
1213         /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
1214          * authenticated. */
1215         accounting_sta_stop(hapd, sta);
1216         ieee802_1x_free_station(sta);
1217         hostapd_sta_remove(hapd, sta->addr);
1218
1219         if (sta->timeout_next == STA_NULLFUNC ||
1220             sta->timeout_next == STA_DISASSOC) {
1221                 sta->timeout_next = STA_DEAUTH;
1222                 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
1223                 eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
1224                                        hapd, sta);
1225         }
1226
1227         mlme_disassociate_indication(
1228                 hapd, sta, le_to_host16(mgmt->u.disassoc.reason_code));
1229 }
1230
1231
1232 static void handle_deauth(struct hostapd_data *hapd,
1233                           struct ieee80211_mgmt *mgmt, size_t len)
1234 {
1235         struct sta_info *sta;
1236
1237         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.deauth)) {
1238                 printf("handle_deauth - too short payload (len=%lu)\n",
1239                        (unsigned long) len);
1240                 return;
1241         }
1242
1243         wpa_printf(MSG_DEBUG, "deauthentication: STA=" MACSTR
1244                    " reason_code=%d",
1245                    MAC2STR(mgmt->sa),
1246                    le_to_host16(mgmt->u.deauth.reason_code));
1247
1248         sta = ap_get_sta(hapd, mgmt->sa);
1249         if (sta == NULL) {
1250                 printf("Station " MACSTR " trying to deauthenticate, but it "
1251                        "is not authenticated.\n", MAC2STR(mgmt->sa));
1252                 return;
1253         }
1254
1255         sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
1256         wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
1257                 MAC2STR(sta->addr));
1258         wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
1259         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1260                        HOSTAPD_LEVEL_DEBUG, "deauthenticated");
1261         mlme_deauthenticate_indication(
1262                 hapd, sta, le_to_host16(mgmt->u.deauth.reason_code));
1263         sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
1264         ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
1265         ap_free_sta(hapd, sta);
1266 }
1267
1268
1269 static void handle_beacon(struct hostapd_data *hapd,
1270                           struct ieee80211_mgmt *mgmt, size_t len,
1271                           struct hostapd_frame_info *fi)
1272 {
1273         struct ieee802_11_elems elems;
1274
1275         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.beacon)) {
1276                 printf("handle_beacon - too short payload (len=%lu)\n",
1277                        (unsigned long) len);
1278                 return;
1279         }
1280
1281         (void) ieee802_11_parse_elems(mgmt->u.beacon.variable,
1282                                       len - (IEEE80211_HDRLEN +
1283                                              sizeof(mgmt->u.beacon)), &elems,
1284                                       0);
1285
1286         ap_list_process_beacon(hapd->iface, mgmt, &elems, fi);
1287 }
1288
1289
1290 #ifdef CONFIG_IEEE80211W
1291
1292 /* MLME-SAQuery.request */
1293 void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
1294                                   const u8 *addr, const u8 *trans_id)
1295 {
1296         struct ieee80211_mgmt mgmt;
1297         u8 *end;
1298
1299         wpa_printf(MSG_DEBUG, "IEEE 802.11: Sending SA Query Request to "
1300                    MACSTR, MAC2STR(addr));
1301         wpa_hexdump(MSG_DEBUG, "IEEE 802.11: SA Query Transaction ID",
1302                     trans_id, WLAN_SA_QUERY_TR_ID_LEN);
1303
1304         os_memset(&mgmt, 0, sizeof(mgmt));
1305         mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
1306                                           WLAN_FC_STYPE_ACTION);
1307         os_memcpy(mgmt.da, addr, ETH_ALEN);
1308         os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
1309         os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
1310         mgmt.u.action.category = WLAN_ACTION_SA_QUERY;
1311         mgmt.u.action.u.sa_query_req.action = WLAN_SA_QUERY_REQUEST;
1312         os_memcpy(mgmt.u.action.u.sa_query_req.trans_id, trans_id,
1313                   WLAN_SA_QUERY_TR_ID_LEN);
1314         end = mgmt.u.action.u.sa_query_req.trans_id + WLAN_SA_QUERY_TR_ID_LEN;
1315         if (hostapd_send_mgmt_frame(hapd, &mgmt, end - (u8 *) &mgmt) < 0)
1316                 perror("ieee802_11_send_sa_query_req: send");
1317 }
1318
1319
1320 static void hostapd_sa_query_action(struct hostapd_data *hapd,
1321                                     struct ieee80211_mgmt *mgmt, size_t len)
1322 {
1323         struct sta_info *sta;
1324         u8 *end;
1325         int i;
1326
1327         end = mgmt->u.action.u.sa_query_resp.trans_id +
1328                 WLAN_SA_QUERY_TR_ID_LEN;
1329         if (((u8 *) mgmt) + len < end) {
1330                 wpa_printf(MSG_DEBUG, "IEEE 802.11: Too short SA Query Action "
1331                            "frame (len=%lu)", (unsigned long) len);
1332                 return;
1333         }
1334
1335         if (mgmt->u.action.u.sa_query_resp.action != WLAN_SA_QUERY_RESPONSE) {
1336                 wpa_printf(MSG_DEBUG, "IEEE 802.11: Unexpected SA Query "
1337                            "Action %d", mgmt->u.action.u.sa_query_resp.action);
1338                 return;
1339         }
1340
1341         wpa_printf(MSG_DEBUG, "IEEE 802.11: Received SA Query Response from "
1342                    MACSTR, MAC2STR(mgmt->sa));
1343         wpa_hexdump(MSG_DEBUG, "IEEE 802.11: SA Query Transaction ID",
1344                     mgmt->u.action.u.sa_query_resp.trans_id,
1345                     WLAN_SA_QUERY_TR_ID_LEN);
1346
1347         /* MLME-SAQuery.confirm */
1348
1349         sta = ap_get_sta(hapd, mgmt->sa);
1350         if (sta == NULL || sta->sa_query_trans_id == NULL) {
1351                 wpa_printf(MSG_DEBUG, "IEEE 802.11: No matching STA with "
1352                            "pending SA Query request found");
1353                 return;
1354         }
1355
1356         for (i = 0; i < sta->sa_query_count; i++) {
1357                 if (os_memcmp(sta->sa_query_trans_id +
1358                               i * WLAN_SA_QUERY_TR_ID_LEN,
1359                               mgmt->u.action.u.sa_query_resp.trans_id,
1360                               WLAN_SA_QUERY_TR_ID_LEN) == 0)
1361                         break;
1362         }
1363
1364         if (i >= sta->sa_query_count) {
1365                 wpa_printf(MSG_DEBUG, "IEEE 802.11: No matching SA Query "
1366                            "transaction identifier found");
1367                 return;
1368         }
1369
1370         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1371                        HOSTAPD_LEVEL_DEBUG,
1372                        "Reply to pending SA Query received");
1373         ap_sta_stop_sa_query(hapd, sta);
1374 }
1375
1376
1377 static int robust_action_frame(u8 category)
1378 {
1379         return category != WLAN_ACTION_PUBLIC &&
1380                 category != WLAN_ACTION_HT;
1381 }
1382 #endif /* CONFIG_IEEE80211W */
1383
1384
1385 static void handle_action(struct hostapd_data *hapd,
1386                           struct ieee80211_mgmt *mgmt, size_t len)
1387 {
1388         struct sta_info *sta;
1389
1390         if (len < IEEE80211_HDRLEN + 1) {
1391                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1392                                HOSTAPD_LEVEL_DEBUG,
1393                                "handle_action - too short payload (len=%lu)",
1394                                (unsigned long) len);
1395                 return;
1396         }
1397
1398         sta = ap_get_sta(hapd, mgmt->sa);
1399 #ifdef CONFIG_IEEE80211W
1400         if (sta && (sta->flags & WLAN_STA_MFP) &&
1401             !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP) &&
1402               robust_action_frame(mgmt->u.action.category))) {
1403                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1404                                HOSTAPD_LEVEL_DEBUG,
1405                                "Dropped unprotected Robust Action frame from "
1406                                "an MFP STA");
1407                 return;
1408         }
1409 #endif /* CONFIG_IEEE80211W */
1410
1411         switch (mgmt->u.action.category) {
1412 #ifdef CONFIG_IEEE80211R
1413         case WLAN_ACTION_FT:
1414         {
1415                 if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
1416                         wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored FT Action "
1417                                    "frame from unassociated STA " MACSTR,
1418                                    MAC2STR(mgmt->sa));
1419                         return;
1420                 }
1421
1422                 if (wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action,
1423                                      len - IEEE80211_HDRLEN))
1424                         break;
1425
1426                 return;
1427         }
1428 #endif /* CONFIG_IEEE80211R */
1429         case WLAN_ACTION_WMM:
1430                 hostapd_wmm_action(hapd, mgmt, len);
1431                 return;
1432 #ifdef CONFIG_IEEE80211W
1433         case WLAN_ACTION_SA_QUERY:
1434                 hostapd_sa_query_action(hapd, mgmt, len);
1435                 return;
1436 #endif /* CONFIG_IEEE80211W */
1437         }
1438
1439         hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1440                        HOSTAPD_LEVEL_DEBUG,
1441                        "handle_action - unknown action category %d or invalid "
1442                        "frame",
1443                        mgmt->u.action.category);
1444         if (!(mgmt->da[0] & 0x01) && !(mgmt->u.action.category & 0x80) &&
1445             !(mgmt->sa[0] & 0x01)) {
1446                 /*
1447                  * IEEE 802.11-REVma/D9.0 - 7.3.1.11
1448                  * Return the Action frame to the source without change
1449                  * except that MSB of the Category set to 1.
1450                  */
1451                 wpa_printf(MSG_DEBUG, "IEEE 802.11: Return unknown Action "
1452                            "frame back to sender");
1453                 os_memcpy(mgmt->da, mgmt->sa, ETH_ALEN);
1454                 os_memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN);
1455                 os_memcpy(mgmt->bssid, hapd->own_addr, ETH_ALEN);
1456                 mgmt->u.action.category |= 0x80;
1457
1458                 hostapd_send_mgmt_frame(hapd, mgmt, len);
1459         }
1460 }
1461
1462
1463 /**
1464  * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
1465  * @hapd: hostapd BSS data structure (the BSS to which the management frame was
1466  * sent to)
1467  * @buf: management frame data (starting from IEEE 802.11 header)
1468  * @len: length of frame data in octets
1469  * @stype: management frame subtype from frame control field
1470  * @fi: meta data about received frame (signal level, etc.)
1471  *
1472  * Process all incoming IEEE 802.11 management frames. This will be called for
1473  * each frame received from the kernel driver through wlan#ap interface. In
1474  * addition, it can be called to re-inserted pending frames (e.g., when using
1475  * external RADIUS server as an MAC ACL).
1476  */
1477 void ieee802_11_mgmt(struct hostapd_data *hapd, u8 *buf, size_t len, u16 stype,
1478                      struct hostapd_frame_info *fi)
1479 {
1480         struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) buf;
1481         int broadcast;
1482
1483         if (stype == WLAN_FC_STYPE_BEACON) {
1484                 handle_beacon(hapd, mgmt, len, fi);
1485                 return;
1486         }
1487
1488         broadcast = mgmt->bssid[0] == 0xff && mgmt->bssid[1] == 0xff &&
1489                 mgmt->bssid[2] == 0xff && mgmt->bssid[3] == 0xff &&
1490                 mgmt->bssid[4] == 0xff && mgmt->bssid[5] == 0xff;
1491
1492         if (!broadcast &&
1493             os_memcmp(mgmt->bssid, hapd->own_addr, ETH_ALEN) != 0) {
1494                 printf("MGMT: BSSID=" MACSTR " not our address\n",
1495                        MAC2STR(mgmt->bssid));
1496                 return;
1497         }
1498
1499
1500         if (stype == WLAN_FC_STYPE_PROBE_REQ) {
1501                 handle_probe_req(hapd, mgmt, len);
1502                 return;
1503         }
1504
1505         if (os_memcmp(mgmt->da, hapd->own_addr, ETH_ALEN) != 0) {
1506                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1507                                HOSTAPD_LEVEL_DEBUG,
1508                                "MGMT: DA=" MACSTR " not our address",
1509                                MAC2STR(mgmt->da));
1510                 return;
1511         }
1512
1513         switch (stype) {
1514         case WLAN_FC_STYPE_AUTH:
1515                 wpa_printf(MSG_DEBUG, "mgmt::auth");
1516                 handle_auth(hapd, mgmt, len);
1517                 break;
1518         case WLAN_FC_STYPE_ASSOC_REQ:
1519                 wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
1520                 handle_assoc(hapd, mgmt, len, 0);
1521                 break;
1522         case WLAN_FC_STYPE_REASSOC_REQ:
1523                 wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
1524                 handle_assoc(hapd, mgmt, len, 1);
1525                 break;
1526         case WLAN_FC_STYPE_DISASSOC:
1527                 wpa_printf(MSG_DEBUG, "mgmt::disassoc");
1528                 handle_disassoc(hapd, mgmt, len);
1529                 break;
1530         case WLAN_FC_STYPE_DEAUTH:
1531                 wpa_printf(MSG_DEBUG, "mgmt::deauth");
1532                 handle_deauth(hapd, mgmt, len);
1533                 break;
1534         case WLAN_FC_STYPE_ACTION:
1535                 wpa_printf(MSG_DEBUG, "mgmt::action");
1536                 handle_action(hapd, mgmt, len);
1537                 break;
1538         default:
1539                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1540                                HOSTAPD_LEVEL_DEBUG,
1541                                "unknown mgmt frame subtype %d", stype);
1542                 break;
1543         }
1544 }
1545
1546
1547 static void handle_auth_cb(struct hostapd_data *hapd,
1548                            struct ieee80211_mgmt *mgmt,
1549                            size_t len, int ok)
1550 {
1551         u16 auth_alg, auth_transaction, status_code;
1552         struct sta_info *sta;
1553
1554         if (!ok) {
1555                 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
1556                                HOSTAPD_LEVEL_NOTICE,
1557                                "did not acknowledge authentication response");
1558                 return;
1559         }
1560
1561         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
1562                 printf("handle_auth_cb - too short payload (len=%lu)\n",
1563                        (unsigned long) len);
1564                 return;
1565         }
1566
1567         auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
1568         auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
1569         status_code = le_to_host16(mgmt->u.auth.status_code);
1570
1571         sta = ap_get_sta(hapd, mgmt->da);
1572         if (!sta) {
1573                 printf("handle_auth_cb: STA " MACSTR " not found\n",
1574                        MAC2STR(mgmt->da));
1575                 return;
1576         }
1577
1578         if (status_code == WLAN_STATUS_SUCCESS &&
1579             ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
1580              (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
1581                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1582                                HOSTAPD_LEVEL_INFO, "authenticated");
1583                 sta->flags |= WLAN_STA_AUTH;
1584         }
1585 }
1586
1587
1588 #ifdef CONFIG_IEEE80211N
1589 static void
1590 hostapd_get_ht_capab(struct hostapd_data *hapd,
1591                      struct ht_cap_ie *ht_cap_ie,
1592                      struct ht_cap_ie *neg_ht_cap_ie)
1593 {
1594         u16 cap;
1595
1596         os_memcpy(neg_ht_cap_ie, ht_cap_ie, sizeof(struct ht_cap_ie));
1597         cap = le_to_host16(neg_ht_cap_ie->data.ht_capabilities_info);
1598         cap &= hapd->iconf->ht_capab;
1599         cap |= (hapd->iconf->ht_capab & HT_CAP_INFO_SMPS_DISABLED);
1600
1601         /* FIXME: Rx STBC needs to be handled specially */
1602         cap |= (hapd->iconf->ht_capab & HT_CAP_INFO_RX_STBC_MASK);
1603         neg_ht_cap_ie->data.ht_capabilities_info = host_to_le16(cap);
1604 }
1605 #endif /* CONFIG_IEEE80211N */
1606
1607
1608 static void handle_assoc_cb(struct hostapd_data *hapd,
1609                             struct ieee80211_mgmt *mgmt,
1610                             size_t len, int reassoc, int ok)
1611 {
1612         u16 status;
1613         struct sta_info *sta;
1614         int new_assoc = 1;
1615 #ifdef CONFIG_IEEE80211N
1616         struct ht_cap_ie ht_cap;
1617 #endif /* CONFIG_IEEE80211N */
1618         struct ht_cap_ie *ht_cap_ptr = NULL;
1619         int set_flags, flags_and, flags_or;
1620
1621         if (!ok) {
1622                 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
1623                                HOSTAPD_LEVEL_DEBUG,
1624                                "did not acknowledge association response");
1625                 return;
1626         }
1627
1628         if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) :
1629                                       sizeof(mgmt->u.assoc_resp))) {
1630                 printf("handle_assoc_cb(reassoc=%d) - too short payload "
1631                        "(len=%lu)\n", reassoc, (unsigned long) len);
1632                 return;
1633         }
1634
1635         if (reassoc)
1636                 status = le_to_host16(mgmt->u.reassoc_resp.status_code);
1637         else
1638                 status = le_to_host16(mgmt->u.assoc_resp.status_code);
1639
1640         sta = ap_get_sta(hapd, mgmt->da);
1641         if (!sta) {
1642                 printf("handle_assoc_cb: STA " MACSTR " not found\n",
1643                        MAC2STR(mgmt->da));
1644                 return;
1645         }
1646
1647         if (status != WLAN_STATUS_SUCCESS)
1648                 goto fail;
1649
1650         /* Stop previous accounting session, if one is started, and allocate
1651          * new session id for the new session. */
1652         accounting_sta_stop(hapd, sta);
1653
1654         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1655                        HOSTAPD_LEVEL_INFO,
1656                        "associated (aid %d)",
1657                        sta->aid);
1658
1659         if (sta->flags & WLAN_STA_ASSOC)
1660                 new_assoc = 0;
1661         sta->flags |= WLAN_STA_ASSOC;
1662         if (!hapd->conf->ieee802_1x && !hapd->conf->wpa) {
1663                 /* Open or static WEP; no separate authorization */
1664                 sta->flags |= WLAN_STA_AUTHORIZED;
1665                 wpa_msg(hapd->msg_ctx, MSG_INFO,
1666                         AP_STA_CONNECTED MACSTR, MAC2STR(sta->addr));
1667         }
1668
1669         if (reassoc)
1670                 mlme_reassociate_indication(hapd, sta);
1671         else
1672                 mlme_associate_indication(hapd, sta);
1673
1674 #ifdef CONFIG_IEEE80211N
1675         if (sta->flags & WLAN_STA_HT) {
1676                 ht_cap_ptr = &ht_cap;
1677                 hostapd_get_ht_capab(hapd, &sta->ht_capabilities, ht_cap_ptr);
1678         }
1679 #endif /* CONFIG_IEEE80211N */
1680
1681 #ifdef CONFIG_IEEE80211W
1682         sta->sa_query_timed_out = 0;
1683 #endif /* CONFIG_IEEE80211W */
1684
1685         /*
1686          * Remove the STA entry in order to make sure the STA PS state gets
1687          * cleared and configuration gets updated in case of reassociation back
1688          * to the same AP.
1689          */
1690         hostapd_sta_remove(hapd, sta->addr);
1691
1692         if (hostapd_sta_add(hapd->conf->iface, hapd, sta->addr, sta->aid,
1693                             sta->capability, sta->supported_rates,
1694                             sta->supported_rates_len, 0, sta->listen_interval,
1695                             ht_cap_ptr))
1696         {
1697                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1698                                HOSTAPD_LEVEL_NOTICE,
1699                                "Could not add STA to kernel driver");
1700         }
1701
1702         if (sta->eapol_sm == NULL) {
1703                 /*
1704                  * This STA does not use RADIUS server for EAP authentication,
1705                  * so bind it to the selected VLAN interface now, since the
1706                  * interface selection is not going to change anymore.
1707                  */
1708                 ap_sta_bind_vlan(hapd, sta, 0);
1709         } else if (sta->vlan_id) {
1710                 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
1711                 ap_sta_bind_vlan(hapd, sta, 0);
1712         }
1713
1714         set_flags = WLAN_STA_SHORT_PREAMBLE | WLAN_STA_WMM | WLAN_STA_MFP;
1715         if (!hapd->conf->ieee802_1x && !hapd->conf->wpa &&
1716             sta->flags & WLAN_STA_AUTHORIZED)
1717                 set_flags |= WLAN_STA_AUTHORIZED;
1718         flags_or = sta->flags & set_flags;
1719         flags_and = sta->flags | ~set_flags;
1720         hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
1721                               flags_or, flags_and);
1722
1723         if (sta->auth_alg == WLAN_AUTH_FT)
1724                 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
1725         else
1726                 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
1727         hostapd_new_assoc_sta(hapd, sta, !new_assoc);
1728
1729         ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
1730
1731  fail:
1732         /* Copy of the association request is not needed anymore */
1733         if (sta->last_assoc_req) {
1734                 os_free(sta->last_assoc_req);
1735                 sta->last_assoc_req = NULL;
1736         }
1737 }
1738
1739
1740 /**
1741  * ieee802_11_mgmt_cb - Process management frame TX status callback
1742  * @hapd: hostapd BSS data structure (the BSS from which the management frame
1743  * was sent from)
1744  * @buf: management frame data (starting from IEEE 802.11 header)
1745  * @len: length of frame data in octets
1746  * @stype: management frame subtype from frame control field
1747  * @ok: Whether the frame was ACK'ed
1748  */
1749 void ieee802_11_mgmt_cb(struct hostapd_data *hapd, u8 *buf, size_t len,
1750                         u16 stype, int ok)
1751 {
1752         struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) buf;
1753
1754         switch (stype) {
1755         case WLAN_FC_STYPE_AUTH:
1756                 wpa_printf(MSG_DEBUG, "mgmt::auth cb");
1757                 handle_auth_cb(hapd, mgmt, len, ok);
1758                 break;
1759         case WLAN_FC_STYPE_ASSOC_RESP:
1760                 wpa_printf(MSG_DEBUG, "mgmt::assoc_resp cb");
1761                 handle_assoc_cb(hapd, mgmt, len, 0, ok);
1762                 break;
1763         case WLAN_FC_STYPE_REASSOC_RESP:
1764                 wpa_printf(MSG_DEBUG, "mgmt::reassoc_resp cb");
1765                 handle_assoc_cb(hapd, mgmt, len, 1, ok);
1766                 break;
1767         case WLAN_FC_STYPE_PROBE_RESP:
1768                 wpa_printf(MSG_DEBUG, "mgmt::proberesp cb");
1769                 break;
1770         case WLAN_FC_STYPE_DEAUTH:
1771                 /* ignore */
1772                 break;
1773         case WLAN_FC_STYPE_ACTION:
1774                 wpa_printf(MSG_DEBUG, "mgmt::action cb");
1775                 break;
1776         default:
1777                 printf("unknown mgmt cb frame subtype %d\n", stype);
1778                 break;
1779         }
1780 }
1781
1782
1783 int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
1784 {
1785         /* TODO */
1786         return 0;
1787 }
1788
1789
1790 int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
1791                            char *buf, size_t buflen)
1792 {
1793         /* TODO */
1794         return 0;
1795 }
1796
1797 #endif /* CONFIG_NATIVE_WINDOWS */