Home | History | Annotate | Download | only in ap
      1 /*
      2  * hostapd / Callback functions for driver wrappers
      3  * Copyright (c) 2002-2013, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "utils/includes.h"
     10 
     11 #include "utils/common.h"
     12 #include "utils/eloop.h"
     13 #include "radius/radius.h"
     14 #include "drivers/driver.h"
     15 #include "common/ieee802_11_defs.h"
     16 #include "common/ieee802_11_common.h"
     17 #include "common/wpa_ctrl.h"
     18 #include "crypto/random.h"
     19 #include "p2p/p2p.h"
     20 #include "wps/wps.h"
     21 #include "fst/fst.h"
     22 #include "wnm_ap.h"
     23 #include "hostapd.h"
     24 #include "ieee802_11.h"
     25 #include "ieee802_11_auth.h"
     26 #include "sta_info.h"
     27 #include "accounting.h"
     28 #include "tkip_countermeasures.h"
     29 #include "ieee802_1x.h"
     30 #include "wpa_auth.h"
     31 #include "wps_hostapd.h"
     32 #include "ap_drv_ops.h"
     33 #include "ap_config.h"
     34 #include "hw_features.h"
     35 #include "dfs.h"
     36 #include "beacon.h"
     37 #include "mbo_ap.h"
     38 
     39 
     40 int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
     41 			const u8 *req_ies, size_t req_ies_len, int reassoc)
     42 {
     43 	struct sta_info *sta;
     44 	int new_assoc, res;
     45 	struct ieee802_11_elems elems;
     46 	const u8 *ie;
     47 	size_t ielen;
     48 #if defined(CONFIG_IEEE80211R_AP) || defined(CONFIG_IEEE80211W)
     49 	u8 buf[sizeof(struct ieee80211_mgmt) + 1024];
     50 	u8 *p = buf;
     51 #endif /* CONFIG_IEEE80211R_AP || CONFIG_IEEE80211W */
     52 	u16 reason = WLAN_REASON_UNSPECIFIED;
     53 	u16 status = WLAN_STATUS_SUCCESS;
     54 	const u8 *p2p_dev_addr = NULL;
     55 
     56 	if (addr == NULL) {
     57 		/*
     58 		 * This could potentially happen with unexpected event from the
     59 		 * driver wrapper. This was seen at least in one case where the
     60 		 * driver ended up being set to station mode while hostapd was
     61 		 * running, so better make sure we stop processing such an
     62 		 * event here.
     63 		 */
     64 		wpa_printf(MSG_DEBUG,
     65 			   "hostapd_notif_assoc: Skip event with no address");
     66 		return -1;
     67 	}
     68 	random_add_randomness(addr, ETH_ALEN);
     69 
     70 	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
     71 		       HOSTAPD_LEVEL_INFO, "associated");
     72 
     73 	ieee802_11_parse_elems(req_ies, req_ies_len, &elems, 0);
     74 	if (elems.wps_ie) {
     75 		ie = elems.wps_ie - 2;
     76 		ielen = elems.wps_ie_len + 2;
     77 		wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)AssocReq");
     78 	} else if (elems.rsn_ie) {
     79 		ie = elems.rsn_ie - 2;
     80 		ielen = elems.rsn_ie_len + 2;
     81 		wpa_printf(MSG_DEBUG, "STA included RSN IE in (Re)AssocReq");
     82 	} else if (elems.wpa_ie) {
     83 		ie = elems.wpa_ie - 2;
     84 		ielen = elems.wpa_ie_len + 2;
     85 		wpa_printf(MSG_DEBUG, "STA included WPA IE in (Re)AssocReq");
     86 #ifdef CONFIG_HS20
     87 	} else if (elems.osen) {
     88 		ie = elems.osen - 2;
     89 		ielen = elems.osen_len + 2;
     90 		wpa_printf(MSG_DEBUG, "STA included OSEN IE in (Re)AssocReq");
     91 #endif /* CONFIG_HS20 */
     92 	} else {
     93 		ie = NULL;
     94 		ielen = 0;
     95 		wpa_printf(MSG_DEBUG,
     96 			   "STA did not include WPS/RSN/WPA IE in (Re)AssocReq");
     97 	}
     98 
     99 	sta = ap_get_sta(hapd, addr);
    100 	if (sta) {
    101 		ap_sta_no_session_timeout(hapd, sta);
    102 		accounting_sta_stop(hapd, sta);
    103 
    104 		/*
    105 		 * Make sure that the previously registered inactivity timer
    106 		 * will not remove the STA immediately.
    107 		 */
    108 		sta->timeout_next = STA_NULLFUNC;
    109 	} else {
    110 		sta = ap_sta_add(hapd, addr);
    111 		if (sta == NULL) {
    112 			hostapd_drv_sta_disassoc(hapd, addr,
    113 						 WLAN_REASON_DISASSOC_AP_BUSY);
    114 			return -1;
    115 		}
    116 	}
    117 	sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
    118 
    119 	/*
    120 	 * ACL configurations to the drivers (implementing AP SME and ACL
    121 	 * offload) without hostapd's knowledge, can result in a disconnection
    122 	 * though the driver accepts the connection. Skip the hostapd check for
    123 	 * ACL if the driver supports ACL offload to avoid potentially
    124 	 * conflicting ACL rules.
    125 	 */
    126 	if (hapd->iface->drv_max_acl_mac_addrs == 0 &&
    127 	    hostapd_check_acl(hapd, addr, NULL) != HOSTAPD_ACL_ACCEPT) {
    128 		wpa_printf(MSG_INFO, "STA " MACSTR " not allowed to connect",
    129 			   MAC2STR(addr));
    130 		reason = WLAN_REASON_UNSPECIFIED;
    131 		goto fail;
    132 	}
    133 
    134 #ifdef CONFIG_P2P
    135 	if (elems.p2p) {
    136 		wpabuf_free(sta->p2p_ie);
    137 		sta->p2p_ie = ieee802_11_vendor_ie_concat(req_ies, req_ies_len,
    138 							  P2P_IE_VENDOR_TYPE);
    139 		if (sta->p2p_ie)
    140 			p2p_dev_addr = p2p_get_go_dev_addr(sta->p2p_ie);
    141 	}
    142 #endif /* CONFIG_P2P */
    143 
    144 #ifdef CONFIG_IEEE80211N
    145 #ifdef NEED_AP_MLME
    146 	if (elems.ht_capabilities &&
    147 	    (hapd->iface->conf->ht_capab &
    148 	     HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
    149 		struct ieee80211_ht_capabilities *ht_cap =
    150 			(struct ieee80211_ht_capabilities *)
    151 			elems.ht_capabilities;
    152 
    153 		if (le_to_host16(ht_cap->ht_capabilities_info) &
    154 		    HT_CAP_INFO_40MHZ_INTOLERANT)
    155 			ht40_intolerant_add(hapd->iface, sta);
    156 	}
    157 #endif /* NEED_AP_MLME */
    158 #endif /* CONFIG_IEEE80211N */
    159 
    160 #ifdef CONFIG_INTERWORKING
    161 	if (elems.ext_capab && elems.ext_capab_len > 4) {
    162 		if (elems.ext_capab[4] & 0x01)
    163 			sta->qos_map_enabled = 1;
    164 	}
    165 #endif /* CONFIG_INTERWORKING */
    166 
    167 #ifdef CONFIG_HS20
    168 	wpabuf_free(sta->hs20_ie);
    169 	if (elems.hs20 && elems.hs20_len > 4) {
    170 		sta->hs20_ie = wpabuf_alloc_copy(elems.hs20 + 4,
    171 						 elems.hs20_len - 4);
    172 	} else
    173 		sta->hs20_ie = NULL;
    174 #endif /* CONFIG_HS20 */
    175 
    176 #ifdef CONFIG_FST
    177 	wpabuf_free(sta->mb_ies);
    178 	if (hapd->iface->fst)
    179 		sta->mb_ies = mb_ies_by_info(&elems.mb_ies);
    180 	else
    181 		sta->mb_ies = NULL;
    182 #endif /* CONFIG_FST */
    183 
    184 	mbo_ap_check_sta_assoc(hapd, sta, &elems);
    185 
    186 	ap_copy_sta_supp_op_classes(sta, elems.supp_op_classes,
    187 				    elems.supp_op_classes_len);
    188 
    189 	if (hapd->conf->wpa) {
    190 		if (ie == NULL || ielen == 0) {
    191 #ifdef CONFIG_WPS
    192 			if (hapd->conf->wps_state) {
    193 				wpa_printf(MSG_DEBUG,
    194 					   "STA did not include WPA/RSN IE in (Re)Association Request - possible WPS use");
    195 				sta->flags |= WLAN_STA_MAYBE_WPS;
    196 				goto skip_wpa_check;
    197 			}
    198 #endif /* CONFIG_WPS */
    199 
    200 			wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA");
    201 			return -1;
    202 		}
    203 #ifdef CONFIG_WPS
    204 		if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 &&
    205 		    os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) {
    206 			struct wpabuf *wps;
    207 
    208 			sta->flags |= WLAN_STA_WPS;
    209 			wps = ieee802_11_vendor_ie_concat(ie, ielen,
    210 							  WPS_IE_VENDOR_TYPE);
    211 			if (wps) {
    212 				if (wps_is_20(wps)) {
    213 					wpa_printf(MSG_DEBUG,
    214 						   "WPS: STA supports WPS 2.0");
    215 					sta->flags |= WLAN_STA_WPS2;
    216 				}
    217 				wpabuf_free(wps);
    218 			}
    219 			goto skip_wpa_check;
    220 		}
    221 #endif /* CONFIG_WPS */
    222 
    223 		if (sta->wpa_sm == NULL)
    224 			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
    225 							sta->addr,
    226 							p2p_dev_addr);
    227 		if (sta->wpa_sm == NULL) {
    228 			wpa_printf(MSG_ERROR,
    229 				   "Failed to initialize WPA state machine");
    230 			return -1;
    231 		}
    232 		res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
    233 					  ie, ielen,
    234 					  elems.mdie, elems.mdie_len);
    235 		if (res != WPA_IE_OK) {
    236 			wpa_printf(MSG_DEBUG,
    237 				   "WPA/RSN information element rejected? (res %u)",
    238 				   res);
    239 			wpa_hexdump(MSG_DEBUG, "IE", ie, ielen);
    240 			if (res == WPA_INVALID_GROUP) {
    241 				reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID;
    242 				status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
    243 			} else if (res == WPA_INVALID_PAIRWISE) {
    244 				reason = WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID;
    245 				status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
    246 			} else if (res == WPA_INVALID_AKMP) {
    247 				reason = WLAN_REASON_AKMP_NOT_VALID;
    248 				status = WLAN_STATUS_AKMP_NOT_VALID;
    249 			}
    250 #ifdef CONFIG_IEEE80211W
    251 			else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION) {
    252 				reason = WLAN_REASON_INVALID_IE;
    253 				status = WLAN_STATUS_INVALID_IE;
    254 			} else if (res == WPA_INVALID_MGMT_GROUP_CIPHER) {
    255 				reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID;
    256 				status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
    257 			}
    258 #endif /* CONFIG_IEEE80211W */
    259 			else {
    260 				reason = WLAN_REASON_INVALID_IE;
    261 				status = WLAN_STATUS_INVALID_IE;
    262 			}
    263 			goto fail;
    264 		}
    265 #ifdef CONFIG_IEEE80211W
    266 		if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
    267 		    sta->sa_query_count > 0)
    268 			ap_check_sa_query_timeout(hapd, sta);
    269 		if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
    270 		    (sta->auth_alg != WLAN_AUTH_FT)) {
    271 			/*
    272 			 * STA has already been associated with MFP and SA
    273 			 * Query timeout has not been reached. Reject the
    274 			 * association attempt temporarily and start SA Query,
    275 			 * if one is not pending.
    276 			 */
    277 
    278 			if (sta->sa_query_count == 0)
    279 				ap_sta_start_sa_query(hapd, sta);
    280 
    281 			status = WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
    282 
    283 			p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
    284 
    285 			hostapd_sta_assoc(hapd, addr, reassoc, status, buf,
    286 					  p - buf);
    287 			return 0;
    288 		}
    289 
    290 		if (wpa_auth_uses_mfp(sta->wpa_sm))
    291 			sta->flags |= WLAN_STA_MFP;
    292 		else
    293 			sta->flags &= ~WLAN_STA_MFP;
    294 #endif /* CONFIG_IEEE80211W */
    295 
    296 #ifdef CONFIG_IEEE80211R_AP
    297 		if (sta->auth_alg == WLAN_AUTH_FT) {
    298 			status = wpa_ft_validate_reassoc(sta->wpa_sm, req_ies,
    299 							 req_ies_len);
    300 			if (status != WLAN_STATUS_SUCCESS) {
    301 				if (status == WLAN_STATUS_INVALID_PMKID)
    302 					reason = WLAN_REASON_INVALID_IE;
    303 				if (status == WLAN_STATUS_INVALID_MDIE)
    304 					reason = WLAN_REASON_INVALID_IE;
    305 				if (status == WLAN_STATUS_INVALID_FTIE)
    306 					reason = WLAN_REASON_INVALID_IE;
    307 				goto fail;
    308 			}
    309 		}
    310 #endif /* CONFIG_IEEE80211R_AP */
    311 	} else if (hapd->conf->wps_state) {
    312 #ifdef CONFIG_WPS
    313 		struct wpabuf *wps;
    314 
    315 		if (req_ies)
    316 			wps = ieee802_11_vendor_ie_concat(req_ies, req_ies_len,
    317 							  WPS_IE_VENDOR_TYPE);
    318 		else
    319 			wps = NULL;
    320 #ifdef CONFIG_WPS_STRICT
    321 		if (wps && wps_validate_assoc_req(wps) < 0) {
    322 			reason = WLAN_REASON_INVALID_IE;
    323 			status = WLAN_STATUS_INVALID_IE;
    324 			wpabuf_free(wps);
    325 			goto fail;
    326 		}
    327 #endif /* CONFIG_WPS_STRICT */
    328 		if (wps) {
    329 			sta->flags |= WLAN_STA_WPS;
    330 			if (wps_is_20(wps)) {
    331 				wpa_printf(MSG_DEBUG,
    332 					   "WPS: STA supports WPS 2.0");
    333 				sta->flags |= WLAN_STA_WPS2;
    334 			}
    335 		} else
    336 			sta->flags |= WLAN_STA_MAYBE_WPS;
    337 		wpabuf_free(wps);
    338 #endif /* CONFIG_WPS */
    339 #ifdef CONFIG_HS20
    340 	} else if (hapd->conf->osen) {
    341 		if (elems.osen == NULL) {
    342 			hostapd_logger(
    343 				hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    344 				HOSTAPD_LEVEL_INFO,
    345 				"No HS 2.0 OSEN element in association request");
    346 			return WLAN_STATUS_INVALID_IE;
    347 		}
    348 
    349 		wpa_printf(MSG_DEBUG, "HS 2.0: OSEN association");
    350 		if (sta->wpa_sm == NULL)
    351 			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
    352 							sta->addr, NULL);
    353 		if (sta->wpa_sm == NULL) {
    354 			wpa_printf(MSG_WARNING,
    355 				   "Failed to initialize WPA state machine");
    356 			return WLAN_STATUS_UNSPECIFIED_FAILURE;
    357 		}
    358 		if (wpa_validate_osen(hapd->wpa_auth, sta->wpa_sm,
    359 				      elems.osen - 2, elems.osen_len + 2) < 0)
    360 			return WLAN_STATUS_INVALID_IE;
    361 #endif /* CONFIG_HS20 */
    362 	}
    363 
    364 #ifdef CONFIG_MBO
    365 	if (hapd->conf->mbo_enabled && (hapd->conf->wpa & 2) &&
    366 	    elems.mbo && sta->cell_capa && !(sta->flags & WLAN_STA_MFP) &&
    367 	    hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
    368 		wpa_printf(MSG_INFO,
    369 			   "MBO: Reject WPA2 association without PMF");
    370 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
    371 	}
    372 #endif /* CONFIG_MBO */
    373 
    374 #ifdef CONFIG_WPS
    375 skip_wpa_check:
    376 #endif /* CONFIG_WPS */
    377 
    378 #ifdef CONFIG_IEEE80211R_AP
    379 	p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, buf, sizeof(buf),
    380 					sta->auth_alg, req_ies, req_ies_len);
    381 
    382 	hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf);
    383 
    384 	if (sta->auth_alg == WLAN_AUTH_FT)
    385 		ap_sta_set_authorized(hapd, sta, 1);
    386 #else /* CONFIG_IEEE80211R_AP */
    387 	/* Keep compiler silent about unused variables */
    388 	if (status) {
    389 	}
    390 #endif /* CONFIG_IEEE80211R_AP */
    391 
    392 	new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
    393 	sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
    394 	sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
    395 
    396 	hostapd_set_sta_flags(hapd, sta);
    397 
    398 	if (reassoc && (sta->auth_alg == WLAN_AUTH_FT))
    399 		wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
    400 	else
    401 		wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
    402 
    403 	hostapd_new_assoc_sta(hapd, sta, !new_assoc);
    404 
    405 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
    406 
    407 #ifdef CONFIG_P2P
    408 	if (req_ies) {
    409 		p2p_group_notif_assoc(hapd->p2p_group, sta->addr,
    410 				      req_ies, req_ies_len);
    411 	}
    412 #endif /* CONFIG_P2P */
    413 
    414 	return 0;
    415 
    416 fail:
    417 #ifdef CONFIG_IEEE80211R_AP
    418 	hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf);
    419 #endif /* CONFIG_IEEE80211R_AP */
    420 	hostapd_drv_sta_disassoc(hapd, sta->addr, reason);
    421 	ap_free_sta(hapd, sta);
    422 	return -1;
    423 }
    424 
    425 
    426 void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
    427 {
    428 	struct sta_info *sta;
    429 
    430 	if (addr == NULL) {
    431 		/*
    432 		 * This could potentially happen with unexpected event from the
    433 		 * driver wrapper. This was seen at least in one case where the
    434 		 * driver ended up reporting a station mode event while hostapd
    435 		 * was running, so better make sure we stop processing such an
    436 		 * event here.
    437 		 */
    438 		wpa_printf(MSG_DEBUG,
    439 			   "hostapd_notif_disassoc: Skip event with no address");
    440 		return;
    441 	}
    442 
    443 	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
    444 		       HOSTAPD_LEVEL_INFO, "disassociated");
    445 
    446 	sta = ap_get_sta(hapd, addr);
    447 	if (sta == NULL) {
    448 		wpa_printf(MSG_DEBUG,
    449 			   "Disassociation notification for unknown STA "
    450 			   MACSTR, MAC2STR(addr));
    451 		return;
    452 	}
    453 
    454 	ap_sta_set_authorized(hapd, sta, 0);
    455 	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
    456 	wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
    457 	sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
    458 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
    459 	ap_free_sta(hapd, sta);
    460 }
    461 
    462 
    463 void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr)
    464 {
    465 	struct sta_info *sta = ap_get_sta(hapd, addr);
    466 
    467 	if (!sta || !hapd->conf->disassoc_low_ack)
    468 		return;
    469 
    470 	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
    471 		       HOSTAPD_LEVEL_INFO,
    472 		       "disconnected due to excessive missing ACKs");
    473 	hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_DISASSOC_LOW_ACK);
    474 	ap_sta_disassociate(hapd, sta, WLAN_REASON_DISASSOC_LOW_ACK);
    475 }
    476 
    477 
    478 void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
    479 			     int offset, int width, int cf1, int cf2)
    480 {
    481 #ifdef NEED_AP_MLME
    482 	int channel, chwidth, is_dfs;
    483 	u8 seg0_idx = 0, seg1_idx = 0;
    484 
    485 	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
    486 		       HOSTAPD_LEVEL_INFO,
    487 		       "driver had channel switch: freq=%d, ht=%d, offset=%d, width=%d (%s), cf1=%d, cf2=%d",
    488 		       freq, ht, offset, width, channel_width_to_string(width),
    489 		       cf1, cf2);
    490 
    491 	hapd->iface->freq = freq;
    492 
    493 	channel = hostapd_hw_get_channel(hapd, freq);
    494 	if (!channel) {
    495 		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
    496 			       HOSTAPD_LEVEL_WARNING,
    497 			       "driver switched to bad channel!");
    498 		return;
    499 	}
    500 
    501 	switch (width) {
    502 	case CHAN_WIDTH_80:
    503 		chwidth = VHT_CHANWIDTH_80MHZ;
    504 		break;
    505 	case CHAN_WIDTH_80P80:
    506 		chwidth = VHT_CHANWIDTH_80P80MHZ;
    507 		break;
    508 	case CHAN_WIDTH_160:
    509 		chwidth = VHT_CHANWIDTH_160MHZ;
    510 		break;
    511 	case CHAN_WIDTH_20_NOHT:
    512 	case CHAN_WIDTH_20:
    513 	case CHAN_WIDTH_40:
    514 	default:
    515 		chwidth = VHT_CHANWIDTH_USE_HT;
    516 		break;
    517 	}
    518 
    519 	switch (hapd->iface->current_mode->mode) {
    520 	case HOSTAPD_MODE_IEEE80211A:
    521 		if (cf1 > 5000)
    522 			seg0_idx = (cf1 - 5000) / 5;
    523 		if (cf2 > 5000)
    524 			seg1_idx = (cf2 - 5000) / 5;
    525 		break;
    526 	default:
    527 		ieee80211_freq_to_chan(cf1, &seg0_idx);
    528 		ieee80211_freq_to_chan(cf2, &seg1_idx);
    529 		break;
    530 	}
    531 
    532 	hapd->iconf->channel = channel;
    533 	hapd->iconf->ieee80211n = ht;
    534 	if (!ht)
    535 		hapd->iconf->ieee80211ac = 0;
    536 	hapd->iconf->secondary_channel = offset;
    537 	hapd->iconf->vht_oper_chwidth = chwidth;
    538 	hapd->iconf->vht_oper_centr_freq_seg0_idx = seg0_idx;
    539 	hapd->iconf->vht_oper_centr_freq_seg1_idx = seg1_idx;
    540 
    541 	is_dfs = ieee80211_is_dfs(freq);
    542 
    543 	if (hapd->csa_in_progress &&
    544 	    freq == hapd->cs_freq_params.freq) {
    545 		hostapd_cleanup_cs_params(hapd);
    546 		ieee802_11_set_beacon(hapd);
    547 
    548 		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
    549 			"freq=%d dfs=%d", freq, is_dfs);
    550 	} else if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) {
    551 		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
    552 			"freq=%d dfs=%d", freq, is_dfs);
    553 	}
    554 #endif /* NEED_AP_MLME */
    555 }
    556 
    557 
    558 void hostapd_event_connect_failed_reason(struct hostapd_data *hapd,
    559 					 const u8 *addr, int reason_code)
    560 {
    561 	switch (reason_code) {
    562 	case MAX_CLIENT_REACHED:
    563 		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_REJECTED_MAX_STA MACSTR,
    564 			MAC2STR(addr));
    565 		break;
    566 	case BLOCKED_CLIENT:
    567 		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_REJECTED_BLOCKED_STA MACSTR,
    568 			MAC2STR(addr));
    569 		break;
    570 	}
    571 }
    572 
    573 
    574 #ifdef CONFIG_ACS
    575 void hostapd_acs_channel_selected(struct hostapd_data *hapd,
    576 				  struct acs_selected_channels *acs_res)
    577 {
    578 	int ret, i;
    579 	int err = 0;
    580 
    581 	if (hapd->iconf->channel) {
    582 		wpa_printf(MSG_INFO, "ACS: Channel was already set to %d",
    583 			   hapd->iconf->channel);
    584 		return;
    585 	}
    586 
    587 	if (!hapd->iface->current_mode) {
    588 		for (i = 0; i < hapd->iface->num_hw_features; i++) {
    589 			struct hostapd_hw_modes *mode =
    590 				&hapd->iface->hw_features[i];
    591 
    592 			if (mode->mode == acs_res->hw_mode) {
    593 				hapd->iface->current_mode = mode;
    594 				break;
    595 			}
    596 		}
    597 		if (!hapd->iface->current_mode) {
    598 			hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
    599 				       HOSTAPD_LEVEL_WARNING,
    600 				       "driver selected to bad hw_mode");
    601 			err = 1;
    602 			goto out;
    603 		}
    604 	}
    605 
    606 	hapd->iface->freq = hostapd_hw_get_freq(hapd, acs_res->pri_channel);
    607 
    608 	if (!acs_res->pri_channel) {
    609 		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
    610 			       HOSTAPD_LEVEL_WARNING,
    611 			       "driver switched to bad channel");
    612 		err = 1;
    613 		goto out;
    614 	}
    615 
    616 	hapd->iconf->channel = acs_res->pri_channel;
    617 	hapd->iconf->acs = 1;
    618 
    619 	if (acs_res->sec_channel == 0)
    620 		hapd->iconf->secondary_channel = 0;
    621 	else if (acs_res->sec_channel < acs_res->pri_channel)
    622 		hapd->iconf->secondary_channel = -1;
    623 	else if (acs_res->sec_channel > acs_res->pri_channel)
    624 		hapd->iconf->secondary_channel = 1;
    625 	else {
    626 		wpa_printf(MSG_ERROR, "Invalid secondary channel!");
    627 		err = 1;
    628 		goto out;
    629 	}
    630 
    631 	if (hapd->iface->conf->ieee80211ac) {
    632 		/* set defaults for backwards compatibility */
    633 		hapd->iconf->vht_oper_centr_freq_seg1_idx = 0;
    634 		hapd->iconf->vht_oper_centr_freq_seg0_idx = 0;
    635 		hapd->iconf->vht_oper_chwidth = VHT_CHANWIDTH_USE_HT;
    636 		if (acs_res->ch_width == 80) {
    637 			hapd->iconf->vht_oper_centr_freq_seg0_idx =
    638 				acs_res->vht_seg0_center_ch;
    639 			hapd->iconf->vht_oper_chwidth = VHT_CHANWIDTH_80MHZ;
    640 		} else if (acs_res->ch_width == 160) {
    641 			if (acs_res->vht_seg1_center_ch == 0) {
    642 				hapd->iconf->vht_oper_centr_freq_seg0_idx =
    643 					acs_res->vht_seg0_center_ch;
    644 				hapd->iconf->vht_oper_chwidth =
    645 					VHT_CHANWIDTH_160MHZ;
    646 			} else {
    647 				hapd->iconf->vht_oper_centr_freq_seg0_idx =
    648 					acs_res->vht_seg0_center_ch;
    649 				hapd->iconf->vht_oper_centr_freq_seg1_idx =
    650 					acs_res->vht_seg1_center_ch;
    651 				hapd->iconf->vht_oper_chwidth =
    652 					VHT_CHANWIDTH_80P80MHZ;
    653 			}
    654 		}
    655 	}
    656 
    657 out:
    658 	ret = hostapd_acs_completed(hapd->iface, err);
    659 	if (ret) {
    660 		wpa_printf(MSG_ERROR,
    661 			   "ACS: Possibly channel configuration is invalid");
    662 	}
    663 }
    664 #endif /* CONFIG_ACS */
    665 
    666 
    667 int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
    668 			 const u8 *bssid, const u8 *ie, size_t ie_len,
    669 			 int ssi_signal)
    670 {
    671 	size_t i;
    672 	int ret = 0;
    673 
    674 	if (sa == NULL || ie == NULL)
    675 		return -1;
    676 
    677 	random_add_randomness(sa, ETH_ALEN);
    678 	for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) {
    679 		if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
    680 					    sa, da, bssid, ie, ie_len,
    681 					    ssi_signal) > 0) {
    682 			ret = 1;
    683 			break;
    684 		}
    685 	}
    686 	return ret;
    687 }
    688 
    689 
    690 #ifdef HOSTAPD
    691 
    692 #ifdef CONFIG_IEEE80211R_AP
    693 static void hostapd_notify_auth_ft_finish(void *ctx, const u8 *dst,
    694 					  const u8 *bssid,
    695 					  u16 auth_transaction, u16 status,
    696 					  const u8 *ies, size_t ies_len)
    697 {
    698 	struct hostapd_data *hapd = ctx;
    699 	struct sta_info *sta;
    700 
    701 	sta = ap_get_sta(hapd, dst);
    702 	if (sta == NULL)
    703 		return;
    704 
    705 	hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
    706 		       HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
    707 	sta->flags |= WLAN_STA_AUTH;
    708 
    709 	hostapd_sta_auth(hapd, dst, auth_transaction, status, ies, ies_len);
    710 }
    711 #endif /* CONFIG_IEEE80211R_AP */
    712 
    713 
    714 static void hostapd_notif_auth(struct hostapd_data *hapd,
    715 			       struct auth_info *rx_auth)
    716 {
    717 	struct sta_info *sta;
    718 	u16 status = WLAN_STATUS_SUCCESS;
    719 	u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
    720 	size_t resp_ies_len = 0;
    721 
    722 	sta = ap_get_sta(hapd, rx_auth->peer);
    723 	if (!sta) {
    724 		sta = ap_sta_add(hapd, rx_auth->peer);
    725 		if (sta == NULL) {
    726 			status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
    727 			goto fail;
    728 		}
    729 	}
    730 	sta->flags &= ~WLAN_STA_PREAUTH;
    731 	ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
    732 #ifdef CONFIG_IEEE80211R_AP
    733 	if (rx_auth->auth_type == WLAN_AUTH_FT && hapd->wpa_auth) {
    734 		sta->auth_alg = WLAN_AUTH_FT;
    735 		if (sta->wpa_sm == NULL)
    736 			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
    737 							sta->addr, NULL);
    738 		if (sta->wpa_sm == NULL) {
    739 			wpa_printf(MSG_DEBUG,
    740 				   "FT: Failed to initialize WPA state machine");
    741 			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
    742 			goto fail;
    743 		}
    744 		wpa_ft_process_auth(sta->wpa_sm, rx_auth->bssid,
    745 				    rx_auth->auth_transaction, rx_auth->ies,
    746 				    rx_auth->ies_len,
    747 				    hostapd_notify_auth_ft_finish, hapd);
    748 		return;
    749 	}
    750 #endif /* CONFIG_IEEE80211R_AP */
    751 fail:
    752 	hostapd_sta_auth(hapd, rx_auth->peer, rx_auth->auth_transaction + 1,
    753 			 status, resp_ies, resp_ies_len);
    754 }
    755 
    756 
    757 static void hostapd_action_rx(struct hostapd_data *hapd,
    758 			      struct rx_mgmt *drv_mgmt)
    759 {
    760 	struct ieee80211_mgmt *mgmt;
    761 	struct sta_info *sta;
    762 	size_t plen __maybe_unused;
    763 	u16 fc;
    764 
    765 	if (drv_mgmt->frame_len < 24 + 1)
    766 		return;
    767 
    768 	plen = drv_mgmt->frame_len - 24 - 1;
    769 
    770 	mgmt = (struct ieee80211_mgmt *) drv_mgmt->frame;
    771 	fc = le_to_host16(mgmt->frame_control);
    772 	if (WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ACTION)
    773 		return; /* handled by the driver */
    774 
    775 	wpa_printf(MSG_DEBUG, "RX_ACTION cat %d action plen %d",
    776 		   mgmt->u.action.category, (int) plen);
    777 
    778 	sta = ap_get_sta(hapd, mgmt->sa);
    779 	if (sta == NULL) {
    780 		wpa_printf(MSG_DEBUG, "%s: station not found", __func__);
    781 		return;
    782 	}
    783 #ifdef CONFIG_IEEE80211R_AP
    784 	if (mgmt->u.action.category == WLAN_ACTION_FT) {
    785 		const u8 *payload = drv_mgmt->frame + 24 + 1;
    786 
    787 		wpa_ft_action_rx(sta->wpa_sm, payload, plen);
    788 	}
    789 #endif /* CONFIG_IEEE80211R_AP */
    790 #ifdef CONFIG_IEEE80211W
    791 	if (mgmt->u.action.category == WLAN_ACTION_SA_QUERY && plen >= 4) {
    792 		ieee802_11_sa_query_action(
    793 			hapd, mgmt->sa,
    794 			mgmt->u.action.u.sa_query_resp.action,
    795 			mgmt->u.action.u.sa_query_resp.trans_id);
    796 	}
    797 #endif /* CONFIG_IEEE80211W */
    798 #ifdef CONFIG_WNM
    799 	if (mgmt->u.action.category == WLAN_ACTION_WNM) {
    800 		ieee802_11_rx_wnm_action_ap(hapd, mgmt, drv_mgmt->frame_len);
    801 	}
    802 #endif /* CONFIG_WNM */
    803 #ifdef CONFIG_FST
    804 	if (mgmt->u.action.category == WLAN_ACTION_FST && hapd->iface->fst) {
    805 		fst_rx_action(hapd->iface->fst, mgmt, drv_mgmt->frame_len);
    806 		return;
    807 	}
    808 #endif /* CONFIG_FST */
    809 
    810 }
    811 
    812 
    813 #ifdef NEED_AP_MLME
    814 
    815 #define HAPD_BROADCAST ((struct hostapd_data *) -1)
    816 
    817 static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface,
    818 					    const u8 *bssid)
    819 {
    820 	size_t i;
    821 
    822 	if (bssid == NULL)
    823 		return NULL;
    824 	if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff &&
    825 	    bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff)
    826 		return HAPD_BROADCAST;
    827 
    828 	for (i = 0; i < iface->num_bss; i++) {
    829 		if (os_memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0)
    830 			return iface->bss[i];
    831 	}
    832 
    833 	return NULL;
    834 }
    835 
    836 
    837 static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd,
    838 					const u8 *bssid, const u8 *addr,
    839 					int wds)
    840 {
    841 	hapd = get_hapd_bssid(hapd->iface, bssid);
    842 	if (hapd == NULL || hapd == HAPD_BROADCAST)
    843 		return;
    844 
    845 	ieee802_11_rx_from_unknown(hapd, addr, wds);
    846 }
    847 
    848 
    849 static int hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt)
    850 {
    851 	struct hostapd_iface *iface = hapd->iface;
    852 	const struct ieee80211_hdr *hdr;
    853 	const u8 *bssid;
    854 	struct hostapd_frame_info fi;
    855 	int ret;
    856 
    857 #ifdef CONFIG_TESTING_OPTIONS
    858 	if (hapd->ext_mgmt_frame_handling) {
    859 		size_t hex_len = 2 * rx_mgmt->frame_len + 1;
    860 		char *hex = os_malloc(hex_len);
    861 
    862 		if (hex) {
    863 			wpa_snprintf_hex(hex, hex_len, rx_mgmt->frame,
    864 					 rx_mgmt->frame_len);
    865 			wpa_msg(hapd->msg_ctx, MSG_INFO, "MGMT-RX %s", hex);
    866 			os_free(hex);
    867 		}
    868 		return 1;
    869 	}
    870 #endif /* CONFIG_TESTING_OPTIONS */
    871 
    872 	hdr = (const struct ieee80211_hdr *) rx_mgmt->frame;
    873 	bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len);
    874 	if (bssid == NULL)
    875 		return 0;
    876 
    877 	hapd = get_hapd_bssid(iface, bssid);
    878 	if (hapd == NULL) {
    879 		u16 fc = le_to_host16(hdr->frame_control);
    880 
    881 		/*
    882 		 * Drop frames to unknown BSSIDs except for Beacon frames which
    883 		 * could be used to update neighbor information.
    884 		 */
    885 		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
    886 		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
    887 			hapd = iface->bss[0];
    888 		else
    889 			return 0;
    890 	}
    891 
    892 	os_memset(&fi, 0, sizeof(fi));
    893 	fi.datarate = rx_mgmt->datarate;
    894 	fi.ssi_signal = rx_mgmt->ssi_signal;
    895 
    896 	if (hapd == HAPD_BROADCAST) {
    897 		size_t i;
    898 
    899 		ret = 0;
    900 		for (i = 0; i < iface->num_bss; i++) {
    901 			/* if bss is set, driver will call this function for
    902 			 * each bss individually. */
    903 			if (rx_mgmt->drv_priv &&
    904 			    (iface->bss[i]->drv_priv != rx_mgmt->drv_priv))
    905 				continue;
    906 
    907 			if (ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame,
    908 					    rx_mgmt->frame_len, &fi) > 0)
    909 				ret = 1;
    910 		}
    911 	} else
    912 		ret = ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len,
    913 				      &fi);
    914 
    915 	random_add_randomness(&fi, sizeof(fi));
    916 
    917 	return ret;
    918 }
    919 
    920 
    921 static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf,
    922 			       size_t len, u16 stype, int ok)
    923 {
    924 	struct ieee80211_hdr *hdr;
    925 	struct hostapd_data *orig_hapd = hapd;
    926 
    927 	hdr = (struct ieee80211_hdr *) buf;
    928 	hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len));
    929 	if (!hapd)
    930 		return;
    931 	if (hapd == HAPD_BROADCAST) {
    932 		if (stype != WLAN_FC_STYPE_ACTION || len <= 25 ||
    933 		    buf[24] != WLAN_ACTION_PUBLIC)
    934 			return;
    935 		hapd = get_hapd_bssid(orig_hapd->iface, hdr->addr2);
    936 		if (!hapd || hapd == HAPD_BROADCAST)
    937 			return;
    938 		/*
    939 		 * Allow processing of TX status for a Public Action frame that
    940 		 * used wildcard BBSID.
    941 		 */
    942 	}
    943 	ieee802_11_mgmt_cb(hapd, buf, len, stype, ok);
    944 }
    945 
    946 #endif /* NEED_AP_MLME */
    947 
    948 
    949 static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr)
    950 {
    951 	struct sta_info *sta = ap_get_sta(hapd, addr);
    952 
    953 	if (sta)
    954 		return 0;
    955 
    956 	wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR
    957 		   " - adding a new STA", MAC2STR(addr));
    958 	sta = ap_sta_add(hapd, addr);
    959 	if (sta) {
    960 		hostapd_new_assoc_sta(hapd, sta, 0);
    961 	} else {
    962 		wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR,
    963 			   MAC2STR(addr));
    964 		return -1;
    965 	}
    966 
    967 	return 0;
    968 }
    969 
    970 
    971 static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
    972 				   const u8 *data, size_t data_len)
    973 {
    974 	struct hostapd_iface *iface = hapd->iface;
    975 	struct sta_info *sta;
    976 	size_t j;
    977 
    978 	for (j = 0; j < iface->num_bss; j++) {
    979 		sta = ap_get_sta(iface->bss[j], src);
    980 		if (sta && sta->flags & WLAN_STA_ASSOC) {
    981 			hapd = iface->bss[j];
    982 			break;
    983 		}
    984 	}
    985 
    986 	ieee802_1x_receive(hapd, src, data, data_len);
    987 }
    988 
    989 #endif /* HOSTAPD */
    990 
    991 
    992 static struct hostapd_channel_data * hostapd_get_mode_channel(
    993 	struct hostapd_iface *iface, unsigned int freq)
    994 {
    995 	int i;
    996 	struct hostapd_channel_data *chan;
    997 
    998 	for (i = 0; i < iface->current_mode->num_channels; i++) {
    999 		chan = &iface->current_mode->channels[i];
   1000 		if ((unsigned int) chan->freq == freq)
   1001 			return chan;
   1002 	}
   1003 
   1004 	return NULL;
   1005 }
   1006 
   1007 
   1008 static void hostapd_update_nf(struct hostapd_iface *iface,
   1009 			      struct hostapd_channel_data *chan,
   1010 			      struct freq_survey *survey)
   1011 {
   1012 	if (!iface->chans_surveyed) {
   1013 		chan->min_nf = survey->nf;
   1014 		iface->lowest_nf = survey->nf;
   1015 	} else {
   1016 		if (dl_list_empty(&chan->survey_list))
   1017 			chan->min_nf = survey->nf;
   1018 		else if (survey->nf < chan->min_nf)
   1019 			chan->min_nf = survey->nf;
   1020 		if (survey->nf < iface->lowest_nf)
   1021 			iface->lowest_nf = survey->nf;
   1022 	}
   1023 }
   1024 
   1025 
   1026 static void hostapd_single_channel_get_survey(struct hostapd_iface *iface,
   1027 					      struct survey_results *survey_res)
   1028 {
   1029 	struct hostapd_channel_data *chan;
   1030 	struct freq_survey *survey;
   1031 	u64 divisor, dividend;
   1032 
   1033 	survey = dl_list_first(&survey_res->survey_list, struct freq_survey,
   1034 			       list);
   1035 	if (!survey || !survey->freq)
   1036 		return;
   1037 
   1038 	chan = hostapd_get_mode_channel(iface, survey->freq);
   1039 	if (!chan || chan->flag & HOSTAPD_CHAN_DISABLED)
   1040 		return;
   1041 
   1042 	wpa_printf(MSG_DEBUG,
   1043 		   "Single Channel Survey: (freq=%d channel_time=%ld channel_time_busy=%ld)",
   1044 		   survey->freq,
   1045 		   (unsigned long int) survey->channel_time,
   1046 		   (unsigned long int) survey->channel_time_busy);
   1047 
   1048 	if (survey->channel_time > iface->last_channel_time &&
   1049 	    survey->channel_time > survey->channel_time_busy) {
   1050 		dividend = survey->channel_time_busy -
   1051 			iface->last_channel_time_busy;
   1052 		divisor = survey->channel_time - iface->last_channel_time;
   1053 
   1054 		iface->channel_utilization = dividend * 255 / divisor;
   1055 		wpa_printf(MSG_DEBUG, "Channel Utilization: %d",
   1056 			   iface->channel_utilization);
   1057 	}
   1058 	iface->last_channel_time = survey->channel_time;
   1059 	iface->last_channel_time_busy = survey->channel_time_busy;
   1060 }
   1061 
   1062 
   1063 void hostapd_event_get_survey(struct hostapd_iface *iface,
   1064 			      struct survey_results *survey_results)
   1065 {
   1066 	struct freq_survey *survey, *tmp;
   1067 	struct hostapd_channel_data *chan;
   1068 
   1069 	if (dl_list_empty(&survey_results->survey_list)) {
   1070 		wpa_printf(MSG_DEBUG, "No survey data received");
   1071 		return;
   1072 	}
   1073 
   1074 	if (survey_results->freq_filter) {
   1075 		hostapd_single_channel_get_survey(iface, survey_results);
   1076 		return;
   1077 	}
   1078 
   1079 	dl_list_for_each_safe(survey, tmp, &survey_results->survey_list,
   1080 			      struct freq_survey, list) {
   1081 		chan = hostapd_get_mode_channel(iface, survey->freq);
   1082 		if (!chan)
   1083 			continue;
   1084 		if (chan->flag & HOSTAPD_CHAN_DISABLED)
   1085 			continue;
   1086 
   1087 		dl_list_del(&survey->list);
   1088 		dl_list_add_tail(&chan->survey_list, &survey->list);
   1089 
   1090 		hostapd_update_nf(iface, chan, survey);
   1091 
   1092 		iface->chans_surveyed++;
   1093 	}
   1094 }
   1095 
   1096 
   1097 #ifdef HOSTAPD
   1098 #ifdef NEED_AP_MLME
   1099 
   1100 static void hostapd_event_iface_unavailable(struct hostapd_data *hapd)
   1101 {
   1102 	wpa_printf(MSG_DEBUG, "Interface %s is unavailable -- stopped",
   1103 		   hapd->conf->iface);
   1104 
   1105 	if (hapd->csa_in_progress) {
   1106 		wpa_printf(MSG_INFO, "CSA failed (%s was stopped)",
   1107 			   hapd->conf->iface);
   1108 		hostapd_switch_channel_fallback(hapd->iface,
   1109 						&hapd->cs_freq_params);
   1110 	}
   1111 }
   1112 
   1113 
   1114 static void hostapd_event_dfs_radar_detected(struct hostapd_data *hapd,
   1115 					     struct dfs_event *radar)
   1116 {
   1117 	wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq);
   1118 	hostapd_dfs_radar_detected(hapd->iface, radar->freq, radar->ht_enabled,
   1119 				   radar->chan_offset, radar->chan_width,
   1120 				   radar->cf1, radar->cf2);
   1121 }
   1122 
   1123 
   1124 static void hostapd_event_dfs_cac_finished(struct hostapd_data *hapd,
   1125 					   struct dfs_event *radar)
   1126 {
   1127 	wpa_printf(MSG_DEBUG, "DFS CAC finished on %d MHz", radar->freq);
   1128 	hostapd_dfs_complete_cac(hapd->iface, 1, radar->freq, radar->ht_enabled,
   1129 				 radar->chan_offset, radar->chan_width,
   1130 				 radar->cf1, radar->cf2);
   1131 }
   1132 
   1133 
   1134 static void hostapd_event_dfs_cac_aborted(struct hostapd_data *hapd,
   1135 					  struct dfs_event *radar)
   1136 {
   1137 	wpa_printf(MSG_DEBUG, "DFS CAC aborted on %d MHz", radar->freq);
   1138 	hostapd_dfs_complete_cac(hapd->iface, 0, radar->freq, radar->ht_enabled,
   1139 				 radar->chan_offset, radar->chan_width,
   1140 				 radar->cf1, radar->cf2);
   1141 }
   1142 
   1143 
   1144 static void hostapd_event_dfs_nop_finished(struct hostapd_data *hapd,
   1145 					   struct dfs_event *radar)
   1146 {
   1147 	wpa_printf(MSG_DEBUG, "DFS NOP finished on %d MHz", radar->freq);
   1148 	hostapd_dfs_nop_finished(hapd->iface, radar->freq, radar->ht_enabled,
   1149 				 radar->chan_offset, radar->chan_width,
   1150 				 radar->cf1, radar->cf2);
   1151 }
   1152 
   1153 
   1154 static void hostapd_event_dfs_cac_started(struct hostapd_data *hapd,
   1155 					  struct dfs_event *radar)
   1156 {
   1157 	wpa_printf(MSG_DEBUG, "DFS offload CAC started on %d MHz", radar->freq);
   1158 	hostapd_dfs_start_cac(hapd->iface, radar->freq, radar->ht_enabled,
   1159 			      radar->chan_offset, radar->chan_width,
   1160 			      radar->cf1, radar->cf2);
   1161 }
   1162 
   1163 #endif /* NEED_AP_MLME */
   1164 
   1165 
   1166 void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
   1167 			  union wpa_event_data *data)
   1168 {
   1169 	struct hostapd_data *hapd = ctx;
   1170 #ifndef CONFIG_NO_STDOUT_DEBUG
   1171 	int level = MSG_DEBUG;
   1172 
   1173 	if (event == EVENT_RX_MGMT && data->rx_mgmt.frame &&
   1174 	    data->rx_mgmt.frame_len >= 24) {
   1175 		const struct ieee80211_hdr *hdr;
   1176 		u16 fc;
   1177 
   1178 		hdr = (const struct ieee80211_hdr *) data->rx_mgmt.frame;
   1179 		fc = le_to_host16(hdr->frame_control);
   1180 		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
   1181 		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
   1182 			level = MSG_EXCESSIVE;
   1183 		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
   1184 		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_REQ)
   1185 			level = MSG_EXCESSIVE;
   1186 	}
   1187 
   1188 	wpa_dbg(hapd->msg_ctx, level, "Event %s (%d) received",
   1189 		event_to_string(event), event);
   1190 #endif /* CONFIG_NO_STDOUT_DEBUG */
   1191 
   1192 	switch (event) {
   1193 	case EVENT_MICHAEL_MIC_FAILURE:
   1194 		michael_mic_failure(hapd, data->michael_mic_failure.src, 1);
   1195 		break;
   1196 	case EVENT_SCAN_RESULTS:
   1197 		if (hapd->iface->scan_cb)
   1198 			hapd->iface->scan_cb(hapd->iface);
   1199 		break;
   1200 	case EVENT_WPS_BUTTON_PUSHED:
   1201 		hostapd_wps_button_pushed(hapd, NULL);
   1202 		break;
   1203 #ifdef NEED_AP_MLME
   1204 	case EVENT_TX_STATUS:
   1205 		switch (data->tx_status.type) {
   1206 		case WLAN_FC_TYPE_MGMT:
   1207 			hostapd_mgmt_tx_cb(hapd, data->tx_status.data,
   1208 					   data->tx_status.data_len,
   1209 					   data->tx_status.stype,
   1210 					   data->tx_status.ack);
   1211 			break;
   1212 		case WLAN_FC_TYPE_DATA:
   1213 			hostapd_tx_status(hapd, data->tx_status.dst,
   1214 					  data->tx_status.data,
   1215 					  data->tx_status.data_len,
   1216 					  data->tx_status.ack);
   1217 			break;
   1218 		}
   1219 		break;
   1220 	case EVENT_EAPOL_TX_STATUS:
   1221 		hostapd_eapol_tx_status(hapd, data->eapol_tx_status.dst,
   1222 					data->eapol_tx_status.data,
   1223 					data->eapol_tx_status.data_len,
   1224 					data->eapol_tx_status.ack);
   1225 		break;
   1226 	case EVENT_DRIVER_CLIENT_POLL_OK:
   1227 		hostapd_client_poll_ok(hapd, data->client_poll.addr);
   1228 		break;
   1229 	case EVENT_RX_FROM_UNKNOWN:
   1230 		hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.bssid,
   1231 					    data->rx_from_unknown.addr,
   1232 					    data->rx_from_unknown.wds);
   1233 		break;
   1234 #endif /* NEED_AP_MLME */
   1235 	case EVENT_RX_MGMT:
   1236 		if (!data->rx_mgmt.frame)
   1237 			break;
   1238 #ifdef NEED_AP_MLME
   1239 		if (hostapd_mgmt_rx(hapd, &data->rx_mgmt) > 0)
   1240 			break;
   1241 #endif /* NEED_AP_MLME */
   1242 		hostapd_action_rx(hapd, &data->rx_mgmt);
   1243 		break;
   1244 	case EVENT_RX_PROBE_REQ:
   1245 		if (data->rx_probe_req.sa == NULL ||
   1246 		    data->rx_probe_req.ie == NULL)
   1247 			break;
   1248 		hostapd_probe_req_rx(hapd, data->rx_probe_req.sa,
   1249 				     data->rx_probe_req.da,
   1250 				     data->rx_probe_req.bssid,
   1251 				     data->rx_probe_req.ie,
   1252 				     data->rx_probe_req.ie_len,
   1253 				     data->rx_probe_req.ssi_signal);
   1254 		break;
   1255 	case EVENT_NEW_STA:
   1256 		hostapd_event_new_sta(hapd, data->new_sta.addr);
   1257 		break;
   1258 	case EVENT_EAPOL_RX:
   1259 		hostapd_event_eapol_rx(hapd, data->eapol_rx.src,
   1260 				       data->eapol_rx.data,
   1261 				       data->eapol_rx.data_len);
   1262 		break;
   1263 	case EVENT_ASSOC:
   1264 		if (!data)
   1265 			return;
   1266 		hostapd_notif_assoc(hapd, data->assoc_info.addr,
   1267 				    data->assoc_info.req_ies,
   1268 				    data->assoc_info.req_ies_len,
   1269 				    data->assoc_info.reassoc);
   1270 		break;
   1271 	case EVENT_DISASSOC:
   1272 		if (data)
   1273 			hostapd_notif_disassoc(hapd, data->disassoc_info.addr);
   1274 		break;
   1275 	case EVENT_DEAUTH:
   1276 		if (data)
   1277 			hostapd_notif_disassoc(hapd, data->deauth_info.addr);
   1278 		break;
   1279 	case EVENT_STATION_LOW_ACK:
   1280 		if (!data)
   1281 			break;
   1282 		hostapd_event_sta_low_ack(hapd, data->low_ack.addr);
   1283 		break;
   1284 	case EVENT_AUTH:
   1285 		hostapd_notif_auth(hapd, &data->auth);
   1286 		break;
   1287 	case EVENT_CH_SWITCH:
   1288 		if (!data)
   1289 			break;
   1290 		hostapd_event_ch_switch(hapd, data->ch_switch.freq,
   1291 					data->ch_switch.ht_enabled,
   1292 					data->ch_switch.ch_offset,
   1293 					data->ch_switch.ch_width,
   1294 					data->ch_switch.cf1,
   1295 					data->ch_switch.cf2);
   1296 		break;
   1297 	case EVENT_CONNECT_FAILED_REASON:
   1298 		if (!data)
   1299 			break;
   1300 		hostapd_event_connect_failed_reason(
   1301 			hapd, data->connect_failed_reason.addr,
   1302 			data->connect_failed_reason.code);
   1303 		break;
   1304 	case EVENT_SURVEY:
   1305 		hostapd_event_get_survey(hapd->iface, &data->survey_results);
   1306 		break;
   1307 #ifdef NEED_AP_MLME
   1308 	case EVENT_INTERFACE_UNAVAILABLE:
   1309 		hostapd_event_iface_unavailable(hapd);
   1310 		break;
   1311 	case EVENT_DFS_RADAR_DETECTED:
   1312 		if (!data)
   1313 			break;
   1314 		hostapd_event_dfs_radar_detected(hapd, &data->dfs_event);
   1315 		break;
   1316 	case EVENT_DFS_CAC_FINISHED:
   1317 		if (!data)
   1318 			break;
   1319 		hostapd_event_dfs_cac_finished(hapd, &data->dfs_event);
   1320 		break;
   1321 	case EVENT_DFS_CAC_ABORTED:
   1322 		if (!data)
   1323 			break;
   1324 		hostapd_event_dfs_cac_aborted(hapd, &data->dfs_event);
   1325 		break;
   1326 	case EVENT_DFS_NOP_FINISHED:
   1327 		if (!data)
   1328 			break;
   1329 		hostapd_event_dfs_nop_finished(hapd, &data->dfs_event);
   1330 		break;
   1331 	case EVENT_CHANNEL_LIST_CHANGED:
   1332 		/* channel list changed (regulatory?), update channel list */
   1333 		/* TODO: check this. hostapd_get_hw_features() initializes
   1334 		 * too much stuff. */
   1335 		/* hostapd_get_hw_features(hapd->iface); */
   1336 		hostapd_channel_list_updated(
   1337 			hapd->iface, data->channel_list_changed.initiator);
   1338 		break;
   1339 	case EVENT_DFS_CAC_STARTED:
   1340 		if (!data)
   1341 			break;
   1342 		hostapd_event_dfs_cac_started(hapd, &data->dfs_event);
   1343 		break;
   1344 #endif /* NEED_AP_MLME */
   1345 	case EVENT_INTERFACE_ENABLED:
   1346 		wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_ENABLED);
   1347 		if (hapd->disabled && hapd->started) {
   1348 			hapd->disabled = 0;
   1349 			/*
   1350 			 * Try to re-enable interface if the driver stopped it
   1351 			 * when the interface got disabled.
   1352 			 */
   1353 			wpa_auth_reconfig_group_keys(hapd->wpa_auth);
   1354 			hapd->reenable_beacon = 1;
   1355 			ieee802_11_set_beacon(hapd);
   1356 		}
   1357 		break;
   1358 	case EVENT_INTERFACE_DISABLED:
   1359 		hostapd_free_stas(hapd);
   1360 		wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_DISABLED);
   1361 		hapd->disabled = 1;
   1362 		break;
   1363 #ifdef CONFIG_ACS
   1364 	case EVENT_ACS_CHANNEL_SELECTED:
   1365 		hostapd_acs_channel_selected(hapd,
   1366 					     &data->acs_selected_channels);
   1367 		break;
   1368 #endif /* CONFIG_ACS */
   1369 	default:
   1370 		wpa_printf(MSG_DEBUG, "Unknown event %d", event);
   1371 		break;
   1372 	}
   1373 }
   1374 
   1375 
   1376 void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event,
   1377 				 union wpa_event_data *data)
   1378 {
   1379 	struct hapd_interfaces *interfaces = ctx;
   1380 	struct hostapd_data *hapd;
   1381 
   1382 	if (event != EVENT_INTERFACE_STATUS)
   1383 		return;
   1384 
   1385 	hapd = hostapd_get_iface(interfaces, data->interface_status.ifname);
   1386 	if (hapd && hapd->driver && hapd->driver->get_ifindex &&
   1387 	    hapd->drv_priv) {
   1388 		unsigned int ifindex;
   1389 
   1390 		ifindex = hapd->driver->get_ifindex(hapd->drv_priv);
   1391 		if (ifindex != data->interface_status.ifindex) {
   1392 			wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
   1393 				"interface status ifindex %d mismatch (%d)",
   1394 				ifindex, data->interface_status.ifindex);
   1395 			return;
   1396 		}
   1397 	}
   1398 	if (hapd)
   1399 		wpa_supplicant_event(hapd, event, data);
   1400 }
   1401 
   1402 #endif /* HOSTAPD */
   1403