1 /* 2 * hostapd / Callback functions for driver wrappers 3 * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> 4 * 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. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15 #include "utils/includes.h" 16 17 #include "utils/common.h" 18 #include "radius/radius.h" 19 #include "drivers/driver.h" 20 #include "common/ieee802_11_defs.h" 21 #include "common/ieee802_11_common.h" 22 #include "common/wpa_ctrl.h" 23 #include "crypto/random.h" 24 #include "p2p/p2p.h" 25 #include "wps/wps.h" 26 #include "hostapd.h" 27 #include "ieee802_11.h" 28 #include "sta_info.h" 29 #include "accounting.h" 30 #include "tkip_countermeasures.h" 31 #include "iapp.h" 32 #include "ieee802_1x.h" 33 #include "wpa_auth.h" 34 #include "wmm.h" 35 #include "wps_hostapd.h" 36 #include "ap_drv_ops.h" 37 #include "ap_config.h" 38 39 40 int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, 41 const u8 *req_ies, size_t req_ies_len, int reassoc) 42 { 43 struct sta_info *sta; 44 int new_assoc, res; 45 struct ieee802_11_elems elems; 46 const u8 *ie; 47 size_t ielen; 48 u16 reason = WLAN_REASON_UNSPECIFIED; 49 50 if (addr == NULL) { 51 /* 52 * This could potentially happen with unexpected event from the 53 * driver wrapper. This was seen at least in one case where the 54 * driver ended up being set to station mode while hostapd was 55 * running, so better make sure we stop processing such an 56 * event here. 57 */ 58 wpa_printf(MSG_DEBUG, "hostapd_notif_assoc: Skip event with " 59 "no address"); 60 return -1; 61 } 62 random_add_randomness(addr, ETH_ALEN); 63 64 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, 65 HOSTAPD_LEVEL_INFO, "associated"); 66 67 ieee802_11_parse_elems(req_ies, req_ies_len, &elems, 0); 68 if (elems.wps_ie) { 69 ie = elems.wps_ie - 2; 70 ielen = elems.wps_ie_len + 2; 71 wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)AssocReq"); 72 } else if (elems.rsn_ie) { 73 ie = elems.rsn_ie - 2; 74 ielen = elems.rsn_ie_len + 2; 75 wpa_printf(MSG_DEBUG, "STA included RSN IE in (Re)AssocReq"); 76 } else if (elems.wpa_ie) { 77 ie = elems.wpa_ie - 2; 78 ielen = elems.wpa_ie_len + 2; 79 wpa_printf(MSG_DEBUG, "STA included WPA IE in (Re)AssocReq"); 80 } else { 81 ie = NULL; 82 ielen = 0; 83 wpa_printf(MSG_DEBUG, "STA did not include WPS/RSN/WPA IE in " 84 "(Re)AssocReq"); 85 } 86 87 sta = ap_get_sta(hapd, addr); 88 if (sta) { 89 accounting_sta_stop(hapd, sta); 90 91 /* 92 * Make sure that the previously registered inactivity timer 93 * will not remove the STA immediately. 94 */ 95 sta->timeout_next = STA_NULLFUNC; 96 } else { 97 sta = ap_sta_add(hapd, addr); 98 if (sta == NULL) 99 return -1; 100 } 101 sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2); 102 103 #ifdef CONFIG_P2P 104 if (elems.p2p) { 105 wpabuf_free(sta->p2p_ie); 106 sta->p2p_ie = ieee802_11_vendor_ie_concat(req_ies, req_ies_len, 107 P2P_IE_VENDOR_TYPE); 108 } 109 #endif /* CONFIG_P2P */ 110 111 if (hapd->conf->wpa) { 112 if (ie == NULL || ielen == 0) { 113 #ifdef CONFIG_WPS 114 if (hapd->conf->wps_state) { 115 wpa_printf(MSG_DEBUG, "STA did not include " 116 "WPA/RSN IE in (Re)Association " 117 "Request - possible WPS use"); 118 sta->flags |= WLAN_STA_MAYBE_WPS; 119 goto skip_wpa_check; 120 } 121 #endif /* CONFIG_WPS */ 122 123 wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA"); 124 return -1; 125 } 126 #ifdef CONFIG_WPS 127 if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 && 128 os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) { 129 struct wpabuf *wps; 130 sta->flags |= WLAN_STA_WPS; 131 wps = ieee802_11_vendor_ie_concat(ie, ielen, 132 WPS_IE_VENDOR_TYPE); 133 if (wps) { 134 if (wps_is_20(wps)) { 135 wpa_printf(MSG_DEBUG, "WPS: STA " 136 "supports WPS 2.0"); 137 sta->flags |= WLAN_STA_WPS2; 138 } 139 wpabuf_free(wps); 140 } 141 goto skip_wpa_check; 142 } 143 #endif /* CONFIG_WPS */ 144 145 if (sta->wpa_sm == NULL) 146 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, 147 sta->addr); 148 if (sta->wpa_sm == NULL) { 149 wpa_printf(MSG_ERROR, "Failed to initialize WPA state " 150 "machine"); 151 return -1; 152 } 153 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, 154 ie, ielen, NULL, 0); 155 if (res != WPA_IE_OK) { 156 wpa_printf(MSG_DEBUG, "WPA/RSN information element " 157 "rejected? (res %u)", res); 158 wpa_hexdump(MSG_DEBUG, "IE", ie, ielen); 159 if (res == WPA_INVALID_GROUP) 160 reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID; 161 else if (res == WPA_INVALID_PAIRWISE) 162 reason = WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID; 163 else if (res == WPA_INVALID_AKMP) 164 reason = WLAN_REASON_AKMP_NOT_VALID; 165 #ifdef CONFIG_IEEE80211W 166 else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION) 167 reason = WLAN_REASON_INVALID_IE; 168 else if (res == WPA_INVALID_MGMT_GROUP_CIPHER) 169 reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID; 170 #endif /* CONFIG_IEEE80211W */ 171 else 172 reason = WLAN_REASON_INVALID_IE; 173 goto fail; 174 } 175 } else if (hapd->conf->wps_state) { 176 #ifdef CONFIG_WPS 177 struct wpabuf *wps; 178 if (req_ies) 179 wps = ieee802_11_vendor_ie_concat(req_ies, req_ies_len, 180 WPS_IE_VENDOR_TYPE); 181 else 182 wps = NULL; 183 #ifdef CONFIG_WPS_STRICT 184 if (wps && wps_validate_assoc_req(wps) < 0) { 185 reason = WLAN_REASON_INVALID_IE; 186 wpabuf_free(wps); 187 goto fail; 188 } 189 #endif /* CONFIG_WPS_STRICT */ 190 if (wps) { 191 sta->flags |= WLAN_STA_WPS; 192 if (wps_is_20(wps)) { 193 wpa_printf(MSG_DEBUG, "WPS: STA supports " 194 "WPS 2.0"); 195 sta->flags |= WLAN_STA_WPS2; 196 } 197 } else 198 sta->flags |= WLAN_STA_MAYBE_WPS; 199 wpabuf_free(wps); 200 #endif /* CONFIG_WPS */ 201 } 202 #ifdef CONFIG_WPS 203 skip_wpa_check: 204 #endif /* CONFIG_WPS */ 205 206 new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0; 207 sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC; 208 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC); 209 210 hostapd_new_assoc_sta(hapd, sta, !new_assoc); 211 212 ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); 213 214 #ifdef CONFIG_P2P 215 if (req_ies) { 216 p2p_group_notif_assoc(hapd->p2p_group, sta->addr, 217 req_ies, req_ies_len); 218 } 219 #endif /* CONFIG_P2P */ 220 221 return 0; 222 223 fail: 224 hostapd_drv_sta_disassoc(hapd, sta->addr, reason); 225 ap_free_sta(hapd, sta); 226 return -1; 227 } 228 229 230 void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr) 231 { 232 struct sta_info *sta; 233 234 if (addr == NULL) { 235 /* 236 * This could potentially happen with unexpected event from the 237 * driver wrapper. This was seen at least in one case where the 238 * driver ended up reporting a station mode event while hostapd 239 * was running, so better make sure we stop processing such an 240 * event here. 241 */ 242 wpa_printf(MSG_DEBUG, "hostapd_notif_disassoc: Skip event " 243 "with no address"); 244 return; 245 } 246 247 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, 248 HOSTAPD_LEVEL_INFO, "disassociated"); 249 250 sta = ap_get_sta(hapd, addr); 251 if (sta == NULL) { 252 wpa_printf(MSG_DEBUG, "Disassociation notification for " 253 "unknown STA " MACSTR, MAC2STR(addr)); 254 return; 255 } 256 257 ap_sta_set_authorized(hapd, sta, 0); 258 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); 259 wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC); 260 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; 261 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); 262 ap_free_sta(hapd, sta); 263 } 264 265 266 void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr) 267 { 268 struct sta_info *sta = ap_get_sta(hapd, addr); 269 270 if (!sta || !hapd->conf->disassoc_low_ack) 271 return; 272 273 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, 274 HOSTAPD_LEVEL_INFO, "disconnected due to excessive " 275 "missing ACKs"); 276 hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_DISASSOC_LOW_ACK); 277 if (sta) 278 ap_sta_disassociate(hapd, sta, WLAN_REASON_DISASSOC_LOW_ACK); 279 } 280 281 282 int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da, 283 const u8 *bssid, const u8 *ie, size_t ie_len) 284 { 285 size_t i; 286 int ret = 0; 287 288 if (sa == NULL || ie == NULL) 289 return -1; 290 291 random_add_randomness(sa, ETH_ALEN); 292 for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) { 293 if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx, 294 sa, da, bssid, ie, ie_len) > 0) { 295 ret = 1; 296 break; 297 } 298 } 299 return ret; 300 } 301 302 303 #ifdef HOSTAPD 304 305 #ifdef NEED_AP_MLME 306 307 #define HAPD_BROADCAST ((struct hostapd_data *) -1) 308 309 static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface, 310 const u8 *bssid) 311 { 312 size_t i; 313 314 if (bssid == NULL) 315 return NULL; 316 if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff && 317 bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff) 318 return HAPD_BROADCAST; 319 320 for (i = 0; i < iface->num_bss; i++) { 321 if (os_memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0) 322 return iface->bss[i]; 323 } 324 325 return NULL; 326 } 327 328 329 static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd, 330 const u8 *bssid, const u8 *addr, 331 int wds) 332 { 333 hapd = get_hapd_bssid(hapd->iface, bssid); 334 if (hapd == NULL || hapd == HAPD_BROADCAST) 335 return; 336 337 ieee802_11_rx_from_unknown(hapd, addr, wds); 338 } 339 340 341 static void hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt) 342 { 343 struct hostapd_iface *iface = hapd->iface; 344 const struct ieee80211_hdr *hdr; 345 const u8 *bssid; 346 struct hostapd_frame_info fi; 347 348 hdr = (const struct ieee80211_hdr *) rx_mgmt->frame; 349 bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len); 350 if (bssid == NULL) 351 return; 352 353 hapd = get_hapd_bssid(iface, bssid); 354 if (hapd == NULL) { 355 u16 fc; 356 fc = le_to_host16(hdr->frame_control); 357 358 /* 359 * Drop frames to unknown BSSIDs except for Beacon frames which 360 * could be used to update neighbor information. 361 */ 362 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && 363 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) 364 hapd = iface->bss[0]; 365 else 366 return; 367 } 368 369 os_memset(&fi, 0, sizeof(fi)); 370 fi.datarate = rx_mgmt->datarate; 371 fi.ssi_signal = rx_mgmt->ssi_signal; 372 373 if (hapd == HAPD_BROADCAST) { 374 size_t i; 375 for (i = 0; i < iface->num_bss; i++) 376 ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame, 377 rx_mgmt->frame_len, &fi); 378 } else 379 ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len, &fi); 380 381 random_add_randomness(&fi, sizeof(fi)); 382 } 383 384 385 static void hostapd_rx_action(struct hostapd_data *hapd, 386 struct rx_action *rx_action) 387 { 388 struct rx_mgmt rx_mgmt; 389 u8 *buf; 390 struct ieee80211_hdr *hdr; 391 392 wpa_printf(MSG_DEBUG, "EVENT_RX_ACTION DA=" MACSTR " SA=" MACSTR 393 " BSSID=" MACSTR " category=%u", 394 MAC2STR(rx_action->da), MAC2STR(rx_action->sa), 395 MAC2STR(rx_action->bssid), rx_action->category); 396 wpa_hexdump(MSG_MSGDUMP, "Received action frame contents", 397 rx_action->data, rx_action->len); 398 399 buf = os_zalloc(24 + 1 + rx_action->len); 400 if (buf == NULL) 401 return; 402 hdr = (struct ieee80211_hdr *) buf; 403 hdr->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 404 WLAN_FC_STYPE_ACTION); 405 if (rx_action->category == WLAN_ACTION_SA_QUERY) { 406 /* 407 * Assume frame was protected; it would have been dropped if 408 * not. 409 */ 410 hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP); 411 } 412 os_memcpy(hdr->addr1, rx_action->da, ETH_ALEN); 413 os_memcpy(hdr->addr2, rx_action->sa, ETH_ALEN); 414 os_memcpy(hdr->addr3, rx_action->bssid, ETH_ALEN); 415 buf[24] = rx_action->category; 416 os_memcpy(buf + 24 + 1, rx_action->data, rx_action->len); 417 os_memset(&rx_mgmt, 0, sizeof(rx_mgmt)); 418 rx_mgmt.frame = buf; 419 rx_mgmt.frame_len = 24 + 1 + rx_action->len; 420 hostapd_mgmt_rx(hapd, &rx_mgmt); 421 os_free(buf); 422 } 423 424 425 static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf, 426 size_t len, u16 stype, int ok) 427 { 428 struct ieee80211_hdr *hdr; 429 hdr = (struct ieee80211_hdr *) buf; 430 hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len)); 431 if (hapd == NULL || hapd == HAPD_BROADCAST) 432 return; 433 ieee802_11_mgmt_cb(hapd, buf, len, stype, ok); 434 } 435 436 #endif /* NEED_AP_MLME */ 437 438 439 static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr) 440 { 441 struct sta_info *sta = ap_get_sta(hapd, addr); 442 if (sta) 443 return 0; 444 445 wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR 446 " - adding a new STA", MAC2STR(addr)); 447 sta = ap_sta_add(hapd, addr); 448 if (sta) { 449 hostapd_new_assoc_sta(hapd, sta, 0); 450 } else { 451 wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR, 452 MAC2STR(addr)); 453 return -1; 454 } 455 456 return 0; 457 } 458 459 460 static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src, 461 const u8 *data, size_t data_len) 462 { 463 struct hostapd_iface *iface = hapd->iface; 464 struct sta_info *sta; 465 size_t j; 466 467 for (j = 0; j < iface->num_bss; j++) { 468 if ((sta = ap_get_sta(iface->bss[j], src))) { 469 if (sta->flags & WLAN_STA_ASSOC) { 470 hapd = iface->bss[j]; 471 break; 472 } 473 } 474 } 475 476 ieee802_1x_receive(hapd, src, data, data_len); 477 } 478 479 480 void wpa_supplicant_event(void *ctx, enum wpa_event_type event, 481 union wpa_event_data *data) 482 { 483 struct hostapd_data *hapd = ctx; 484 485 switch (event) { 486 case EVENT_MICHAEL_MIC_FAILURE: 487 michael_mic_failure(hapd, data->michael_mic_failure.src, 1); 488 break; 489 case EVENT_SCAN_RESULTS: 490 if (hapd->iface->scan_cb) 491 hapd->iface->scan_cb(hapd->iface); 492 break; 493 #ifdef CONFIG_IEEE80211R 494 case EVENT_FT_RRB_RX: 495 wpa_ft_rrb_rx(hapd->wpa_auth, data->ft_rrb_rx.src, 496 data->ft_rrb_rx.data, data->ft_rrb_rx.data_len); 497 break; 498 #endif /* CONFIG_IEEE80211R */ 499 case EVENT_WPS_BUTTON_PUSHED: 500 hostapd_wps_button_pushed(hapd, NULL); 501 break; 502 #ifdef NEED_AP_MLME 503 case EVENT_TX_STATUS: 504 switch (data->tx_status.type) { 505 case WLAN_FC_TYPE_MGMT: 506 hostapd_mgmt_tx_cb(hapd, data->tx_status.data, 507 data->tx_status.data_len, 508 data->tx_status.stype, 509 data->tx_status.ack); 510 break; 511 case WLAN_FC_TYPE_DATA: 512 hostapd_tx_status(hapd, data->tx_status.dst, 513 data->tx_status.data, 514 data->tx_status.data_len, 515 data->tx_status.ack); 516 break; 517 } 518 break; 519 case EVENT_DRIVER_CLIENT_POLL_OK: 520 hostapd_client_poll_ok(hapd, data->client_poll.addr); 521 break; 522 case EVENT_RX_FROM_UNKNOWN: 523 hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.bssid, 524 data->rx_from_unknown.addr, 525 data->rx_from_unknown.wds); 526 break; 527 case EVENT_RX_MGMT: 528 hostapd_mgmt_rx(hapd, &data->rx_mgmt); 529 break; 530 #endif /* NEED_AP_MLME */ 531 case EVENT_RX_PROBE_REQ: 532 if (data->rx_probe_req.sa == NULL || 533 data->rx_probe_req.ie == NULL) 534 break; 535 hostapd_probe_req_rx(hapd, data->rx_probe_req.sa, 536 data->rx_probe_req.da, 537 data->rx_probe_req.bssid, 538 data->rx_probe_req.ie, 539 data->rx_probe_req.ie_len); 540 break; 541 case EVENT_NEW_STA: 542 hostapd_event_new_sta(hapd, data->new_sta.addr); 543 break; 544 case EVENT_EAPOL_RX: 545 hostapd_event_eapol_rx(hapd, data->eapol_rx.src, 546 data->eapol_rx.data, 547 data->eapol_rx.data_len); 548 break; 549 case EVENT_ASSOC: 550 hostapd_notif_assoc(hapd, data->assoc_info.addr, 551 data->assoc_info.req_ies, 552 data->assoc_info.req_ies_len, 553 data->assoc_info.reassoc); 554 break; 555 case EVENT_DISASSOC: 556 if (data) 557 hostapd_notif_disassoc(hapd, data->disassoc_info.addr); 558 break; 559 case EVENT_DEAUTH: 560 if (data) 561 hostapd_notif_disassoc(hapd, data->deauth_info.addr); 562 break; 563 case EVENT_STATION_LOW_ACK: 564 if (!data) 565 break; 566 hostapd_event_sta_low_ack(hapd, data->low_ack.addr); 567 break; 568 #ifdef NEED_AP_MLME 569 case EVENT_RX_ACTION: 570 if (data->rx_action.da == NULL || data->rx_action.sa == NULL || 571 data->rx_action.bssid == NULL) 572 break; 573 hostapd_rx_action(hapd, &data->rx_action); 574 break; 575 #endif /* NEED_AP_MLME */ 576 default: 577 wpa_printf(MSG_DEBUG, "Unknown event %d", event); 578 break; 579 } 580 } 581 582 #endif /* HOSTAPD */ 583