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