1 /* 2 * hostapd / Callback functions for driver wrappers 3 * Copyright (c) 2002-2009, 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 "crypto/random.h" 17 #include "p2p/p2p.h" 18 #include "wps/wps.h" 19 #include "wnm_ap.h" 20 #include "hostapd.h" 21 #include "ieee802_11.h" 22 #include "sta_info.h" 23 #include "accounting.h" 24 #include "tkip_countermeasures.h" 25 #include "ieee802_1x.h" 26 #include "wpa_auth.h" 27 #include "wps_hostapd.h" 28 #include "ap_drv_ops.h" 29 #include "ap_config.h" 30 #include "hw_features.h" 31 32 33 int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, 34 const u8 *req_ies, size_t req_ies_len, int reassoc) 35 { 36 struct sta_info *sta; 37 int new_assoc, res; 38 struct ieee802_11_elems elems; 39 const u8 *ie; 40 size_t ielen; 41 #ifdef CONFIG_IEEE80211R 42 u8 buf[sizeof(struct ieee80211_mgmt) + 1024]; 43 u8 *p = buf; 44 #endif /* CONFIG_IEEE80211R */ 45 u16 reason = WLAN_REASON_UNSPECIFIED; 46 u16 status = WLAN_STATUS_SUCCESS; 47 48 if (addr == NULL) { 49 /* 50 * This could potentially happen with unexpected event from the 51 * driver wrapper. This was seen at least in one case where the 52 * driver ended up being set to station mode while hostapd was 53 * running, so better make sure we stop processing such an 54 * event here. 55 */ 56 wpa_printf(MSG_DEBUG, "hostapd_notif_assoc: Skip event with " 57 "no address"); 58 return -1; 59 } 60 random_add_randomness(addr, ETH_ALEN); 61 62 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, 63 HOSTAPD_LEVEL_INFO, "associated"); 64 65 ieee802_11_parse_elems(req_ies, req_ies_len, &elems, 0); 66 if (elems.wps_ie) { 67 ie = elems.wps_ie - 2; 68 ielen = elems.wps_ie_len + 2; 69 wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)AssocReq"); 70 } else if (elems.rsn_ie) { 71 ie = elems.rsn_ie - 2; 72 ielen = elems.rsn_ie_len + 2; 73 wpa_printf(MSG_DEBUG, "STA included RSN IE in (Re)AssocReq"); 74 } else if (elems.wpa_ie) { 75 ie = elems.wpa_ie - 2; 76 ielen = elems.wpa_ie_len + 2; 77 wpa_printf(MSG_DEBUG, "STA included WPA IE in (Re)AssocReq"); 78 } else { 79 ie = NULL; 80 ielen = 0; 81 wpa_printf(MSG_DEBUG, "STA did not include WPS/RSN/WPA IE in " 82 "(Re)AssocReq"); 83 } 84 85 sta = ap_get_sta(hapd, addr); 86 if (sta) { 87 accounting_sta_stop(hapd, sta); 88 89 /* 90 * Make sure that the previously registered inactivity timer 91 * will not remove the STA immediately. 92 */ 93 sta->timeout_next = STA_NULLFUNC; 94 } else { 95 sta = ap_sta_add(hapd, addr); 96 if (sta == NULL) { 97 hostapd_drv_sta_disassoc(hapd, addr, 98 WLAN_REASON_DISASSOC_AP_BUSY); 99 return -1; 100 } 101 } 102 sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2); 103 104 #ifdef CONFIG_P2P 105 if (elems.p2p) { 106 wpabuf_free(sta->p2p_ie); 107 sta->p2p_ie = ieee802_11_vendor_ie_concat(req_ies, req_ies_len, 108 P2P_IE_VENDOR_TYPE); 109 } 110 #endif /* CONFIG_P2P */ 111 112 #ifdef CONFIG_HS20 113 wpabuf_free(sta->hs20_ie); 114 if (elems.hs20 && elems.hs20_len > 4) { 115 sta->hs20_ie = wpabuf_alloc_copy(elems.hs20 + 4, 116 elems.hs20_len - 4); 117 } else 118 sta->hs20_ie = NULL; 119 #endif /* CONFIG_HS20 */ 120 121 if (hapd->conf->wpa) { 122 if (ie == NULL || ielen == 0) { 123 #ifdef CONFIG_WPS 124 if (hapd->conf->wps_state) { 125 wpa_printf(MSG_DEBUG, "STA did not include " 126 "WPA/RSN IE in (Re)Association " 127 "Request - possible WPS use"); 128 sta->flags |= WLAN_STA_MAYBE_WPS; 129 goto skip_wpa_check; 130 } 131 #endif /* CONFIG_WPS */ 132 133 wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA"); 134 return -1; 135 } 136 #ifdef CONFIG_WPS 137 if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 && 138 os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) { 139 struct wpabuf *wps; 140 sta->flags |= WLAN_STA_WPS; 141 wps = ieee802_11_vendor_ie_concat(ie, ielen, 142 WPS_IE_VENDOR_TYPE); 143 if (wps) { 144 if (wps_is_20(wps)) { 145 wpa_printf(MSG_DEBUG, "WPS: STA " 146 "supports WPS 2.0"); 147 sta->flags |= WLAN_STA_WPS2; 148 } 149 wpabuf_free(wps); 150 } 151 goto skip_wpa_check; 152 } 153 #endif /* CONFIG_WPS */ 154 155 if (sta->wpa_sm == NULL) 156 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, 157 sta->addr); 158 if (sta->wpa_sm == NULL) { 159 wpa_printf(MSG_ERROR, "Failed to initialize WPA state " 160 "machine"); 161 return -1; 162 } 163 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, 164 ie, ielen, 165 elems.mdie, elems.mdie_len); 166 if (res != WPA_IE_OK) { 167 wpa_printf(MSG_DEBUG, "WPA/RSN information element " 168 "rejected? (res %u)", res); 169 wpa_hexdump(MSG_DEBUG, "IE", ie, ielen); 170 if (res == WPA_INVALID_GROUP) { 171 reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID; 172 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; 173 } else if (res == WPA_INVALID_PAIRWISE) { 174 reason = WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID; 175 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; 176 } else if (res == WPA_INVALID_AKMP) { 177 reason = WLAN_REASON_AKMP_NOT_VALID; 178 status = WLAN_STATUS_AKMP_NOT_VALID; 179 } 180 #ifdef CONFIG_IEEE80211W 181 else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION) { 182 reason = WLAN_REASON_INVALID_IE; 183 status = WLAN_STATUS_INVALID_IE; 184 } else if (res == WPA_INVALID_MGMT_GROUP_CIPHER) { 185 reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID; 186 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; 187 } 188 #endif /* CONFIG_IEEE80211W */ 189 else { 190 reason = WLAN_REASON_INVALID_IE; 191 status = WLAN_STATUS_INVALID_IE; 192 } 193 goto fail; 194 } 195 #ifdef CONFIG_IEEE80211W 196 if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out && 197 sta->sa_query_count > 0) 198 ap_check_sa_query_timeout(hapd, sta); 199 if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out && 200 (sta->auth_alg != WLAN_AUTH_FT)) { 201 /* 202 * STA has already been associated with MFP and SA 203 * Query timeout has not been reached. Reject the 204 * association attempt temporarily and start SA Query, 205 * if one is not pending. 206 */ 207 208 if (sta->sa_query_count == 0) 209 ap_sta_start_sa_query(hapd, sta); 210 211 #ifdef CONFIG_IEEE80211R 212 status = WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY; 213 214 p = hostapd_eid_assoc_comeback_time(hapd, sta, p); 215 216 hostapd_sta_assoc(hapd, addr, reassoc, status, buf, 217 p - buf); 218 #endif /* CONFIG_IEEE80211R */ 219 return 0; 220 } 221 222 if (wpa_auth_uses_mfp(sta->wpa_sm)) 223 sta->flags |= WLAN_STA_MFP; 224 else 225 sta->flags &= ~WLAN_STA_MFP; 226 #endif /* CONFIG_IEEE80211W */ 227 228 #ifdef CONFIG_IEEE80211R 229 if (sta->auth_alg == WLAN_AUTH_FT) { 230 status = wpa_ft_validate_reassoc(sta->wpa_sm, req_ies, 231 req_ies_len); 232 if (status != WLAN_STATUS_SUCCESS) { 233 if (status == WLAN_STATUS_INVALID_PMKID) 234 reason = WLAN_REASON_INVALID_IE; 235 if (status == WLAN_STATUS_INVALID_MDIE) 236 reason = WLAN_REASON_INVALID_IE; 237 if (status == WLAN_STATUS_INVALID_FTIE) 238 reason = WLAN_REASON_INVALID_IE; 239 goto fail; 240 } 241 } 242 #endif /* CONFIG_IEEE80211R */ 243 } else if (hapd->conf->wps_state) { 244 #ifdef CONFIG_WPS 245 struct wpabuf *wps; 246 if (req_ies) 247 wps = ieee802_11_vendor_ie_concat(req_ies, req_ies_len, 248 WPS_IE_VENDOR_TYPE); 249 else 250 wps = NULL; 251 #ifdef CONFIG_WPS_STRICT 252 if (wps && wps_validate_assoc_req(wps) < 0) { 253 reason = WLAN_REASON_INVALID_IE; 254 status = WLAN_STATUS_INVALID_IE; 255 wpabuf_free(wps); 256 goto fail; 257 } 258 #endif /* CONFIG_WPS_STRICT */ 259 if (wps) { 260 sta->flags |= WLAN_STA_WPS; 261 if (wps_is_20(wps)) { 262 wpa_printf(MSG_DEBUG, "WPS: STA supports " 263 "WPS 2.0"); 264 sta->flags |= WLAN_STA_WPS2; 265 } 266 } else 267 sta->flags |= WLAN_STA_MAYBE_WPS; 268 wpabuf_free(wps); 269 #endif /* CONFIG_WPS */ 270 } 271 #ifdef CONFIG_WPS 272 skip_wpa_check: 273 #endif /* CONFIG_WPS */ 274 275 #ifdef CONFIG_IEEE80211R 276 p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, buf, sizeof(buf), 277 sta->auth_alg, req_ies, req_ies_len); 278 279 hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf); 280 #else /* CONFIG_IEEE80211R */ 281 /* Keep compiler silent about unused variables */ 282 if (status) { 283 } 284 #endif /* CONFIG_IEEE80211R */ 285 286 new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0; 287 sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC; 288 289 if (reassoc && (sta->auth_alg == WLAN_AUTH_FT)) 290 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT); 291 else 292 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC); 293 294 hostapd_new_assoc_sta(hapd, sta, !new_assoc); 295 296 ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); 297 298 #ifdef CONFIG_P2P 299 if (req_ies) { 300 p2p_group_notif_assoc(hapd->p2p_group, sta->addr, 301 req_ies, req_ies_len); 302 } 303 #endif /* CONFIG_P2P */ 304 305 return 0; 306 307 fail: 308 #ifdef CONFIG_IEEE80211R 309 hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf); 310 #endif /* CONFIG_IEEE80211R */ 311 hostapd_drv_sta_disassoc(hapd, sta->addr, reason); 312 ap_free_sta(hapd, sta); 313 return -1; 314 } 315 316 317 void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr) 318 { 319 struct sta_info *sta; 320 321 if (addr == NULL) { 322 /* 323 * This could potentially happen with unexpected event from the 324 * driver wrapper. This was seen at least in one case where the 325 * driver ended up reporting a station mode event while hostapd 326 * was running, so better make sure we stop processing such an 327 * event here. 328 */ 329 wpa_printf(MSG_DEBUG, "hostapd_notif_disassoc: Skip event " 330 "with no address"); 331 return; 332 } 333 334 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, 335 HOSTAPD_LEVEL_INFO, "disassociated"); 336 337 sta = ap_get_sta(hapd, addr); 338 if (sta == NULL) { 339 wpa_printf(MSG_DEBUG, "Disassociation notification for " 340 "unknown STA " MACSTR, MAC2STR(addr)); 341 return; 342 } 343 344 ap_sta_set_authorized(hapd, sta, 0); 345 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); 346 wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC); 347 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; 348 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); 349 ap_free_sta(hapd, sta); 350 } 351 352 353 void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr) 354 { 355 struct sta_info *sta = ap_get_sta(hapd, addr); 356 357 if (!sta || !hapd->conf->disassoc_low_ack) 358 return; 359 360 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, 361 HOSTAPD_LEVEL_INFO, "disconnected due to excessive " 362 "missing ACKs"); 363 hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_DISASSOC_LOW_ACK); 364 if (sta) 365 ap_sta_disassociate(hapd, sta, WLAN_REASON_DISASSOC_LOW_ACK); 366 } 367 368 369 void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, 370 int offset) 371 { 372 #ifdef NEED_AP_MLME 373 int channel; 374 375 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, 376 HOSTAPD_LEVEL_INFO, "driver had channel switch: " 377 "freq=%d, ht=%d, offset=%d", freq, ht, offset); 378 379 hapd->iface->freq = freq; 380 381 channel = hostapd_hw_get_channel(hapd, freq); 382 if (!channel) { 383 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, 384 HOSTAPD_LEVEL_WARNING, "driver switched to " 385 "bad channel!"); 386 return; 387 } 388 389 hapd->iconf->channel = channel; 390 hapd->iconf->ieee80211n = ht; 391 hapd->iconf->secondary_channel = offset; 392 #endif /* NEED_AP_MLME */ 393 } 394 395 396 int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da, 397 const u8 *bssid, const u8 *ie, size_t ie_len, 398 int ssi_signal) 399 { 400 size_t i; 401 int ret = 0; 402 403 if (sa == NULL || ie == NULL) 404 return -1; 405 406 random_add_randomness(sa, ETH_ALEN); 407 for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) { 408 if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx, 409 sa, da, bssid, ie, ie_len, 410 ssi_signal) > 0) { 411 ret = 1; 412 break; 413 } 414 } 415 return ret; 416 } 417 418 419 #ifdef HOSTAPD 420 421 #ifdef CONFIG_IEEE80211R 422 static void hostapd_notify_auth_ft_finish(void *ctx, const u8 *dst, 423 const u8 *bssid, 424 u16 auth_transaction, u16 status, 425 const u8 *ies, size_t ies_len) 426 { 427 struct hostapd_data *hapd = ctx; 428 struct sta_info *sta; 429 430 sta = ap_get_sta(hapd, dst); 431 if (sta == NULL) 432 return; 433 434 hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211, 435 HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)"); 436 sta->flags |= WLAN_STA_AUTH; 437 438 hostapd_sta_auth(hapd, dst, auth_transaction, status, ies, ies_len); 439 } 440 #endif /* CONFIG_IEEE80211R */ 441 442 443 static void hostapd_notif_auth(struct hostapd_data *hapd, 444 struct auth_info *rx_auth) 445 { 446 struct sta_info *sta; 447 u16 status = WLAN_STATUS_SUCCESS; 448 u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN]; 449 size_t resp_ies_len = 0; 450 451 sta = ap_get_sta(hapd, rx_auth->peer); 452 if (!sta) { 453 sta = ap_sta_add(hapd, rx_auth->peer); 454 if (sta == NULL) { 455 status = WLAN_STATUS_UNSPECIFIED_FAILURE; 456 goto fail; 457 } 458 } 459 sta->flags &= ~WLAN_STA_PREAUTH; 460 ieee802_1x_notify_pre_auth(sta->eapol_sm, 0); 461 #ifdef CONFIG_IEEE80211R 462 if (rx_auth->auth_type == WLAN_AUTH_FT && hapd->wpa_auth) { 463 sta->auth_alg = WLAN_AUTH_FT; 464 if (sta->wpa_sm == NULL) 465 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, 466 sta->addr); 467 if (sta->wpa_sm == NULL) { 468 wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA " 469 "state machine"); 470 status = WLAN_STATUS_UNSPECIFIED_FAILURE; 471 goto fail; 472 } 473 wpa_ft_process_auth(sta->wpa_sm, rx_auth->bssid, 474 rx_auth->auth_transaction, rx_auth->ies, 475 rx_auth->ies_len, 476 hostapd_notify_auth_ft_finish, hapd); 477 return; 478 } 479 #endif /* CONFIG_IEEE80211R */ 480 fail: 481 hostapd_sta_auth(hapd, rx_auth->peer, rx_auth->auth_transaction + 1, 482 status, resp_ies, resp_ies_len); 483 } 484 485 486 static void hostapd_action_rx(struct hostapd_data *hapd, 487 struct rx_action *action) 488 { 489 struct sta_info *sta; 490 491 wpa_printf(MSG_DEBUG, "RX_ACTION cat %d action plen %d", 492 action->category, (int) action->len); 493 494 sta = ap_get_sta(hapd, action->sa); 495 if (sta == NULL) { 496 wpa_printf(MSG_DEBUG, "%s: station not found", __func__); 497 return; 498 } 499 #ifdef CONFIG_IEEE80211R 500 if (action->category == WLAN_ACTION_FT) { 501 wpa_printf(MSG_DEBUG, "%s: FT_ACTION length %d", 502 __func__, (int) action->len); 503 wpa_ft_action_rx(sta->wpa_sm, action->data, action->len); 504 } 505 #endif /* CONFIG_IEEE80211R */ 506 #ifdef CONFIG_IEEE80211W 507 if (action->category == WLAN_ACTION_SA_QUERY && action->len >= 4) { 508 wpa_printf(MSG_DEBUG, "%s: SA_QUERY_ACTION length %d", 509 __func__, (int) action->len); 510 ieee802_11_sa_query_action(hapd, action->sa, 511 *(action->data + 1), 512 action->data + 2); 513 } 514 #endif /* CONFIG_IEEE80211W */ 515 #ifdef CONFIG_WNM 516 if (action->category == WLAN_ACTION_WNM) { 517 wpa_printf(MSG_DEBUG, "%s: WNM_ACTION length %d", 518 __func__, (int) action->len); 519 ieee802_11_rx_wnm_action_ap(hapd, action); 520 } 521 #endif /* CONFIG_WNM */ 522 } 523 524 525 #ifdef NEED_AP_MLME 526 527 #define HAPD_BROADCAST ((struct hostapd_data *) -1) 528 529 static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface, 530 const u8 *bssid) 531 { 532 size_t i; 533 534 if (bssid == NULL) 535 return NULL; 536 if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff && 537 bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff) 538 return HAPD_BROADCAST; 539 540 for (i = 0; i < iface->num_bss; i++) { 541 if (os_memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0) 542 return iface->bss[i]; 543 } 544 545 return NULL; 546 } 547 548 549 static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd, 550 const u8 *bssid, const u8 *addr, 551 int wds) 552 { 553 hapd = get_hapd_bssid(hapd->iface, bssid); 554 if (hapd == NULL || hapd == HAPD_BROADCAST) 555 return; 556 557 ieee802_11_rx_from_unknown(hapd, addr, wds); 558 } 559 560 561 static void hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt) 562 { 563 struct hostapd_iface *iface = hapd->iface; 564 const struct ieee80211_hdr *hdr; 565 const u8 *bssid; 566 struct hostapd_frame_info fi; 567 568 hdr = (const struct ieee80211_hdr *) rx_mgmt->frame; 569 bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len); 570 if (bssid == NULL) 571 return; 572 573 hapd = get_hapd_bssid(iface, bssid); 574 if (hapd == NULL) { 575 u16 fc; 576 fc = le_to_host16(hdr->frame_control); 577 578 /* 579 * Drop frames to unknown BSSIDs except for Beacon frames which 580 * could be used to update neighbor information. 581 */ 582 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && 583 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) 584 hapd = iface->bss[0]; 585 else 586 return; 587 } 588 589 os_memset(&fi, 0, sizeof(fi)); 590 fi.datarate = rx_mgmt->datarate; 591 fi.ssi_signal = rx_mgmt->ssi_signal; 592 593 if (hapd == HAPD_BROADCAST) { 594 size_t i; 595 for (i = 0; i < iface->num_bss; i++) 596 ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame, 597 rx_mgmt->frame_len, &fi); 598 } else 599 ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len, &fi); 600 601 random_add_randomness(&fi, sizeof(fi)); 602 } 603 604 605 static void hostapd_rx_action(struct hostapd_data *hapd, 606 struct rx_action *rx_action) 607 { 608 struct rx_mgmt rx_mgmt; 609 u8 *buf; 610 struct ieee80211_hdr *hdr; 611 612 wpa_printf(MSG_DEBUG, "EVENT_RX_ACTION DA=" MACSTR " SA=" MACSTR 613 " BSSID=" MACSTR " category=%u", 614 MAC2STR(rx_action->da), MAC2STR(rx_action->sa), 615 MAC2STR(rx_action->bssid), rx_action->category); 616 wpa_hexdump(MSG_MSGDUMP, "Received action frame contents", 617 rx_action->data, rx_action->len); 618 619 buf = os_zalloc(24 + 1 + rx_action->len); 620 if (buf == NULL) 621 return; 622 hdr = (struct ieee80211_hdr *) buf; 623 hdr->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 624 WLAN_FC_STYPE_ACTION); 625 if (rx_action->category == WLAN_ACTION_SA_QUERY) { 626 /* 627 * Assume frame was protected; it would have been dropped if 628 * not. 629 */ 630 hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP); 631 } 632 os_memcpy(hdr->addr1, rx_action->da, ETH_ALEN); 633 os_memcpy(hdr->addr2, rx_action->sa, ETH_ALEN); 634 os_memcpy(hdr->addr3, rx_action->bssid, ETH_ALEN); 635 buf[24] = rx_action->category; 636 os_memcpy(buf + 24 + 1, rx_action->data, rx_action->len); 637 os_memset(&rx_mgmt, 0, sizeof(rx_mgmt)); 638 rx_mgmt.frame = buf; 639 rx_mgmt.frame_len = 24 + 1 + rx_action->len; 640 hostapd_mgmt_rx(hapd, &rx_mgmt); 641 os_free(buf); 642 } 643 644 645 static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf, 646 size_t len, u16 stype, int ok) 647 { 648 struct ieee80211_hdr *hdr; 649 hdr = (struct ieee80211_hdr *) buf; 650 hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len)); 651 if (hapd == NULL || hapd == HAPD_BROADCAST) 652 return; 653 ieee802_11_mgmt_cb(hapd, buf, len, stype, ok); 654 } 655 656 #endif /* NEED_AP_MLME */ 657 658 659 static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr) 660 { 661 struct sta_info *sta = ap_get_sta(hapd, addr); 662 if (sta) 663 return 0; 664 665 wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR 666 " - adding a new STA", MAC2STR(addr)); 667 sta = ap_sta_add(hapd, addr); 668 if (sta) { 669 hostapd_new_assoc_sta(hapd, sta, 0); 670 } else { 671 wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR, 672 MAC2STR(addr)); 673 return -1; 674 } 675 676 return 0; 677 } 678 679 680 static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src, 681 const u8 *data, size_t data_len) 682 { 683 struct hostapd_iface *iface = hapd->iface; 684 struct sta_info *sta; 685 size_t j; 686 687 for (j = 0; j < iface->num_bss; j++) { 688 if ((sta = ap_get_sta(iface->bss[j], src))) { 689 if (sta->flags & WLAN_STA_ASSOC) { 690 hapd = iface->bss[j]; 691 break; 692 } 693 } 694 } 695 696 ieee802_1x_receive(hapd, src, data, data_len); 697 } 698 699 700 void wpa_supplicant_event(void *ctx, enum wpa_event_type event, 701 union wpa_event_data *data) 702 { 703 struct hostapd_data *hapd = ctx; 704 #ifndef CONFIG_NO_STDOUT_DEBUG 705 int level = MSG_DEBUG; 706 707 if (event == EVENT_RX_MGMT && data->rx_mgmt.frame && 708 data->rx_mgmt.frame_len >= 24) { 709 const struct ieee80211_hdr *hdr; 710 u16 fc; 711 hdr = (const struct ieee80211_hdr *) data->rx_mgmt.frame; 712 fc = le_to_host16(hdr->frame_control); 713 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && 714 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) 715 level = MSG_EXCESSIVE; 716 } 717 718 wpa_dbg(hapd->msg_ctx, level, "Event %s (%d) received", 719 event_to_string(event), event); 720 #endif /* CONFIG_NO_STDOUT_DEBUG */ 721 722 switch (event) { 723 case EVENT_MICHAEL_MIC_FAILURE: 724 michael_mic_failure(hapd, data->michael_mic_failure.src, 1); 725 break; 726 case EVENT_SCAN_RESULTS: 727 if (hapd->iface->scan_cb) 728 hapd->iface->scan_cb(hapd->iface); 729 break; 730 #ifdef CONFIG_IEEE80211R 731 case EVENT_FT_RRB_RX: 732 wpa_ft_rrb_rx(hapd->wpa_auth, data->ft_rrb_rx.src, 733 data->ft_rrb_rx.data, data->ft_rrb_rx.data_len); 734 break; 735 #endif /* CONFIG_IEEE80211R */ 736 case EVENT_WPS_BUTTON_PUSHED: 737 hostapd_wps_button_pushed(hapd, NULL); 738 break; 739 #ifdef NEED_AP_MLME 740 case EVENT_TX_STATUS: 741 switch (data->tx_status.type) { 742 case WLAN_FC_TYPE_MGMT: 743 hostapd_mgmt_tx_cb(hapd, data->tx_status.data, 744 data->tx_status.data_len, 745 data->tx_status.stype, 746 data->tx_status.ack); 747 break; 748 case WLAN_FC_TYPE_DATA: 749 hostapd_tx_status(hapd, data->tx_status.dst, 750 data->tx_status.data, 751 data->tx_status.data_len, 752 data->tx_status.ack); 753 break; 754 } 755 break; 756 case EVENT_EAPOL_TX_STATUS: 757 hostapd_eapol_tx_status(hapd, data->eapol_tx_status.dst, 758 data->eapol_tx_status.data, 759 data->eapol_tx_status.data_len, 760 data->eapol_tx_status.ack); 761 break; 762 case EVENT_DRIVER_CLIENT_POLL_OK: 763 hostapd_client_poll_ok(hapd, data->client_poll.addr); 764 break; 765 case EVENT_RX_FROM_UNKNOWN: 766 hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.bssid, 767 data->rx_from_unknown.addr, 768 data->rx_from_unknown.wds); 769 break; 770 case EVENT_RX_MGMT: 771 hostapd_mgmt_rx(hapd, &data->rx_mgmt); 772 break; 773 #endif /* NEED_AP_MLME */ 774 case EVENT_RX_PROBE_REQ: 775 if (data->rx_probe_req.sa == NULL || 776 data->rx_probe_req.ie == NULL) 777 break; 778 hostapd_probe_req_rx(hapd, data->rx_probe_req.sa, 779 data->rx_probe_req.da, 780 data->rx_probe_req.bssid, 781 data->rx_probe_req.ie, 782 data->rx_probe_req.ie_len, 783 data->rx_probe_req.ssi_signal); 784 break; 785 case EVENT_NEW_STA: 786 hostapd_event_new_sta(hapd, data->new_sta.addr); 787 break; 788 case EVENT_EAPOL_RX: 789 hostapd_event_eapol_rx(hapd, data->eapol_rx.src, 790 data->eapol_rx.data, 791 data->eapol_rx.data_len); 792 break; 793 case EVENT_ASSOC: 794 hostapd_notif_assoc(hapd, data->assoc_info.addr, 795 data->assoc_info.req_ies, 796 data->assoc_info.req_ies_len, 797 data->assoc_info.reassoc); 798 break; 799 case EVENT_DISASSOC: 800 if (data) 801 hostapd_notif_disassoc(hapd, data->disassoc_info.addr); 802 break; 803 case EVENT_DEAUTH: 804 if (data) 805 hostapd_notif_disassoc(hapd, data->deauth_info.addr); 806 break; 807 case EVENT_STATION_LOW_ACK: 808 if (!data) 809 break; 810 hostapd_event_sta_low_ack(hapd, data->low_ack.addr); 811 break; 812 case EVENT_RX_ACTION: 813 if (data->rx_action.da == NULL || data->rx_action.sa == NULL || 814 data->rx_action.bssid == NULL) 815 break; 816 #ifdef NEED_AP_MLME 817 hostapd_rx_action(hapd, &data->rx_action); 818 #endif /* NEED_AP_MLME */ 819 hostapd_action_rx(hapd, &data->rx_action); 820 break; 821 case EVENT_AUTH: 822 hostapd_notif_auth(hapd, &data->auth); 823 break; 824 case EVENT_CH_SWITCH: 825 if (!data) 826 break; 827 hostapd_event_ch_switch(hapd, data->ch_switch.freq, 828 data->ch_switch.ht_enabled, 829 data->ch_switch.ch_offset); 830 break; 831 default: 832 wpa_printf(MSG_DEBUG, "Unknown event %d", event); 833 break; 834 } 835 } 836 837 #endif /* HOSTAPD */ 838