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