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