AP: Update logging related to inactivity and disassociation
[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                         time_t 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                         now = time(NULL);
254                         r = random();
255                         os_memcpy(key, &now, 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);
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                 wpa_ie = NULL;
713                 wpa_ie_len = 0;
714                 if (sta->wps_ie && wps_validate_assoc_req(sta->wps_ie) < 0) {
715                         wpa_printf(MSG_DEBUG, "WPS: Invalid WPS IE in "
716                                    "(Re)Association Request - reject");
717                         return WLAN_STATUS_INVALID_IE;
718                 }
719         } else if (hapd->conf->wps_state && wpa_ie == NULL) {
720                 wpa_printf(MSG_DEBUG, "STA did not include WPA/RSN IE in "
721                            "(Re)Association Request - possible WPS use");
722                 sta->flags |= WLAN_STA_MAYBE_WPS;
723         } else
724 #endif /* CONFIG_WPS */
725         if (hapd->conf->wpa && wpa_ie == NULL) {
726                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
727                                HOSTAPD_LEVEL_INFO,
728                                "No WPA/RSN IE in association request");
729                 return WLAN_STATUS_INVALID_IE;
730         }
731
732         if (hapd->conf->wpa && wpa_ie) {
733                 int res;
734                 wpa_ie -= 2;
735                 wpa_ie_len += 2;
736                 if (sta->wpa_sm == NULL)
737                         sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
738                                                         sta->addr);
739                 if (sta->wpa_sm == NULL) {
740                         wpa_printf(MSG_WARNING, "Failed to initialize WPA "
741                                    "state machine");
742                         return WLAN_STATUS_UNSPECIFIED_FAILURE;
743                 }
744                 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
745                                           wpa_ie, wpa_ie_len,
746                                           elems.mdie, elems.mdie_len);
747                 if (res == WPA_INVALID_GROUP)
748                         resp = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
749                 else if (res == WPA_INVALID_PAIRWISE)
750                         resp = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
751                 else if (res == WPA_INVALID_AKMP)
752                         resp = WLAN_STATUS_AKMP_NOT_VALID;
753                 else if (res == WPA_ALLOC_FAIL)
754                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
755 #ifdef CONFIG_IEEE80211W
756                 else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION)
757                         resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
758                 else if (res == WPA_INVALID_MGMT_GROUP_CIPHER)
759                         resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
760 #endif /* CONFIG_IEEE80211W */
761                 else if (res == WPA_INVALID_MDIE)
762                         resp = WLAN_STATUS_INVALID_MDIE;
763                 else if (res != WPA_IE_OK)
764                         resp = WLAN_STATUS_INVALID_IE;
765                 if (resp != WLAN_STATUS_SUCCESS)
766                         return resp;
767 #ifdef CONFIG_IEEE80211W
768                 if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
769                     sta->sa_query_count > 0)
770                         ap_check_sa_query_timeout(hapd, sta);
771                 if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
772                     (!reassoc || sta->auth_alg != WLAN_AUTH_FT)) {
773                         /*
774                          * STA has already been associated with MFP and SA
775                          * Query timeout has not been reached. Reject the
776                          * association attempt temporarily and start SA Query,
777                          * if one is not pending.
778                          */
779
780                         if (sta->sa_query_count == 0)
781                                 ap_sta_start_sa_query(hapd, sta);
782
783                         return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
784                 }
785
786                 if (wpa_auth_uses_mfp(sta->wpa_sm))
787                         sta->flags |= WLAN_STA_MFP;
788                 else
789                         sta->flags &= ~WLAN_STA_MFP;
790 #endif /* CONFIG_IEEE80211W */
791
792 #ifdef CONFIG_IEEE80211R
793                 if (sta->auth_alg == WLAN_AUTH_FT) {
794                         if (!reassoc) {
795                                 wpa_printf(MSG_DEBUG, "FT: " MACSTR " tried "
796                                            "to use association (not "
797                                            "re-association) with FT auth_alg",
798                                            MAC2STR(sta->addr));
799                                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
800                         }
801
802                         resp = wpa_ft_validate_reassoc(sta->wpa_sm, ies,
803                                                        ies_len);
804                         if (resp != WLAN_STATUS_SUCCESS)
805                                 return resp;
806                 }
807 #endif /* CONFIG_IEEE80211R */
808
809 #ifdef CONFIG_IEEE80211N
810                 if ((sta->flags & WLAN_STA_HT) &&
811                     wpa_auth_get_pairwise(sta->wpa_sm) == WPA_CIPHER_TKIP) {
812                         hostapd_logger(hapd, sta->addr,
813                                        HOSTAPD_MODULE_IEEE80211,
814                                        HOSTAPD_LEVEL_INFO,
815                                        "Station tried to use TKIP with HT "
816                                        "association");
817                         return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
818                 }
819 #endif /* CONFIG_IEEE80211N */
820         } else
821                 wpa_auth_sta_no_wpa(sta->wpa_sm);
822
823 #ifdef CONFIG_P2P
824         if (elems.p2p) {
825                 wpabuf_free(sta->p2p_ie);
826                 sta->p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
827                                                           P2P_IE_VENDOR_TYPE);
828
829         } else {
830                 wpabuf_free(sta->p2p_ie);
831                 sta->p2p_ie = NULL;
832         }
833
834         p2p_group_notif_assoc(hapd->p2p_group, sta->addr, ies, ies_len);
835 #endif /* CONFIG_P2P */
836
837         return WLAN_STATUS_SUCCESS;
838 }
839
840
841 static void send_deauth(struct hostapd_data *hapd, const u8 *addr,
842                         u16 reason_code)
843 {
844         int send_len;
845         struct ieee80211_mgmt reply;
846
847         os_memset(&reply, 0, sizeof(reply));
848         reply.frame_control =
849                 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH);
850         os_memcpy(reply.da, addr, ETH_ALEN);
851         os_memcpy(reply.sa, hapd->own_addr, ETH_ALEN);
852         os_memcpy(reply.bssid, hapd->own_addr, ETH_ALEN);
853
854         send_len = IEEE80211_HDRLEN + sizeof(reply.u.deauth);
855         reply.u.deauth.reason_code = host_to_le16(reason_code);
856
857         if (hostapd_drv_send_mlme(hapd, &reply, send_len) < 0)
858                 wpa_printf(MSG_INFO, "Failed to send deauth: %s",
859                            strerror(errno));
860 }
861
862
863 static void send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
864                             u16 status_code, int reassoc, const u8 *ies,
865                             size_t ies_len)
866 {
867         int send_len;
868         u8 buf[sizeof(struct ieee80211_mgmt) + 1024];
869         struct ieee80211_mgmt *reply;
870         u8 *p;
871
872         os_memset(buf, 0, sizeof(buf));
873         reply = (struct ieee80211_mgmt *) buf;
874         reply->frame_control =
875                 IEEE80211_FC(WLAN_FC_TYPE_MGMT,
876                              (reassoc ? WLAN_FC_STYPE_REASSOC_RESP :
877                               WLAN_FC_STYPE_ASSOC_RESP));
878         os_memcpy(reply->da, sta->addr, ETH_ALEN);
879         os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
880         os_memcpy(reply->bssid, hapd->own_addr, ETH_ALEN);
881
882         send_len = IEEE80211_HDRLEN;
883         send_len += sizeof(reply->u.assoc_resp);
884         reply->u.assoc_resp.capab_info =
885                 host_to_le16(hostapd_own_capab_info(hapd, sta, 0));
886         reply->u.assoc_resp.status_code = host_to_le16(status_code);
887         reply->u.assoc_resp.aid = host_to_le16((sta ? sta->aid : 0)
888                                                | BIT(14) | BIT(15));
889         /* Supported rates */
890         p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable);
891         /* Extended supported rates */
892         p = hostapd_eid_ext_supp_rates(hapd, p);
893
894 #ifdef CONFIG_IEEE80211R
895         if (status_code == WLAN_STATUS_SUCCESS) {
896                 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
897                  * Transition Information, RSN, [RIC Response] */
898                 p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, p,
899                                                 buf + sizeof(buf) - p,
900                                                 sta->auth_alg, ies, ies_len);
901         }
902 #endif /* CONFIG_IEEE80211R */
903
904 #ifdef CONFIG_IEEE80211W
905         if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY)
906                 p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
907 #endif /* CONFIG_IEEE80211W */
908
909 #ifdef CONFIG_IEEE80211N
910         p = hostapd_eid_ht_capabilities(hapd, p);
911         p = hostapd_eid_ht_operation(hapd, p);
912 #endif /* CONFIG_IEEE80211N */
913
914         p = hostapd_eid_ext_capab(hapd, p);
915
916         if (sta->flags & WLAN_STA_WMM)
917                 p = hostapd_eid_wmm(hapd, p);
918
919 #ifdef CONFIG_WPS
920         if (sta->flags & WLAN_STA_WPS) {
921                 struct wpabuf *wps = wps_build_assoc_resp_ie();
922                 if (wps) {
923                         os_memcpy(p, wpabuf_head(wps), wpabuf_len(wps));
924                         p += wpabuf_len(wps);
925                         wpabuf_free(wps);
926                 }
927         }
928 #endif /* CONFIG_WPS */
929
930 #ifdef CONFIG_P2P
931         if (sta->p2p_ie) {
932                 struct wpabuf *p2p_resp_ie;
933                 enum p2p_status_code status;
934                 switch (status_code) {
935                 case WLAN_STATUS_SUCCESS:
936                         status = P2P_SC_SUCCESS;
937                         break;
938                 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA:
939                         status = P2P_SC_FAIL_LIMIT_REACHED;
940                         break;
941                 default:
942                         status = P2P_SC_FAIL_INVALID_PARAMS;
943                         break;
944                 }
945                 p2p_resp_ie = p2p_group_assoc_resp_ie(hapd->p2p_group, status);
946                 if (p2p_resp_ie) {
947                         os_memcpy(p, wpabuf_head(p2p_resp_ie),
948                                   wpabuf_len(p2p_resp_ie));
949                         p += wpabuf_len(p2p_resp_ie);
950                         wpabuf_free(p2p_resp_ie);
951                 }
952         }
953 #endif /* CONFIG_P2P */
954
955 #ifdef CONFIG_P2P_MANAGER
956         if (hapd->conf->p2p & P2P_MANAGE)
957                 p = hostapd_eid_p2p_manage(hapd, p);
958 #endif /* CONFIG_P2P_MANAGER */
959
960         send_len += p - reply->u.assoc_resp.variable;
961
962         if (hostapd_drv_send_mlme(hapd, reply, send_len) < 0)
963                 wpa_printf(MSG_INFO, "Failed to send assoc resp: %s",
964                            strerror(errno));
965 }
966
967
968 static void handle_assoc(struct hostapd_data *hapd,
969                          const struct ieee80211_mgmt *mgmt, size_t len,
970                          int reassoc)
971 {
972         u16 capab_info, listen_interval;
973         u16 resp = WLAN_STATUS_SUCCESS;
974         const u8 *pos;
975         int left, i;
976         struct sta_info *sta;
977
978         if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
979                                       sizeof(mgmt->u.assoc_req))) {
980                 printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
981                        "\n", reassoc, (unsigned long) len);
982                 return;
983         }
984
985         if (reassoc) {
986                 capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info);
987                 listen_interval = le_to_host16(
988                         mgmt->u.reassoc_req.listen_interval);
989                 wpa_printf(MSG_DEBUG, "reassociation request: STA=" MACSTR
990                            " capab_info=0x%02x listen_interval=%d current_ap="
991                            MACSTR,
992                            MAC2STR(mgmt->sa), capab_info, listen_interval,
993                            MAC2STR(mgmt->u.reassoc_req.current_ap));
994                 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req));
995                 pos = mgmt->u.reassoc_req.variable;
996         } else {
997                 capab_info = le_to_host16(mgmt->u.assoc_req.capab_info);
998                 listen_interval = le_to_host16(
999                         mgmt->u.assoc_req.listen_interval);
1000                 wpa_printf(MSG_DEBUG, "association request: STA=" MACSTR
1001                            " capab_info=0x%02x listen_interval=%d",
1002                            MAC2STR(mgmt->sa), capab_info, listen_interval);
1003                 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req));
1004                 pos = mgmt->u.assoc_req.variable;
1005         }
1006
1007         sta = ap_get_sta(hapd, mgmt->sa);
1008 #ifdef CONFIG_IEEE80211R
1009         if (sta && sta->auth_alg == WLAN_AUTH_FT &&
1010             (sta->flags & WLAN_STA_AUTH) == 0) {
1011                 wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate "
1012                            "prior to authentication since it is using "
1013                            "over-the-DS FT", MAC2STR(mgmt->sa));
1014         } else
1015 #endif /* CONFIG_IEEE80211R */
1016         if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {
1017                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1018                                HOSTAPD_LEVEL_INFO, "Station tried to "
1019                                "associate before authentication "
1020                                "(aid=%d flags=0x%x)",
1021                                sta ? sta->aid : -1,
1022                                sta ? sta->flags : 0);
1023                 send_deauth(hapd, mgmt->sa,
1024                             WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
1025                 return;
1026         }
1027
1028         if (hapd->tkip_countermeasures) {
1029                 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
1030                 goto fail;
1031         }
1032
1033         if (listen_interval > hapd->conf->max_listen_interval) {
1034                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1035                                HOSTAPD_LEVEL_DEBUG,
1036                                "Too large Listen Interval (%d)",
1037                                listen_interval);
1038                 resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
1039                 goto fail;
1040         }
1041
1042         /* followed by SSID and Supported rates; and HT capabilities if 802.11n
1043          * is used */
1044         resp = check_assoc_ies(hapd, sta, pos, left, reassoc);
1045         if (resp != WLAN_STATUS_SUCCESS)
1046                 goto fail;
1047
1048         if (hostapd_get_aid(hapd, sta) < 0) {
1049                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1050                                HOSTAPD_LEVEL_INFO, "No room for more AIDs");
1051                 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1052                 goto fail;
1053         }
1054
1055         sta->capability = capab_info;
1056         sta->listen_interval = listen_interval;
1057
1058         if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
1059                 sta->flags |= WLAN_STA_NONERP;
1060         for (i = 0; i < sta->supported_rates_len; i++) {
1061                 if ((sta->supported_rates[i] & 0x7f) > 22) {
1062                         sta->flags &= ~WLAN_STA_NONERP;
1063                         break;
1064                 }
1065         }
1066         if (sta->flags & WLAN_STA_NONERP && !sta->nonerp_set) {
1067                 sta->nonerp_set = 1;
1068                 hapd->iface->num_sta_non_erp++;
1069                 if (hapd->iface->num_sta_non_erp == 1)
1070                         ieee802_11_set_beacons(hapd->iface);
1071         }
1072
1073         if (!(sta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) &&
1074             !sta->no_short_slot_time_set) {
1075                 sta->no_short_slot_time_set = 1;
1076                 hapd->iface->num_sta_no_short_slot_time++;
1077                 if (hapd->iface->current_mode->mode ==
1078                     HOSTAPD_MODE_IEEE80211G &&
1079                     hapd->iface->num_sta_no_short_slot_time == 1)
1080                         ieee802_11_set_beacons(hapd->iface);
1081         }
1082
1083         if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1084                 sta->flags |= WLAN_STA_SHORT_PREAMBLE;
1085         else
1086                 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1087
1088         if (!(sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
1089             !sta->no_short_preamble_set) {
1090                 sta->no_short_preamble_set = 1;
1091                 hapd->iface->num_sta_no_short_preamble++;
1092                 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
1093                     && hapd->iface->num_sta_no_short_preamble == 1)
1094                         ieee802_11_set_beacons(hapd->iface);
1095         }
1096
1097 #ifdef CONFIG_IEEE80211N
1098         update_ht_state(hapd, sta);
1099 #endif /* CONFIG_IEEE80211N */
1100
1101         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1102                        HOSTAPD_LEVEL_DEBUG,
1103                        "association OK (aid %d)", sta->aid);
1104         /* Station will be marked associated, after it acknowledges AssocResp
1105          */
1106
1107 #ifdef CONFIG_IEEE80211W
1108         if ((sta->flags & WLAN_STA_MFP) && sta->sa_query_timed_out) {
1109                 wpa_printf(MSG_DEBUG, "Allowing %sassociation after timed out "
1110                            "SA Query procedure", reassoc ? "re" : "");
1111                 /* TODO: Send a protected Disassociate frame to the STA using
1112                  * the old key and Reason Code "Previous Authentication no
1113                  * longer valid". Make sure this is only sent protected since
1114                  * unprotected frame would be received by the STA that is now
1115                  * trying to associate.
1116                  */
1117         }
1118 #endif /* CONFIG_IEEE80211W */
1119
1120         if (reassoc) {
1121                 os_memcpy(sta->previous_ap, mgmt->u.reassoc_req.current_ap,
1122                           ETH_ALEN);
1123         }
1124
1125         if (sta->last_assoc_req)
1126                 os_free(sta->last_assoc_req);
1127         sta->last_assoc_req = os_malloc(len);
1128         if (sta->last_assoc_req)
1129                 os_memcpy(sta->last_assoc_req, mgmt, len);
1130
1131         /* Make sure that the previously registered inactivity timer will not
1132          * remove the STA immediately. */
1133         sta->timeout_next = STA_NULLFUNC;
1134
1135  fail:
1136         send_assoc_resp(hapd, sta, resp, reassoc, pos, left);
1137 }
1138
1139
1140 static void handle_disassoc(struct hostapd_data *hapd,
1141                             const struct ieee80211_mgmt *mgmt, size_t len)
1142 {
1143         struct sta_info *sta;
1144
1145         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) {
1146                 printf("handle_disassoc - too short payload (len=%lu)\n",
1147                        (unsigned long) len);
1148                 return;
1149         }
1150
1151         wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d",
1152                    MAC2STR(mgmt->sa),
1153                    le_to_host16(mgmt->u.disassoc.reason_code));
1154
1155         sta = ap_get_sta(hapd, mgmt->sa);
1156         if (sta == NULL) {
1157                 printf("Station " MACSTR " trying to disassociate, but it "
1158                        "is not associated.\n", MAC2STR(mgmt->sa));
1159                 return;
1160         }
1161
1162         sta->flags &= ~WLAN_STA_ASSOC;
1163         wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
1164                 MAC2STR(sta->addr));
1165         wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
1166         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1167                        HOSTAPD_LEVEL_INFO, "disassociated");
1168         sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
1169         ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
1170         /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
1171          * authenticated. */
1172         accounting_sta_stop(hapd, sta);
1173         ieee802_1x_free_station(sta);
1174         hostapd_drv_sta_remove(hapd, sta->addr);
1175
1176         if (sta->timeout_next == STA_NULLFUNC ||
1177             sta->timeout_next == STA_DISASSOC) {
1178                 sta->timeout_next = STA_DEAUTH;
1179                 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
1180                 eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
1181                                        hapd, sta);
1182         }
1183
1184         mlme_disassociate_indication(
1185                 hapd, sta, le_to_host16(mgmt->u.disassoc.reason_code));
1186 }
1187
1188
1189 static void handle_deauth(struct hostapd_data *hapd,
1190                           const struct ieee80211_mgmt *mgmt, size_t len)
1191 {
1192         struct sta_info *sta;
1193
1194         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.deauth)) {
1195                 wpa_msg(hapd, MSG_DEBUG, "handle_deauth - too short payload "
1196                         "(len=%lu)", (unsigned long) len);
1197                 return;
1198         }
1199
1200         wpa_msg(hapd, MSG_DEBUG, "deauthentication: STA=" MACSTR
1201                 " reason_code=%d",
1202                 MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code));
1203
1204         sta = ap_get_sta(hapd, mgmt->sa);
1205         if (sta == NULL) {
1206                 wpa_msg(hapd, MSG_DEBUG, "Station " MACSTR " trying to "
1207                         "deauthenticate, but it is not authenticated",
1208                         MAC2STR(mgmt->sa));
1209                 return;
1210         }
1211
1212         sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
1213         wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
1214                 MAC2STR(sta->addr));
1215         wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
1216         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1217                        HOSTAPD_LEVEL_DEBUG, "deauthenticated");
1218         mlme_deauthenticate_indication(
1219                 hapd, sta, le_to_host16(mgmt->u.deauth.reason_code));
1220         sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
1221         ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
1222         ap_free_sta(hapd, sta);
1223 }
1224
1225
1226 static void handle_beacon(struct hostapd_data *hapd,
1227                           const struct ieee80211_mgmt *mgmt, size_t len,
1228                           struct hostapd_frame_info *fi)
1229 {
1230         struct ieee802_11_elems elems;
1231
1232         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.beacon)) {
1233                 printf("handle_beacon - too short payload (len=%lu)\n",
1234                        (unsigned long) len);
1235                 return;
1236         }
1237
1238         (void) ieee802_11_parse_elems(mgmt->u.beacon.variable,
1239                                       len - (IEEE80211_HDRLEN +
1240                                              sizeof(mgmt->u.beacon)), &elems,
1241                                       0);
1242
1243         ap_list_process_beacon(hapd->iface, mgmt, &elems, fi);
1244 }
1245
1246
1247 #ifdef CONFIG_IEEE80211W
1248
1249 /* MLME-SAQuery.request */
1250 void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
1251                                   const u8 *addr, const u8 *trans_id)
1252 {
1253         struct ieee80211_mgmt mgmt;
1254         u8 *end;
1255
1256         wpa_printf(MSG_DEBUG, "IEEE 802.11: Sending SA Query Request to "
1257                    MACSTR, MAC2STR(addr));
1258         wpa_hexdump(MSG_DEBUG, "IEEE 802.11: SA Query Transaction ID",
1259                     trans_id, WLAN_SA_QUERY_TR_ID_LEN);
1260
1261         os_memset(&mgmt, 0, sizeof(mgmt));
1262         mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
1263                                           WLAN_FC_STYPE_ACTION);
1264         os_memcpy(mgmt.da, addr, ETH_ALEN);
1265         os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
1266         os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
1267         mgmt.u.action.category = WLAN_ACTION_SA_QUERY;
1268         mgmt.u.action.u.sa_query_req.action = WLAN_SA_QUERY_REQUEST;
1269         os_memcpy(mgmt.u.action.u.sa_query_req.trans_id, trans_id,
1270                   WLAN_SA_QUERY_TR_ID_LEN);
1271         end = mgmt.u.action.u.sa_query_req.trans_id + WLAN_SA_QUERY_TR_ID_LEN;
1272         if (hostapd_drv_send_mlme(hapd, &mgmt, end - (u8 *) &mgmt) < 0)
1273                 perror("ieee802_11_send_sa_query_req: send");
1274 }
1275
1276
1277 static void hostapd_sa_query_request(struct hostapd_data *hapd,
1278                                      const struct ieee80211_mgmt *mgmt)
1279 {
1280         struct sta_info *sta;
1281         struct ieee80211_mgmt resp;
1282         u8 *end;
1283
1284         wpa_printf(MSG_DEBUG, "IEEE 802.11: Received SA Query Request from "
1285                    MACSTR, MAC2STR(mgmt->sa));
1286         wpa_hexdump(MSG_DEBUG, "IEEE 802.11: SA Query Transaction ID",
1287                     mgmt->u.action.u.sa_query_resp.trans_id,
1288                     WLAN_SA_QUERY_TR_ID_LEN);
1289
1290         sta = ap_get_sta(hapd, mgmt->sa);
1291         if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
1292                 wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignore SA Query Request "
1293                            "from unassociated STA " MACSTR, MAC2STR(mgmt->sa));
1294                 return;
1295         }
1296
1297         wpa_printf(MSG_DEBUG, "IEEE 802.11: Sending SA Query Response to "
1298                    MACSTR, MAC2STR(mgmt->sa));
1299
1300         os_memset(&resp, 0, sizeof(resp));
1301         resp.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
1302                                           WLAN_FC_STYPE_ACTION);
1303         os_memcpy(resp.da, mgmt->sa, ETH_ALEN);
1304         os_memcpy(resp.sa, hapd->own_addr, ETH_ALEN);
1305         os_memcpy(resp.bssid, hapd->own_addr, ETH_ALEN);
1306         resp.u.action.category = WLAN_ACTION_SA_QUERY;
1307         resp.u.action.u.sa_query_req.action = WLAN_SA_QUERY_RESPONSE;
1308         os_memcpy(resp.u.action.u.sa_query_req.trans_id,
1309                   mgmt->u.action.u.sa_query_req.trans_id,
1310                   WLAN_SA_QUERY_TR_ID_LEN);
1311         end = resp.u.action.u.sa_query_req.trans_id + WLAN_SA_QUERY_TR_ID_LEN;
1312         if (hostapd_drv_send_mlme(hapd, &resp, end - (u8 *) &resp) < 0)
1313                 perror("hostapd_sa_query_request: send");
1314 }
1315
1316
1317 static void hostapd_sa_query_action(struct hostapd_data *hapd,
1318                                     const struct ieee80211_mgmt *mgmt,
1319                                     size_t len)
1320 {
1321         struct sta_info *sta;
1322         const u8 *end;
1323         int i;
1324
1325         end = mgmt->u.action.u.sa_query_resp.trans_id +
1326                 WLAN_SA_QUERY_TR_ID_LEN;
1327         if (((u8 *) mgmt) + len < end) {
1328                 wpa_printf(MSG_DEBUG, "IEEE 802.11: Too short SA Query Action "
1329                            "frame (len=%lu)", (unsigned long) len);
1330                 return;
1331         }
1332
1333         if (mgmt->u.action.u.sa_query_resp.action == WLAN_SA_QUERY_REQUEST) {
1334                 hostapd_sa_query_request(hapd, mgmt);
1335                 return;
1336         }
1337
1338         if (mgmt->u.action.u.sa_query_resp.action != WLAN_SA_QUERY_RESPONSE) {
1339                 wpa_printf(MSG_DEBUG, "IEEE 802.11: Unexpected SA Query "
1340                            "Action %d", mgmt->u.action.u.sa_query_resp.action);
1341                 return;
1342         }
1343
1344         wpa_printf(MSG_DEBUG, "IEEE 802.11: Received SA Query Response from "
1345                    MACSTR, MAC2STR(mgmt->sa));
1346         wpa_hexdump(MSG_DEBUG, "IEEE 802.11: SA Query Transaction ID",
1347                     mgmt->u.action.u.sa_query_resp.trans_id,
1348                     WLAN_SA_QUERY_TR_ID_LEN);
1349
1350         /* MLME-SAQuery.confirm */
1351
1352         sta = ap_get_sta(hapd, mgmt->sa);
1353         if (sta == NULL || sta->sa_query_trans_id == NULL) {
1354                 wpa_printf(MSG_DEBUG, "IEEE 802.11: No matching STA with "
1355                            "pending SA Query request found");
1356                 return;
1357         }
1358
1359         for (i = 0; i < sta->sa_query_count; i++) {
1360                 if (os_memcmp(sta->sa_query_trans_id +
1361                               i * WLAN_SA_QUERY_TR_ID_LEN,
1362                               mgmt->u.action.u.sa_query_resp.trans_id,
1363                               WLAN_SA_QUERY_TR_ID_LEN) == 0)
1364                         break;
1365         }
1366
1367         if (i >= sta->sa_query_count) {
1368                 wpa_printf(MSG_DEBUG, "IEEE 802.11: No matching SA Query "
1369                            "transaction identifier found");
1370                 return;
1371         }
1372
1373         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1374                        HOSTAPD_LEVEL_DEBUG,
1375                        "Reply to pending SA Query received");
1376         ap_sta_stop_sa_query(hapd, sta);
1377 }
1378
1379
1380 static int robust_action_frame(u8 category)
1381 {
1382         return category != WLAN_ACTION_PUBLIC &&
1383                 category != WLAN_ACTION_HT;
1384 }
1385 #endif /* CONFIG_IEEE80211W */
1386
1387
1388 static void handle_action(struct hostapd_data *hapd,
1389                           const struct ieee80211_mgmt *mgmt, size_t len)
1390 {
1391         struct sta_info *sta;
1392
1393         if (len < IEEE80211_HDRLEN + 1) {
1394                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1395                                HOSTAPD_LEVEL_DEBUG,
1396                                "handle_action - too short payload (len=%lu)",
1397                                (unsigned long) len);
1398                 return;
1399         }
1400
1401         sta = ap_get_sta(hapd, mgmt->sa);
1402 #ifdef CONFIG_IEEE80211W
1403         if (sta && (sta->flags & WLAN_STA_MFP) &&
1404             !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP) &&
1405               robust_action_frame(mgmt->u.action.category))) {
1406                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1407                                HOSTAPD_LEVEL_DEBUG,
1408                                "Dropped unprotected Robust Action frame from "
1409                                "an MFP STA");
1410                 return;
1411         }
1412 #endif /* CONFIG_IEEE80211W */
1413
1414         switch (mgmt->u.action.category) {
1415 #ifdef CONFIG_IEEE80211R
1416         case WLAN_ACTION_FT:
1417         {
1418                 if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
1419                         wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored FT Action "
1420                                    "frame from unassociated STA " MACSTR,
1421                                    MAC2STR(mgmt->sa));
1422                         return;
1423                 }
1424
1425                 if (wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action,
1426                                      len - IEEE80211_HDRLEN))
1427                         break;
1428
1429                 return;
1430         }
1431 #endif /* CONFIG_IEEE80211R */
1432         case WLAN_ACTION_WMM:
1433                 hostapd_wmm_action(hapd, mgmt, len);
1434                 return;
1435 #ifdef CONFIG_IEEE80211W
1436         case WLAN_ACTION_SA_QUERY:
1437                 hostapd_sa_query_action(hapd, mgmt, len);
1438                 return;
1439 #endif /* CONFIG_IEEE80211W */
1440         case WLAN_ACTION_PUBLIC:
1441                 if (hapd->public_action_cb) {
1442                         hapd->public_action_cb(hapd->public_action_cb_ctx,
1443                                                (u8 *) mgmt, len,
1444                                                hapd->iface->freq);
1445                         return;
1446                 }
1447                 break;
1448         case WLAN_ACTION_VENDOR_SPECIFIC:
1449                 if (hapd->vendor_action_cb) {
1450                         if (hapd->vendor_action_cb(hapd->vendor_action_cb_ctx,
1451                                                    (u8 *) mgmt, len,
1452                                                    hapd->iface->freq) == 0)
1453                                 return;
1454                 }
1455                 break;
1456         }
1457
1458         hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1459                        HOSTAPD_LEVEL_DEBUG,
1460                        "handle_action - unknown action category %d or invalid "
1461                        "frame",
1462                        mgmt->u.action.category);
1463         if (!(mgmt->da[0] & 0x01) && !(mgmt->u.action.category & 0x80) &&
1464             !(mgmt->sa[0] & 0x01)) {
1465                 struct ieee80211_mgmt *resp;
1466
1467                 /*
1468                  * IEEE 802.11-REVma/D9.0 - 7.3.1.11
1469                  * Return the Action frame to the source without change
1470                  * except that MSB of the Category set to 1.
1471                  */
1472                 wpa_printf(MSG_DEBUG, "IEEE 802.11: Return unknown Action "
1473                            "frame back to sender");
1474                 resp = os_malloc(len);
1475                 if (resp == NULL)
1476                         return;
1477                 os_memcpy(resp, mgmt, len);
1478                 os_memcpy(resp->da, resp->sa, ETH_ALEN);
1479                 os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
1480                 os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
1481                 resp->u.action.category |= 0x80;
1482
1483                 hostapd_drv_send_mlme(hapd, resp, len);
1484                 os_free(resp);
1485         }
1486 }
1487
1488
1489 /**
1490  * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
1491  * @hapd: hostapd BSS data structure (the BSS to which the management frame was
1492  * sent to)
1493  * @buf: management frame data (starting from IEEE 802.11 header)
1494  * @len: length of frame data in octets
1495  * @fi: meta data about received frame (signal level, etc.)
1496  *
1497  * Process all incoming IEEE 802.11 management frames. This will be called for
1498  * each frame received from the kernel driver through wlan#ap interface. In
1499  * addition, it can be called to re-inserted pending frames (e.g., when using
1500  * external RADIUS server as an MAC ACL).
1501  */
1502 void ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
1503                      struct hostapd_frame_info *fi)
1504 {
1505         struct ieee80211_mgmt *mgmt;
1506         int broadcast;
1507         u16 fc, stype;
1508
1509         if (len < 24)
1510                 return;
1511
1512         mgmt = (struct ieee80211_mgmt *) buf;
1513         fc = le_to_host16(mgmt->frame_control);
1514         stype = WLAN_FC_GET_STYPE(fc);
1515
1516         if (stype == WLAN_FC_STYPE_BEACON) {
1517                 handle_beacon(hapd, mgmt, len, fi);
1518                 return;
1519         }
1520
1521         broadcast = mgmt->bssid[0] == 0xff && mgmt->bssid[1] == 0xff &&
1522                 mgmt->bssid[2] == 0xff && mgmt->bssid[3] == 0xff &&
1523                 mgmt->bssid[4] == 0xff && mgmt->bssid[5] == 0xff;
1524
1525         if (!broadcast &&
1526             os_memcmp(mgmt->bssid, hapd->own_addr, ETH_ALEN) != 0) {
1527                 printf("MGMT: BSSID=" MACSTR " not our address\n",
1528                        MAC2STR(mgmt->bssid));
1529                 return;
1530         }
1531
1532
1533         if (stype == WLAN_FC_STYPE_PROBE_REQ) {
1534                 handle_probe_req(hapd, mgmt, len);
1535                 return;
1536         }
1537
1538         if (os_memcmp(mgmt->da, hapd->own_addr, ETH_ALEN) != 0) {
1539                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1540                                HOSTAPD_LEVEL_DEBUG,
1541                                "MGMT: DA=" MACSTR " not our address",
1542                                MAC2STR(mgmt->da));
1543                 return;
1544         }
1545
1546         switch (stype) {
1547         case WLAN_FC_STYPE_AUTH:
1548                 wpa_printf(MSG_DEBUG, "mgmt::auth");
1549                 handle_auth(hapd, mgmt, len);
1550                 break;
1551         case WLAN_FC_STYPE_ASSOC_REQ:
1552                 wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
1553                 handle_assoc(hapd, mgmt, len, 0);
1554                 break;
1555         case WLAN_FC_STYPE_REASSOC_REQ:
1556                 wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
1557                 handle_assoc(hapd, mgmt, len, 1);
1558                 break;
1559         case WLAN_FC_STYPE_DISASSOC:
1560                 wpa_printf(MSG_DEBUG, "mgmt::disassoc");
1561                 handle_disassoc(hapd, mgmt, len);
1562                 break;
1563         case WLAN_FC_STYPE_DEAUTH:
1564                 wpa_msg(hapd, MSG_DEBUG, "mgmt::deauth");
1565                 handle_deauth(hapd, mgmt, len);
1566                 break;
1567         case WLAN_FC_STYPE_ACTION:
1568                 wpa_printf(MSG_DEBUG, "mgmt::action");
1569                 handle_action(hapd, mgmt, len);
1570                 break;
1571         default:
1572                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1573                                HOSTAPD_LEVEL_DEBUG,
1574                                "unknown mgmt frame subtype %d", stype);
1575                 break;
1576         }
1577 }
1578
1579
1580 static void handle_auth_cb(struct hostapd_data *hapd,
1581                            const struct ieee80211_mgmt *mgmt,
1582                            size_t len, int ok)
1583 {
1584         u16 auth_alg, auth_transaction, status_code;
1585         struct sta_info *sta;
1586
1587         if (!ok) {
1588                 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
1589                                HOSTAPD_LEVEL_NOTICE,
1590                                "did not acknowledge authentication response");
1591                 return;
1592         }
1593
1594         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
1595                 printf("handle_auth_cb - too short payload (len=%lu)\n",
1596                        (unsigned long) len);
1597                 return;
1598         }
1599
1600         auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
1601         auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
1602         status_code = le_to_host16(mgmt->u.auth.status_code);
1603
1604         sta = ap_get_sta(hapd, mgmt->da);
1605         if (!sta) {
1606                 printf("handle_auth_cb: STA " MACSTR " not found\n",
1607                        MAC2STR(mgmt->da));
1608                 return;
1609         }
1610
1611         if (status_code == WLAN_STATUS_SUCCESS &&
1612             ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
1613              (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
1614                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1615                                HOSTAPD_LEVEL_INFO, "authenticated");
1616                 sta->flags |= WLAN_STA_AUTH;
1617         }
1618 }
1619
1620
1621 static void handle_assoc_cb(struct hostapd_data *hapd,
1622                             const struct ieee80211_mgmt *mgmt,
1623                             size_t len, int reassoc, int ok)
1624 {
1625         u16 status;
1626         struct sta_info *sta;
1627         int new_assoc = 1;
1628         struct ieee80211_ht_capabilities ht_cap;
1629
1630         if (!ok) {
1631                 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
1632                                HOSTAPD_LEVEL_DEBUG,
1633                                "did not acknowledge association response");
1634                 return;
1635         }
1636
1637         if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) :
1638                                       sizeof(mgmt->u.assoc_resp))) {
1639                 printf("handle_assoc_cb(reassoc=%d) - too short payload "
1640                        "(len=%lu)\n", reassoc, (unsigned long) len);
1641                 return;
1642         }
1643
1644         if (reassoc)
1645                 status = le_to_host16(mgmt->u.reassoc_resp.status_code);
1646         else
1647                 status = le_to_host16(mgmt->u.assoc_resp.status_code);
1648
1649         sta = ap_get_sta(hapd, mgmt->da);
1650         if (!sta) {
1651                 printf("handle_assoc_cb: STA " MACSTR " not found\n",
1652                        MAC2STR(mgmt->da));
1653                 return;
1654         }
1655
1656         if (status != WLAN_STATUS_SUCCESS)
1657                 goto fail;
1658
1659         /* Stop previous accounting session, if one is started, and allocate
1660          * new session id for the new session. */
1661         accounting_sta_stop(hapd, sta);
1662
1663         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1664                        HOSTAPD_LEVEL_INFO,
1665                        "associated (aid %d)",
1666                        sta->aid);
1667
1668         if (sta->flags & WLAN_STA_ASSOC)
1669                 new_assoc = 0;
1670         sta->flags |= WLAN_STA_ASSOC;
1671         if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa) ||
1672             sta->auth_alg == WLAN_AUTH_FT) {
1673                 /*
1674                  * Open, static WEP, or FT protocol; no separate authorization
1675                  * step.
1676                  */
1677                 ap_sta_set_authorized(hapd, sta, 1);
1678                 wpa_msg(hapd->msg_ctx, MSG_INFO,
1679                         AP_STA_CONNECTED MACSTR, MAC2STR(sta->addr));
1680         }
1681
1682         if (reassoc)
1683                 mlme_reassociate_indication(hapd, sta);
1684         else
1685                 mlme_associate_indication(hapd, sta);
1686
1687 #ifdef CONFIG_IEEE80211W
1688         sta->sa_query_timed_out = 0;
1689 #endif /* CONFIG_IEEE80211W */
1690
1691         /*
1692          * Remove the STA entry in order to make sure the STA PS state gets
1693          * cleared and configuration gets updated in case of reassociation back
1694          * to the same AP.
1695          */
1696         hostapd_drv_sta_remove(hapd, sta->addr);
1697
1698 #ifdef CONFIG_IEEE80211N
1699         if (sta->flags & WLAN_STA_HT)
1700                 hostapd_get_ht_capab(hapd, sta->ht_capabilities, &ht_cap);
1701 #endif /* CONFIG_IEEE80211N */
1702
1703         if (hostapd_sta_add(hapd, sta->addr, sta->aid, sta->capability,
1704                             sta->supported_rates, sta->supported_rates_len,
1705                             sta->listen_interval,
1706                             sta->flags & WLAN_STA_HT ? &ht_cap : NULL)) {
1707                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1708                                HOSTAPD_LEVEL_NOTICE,
1709                                "Could not add STA to kernel driver");
1710         }
1711
1712         if (sta->flags & WLAN_STA_WDS)
1713                 hostapd_set_wds_sta(hapd, sta->addr, sta->aid, 1);
1714
1715         if (sta->eapol_sm == NULL) {
1716                 /*
1717                  * This STA does not use RADIUS server for EAP authentication,
1718                  * so bind it to the selected VLAN interface now, since the
1719                  * interface selection is not going to change anymore.
1720                  */
1721                 if (ap_sta_bind_vlan(hapd, sta, 0) < 0)
1722                         goto fail;
1723         } else if (sta->vlan_id) {
1724                 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
1725                 if (ap_sta_bind_vlan(hapd, sta, 0) < 0)
1726                         goto fail;
1727         }
1728
1729         hostapd_set_sta_flags(hapd, sta);
1730
1731         if (sta->auth_alg == WLAN_AUTH_FT)
1732                 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
1733         else
1734                 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
1735         hapd->new_assoc_sta_cb(hapd, sta, !new_assoc);
1736
1737         ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
1738
1739  fail:
1740         /* Copy of the association request is not needed anymore */
1741         if (sta->last_assoc_req) {
1742                 os_free(sta->last_assoc_req);
1743                 sta->last_assoc_req = NULL;
1744         }
1745 }
1746
1747
1748 /**
1749  * ieee802_11_mgmt_cb - Process management frame TX status callback
1750  * @hapd: hostapd BSS data structure (the BSS from which the management frame
1751  * was sent from)
1752  * @buf: management frame data (starting from IEEE 802.11 header)
1753  * @len: length of frame data in octets
1754  * @stype: management frame subtype from frame control field
1755  * @ok: Whether the frame was ACK'ed
1756  */
1757 void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len,
1758                         u16 stype, int ok)
1759 {
1760         const struct ieee80211_mgmt *mgmt;
1761         mgmt = (const struct ieee80211_mgmt *) buf;
1762
1763         switch (stype) {
1764         case WLAN_FC_STYPE_AUTH:
1765                 wpa_printf(MSG_DEBUG, "mgmt::auth cb");
1766                 handle_auth_cb(hapd, mgmt, len, ok);
1767                 break;
1768         case WLAN_FC_STYPE_ASSOC_RESP:
1769                 wpa_printf(MSG_DEBUG, "mgmt::assoc_resp cb");
1770                 handle_assoc_cb(hapd, mgmt, len, 0, ok);
1771                 break;
1772         case WLAN_FC_STYPE_REASSOC_RESP:
1773                 wpa_printf(MSG_DEBUG, "mgmt::reassoc_resp cb");
1774                 handle_assoc_cb(hapd, mgmt, len, 1, ok);
1775                 break;
1776         case WLAN_FC_STYPE_PROBE_RESP:
1777                 wpa_printf(MSG_EXCESSIVE, "mgmt::proberesp cb");
1778                 break;
1779         case WLAN_FC_STYPE_DEAUTH:
1780                 /* ignore */
1781                 break;
1782         case WLAN_FC_STYPE_ACTION:
1783                 wpa_printf(MSG_DEBUG, "mgmt::action cb");
1784                 break;
1785         default:
1786                 printf("unknown mgmt cb frame subtype %d\n", stype);
1787                 break;
1788         }
1789 }
1790
1791
1792 int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
1793 {
1794         /* TODO */
1795         return 0;
1796 }
1797
1798
1799 int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
1800                            char *buf, size_t buflen)
1801 {
1802         /* TODO */
1803         return 0;
1804 }
1805
1806
1807 void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr,
1808                        const u8 *buf, size_t len, int ack)
1809 {
1810         struct sta_info *sta;
1811         struct hostapd_iface *iface = hapd->iface;
1812
1813         sta = ap_get_sta(hapd, addr);
1814         if (sta == NULL && iface->num_bss > 1) {
1815                 size_t j;
1816                 for (j = 0; j < iface->num_bss; j++) {
1817                         hapd = iface->bss[j];
1818                         sta = ap_get_sta(hapd, addr);
1819                         if (sta)
1820                                 break;
1821                 }
1822         }
1823         if (sta == NULL)
1824                 return;
1825         if (sta->flags & WLAN_STA_PENDING_POLL) {
1826                 wpa_printf(MSG_DEBUG, "STA " MACSTR " %s pending "
1827                            "activity poll", MAC2STR(sta->addr),
1828                            ack ? "ACKed" : "did not ACK");
1829                 if (ack)
1830                         sta->flags &= ~WLAN_STA_PENDING_POLL;
1831         }
1832
1833         ieee802_1x_tx_status(hapd, sta, buf, len, ack);
1834 }
1835
1836
1837 void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src,
1838                                 int wds)
1839 {
1840         struct sta_info *sta;
1841
1842         sta = ap_get_sta(hapd, src);
1843         if (sta && (sta->flags & WLAN_STA_ASSOC)) {
1844                 if (wds && !(sta->flags & WLAN_STA_WDS)) {
1845                         wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for "
1846                                    "STA " MACSTR " (aid %u)",
1847                                    MAC2STR(sta->addr), sta->aid);
1848                         sta->flags |= WLAN_STA_WDS;
1849                         hostapd_set_wds_sta(hapd, sta->addr, sta->aid, 1);
1850                 }
1851                 return;
1852         }
1853
1854         wpa_printf(MSG_DEBUG, "Data/PS-poll frame from not associated STA "
1855                    MACSTR, MAC2STR(src));
1856         if (src[0] & 0x01) {
1857                 /* Broadcast bit set in SA?! Ignore the frame silently. */
1858                 return;
1859         }
1860
1861         if (sta && (sta->flags & WLAN_STA_AUTH))
1862                 hostapd_drv_sta_disassoc(
1863                         hapd, src,
1864                         WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1865         else
1866                 hostapd_drv_sta_deauth(
1867                         hapd, src,
1868                         WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1869 }
1870
1871
1872 #endif /* CONFIG_NATIVE_WINDOWS */