2 * hostapd / IEEE 802.11 Management
3 * Copyright (c) 2002-2006, 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.
17 #ifndef CONFIG_NATIVE_WINDOWS
23 #include "ieee802_11.h"
25 #include "hw_features.h"
27 #include "radius_client.h"
28 #include "ieee802_11_auth.h"
32 #include "ieee802_1x.h"
36 #include "accounting.h"
38 #include "ieee802_11h.h"
42 u8
* hostapd_eid_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
47 if (hapd
->iface
->current_rates
== NULL
)
50 *pos
++ = WLAN_EID_SUPP_RATES
;
51 num
= hapd
->iface
->num_rates
;
53 /* rest of the rates are encoded in Extended supported
60 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
;
63 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
64 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
73 u8
* hostapd_eid_ext_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
78 if (hapd
->iface
->current_rates
== NULL
)
81 num
= hapd
->iface
->num_rates
;
86 *pos
++ = WLAN_EID_EXT_SUPP_RATES
;
89 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
+ 8;
93 continue; /* already in SuppRates IE */
94 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
95 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
104 u16
hostapd_own_capab_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
107 int capab
= WLAN_CAPABILITY_ESS
;
110 if (hapd
->iface
->num_sta_no_short_preamble
== 0 &&
111 hapd
->iconf
->preamble
== SHORT_PREAMBLE
)
112 capab
|= WLAN_CAPABILITY_SHORT_PREAMBLE
;
114 privacy
= hapd
->conf
->ssid
.wep
.keys_set
;
116 if (hapd
->conf
->ieee802_1x
&&
117 (hapd
->conf
->default_wep_key_len
||
118 hapd
->conf
->individual_wep_key_len
))
125 int policy
, def_klen
;
126 if (probe
&& sta
->ssid_probe
) {
127 policy
= sta
->ssid_probe
->security_policy
;
128 def_klen
= sta
->ssid_probe
->wep
.default_len
;
130 policy
= sta
->ssid
->security_policy
;
131 def_klen
= sta
->ssid
->wep
.default_len
;
133 privacy
= policy
!= SECURITY_PLAINTEXT
;
134 if (policy
== SECURITY_IEEE_802_1X
&& def_klen
== 0)
139 capab
|= WLAN_CAPABILITY_PRIVACY
;
141 if (hapd
->iface
&& hapd
->iface
->current_mode
&&
142 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
143 hapd
->iface
->num_sta_no_short_slot_time
== 0)
144 capab
|= WLAN_CAPABILITY_SHORT_SLOT_TIME
;
146 if (hapd
->iface
->dfs_enable
)
147 capab
|= WLAN_CAPABILITY_SPECTRUM_MGMT
;
153 #define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs)
156 static int ieee802_11_parse_vendor_specific(struct hostapd_data
*hapd
,
157 u8
*pos
, size_t elen
,
158 struct ieee802_11_elems
*elems
,
163 /* first 3 bytes in vendor specific information element are the IEEE
164 * OUI of the vendor. The following byte is used a vendor specific
168 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MSGDUMPS
, "short vendor "
169 "specific information element ignored "
170 "(len=%lu)\n", (unsigned long) elen
);
175 oui
= (pos
[0] << 16) | (pos
[1] << 8) | pos
[2];
178 /* Microsoft/Wi-Fi information elements are further typed and
182 /* Microsoft OUI (00:50:F2) with OUI Type 1:
183 * real WPA information element */
185 elems
->wpa_ie_len
= elen
;
187 case WME_OUI_TYPE
: /* this is a Wi-Fi WME info. element */
189 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MSGDUMPS
,
190 "short WME information element "
191 "ignored (len=%lu)\n",
192 (unsigned long) elen
);
196 case WME_OUI_SUBTYPE_INFORMATION_ELEMENT
:
197 case WME_OUI_SUBTYPE_PARAMETER_ELEMENT
:
199 elems
->wme_len
= elen
;
201 case WME_OUI_SUBTYPE_TSPEC_ELEMENT
:
202 elems
->wme_tspec
= pos
;
203 elems
->wme_tspec_len
= elen
;
206 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MSGDUMPS
,
207 "unknown WME information element"
208 " ignored (subtype=%d "
210 pos
[4], (unsigned long) elen
);
215 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MSGDUMPS
,
216 "Unknown Microsoft information element "
217 "ignored (type=%d len=%lu)\n",
218 pos
[3], (unsigned long) elen
);
224 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MSGDUMPS
,
225 "unknown vendor specific information element "
226 "ignored (vendor OUI %02x:%02x:%02x len=%lu)\n",
227 pos
[0], pos
[1], pos
[2], (unsigned long) elen
);
235 ParseRes
ieee802_11_parse_elems(struct hostapd_data
*hapd
, u8
*start
,
237 struct ieee802_11_elems
*elems
,
244 memset(elems
, 0, sizeof(*elems
));
255 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
256 "IEEE 802.11 element parse "
257 "failed (id=%d elen=%d "
259 id
, elen
, (unsigned long) left
);
260 wpa_hexdump(MSG_MSGDUMP
, "IEs", start
, len
);
268 elems
->ssid_len
= elen
;
270 case WLAN_EID_SUPP_RATES
:
271 elems
->supp_rates
= pos
;
272 elems
->supp_rates_len
= elen
;
274 case WLAN_EID_FH_PARAMS
:
275 elems
->fh_params
= pos
;
276 elems
->fh_params_len
= elen
;
278 case WLAN_EID_DS_PARAMS
:
279 elems
->ds_params
= pos
;
280 elems
->ds_params_len
= elen
;
282 case WLAN_EID_CF_PARAMS
:
283 elems
->cf_params
= pos
;
284 elems
->cf_params_len
= elen
;
288 elems
->tim_len
= elen
;
290 case WLAN_EID_IBSS_PARAMS
:
291 elems
->ibss_params
= pos
;
292 elems
->ibss_params_len
= elen
;
294 case WLAN_EID_CHALLENGE
:
295 elems
->challenge
= pos
;
296 elems
->challenge_len
= elen
;
298 case WLAN_EID_ERP_INFO
:
299 elems
->erp_info
= pos
;
300 elems
->erp_info_len
= elen
;
302 case WLAN_EID_EXT_SUPP_RATES
:
303 elems
->ext_supp_rates
= pos
;
304 elems
->ext_supp_rates_len
= elen
;
306 case WLAN_EID_VENDOR_SPECIFIC
:
307 if (ieee802_11_parse_vendor_specific(hapd
, pos
, elen
,
314 elems
->rsn_ie_len
= elen
;
316 case WLAN_EID_PWR_CAPABILITY
:
317 elems
->power_cap
= pos
;
318 elems
->power_cap_len
= elen
;
320 case WLAN_EID_SUPPORTED_CHANNELS
:
321 elems
->supp_channels
= pos
;
322 elems
->supp_channels_len
= elen
;
328 HOSTAPD_DEBUG(HOSTAPD_DEBUG_EXCESSIVE
,
329 "IEEE 802.11 element parse ignored "
330 "unknown element (id=%d elen=%d)\n",
342 return unknown
? ParseUnknown
: ParseOK
;
346 void ieee802_11_print_ssid(const u8
*ssid
, u8 len
)
349 for (i
= 0; i
< len
; i
++) {
350 if (ssid
[i
] >= 32 && ssid
[i
] < 127)
351 printf("%c", ssid
[i
]);
353 printf("<%02x>", ssid
[i
]);
358 void ieee802_11_send_deauth(struct hostapd_data
*hapd
, u8
*addr
, u16 reason
)
360 struct ieee80211_mgmt mgmt
;
363 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE80211
,
365 "deauthenticate - reason %d", reason
);
366 snprintf(buf
, sizeof(buf
), "SEND-DEAUTHENTICATE %d", reason
);
367 memset(&mgmt
, 0, sizeof(mgmt
));
368 mgmt
.frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
369 WLAN_FC_STYPE_DEAUTH
);
370 memcpy(mgmt
.da
, addr
, ETH_ALEN
);
371 memcpy(mgmt
.sa
, hapd
->own_addr
, ETH_ALEN
);
372 memcpy(mgmt
.bssid
, hapd
->own_addr
, ETH_ALEN
);
373 mgmt
.u
.deauth
.reason_code
= host_to_le16(reason
);
374 if (hostapd_send_mgmt_frame(hapd
, &mgmt
, IEEE80211_HDRLEN
+
375 sizeof(mgmt
.u
.deauth
), 0) < 0)
376 perror("ieee802_11_send_deauth: send");
380 static void ieee802_11_sta_authenticate(void *eloop_ctx
, void *timeout_ctx
)
382 struct hostapd_data
*hapd
= eloop_ctx
;
383 struct ieee80211_mgmt mgmt
;
385 if (hapd
->assoc_ap_state
== WAIT_BEACON
)
386 hapd
->assoc_ap_state
= AUTHENTICATE
;
387 if (hapd
->assoc_ap_state
!= AUTHENTICATE
)
390 printf("Authenticate with AP " MACSTR
" SSID=",
391 MAC2STR(hapd
->conf
->assoc_ap_addr
));
392 ieee802_11_print_ssid((u8
*) hapd
->assoc_ap_ssid
,
393 hapd
->assoc_ap_ssid_len
);
394 printf(" (as station)\n");
396 memset(&mgmt
, 0, sizeof(mgmt
));
397 mgmt
.frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
399 /* Request TX callback */
400 mgmt
.frame_control
|= host_to_le16(BIT(1));
401 memcpy(mgmt
.da
, hapd
->conf
->assoc_ap_addr
, ETH_ALEN
);
402 memcpy(mgmt
.sa
, hapd
->own_addr
, ETH_ALEN
);
403 memcpy(mgmt
.bssid
, hapd
->conf
->assoc_ap_addr
, ETH_ALEN
);
404 mgmt
.u
.auth
.auth_alg
= host_to_le16(WLAN_AUTH_OPEN
);
405 mgmt
.u
.auth
.auth_transaction
= host_to_le16(1);
406 mgmt
.u
.auth
.status_code
= host_to_le16(0);
407 if (hostapd_send_mgmt_frame(hapd
, &mgmt
, IEEE80211_HDRLEN
+
408 sizeof(mgmt
.u
.auth
), 0) < 0)
409 perror("ieee802_11_sta_authenticate: send");
411 /* Try to authenticate again, if this attempt fails or times out. */
412 eloop_register_timeout(5, 0, ieee802_11_sta_authenticate
, hapd
, NULL
);
416 static void ieee802_11_sta_associate(void *eloop_ctx
, void *timeout_ctx
)
418 struct hostapd_data
*hapd
= eloop_ctx
;
420 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) buf
;
423 if (hapd
->assoc_ap_state
== AUTHENTICATE
)
424 hapd
->assoc_ap_state
= ASSOCIATE
;
425 if (hapd
->assoc_ap_state
!= ASSOCIATE
)
428 printf("Associate with AP " MACSTR
" SSID=",
429 MAC2STR(hapd
->conf
->assoc_ap_addr
));
430 ieee802_11_print_ssid((u8
*) hapd
->assoc_ap_ssid
,
431 hapd
->assoc_ap_ssid_len
);
432 printf(" (as station)\n");
434 memset(mgmt
, 0, sizeof(*mgmt
));
435 mgmt
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
436 WLAN_FC_STYPE_ASSOC_REQ
);
437 /* Request TX callback */
438 mgmt
->frame_control
|= host_to_le16(BIT(1));
439 memcpy(mgmt
->da
, hapd
->conf
->assoc_ap_addr
, ETH_ALEN
);
440 memcpy(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
);
441 memcpy(mgmt
->bssid
, hapd
->conf
->assoc_ap_addr
, ETH_ALEN
);
442 mgmt
->u
.assoc_req
.capab_info
= host_to_le16(0);
443 mgmt
->u
.assoc_req
.listen_interval
= host_to_le16(1);
444 p
= &mgmt
->u
.assoc_req
.variable
[0];
446 *p
++ = WLAN_EID_SSID
;
447 *p
++ = hapd
->assoc_ap_ssid_len
;
448 memcpy(p
, hapd
->assoc_ap_ssid
, hapd
->assoc_ap_ssid_len
);
449 p
+= hapd
->assoc_ap_ssid_len
;
451 p
= hostapd_eid_supp_rates(hapd
, p
);
452 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
454 if (hostapd_send_mgmt_frame(hapd
, mgmt
, p
- (u8
*) mgmt
, 0) < 0)
455 perror("ieee802_11_sta_associate: send");
457 /* Try to authenticate again, if this attempt fails or times out. */
458 eloop_register_timeout(5, 0, ieee802_11_sta_associate
, hapd
, NULL
);
462 static u16
auth_shared_key(struct hostapd_data
*hapd
, struct sta_info
*sta
,
463 u16 auth_transaction
, u8
*challenge
, int iswep
)
465 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
467 "authentication (shared key, transaction %d)",
470 if (auth_transaction
== 1) {
471 if (!sta
->challenge
) {
472 /* Generate a pseudo-random challenge */
476 sta
->challenge
= wpa_zalloc(WLAN_AUTH_CHALLENGE_LEN
);
477 if (sta
->challenge
== NULL
)
478 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
482 memcpy(key
, &now
, 4);
483 memcpy(key
+ 4, &r
, 4);
484 rc4(sta
->challenge
, WLAN_AUTH_CHALLENGE_LEN
,
490 if (auth_transaction
!= 3)
491 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
494 if (!iswep
|| !sta
->challenge
|| !challenge
||
495 memcmp(sta
->challenge
, challenge
, WLAN_AUTH_CHALLENGE_LEN
)) {
496 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
498 "shared key authentication - invalid "
499 "challenge-response");
500 return WLAN_STATUS_CHALLENGE_FAIL
;
503 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
505 "authentication OK (shared key)");
506 #ifdef IEEE80211_REQUIRE_AUTH_ACK
507 /* Station will be marked authenticated if it ACKs the
508 * authentication reply. */
510 sta
->flags
|= WLAN_STA_AUTH
;
511 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
513 free(sta
->challenge
);
514 sta
->challenge
= NULL
;
520 static void send_auth_reply(struct hostapd_data
*hapd
,
521 struct ieee80211_mgmt
*mgmt
,
522 u16 auth_alg
, u16 auth_transaction
, u16 resp
,
525 u8 buf
[IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) + 2 +
526 WLAN_AUTH_CHALLENGE_LEN
];
527 struct ieee80211_mgmt
*reply
;
530 memset(buf
, 0, sizeof(buf
));
531 reply
= (struct ieee80211_mgmt
*) buf
;
532 reply
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
534 /* Request TX callback */
535 reply
->frame_control
|= host_to_le16(BIT(1));
536 memcpy(reply
->da
, mgmt
->sa
, ETH_ALEN
);
537 memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
538 memcpy(reply
->bssid
, mgmt
->bssid
, ETH_ALEN
);
540 reply
->u
.auth
.auth_alg
= host_to_le16(auth_alg
);
541 reply
->u
.auth
.auth_transaction
= host_to_le16(auth_transaction
);
542 reply
->u
.auth
.status_code
= host_to_le16(resp
);
543 rlen
= IEEE80211_HDRLEN
+ sizeof(reply
->u
.auth
);
544 if (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 2 &&
546 u8
*p
= reply
->u
.auth
.variable
;
547 *p
++ = WLAN_EID_CHALLENGE
;
548 *p
++ = WLAN_AUTH_CHALLENGE_LEN
;
549 memcpy(p
, challenge
, WLAN_AUTH_CHALLENGE_LEN
);
550 rlen
+= 2 + WLAN_AUTH_CHALLENGE_LEN
;
554 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
555 "authentication reply: STA=" MACSTR
" auth_alg=%d "
556 "auth_transaction=%d resp=%d%s\n",
557 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
558 resp
, challenge
? " challenge" : "");
559 if (hostapd_send_mgmt_frame(hapd
, reply
, rlen
, 0) < 0)
560 perror("send_auth_reply: send");
564 static void handle_auth(struct hostapd_data
*hapd
, struct ieee80211_mgmt
*mgmt
,
567 u16 auth_alg
, auth_transaction
, status_code
;
568 u16 resp
= WLAN_STATUS_SUCCESS
;
569 struct sta_info
*sta
= NULL
;
572 u8
*challenge
= NULL
;
573 u32 session_timeout
, acct_interim_interval
;
576 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
577 printf("handle_auth - too short payload (len=%lu)\n",
578 (unsigned long) len
);
582 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
583 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
584 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
585 fc
= le_to_host16(mgmt
->frame_control
);
587 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
588 2 + WLAN_AUTH_CHALLENGE_LEN
&&
589 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
590 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
591 challenge
= &mgmt
->u
.auth
.variable
[2];
593 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
594 "authentication: STA=" MACSTR
" auth_alg=%d "
595 "auth_transaction=%d status_code=%d wep=%d%s\n",
596 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
597 status_code
, !!(fc
& WLAN_FC_ISWEP
),
598 challenge
? " challenge" : "");
600 if (hapd
->assoc_ap_state
== AUTHENTICATE
&& auth_transaction
== 2 &&
601 memcmp(mgmt
->sa
, hapd
->conf
->assoc_ap_addr
, ETH_ALEN
) == 0 &&
602 memcmp(mgmt
->bssid
, hapd
->conf
->assoc_ap_addr
, ETH_ALEN
) == 0) {
603 if (status_code
!= 0) {
604 printf("Authentication (as station) with AP "
605 MACSTR
" failed (status_code=%d)\n",
606 MAC2STR(hapd
->conf
->assoc_ap_addr
),
610 printf("Authenticated (as station) with AP " MACSTR
"\n",
611 MAC2STR(hapd
->conf
->assoc_ap_addr
));
612 ieee802_11_sta_associate(hapd
, NULL
);
616 if (hapd
->tkip_countermeasures
) {
617 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
621 if (!(((hapd
->conf
->auth_algs
& HOSTAPD_AUTH_OPEN
) &&
622 auth_alg
== WLAN_AUTH_OPEN
) ||
623 ((hapd
->conf
->auth_algs
& HOSTAPD_AUTH_SHARED_KEY
) &&
624 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
625 printf("Unsupported authentication algorithm (%d)\n",
627 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
631 if (!(auth_transaction
== 1 ||
632 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
633 printf("Unknown authentication transaction number (%d)\n",
635 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
639 if (memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
640 printf("Station " MACSTR
" not allowed to authenticate.\n",
642 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
646 res
= hostapd_allowed_address(hapd
, mgmt
->sa
, (u8
*) mgmt
, len
,
648 &acct_interim_interval
, &vlan_id
);
649 if (res
== HOSTAPD_ACL_REJECT
) {
650 printf("Station " MACSTR
" not allowed to authenticate.\n",
652 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
655 if (res
== HOSTAPD_ACL_PENDING
) {
656 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "Authentication frame "
657 "from " MACSTR
" waiting for an external "
658 "authentication\n", MAC2STR(mgmt
->sa
));
659 /* Authentication code will re-send the authentication frame
660 * after it has received (and cached) information from the
661 * external source. */
665 sta
= ap_sta_add(hapd
, mgmt
->sa
);
667 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
672 if (hostapd_get_vlan_id_ifname(hapd
->conf
->vlan
,
673 sta
->vlan_id
) == NULL
) {
674 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
675 HOSTAPD_LEVEL_INFO
, "Invalid VLAN ID "
676 "%d received from RADIUS server",
678 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
681 sta
->vlan_id
= vlan_id
;
682 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
683 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
686 sta
->flags
&= ~WLAN_STA_PREAUTH
;
687 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
689 if (hapd
->conf
->radius
->acct_interim_interval
== 0 &&
690 acct_interim_interval
)
691 sta
->acct_interim_interval
= acct_interim_interval
;
692 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
)
693 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
695 ap_sta_no_session_timeout(hapd
, sta
);
699 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
701 "authentication OK (open system)");
702 #ifdef IEEE80211_REQUIRE_AUTH_ACK
703 /* Station will be marked authenticated if it ACKs the
704 * authentication reply. */
706 sta
->flags
|= WLAN_STA_AUTH
;
707 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
708 sta
->auth_alg
= WLAN_AUTH_OPEN
;
709 mlme_authenticate_indication(hapd
, sta
);
712 case WLAN_AUTH_SHARED_KEY
:
713 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
715 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
716 mlme_authenticate_indication(hapd
, sta
);
721 send_auth_reply(hapd
, mgmt
, auth_alg
, auth_transaction
+ 1, resp
,
722 sta
? sta
->challenge
: NULL
);
726 static void handle_assoc(struct hostapd_data
*hapd
,
727 struct ieee80211_mgmt
*mgmt
, size_t len
, int reassoc
)
729 u16 capab_info
, listen_interval
;
730 u16 resp
= WLAN_STATUS_SUCCESS
;
733 int send_deauth
= 0, send_len
, left
, i
;
734 struct sta_info
*sta
;
735 struct ieee802_11_elems elems
;
737 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
738 sizeof(mgmt
->u
.assoc_req
))) {
739 printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
740 "\n", reassoc
, (unsigned long) len
);
745 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
746 listen_interval
= le_to_host16(
747 mgmt
->u
.reassoc_req
.listen_interval
);
748 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
749 "reassociation request: STA=" MACSTR
750 " capab_info=0x%02x "
751 "listen_interval=%d current_ap=" MACSTR
"\n",
752 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
753 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
));
754 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
755 pos
= mgmt
->u
.reassoc_req
.variable
;
757 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
758 listen_interval
= le_to_host16(
759 mgmt
->u
.assoc_req
.listen_interval
);
760 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
761 "association request: STA=" MACSTR
762 " capab_info=0x%02x listen_interval=%d\n",
763 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
);
764 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
765 pos
= mgmt
->u
.assoc_req
.variable
;
768 sta
= ap_get_sta(hapd
, mgmt
->sa
);
769 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
770 printf("STA " MACSTR
" trying to associate before "
771 "authentication\n", MAC2STR(mgmt
->sa
));
773 printf(" sta: addr=" MACSTR
" aid=%d flags=0x%04x\n",
774 MAC2STR(sta
->addr
), sta
->aid
, sta
->flags
);
777 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
781 if (hapd
->tkip_countermeasures
) {
782 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
787 memcpy(sta
->previous_ap
, mgmt
->u
.reassoc_req
.current_ap
,
791 sta
->capability
= capab_info
;
793 /* followed by SSID and Supported rates */
794 if (ieee802_11_parse_elems(hapd
, pos
, left
, &elems
, 1) == ParseFailed
796 printf("STA " MACSTR
" sent invalid association request\n",
798 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
802 if (elems
.ssid_len
!= hapd
->conf
->ssid
.ssid_len
||
803 memcmp(elems
.ssid
, hapd
->conf
->ssid
.ssid
, elems
.ssid_len
) != 0) {
804 printf("Station " MACSTR
" tried to associate with "
805 "unknown SSID '", MAC2STR(sta
->addr
));
806 ieee802_11_print_ssid(elems
.ssid
, elems
.ssid_len
);
808 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
812 sta
->flags
&= ~WLAN_STA_WME
;
813 if (elems
.wme
&& hapd
->conf
->wme_enabled
) {
814 if (hostapd_eid_wme_valid(hapd
, elems
.wme
, elems
.wme_len
))
815 hostapd_logger(hapd
, sta
->addr
,
818 "invalid WME element in association "
821 sta
->flags
|= WLAN_STA_WME
;
824 if (!elems
.supp_rates
) {
825 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
827 "No supported rates element in AssocReq");
828 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
832 if (elems
.supp_rates_len
> sizeof(sta
->supported_rates
)) {
833 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
835 "Invalid supported rates element length %d",
836 elems
.supp_rates_len
);
837 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
841 memset(sta
->supported_rates
, 0, sizeof(sta
->supported_rates
));
842 memcpy(sta
->supported_rates
, elems
.supp_rates
, elems
.supp_rates_len
);
843 sta
->supported_rates_len
= elems
.supp_rates_len
;
845 if (elems
.ext_supp_rates
) {
846 if (elems
.supp_rates_len
+ elems
.ext_supp_rates_len
>
847 sizeof(sta
->supported_rates
)) {
848 hostapd_logger(hapd
, mgmt
->sa
,
849 HOSTAPD_MODULE_IEEE80211
,
851 "Invalid supported rates element length"
852 " %d+%d", elems
.supp_rates_len
,
853 elems
.ext_supp_rates_len
);
854 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
858 memcpy(sta
->supported_rates
+ elems
.supp_rates_len
,
859 elems
.ext_supp_rates
, elems
.ext_supp_rates_len
);
860 sta
->supported_rates_len
+= elems
.ext_supp_rates_len
;
863 if ((hapd
->conf
->wpa
& HOSTAPD_WPA_VERSION_WPA2
) && elems
.rsn_ie
) {
864 wpa_ie
= elems
.rsn_ie
;
865 wpa_ie_len
= elems
.rsn_ie_len
;
866 } else if ((hapd
->conf
->wpa
& HOSTAPD_WPA_VERSION_WPA
) &&
868 wpa_ie
= elems
.wpa_ie
;
869 wpa_ie_len
= elems
.wpa_ie_len
;
874 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
875 printf("STA " MACSTR
": No WPA/RSN IE in association "
876 "request\n", MAC2STR(sta
->addr
));
877 resp
= WLAN_STATUS_INVALID_IE
;
881 if (hapd
->conf
->wpa
) {
885 if (sta
->wpa_sm
== NULL
)
886 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
888 if (sta
->wpa_sm
== NULL
) {
889 printf("Failed to initialize WPA state machine\n");
890 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
893 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
895 if (res
== WPA_INVALID_GROUP
)
896 resp
= WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
897 else if (res
== WPA_INVALID_PAIRWISE
)
898 resp
= WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
899 else if (res
== WPA_INVALID_AKMP
)
900 resp
= WLAN_STATUS_AKMP_NOT_VALID
;
901 else if (res
== WPA_ALLOC_FAIL
)
902 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
903 #ifdef CONFIG_IEEE80211W
904 else if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
905 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
; /* FIX */
906 else if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
907 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
; /* FIX */
908 #endif /* CONFIG_IEEE80211W */
909 else if (res
!= WPA_IE_OK
)
910 resp
= WLAN_STATUS_INVALID_IE
;
911 if (resp
!= WLAN_STATUS_SUCCESS
)
915 if (hapd
->iface
->dfs_enable
&&
916 hapd
->iconf
->ieee80211h
== SPECT_STRICT_BINDING
) {
917 if (hostapd_check_power_cap(hapd
, elems
.power_cap
,
918 elems
.power_cap_len
)) {
919 resp
= WLAN_STATUS_PWR_CAPABILITY_NOT_VALID
;
920 hostapd_logger(hapd
, sta
->addr
,
921 HOSTAPD_MODULE_IEEE80211
,
923 "Power capabilities of the station not "
929 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
930 sta
->flags
|= WLAN_STA_NONERP
;
931 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
932 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
933 sta
->flags
&= ~WLAN_STA_NONERP
;
937 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
939 hapd
->iface
->num_sta_non_erp
++;
940 if (hapd
->iface
->num_sta_non_erp
== 1)
941 ieee802_11_set_beacons(hapd
->iface
);
944 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
945 !sta
->no_short_slot_time_set
) {
946 sta
->no_short_slot_time_set
= 1;
947 hapd
->iface
->num_sta_no_short_slot_time
++;
948 if (hapd
->iface
->current_mode
->mode
==
949 HOSTAPD_MODE_IEEE80211G
&&
950 hapd
->iface
->num_sta_no_short_slot_time
== 1)
951 ieee802_11_set_beacons(hapd
->iface
);
954 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
955 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
957 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
959 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
960 !sta
->no_short_preamble_set
) {
961 sta
->no_short_preamble_set
= 1;
962 hapd
->iface
->num_sta_no_short_preamble
++;
963 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
964 && hapd
->iface
->num_sta_no_short_preamble
== 1)
965 ieee802_11_set_beacons(hapd
->iface
);
968 /* get a unique AID */
970 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
971 " old AID %d\n", sta
->aid
);
973 for (sta
->aid
= 1; sta
->aid
<= MAX_AID_TABLE_SIZE
; sta
->aid
++)
974 if (hapd
->sta_aid
[sta
->aid
- 1] == NULL
)
976 if (sta
->aid
> MAX_AID_TABLE_SIZE
) {
978 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
979 printf(" no room for more AIDs\n");
982 hapd
->sta_aid
[sta
->aid
- 1] = sta
;
983 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
984 " new AID %d\n", sta
->aid
);
988 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
990 "association OK (aid %d)", sta
->aid
);
991 /* Station will be marked associated, after it acknowledges AssocResp
994 if (sta
->last_assoc_req
)
995 free(sta
->last_assoc_req
);
996 sta
->last_assoc_req
= (struct ieee80211_mgmt
*) malloc(len
);
997 if (sta
->last_assoc_req
)
998 memcpy(sta
->last_assoc_req
, mgmt
, len
);
1000 /* Make sure that the previously registered inactivity timer will not
1001 * remove the STA immediately. */
1002 sta
->timeout_next
= STA_NULLFUNC
;
1006 /* use the queued buffer for transmission because it is large enough
1007 * and not needed anymore */
1008 mgmt
->frame_control
=
1009 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
1010 (send_deauth
? WLAN_FC_STYPE_DEAUTH
:
1011 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
1012 WLAN_FC_STYPE_ASSOC_RESP
)));
1013 memcpy(mgmt
->da
, mgmt
->sa
, ETH_ALEN
);
1014 memcpy(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
);
1015 /* Addr3 = BSSID - already set */
1017 send_len
= IEEE80211_HDRLEN
;
1019 send_len
+= sizeof(mgmt
->u
.deauth
);
1020 mgmt
->u
.deauth
.reason_code
= host_to_le16(resp
);
1023 send_len
+= sizeof(mgmt
->u
.assoc_resp
);
1024 mgmt
->u
.assoc_resp
.capab_info
=
1025 host_to_le16(hostapd_own_capab_info(hapd
, sta
, 0));
1026 mgmt
->u
.assoc_resp
.status_code
= host_to_le16(resp
);
1027 mgmt
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0)
1028 | BIT(14) | BIT(15));
1029 /* Supported rates */
1030 p
= hostapd_eid_supp_rates(hapd
, mgmt
->u
.assoc_resp
.variable
);
1031 /* Extended supported rates */
1032 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
1033 if (sta
->flags
& WLAN_STA_WME
)
1034 p
= hostapd_eid_wme(hapd
, p
);
1035 send_len
+= p
- mgmt
->u
.assoc_resp
.variable
;
1037 /* Request TX callback */
1038 mgmt
->frame_control
|= host_to_le16(BIT(1));
1041 if (hostapd_send_mgmt_frame(hapd
, mgmt
, send_len
, 0) < 0)
1042 perror("handle_assoc: send");
1046 static void handle_assoc_resp(struct hostapd_data
*hapd
,
1047 struct ieee80211_mgmt
*mgmt
, size_t len
)
1049 u16 status_code
, aid
;
1051 if (hapd
->assoc_ap_state
!= ASSOCIATE
) {
1052 printf("Unexpected association response received from " MACSTR
1053 "\n", MAC2STR(mgmt
->sa
));
1057 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_resp
)) {
1058 printf("handle_assoc_resp - too short payload (len=%lu)\n",
1059 (unsigned long) len
);
1063 if (memcmp(mgmt
->sa
, hapd
->conf
->assoc_ap_addr
, ETH_ALEN
) != 0 ||
1064 memcmp(mgmt
->bssid
, hapd
->conf
->assoc_ap_addr
, ETH_ALEN
) != 0) {
1065 printf("Received association response from unexpected address "
1066 "(SA=" MACSTR
" BSSID=" MACSTR
"\n",
1067 MAC2STR(mgmt
->sa
), MAC2STR(mgmt
->bssid
));
1071 status_code
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
1072 aid
= le_to_host16(mgmt
->u
.assoc_resp
.aid
);
1073 aid
&= ~(BIT(14) | BIT(15));
1075 if (status_code
!= 0) {
1076 printf("Association (as station) with AP " MACSTR
" failed "
1077 "(status_code=%d)\n",
1078 MAC2STR(hapd
->conf
->assoc_ap_addr
), status_code
);
1079 /* Try to authenticate again */
1080 hapd
->assoc_ap_state
= AUTHENTICATE
;
1081 eloop_register_timeout(5, 0, ieee802_11_sta_authenticate
,
1085 printf("Associated (as station) with AP " MACSTR
" (aid=%d)\n",
1086 MAC2STR(hapd
->conf
->assoc_ap_addr
), aid
);
1087 hapd
->assoc_ap_aid
= aid
;
1088 hapd
->assoc_ap_state
= ASSOCIATED
;
1090 if (hostapd_set_assoc_ap(hapd
, hapd
->conf
->assoc_ap_addr
)) {
1091 printf("Could not set associated AP address to kernel "
1097 static void handle_disassoc(struct hostapd_data
*hapd
,
1098 struct ieee80211_mgmt
*mgmt
, size_t len
)
1100 struct sta_info
*sta
;
1102 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
1103 printf("handle_disassoc - too short payload (len=%lu)\n",
1104 (unsigned long) len
);
1108 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
1109 "disassocation: STA=" MACSTR
" reason_code=%d\n",
1111 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1113 if (hapd
->assoc_ap_state
!= DO_NOT_ASSOC
&&
1114 memcmp(mgmt
->sa
, hapd
->conf
->assoc_ap_addr
, ETH_ALEN
) == 0) {
1115 printf("Assoc AP " MACSTR
" sent disassociation "
1116 "(reason_code=%d) - try to authenticate\n",
1117 MAC2STR(hapd
->conf
->assoc_ap_addr
),
1118 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1119 hapd
->assoc_ap_state
= AUTHENTICATE
;
1120 ieee802_11_sta_authenticate(hapd
, NULL
);
1121 eloop_register_timeout(0, 500000, ieee802_11_sta_authenticate
,
1126 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1128 printf("Station " MACSTR
" trying to disassociate, but it "
1129 "is not associated.\n", MAC2STR(mgmt
->sa
));
1133 sta
->flags
&= ~WLAN_STA_ASSOC
;
1134 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
1135 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1136 HOSTAPD_LEVEL_INFO
, "disassociated");
1137 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1138 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1139 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
1141 accounting_sta_stop(hapd
, sta
);
1142 ieee802_1x_free_station(sta
);
1143 hostapd_sta_remove(hapd
, sta
->addr
);
1145 if (sta
->timeout_next
== STA_NULLFUNC
||
1146 sta
->timeout_next
== STA_DISASSOC
) {
1147 sta
->timeout_next
= STA_DEAUTH
;
1148 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
1149 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
1153 mlme_disassociate_indication(
1154 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1158 static void handle_deauth(struct hostapd_data
*hapd
,
1159 struct ieee80211_mgmt
*mgmt
, size_t len
)
1161 struct sta_info
*sta
;
1163 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
1164 printf("handle_deauth - too short payload (len=%lu)\n",
1165 (unsigned long) len
);
1169 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
1170 "deauthentication: STA=" MACSTR
" reason_code=%d\n",
1172 le_to_host16(mgmt
->u
.deauth
.reason_code
));
1174 if (hapd
->assoc_ap_state
!= DO_NOT_ASSOC
&&
1175 memcmp(mgmt
->sa
, hapd
->conf
->assoc_ap_addr
, ETH_ALEN
) == 0) {
1176 printf("Assoc AP " MACSTR
" sent deauthentication "
1177 "(reason_code=%d) - try to authenticate\n",
1178 MAC2STR(hapd
->conf
->assoc_ap_addr
),
1179 le_to_host16(mgmt
->u
.deauth
.reason_code
));
1180 hapd
->assoc_ap_state
= AUTHENTICATE
;
1181 eloop_register_timeout(0, 500000, ieee802_11_sta_authenticate
,
1186 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1188 printf("Station " MACSTR
" trying to deauthenticate, but it "
1189 "is not authenticated.\n", MAC2STR(mgmt
->sa
));
1193 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
);
1194 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
1195 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1196 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
1197 mlme_deauthenticate_indication(
1198 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
1199 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1200 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1201 ap_free_sta(hapd
, sta
);
1205 static void handle_beacon(struct hostapd_data
*hapd
,
1206 struct ieee80211_mgmt
*mgmt
, size_t len
,
1207 struct hostapd_frame_info
*fi
)
1209 struct ieee802_11_elems elems
;
1211 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
1212 printf("handle_beacon - too short payload (len=%lu)\n",
1213 (unsigned long) len
);
1217 (void) ieee802_11_parse_elems(hapd
, mgmt
->u
.beacon
.variable
,
1218 len
- (IEEE80211_HDRLEN
+
1219 sizeof(mgmt
->u
.beacon
)), &elems
,
1222 if (hapd
->assoc_ap_state
== WAIT_BEACON
&&
1223 memcmp(mgmt
->sa
, hapd
->conf
->assoc_ap_addr
, ETH_ALEN
) == 0) {
1224 if (elems
.ssid
&& elems
.ssid_len
<= 32) {
1225 memcpy(hapd
->assoc_ap_ssid
, elems
.ssid
,
1227 hapd
->assoc_ap_ssid
[elems
.ssid_len
] = '\0';
1228 hapd
->assoc_ap_ssid_len
= elems
.ssid_len
;
1230 ieee802_11_sta_authenticate(hapd
, NULL
);
1233 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
1235 if (!HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_EXCESSIVE
))
1238 printf("Beacon from " MACSTR
, MAC2STR(mgmt
->sa
));
1241 ieee802_11_print_ssid(elems
.ssid
, elems
.ssid_len
);
1244 if (elems
.ds_params
&& elems
.ds_params_len
== 1)
1245 printf(" CHAN=%d", elems
.ds_params
[0]);
1250 static void handle_action(struct hostapd_data
*hapd
,
1251 struct ieee80211_mgmt
*mgmt
, size_t len
)
1253 if (len
< IEEE80211_HDRLEN
+ 1) {
1254 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1255 HOSTAPD_LEVEL_DEBUG
,
1256 "handle_action - too short payload (len=%lu)",
1257 (unsigned long) len
);
1261 switch (mgmt
->u
.action
.category
) {
1262 case WME_ACTION_CATEGORY
:
1263 hostapd_wme_action(hapd
, mgmt
, len
);
1267 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1268 HOSTAPD_LEVEL_DEBUG
,
1269 "handle_action - unknown action category %d",
1270 mgmt
->u
.action
.category
);
1271 if (!(mgmt
->da
[0] & 0x01) && !(mgmt
->u
.action
.category
& 0x80) &&
1272 !(mgmt
->sa
[0] & 0x01)) {
1274 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
1275 * Return the Action frame to the source without change
1276 * except that MSB of the Category set to 1.
1278 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
1279 "frame back to sender");
1280 os_memcpy(mgmt
->da
, mgmt
->sa
, ETH_ALEN
);
1281 os_memcpy(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
);
1282 os_memcpy(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
);
1283 mgmt
->u
.action
.category
|= 0x80;
1285 hostapd_send_mgmt_frame(hapd
, mgmt
, len
, 0);
1291 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
1292 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
1294 * @buf: management frame data (starting from IEEE 802.11 header)
1295 * @len: length of frame data in octets
1296 * @stype: management frame subtype from frame control field
1298 * Process all incoming IEEE 802.11 management frames. This will be called for
1299 * each frame received from the kernel driver through wlan#ap interface. In
1300 * addition, it can be called to re-inserted pending frames (e.g., when using
1301 * external RADIUS server as an MAC ACL).
1303 void ieee802_11_mgmt(struct hostapd_data
*hapd
, u8
*buf
, size_t len
, u16 stype
,
1304 struct hostapd_frame_info
*fi
)
1306 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) buf
;
1309 if (stype
== WLAN_FC_STYPE_BEACON
) {
1310 HOSTAPD_DEBUG(HOSTAPD_DEBUG_EXCESSIVE
, "mgmt::beacon\n");
1311 handle_beacon(hapd
, mgmt
, len
, fi
);
1315 if (fi
&& fi
->passive_scan
)
1318 broadcast
= mgmt
->bssid
[0] == 0xff && mgmt
->bssid
[1] == 0xff &&
1319 mgmt
->bssid
[2] == 0xff && mgmt
->bssid
[3] == 0xff &&
1320 mgmt
->bssid
[4] == 0xff && mgmt
->bssid
[5] == 0xff;
1322 if (!broadcast
&& memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0 &&
1323 (hapd
->assoc_ap_state
== DO_NOT_ASSOC
||
1324 memcmp(mgmt
->bssid
, hapd
->conf
->assoc_ap_addr
, ETH_ALEN
) != 0)) {
1325 printf("MGMT: BSSID=" MACSTR
" not our address\n",
1326 MAC2STR(mgmt
->bssid
));
1331 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
1332 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MSGDUMPS
, "mgmt::probe_req\n");
1333 handle_probe_req(hapd
, mgmt
, len
);
1337 if (memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
1338 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1339 HOSTAPD_LEVEL_DEBUG
,
1340 "MGMT: DA=" MACSTR
" not our address",
1346 case WLAN_FC_STYPE_AUTH
:
1347 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "mgmt::auth\n");
1348 handle_auth(hapd
, mgmt
, len
);
1350 case WLAN_FC_STYPE_ASSOC_REQ
:
1351 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "mgmt::assoc_req\n");
1352 handle_assoc(hapd
, mgmt
, len
, 0);
1354 case WLAN_FC_STYPE_ASSOC_RESP
:
1355 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "mgmt::assoc_resp\n");
1356 handle_assoc_resp(hapd
, mgmt
, len
);
1358 case WLAN_FC_STYPE_REASSOC_REQ
:
1359 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "mgmt::reassoc_req\n");
1360 handle_assoc(hapd
, mgmt
, len
, 1);
1362 case WLAN_FC_STYPE_DISASSOC
:
1363 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "mgmt::disassoc\n");
1364 handle_disassoc(hapd
, mgmt
, len
);
1366 case WLAN_FC_STYPE_DEAUTH
:
1367 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "mgmt::deauth\n");
1368 handle_deauth(hapd
, mgmt
, len
);
1370 case WLAN_FC_STYPE_ACTION
:
1371 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "mgmt::action\n");
1372 handle_action(hapd
, mgmt
, len
);
1375 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1376 HOSTAPD_LEVEL_DEBUG
,
1377 "unknown mgmt frame subtype %d", stype
);
1383 static void handle_auth_cb(struct hostapd_data
*hapd
,
1384 struct ieee80211_mgmt
*mgmt
,
1387 u16 auth_alg
, auth_transaction
, status_code
;
1388 struct sta_info
*sta
;
1391 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
1392 HOSTAPD_LEVEL_NOTICE
,
1393 "did not acknowledge authentication response");
1397 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
1398 printf("handle_auth_cb - too short payload (len=%lu)\n",
1399 (unsigned long) len
);
1403 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
1404 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
1405 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
1407 sta
= ap_get_sta(hapd
, mgmt
->da
);
1409 printf("handle_auth_cb: STA " MACSTR
" not found\n",
1414 if (status_code
== WLAN_STATUS_SUCCESS
&&
1415 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
1416 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
1417 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1418 HOSTAPD_LEVEL_INFO
, "authenticated");
1419 sta
->flags
|= WLAN_STA_AUTH
;
1424 static void handle_assoc_cb(struct hostapd_data
*hapd
,
1425 struct ieee80211_mgmt
*mgmt
,
1426 size_t len
, int reassoc
, int ok
)
1429 struct sta_info
*sta
;
1433 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
1434 HOSTAPD_LEVEL_DEBUG
,
1435 "did not acknowledge association response");
1439 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
1440 sizeof(mgmt
->u
.assoc_req
))) {
1441 printf("handle_assoc_cb(reassoc=%d) - too short payload "
1442 "(len=%lu)\n", reassoc
, (unsigned long) len
);
1447 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
1449 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
1451 sta
= ap_get_sta(hapd
, mgmt
->da
);
1453 printf("handle_assoc_cb: STA " MACSTR
" not found\n",
1458 if (status
!= WLAN_STATUS_SUCCESS
)
1461 /* Stop previous accounting session, if one is started, and allocate
1462 * new session id for the new session. */
1463 accounting_sta_stop(hapd
, sta
);
1464 accounting_sta_get_id(hapd
, sta
);
1466 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1468 "associated (aid %d, accounting session %08X-%08X)",
1469 sta
->aid
, sta
->acct_session_id_hi
,
1470 sta
->acct_session_id_lo
);
1472 if (sta
->flags
& WLAN_STA_ASSOC
)
1474 sta
->flags
|= WLAN_STA_ASSOC
;
1477 mlme_reassociate_indication(hapd
, sta
);
1479 mlme_associate_indication(hapd
, sta
);
1481 if (hostapd_sta_add(hapd
->conf
->iface
, hapd
, sta
->addr
, sta
->aid
,
1482 sta
->capability
, sta
->supported_rates
,
1483 sta
->supported_rates_len
, 0)) {
1484 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1485 HOSTAPD_LEVEL_NOTICE
,
1486 "Could not add STA to kernel driver");
1489 if (sta
->eapol_sm
== NULL
) {
1491 * This STA does not use RADIUS server for EAP authentication,
1492 * so bind it to the selected VLAN interface now, since the
1493 * interface selection is not going to change anymore.
1495 ap_sta_bind_vlan(hapd
, sta
, 0);
1496 } else if (sta
->vlan_id
) {
1497 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
1498 ap_sta_bind_vlan(hapd
, sta
, 0);
1500 if (sta
->flags
& WLAN_STA_SHORT_PREAMBLE
) {
1501 hostapd_sta_set_flags(hapd
, sta
->addr
,
1502 WLAN_STA_SHORT_PREAMBLE
, ~0);
1504 hostapd_sta_set_flags(hapd
, sta
->addr
,
1505 0, ~WLAN_STA_SHORT_PREAMBLE
);
1508 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
1509 hostapd_new_assoc_sta(hapd
, sta
, !new_assoc
);
1511 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
1514 /* Copy of the association request is not needed anymore */
1515 if (sta
->last_assoc_req
) {
1516 free(sta
->last_assoc_req
);
1517 sta
->last_assoc_req
= NULL
;
1522 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, u8
*buf
, size_t len
,
1525 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) buf
;
1528 case WLAN_FC_STYPE_AUTH
:
1529 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "mgmt::auth cb\n");
1530 handle_auth_cb(hapd
, mgmt
, len
, ok
);
1532 case WLAN_FC_STYPE_ASSOC_RESP
:
1533 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
1534 "mgmt::assoc_resp cb\n");
1535 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
1537 case WLAN_FC_STYPE_REASSOC_RESP
:
1538 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
1539 "mgmt::reassoc_resp cb\n");
1540 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
1542 case WLAN_FC_STYPE_PROBE_RESP
:
1543 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "mgmt::proberesp cb\n");
1546 printf("unknown mgmt cb frame subtype %d\n", stype
);
1552 static void ieee80211_tkip_countermeasures_stop(void *eloop_ctx
,
1555 struct hostapd_data
*hapd
= eloop_ctx
;
1556 hapd
->tkip_countermeasures
= 0;
1557 hostapd_set_countermeasures(hapd
, 0);
1558 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_IEEE80211
,
1559 HOSTAPD_LEVEL_INFO
, "TKIP countermeasures ended");
1563 static void ieee80211_tkip_countermeasures_start(struct hostapd_data
*hapd
)
1565 struct sta_info
*sta
;
1567 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_IEEE80211
,
1568 HOSTAPD_LEVEL_INFO
, "TKIP countermeasures initiated");
1570 wpa_auth_countermeasures_start(hapd
->wpa_auth
);
1571 hapd
->tkip_countermeasures
= 1;
1572 hostapd_set_countermeasures(hapd
, 1);
1573 wpa_gtk_rekey(hapd
->wpa_auth
);
1574 eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop
, hapd
, NULL
);
1575 eloop_register_timeout(60, 0, ieee80211_tkip_countermeasures_stop
,
1577 for (sta
= hapd
->sta_list
; sta
!= NULL
; sta
= sta
->next
) {
1578 hostapd_sta_deauth(hapd
, sta
->addr
,
1579 WLAN_REASON_MICHAEL_MIC_FAILURE
);
1580 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
1581 WLAN_STA_AUTHORIZED
);
1582 hostapd_sta_remove(hapd
, sta
->addr
);
1587 void ieee80211_michael_mic_failure(struct hostapd_data
*hapd
, const u8
*addr
,
1592 if (addr
&& local
) {
1593 struct sta_info
*sta
= ap_get_sta(hapd
, addr
);
1595 wpa_auth_sta_local_mic_failure_report(sta
->wpa_sm
);
1596 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE80211
,
1598 "Michael MIC failure detected in "
1600 mlme_michaelmicfailure_indication(hapd
, addr
);
1602 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
1603 "MLME-MICHAELMICFAILURE.indication "
1604 "for not associated STA (" MACSTR
1605 ") ignored\n", MAC2STR(addr
));
1611 if (now
> hapd
->michael_mic_failure
+ 60) {
1612 hapd
->michael_mic_failures
= 1;
1614 hapd
->michael_mic_failures
++;
1615 if (hapd
->michael_mic_failures
> 1)
1616 ieee80211_tkip_countermeasures_start(hapd
);
1618 hapd
->michael_mic_failure
= now
;
1622 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
1629 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1630 char *buf
, size_t buflen
)
1636 #endif /* CONFIG_NATIVE_WINDOWS */