00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
00046
00047
00048
00049
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
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
00196
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
00286
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
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
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
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