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