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