drv_callbacks.c revision 04f534e89ed127da4077485376f24debc50d80d5
1/* 2 * hostapd / Callback functions for driver wrappers 3 * Copyright (c) 2002-2013, 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#include "utils/common.h" 12#include "radius/radius.h" 13#include "drivers/driver.h" 14#include "common/ieee802_11_defs.h" 15#include "common/ieee802_11_common.h" 16#include "common/wpa_ctrl.h" 17#include "crypto/random.h" 18#include "p2p/p2p.h" 19#include "wps/wps.h" 20#include "wnm_ap.h" 21#include "hostapd.h" 22#include "ieee802_11.h" 23#include "sta_info.h" 24#include "accounting.h" 25#include "tkip_countermeasures.h" 26#include "ieee802_1x.h" 27#include "wpa_auth.h" 28#include "wps_hostapd.h" 29#include "ap_drv_ops.h" 30#include "ap_config.h" 31#include "hw_features.h" 32#include "dfs.h" 33 34 35int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, 36 const u8 *req_ies, size_t req_ies_len, int reassoc) 37{ 38 struct sta_info *sta; 39 int new_assoc, res; 40 struct ieee802_11_elems elems; 41 const u8 *ie; 42 size_t ielen; 43#ifdef CONFIG_IEEE80211R 44 u8 buf[sizeof(struct ieee80211_mgmt) + 1024]; 45 u8 *p = buf; 46#endif /* CONFIG_IEEE80211R */ 47 u16 reason = WLAN_REASON_UNSPECIFIED; 48 u16 status = WLAN_STATUS_SUCCESS; 49 const u8 *p2p_dev_addr = NULL; 50 51 if (addr == NULL) { 52 /* 53 * This could potentially happen with unexpected event from the 54 * driver wrapper. This was seen at least in one case where the 55 * driver ended up being set to station mode while hostapd was 56 * running, so better make sure we stop processing such an 57 * event here. 58 */ 59 wpa_printf(MSG_DEBUG, "hostapd_notif_assoc: Skip event with " 60 "no address"); 61 return -1; 62 } 63 random_add_randomness(addr, ETH_ALEN); 64 65 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, 66 HOSTAPD_LEVEL_INFO, "associated"); 67 68 ieee802_11_parse_elems(req_ies, req_ies_len, &elems, 0); 69 if (elems.wps_ie) { 70 ie = elems.wps_ie - 2; 71 ielen = elems.wps_ie_len + 2; 72 wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)AssocReq"); 73 } else if (elems.rsn_ie) { 74 ie = elems.rsn_ie - 2; 75 ielen = elems.rsn_ie_len + 2; 76 wpa_printf(MSG_DEBUG, "STA included RSN IE in (Re)AssocReq"); 77 } else if (elems.wpa_ie) { 78 ie = elems.wpa_ie - 2; 79 ielen = elems.wpa_ie_len + 2; 80 wpa_printf(MSG_DEBUG, "STA included WPA IE in (Re)AssocReq"); 81 } else { 82 ie = NULL; 83 ielen = 0; 84 wpa_printf(MSG_DEBUG, "STA did not include WPS/RSN/WPA IE in " 85 "(Re)AssocReq"); 86 } 87 88 sta = ap_get_sta(hapd, addr); 89 if (sta) { 90 ap_sta_no_session_timeout(hapd, sta); 91 accounting_sta_stop(hapd, sta); 92 93 /* 94 * Make sure that the previously registered inactivity timer 95 * will not remove the STA immediately. 96 */ 97 sta->timeout_next = STA_NULLFUNC; 98 } else { 99 sta = ap_sta_add(hapd, addr); 100 if (sta == NULL) { 101 hostapd_drv_sta_disassoc(hapd, addr, 102 WLAN_REASON_DISASSOC_AP_BUSY); 103 return -1; 104 } 105 } 106 sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2); 107 108#ifdef CONFIG_P2P 109 if (elems.p2p) { 110 wpabuf_free(sta->p2p_ie); 111 sta->p2p_ie = ieee802_11_vendor_ie_concat(req_ies, req_ies_len, 112 P2P_IE_VENDOR_TYPE); 113 if (sta->p2p_ie) 114 p2p_dev_addr = p2p_get_go_dev_addr(sta->p2p_ie); 115 } 116#endif /* CONFIG_P2P */ 117 118#ifdef CONFIG_INTERWORKING 119 if (elems.ext_capab && elems.ext_capab_len > 4) { 120 if (elems.ext_capab[4] & 0x01) 121 sta->qos_map_enabled = 1; 122 } 123#endif /* CONFIG_INTERWORKING */ 124 125#ifdef CONFIG_HS20 126 wpabuf_free(sta->hs20_ie); 127 if (elems.hs20 && elems.hs20_len > 4) { 128 sta->hs20_ie = wpabuf_alloc_copy(elems.hs20 + 4, 129 elems.hs20_len - 4); 130 } else 131 sta->hs20_ie = NULL; 132#endif /* CONFIG_HS20 */ 133 134 if (hapd->conf->wpa) { 135 if (ie == NULL || ielen == 0) { 136#ifdef CONFIG_WPS 137 if (hapd->conf->wps_state) { 138 wpa_printf(MSG_DEBUG, "STA did not include " 139 "WPA/RSN IE in (Re)Association " 140 "Request - possible WPS use"); 141 sta->flags |= WLAN_STA_MAYBE_WPS; 142 goto skip_wpa_check; 143 } 144#endif /* CONFIG_WPS */ 145 146 wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA"); 147 return -1; 148 } 149#ifdef CONFIG_WPS 150 if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 && 151 os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) { 152 struct wpabuf *wps; 153 sta->flags |= WLAN_STA_WPS; 154 wps = ieee802_11_vendor_ie_concat(ie, ielen, 155 WPS_IE_VENDOR_TYPE); 156 if (wps) { 157 if (wps_is_20(wps)) { 158 wpa_printf(MSG_DEBUG, "WPS: STA " 159 "supports WPS 2.0"); 160 sta->flags |= WLAN_STA_WPS2; 161 } 162 wpabuf_free(wps); 163 } 164 goto skip_wpa_check; 165 } 166#endif /* CONFIG_WPS */ 167 168 if (sta->wpa_sm == NULL) 169 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, 170 sta->addr, 171 p2p_dev_addr); 172 if (sta->wpa_sm == NULL) { 173 wpa_printf(MSG_ERROR, "Failed to initialize WPA state " 174 "machine"); 175 return -1; 176 } 177 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, 178 ie, ielen, 179 elems.mdie, elems.mdie_len); 180 if (res != WPA_IE_OK) { 181 wpa_printf(MSG_DEBUG, "WPA/RSN information element " 182 "rejected? (res %u)", res); 183 wpa_hexdump(MSG_DEBUG, "IE", ie, ielen); 184 if (res == WPA_INVALID_GROUP) { 185 reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID; 186 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; 187 } else if (res == WPA_INVALID_PAIRWISE) { 188 reason = WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID; 189 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; 190 } else if (res == WPA_INVALID_AKMP) { 191 reason = WLAN_REASON_AKMP_NOT_VALID; 192 status = WLAN_STATUS_AKMP_NOT_VALID; 193 } 194#ifdef CONFIG_IEEE80211W 195 else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION) { 196 reason = WLAN_REASON_INVALID_IE; 197 status = WLAN_STATUS_INVALID_IE; 198 } else if (res == WPA_INVALID_MGMT_GROUP_CIPHER) { 199 reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID; 200 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; 201 } 202#endif /* CONFIG_IEEE80211W */ 203 else { 204 reason = WLAN_REASON_INVALID_IE; 205 status = WLAN_STATUS_INVALID_IE; 206 } 207 goto fail; 208 } 209#ifdef CONFIG_IEEE80211W 210 if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out && 211 sta->sa_query_count > 0) 212 ap_check_sa_query_timeout(hapd, sta); 213 if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out && 214 (sta->auth_alg != WLAN_AUTH_FT)) { 215 /* 216 * STA has already been associated with MFP and SA 217 * Query timeout has not been reached. Reject the 218 * association attempt temporarily and start SA Query, 219 * if one is not pending. 220 */ 221 222 if (sta->sa_query_count == 0) 223 ap_sta_start_sa_query(hapd, sta); 224 225#ifdef CONFIG_IEEE80211R 226 status = WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY; 227 228 p = hostapd_eid_assoc_comeback_time(hapd, sta, p); 229 230 hostapd_sta_assoc(hapd, addr, reassoc, status, buf, 231 p - buf); 232#endif /* CONFIG_IEEE80211R */ 233 return 0; 234 } 235 236 if (wpa_auth_uses_mfp(sta->wpa_sm)) 237 sta->flags |= WLAN_STA_MFP; 238 else 239 sta->flags &= ~WLAN_STA_MFP; 240#endif /* CONFIG_IEEE80211W */ 241 242#ifdef CONFIG_IEEE80211R 243 if (sta->auth_alg == WLAN_AUTH_FT) { 244 status = wpa_ft_validate_reassoc(sta->wpa_sm, req_ies, 245 req_ies_len); 246 if (status != WLAN_STATUS_SUCCESS) { 247 if (status == WLAN_STATUS_INVALID_PMKID) 248 reason = WLAN_REASON_INVALID_IE; 249 if (status == WLAN_STATUS_INVALID_MDIE) 250 reason = WLAN_REASON_INVALID_IE; 251 if (status == WLAN_STATUS_INVALID_FTIE) 252 reason = WLAN_REASON_INVALID_IE; 253 goto fail; 254 } 255 } 256#endif /* CONFIG_IEEE80211R */ 257 } else if (hapd->conf->wps_state) { 258#ifdef CONFIG_WPS 259 struct wpabuf *wps; 260 if (req_ies) 261 wps = ieee802_11_vendor_ie_concat(req_ies, req_ies_len, 262 WPS_IE_VENDOR_TYPE); 263 else 264 wps = NULL; 265#ifdef CONFIG_WPS_STRICT 266 if (wps && wps_validate_assoc_req(wps) < 0) { 267 reason = WLAN_REASON_INVALID_IE; 268 status = WLAN_STATUS_INVALID_IE; 269 wpabuf_free(wps); 270 goto fail; 271 } 272#endif /* CONFIG_WPS_STRICT */ 273 if (wps) { 274 sta->flags |= WLAN_STA_WPS; 275 if (wps_is_20(wps)) { 276 wpa_printf(MSG_DEBUG, "WPS: STA supports " 277 "WPS 2.0"); 278 sta->flags |= WLAN_STA_WPS2; 279 } 280 } else 281 sta->flags |= WLAN_STA_MAYBE_WPS; 282 wpabuf_free(wps); 283#endif /* CONFIG_WPS */ 284 } 285#ifdef CONFIG_WPS 286skip_wpa_check: 287#endif /* CONFIG_WPS */ 288 289#ifdef CONFIG_IEEE80211R 290 p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, buf, sizeof(buf), 291 sta->auth_alg, req_ies, req_ies_len); 292 293 hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf); 294#else /* CONFIG_IEEE80211R */ 295 /* Keep compiler silent about unused variables */ 296 if (status) { 297 } 298#endif /* CONFIG_IEEE80211R */ 299 300 new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0; 301 sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC; 302 303 if (reassoc && (sta->auth_alg == WLAN_AUTH_FT)) 304 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT); 305 else 306 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC); 307 308 hostapd_new_assoc_sta(hapd, sta, !new_assoc); 309 310 ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); 311 312#ifdef CONFIG_P2P 313 if (req_ies) { 314 p2p_group_notif_assoc(hapd->p2p_group, sta->addr, 315 req_ies, req_ies_len); 316 } 317#endif /* CONFIG_P2P */ 318 319 return 0; 320 321fail: 322#ifdef CONFIG_IEEE80211R 323 hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf); 324#endif /* CONFIG_IEEE80211R */ 325 hostapd_drv_sta_disassoc(hapd, sta->addr, reason); 326 ap_free_sta(hapd, sta); 327 return -1; 328} 329 330 331void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr) 332{ 333 struct sta_info *sta; 334 335 if (addr == NULL) { 336 /* 337 * This could potentially happen with unexpected event from the 338 * driver wrapper. This was seen at least in one case where the 339 * driver ended up reporting a station mode event while hostapd 340 * was running, so better make sure we stop processing such an 341 * event here. 342 */ 343 wpa_printf(MSG_DEBUG, "hostapd_notif_disassoc: Skip event " 344 "with no address"); 345 return; 346 } 347 348 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, 349 HOSTAPD_LEVEL_INFO, "disassociated"); 350 351 sta = ap_get_sta(hapd, addr); 352 if (sta == NULL) { 353 wpa_printf(MSG_DEBUG, "Disassociation notification for " 354 "unknown STA " MACSTR, MAC2STR(addr)); 355 return; 356 } 357 358 ap_sta_set_authorized(hapd, sta, 0); 359 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); 360 wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC); 361 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; 362 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); 363 ap_free_sta(hapd, sta); 364} 365 366 367void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr) 368{ 369 struct sta_info *sta = ap_get_sta(hapd, addr); 370 371 if (!sta || !hapd->conf->disassoc_low_ack) 372 return; 373 374 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, 375 HOSTAPD_LEVEL_INFO, "disconnected due to excessive " 376 "missing ACKs"); 377 hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_DISASSOC_LOW_ACK); 378 if (sta) 379 ap_sta_disassociate(hapd, sta, WLAN_REASON_DISASSOC_LOW_ACK); 380} 381 382 383void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, 384 int offset, int width, int cf1, int cf2) 385{ 386#ifdef NEED_AP_MLME 387 int channel, chwidth, seg0_idx = 0, seg1_idx = 0; 388 389 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, 390 HOSTAPD_LEVEL_INFO, "driver had channel switch: " 391 "freq=%d, ht=%d, offset=%d, width=%d, cf1=%d, cf2=%d", 392 freq, ht, offset, width, cf1, cf2); 393 394 hapd->iface->freq = freq; 395 396 channel = hostapd_hw_get_channel(hapd, freq); 397 if (!channel) { 398 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, 399 HOSTAPD_LEVEL_WARNING, "driver switched to " 400 "bad channel!"); 401 return; 402 } 403 404 switch (width) { 405 case CHAN_WIDTH_80: 406 chwidth = VHT_CHANWIDTH_80MHZ; 407 break; 408 case CHAN_WIDTH_80P80: 409 chwidth = VHT_CHANWIDTH_80P80MHZ; 410 break; 411 case CHAN_WIDTH_160: 412 chwidth = VHT_CHANWIDTH_160MHZ; 413 break; 414 case CHAN_WIDTH_20_NOHT: 415 case CHAN_WIDTH_20: 416 case CHAN_WIDTH_40: 417 default: 418 chwidth = VHT_CHANWIDTH_USE_HT; 419 break; 420 } 421 422 switch (hapd->iface->current_mode->mode) { 423 case HOSTAPD_MODE_IEEE80211A: 424 if (cf1 > 5000) 425 seg0_idx = (cf1 - 5000) / 5; 426 if (cf2 > 5000) 427 seg1_idx = (cf2 - 5000) / 5; 428 break; 429 default: 430 seg0_idx = hostapd_hw_get_channel(hapd, cf1); 431 seg1_idx = hostapd_hw_get_channel(hapd, cf2); 432 break; 433 } 434 435 hapd->iconf->channel = channel; 436 hapd->iconf->ieee80211n = ht; 437 hapd->iconf->secondary_channel = offset; 438 hapd->iconf->vht_oper_chwidth = chwidth; 439 hapd->iconf->vht_oper_centr_freq_seg0_idx = seg0_idx; 440 hapd->iconf->vht_oper_centr_freq_seg1_idx = seg1_idx; 441 442 if (hapd->iface->csa_in_progress && freq == hapd->iface->cs_freq) { 443 hostapd_cleanup_cs_params(hapd); 444 445 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED "freq=%d", 446 freq); 447 } 448#endif /* NEED_AP_MLME */ 449} 450 451 452void hostapd_event_connect_failed_reason(struct hostapd_data *hapd, 453 const u8 *addr, int reason_code) 454{ 455 switch (reason_code) { 456 case MAX_CLIENT_REACHED: 457 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_REJECTED_MAX_STA MACSTR, 458 MAC2STR(addr)); 459 break; 460 case BLOCKED_CLIENT: 461 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_REJECTED_BLOCKED_STA MACSTR, 462 MAC2STR(addr)); 463 break; 464 } 465} 466 467 468int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da, 469 const u8 *bssid, const u8 *ie, size_t ie_len, 470 int ssi_signal) 471{ 472 size_t i; 473 int ret = 0; 474 475 if (sa == NULL || ie == NULL) 476 return -1; 477 478 random_add_randomness(sa, ETH_ALEN); 479 for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) { 480 if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx, 481 sa, da, bssid, ie, ie_len, 482 ssi_signal) > 0) { 483 ret = 1; 484 break; 485 } 486 } 487 return ret; 488} 489 490 491#ifdef HOSTAPD 492 493#ifdef CONFIG_IEEE80211R 494static void hostapd_notify_auth_ft_finish(void *ctx, const u8 *dst, 495 const u8 *bssid, 496 u16 auth_transaction, u16 status, 497 const u8 *ies, size_t ies_len) 498{ 499 struct hostapd_data *hapd = ctx; 500 struct sta_info *sta; 501 502 sta = ap_get_sta(hapd, dst); 503 if (sta == NULL) 504 return; 505 506 hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211, 507 HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)"); 508 sta->flags |= WLAN_STA_AUTH; 509 510 hostapd_sta_auth(hapd, dst, auth_transaction, status, ies, ies_len); 511} 512#endif /* CONFIG_IEEE80211R */ 513 514 515static void hostapd_notif_auth(struct hostapd_data *hapd, 516 struct auth_info *rx_auth) 517{ 518 struct sta_info *sta; 519 u16 status = WLAN_STATUS_SUCCESS; 520 u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN]; 521 size_t resp_ies_len = 0; 522 523 sta = ap_get_sta(hapd, rx_auth->peer); 524 if (!sta) { 525 sta = ap_sta_add(hapd, rx_auth->peer); 526 if (sta == NULL) { 527 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; 528 goto fail; 529 } 530 } 531 sta->flags &= ~WLAN_STA_PREAUTH; 532 ieee802_1x_notify_pre_auth(sta->eapol_sm, 0); 533#ifdef CONFIG_IEEE80211R 534 if (rx_auth->auth_type == WLAN_AUTH_FT && hapd->wpa_auth) { 535 sta->auth_alg = WLAN_AUTH_FT; 536 if (sta->wpa_sm == NULL) 537 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, 538 sta->addr, NULL); 539 if (sta->wpa_sm == NULL) { 540 wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA " 541 "state machine"); 542 status = WLAN_STATUS_UNSPECIFIED_FAILURE; 543 goto fail; 544 } 545 wpa_ft_process_auth(sta->wpa_sm, rx_auth->bssid, 546 rx_auth->auth_transaction, rx_auth->ies, 547 rx_auth->ies_len, 548 hostapd_notify_auth_ft_finish, hapd); 549 return; 550 } 551#endif /* CONFIG_IEEE80211R */ 552fail: 553 hostapd_sta_auth(hapd, rx_auth->peer, rx_auth->auth_transaction + 1, 554 status, resp_ies, resp_ies_len); 555} 556 557 558static void hostapd_action_rx(struct hostapd_data *hapd, 559 struct rx_action *action) 560{ 561 struct sta_info *sta; 562 563 wpa_printf(MSG_DEBUG, "RX_ACTION cat %d action plen %d", 564 action->category, (int) action->len); 565 566 sta = ap_get_sta(hapd, action->sa); 567 if (sta == NULL) { 568 wpa_printf(MSG_DEBUG, "%s: station not found", __func__); 569 return; 570 } 571#ifdef CONFIG_IEEE80211R 572 if (action->category == WLAN_ACTION_FT) { 573 wpa_printf(MSG_DEBUG, "%s: FT_ACTION length %d", 574 __func__, (int) action->len); 575 wpa_ft_action_rx(sta->wpa_sm, action->data, action->len); 576 } 577#endif /* CONFIG_IEEE80211R */ 578#ifdef CONFIG_IEEE80211W 579 if (action->category == WLAN_ACTION_SA_QUERY && action->len >= 4) { 580 wpa_printf(MSG_DEBUG, "%s: SA_QUERY_ACTION length %d", 581 __func__, (int) action->len); 582 ieee802_11_sa_query_action(hapd, action->sa, 583 *(action->data + 1), 584 action->data + 2); 585 } 586#endif /* CONFIG_IEEE80211W */ 587#ifdef CONFIG_WNM 588 if (action->category == WLAN_ACTION_WNM) { 589 wpa_printf(MSG_DEBUG, "%s: WNM_ACTION length %d", 590 __func__, (int) action->len); 591 ieee802_11_rx_wnm_action_ap(hapd, action); 592 } 593#endif /* CONFIG_WNM */ 594} 595 596 597#ifdef NEED_AP_MLME 598 599#define HAPD_BROADCAST ((struct hostapd_data *) -1) 600 601static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface, 602 const u8 *bssid) 603{ 604 size_t i; 605 606 if (bssid == NULL) 607 return NULL; 608 if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff && 609 bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff) 610 return HAPD_BROADCAST; 611 612 for (i = 0; i < iface->num_bss; i++) { 613 if (os_memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0) 614 return iface->bss[i]; 615 } 616 617 return NULL; 618} 619 620 621static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd, 622 const u8 *bssid, const u8 *addr, 623 int wds) 624{ 625 hapd = get_hapd_bssid(hapd->iface, bssid); 626 if (hapd == NULL || hapd == HAPD_BROADCAST) 627 return; 628 629 ieee802_11_rx_from_unknown(hapd, addr, wds); 630} 631 632 633static void hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt) 634{ 635 struct hostapd_iface *iface = hapd->iface; 636 const struct ieee80211_hdr *hdr; 637 const u8 *bssid; 638 struct hostapd_frame_info fi; 639 640 hdr = (const struct ieee80211_hdr *) rx_mgmt->frame; 641 bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len); 642 if (bssid == NULL) 643 return; 644 645 hapd = get_hapd_bssid(iface, bssid); 646 if (hapd == NULL) { 647 u16 fc; 648 fc = le_to_host16(hdr->frame_control); 649 650 /* 651 * Drop frames to unknown BSSIDs except for Beacon frames which 652 * could be used to update neighbor information. 653 */ 654 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && 655 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) 656 hapd = iface->bss[0]; 657 else 658 return; 659 } 660 661 os_memset(&fi, 0, sizeof(fi)); 662 fi.datarate = rx_mgmt->datarate; 663 fi.ssi_signal = rx_mgmt->ssi_signal; 664 665 if (hapd == HAPD_BROADCAST) { 666 size_t i; 667 for (i = 0; i < iface->num_bss; i++) 668 ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame, 669 rx_mgmt->frame_len, &fi); 670 } else 671 ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len, &fi); 672 673 random_add_randomness(&fi, sizeof(fi)); 674} 675 676 677static void hostapd_rx_action(struct hostapd_data *hapd, 678 struct rx_action *rx_action) 679{ 680 struct rx_mgmt rx_mgmt; 681 u8 *buf; 682 struct ieee80211_hdr *hdr; 683 684 wpa_printf(MSG_DEBUG, "EVENT_RX_ACTION DA=" MACSTR " SA=" MACSTR 685 " BSSID=" MACSTR " category=%u", 686 MAC2STR(rx_action->da), MAC2STR(rx_action->sa), 687 MAC2STR(rx_action->bssid), rx_action->category); 688 wpa_hexdump(MSG_MSGDUMP, "Received action frame contents", 689 rx_action->data, rx_action->len); 690 691 buf = os_zalloc(24 + 1 + rx_action->len); 692 if (buf == NULL) 693 return; 694 hdr = (struct ieee80211_hdr *) buf; 695 hdr->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 696 WLAN_FC_STYPE_ACTION); 697 if (rx_action->category == WLAN_ACTION_SA_QUERY) { 698 /* 699 * Assume frame was protected; it would have been dropped if 700 * not. 701 */ 702 hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP); 703 } 704 os_memcpy(hdr->addr1, rx_action->da, ETH_ALEN); 705 os_memcpy(hdr->addr2, rx_action->sa, ETH_ALEN); 706 os_memcpy(hdr->addr3, rx_action->bssid, ETH_ALEN); 707 buf[24] = rx_action->category; 708 os_memcpy(buf + 24 + 1, rx_action->data, rx_action->len); 709 os_memset(&rx_mgmt, 0, sizeof(rx_mgmt)); 710 rx_mgmt.frame = buf; 711 rx_mgmt.frame_len = 24 + 1 + rx_action->len; 712 hostapd_mgmt_rx(hapd, &rx_mgmt); 713 os_free(buf); 714} 715 716 717static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf, 718 size_t len, u16 stype, int ok) 719{ 720 struct ieee80211_hdr *hdr; 721 hdr = (struct ieee80211_hdr *) buf; 722 hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len)); 723 if (hapd == NULL || hapd == HAPD_BROADCAST) 724 return; 725 ieee802_11_mgmt_cb(hapd, buf, len, stype, ok); 726} 727 728#endif /* NEED_AP_MLME */ 729 730 731static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr) 732{ 733 struct sta_info *sta = ap_get_sta(hapd, addr); 734 if (sta) 735 return 0; 736 737 wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR 738 " - adding a new STA", MAC2STR(addr)); 739 sta = ap_sta_add(hapd, addr); 740 if (sta) { 741 hostapd_new_assoc_sta(hapd, sta, 0); 742 } else { 743 wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR, 744 MAC2STR(addr)); 745 return -1; 746 } 747 748 return 0; 749} 750 751 752static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src, 753 const u8 *data, size_t data_len) 754{ 755 struct hostapd_iface *iface = hapd->iface; 756 struct sta_info *sta; 757 size_t j; 758 759 for (j = 0; j < iface->num_bss; j++) { 760 if ((sta = ap_get_sta(iface->bss[j], src))) { 761 if (sta->flags & WLAN_STA_ASSOC) { 762 hapd = iface->bss[j]; 763 break; 764 } 765 } 766 } 767 768 ieee802_1x_receive(hapd, src, data, data_len); 769} 770 771 772static struct hostapd_channel_data * hostapd_get_mode_channel( 773 struct hostapd_iface *iface, unsigned int freq) 774{ 775 int i; 776 struct hostapd_channel_data *chan; 777 778 for (i = 0; i < iface->current_mode->num_channels; i++) { 779 chan = &iface->current_mode->channels[i]; 780 if (!chan) 781 return NULL; 782 if ((unsigned int) chan->freq == freq) 783 return chan; 784 } 785 786 return NULL; 787} 788 789 790static void hostapd_update_nf(struct hostapd_iface *iface, 791 struct hostapd_channel_data *chan, 792 struct freq_survey *survey) 793{ 794 if (!iface->chans_surveyed) { 795 chan->min_nf = survey->nf; 796 iface->lowest_nf = survey->nf; 797 } else { 798 if (dl_list_empty(&chan->survey_list)) 799 chan->min_nf = survey->nf; 800 else if (survey->nf < chan->min_nf) 801 chan->min_nf = survey->nf; 802 if (survey->nf < iface->lowest_nf) 803 iface->lowest_nf = survey->nf; 804 } 805} 806 807 808static void hostapd_event_get_survey(struct hostapd_data *hapd, 809 struct survey_results *survey_results) 810{ 811 struct hostapd_iface *iface = hapd->iface; 812 struct freq_survey *survey, *tmp; 813 struct hostapd_channel_data *chan; 814 815 if (dl_list_empty(&survey_results->survey_list)) { 816 wpa_printf(MSG_DEBUG, "No survey data received"); 817 return; 818 } 819 820 dl_list_for_each_safe(survey, tmp, &survey_results->survey_list, 821 struct freq_survey, list) { 822 chan = hostapd_get_mode_channel(iface, survey->freq); 823 if (!chan) 824 continue; 825 if (chan->flag & HOSTAPD_CHAN_DISABLED) 826 continue; 827 828 dl_list_del(&survey->list); 829 dl_list_add_tail(&chan->survey_list, &survey->list); 830 831 hostapd_update_nf(iface, chan, survey); 832 833 iface->chans_surveyed++; 834 } 835} 836 837 838#ifdef NEED_AP_MLME 839 840static void hostapd_event_dfs_radar_detected(struct hostapd_data *hapd, 841 struct dfs_event *radar) 842{ 843 wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq); 844 hostapd_dfs_radar_detected(hapd->iface, radar->freq, radar->ht_enabled, 845 radar->chan_offset, radar->chan_width, 846 radar->cf1, radar->cf2); 847} 848 849 850static void hostapd_event_dfs_cac_finished(struct hostapd_data *hapd, 851 struct dfs_event *radar) 852{ 853 wpa_printf(MSG_DEBUG, "DFS CAC finished on %d MHz", radar->freq); 854 hostapd_dfs_complete_cac(hapd->iface, 1, radar->freq, radar->ht_enabled, 855 radar->chan_offset, radar->chan_width, 856 radar->cf1, radar->cf2); 857} 858 859 860static void hostapd_event_dfs_cac_aborted(struct hostapd_data *hapd, 861 struct dfs_event *radar) 862{ 863 wpa_printf(MSG_DEBUG, "DFS CAC aborted on %d MHz", radar->freq); 864 hostapd_dfs_complete_cac(hapd->iface, 0, radar->freq, radar->ht_enabled, 865 radar->chan_offset, radar->chan_width, 866 radar->cf1, radar->cf2); 867} 868 869 870static void hostapd_event_dfs_nop_finished(struct hostapd_data *hapd, 871 struct dfs_event *radar) 872{ 873 wpa_printf(MSG_DEBUG, "DFS NOP finished on %d MHz", radar->freq); 874 hostapd_dfs_nop_finished(hapd->iface, radar->freq, radar->ht_enabled, 875 radar->chan_offset, radar->chan_width, 876 radar->cf1, radar->cf2); 877} 878 879#endif /* NEED_AP_MLME */ 880 881 882void wpa_supplicant_event(void *ctx, enum wpa_event_type event, 883 union wpa_event_data *data) 884{ 885 struct hostapd_data *hapd = ctx; 886#ifndef CONFIG_NO_STDOUT_DEBUG 887 int level = MSG_DEBUG; 888 889 if (event == EVENT_RX_MGMT && data->rx_mgmt.frame && 890 data->rx_mgmt.frame_len >= 24) { 891 const struct ieee80211_hdr *hdr; 892 u16 fc; 893 hdr = (const struct ieee80211_hdr *) data->rx_mgmt.frame; 894 fc = le_to_host16(hdr->frame_control); 895 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && 896 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) 897 level = MSG_EXCESSIVE; 898 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && 899 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_REQ) 900 level = MSG_EXCESSIVE; 901 } 902 903 wpa_dbg(hapd->msg_ctx, level, "Event %s (%d) received", 904 event_to_string(event), event); 905#endif /* CONFIG_NO_STDOUT_DEBUG */ 906 907 switch (event) { 908 case EVENT_MICHAEL_MIC_FAILURE: 909 michael_mic_failure(hapd, data->michael_mic_failure.src, 1); 910 break; 911 case EVENT_SCAN_RESULTS: 912 if (hapd->iface->scan_cb) 913 hapd->iface->scan_cb(hapd->iface); 914 break; 915#ifdef CONFIG_IEEE80211R 916 case EVENT_FT_RRB_RX: 917 wpa_ft_rrb_rx(hapd->wpa_auth, data->ft_rrb_rx.src, 918 data->ft_rrb_rx.data, data->ft_rrb_rx.data_len); 919 break; 920#endif /* CONFIG_IEEE80211R */ 921 case EVENT_WPS_BUTTON_PUSHED: 922 hostapd_wps_button_pushed(hapd, NULL); 923 break; 924#ifdef NEED_AP_MLME 925 case EVENT_TX_STATUS: 926 switch (data->tx_status.type) { 927 case WLAN_FC_TYPE_MGMT: 928 hostapd_mgmt_tx_cb(hapd, data->tx_status.data, 929 data->tx_status.data_len, 930 data->tx_status.stype, 931 data->tx_status.ack); 932 break; 933 case WLAN_FC_TYPE_DATA: 934 hostapd_tx_status(hapd, data->tx_status.dst, 935 data->tx_status.data, 936 data->tx_status.data_len, 937 data->tx_status.ack); 938 break; 939 } 940 break; 941 case EVENT_EAPOL_TX_STATUS: 942 hostapd_eapol_tx_status(hapd, data->eapol_tx_status.dst, 943 data->eapol_tx_status.data, 944 data->eapol_tx_status.data_len, 945 data->eapol_tx_status.ack); 946 break; 947 case EVENT_DRIVER_CLIENT_POLL_OK: 948 hostapd_client_poll_ok(hapd, data->client_poll.addr); 949 break; 950 case EVENT_RX_FROM_UNKNOWN: 951 hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.bssid, 952 data->rx_from_unknown.addr, 953 data->rx_from_unknown.wds); 954 break; 955 case EVENT_RX_MGMT: 956 hostapd_mgmt_rx(hapd, &data->rx_mgmt); 957 break; 958#endif /* NEED_AP_MLME */ 959 case EVENT_RX_PROBE_REQ: 960 if (data->rx_probe_req.sa == NULL || 961 data->rx_probe_req.ie == NULL) 962 break; 963 hostapd_probe_req_rx(hapd, data->rx_probe_req.sa, 964 data->rx_probe_req.da, 965 data->rx_probe_req.bssid, 966 data->rx_probe_req.ie, 967 data->rx_probe_req.ie_len, 968 data->rx_probe_req.ssi_signal); 969 break; 970 case EVENT_NEW_STA: 971 hostapd_event_new_sta(hapd, data->new_sta.addr); 972 break; 973 case EVENT_EAPOL_RX: 974 hostapd_event_eapol_rx(hapd, data->eapol_rx.src, 975 data->eapol_rx.data, 976 data->eapol_rx.data_len); 977 break; 978 case EVENT_ASSOC: 979 hostapd_notif_assoc(hapd, data->assoc_info.addr, 980 data->assoc_info.req_ies, 981 data->assoc_info.req_ies_len, 982 data->assoc_info.reassoc); 983 break; 984 case EVENT_DISASSOC: 985 if (data) 986 hostapd_notif_disassoc(hapd, data->disassoc_info.addr); 987 break; 988 case EVENT_DEAUTH: 989 if (data) 990 hostapd_notif_disassoc(hapd, data->deauth_info.addr); 991 break; 992 case EVENT_STATION_LOW_ACK: 993 if (!data) 994 break; 995 hostapd_event_sta_low_ack(hapd, data->low_ack.addr); 996 break; 997 case EVENT_RX_ACTION: 998 if (data->rx_action.da == NULL || data->rx_action.sa == NULL || 999 data->rx_action.bssid == NULL) 1000 break; 1001#ifdef NEED_AP_MLME 1002 hostapd_rx_action(hapd, &data->rx_action); 1003#endif /* NEED_AP_MLME */ 1004 hostapd_action_rx(hapd, &data->rx_action); 1005 break; 1006 case EVENT_AUTH: 1007 hostapd_notif_auth(hapd, &data->auth); 1008 break; 1009 case EVENT_CH_SWITCH: 1010 if (!data) 1011 break; 1012 hostapd_event_ch_switch(hapd, data->ch_switch.freq, 1013 data->ch_switch.ht_enabled, 1014 data->ch_switch.ch_offset, 1015 data->ch_switch.ch_width, 1016 data->ch_switch.cf1, 1017 data->ch_switch.cf2); 1018 break; 1019 case EVENT_CONNECT_FAILED_REASON: 1020 if (!data) 1021 break; 1022 hostapd_event_connect_failed_reason( 1023 hapd, data->connect_failed_reason.addr, 1024 data->connect_failed_reason.code); 1025 break; 1026 case EVENT_SURVEY: 1027 hostapd_event_get_survey(hapd, &data->survey_results); 1028 break; 1029#ifdef NEED_AP_MLME 1030 case EVENT_DFS_RADAR_DETECTED: 1031 if (!data) 1032 break; 1033 hostapd_event_dfs_radar_detected(hapd, &data->dfs_event); 1034 break; 1035 case EVENT_DFS_CAC_FINISHED: 1036 if (!data) 1037 break; 1038 hostapd_event_dfs_cac_finished(hapd, &data->dfs_event); 1039 break; 1040 case EVENT_DFS_CAC_ABORTED: 1041 if (!data) 1042 break; 1043 hostapd_event_dfs_cac_aborted(hapd, &data->dfs_event); 1044 break; 1045 case EVENT_DFS_NOP_FINISHED: 1046 if (!data) 1047 break; 1048 hostapd_event_dfs_nop_finished(hapd, &data->dfs_event); 1049 break; 1050 case EVENT_CHANNEL_LIST_CHANGED: 1051 /* channel list changed (regulatory?), update channel list */ 1052 /* TODO: check this. hostapd_get_hw_features() initializes 1053 * too much stuff. */ 1054 /* hostapd_get_hw_features(hapd->iface); */ 1055 hostapd_channel_list_updated( 1056 hapd->iface, data->channel_list_changed.initiator); 1057 break; 1058#endif /* NEED_AP_MLME */ 1059 default: 1060 wpa_printf(MSG_DEBUG, "Unknown event %d", event); 1061 break; 1062 } 1063} 1064 1065#endif /* HOSTAPD */ 1066