drv_callbacks.c revision 214501
1214501Srpaulo/* 2214501Srpaulo * hostapd / Callback functions for driver wrappers 3214501Srpaulo * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> 4214501Srpaulo * 5214501Srpaulo * This program is free software; you can redistribute it and/or modify 6214501Srpaulo * it under the terms of the GNU General Public License version 2 as 7214501Srpaulo * published by the Free Software Foundation. 8214501Srpaulo * 9214501Srpaulo * Alternatively, this software may be distributed under the terms of BSD 10214501Srpaulo * license. 11214501Srpaulo * 12214501Srpaulo * See README and COPYING for more details. 13214501Srpaulo */ 14214501Srpaulo 15214501Srpaulo#include "utils/includes.h" 16214501Srpaulo 17214501Srpaulo#include "utils/common.h" 18214501Srpaulo#include "radius/radius.h" 19214501Srpaulo#include "drivers/driver.h" 20214501Srpaulo#include "common/ieee802_11_defs.h" 21214501Srpaulo#include "common/ieee802_11_common.h" 22214501Srpaulo#include "common/wpa_ctrl.h" 23214501Srpaulo#include "hostapd.h" 24214501Srpaulo#include "ieee802_11.h" 25214501Srpaulo#include "sta_info.h" 26214501Srpaulo#include "accounting.h" 27214501Srpaulo#include "tkip_countermeasures.h" 28214501Srpaulo#include "iapp.h" 29214501Srpaulo#include "ieee802_1x.h" 30214501Srpaulo#include "wpa_auth.h" 31214501Srpaulo#include "wmm.h" 32214501Srpaulo#include "wps_hostapd.h" 33214501Srpaulo#include "ap_config.h" 34214501Srpaulo 35214501Srpaulo 36214501Srpauloint hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, 37214501Srpaulo const u8 *ie, size_t ielen) 38214501Srpaulo{ 39214501Srpaulo struct sta_info *sta; 40214501Srpaulo int new_assoc, res; 41214501Srpaulo struct ieee802_11_elems elems; 42214501Srpaulo 43214501Srpaulo if (addr == NULL) { 44214501Srpaulo /* 45214501Srpaulo * This could potentially happen with unexpected event from the 46214501Srpaulo * driver wrapper. This was seen at least in one case where the 47214501Srpaulo * driver ended up being set to station mode while hostapd was 48214501Srpaulo * running, so better make sure we stop processing such an 49214501Srpaulo * event here. 50214501Srpaulo */ 51214501Srpaulo wpa_printf(MSG_DEBUG, "hostapd_notif_assoc: Skip event with " 52214501Srpaulo "no address"); 53214501Srpaulo return -1; 54214501Srpaulo } 55214501Srpaulo 56214501Srpaulo hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, 57214501Srpaulo HOSTAPD_LEVEL_INFO, "associated"); 58214501Srpaulo 59214501Srpaulo ieee802_11_parse_elems(ie, ielen, &elems, 0); 60214501Srpaulo if (elems.wps_ie) { 61214501Srpaulo ie = elems.wps_ie - 2; 62214501Srpaulo ielen = elems.wps_ie_len + 2; 63214501Srpaulo wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)AssocReq"); 64214501Srpaulo } else if (elems.rsn_ie) { 65214501Srpaulo ie = elems.rsn_ie - 2; 66214501Srpaulo ielen = elems.rsn_ie_len + 2; 67214501Srpaulo wpa_printf(MSG_DEBUG, "STA included RSN IE in (Re)AssocReq"); 68214501Srpaulo } else if (elems.wpa_ie) { 69214501Srpaulo ie = elems.wpa_ie - 2; 70214501Srpaulo ielen = elems.wpa_ie_len + 2; 71214501Srpaulo wpa_printf(MSG_DEBUG, "STA included WPA IE in (Re)AssocReq"); 72214501Srpaulo } else { 73214501Srpaulo ie = NULL; 74214501Srpaulo ielen = 0; 75214501Srpaulo wpa_printf(MSG_DEBUG, "STA did not include WPS/RSN/WPA IE in " 76214501Srpaulo "(Re)AssocReq"); 77214501Srpaulo } 78214501Srpaulo 79214501Srpaulo sta = ap_get_sta(hapd, addr); 80214501Srpaulo if (sta) { 81214501Srpaulo accounting_sta_stop(hapd, sta); 82214501Srpaulo } else { 83214501Srpaulo sta = ap_sta_add(hapd, addr); 84214501Srpaulo if (sta == NULL) 85214501Srpaulo return -1; 86214501Srpaulo } 87214501Srpaulo sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS); 88214501Srpaulo 89214501Srpaulo if (hapd->conf->wpa) { 90214501Srpaulo if (ie == NULL || ielen == 0) { 91214501Srpaulo if (hapd->conf->wps_state) { 92214501Srpaulo wpa_printf(MSG_DEBUG, "STA did not include " 93214501Srpaulo "WPA/RSN IE in (Re)Association " 94214501Srpaulo "Request - possible WPS use"); 95214501Srpaulo sta->flags |= WLAN_STA_MAYBE_WPS; 96214501Srpaulo goto skip_wpa_check; 97214501Srpaulo } 98214501Srpaulo 99214501Srpaulo wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA"); 100214501Srpaulo return -1; 101214501Srpaulo } 102214501Srpaulo if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 && 103214501Srpaulo os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) { 104214501Srpaulo sta->flags |= WLAN_STA_WPS; 105214501Srpaulo goto skip_wpa_check; 106214501Srpaulo } 107214501Srpaulo 108214501Srpaulo if (sta->wpa_sm == NULL) 109214501Srpaulo sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, 110214501Srpaulo sta->addr); 111214501Srpaulo if (sta->wpa_sm == NULL) { 112214501Srpaulo wpa_printf(MSG_ERROR, "Failed to initialize WPA state " 113214501Srpaulo "machine"); 114214501Srpaulo return -1; 115214501Srpaulo } 116214501Srpaulo res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, 117214501Srpaulo ie, ielen, NULL, 0); 118214501Srpaulo if (res != WPA_IE_OK) { 119214501Srpaulo int resp; 120214501Srpaulo wpa_printf(MSG_DEBUG, "WPA/RSN information element " 121214501Srpaulo "rejected? (res %u)", res); 122214501Srpaulo wpa_hexdump(MSG_DEBUG, "IE", ie, ielen); 123214501Srpaulo if (res == WPA_INVALID_GROUP) 124214501Srpaulo resp = WLAN_REASON_GROUP_CIPHER_NOT_VALID; 125214501Srpaulo else if (res == WPA_INVALID_PAIRWISE) 126214501Srpaulo resp = WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID; 127214501Srpaulo else if (res == WPA_INVALID_AKMP) 128214501Srpaulo resp = WLAN_REASON_AKMP_NOT_VALID; 129214501Srpaulo#ifdef CONFIG_IEEE80211W 130214501Srpaulo else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION) 131214501Srpaulo resp = WLAN_REASON_INVALID_IE; 132214501Srpaulo else if (res == WPA_INVALID_MGMT_GROUP_CIPHER) 133214501Srpaulo resp = WLAN_REASON_GROUP_CIPHER_NOT_VALID; 134214501Srpaulo#endif /* CONFIG_IEEE80211W */ 135214501Srpaulo else 136214501Srpaulo resp = WLAN_REASON_INVALID_IE; 137214501Srpaulo hapd->drv.sta_disassoc(hapd, sta->addr, resp); 138214501Srpaulo ap_free_sta(hapd, sta); 139214501Srpaulo return -1; 140214501Srpaulo } 141214501Srpaulo } else if (hapd->conf->wps_state) { 142214501Srpaulo if (ie && ielen > 4 && ie[0] == 0xdd && ie[1] >= 4 && 143214501Srpaulo os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) { 144214501Srpaulo sta->flags |= WLAN_STA_WPS; 145214501Srpaulo } else 146214501Srpaulo sta->flags |= WLAN_STA_MAYBE_WPS; 147214501Srpaulo } 148214501Srpauloskip_wpa_check: 149214501Srpaulo 150214501Srpaulo new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0; 151214501Srpaulo sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC; 152214501Srpaulo wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC); 153214501Srpaulo 154214501Srpaulo hostapd_new_assoc_sta(hapd, sta, !new_assoc); 155214501Srpaulo 156214501Srpaulo ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); 157214501Srpaulo 158214501Srpaulo return 0; 159214501Srpaulo} 160214501Srpaulo 161214501Srpaulo 162214501Srpaulovoid hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr) 163214501Srpaulo{ 164214501Srpaulo struct sta_info *sta; 165214501Srpaulo 166214501Srpaulo hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, 167214501Srpaulo HOSTAPD_LEVEL_INFO, "disassociated"); 168214501Srpaulo 169214501Srpaulo sta = ap_get_sta(hapd, addr); 170214501Srpaulo if (sta == NULL) { 171214501Srpaulo wpa_printf(MSG_DEBUG, "Disassociation notification for " 172214501Srpaulo "unknown STA " MACSTR, MAC2STR(addr)); 173214501Srpaulo return; 174214501Srpaulo } 175214501Srpaulo 176214501Srpaulo sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); 177214501Srpaulo wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR, 178214501Srpaulo MAC2STR(sta->addr)); 179214501Srpaulo wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC); 180214501Srpaulo sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; 181214501Srpaulo ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); 182214501Srpaulo ap_free_sta(hapd, sta); 183214501Srpaulo} 184214501Srpaulo 185214501Srpaulo 186214501Srpaulo#ifdef HOSTAPD 187214501Srpaulo 188214501Srpaulo#ifdef NEED_AP_MLME 189214501Srpaulo 190214501Srpaulostatic const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len) 191214501Srpaulo{ 192214501Srpaulo u16 fc, type, stype; 193214501Srpaulo 194214501Srpaulo /* 195214501Srpaulo * PS-Poll frames are 16 bytes. All other frames are 196214501Srpaulo * 24 bytes or longer. 197214501Srpaulo */ 198214501Srpaulo if (len < 16) 199214501Srpaulo return NULL; 200214501Srpaulo 201214501Srpaulo fc = le_to_host16(hdr->frame_control); 202214501Srpaulo type = WLAN_FC_GET_TYPE(fc); 203214501Srpaulo stype = WLAN_FC_GET_STYPE(fc); 204214501Srpaulo 205214501Srpaulo switch (type) { 206214501Srpaulo case WLAN_FC_TYPE_DATA: 207214501Srpaulo if (len < 24) 208214501Srpaulo return NULL; 209214501Srpaulo switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) { 210214501Srpaulo case WLAN_FC_FROMDS | WLAN_FC_TODS: 211214501Srpaulo case WLAN_FC_TODS: 212214501Srpaulo return hdr->addr1; 213214501Srpaulo case WLAN_FC_FROMDS: 214214501Srpaulo return hdr->addr2; 215214501Srpaulo default: 216214501Srpaulo return NULL; 217214501Srpaulo } 218214501Srpaulo case WLAN_FC_TYPE_CTRL: 219214501Srpaulo if (stype != WLAN_FC_STYPE_PSPOLL) 220214501Srpaulo return NULL; 221214501Srpaulo return hdr->addr1; 222214501Srpaulo case WLAN_FC_TYPE_MGMT: 223214501Srpaulo return hdr->addr3; 224214501Srpaulo default: 225214501Srpaulo return NULL; 226214501Srpaulo } 227214501Srpaulo} 228214501Srpaulo 229214501Srpaulo 230214501Srpaulo#define HAPD_BROADCAST ((struct hostapd_data *) -1) 231214501Srpaulo 232214501Srpaulostatic struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface, 233214501Srpaulo const u8 *bssid) 234214501Srpaulo{ 235214501Srpaulo size_t i; 236214501Srpaulo 237214501Srpaulo if (bssid == NULL) 238214501Srpaulo return NULL; 239214501Srpaulo if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff && 240214501Srpaulo bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff) 241214501Srpaulo return HAPD_BROADCAST; 242214501Srpaulo 243214501Srpaulo for (i = 0; i < iface->num_bss; i++) { 244214501Srpaulo if (os_memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0) 245214501Srpaulo return iface->bss[i]; 246214501Srpaulo } 247214501Srpaulo 248214501Srpaulo return NULL; 249214501Srpaulo} 250214501Srpaulo 251214501Srpaulo 252214501Srpaulostatic void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd, 253214501Srpaulo const u8 *frame, size_t len) 254214501Srpaulo{ 255214501Srpaulo const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) frame; 256214501Srpaulo u16 fc = le_to_host16(hdr->frame_control); 257214501Srpaulo hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len)); 258214501Srpaulo if (hapd == NULL || hapd == HAPD_BROADCAST) 259214501Srpaulo return; 260214501Srpaulo 261214501Srpaulo ieee802_11_rx_from_unknown(hapd, hdr->addr2, 262214501Srpaulo (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == 263214501Srpaulo (WLAN_FC_TODS | WLAN_FC_FROMDS)); 264214501Srpaulo} 265214501Srpaulo 266214501Srpaulo 267214501Srpaulostatic void hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt) 268214501Srpaulo{ 269214501Srpaulo struct hostapd_iface *iface = hapd->iface; 270214501Srpaulo const struct ieee80211_hdr *hdr; 271214501Srpaulo const u8 *bssid; 272214501Srpaulo struct hostapd_frame_info fi; 273214501Srpaulo 274214501Srpaulo hdr = (const struct ieee80211_hdr *) rx_mgmt->frame; 275214501Srpaulo bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len); 276214501Srpaulo if (bssid == NULL) 277214501Srpaulo return; 278214501Srpaulo 279214501Srpaulo hapd = get_hapd_bssid(iface, bssid); 280214501Srpaulo if (hapd == NULL) { 281214501Srpaulo u16 fc; 282214501Srpaulo fc = le_to_host16(hdr->frame_control); 283214501Srpaulo 284214501Srpaulo /* 285214501Srpaulo * Drop frames to unknown BSSIDs except for Beacon frames which 286214501Srpaulo * could be used to update neighbor information. 287214501Srpaulo */ 288214501Srpaulo if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && 289214501Srpaulo WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) 290214501Srpaulo hapd = iface->bss[0]; 291214501Srpaulo else 292214501Srpaulo return; 293214501Srpaulo } 294214501Srpaulo 295214501Srpaulo os_memset(&fi, 0, sizeof(fi)); 296214501Srpaulo fi.datarate = rx_mgmt->datarate; 297214501Srpaulo fi.ssi_signal = rx_mgmt->ssi_signal; 298214501Srpaulo 299214501Srpaulo if (hapd == HAPD_BROADCAST) { 300214501Srpaulo size_t i; 301214501Srpaulo for (i = 0; i < iface->num_bss; i++) 302214501Srpaulo ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame, 303214501Srpaulo rx_mgmt->frame_len, &fi); 304214501Srpaulo } else 305214501Srpaulo ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len, &fi); 306214501Srpaulo} 307214501Srpaulo 308214501Srpaulo 309214501Srpaulostatic void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf, 310214501Srpaulo size_t len, u16 stype, int ok) 311214501Srpaulo{ 312214501Srpaulo struct ieee80211_hdr *hdr; 313214501Srpaulo hdr = (struct ieee80211_hdr *) buf; 314214501Srpaulo hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len)); 315214501Srpaulo if (hapd == NULL || hapd == HAPD_BROADCAST) 316214501Srpaulo return; 317214501Srpaulo ieee802_11_mgmt_cb(hapd, buf, len, stype, ok); 318214501Srpaulo} 319214501Srpaulo 320214501Srpaulo#endif /* NEED_AP_MLME */ 321214501Srpaulo 322214501Srpaulo 323214501Srpaulostatic int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, 324214501Srpaulo const u8 *ie, size_t ie_len) 325214501Srpaulo{ 326214501Srpaulo size_t i; 327214501Srpaulo int ret = 0; 328214501Srpaulo 329214501Srpaulo for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) { 330214501Srpaulo if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx, 331214501Srpaulo sa, ie, ie_len) > 0) { 332214501Srpaulo ret = 1; 333214501Srpaulo break; 334214501Srpaulo } 335214501Srpaulo } 336214501Srpaulo return ret; 337214501Srpaulo} 338214501Srpaulo 339214501Srpaulo 340214501Srpaulostatic int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr) 341214501Srpaulo{ 342214501Srpaulo struct sta_info *sta = ap_get_sta(hapd, addr); 343214501Srpaulo if (sta) 344214501Srpaulo return 0; 345214501Srpaulo 346214501Srpaulo wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR 347214501Srpaulo " - adding a new STA", MAC2STR(addr)); 348214501Srpaulo sta = ap_sta_add(hapd, addr); 349214501Srpaulo if (sta) { 350214501Srpaulo hostapd_new_assoc_sta(hapd, sta, 0); 351214501Srpaulo } else { 352214501Srpaulo wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR, 353214501Srpaulo MAC2STR(addr)); 354214501Srpaulo return -1; 355214501Srpaulo } 356214501Srpaulo 357214501Srpaulo return 0; 358214501Srpaulo} 359214501Srpaulo 360214501Srpaulo 361214501Srpaulostatic void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src, 362214501Srpaulo const u8 *data, size_t data_len) 363214501Srpaulo{ 364214501Srpaulo struct hostapd_iface *iface = hapd->iface; 365214501Srpaulo size_t j; 366214501Srpaulo 367214501Srpaulo for (j = 0; j < iface->num_bss; j++) { 368214501Srpaulo if (ap_get_sta(iface->bss[j], src)) { 369214501Srpaulo hapd = iface->bss[j]; 370214501Srpaulo break; 371214501Srpaulo } 372214501Srpaulo } 373214501Srpaulo 374214501Srpaulo ieee802_1x_receive(hapd, src, data, data_len); 375214501Srpaulo} 376214501Srpaulo 377214501Srpaulo 378214501Srpaulovoid wpa_supplicant_event(void *ctx, enum wpa_event_type event, 379214501Srpaulo union wpa_event_data *data) 380214501Srpaulo{ 381214501Srpaulo struct hostapd_data *hapd = ctx; 382214501Srpaulo 383214501Srpaulo switch (event) { 384214501Srpaulo case EVENT_MICHAEL_MIC_FAILURE: 385214501Srpaulo michael_mic_failure(hapd, data->michael_mic_failure.src, 1); 386214501Srpaulo break; 387214501Srpaulo case EVENT_SCAN_RESULTS: 388214501Srpaulo if (hapd->iface->scan_cb) 389214501Srpaulo hapd->iface->scan_cb(hapd->iface); 390214501Srpaulo break; 391214501Srpaulo#ifdef CONFIG_IEEE80211R 392214501Srpaulo case EVENT_FT_RRB_RX: 393214501Srpaulo wpa_ft_rrb_rx(hapd->wpa_auth, data->ft_rrb_rx.src, 394214501Srpaulo data->ft_rrb_rx.data, data->ft_rrb_rx.data_len); 395214501Srpaulo break; 396214501Srpaulo#endif /* CONFIG_IEEE80211R */ 397214501Srpaulo case EVENT_WPS_BUTTON_PUSHED: 398214501Srpaulo hostapd_wps_button_pushed(hapd); 399214501Srpaulo break; 400214501Srpaulo#ifdef NEED_AP_MLME 401214501Srpaulo case EVENT_TX_STATUS: 402214501Srpaulo switch (data->tx_status.type) { 403214501Srpaulo case WLAN_FC_TYPE_MGMT: 404214501Srpaulo hostapd_mgmt_tx_cb(hapd, data->tx_status.data, 405214501Srpaulo data->tx_status.data_len, 406214501Srpaulo data->tx_status.stype, 407214501Srpaulo data->tx_status.ack); 408214501Srpaulo break; 409214501Srpaulo case WLAN_FC_TYPE_DATA: 410214501Srpaulo hostapd_tx_status(hapd, data->tx_status.dst, 411214501Srpaulo data->tx_status.data, 412214501Srpaulo data->tx_status.data_len, 413214501Srpaulo data->tx_status.ack); 414214501Srpaulo break; 415214501Srpaulo } 416214501Srpaulo break; 417214501Srpaulo case EVENT_RX_FROM_UNKNOWN: 418214501Srpaulo hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.frame, 419214501Srpaulo data->rx_from_unknown.len); 420214501Srpaulo break; 421214501Srpaulo case EVENT_RX_MGMT: 422214501Srpaulo hostapd_mgmt_rx(hapd, &data->rx_mgmt); 423214501Srpaulo break; 424214501Srpaulo#endif /* NEED_AP_MLME */ 425214501Srpaulo case EVENT_RX_PROBE_REQ: 426214501Srpaulo hostapd_probe_req_rx(hapd, data->rx_probe_req.sa, 427214501Srpaulo data->rx_probe_req.ie, 428214501Srpaulo data->rx_probe_req.ie_len); 429214501Srpaulo break; 430214501Srpaulo case EVENT_NEW_STA: 431214501Srpaulo hostapd_event_new_sta(hapd, data->new_sta.addr); 432214501Srpaulo break; 433214501Srpaulo case EVENT_EAPOL_RX: 434214501Srpaulo hostapd_event_eapol_rx(hapd, data->eapol_rx.src, 435214501Srpaulo data->eapol_rx.data, 436214501Srpaulo data->eapol_rx.data_len); 437214501Srpaulo break; 438214501Srpaulo case EVENT_ASSOC: 439214501Srpaulo hostapd_notif_assoc(hapd, data->assoc_info.addr, 440214501Srpaulo data->assoc_info.req_ies, 441214501Srpaulo data->assoc_info.req_ies_len); 442214501Srpaulo break; 443214501Srpaulo case EVENT_DISASSOC: 444214501Srpaulo if (data) 445214501Srpaulo hostapd_notif_disassoc(hapd, data->disassoc_info.addr); 446214501Srpaulo break; 447214501Srpaulo case EVENT_DEAUTH: 448214501Srpaulo if (data) 449214501Srpaulo hostapd_notif_disassoc(hapd, data->deauth_info.addr); 450214501Srpaulo break; 451214501Srpaulo default: 452214501Srpaulo wpa_printf(MSG_DEBUG, "Unknown event %d", event); 453214501Srpaulo break; 454214501Srpaulo } 455214501Srpaulo} 456214501Srpaulo 457214501Srpaulo#endif /* HOSTAPD */ 458