Home | History | Annotate | Download | only in ap
      1 /*
      2  * hostapd - Driver operations
      3  * Copyright (c) 2009-2010, 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 "common/ieee802_11_defs.h"
     13 #include "common/hw_features_common.h"
     14 #include "wps/wps.h"
     15 #include "p2p/p2p.h"
     16 #include "hostapd.h"
     17 #include "ieee802_11.h"
     18 #include "sta_info.h"
     19 #include "ap_config.h"
     20 #include "p2p_hostapd.h"
     21 #include "hs20.h"
     22 #include "wpa_auth.h"
     23 #include "ap_drv_ops.h"
     24 
     25 
     26 u32 hostapd_sta_flags_to_drv(u32 flags)
     27 {
     28 	int res = 0;
     29 	if (flags & WLAN_STA_AUTHORIZED)
     30 		res |= WPA_STA_AUTHORIZED;
     31 	if (flags & WLAN_STA_WMM)
     32 		res |= WPA_STA_WMM;
     33 	if (flags & WLAN_STA_SHORT_PREAMBLE)
     34 		res |= WPA_STA_SHORT_PREAMBLE;
     35 	if (flags & WLAN_STA_MFP)
     36 		res |= WPA_STA_MFP;
     37 	if (flags & WLAN_STA_AUTH)
     38 		res |= WPA_STA_AUTHENTICATED;
     39 	if (flags & WLAN_STA_ASSOC)
     40 		res |= WPA_STA_ASSOCIATED;
     41 	return res;
     42 }
     43 
     44 
     45 static int add_buf(struct wpabuf **dst, const struct wpabuf *src)
     46 {
     47 	if (!src)
     48 		return 0;
     49 	if (wpabuf_resize(dst, wpabuf_len(src)) != 0)
     50 		return -1;
     51 	wpabuf_put_buf(*dst, src);
     52 	return 0;
     53 }
     54 
     55 
     56 static int add_buf_data(struct wpabuf **dst, const u8 *data, size_t len)
     57 {
     58 	if (!data || !len)
     59 		return 0;
     60 	if (wpabuf_resize(dst, len) != 0)
     61 		return -1;
     62 	wpabuf_put_data(*dst, data, len);
     63 	return 0;
     64 }
     65 
     66 
     67 int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
     68 			       struct wpabuf **beacon_ret,
     69 			       struct wpabuf **proberesp_ret,
     70 			       struct wpabuf **assocresp_ret)
     71 {
     72 	struct wpabuf *beacon = NULL, *proberesp = NULL, *assocresp = NULL;
     73 	u8 buf[200], *pos;
     74 
     75 	*beacon_ret = *proberesp_ret = *assocresp_ret = NULL;
     76 
     77 	pos = buf;
     78 	pos = hostapd_eid_time_adv(hapd, pos);
     79 	if (add_buf_data(&beacon, buf, pos - buf) < 0)
     80 		goto fail;
     81 	pos = hostapd_eid_time_zone(hapd, pos);
     82 	if (add_buf_data(&proberesp, buf, pos - buf) < 0)
     83 		goto fail;
     84 
     85 	pos = buf;
     86 	pos = hostapd_eid_ext_capab(hapd, pos);
     87 	if (add_buf_data(&assocresp, buf, pos - buf) < 0)
     88 		goto fail;
     89 	pos = hostapd_eid_interworking(hapd, pos);
     90 	pos = hostapd_eid_adv_proto(hapd, pos);
     91 	pos = hostapd_eid_roaming_consortium(hapd, pos);
     92 	if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
     93 	    add_buf_data(&proberesp, buf, pos - buf) < 0)
     94 		goto fail;
     95 
     96 #ifdef CONFIG_FST
     97 	if (add_buf(&beacon, hapd->iface->fst_ies) < 0 ||
     98 	    add_buf(&proberesp, hapd->iface->fst_ies) < 0 ||
     99 	    add_buf(&assocresp, hapd->iface->fst_ies) < 0)
    100 		goto fail;
    101 #endif /* CONFIG_FST */
    102 
    103 #ifdef CONFIG_FILS
    104 	pos = hostapd_eid_fils_indic(hapd, buf, 0);
    105 	if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
    106 	    add_buf_data(&proberesp, buf, pos - buf) < 0)
    107 		goto fail;
    108 #endif /* CONFIG_FILS */
    109 
    110 	if (add_buf(&beacon, hapd->wps_beacon_ie) < 0 ||
    111 	    add_buf(&proberesp, hapd->wps_probe_resp_ie) < 0)
    112 		goto fail;
    113 
    114 #ifdef CONFIG_P2P
    115 	if (add_buf(&beacon, hapd->p2p_beacon_ie) < 0 ||
    116 	    add_buf(&proberesp, hapd->p2p_probe_resp_ie) < 0)
    117 		goto fail;
    118 #endif /* CONFIG_P2P */
    119 
    120 #ifdef CONFIG_P2P_MANAGER
    121 	if (hapd->conf->p2p & P2P_MANAGE) {
    122 		if (wpabuf_resize(&beacon, 100) == 0) {
    123 			u8 *start, *p;
    124 			start = wpabuf_put(beacon, 0);
    125 			p = hostapd_eid_p2p_manage(hapd, start);
    126 			wpabuf_put(beacon, p - start);
    127 		}
    128 
    129 		if (wpabuf_resize(&proberesp, 100) == 0) {
    130 			u8 *start, *p;
    131 			start = wpabuf_put(proberesp, 0);
    132 			p = hostapd_eid_p2p_manage(hapd, start);
    133 			wpabuf_put(proberesp, p - start);
    134 		}
    135 	}
    136 #endif /* CONFIG_P2P_MANAGER */
    137 
    138 #ifdef CONFIG_WPS
    139 	if (hapd->conf->wps_state) {
    140 		struct wpabuf *a = wps_build_assoc_resp_ie();
    141 		add_buf(&assocresp, a);
    142 		wpabuf_free(a);
    143 	}
    144 #endif /* CONFIG_WPS */
    145 
    146 #ifdef CONFIG_P2P_MANAGER
    147 	if (hapd->conf->p2p & P2P_MANAGE) {
    148 		if (wpabuf_resize(&assocresp, 100) == 0) {
    149 			u8 *start, *p;
    150 			start = wpabuf_put(assocresp, 0);
    151 			p = hostapd_eid_p2p_manage(hapd, start);
    152 			wpabuf_put(assocresp, p - start);
    153 		}
    154 	}
    155 #endif /* CONFIG_P2P_MANAGER */
    156 
    157 #ifdef CONFIG_WIFI_DISPLAY
    158 	if (hapd->p2p_group) {
    159 		struct wpabuf *a;
    160 		a = p2p_group_assoc_resp_ie(hapd->p2p_group, P2P_SC_SUCCESS);
    161 		add_buf(&assocresp, a);
    162 		wpabuf_free(a);
    163 	}
    164 #endif /* CONFIG_WIFI_DISPLAY */
    165 
    166 #ifdef CONFIG_HS20
    167 	pos = hostapd_eid_hs20_indication(hapd, buf);
    168 	if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
    169 	    add_buf_data(&proberesp, buf, pos - buf) < 0)
    170 		goto fail;
    171 
    172 	pos = hostapd_eid_osen(hapd, buf);
    173 	if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
    174 	    add_buf_data(&proberesp, buf, pos - buf) < 0)
    175 		goto fail;
    176 #endif /* CONFIG_HS20 */
    177 
    178 #ifdef CONFIG_MBO
    179 	if (hapd->conf->mbo_enabled || hapd->enable_oce) {
    180 		pos = hostapd_eid_mbo(hapd, buf, sizeof(buf));
    181 		if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
    182 		    add_buf_data(&proberesp, buf, pos - buf) < 0 ||
    183 		    add_buf_data(&assocresp, buf, pos - buf) < 0)
    184 			goto fail;
    185 	}
    186 #endif /* CONFIG_MBO */
    187 
    188 	add_buf(&beacon, hapd->conf->vendor_elements);
    189 	add_buf(&proberesp, hapd->conf->vendor_elements);
    190 	add_buf(&assocresp, hapd->conf->assocresp_elements);
    191 
    192 	*beacon_ret = beacon;
    193 	*proberesp_ret = proberesp;
    194 	*assocresp_ret = assocresp;
    195 
    196 	return 0;
    197 
    198 fail:
    199 	wpabuf_free(beacon);
    200 	wpabuf_free(proberesp);
    201 	wpabuf_free(assocresp);
    202 	return -1;
    203 }
    204 
    205 
    206 void hostapd_free_ap_extra_ies(struct hostapd_data *hapd,
    207 			       struct wpabuf *beacon,
    208 			       struct wpabuf *proberesp,
    209 			       struct wpabuf *assocresp)
    210 {
    211 	wpabuf_free(beacon);
    212 	wpabuf_free(proberesp);
    213 	wpabuf_free(assocresp);
    214 }
    215 
    216 
    217 int hostapd_reset_ap_wps_ie(struct hostapd_data *hapd)
    218 {
    219 	if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
    220 		return 0;
    221 
    222 	return hapd->driver->set_ap_wps_ie(hapd->drv_priv, NULL, NULL, NULL);
    223 }
    224 
    225 
    226 int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
    227 {
    228 	struct wpabuf *beacon, *proberesp, *assocresp;
    229 	int ret;
    230 
    231 	if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
    232 		return 0;
    233 
    234 	if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) <
    235 	    0)
    236 		return -1;
    237 
    238 	ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp,
    239 					  assocresp);
    240 
    241 	hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
    242 
    243 	return ret;
    244 }
    245 
    246 
    247 int hostapd_set_authorized(struct hostapd_data *hapd,
    248 			   struct sta_info *sta, int authorized)
    249 {
    250 	if (authorized) {
    251 		return hostapd_sta_set_flags(hapd, sta->addr,
    252 					     hostapd_sta_flags_to_drv(
    253 						     sta->flags),
    254 					     WPA_STA_AUTHORIZED, ~0);
    255 	}
    256 
    257 	return hostapd_sta_set_flags(hapd, sta->addr,
    258 				     hostapd_sta_flags_to_drv(sta->flags),
    259 				     0, ~WPA_STA_AUTHORIZED);
    260 }
    261 
    262 
    263 int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta)
    264 {
    265 	int set_flags, total_flags, flags_and, flags_or;
    266 	total_flags = hostapd_sta_flags_to_drv(sta->flags);
    267 	set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP;
    268 	if (((!hapd->conf->ieee802_1x && !hapd->conf->wpa) ||
    269 	     sta->auth_alg == WLAN_AUTH_FT) &&
    270 	    sta->flags & WLAN_STA_AUTHORIZED)
    271 		set_flags |= WPA_STA_AUTHORIZED;
    272 	flags_or = total_flags & set_flags;
    273 	flags_and = total_flags | ~set_flags;
    274 	return hostapd_sta_set_flags(hapd, sta->addr, total_flags,
    275 				     flags_or, flags_and);
    276 }
    277 
    278 
    279 int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
    280 			      int enabled)
    281 {
    282 	struct wpa_bss_params params;
    283 	os_memset(&params, 0, sizeof(params));
    284 	params.ifname = ifname;
    285 	params.enabled = enabled;
    286 	if (enabled) {
    287 		params.wpa = hapd->conf->wpa;
    288 		params.ieee802_1x = hapd->conf->ieee802_1x;
    289 		params.wpa_group = hapd->conf->wpa_group;
    290 		if ((hapd->conf->wpa & (WPA_PROTO_WPA | WPA_PROTO_RSN)) ==
    291 		    (WPA_PROTO_WPA | WPA_PROTO_RSN))
    292 			params.wpa_pairwise = hapd->conf->wpa_pairwise |
    293 				hapd->conf->rsn_pairwise;
    294 		else if (hapd->conf->wpa & WPA_PROTO_RSN)
    295 			params.wpa_pairwise = hapd->conf->rsn_pairwise;
    296 		else if (hapd->conf->wpa & WPA_PROTO_WPA)
    297 			params.wpa_pairwise = hapd->conf->wpa_pairwise;
    298 		params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt;
    299 		params.rsn_preauth = hapd->conf->rsn_preauth;
    300 #ifdef CONFIG_IEEE80211W
    301 		params.ieee80211w = hapd->conf->ieee80211w;
    302 #endif /* CONFIG_IEEE80211W */
    303 	}
    304 	return hostapd_set_ieee8021x(hapd, &params);
    305 }
    306 
    307 
    308 int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname)
    309 {
    310 	char force_ifname[IFNAMSIZ];
    311 	u8 if_addr[ETH_ALEN];
    312 	return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, hapd->own_addr,
    313 			      NULL, NULL, force_ifname, if_addr, NULL, 0);
    314 }
    315 
    316 
    317 int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname)
    318 {
    319 	return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname);
    320 }
    321 
    322 
    323 int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds,
    324 			const u8 *addr, int aid, int val)
    325 {
    326 	const char *bridge = NULL;
    327 
    328 	if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL)
    329 		return -1;
    330 	if (hapd->conf->wds_bridge[0])
    331 		bridge = hapd->conf->wds_bridge;
    332 	else if (hapd->conf->bridge[0])
    333 		bridge = hapd->conf->bridge;
    334 	return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
    335 					 bridge, ifname_wds);
    336 }
    337 
    338 
    339 int hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr,
    340 			 u16 auth_alg)
    341 {
    342 	if (hapd->driver == NULL || hapd->driver->add_sta_node == NULL)
    343 		return 0;
    344 	return hapd->driver->add_sta_node(hapd->drv_priv, addr, auth_alg);
    345 }
    346 
    347 
    348 int hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr,
    349 		     u16 seq, u16 status, const u8 *ie, size_t len)
    350 {
    351 	struct wpa_driver_sta_auth_params params;
    352 #ifdef CONFIG_FILS
    353 	struct sta_info *sta;
    354 #endif /* CONFIG_FILS */
    355 
    356 	if (hapd->driver == NULL || hapd->driver->sta_auth == NULL)
    357 		return 0;
    358 
    359 	os_memset(&params, 0, sizeof(params));
    360 
    361 #ifdef CONFIG_FILS
    362 	sta = ap_get_sta(hapd, addr);
    363 	if (!sta) {
    364 		wpa_printf(MSG_DEBUG, "Station " MACSTR
    365 			   " not found for sta_auth processing",
    366 			   MAC2STR(addr));
    367 		return 0;
    368 	}
    369 
    370 	if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
    371 	    sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
    372 	    sta->auth_alg == WLAN_AUTH_FILS_PK) {
    373 		params.fils_auth = 1;
    374 		wpa_auth_get_fils_aead_params(sta->wpa_sm, params.fils_anonce,
    375 					      params.fils_snonce,
    376 					      params.fils_kek,
    377 					      &params.fils_kek_len);
    378 	}
    379 #endif /* CONFIG_FILS */
    380 
    381 	params.own_addr = hapd->own_addr;
    382 	params.addr = addr;
    383 	params.seq = seq;
    384 	params.status = status;
    385 	params.ie = ie;
    386 	params.len = len;
    387 
    388 	return hapd->driver->sta_auth(hapd->drv_priv, &params);
    389 }
    390 
    391 
    392 int hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr,
    393 		      int reassoc, u16 status, const u8 *ie, size_t len)
    394 {
    395 	if (hapd->driver == NULL || hapd->driver->sta_assoc == NULL)
    396 		return 0;
    397 	return hapd->driver->sta_assoc(hapd->drv_priv, hapd->own_addr, addr,
    398 				       reassoc, status, ie, len);
    399 }
    400 
    401 
    402 int hostapd_sta_add(struct hostapd_data *hapd,
    403 		    const u8 *addr, u16 aid, u16 capability,
    404 		    const u8 *supp_rates, size_t supp_rates_len,
    405 		    u16 listen_interval,
    406 		    const struct ieee80211_ht_capabilities *ht_capab,
    407 		    const struct ieee80211_vht_capabilities *vht_capab,
    408 		    u32 flags, u8 qosinfo, u8 vht_opmode, int supp_p2p_ps,
    409 		    int set)
    410 {
    411 	struct hostapd_sta_add_params params;
    412 
    413 	if (hapd->driver == NULL)
    414 		return 0;
    415 	if (hapd->driver->sta_add == NULL)
    416 		return 0;
    417 
    418 	os_memset(&params, 0, sizeof(params));
    419 	params.addr = addr;
    420 	params.aid = aid;
    421 	params.capability = capability;
    422 	params.supp_rates = supp_rates;
    423 	params.supp_rates_len = supp_rates_len;
    424 	params.listen_interval = listen_interval;
    425 	params.ht_capabilities = ht_capab;
    426 	params.vht_capabilities = vht_capab;
    427 	params.vht_opmode_enabled = !!(flags & WLAN_STA_VHT_OPMODE_ENABLED);
    428 	params.vht_opmode = vht_opmode;
    429 	params.flags = hostapd_sta_flags_to_drv(flags);
    430 	params.qosinfo = qosinfo;
    431 	params.support_p2p_ps = supp_p2p_ps;
    432 	params.set = set;
    433 	return hapd->driver->sta_add(hapd->drv_priv, &params);
    434 }
    435 
    436 
    437 int hostapd_add_tspec(struct hostapd_data *hapd, const u8 *addr,
    438 		      u8 *tspec_ie, size_t tspec_ielen)
    439 {
    440 	if (hapd->driver == NULL || hapd->driver->add_tspec == NULL)
    441 		return 0;
    442 	return hapd->driver->add_tspec(hapd->drv_priv, addr, tspec_ie,
    443 				       tspec_ielen);
    444 }
    445 
    446 
    447 int hostapd_set_privacy(struct hostapd_data *hapd, int enabled)
    448 {
    449 	if (hapd->driver == NULL || hapd->driver->set_privacy == NULL)
    450 		return 0;
    451 	return hapd->driver->set_privacy(hapd->drv_priv, enabled);
    452 }
    453 
    454 
    455 int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem,
    456 			     size_t elem_len)
    457 {
    458 	if (hapd->driver == NULL || hapd->driver->set_generic_elem == NULL)
    459 		return 0;
    460 	return hapd->driver->set_generic_elem(hapd->drv_priv, elem, elem_len);
    461 }
    462 
    463 
    464 int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len)
    465 {
    466 	if (hapd->driver == NULL || hapd->driver->hapd_get_ssid == NULL)
    467 		return 0;
    468 	return hapd->driver->hapd_get_ssid(hapd->drv_priv, buf, len);
    469 }
    470 
    471 
    472 int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len)
    473 {
    474 	if (hapd->driver == NULL || hapd->driver->hapd_set_ssid == NULL)
    475 		return 0;
    476 	return hapd->driver->hapd_set_ssid(hapd->drv_priv, buf, len);
    477 }
    478 
    479 
    480 int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
    481 		   const char *ifname, const u8 *addr, void *bss_ctx,
    482 		   void **drv_priv, char *force_ifname, u8 *if_addr,
    483 		   const char *bridge, int use_existing)
    484 {
    485 	if (hapd->driver == NULL || hapd->driver->if_add == NULL)
    486 		return -1;
    487 	return hapd->driver->if_add(hapd->drv_priv, type, ifname, addr,
    488 				    bss_ctx, drv_priv, force_ifname, if_addr,
    489 				    bridge, use_existing, 1);
    490 }
    491 
    492 
    493 int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
    494 		      const char *ifname)
    495 {
    496 	if (hapd->driver == NULL || hapd->drv_priv == NULL ||
    497 	    hapd->driver->if_remove == NULL)
    498 		return -1;
    499 	return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
    500 }
    501 
    502 
    503 int hostapd_set_ieee8021x(struct hostapd_data *hapd,
    504 			  struct wpa_bss_params *params)
    505 {
    506 	if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL)
    507 		return 0;
    508 	return hapd->driver->set_ieee8021x(hapd->drv_priv, params);
    509 }
    510 
    511 
    512 int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
    513 		       const u8 *addr, int idx, u8 *seq)
    514 {
    515 	if (hapd->driver == NULL || hapd->driver->get_seqnum == NULL)
    516 		return 0;
    517 	return hapd->driver->get_seqnum(ifname, hapd->drv_priv, addr, idx,
    518 					seq);
    519 }
    520 
    521 
    522 int hostapd_flush(struct hostapd_data *hapd)
    523 {
    524 	if (hapd->driver == NULL || hapd->driver->flush == NULL)
    525 		return 0;
    526 	return hapd->driver->flush(hapd->drv_priv);
    527 }
    528 
    529 
    530 int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode,
    531 		     int freq, int channel, int ht_enabled, int vht_enabled,
    532 		     int sec_channel_offset, int vht_oper_chwidth,
    533 		     int center_segment0, int center_segment1)
    534 {
    535 	struct hostapd_freq_params data;
    536 
    537 	if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
    538 				    vht_enabled, sec_channel_offset,
    539 				    vht_oper_chwidth,
    540 				    center_segment0, center_segment1,
    541 				    hapd->iface->current_mode ?
    542 				    hapd->iface->current_mode->vht_capab : 0))
    543 		return -1;
    544 
    545 	if (hapd->driver == NULL)
    546 		return 0;
    547 	if (hapd->driver->set_freq == NULL)
    548 		return 0;
    549 	return hapd->driver->set_freq(hapd->drv_priv, &data);
    550 }
    551 
    552 int hostapd_set_rts(struct hostapd_data *hapd, int rts)
    553 {
    554 	if (hapd->driver == NULL || hapd->driver->set_rts == NULL)
    555 		return 0;
    556 	return hapd->driver->set_rts(hapd->drv_priv, rts);
    557 }
    558 
    559 
    560 int hostapd_set_frag(struct hostapd_data *hapd, int frag)
    561 {
    562 	if (hapd->driver == NULL || hapd->driver->set_frag == NULL)
    563 		return 0;
    564 	return hapd->driver->set_frag(hapd->drv_priv, frag);
    565 }
    566 
    567 
    568 int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
    569 			  int total_flags, int flags_or, int flags_and)
    570 {
    571 	if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL)
    572 		return 0;
    573 	return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags,
    574 					   flags_or, flags_and);
    575 }
    576 
    577 
    578 int hostapd_set_country(struct hostapd_data *hapd, const char *country)
    579 {
    580 	if (hapd->driver == NULL ||
    581 	    hapd->driver->set_country == NULL)
    582 		return 0;
    583 	return hapd->driver->set_country(hapd->drv_priv, country);
    584 }
    585 
    586 
    587 int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
    588 				int cw_min, int cw_max, int burst_time)
    589 {
    590 	if (hapd->driver == NULL || hapd->driver->set_tx_queue_params == NULL)
    591 		return 0;
    592 	return hapd->driver->set_tx_queue_params(hapd->drv_priv, queue, aifs,
    593 						 cw_min, cw_max, burst_time);
    594 }
    595 
    596 
    597 struct hostapd_hw_modes *
    598 hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
    599 			    u16 *flags, u8 *dfs_domain)
    600 {
    601 	if (hapd->driver == NULL ||
    602 	    hapd->driver->get_hw_feature_data == NULL)
    603 		return NULL;
    604 	return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
    605 						 flags, dfs_domain);
    606 }
    607 
    608 
    609 int hostapd_driver_commit(struct hostapd_data *hapd)
    610 {
    611 	if (hapd->driver == NULL || hapd->driver->commit == NULL)
    612 		return 0;
    613 	return hapd->driver->commit(hapd->drv_priv);
    614 }
    615 
    616 
    617 int hostapd_drv_none(struct hostapd_data *hapd)
    618 {
    619 	return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0;
    620 }
    621 
    622 
    623 int hostapd_driver_scan(struct hostapd_data *hapd,
    624 			struct wpa_driver_scan_params *params)
    625 {
    626 	if (hapd->driver && hapd->driver->scan2)
    627 		return hapd->driver->scan2(hapd->drv_priv, params);
    628 	return -1;
    629 }
    630 
    631 
    632 struct wpa_scan_results * hostapd_driver_get_scan_results(
    633 	struct hostapd_data *hapd)
    634 {
    635 	if (hapd->driver && hapd->driver->get_scan_results2)
    636 		return hapd->driver->get_scan_results2(hapd->drv_priv);
    637 	return NULL;
    638 }
    639 
    640 
    641 int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
    642 			   int duration)
    643 {
    644 	if (hapd->driver && hapd->driver->set_noa)
    645 		return hapd->driver->set_noa(hapd->drv_priv, count, start,
    646 					     duration);
    647 	return -1;
    648 }
    649 
    650 
    651 int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
    652 			enum wpa_alg alg, const u8 *addr,
    653 			int key_idx, int set_tx,
    654 			const u8 *seq, size_t seq_len,
    655 			const u8 *key, size_t key_len)
    656 {
    657 	if (hapd->driver == NULL || hapd->driver->set_key == NULL)
    658 		return 0;
    659 	return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr,
    660 				     key_idx, set_tx, seq, seq_len, key,
    661 				     key_len);
    662 }
    663 
    664 
    665 int hostapd_drv_send_mlme(struct hostapd_data *hapd,
    666 			  const void *msg, size_t len, int noack)
    667 {
    668 	if (!hapd->driver || !hapd->driver->send_mlme || !hapd->drv_priv)
    669 		return 0;
    670 	return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0,
    671 				       NULL, 0);
    672 }
    673 
    674 
    675 int hostapd_drv_send_mlme_csa(struct hostapd_data *hapd,
    676 			      const void *msg, size_t len, int noack,
    677 			      const u16 *csa_offs, size_t csa_offs_len)
    678 {
    679 	if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
    680 		return 0;
    681 	return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0,
    682 				       csa_offs, csa_offs_len);
    683 }
    684 
    685 
    686 int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
    687 			   const u8 *addr, int reason)
    688 {
    689 	if (!hapd->driver || !hapd->driver->sta_deauth || !hapd->drv_priv)
    690 		return 0;
    691 	return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr,
    692 					reason);
    693 }
    694 
    695 
    696 int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
    697 			     const u8 *addr, int reason)
    698 {
    699 	if (!hapd->driver || !hapd->driver->sta_disassoc || !hapd->drv_priv)
    700 		return 0;
    701 	return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr,
    702 					  reason);
    703 }
    704 
    705 
    706 int hostapd_drv_wnm_oper(struct hostapd_data *hapd, enum wnm_oper oper,
    707 			 const u8 *peer, u8 *buf, u16 *buf_len)
    708 {
    709 	if (hapd->driver == NULL || hapd->driver->wnm_oper == NULL)
    710 		return -1;
    711 	return hapd->driver->wnm_oper(hapd->drv_priv, oper, peer, buf,
    712 				      buf_len);
    713 }
    714 
    715 
    716 int hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
    717 			    unsigned int wait, const u8 *dst, const u8 *data,
    718 			    size_t len)
    719 {
    720 	const u8 *bssid;
    721 	const u8 wildcard_bssid[ETH_ALEN] = {
    722 		0xff, 0xff, 0xff, 0xff, 0xff, 0xff
    723 	};
    724 
    725 	if (!hapd->driver || !hapd->driver->send_action || !hapd->drv_priv)
    726 		return 0;
    727 	bssid = hapd->own_addr;
    728 	if (!is_multicast_ether_addr(dst) &&
    729 	    len > 0 && data[0] == WLAN_ACTION_PUBLIC) {
    730 		struct sta_info *sta;
    731 
    732 		/*
    733 		 * Public Action frames to a STA that is not a member of the BSS
    734 		 * shall use wildcard BSSID value.
    735 		 */
    736 		sta = ap_get_sta(hapd, dst);
    737 		if (!sta || !(sta->flags & WLAN_STA_ASSOC))
    738 			bssid = wildcard_bssid;
    739 	}
    740 	return hapd->driver->send_action(hapd->drv_priv, freq, wait, dst,
    741 					 hapd->own_addr, bssid, data, len, 0);
    742 }
    743 
    744 
    745 int hostapd_drv_send_action_addr3_ap(struct hostapd_data *hapd,
    746 				     unsigned int freq,
    747 				     unsigned int wait, const u8 *dst,
    748 				     const u8 *data, size_t len)
    749 {
    750 	if (hapd->driver == NULL || hapd->driver->send_action == NULL)
    751 		return 0;
    752 	return hapd->driver->send_action(hapd->drv_priv, freq, wait, dst,
    753 					 hapd->own_addr, hapd->own_addr, data,
    754 					 len, 0);
    755 }
    756 
    757 
    758 int hostapd_start_dfs_cac(struct hostapd_iface *iface,
    759 			  enum hostapd_hw_mode mode, int freq,
    760 			  int channel, int ht_enabled, int vht_enabled,
    761 			  int sec_channel_offset, int vht_oper_chwidth,
    762 			  int center_segment0, int center_segment1)
    763 {
    764 	struct hostapd_data *hapd = iface->bss[0];
    765 	struct hostapd_freq_params data;
    766 	int res;
    767 
    768 	if (!hapd->driver || !hapd->driver->start_dfs_cac)
    769 		return 0;
    770 
    771 	if (!iface->conf->ieee80211h) {
    772 		wpa_printf(MSG_ERROR, "Can't start DFS CAC, DFS functionality "
    773 			   "is not enabled");
    774 		return -1;
    775 	}
    776 
    777 	if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
    778 				    vht_enabled, sec_channel_offset,
    779 				    vht_oper_chwidth, center_segment0,
    780 				    center_segment1,
    781 				    iface->current_mode->vht_capab)) {
    782 		wpa_printf(MSG_ERROR, "Can't set freq params");
    783 		return -1;
    784 	}
    785 
    786 	res = hapd->driver->start_dfs_cac(hapd->drv_priv, &data);
    787 	if (!res) {
    788 		iface->cac_started = 1;
    789 		os_get_reltime(&iface->dfs_cac_start);
    790 	}
    791 
    792 	return res;
    793 }
    794 
    795 
    796 int hostapd_drv_set_qos_map(struct hostapd_data *hapd,
    797 			    const u8 *qos_map_set, u8 qos_map_set_len)
    798 {
    799 	if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv)
    800 		return 0;
    801 	return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set,
    802 					 qos_map_set_len);
    803 }
    804 
    805 
    806 static void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd,
    807 					     struct hostapd_hw_modes *mode,
    808 					     int acs_ch_list_all,
    809 					     int **freq_list)
    810 {
    811 	int i;
    812 
    813 	for (i = 0; i < mode->num_channels; i++) {
    814 		struct hostapd_channel_data *chan = &mode->channels[i];
    815 
    816 		if ((acs_ch_list_all ||
    817 		     freq_range_list_includes(&hapd->iface->conf->acs_ch_list,
    818 					      chan->chan)) &&
    819 		    !(chan->flag & HOSTAPD_CHAN_DISABLED) &&
    820 		    !(hapd->iface->conf->acs_exclude_dfs &&
    821 		      (chan->flag & HOSTAPD_CHAN_RADAR)))
    822 			int_array_add_unique(freq_list, chan->freq);
    823 	}
    824 }
    825 
    826 
    827 void hostapd_get_ext_capa(struct hostapd_iface *iface)
    828 {
    829 	struct hostapd_data *hapd = iface->bss[0];
    830 
    831 	if (!hapd->driver || !hapd->driver->get_ext_capab)
    832 		return;
    833 
    834 	hapd->driver->get_ext_capab(hapd->drv_priv, WPA_IF_AP_BSS,
    835 				    &iface->extended_capa,
    836 				    &iface->extended_capa_mask,
    837 				    &iface->extended_capa_len);
    838 }
    839 
    840 
    841 int hostapd_drv_do_acs(struct hostapd_data *hapd)
    842 {
    843 	struct drv_acs_params params;
    844 	int ret, i, acs_ch_list_all = 0;
    845 	u8 *channels = NULL;
    846 	unsigned int num_channels = 0;
    847 	struct hostapd_hw_modes *mode;
    848 	int *freq_list = NULL;
    849 
    850 	if (hapd->driver == NULL || hapd->driver->do_acs == NULL)
    851 		return 0;
    852 
    853 	os_memset(&params, 0, sizeof(params));
    854 	params.hw_mode = hapd->iface->conf->hw_mode;
    855 
    856 	/*
    857 	 * If no chanlist config parameter is provided, include all enabled
    858 	 * channels of the selected hw_mode.
    859 	 */
    860 	if (!hapd->iface->conf->acs_ch_list.num)
    861 		acs_ch_list_all = 1;
    862 
    863 	mode = hapd->iface->current_mode;
    864 	if (mode) {
    865 		channels = os_malloc(mode->num_channels);
    866 		if (channels == NULL)
    867 			return -1;
    868 
    869 		for (i = 0; i < mode->num_channels; i++) {
    870 			struct hostapd_channel_data *chan = &mode->channels[i];
    871 			if (!acs_ch_list_all &&
    872 			    !freq_range_list_includes(
    873 				    &hapd->iface->conf->acs_ch_list,
    874 				    chan->chan))
    875 				continue;
    876 			if (hapd->iface->conf->acs_exclude_dfs &&
    877 			    (chan->flag & HOSTAPD_CHAN_RADAR))
    878 				continue;
    879 			if (!(chan->flag & HOSTAPD_CHAN_DISABLED)) {
    880 				channels[num_channels++] = chan->chan;
    881 				int_array_add_unique(&freq_list, chan->freq);
    882 			}
    883 		}
    884 	} else {
    885 		for (i = 0; i < hapd->iface->num_hw_features; i++) {
    886 			mode = &hapd->iface->hw_features[i];
    887 			hostapd_get_hw_mode_any_channels(hapd, mode,
    888 							 acs_ch_list_all,
    889 							 &freq_list);
    890 		}
    891 	}
    892 
    893 	params.ch_list = channels;
    894 	params.ch_list_len = num_channels;
    895 	params.freq_list = freq_list;
    896 
    897 	params.ht_enabled = !!(hapd->iface->conf->ieee80211n);
    898 	params.ht40_enabled = !!(hapd->iface->conf->ht_capab &
    899 				 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET);
    900 	params.vht_enabled = !!(hapd->iface->conf->ieee80211ac);
    901 	params.ch_width = 20;
    902 	if (hapd->iface->conf->ieee80211n && params.ht40_enabled)
    903 		params.ch_width = 40;
    904 
    905 	/* Note: VHT20 is defined by combination of ht_capab & vht_oper_chwidth
    906 	 */
    907 	if (hapd->iface->conf->ieee80211ac && params.ht40_enabled) {
    908 		if (hapd->iface->conf->vht_oper_chwidth == VHT_CHANWIDTH_80MHZ)
    909 			params.ch_width = 80;
    910 		else if (hapd->iface->conf->vht_oper_chwidth ==
    911 			 VHT_CHANWIDTH_160MHZ ||
    912 			 hapd->iface->conf->vht_oper_chwidth ==
    913 			 VHT_CHANWIDTH_80P80MHZ)
    914 			params.ch_width = 160;
    915 	}
    916 
    917 	ret = hapd->driver->do_acs(hapd->drv_priv, &params);
    918 	os_free(channels);
    919 
    920 	return ret;
    921 }
    922