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