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