$search
00001 /* 00002 * hostapd / Callback functions for driver wrappers 00003 * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "utils/includes.h" 00016 00017 #include "utils/common.h" 00018 #include "radius/radius.h" 00019 #include "drivers/driver.h" 00020 #include "common/ieee802_11_defs.h" 00021 #include "common/ieee802_11_common.h" 00022 #include "common/wpa_ctrl.h" 00023 #include "hostapd.h" 00024 #include "ieee802_11.h" 00025 #include "sta_info.h" 00026 #include "accounting.h" 00027 #include "tkip_countermeasures.h" 00028 #include "iapp.h" 00029 #include "ieee802_1x.h" 00030 #include "wpa_auth.h" 00031 #include "wmm.h" 00032 #include "wps_hostapd.h" 00033 #include "ap_config.h" 00034 00035 00036 int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, 00037 const u8 *ie, size_t ielen) 00038 { 00039 struct sta_info *sta; 00040 int new_assoc, res; 00041 struct ieee802_11_elems elems; 00042 00043 if (addr == NULL) { 00044 /* 00045 * This could potentially happen with unexpected event from the 00046 * driver wrapper. This was seen at least in one case where the 00047 * driver ended up being set to station mode while hostapd was 00048 * running, so better make sure we stop processing such an 00049 * event here. 00050 */ 00051 wpa_printf(MSG_DEBUG, "hostapd_notif_assoc: Skip event with " 00052 "no address"); 00053 return -1; 00054 } 00055 00056 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, 00057 HOSTAPD_LEVEL_INFO, "associated"); 00058 00059 ieee802_11_parse_elems(ie, ielen, &elems, 0); 00060 if (elems.wps_ie) { 00061 ie = elems.wps_ie - 2; 00062 ielen = elems.wps_ie_len + 2; 00063 wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)AssocReq"); 00064 } else if (elems.rsn_ie) { 00065 ie = elems.rsn_ie - 2; 00066 ielen = elems.rsn_ie_len + 2; 00067 wpa_printf(MSG_DEBUG, "STA included RSN IE in (Re)AssocReq"); 00068 } else if (elems.wpa_ie) { 00069 ie = elems.wpa_ie - 2; 00070 ielen = elems.wpa_ie_len + 2; 00071 wpa_printf(MSG_DEBUG, "STA included WPA IE in (Re)AssocReq"); 00072 } else { 00073 ie = NULL; 00074 ielen = 0; 00075 wpa_printf(MSG_DEBUG, "STA did not include WPS/RSN/WPA IE in " 00076 "(Re)AssocReq"); 00077 } 00078 00079 sta = ap_get_sta(hapd, addr); 00080 if (sta) { 00081 accounting_sta_stop(hapd, sta); 00082 } else { 00083 sta = ap_sta_add(hapd, addr); 00084 if (sta == NULL) 00085 return -1; 00086 } 00087 sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS); 00088 00089 if (hapd->conf->wpa) { 00090 if (ie == NULL || ielen == 0) { 00091 if (hapd->conf->wps_state) { 00092 wpa_printf(MSG_DEBUG, "STA did not include " 00093 "WPA/RSN IE in (Re)Association " 00094 "Request - possible WPS use"); 00095 sta->flags |= WLAN_STA_MAYBE_WPS; 00096 goto skip_wpa_check; 00097 } 00098 00099 wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA"); 00100 return -1; 00101 } 00102 if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 && 00103 os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) { 00104 sta->flags |= WLAN_STA_WPS; 00105 goto skip_wpa_check; 00106 } 00107 00108 if (sta->wpa_sm == NULL) 00109 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, 00110 sta->addr); 00111 if (sta->wpa_sm == NULL) { 00112 wpa_printf(MSG_ERROR, "Failed to initialize WPA state " 00113 "machine"); 00114 return -1; 00115 } 00116 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, 00117 ie, ielen, NULL, 0); 00118 if (res != WPA_IE_OK) { 00119 int resp; 00120 wpa_printf(MSG_DEBUG, "WPA/RSN information element " 00121 "rejected? (res %u)", res); 00122 wpa_hexdump(MSG_DEBUG, "IE", ie, ielen); 00123 if (res == WPA_INVALID_GROUP) 00124 resp = WLAN_REASON_GROUP_CIPHER_NOT_VALID; 00125 else if (res == WPA_INVALID_PAIRWISE) 00126 resp = WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID; 00127 else if (res == WPA_INVALID_AKMP) 00128 resp = WLAN_REASON_AKMP_NOT_VALID; 00129 #ifdef CONFIG_IEEE80211W 00130 else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION) 00131 resp = WLAN_REASON_INVALID_IE; 00132 else if (res == WPA_INVALID_MGMT_GROUP_CIPHER) 00133 resp = WLAN_REASON_GROUP_CIPHER_NOT_VALID; 00134 #endif /* CONFIG_IEEE80211W */ 00135 else 00136 resp = WLAN_REASON_INVALID_IE; 00137 hapd->drv.sta_disassoc(hapd, sta->addr, resp); 00138 ap_free_sta(hapd, sta); 00139 return -1; 00140 } 00141 } else if (hapd->conf->wps_state) { 00142 if (ie && ielen > 4 && ie[0] == 0xdd && ie[1] >= 4 && 00143 os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) { 00144 sta->flags |= WLAN_STA_WPS; 00145 } else 00146 sta->flags |= WLAN_STA_MAYBE_WPS; 00147 } 00148 skip_wpa_check: 00149 00150 new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0; 00151 sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC; 00152 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC); 00153 00154 hostapd_new_assoc_sta(hapd, sta, !new_assoc); 00155 00156 ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); 00157 00158 return 0; 00159 } 00160 00161 00162 void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr) 00163 { 00164 struct sta_info *sta; 00165 00166 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, 00167 HOSTAPD_LEVEL_INFO, "disassociated"); 00168 00169 sta = ap_get_sta(hapd, addr); 00170 if (sta == NULL) { 00171 wpa_printf(MSG_DEBUG, "Disassociation notification for " 00172 "unknown STA " MACSTR, MAC2STR(addr)); 00173 return; 00174 } 00175 00176 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); 00177 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR, 00178 MAC2STR(sta->addr)); 00179 wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC); 00180 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; 00181 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); 00182 ap_free_sta(hapd, sta); 00183 } 00184 00185 00186 #ifdef HOSTAPD 00187 00188 #ifdef NEED_AP_MLME 00189 00190 static const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len) 00191 { 00192 u16 fc, type, stype; 00193 00194 /* 00195 * PS-Poll frames are 16 bytes. All other frames are 00196 * 24 bytes or longer. 00197 */ 00198 if (len < 16) 00199 return NULL; 00200 00201 fc = le_to_host16(hdr->frame_control); 00202 type = WLAN_FC_GET_TYPE(fc); 00203 stype = WLAN_FC_GET_STYPE(fc); 00204 00205 switch (type) { 00206 case WLAN_FC_TYPE_DATA: 00207 if (len < 24) 00208 return NULL; 00209 switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) { 00210 case WLAN_FC_FROMDS | WLAN_FC_TODS: 00211 case WLAN_FC_TODS: 00212 return hdr->addr1; 00213 case WLAN_FC_FROMDS: 00214 return hdr->addr2; 00215 default: 00216 return NULL; 00217 } 00218 case WLAN_FC_TYPE_CTRL: 00219 if (stype != WLAN_FC_STYPE_PSPOLL) 00220 return NULL; 00221 return hdr->addr1; 00222 case WLAN_FC_TYPE_MGMT: 00223 return hdr->addr3; 00224 default: 00225 return NULL; 00226 } 00227 } 00228 00229 00230 #define HAPD_BROADCAST ((struct hostapd_data *) -1) 00231 00232 static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface, 00233 const u8 *bssid) 00234 { 00235 size_t i; 00236 00237 if (bssid == NULL) 00238 return NULL; 00239 if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff && 00240 bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff) 00241 return HAPD_BROADCAST; 00242 00243 for (i = 0; i < iface->num_bss; i++) { 00244 if (os_memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0) 00245 return iface->bss[i]; 00246 } 00247 00248 return NULL; 00249 } 00250 00251 00252 static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd, 00253 const u8 *frame, size_t len) 00254 { 00255 const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) frame; 00256 u16 fc = le_to_host16(hdr->frame_control); 00257 hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len)); 00258 if (hapd == NULL || hapd == HAPD_BROADCAST) 00259 return; 00260 00261 ieee802_11_rx_from_unknown(hapd, hdr->addr2, 00262 (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == 00263 (WLAN_FC_TODS | WLAN_FC_FROMDS)); 00264 } 00265 00266 00267 static void hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt) 00268 { 00269 struct hostapd_iface *iface = hapd->iface; 00270 const struct ieee80211_hdr *hdr; 00271 const u8 *bssid; 00272 struct hostapd_frame_info fi; 00273 00274 hdr = (const struct ieee80211_hdr *) rx_mgmt->frame; 00275 bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len); 00276 if (bssid == NULL) 00277 return; 00278 00279 hapd = get_hapd_bssid(iface, bssid); 00280 if (hapd == NULL) { 00281 u16 fc; 00282 fc = le_to_host16(hdr->frame_control); 00283 00284 /* 00285 * Drop frames to unknown BSSIDs except for Beacon frames which 00286 * could be used to update neighbor information. 00287 */ 00288 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && 00289 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) 00290 hapd = iface->bss[0]; 00291 else 00292 return; 00293 } 00294 00295 os_memset(&fi, 0, sizeof(fi)); 00296 fi.datarate = rx_mgmt->datarate; 00297 fi.ssi_signal = rx_mgmt->ssi_signal; 00298 00299 if (hapd == HAPD_BROADCAST) { 00300 size_t i; 00301 for (i = 0; i < iface->num_bss; i++) 00302 ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame, 00303 rx_mgmt->frame_len, &fi); 00304 } else 00305 ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len, &fi); 00306 } 00307 00308 00309 static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf, 00310 size_t len, u16 stype, int ok) 00311 { 00312 struct ieee80211_hdr *hdr; 00313 hdr = (struct ieee80211_hdr *) buf; 00314 hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len)); 00315 if (hapd == NULL || hapd == HAPD_BROADCAST) 00316 return; 00317 ieee802_11_mgmt_cb(hapd, buf, len, stype, ok); 00318 } 00319 00320 #endif /* NEED_AP_MLME */ 00321 00322 00323 static int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, 00324 const u8 *ie, size_t ie_len) 00325 { 00326 size_t i; 00327 int ret = 0; 00328 00329 for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) { 00330 if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx, 00331 sa, ie, ie_len) > 0) { 00332 ret = 1; 00333 break; 00334 } 00335 } 00336 return ret; 00337 } 00338 00339 00340 static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr) 00341 { 00342 struct sta_info *sta = ap_get_sta(hapd, addr); 00343 if (sta) 00344 return 0; 00345 00346 wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR 00347 " - adding a new STA", MAC2STR(addr)); 00348 sta = ap_sta_add(hapd, addr); 00349 if (sta) { 00350 hostapd_new_assoc_sta(hapd, sta, 0); 00351 } else { 00352 wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR, 00353 MAC2STR(addr)); 00354 return -1; 00355 } 00356 00357 return 0; 00358 } 00359 00360 00361 static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src, 00362 const u8 *data, size_t data_len) 00363 { 00364 struct hostapd_iface *iface = hapd->iface; 00365 size_t j; 00366 00367 for (j = 0; j < iface->num_bss; j++) { 00368 if (ap_get_sta(iface->bss[j], src)) { 00369 hapd = iface->bss[j]; 00370 break; 00371 } 00372 } 00373 00374 ieee802_1x_receive(hapd, src, data, data_len); 00375 } 00376 00377 00378 void wpa_supplicant_event(void *ctx, enum wpa_event_type event, 00379 union wpa_event_data *data) 00380 { 00381 struct hostapd_data *hapd = ctx; 00382 00383 switch (event) { 00384 case EVENT_MICHAEL_MIC_FAILURE: 00385 michael_mic_failure(hapd, data->michael_mic_failure.src, 1); 00386 break; 00387 case EVENT_SCAN_RESULTS: 00388 if (hapd->iface->scan_cb) 00389 hapd->iface->scan_cb(hapd->iface); 00390 break; 00391 #ifdef CONFIG_IEEE80211R 00392 case EVENT_FT_RRB_RX: 00393 wpa_ft_rrb_rx(hapd->wpa_auth, data->ft_rrb_rx.src, 00394 data->ft_rrb_rx.data, data->ft_rrb_rx.data_len); 00395 break; 00396 #endif /* CONFIG_IEEE80211R */ 00397 case EVENT_WPS_BUTTON_PUSHED: 00398 hostapd_wps_button_pushed(hapd); 00399 break; 00400 #ifdef NEED_AP_MLME 00401 case EVENT_TX_STATUS: 00402 switch (data->tx_status.type) { 00403 case WLAN_FC_TYPE_MGMT: 00404 hostapd_mgmt_tx_cb(hapd, data->tx_status.data, 00405 data->tx_status.data_len, 00406 data->tx_status.stype, 00407 data->tx_status.ack); 00408 break; 00409 case WLAN_FC_TYPE_DATA: 00410 hostapd_tx_status(hapd, data->tx_status.dst, 00411 data->tx_status.data, 00412 data->tx_status.data_len, 00413 data->tx_status.ack); 00414 break; 00415 } 00416 break; 00417 case EVENT_RX_FROM_UNKNOWN: 00418 hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.frame, 00419 data->rx_from_unknown.len); 00420 break; 00421 case EVENT_RX_MGMT: 00422 hostapd_mgmt_rx(hapd, &data->rx_mgmt); 00423 break; 00424 #endif /* NEED_AP_MLME */ 00425 case EVENT_RX_PROBE_REQ: 00426 hostapd_probe_req_rx(hapd, data->rx_probe_req.sa, 00427 data->rx_probe_req.ie, 00428 data->rx_probe_req.ie_len); 00429 break; 00430 case EVENT_NEW_STA: 00431 hostapd_event_new_sta(hapd, data->new_sta.addr); 00432 break; 00433 case EVENT_EAPOL_RX: 00434 hostapd_event_eapol_rx(hapd, data->eapol_rx.src, 00435 data->eapol_rx.data, 00436 data->eapol_rx.data_len); 00437 break; 00438 case EVENT_ASSOC: 00439 hostapd_notif_assoc(hapd, data->assoc_info.addr, 00440 data->assoc_info.req_ies, 00441 data->assoc_info.req_ies_len); 00442 break; 00443 case EVENT_DISASSOC: 00444 if (data) 00445 hostapd_notif_disassoc(hapd, data->disassoc_info.addr); 00446 break; 00447 case EVENT_DEAUTH: 00448 if (data) 00449 hostapd_notif_disassoc(hapd, data->deauth_info.addr); 00450 break; 00451 default: 00452 wpa_printf(MSG_DEBUG, "Unknown event %d", event); 00453 break; 00454 } 00455 } 00456 00457 #endif /* HOSTAPD */