2 * hostapd / IEEE 802.11 Management
3 * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
15 #include "utils/includes.h"
17 #ifndef CONFIG_NATIVE_WINDOWS
19 #include "utils/common.h"
20 #include "utils/eloop.h"
21 #include "crypto/crypto.h"
22 #include "drivers/driver.h"
23 #include "common/wpa_ctrl.h"
24 #include "radius/radius.h"
25 #include "radius/radius_client.h"
27 #include "ieee802_11.h"
29 #include "ieee802_11_auth.h"
31 #include "ieee802_1x.h"
35 #include "accounting.h"
40 u8
* hostapd_eid_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
45 if (hapd
->iface
->current_rates
== NULL
)
48 *pos
++ = WLAN_EID_SUPP_RATES
;
49 num
= hapd
->iface
->num_rates
;
51 /* rest of the rates are encoded in Extended supported
58 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
;
61 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
62 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
71 u8
* hostapd_eid_ext_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
76 if (hapd
->iface
->current_rates
== NULL
)
79 num
= hapd
->iface
->num_rates
;
84 *pos
++ = WLAN_EID_EXT_SUPP_RATES
;
87 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
+ 8;
91 continue; /* already in SuppRates IE */
92 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
93 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
102 u16
hostapd_own_capab_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
105 int capab
= WLAN_CAPABILITY_ESS
;
108 if (hapd
->iface
->num_sta_no_short_preamble
== 0 &&
109 hapd
->iconf
->preamble
== SHORT_PREAMBLE
)
110 capab
|= WLAN_CAPABILITY_SHORT_PREAMBLE
;
112 privacy
= hapd
->conf
->ssid
.wep
.keys_set
;
114 if (hapd
->conf
->ieee802_1x
&&
115 (hapd
->conf
->default_wep_key_len
||
116 hapd
->conf
->individual_wep_key_len
))
123 int policy
, def_klen
;
124 if (probe
&& sta
->ssid_probe
) {
125 policy
= sta
->ssid_probe
->security_policy
;
126 def_klen
= sta
->ssid_probe
->wep
.default_len
;
128 policy
= sta
->ssid
->security_policy
;
129 def_klen
= sta
->ssid
->wep
.default_len
;
131 privacy
= policy
!= SECURITY_PLAINTEXT
;
132 if (policy
== SECURITY_IEEE_802_1X
&& def_klen
== 0)
137 capab
|= WLAN_CAPABILITY_PRIVACY
;
139 if (hapd
->iface
->current_mode
&&
140 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
141 hapd
->iface
->num_sta_no_short_slot_time
== 0)
142 capab
|= WLAN_CAPABILITY_SHORT_SLOT_TIME
;
148 #ifdef CONFIG_IEEE80211W
149 static u8
* hostapd_eid_assoc_comeback_time(struct hostapd_data
*hapd
,
150 struct sta_info
*sta
, u8
*eid
)
154 struct os_time now
, passed
;
156 *pos
++ = WLAN_EID_TIMEOUT_INTERVAL
;
158 *pos
++ = WLAN_TIMEOUT_ASSOC_COMEBACK
;
160 os_time_sub(&now
, &sta
->sa_query_start
, &passed
);
161 tu
= (passed
.sec
* 1000000 + passed
.usec
) / 1024;
162 if (hapd
->conf
->assoc_sa_query_max_timeout
> tu
)
163 timeout
= hapd
->conf
->assoc_sa_query_max_timeout
- tu
;
166 if (timeout
< hapd
->conf
->assoc_sa_query_max_timeout
)
167 timeout
++; /* add some extra time for local timers */
168 WPA_PUT_LE32(pos
, timeout
);
173 #endif /* CONFIG_IEEE80211W */
176 void ieee802_11_print_ssid(char *buf
, const u8
*ssid
, u8 len
)
179 if (len
> HOSTAPD_MAX_SSID_LEN
)
180 len
= HOSTAPD_MAX_SSID_LEN
;
181 for (i
= 0; i
< len
; i
++) {
182 if (ssid
[i
] >= 32 && ssid
[i
] < 127)
192 * ieee802_11_send_deauth - Send Deauthentication frame
193 * @hapd: hostapd BSS data
194 * @addr: Address of the destination STA
195 * @reason: Reason code for Deauthentication
197 void ieee802_11_send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
200 struct ieee80211_mgmt mgmt
;
202 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE80211
,
204 "deauthenticate - reason %d", reason
);
205 os_memset(&mgmt
, 0, sizeof(mgmt
));
206 mgmt
.frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
207 WLAN_FC_STYPE_DEAUTH
);
208 os_memcpy(mgmt
.da
, addr
, ETH_ALEN
);
209 os_memcpy(mgmt
.sa
, hapd
->own_addr
, ETH_ALEN
);
210 os_memcpy(mgmt
.bssid
, hapd
->own_addr
, ETH_ALEN
);
211 mgmt
.u
.deauth
.reason_code
= host_to_le16(reason
);
212 if (hapd
->drv
.send_mgmt_frame(hapd
, &mgmt
, IEEE80211_HDRLEN
+
213 sizeof(mgmt
.u
.deauth
)) < 0)
214 perror("ieee802_11_send_deauth: send");
218 static u16
auth_shared_key(struct hostapd_data
*hapd
, struct sta_info
*sta
,
219 u16 auth_transaction
, const u8
*challenge
,
222 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
224 "authentication (shared key, transaction %d)",
227 if (auth_transaction
== 1) {
228 if (!sta
->challenge
) {
229 /* Generate a pseudo-random challenge */
233 sta
->challenge
= os_zalloc(WLAN_AUTH_CHALLENGE_LEN
);
234 if (sta
->challenge
== NULL
)
235 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
239 os_memcpy(key
, &now
, 4);
240 os_memcpy(key
+ 4, &r
, 4);
241 rc4_skip(key
, sizeof(key
), 0,
242 sta
->challenge
, WLAN_AUTH_CHALLENGE_LEN
);
247 if (auth_transaction
!= 3)
248 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
251 if (!iswep
|| !sta
->challenge
|| !challenge
||
252 os_memcmp(sta
->challenge
, challenge
, WLAN_AUTH_CHALLENGE_LEN
)) {
253 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
255 "shared key authentication - invalid "
256 "challenge-response");
257 return WLAN_STATUS_CHALLENGE_FAIL
;
260 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
262 "authentication OK (shared key)");
263 #ifdef IEEE80211_REQUIRE_AUTH_ACK
264 /* Station will be marked authenticated if it ACKs the
265 * authentication reply. */
267 sta
->flags
|= WLAN_STA_AUTH
;
268 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
270 os_free(sta
->challenge
);
271 sta
->challenge
= NULL
;
277 static void send_auth_reply(struct hostapd_data
*hapd
,
278 const u8
*dst
, const u8
*bssid
,
279 u16 auth_alg
, u16 auth_transaction
, u16 resp
,
280 const u8
*ies
, size_t ies_len
)
282 struct ieee80211_mgmt
*reply
;
286 rlen
= IEEE80211_HDRLEN
+ sizeof(reply
->u
.auth
) + ies_len
;
287 buf
= os_zalloc(rlen
);
291 reply
= (struct ieee80211_mgmt
*) buf
;
292 reply
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
294 os_memcpy(reply
->da
, dst
, ETH_ALEN
);
295 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
296 os_memcpy(reply
->bssid
, bssid
, ETH_ALEN
);
298 reply
->u
.auth
.auth_alg
= host_to_le16(auth_alg
);
299 reply
->u
.auth
.auth_transaction
= host_to_le16(auth_transaction
);
300 reply
->u
.auth
.status_code
= host_to_le16(resp
);
303 os_memcpy(reply
->u
.auth
.variable
, ies
, ies_len
);
305 wpa_printf(MSG_DEBUG
, "authentication reply: STA=" MACSTR
306 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
307 MAC2STR(dst
), auth_alg
, auth_transaction
,
308 resp
, (unsigned long) ies_len
);
309 if (hapd
->drv
.send_mgmt_frame(hapd
, reply
, rlen
) < 0)
310 perror("send_auth_reply: send");
316 #ifdef CONFIG_IEEE80211R
317 static void handle_auth_ft_finish(void *ctx
, const u8
*dst
, const u8
*bssid
,
318 u16 auth_transaction
, u16 status
,
319 const u8
*ies
, size_t ies_len
)
321 struct hostapd_data
*hapd
= ctx
;
322 struct sta_info
*sta
;
324 send_auth_reply(hapd
, dst
, bssid
, WLAN_AUTH_FT
, auth_transaction
,
325 status
, ies
, ies_len
);
327 if (status
!= WLAN_STATUS_SUCCESS
)
330 sta
= ap_get_sta(hapd
, dst
);
334 hostapd_logger(hapd
, dst
, HOSTAPD_MODULE_IEEE80211
,
335 HOSTAPD_LEVEL_DEBUG
, "authentication OK (FT)");
336 sta
->flags
|= WLAN_STA_AUTH
;
337 mlme_authenticate_indication(hapd
, sta
);
339 #endif /* CONFIG_IEEE80211R */
342 static void handle_auth(struct hostapd_data
*hapd
,
343 const struct ieee80211_mgmt
*mgmt
, size_t len
)
345 u16 auth_alg
, auth_transaction
, status_code
;
346 u16 resp
= WLAN_STATUS_SUCCESS
;
347 struct sta_info
*sta
= NULL
;
350 const u8
*challenge
= NULL
;
351 u32 session_timeout
, acct_interim_interval
;
353 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
354 size_t resp_ies_len
= 0;
356 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
357 printf("handle_auth - too short payload (len=%lu)\n",
358 (unsigned long) len
);
362 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
363 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
364 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
365 fc
= le_to_host16(mgmt
->frame_control
);
367 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
368 2 + WLAN_AUTH_CHALLENGE_LEN
&&
369 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
370 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
371 challenge
= &mgmt
->u
.auth
.variable
[2];
373 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
374 "auth_transaction=%d status_code=%d wep=%d%s",
375 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
376 status_code
, !!(fc
& WLAN_FC_ISWEP
),
377 challenge
? " challenge" : "");
379 if (hapd
->tkip_countermeasures
) {
380 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
384 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
385 auth_alg
== WLAN_AUTH_OPEN
) ||
386 #ifdef CONFIG_IEEE80211R
388 (hapd
->conf
->wpa_key_mgmt
&
389 (WPA_KEY_MGMT_FT_IEEE8021X
| WPA_KEY_MGMT_FT_PSK
)) &&
390 auth_alg
== WLAN_AUTH_FT
) ||
391 #endif /* CONFIG_IEEE80211R */
392 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
393 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
394 printf("Unsupported authentication algorithm (%d)\n",
396 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
400 if (!(auth_transaction
== 1 ||
401 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
402 printf("Unknown authentication transaction number (%d)\n",
404 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
408 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
409 printf("Station " MACSTR
" not allowed to authenticate.\n",
411 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
415 res
= hostapd_allowed_address(hapd
, mgmt
->sa
, (u8
*) mgmt
, len
,
417 &acct_interim_interval
, &vlan_id
);
418 if (res
== HOSTAPD_ACL_REJECT
) {
419 printf("Station " MACSTR
" not allowed to authenticate.\n",
421 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
424 if (res
== HOSTAPD_ACL_PENDING
) {
425 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
426 " waiting for an external authentication",
428 /* Authentication code will re-send the authentication frame
429 * after it has received (and cached) information from the
430 * external source. */
434 sta
= ap_sta_add(hapd
, mgmt
->sa
);
436 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
441 if (hostapd_get_vlan_id_ifname(hapd
->conf
->vlan
,
443 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
444 HOSTAPD_LEVEL_INFO
, "Invalid VLAN ID "
445 "%d received from RADIUS server",
447 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
450 sta
->vlan_id
= vlan_id
;
451 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
452 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
455 sta
->flags
&= ~WLAN_STA_PREAUTH
;
456 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
458 if (hapd
->conf
->acct_interim_interval
== 0 && acct_interim_interval
)
459 sta
->acct_interim_interval
= acct_interim_interval
;
460 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
)
461 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
463 ap_sta_no_session_timeout(hapd
, sta
);
467 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
469 "authentication OK (open system)");
470 #ifdef IEEE80211_REQUIRE_AUTH_ACK
471 /* Station will be marked authenticated if it ACKs the
472 * authentication reply. */
474 sta
->flags
|= WLAN_STA_AUTH
;
475 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
476 sta
->auth_alg
= WLAN_AUTH_OPEN
;
477 mlme_authenticate_indication(hapd
, sta
);
480 case WLAN_AUTH_SHARED_KEY
:
481 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
483 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
484 mlme_authenticate_indication(hapd
, sta
);
485 if (sta
->challenge
&& auth_transaction
== 1) {
486 resp_ies
[0] = WLAN_EID_CHALLENGE
;
487 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
488 os_memcpy(resp_ies
+ 2, sta
->challenge
,
489 WLAN_AUTH_CHALLENGE_LEN
);
490 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
493 #ifdef CONFIG_IEEE80211R
495 sta
->auth_alg
= WLAN_AUTH_FT
;
496 if (sta
->wpa_sm
== NULL
)
497 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
499 if (sta
->wpa_sm
== NULL
) {
500 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
502 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
505 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
506 auth_transaction
, mgmt
->u
.auth
.variable
,
507 len
- IEEE80211_HDRLEN
-
508 sizeof(mgmt
->u
.auth
),
509 handle_auth_ft_finish
, hapd
);
510 /* handle_auth_ft_finish() callback will complete auth. */
512 #endif /* CONFIG_IEEE80211R */
516 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
517 auth_transaction
+ 1, resp
, resp_ies
, resp_ies_len
);
521 static int hostapd_get_aid(struct hostapd_data
*hapd
, struct sta_info
*sta
)
525 /* get a unique AID */
527 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
531 for (i
= 0; i
< AID_WORDS
; i
++) {
532 if (hapd
->sta_aid
[i
] == (u32
) -1)
534 for (j
= 0; j
< 32; j
++) {
535 if (!(hapd
->sta_aid
[i
] & BIT(j
)))
543 aid
= i
* 32 + j
+ 1;
548 hapd
->sta_aid
[i
] |= BIT(j
);
549 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
554 static u16
check_ssid(struct hostapd_data
*hapd
, struct sta_info
*sta
,
555 const u8
*ssid_ie
, size_t ssid_ie_len
)
558 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
560 if (ssid_ie_len
!= hapd
->conf
->ssid
.ssid_len
||
561 os_memcmp(ssid_ie
, hapd
->conf
->ssid
.ssid
, ssid_ie_len
) != 0) {
563 ieee802_11_print_ssid(ssid_txt
, ssid_ie
, ssid_ie_len
);
564 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
566 "Station tried to associate with unknown SSID "
568 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
571 return WLAN_STATUS_SUCCESS
;
575 static u16
check_wmm(struct hostapd_data
*hapd
, struct sta_info
*sta
,
576 const u8
*wmm_ie
, size_t wmm_ie_len
)
578 sta
->flags
&= ~WLAN_STA_WMM
;
579 if (wmm_ie
&& hapd
->conf
->wmm_enabled
) {
580 if (hostapd_eid_wmm_valid(hapd
, wmm_ie
, wmm_ie_len
))
581 hostapd_logger(hapd
, sta
->addr
,
584 "invalid WMM element in association "
587 sta
->flags
|= WLAN_STA_WMM
;
589 return WLAN_STATUS_SUCCESS
;
593 static u16
copy_supp_rates(struct hostapd_data
*hapd
, struct sta_info
*sta
,
594 struct ieee802_11_elems
*elems
)
596 if (!elems
->supp_rates
) {
597 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
599 "No supported rates element in AssocReq");
600 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
603 if (elems
->supp_rates_len
> sizeof(sta
->supported_rates
)) {
604 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
606 "Invalid supported rates element length %d",
607 elems
->supp_rates_len
);
608 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
611 os_memset(sta
->supported_rates
, 0, sizeof(sta
->supported_rates
));
612 os_memcpy(sta
->supported_rates
, elems
->supp_rates
,
613 elems
->supp_rates_len
);
614 sta
->supported_rates_len
= elems
->supp_rates_len
;
616 if (elems
->ext_supp_rates
) {
617 if (elems
->supp_rates_len
+ elems
->ext_supp_rates_len
>
618 sizeof(sta
->supported_rates
)) {
619 hostapd_logger(hapd
, sta
->addr
,
620 HOSTAPD_MODULE_IEEE80211
,
622 "Invalid supported rates element length"
623 " %d+%d", elems
->supp_rates_len
,
624 elems
->ext_supp_rates_len
);
625 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
628 os_memcpy(sta
->supported_rates
+ elems
->supp_rates_len
,
629 elems
->ext_supp_rates
, elems
->ext_supp_rates_len
);
630 sta
->supported_rates_len
+= elems
->ext_supp_rates_len
;
633 return WLAN_STATUS_SUCCESS
;
637 static u16
check_assoc_ies(struct hostapd_data
*hapd
, struct sta_info
*sta
,
638 const u8
*ies
, size_t ies_len
, int reassoc
)
640 struct ieee802_11_elems elems
;
645 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 1) == ParseFailed
) {
646 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
647 HOSTAPD_LEVEL_INFO
, "Station sent an invalid "
648 "association request");
649 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
652 resp
= check_ssid(hapd
, sta
, elems
.ssid
, elems
.ssid_len
);
653 if (resp
!= WLAN_STATUS_SUCCESS
)
655 resp
= check_wmm(hapd
, sta
, elems
.wmm
, elems
.wmm_len
);
656 if (resp
!= WLAN_STATUS_SUCCESS
)
658 resp
= copy_supp_rates(hapd
, sta
, &elems
);
659 if (resp
!= WLAN_STATUS_SUCCESS
)
661 #ifdef CONFIG_IEEE80211N
662 resp
= copy_sta_ht_capab(sta
, elems
.ht_capabilities
,
663 elems
.ht_capabilities_len
);
664 if (resp
!= WLAN_STATUS_SUCCESS
)
666 #endif /* CONFIG_IEEE80211N */
668 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
669 wpa_ie
= elems
.rsn_ie
;
670 wpa_ie_len
= elems
.rsn_ie_len
;
671 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
673 wpa_ie
= elems
.wpa_ie
;
674 wpa_ie_len
= elems
.wpa_ie_len
;
681 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
);
682 if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
684 wpa_printf(MSG_DEBUG
, "STA included WPS IE in "
685 "(Re)Association Request - assume WPS is "
687 sta
->flags
|= WLAN_STA_WPS
;
688 wpabuf_free(sta
->wps_ie
);
689 sta
->wps_ie
= wpabuf_alloc_copy(elems
.wps_ie
+ 4,
690 elems
.wps_ie_len
- 4);
692 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE "
693 "in (Re)Association Request - possible WPS "
695 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
698 #endif /* CONFIG_WPS */
699 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
700 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
702 "No WPA/RSN IE in association request");
703 return WLAN_STATUS_INVALID_IE
;
706 if (hapd
->conf
->wpa
&& wpa_ie
) {
710 if (sta
->wpa_sm
== NULL
)
711 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
713 if (sta
->wpa_sm
== NULL
) {
714 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
716 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
718 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
720 elems
.mdie
, elems
.mdie_len
);
721 if (res
== WPA_INVALID_GROUP
)
722 resp
= WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
723 else if (res
== WPA_INVALID_PAIRWISE
)
724 resp
= WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
725 else if (res
== WPA_INVALID_AKMP
)
726 resp
= WLAN_STATUS_AKMP_NOT_VALID
;
727 else if (res
== WPA_ALLOC_FAIL
)
728 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
729 #ifdef CONFIG_IEEE80211W
730 else if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
731 resp
= WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
732 else if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
733 resp
= WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
734 #endif /* CONFIG_IEEE80211W */
735 else if (res
== WPA_INVALID_MDIE
)
736 resp
= WLAN_STATUS_INVALID_MDIE
;
737 else if (res
!= WPA_IE_OK
)
738 resp
= WLAN_STATUS_INVALID_IE
;
739 if (resp
!= WLAN_STATUS_SUCCESS
)
741 #ifdef CONFIG_IEEE80211W
742 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
743 sta
->sa_query_count
> 0)
744 ap_check_sa_query_timeout(hapd
, sta
);
745 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
746 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
748 * STA has already been associated with MFP and SA
749 * Query timeout has not been reached. Reject the
750 * association attempt temporarily and start SA Query,
751 * if one is not pending.
754 if (sta
->sa_query_count
== 0)
755 ap_sta_start_sa_query(hapd
, sta
);
757 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
760 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
761 sta
->flags
|= WLAN_STA_MFP
;
763 sta
->flags
&= ~WLAN_STA_MFP
;
764 #endif /* CONFIG_IEEE80211W */
766 #ifdef CONFIG_IEEE80211R
767 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
769 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
770 "to use association (not "
771 "re-association) with FT auth_alg",
773 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
776 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, ies
,
778 if (resp
!= WLAN_STATUS_SUCCESS
)
781 #endif /* CONFIG_IEEE80211R */
783 #ifdef CONFIG_IEEE80211N
784 if ((sta
->flags
& WLAN_STA_HT
) &&
785 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
786 hostapd_logger(hapd
, sta
->addr
,
787 HOSTAPD_MODULE_IEEE80211
,
789 "Station tried to use TKIP with HT "
791 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
793 #endif /* CONFIG_IEEE80211N */
795 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
797 return WLAN_STATUS_SUCCESS
;
801 static void send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
805 struct ieee80211_mgmt reply
;
807 os_memset(&reply
, 0, sizeof(reply
));
808 reply
.frame_control
=
809 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_DEAUTH
);
810 os_memcpy(reply
.da
, addr
, ETH_ALEN
);
811 os_memcpy(reply
.sa
, hapd
->own_addr
, ETH_ALEN
);
812 os_memcpy(reply
.bssid
, hapd
->own_addr
, ETH_ALEN
);
814 send_len
= IEEE80211_HDRLEN
+ sizeof(reply
.u
.deauth
);
815 reply
.u
.deauth
.reason_code
= host_to_le16(reason_code
);
817 if (hapd
->drv
.send_mgmt_frame(hapd
, &reply
, send_len
) < 0)
818 wpa_printf(MSG_INFO
, "Failed to send deauth: %s",
823 static void send_assoc_resp(struct hostapd_data
*hapd
, struct sta_info
*sta
,
824 u16 status_code
, int reassoc
, const u8
*ies
,
828 u8 buf
[sizeof(struct ieee80211_mgmt
) + 1024];
829 struct ieee80211_mgmt
*reply
;
832 os_memset(buf
, 0, sizeof(buf
));
833 reply
= (struct ieee80211_mgmt
*) buf
;
834 reply
->frame_control
=
835 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
836 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
837 WLAN_FC_STYPE_ASSOC_RESP
));
838 os_memcpy(reply
->da
, sta
->addr
, ETH_ALEN
);
839 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
840 os_memcpy(reply
->bssid
, hapd
->own_addr
, ETH_ALEN
);
842 send_len
= IEEE80211_HDRLEN
;
843 send_len
+= sizeof(reply
->u
.assoc_resp
);
844 reply
->u
.assoc_resp
.capab_info
=
845 host_to_le16(hostapd_own_capab_info(hapd
, sta
, 0));
846 reply
->u
.assoc_resp
.status_code
= host_to_le16(status_code
);
847 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0)
848 | BIT(14) | BIT(15));
849 /* Supported rates */
850 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
851 /* Extended supported rates */
852 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
853 if (sta
->flags
& WLAN_STA_WMM
)
854 p
= hostapd_eid_wmm(hapd
, p
);
856 #ifdef CONFIG_IEEE80211N
857 p
= hostapd_eid_ht_capabilities(hapd
, p
);
858 p
= hostapd_eid_ht_operation(hapd
, p
);
859 #endif /* CONFIG_IEEE80211N */
861 #ifdef CONFIG_IEEE80211R
862 if (status_code
== WLAN_STATUS_SUCCESS
) {
863 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
864 * Transition Information, RSN, [RIC Response] */
865 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
866 buf
+ sizeof(buf
) - p
,
867 sta
->auth_alg
, ies
, ies_len
);
869 #endif /* CONFIG_IEEE80211R */
871 #ifdef CONFIG_IEEE80211W
872 if (status_code
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
873 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
874 #endif /* CONFIG_IEEE80211W */
876 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
878 if (hapd
->drv
.send_mgmt_frame(hapd
, reply
, send_len
) < 0)
879 wpa_printf(MSG_INFO
, "Failed to send assoc resp: %s",
884 static void handle_assoc(struct hostapd_data
*hapd
,
885 const struct ieee80211_mgmt
*mgmt
, size_t len
,
888 u16 capab_info
, listen_interval
;
889 u16 resp
= WLAN_STATUS_SUCCESS
;
892 struct sta_info
*sta
;
894 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
895 sizeof(mgmt
->u
.assoc_req
))) {
896 printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
897 "\n", reassoc
, (unsigned long) len
);
902 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
903 listen_interval
= le_to_host16(
904 mgmt
->u
.reassoc_req
.listen_interval
);
905 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
906 " capab_info=0x%02x listen_interval=%d current_ap="
908 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
909 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
));
910 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
911 pos
= mgmt
->u
.reassoc_req
.variable
;
913 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
914 listen_interval
= le_to_host16(
915 mgmt
->u
.assoc_req
.listen_interval
);
916 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
917 " capab_info=0x%02x listen_interval=%d",
918 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
);
919 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
920 pos
= mgmt
->u
.assoc_req
.variable
;
923 sta
= ap_get_sta(hapd
, mgmt
->sa
);
924 #ifdef CONFIG_IEEE80211R
925 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
926 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
927 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
928 "prior to authentication since it is using "
929 "over-the-DS FT", MAC2STR(mgmt
->sa
));
931 #endif /* CONFIG_IEEE80211R */
932 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
933 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
934 HOSTAPD_LEVEL_INFO
, "Station tried to "
935 "associate before authentication "
936 "(aid=%d flags=0x%x)",
938 sta
? sta
->flags
: 0);
939 send_deauth(hapd
, mgmt
->sa
,
940 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
);
944 if (hapd
->tkip_countermeasures
) {
945 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
949 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
950 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
952 "Too large Listen Interval (%d)",
954 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
958 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
960 resp
= check_assoc_ies(hapd
, sta
, pos
, left
, reassoc
);
961 if (resp
!= WLAN_STATUS_SUCCESS
)
964 if (hostapd_get_aid(hapd
, sta
) < 0) {
965 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
966 HOSTAPD_LEVEL_INFO
, "No room for more AIDs");
967 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
971 sta
->capability
= capab_info
;
972 sta
->listen_interval
= listen_interval
;
974 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
975 sta
->flags
|= WLAN_STA_NONERP
;
976 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
977 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
978 sta
->flags
&= ~WLAN_STA_NONERP
;
982 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
984 hapd
->iface
->num_sta_non_erp
++;
985 if (hapd
->iface
->num_sta_non_erp
== 1)
986 ieee802_11_set_beacons(hapd
->iface
);
989 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
990 !sta
->no_short_slot_time_set
) {
991 sta
->no_short_slot_time_set
= 1;
992 hapd
->iface
->num_sta_no_short_slot_time
++;
993 if (hapd
->iface
->current_mode
->mode
==
994 HOSTAPD_MODE_IEEE80211G
&&
995 hapd
->iface
->num_sta_no_short_slot_time
== 1)
996 ieee802_11_set_beacons(hapd
->iface
);
999 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
1000 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
1002 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
1004 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
1005 !sta
->no_short_preamble_set
) {
1006 sta
->no_short_preamble_set
= 1;
1007 hapd
->iface
->num_sta_no_short_preamble
++;
1008 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
1009 && hapd
->iface
->num_sta_no_short_preamble
== 1)
1010 ieee802_11_set_beacons(hapd
->iface
);
1013 #ifdef CONFIG_IEEE80211N
1014 update_ht_state(hapd
, sta
);
1015 #endif /* CONFIG_IEEE80211N */
1017 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1018 HOSTAPD_LEVEL_DEBUG
,
1019 "association OK (aid %d)", sta
->aid
);
1020 /* Station will be marked associated, after it acknowledges AssocResp
1023 #ifdef CONFIG_IEEE80211W
1024 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
1025 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
1026 "SA Query procedure", reassoc
? "re" : "");
1027 /* TODO: Send a protected Disassociate frame to the STA using
1028 * the old key and Reason Code "Previous Authentication no
1029 * longer valid". Make sure this is only sent protected since
1030 * unprotected frame would be received by the STA that is now
1031 * trying to associate.
1034 #endif /* CONFIG_IEEE80211W */
1037 os_memcpy(sta
->previous_ap
, mgmt
->u
.reassoc_req
.current_ap
,
1041 if (sta
->last_assoc_req
)
1042 os_free(sta
->last_assoc_req
);
1043 sta
->last_assoc_req
= os_malloc(len
);
1044 if (sta
->last_assoc_req
)
1045 os_memcpy(sta
->last_assoc_req
, mgmt
, len
);
1047 /* Make sure that the previously registered inactivity timer will not
1048 * remove the STA immediately. */
1049 sta
->timeout_next
= STA_NULLFUNC
;
1052 send_assoc_resp(hapd
, sta
, resp
, reassoc
, pos
, left
);
1056 static void handle_disassoc(struct hostapd_data
*hapd
,
1057 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1059 struct sta_info
*sta
;
1061 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
1062 printf("handle_disassoc - too short payload (len=%lu)\n",
1063 (unsigned long) len
);
1067 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
1069 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1071 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1073 printf("Station " MACSTR
" trying to disassociate, but it "
1074 "is not associated.\n", MAC2STR(mgmt
->sa
));
1078 sta
->flags
&= ~WLAN_STA_ASSOC
;
1079 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, AP_STA_DISCONNECTED MACSTR
,
1080 MAC2STR(sta
->addr
));
1081 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
1082 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1083 HOSTAPD_LEVEL_INFO
, "disassociated");
1084 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1085 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1086 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
1088 accounting_sta_stop(hapd
, sta
);
1089 ieee802_1x_free_station(sta
);
1090 hapd
->drv
.sta_remove(hapd
, sta
->addr
);
1092 if (sta
->timeout_next
== STA_NULLFUNC
||
1093 sta
->timeout_next
== STA_DISASSOC
) {
1094 sta
->timeout_next
= STA_DEAUTH
;
1095 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
1096 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
1100 mlme_disassociate_indication(
1101 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1105 static void handle_deauth(struct hostapd_data
*hapd
,
1106 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1108 struct sta_info
*sta
;
1110 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
1111 printf("handle_deauth - too short payload (len=%lu)\n",
1112 (unsigned long) len
);
1116 wpa_printf(MSG_DEBUG
, "deauthentication: STA=" MACSTR
1119 le_to_host16(mgmt
->u
.deauth
.reason_code
));
1121 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1123 printf("Station " MACSTR
" trying to deauthenticate, but it "
1124 "is not authenticated.\n", MAC2STR(mgmt
->sa
));
1128 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
);
1129 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, AP_STA_DISCONNECTED MACSTR
,
1130 MAC2STR(sta
->addr
));
1131 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
1132 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1133 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
1134 mlme_deauthenticate_indication(
1135 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
1136 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1137 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1138 ap_free_sta(hapd
, sta
);
1142 static void handle_beacon(struct hostapd_data
*hapd
,
1143 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1144 struct hostapd_frame_info
*fi
)
1146 struct ieee802_11_elems elems
;
1148 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
1149 printf("handle_beacon - too short payload (len=%lu)\n",
1150 (unsigned long) len
);
1154 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
1155 len
- (IEEE80211_HDRLEN
+
1156 sizeof(mgmt
->u
.beacon
)), &elems
,
1159 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
1163 #ifdef CONFIG_IEEE80211W
1165 /* MLME-SAQuery.request */
1166 void ieee802_11_send_sa_query_req(struct hostapd_data
*hapd
,
1167 const u8
*addr
, const u8
*trans_id
)
1169 struct ieee80211_mgmt mgmt
;
1172 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Sending SA Query Request to "
1173 MACSTR
, MAC2STR(addr
));
1174 wpa_hexdump(MSG_DEBUG
, "IEEE 802.11: SA Query Transaction ID",
1175 trans_id
, WLAN_SA_QUERY_TR_ID_LEN
);
1177 os_memset(&mgmt
, 0, sizeof(mgmt
));
1178 mgmt
.frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
1179 WLAN_FC_STYPE_ACTION
);
1180 os_memcpy(mgmt
.da
, addr
, ETH_ALEN
);
1181 os_memcpy(mgmt
.sa
, hapd
->own_addr
, ETH_ALEN
);
1182 os_memcpy(mgmt
.bssid
, hapd
->own_addr
, ETH_ALEN
);
1183 mgmt
.u
.action
.category
= WLAN_ACTION_SA_QUERY
;
1184 mgmt
.u
.action
.u
.sa_query_req
.action
= WLAN_SA_QUERY_REQUEST
;
1185 os_memcpy(mgmt
.u
.action
.u
.sa_query_req
.trans_id
, trans_id
,
1186 WLAN_SA_QUERY_TR_ID_LEN
);
1187 end
= mgmt
.u
.action
.u
.sa_query_req
.trans_id
+ WLAN_SA_QUERY_TR_ID_LEN
;
1188 if (hapd
->drv
.send_mgmt_frame(hapd
, &mgmt
, end
- (u8
*) &mgmt
) < 0)
1189 perror("ieee802_11_send_sa_query_req: send");
1193 static void hostapd_sa_query_action(struct hostapd_data
*hapd
,
1194 const struct ieee80211_mgmt
*mgmt
,
1197 struct sta_info
*sta
;
1201 end
= mgmt
->u
.action
.u
.sa_query_resp
.trans_id
+
1202 WLAN_SA_QUERY_TR_ID_LEN
;
1203 if (((u8
*) mgmt
) + len
< end
) {
1204 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Too short SA Query Action "
1205 "frame (len=%lu)", (unsigned long) len
);
1209 if (mgmt
->u
.action
.u
.sa_query_resp
.action
!= WLAN_SA_QUERY_RESPONSE
) {
1210 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Unexpected SA Query "
1211 "Action %d", mgmt
->u
.action
.u
.sa_query_resp
.action
);
1215 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Received SA Query Response from "
1216 MACSTR
, MAC2STR(mgmt
->sa
));
1217 wpa_hexdump(MSG_DEBUG
, "IEEE 802.11: SA Query Transaction ID",
1218 mgmt
->u
.action
.u
.sa_query_resp
.trans_id
,
1219 WLAN_SA_QUERY_TR_ID_LEN
);
1221 /* MLME-SAQuery.confirm */
1223 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1224 if (sta
== NULL
|| sta
->sa_query_trans_id
== NULL
) {
1225 wpa_printf(MSG_DEBUG
, "IEEE 802.11: No matching STA with "
1226 "pending SA Query request found");
1230 for (i
= 0; i
< sta
->sa_query_count
; i
++) {
1231 if (os_memcmp(sta
->sa_query_trans_id
+
1232 i
* WLAN_SA_QUERY_TR_ID_LEN
,
1233 mgmt
->u
.action
.u
.sa_query_resp
.trans_id
,
1234 WLAN_SA_QUERY_TR_ID_LEN
) == 0)
1238 if (i
>= sta
->sa_query_count
) {
1239 wpa_printf(MSG_DEBUG
, "IEEE 802.11: No matching SA Query "
1240 "transaction identifier found");
1244 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1245 HOSTAPD_LEVEL_DEBUG
,
1246 "Reply to pending SA Query received");
1247 ap_sta_stop_sa_query(hapd
, sta
);
1251 static int robust_action_frame(u8 category
)
1253 return category
!= WLAN_ACTION_PUBLIC
&&
1254 category
!= WLAN_ACTION_HT
;
1256 #endif /* CONFIG_IEEE80211W */
1259 static void handle_action(struct hostapd_data
*hapd
,
1260 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1262 struct sta_info
*sta
;
1264 if (len
< IEEE80211_HDRLEN
+ 1) {
1265 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1266 HOSTAPD_LEVEL_DEBUG
,
1267 "handle_action - too short payload (len=%lu)",
1268 (unsigned long) len
);
1272 sta
= ap_get_sta(hapd
, mgmt
->sa
);
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 "
1283 #endif /* CONFIG_IEEE80211W */
1285 switch (mgmt
->u
.action
.category
) {
1286 #ifdef CONFIG_IEEE80211R
1287 case WLAN_ACTION_FT
:
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
,
1296 if (wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
1297 len
- IEEE80211_HDRLEN
))
1302 #endif /* CONFIG_IEEE80211R */
1303 case WLAN_ACTION_WMM
:
1304 hostapd_wmm_action(hapd
, mgmt
, len
);
1306 #ifdef CONFIG_IEEE80211W
1307 case WLAN_ACTION_SA_QUERY
:
1308 hostapd_sa_query_action(hapd
, mgmt
, len
);
1310 #endif /* CONFIG_IEEE80211W */
1313 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1314 HOSTAPD_LEVEL_DEBUG
,
1315 "handle_action - unknown action category %d or invalid "
1317 mgmt
->u
.action
.category
);
1318 if (!(mgmt
->da
[0] & 0x01) && !(mgmt
->u
.action
.category
& 0x80) &&
1319 !(mgmt
->sa
[0] & 0x01)) {
1320 struct ieee80211_mgmt
*resp
;
1323 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
1324 * Return the Action frame to the source without change
1325 * except that MSB of the Category set to 1.
1327 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
1328 "frame back to sender");
1329 resp
= os_malloc(len
);
1332 os_memcpy(resp
, mgmt
, len
);
1333 os_memcpy(resp
->da
, resp
->sa
, ETH_ALEN
);
1334 os_memcpy(resp
->sa
, hapd
->own_addr
, ETH_ALEN
);
1335 os_memcpy(resp
->bssid
, hapd
->own_addr
, ETH_ALEN
);
1336 resp
->u
.action
.category
|= 0x80;
1338 hapd
->drv
.send_mgmt_frame(hapd
, resp
, len
);
1345 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
1346 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
1348 * @buf: management frame data (starting from IEEE 802.11 header)
1349 * @len: length of frame data in octets
1350 * @fi: meta data about received frame (signal level, etc.)
1352 * Process all incoming IEEE 802.11 management frames. This will be called for
1353 * each frame received from the kernel driver through wlan#ap interface. In
1354 * addition, it can be called to re-inserted pending frames (e.g., when using
1355 * external RADIUS server as an MAC ACL).
1357 void ieee802_11_mgmt(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
1358 struct hostapd_frame_info
*fi
)
1360 struct ieee80211_mgmt
*mgmt
;
1364 mgmt
= (struct ieee80211_mgmt
*) buf
;
1365 fc
= le_to_host16(mgmt
->frame_control
);
1366 stype
= WLAN_FC_GET_STYPE(fc
);
1368 if (stype
== WLAN_FC_STYPE_BEACON
) {
1369 handle_beacon(hapd
, mgmt
, len
, fi
);
1373 broadcast
= mgmt
->bssid
[0] == 0xff && mgmt
->bssid
[1] == 0xff &&
1374 mgmt
->bssid
[2] == 0xff && mgmt
->bssid
[3] == 0xff &&
1375 mgmt
->bssid
[4] == 0xff && mgmt
->bssid
[5] == 0xff;
1378 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
1379 printf("MGMT: BSSID=" MACSTR
" not our address\n",
1380 MAC2STR(mgmt
->bssid
));
1385 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
1386 handle_probe_req(hapd
, mgmt
, len
);
1390 if (os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
1391 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1392 HOSTAPD_LEVEL_DEBUG
,
1393 "MGMT: DA=" MACSTR
" not our address",
1399 case WLAN_FC_STYPE_AUTH
:
1400 wpa_printf(MSG_DEBUG
, "mgmt::auth");
1401 handle_auth(hapd
, mgmt
, len
);
1403 case WLAN_FC_STYPE_ASSOC_REQ
:
1404 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
1405 handle_assoc(hapd
, mgmt
, len
, 0);
1407 case WLAN_FC_STYPE_REASSOC_REQ
:
1408 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
1409 handle_assoc(hapd
, mgmt
, len
, 1);
1411 case WLAN_FC_STYPE_DISASSOC
:
1412 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
1413 handle_disassoc(hapd
, mgmt
, len
);
1415 case WLAN_FC_STYPE_DEAUTH
:
1416 wpa_printf(MSG_DEBUG
, "mgmt::deauth");
1417 handle_deauth(hapd
, mgmt
, len
);
1419 case WLAN_FC_STYPE_ACTION
:
1420 wpa_printf(MSG_DEBUG
, "mgmt::action");
1421 handle_action(hapd
, mgmt
, len
);
1424 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1425 HOSTAPD_LEVEL_DEBUG
,
1426 "unknown mgmt frame subtype %d", stype
);
1432 static void handle_auth_cb(struct hostapd_data
*hapd
,
1433 const struct ieee80211_mgmt
*mgmt
,
1436 u16 auth_alg
, auth_transaction
, status_code
;
1437 struct sta_info
*sta
;
1440 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
1441 HOSTAPD_LEVEL_NOTICE
,
1442 "did not acknowledge authentication response");
1446 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
1447 printf("handle_auth_cb - too short payload (len=%lu)\n",
1448 (unsigned long) len
);
1452 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
1453 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
1454 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
1456 sta
= ap_get_sta(hapd
, mgmt
->da
);
1458 printf("handle_auth_cb: STA " MACSTR
" not found\n",
1463 if (status_code
== WLAN_STATUS_SUCCESS
&&
1464 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
1465 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
1466 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1467 HOSTAPD_LEVEL_INFO
, "authenticated");
1468 sta
->flags
|= WLAN_STA_AUTH
;
1473 static void handle_assoc_cb(struct hostapd_data
*hapd
,
1474 const struct ieee80211_mgmt
*mgmt
,
1475 size_t len
, int reassoc
, int ok
)
1478 struct sta_info
*sta
;
1480 struct ieee80211_ht_capabilities ht_cap
;
1483 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
1484 HOSTAPD_LEVEL_DEBUG
,
1485 "did not acknowledge association response");
1489 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
1490 sizeof(mgmt
->u
.assoc_resp
))) {
1491 printf("handle_assoc_cb(reassoc=%d) - too short payload "
1492 "(len=%lu)\n", reassoc
, (unsigned long) len
);
1497 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
1499 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
1501 sta
= ap_get_sta(hapd
, mgmt
->da
);
1503 printf("handle_assoc_cb: STA " MACSTR
" not found\n",
1508 if (status
!= WLAN_STATUS_SUCCESS
)
1511 /* Stop previous accounting session, if one is started, and allocate
1512 * new session id for the new session. */
1513 accounting_sta_stop(hapd
, sta
);
1515 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1517 "associated (aid %d)",
1520 if (sta
->flags
& WLAN_STA_ASSOC
)
1522 sta
->flags
|= WLAN_STA_ASSOC
;
1523 if (!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
) {
1524 /* Open or static WEP; no separate authorization */
1525 sta
->flags
|= WLAN_STA_AUTHORIZED
;
1526 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
1527 AP_STA_CONNECTED MACSTR
, MAC2STR(sta
->addr
));
1531 mlme_reassociate_indication(hapd
, sta
);
1533 mlme_associate_indication(hapd
, sta
);
1535 #ifdef CONFIG_IEEE80211W
1536 sta
->sa_query_timed_out
= 0;
1537 #endif /* CONFIG_IEEE80211W */
1540 * Remove the STA entry in order to make sure the STA PS state gets
1541 * cleared and configuration gets updated in case of reassociation back
1544 hapd
->drv
.sta_remove(hapd
, sta
->addr
);
1546 #ifdef CONFIG_IEEE80211N
1547 if (sta
->flags
& WLAN_STA_HT
)
1548 hostapd_get_ht_capab(hapd
, sta
->ht_capabilities
, &ht_cap
);
1549 #endif /* CONFIG_IEEE80211N */
1551 if (hapd
->drv
.sta_add(hapd
->conf
->iface
, hapd
, sta
->addr
, sta
->aid
,
1552 sta
->capability
, sta
->supported_rates
,
1553 sta
->supported_rates_len
, sta
->listen_interval
,
1554 sta
->flags
& WLAN_STA_HT
? &ht_cap
: NULL
)) {
1555 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1556 HOSTAPD_LEVEL_NOTICE
,
1557 "Could not add STA to kernel driver");
1560 if (sta
->eapol_sm
== NULL
) {
1562 * This STA does not use RADIUS server for EAP authentication,
1563 * so bind it to the selected VLAN interface now, since the
1564 * interface selection is not going to change anymore.
1566 ap_sta_bind_vlan(hapd
, sta
, 0);
1567 } else if (sta
->vlan_id
) {
1568 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
1569 ap_sta_bind_vlan(hapd
, sta
, 0);
1572 hapd
->drv
.set_sta_flags(hapd
, sta
);
1574 if (sta
->auth_alg
== WLAN_AUTH_FT
)
1575 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
1577 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
1578 hapd
->new_assoc_sta_cb(hapd
, sta
, !new_assoc
);
1580 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
1583 /* Copy of the association request is not needed anymore */
1584 if (sta
->last_assoc_req
) {
1585 os_free(sta
->last_assoc_req
);
1586 sta
->last_assoc_req
= NULL
;
1592 * ieee802_11_mgmt_cb - Process management frame TX status callback
1593 * @hapd: hostapd BSS data structure (the BSS from which the management frame
1595 * @buf: management frame data (starting from IEEE 802.11 header)
1596 * @len: length of frame data in octets
1597 * @stype: management frame subtype from frame control field
1598 * @ok: Whether the frame was ACK'ed
1600 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
1603 const struct ieee80211_mgmt
*mgmt
;
1604 mgmt
= (const struct ieee80211_mgmt
*) buf
;
1607 case WLAN_FC_STYPE_AUTH
:
1608 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
1609 handle_auth_cb(hapd
, mgmt
, len
, ok
);
1611 case WLAN_FC_STYPE_ASSOC_RESP
:
1612 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
1613 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
1615 case WLAN_FC_STYPE_REASSOC_RESP
:
1616 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
1617 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
1619 case WLAN_FC_STYPE_PROBE_RESP
:
1620 wpa_printf(MSG_DEBUG
, "mgmt::proberesp cb");
1622 case WLAN_FC_STYPE_DEAUTH
:
1625 case WLAN_FC_STYPE_ACTION
:
1626 wpa_printf(MSG_DEBUG
, "mgmt::action cb");
1629 printf("unknown mgmt cb frame subtype %d\n", stype
);
1635 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
1642 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1643 char *buf
, size_t buflen
)
1650 void hostapd_tx_status(struct hostapd_data
*hapd
, const u8
*addr
,
1651 const u8
*buf
, size_t len
, int ack
)
1653 struct sta_info
*sta
;
1654 struct hostapd_iface
*iface
= hapd
->iface
;
1656 sta
= ap_get_sta(hapd
, addr
);
1657 if (sta
== NULL
&& iface
->num_bss
> 1) {
1659 for (j
= 0; j
< iface
->num_bss
; j
++) {
1660 hapd
= iface
->bss
[j
];
1661 sta
= ap_get_sta(hapd
, addr
);
1668 if (sta
->flags
& WLAN_STA_PENDING_POLL
) {
1669 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" %s pending "
1670 "activity poll", MAC2STR(sta
->addr
),
1671 ack
? "ACKed" : "did not ACK");
1673 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
1676 ieee802_1x_tx_status(hapd
, sta
, buf
, len
, ack
);
1680 void ieee802_11_rx_from_unknown(struct hostapd_data
*hapd
, const u8
*src
,
1683 struct sta_info
*sta
;
1685 sta
= ap_get_sta(hapd
, src
);
1686 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC
)) {
1687 if (wds
&& !(sta
->flags
& WLAN_STA_WDS
)) {
1688 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for "
1689 "STA " MACSTR
" (aid %u)",
1690 MAC2STR(sta
->addr
), sta
->aid
);
1691 sta
->flags
|= WLAN_STA_WDS
;
1692 hapd
->drv
.set_wds_sta(hapd
, sta
->addr
, sta
->aid
, 1);
1697 wpa_printf(MSG_DEBUG
, "Data/PS-poll frame from not associated STA "
1698 MACSTR
, MAC2STR(src
));
1699 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
))
1700 hapd
->drv
.sta_disassoc(
1702 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
1704 hapd
->drv
.sta_deauth(
1706 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
1710 #endif /* CONFIG_NATIVE_WINDOWS */