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