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