drv_callbacks.c revision 75ecf5267604f166b85a7ee2cf0d9cb682966680
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 wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC); 231 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; 232 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); 233 ap_free_sta(hapd, sta); 234} 235 236 237void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr) 238{ 239 struct sta_info *sta = ap_get_sta(hapd, addr); 240 241 if (!sta || !hapd->conf->disassoc_low_ack) 242 return; 243 244 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, 245 HOSTAPD_LEVEL_INFO, "disconnected due to excessive " 246 "missing ACKs"); 247 hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_DISASSOC_LOW_ACK); 248 if (sta) 249 ap_sta_disassociate(hapd, sta, WLAN_REASON_DISASSOC_LOW_ACK); 250} 251 252 253int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, 254 const u8 *ie, size_t ie_len) 255{ 256 size_t i; 257 int ret = 0; 258 259 if (sa == NULL || ie == NULL) 260 return -1; 261 262 random_add_randomness(sa, ETH_ALEN); 263 for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) { 264 if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx, 265 sa, ie, ie_len) > 0) { 266 ret = 1; 267 break; 268 } 269 } 270 return ret; 271} 272 273 274#ifdef HOSTAPD 275 276#ifdef NEED_AP_MLME 277 278static const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len) 279{ 280 u16 fc, type, stype; 281 282 /* 283 * PS-Poll frames are 16 bytes. All other frames are 284 * 24 bytes or longer. 285 */ 286 if (len < 16) 287 return NULL; 288 289 fc = le_to_host16(hdr->frame_control); 290 type = WLAN_FC_GET_TYPE(fc); 291 stype = WLAN_FC_GET_STYPE(fc); 292 293 switch (type) { 294 case WLAN_FC_TYPE_DATA: 295 if (len < 24) 296 return NULL; 297 switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) { 298 case WLAN_FC_FROMDS | WLAN_FC_TODS: 299 case WLAN_FC_TODS: 300 return hdr->addr1; 301 case WLAN_FC_FROMDS: 302 return hdr->addr2; 303 default: 304 return NULL; 305 } 306 case WLAN_FC_TYPE_CTRL: 307 if (stype != WLAN_FC_STYPE_PSPOLL) 308 return NULL; 309 return hdr->addr1; 310 case WLAN_FC_TYPE_MGMT: 311 return hdr->addr3; 312 default: 313 return NULL; 314 } 315} 316 317 318#define HAPD_BROADCAST ((struct hostapd_data *) -1) 319 320static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface, 321 const u8 *bssid) 322{ 323 size_t i; 324 325 if (bssid == NULL) 326 return NULL; 327 if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff && 328 bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff) 329 return HAPD_BROADCAST; 330 331 for (i = 0; i < iface->num_bss; i++) { 332 if (os_memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0) 333 return iface->bss[i]; 334 } 335 336 return NULL; 337} 338 339 340static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd, 341 const u8 *frame, size_t len) 342{ 343 const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) frame; 344 u16 fc = le_to_host16(hdr->frame_control); 345 hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len)); 346 if (hapd == NULL || hapd == HAPD_BROADCAST) 347 return; 348 349 ieee802_11_rx_from_unknown(hapd, hdr->addr2, 350 (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == 351 (WLAN_FC_TODS | WLAN_FC_FROMDS)); 352} 353 354 355static void hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt) 356{ 357 struct hostapd_iface *iface = hapd->iface; 358 const struct ieee80211_hdr *hdr; 359 const u8 *bssid; 360 struct hostapd_frame_info fi; 361 362 hdr = (const struct ieee80211_hdr *) rx_mgmt->frame; 363 bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len); 364 if (bssid == NULL) 365 return; 366 367 hapd = get_hapd_bssid(iface, bssid); 368 if (hapd == NULL) { 369 u16 fc; 370 fc = le_to_host16(hdr->frame_control); 371 372 /* 373 * Drop frames to unknown BSSIDs except for Beacon frames which 374 * could be used to update neighbor information. 375 */ 376 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && 377 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) 378 hapd = iface->bss[0]; 379 else 380 return; 381 } 382 383 os_memset(&fi, 0, sizeof(fi)); 384 fi.datarate = rx_mgmt->datarate; 385 fi.ssi_signal = rx_mgmt->ssi_signal; 386 387 if (hapd == HAPD_BROADCAST) { 388 size_t i; 389 for (i = 0; i < iface->num_bss; i++) 390 ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame, 391 rx_mgmt->frame_len, &fi); 392 } else 393 ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len, &fi); 394 395 random_add_randomness(&fi, sizeof(fi)); 396} 397 398 399static void hostapd_rx_action(struct hostapd_data *hapd, 400 struct rx_action *rx_action) 401{ 402 struct rx_mgmt rx_mgmt; 403 u8 *buf; 404 struct ieee80211_hdr *hdr; 405 406 wpa_printf(MSG_DEBUG, "EVENT_RX_ACTION DA=" MACSTR " SA=" MACSTR 407 " BSSID=" MACSTR " category=%u", 408 MAC2STR(rx_action->da), MAC2STR(rx_action->sa), 409 MAC2STR(rx_action->bssid), rx_action->category); 410 wpa_hexdump(MSG_MSGDUMP, "Received action frame contents", 411 rx_action->data, rx_action->len); 412 413 buf = os_zalloc(24 + 1 + rx_action->len); 414 if (buf == NULL) 415 return; 416 hdr = (struct ieee80211_hdr *) buf; 417 hdr->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 418 WLAN_FC_STYPE_ACTION); 419 if (rx_action->category == WLAN_ACTION_SA_QUERY) { 420 /* 421 * Assume frame was protected; it would have been dropped if 422 * not. 423 */ 424 hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP); 425 } 426 os_memcpy(hdr->addr1, rx_action->da, ETH_ALEN); 427 os_memcpy(hdr->addr2, rx_action->sa, ETH_ALEN); 428 os_memcpy(hdr->addr3, rx_action->bssid, ETH_ALEN); 429 buf[24] = rx_action->category; 430 os_memcpy(buf + 24 + 1, rx_action->data, rx_action->len); 431 os_memset(&rx_mgmt, 0, sizeof(rx_mgmt)); 432 rx_mgmt.frame = buf; 433 rx_mgmt.frame_len = 24 + 1 + rx_action->len; 434 hostapd_mgmt_rx(hapd, &rx_mgmt); 435 os_free(buf); 436} 437 438 439static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf, 440 size_t len, u16 stype, int ok) 441{ 442 struct ieee80211_hdr *hdr; 443 hdr = (struct ieee80211_hdr *) buf; 444 hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len)); 445 if (hapd == NULL || hapd == HAPD_BROADCAST) 446 return; 447 ieee802_11_mgmt_cb(hapd, buf, len, stype, ok); 448} 449 450#endif /* NEED_AP_MLME */ 451 452 453static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr) 454{ 455 struct sta_info *sta = ap_get_sta(hapd, addr); 456 if (sta) 457 return 0; 458 459 wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR 460 " - adding a new STA", MAC2STR(addr)); 461 sta = ap_sta_add(hapd, addr); 462 if (sta) { 463 hostapd_new_assoc_sta(hapd, sta, 0); 464 } else { 465 wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR, 466 MAC2STR(addr)); 467 return -1; 468 } 469 470 return 0; 471} 472 473 474static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src, 475 const u8 *data, size_t data_len) 476{ 477 struct hostapd_iface *iface = hapd->iface; 478 size_t j; 479 480 for (j = 0; j < iface->num_bss; j++) { 481 if (ap_get_sta(iface->bss[j], src)) { 482 hapd = iface->bss[j]; 483 break; 484 } 485 } 486 487 ieee802_1x_receive(hapd, src, data, data_len); 488} 489 490 491void wpa_supplicant_event(void *ctx, enum wpa_event_type event, 492 union wpa_event_data *data) 493{ 494 struct hostapd_data *hapd = ctx; 495 496 switch (event) { 497 case EVENT_MICHAEL_MIC_FAILURE: 498 michael_mic_failure(hapd, data->michael_mic_failure.src, 1); 499 break; 500 case EVENT_SCAN_RESULTS: 501 if (hapd->iface->scan_cb) 502 hapd->iface->scan_cb(hapd->iface); 503 break; 504#ifdef CONFIG_IEEE80211R 505 case EVENT_FT_RRB_RX: 506 wpa_ft_rrb_rx(hapd->wpa_auth, data->ft_rrb_rx.src, 507 data->ft_rrb_rx.data, data->ft_rrb_rx.data_len); 508 break; 509#endif /* CONFIG_IEEE80211R */ 510 case EVENT_WPS_BUTTON_PUSHED: 511 hostapd_wps_button_pushed(hapd, NULL); 512 break; 513#ifdef NEED_AP_MLME 514 case EVENT_TX_STATUS: 515 switch (data->tx_status.type) { 516 case WLAN_FC_TYPE_MGMT: 517 hostapd_mgmt_tx_cb(hapd, data->tx_status.data, 518 data->tx_status.data_len, 519 data->tx_status.stype, 520 data->tx_status.ack); 521 break; 522 case WLAN_FC_TYPE_DATA: 523 hostapd_tx_status(hapd, data->tx_status.dst, 524 data->tx_status.data, 525 data->tx_status.data_len, 526 data->tx_status.ack); 527 break; 528 } 529 break; 530 case EVENT_RX_FROM_UNKNOWN: 531 hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.frame, 532 data->rx_from_unknown.len); 533 break; 534 case EVENT_RX_MGMT: 535 hostapd_mgmt_rx(hapd, &data->rx_mgmt); 536 break; 537#endif /* NEED_AP_MLME */ 538 case EVENT_RX_PROBE_REQ: 539 if (data->rx_probe_req.sa == NULL || 540 data->rx_probe_req.ie == NULL) 541 break; 542 hostapd_probe_req_rx(hapd, data->rx_probe_req.sa, 543 data->rx_probe_req.ie, 544 data->rx_probe_req.ie_len); 545 break; 546 case EVENT_NEW_STA: 547 hostapd_event_new_sta(hapd, data->new_sta.addr); 548 break; 549 case EVENT_EAPOL_RX: 550 hostapd_event_eapol_rx(hapd, data->eapol_rx.src, 551 data->eapol_rx.data, 552 data->eapol_rx.data_len); 553 break; 554 case EVENT_ASSOC: 555 hostapd_notif_assoc(hapd, data->assoc_info.addr, 556 data->assoc_info.req_ies, 557 data->assoc_info.req_ies_len, 558 data->assoc_info.reassoc); 559 break; 560 case EVENT_DISASSOC: 561 if (data) 562 hostapd_notif_disassoc(hapd, data->disassoc_info.addr); 563 break; 564 case EVENT_DEAUTH: 565 if (data) 566 hostapd_notif_disassoc(hapd, data->deauth_info.addr); 567 break; 568 case EVENT_STATION_LOW_ACK: 569 if (!data) 570 break; 571 hostapd_event_sta_low_ack(hapd, data->low_ack.addr); 572 break; 573#ifdef NEED_AP_MLME 574 case EVENT_RX_ACTION: 575 if (data->rx_action.da == NULL || data->rx_action.sa == NULL || 576 data->rx_action.bssid == NULL) 577 break; 578 hostapd_rx_action(hapd, &data->rx_action); 579 break; 580#endif /* NEED_AP_MLME */ 581 default: 582 wpa_printf(MSG_DEBUG, "Unknown event %d", event); 583 break; 584 } 585} 586 587#endif /* HOSTAPD */ 588