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