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