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