1 /*
2 * hostapd - Driver operations
3 * Copyright (c) 2009-2010, Jouni Malinen <j@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/ieee802_11_common.h"
14 #include "common/hw_features_common.h"
15 #include "wps/wps.h"
16 #include "p2p/p2p.h"
17 #include "hostapd.h"
18 #include "ieee802_11.h"
19 #include "sta_info.h"
20 #include "ap_config.h"
21 #include "p2p_hostapd.h"
22 #include "hs20.h"
23 #include "wpa_auth.h"
24 #include "ap_drv_ops.h"
25 #ifdef CONFIG_VENDOR_EXT
26 #include "vendor_ext.h"
27 #endif
28 #ifdef CONFIG_P2P_CHR
29 #include "wpa_hw_p2p_chr.h"
30 #endif
31
hostapd_sta_flags_to_drv(u32 flags)32 u32 hostapd_sta_flags_to_drv(u32 flags)
33 {
34 int res = 0;
35 if (flags & WLAN_STA_AUTHORIZED)
36 res |= WPA_STA_AUTHORIZED;
37 if (flags & WLAN_STA_WMM)
38 res |= WPA_STA_WMM;
39 if (flags & WLAN_STA_SHORT_PREAMBLE)
40 res |= WPA_STA_SHORT_PREAMBLE;
41 if (flags & WLAN_STA_MFP)
42 res |= WPA_STA_MFP;
43 if (flags & WLAN_STA_AUTH)
44 res |= WPA_STA_AUTHENTICATED;
45 if (flags & WLAN_STA_ASSOC)
46 res |= WPA_STA_ASSOCIATED;
47 return res;
48 }
49
50
add_buf(struct wpabuf ** dst,const struct wpabuf * src)51 static int add_buf(struct wpabuf **dst, const struct wpabuf *src)
52 {
53 if (!src)
54 return 0;
55 if (wpabuf_resize(dst, wpabuf_len(src)) != 0)
56 return -1;
57 wpabuf_put_buf(*dst, src);
58 return 0;
59 }
60
61
add_buf_data(struct wpabuf ** dst,const u8 * data,size_t len)62 int add_buf_data(struct wpabuf **dst, const u8 *data, size_t len)
63 {
64 if (!data || !len)
65 return 0;
66 if (wpabuf_resize(dst, len) != 0)
67 return -1;
68 wpabuf_put_data(*dst, data, len);
69 return 0;
70 }
71
72
hostapd_build_ap_extra_ies(struct hostapd_data * hapd,struct wpabuf ** beacon_ret,struct wpabuf ** proberesp_ret,struct wpabuf ** assocresp_ret)73 int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
74 struct wpabuf **beacon_ret,
75 struct wpabuf **proberesp_ret,
76 struct wpabuf **assocresp_ret)
77 {
78 struct wpabuf *beacon = NULL, *proberesp = NULL, *assocresp = NULL;
79 u8 buf[200], *pos;
80
81 *beacon_ret = *proberesp_ret = *assocresp_ret = NULL;
82
83 #ifdef NEED_AP_MLME
84 pos = buf;
85 pos = hostapd_eid_rm_enabled_capab(hapd, pos, sizeof(buf));
86 if (add_buf_data(&assocresp, buf, pos - buf) < 0 ||
87 add_buf_data(&proberesp, buf, pos - buf) < 0)
88 goto fail;
89 #endif /* NEED_AP_MLME */
90
91 pos = buf;
92 pos = hostapd_eid_time_adv(hapd, pos);
93 if (add_buf_data(&beacon, buf, pos - buf) < 0)
94 goto fail;
95 pos = hostapd_eid_time_zone(hapd, pos);
96 if (add_buf_data(&proberesp, buf, pos - buf) < 0)
97 goto fail;
98
99 pos = buf;
100 pos = hostapd_eid_ext_capab(hapd, pos, false);
101 if (add_buf_data(&assocresp, buf, pos - buf) < 0)
102 goto fail;
103 pos = hostapd_eid_interworking(hapd, pos);
104 pos = hostapd_eid_adv_proto(hapd, pos);
105 pos = hostapd_eid_roaming_consortium(hapd, pos);
106 if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
107 add_buf_data(&proberesp, buf, pos - buf) < 0)
108 goto fail;
109
110 #ifdef CONFIG_FST
111 if (add_buf(&beacon, hapd->iface->fst_ies) < 0 ||
112 add_buf(&proberesp, hapd->iface->fst_ies) < 0 ||
113 add_buf(&assocresp, hapd->iface->fst_ies) < 0)
114 goto fail;
115 #endif /* CONFIG_FST */
116
117 #ifdef CONFIG_FILS
118 pos = hostapd_eid_fils_indic(hapd, buf, 0);
119 if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
120 add_buf_data(&proberesp, buf, pos - buf) < 0)
121 goto fail;
122 #endif /* CONFIG_FILS */
123
124 pos = hostapd_eid_rsnxe(hapd, buf, sizeof(buf));
125 if (add_buf_data(&assocresp, buf, pos - buf) < 0)
126 goto fail;
127
128 if (add_buf(&beacon, hapd->wps_beacon_ie) < 0 ||
129 add_buf(&proberesp, hapd->wps_probe_resp_ie) < 0)
130 goto fail;
131
132 #ifdef CONFIG_P2P
133 if (add_buf(&beacon, hapd->p2p_beacon_ie) < 0 ||
134 add_buf(&proberesp, hapd->p2p_probe_resp_ie) < 0)
135 goto fail;
136 #endif /* CONFIG_P2P */
137
138 #ifdef CONFIG_P2P_MANAGER
139 if (hapd->conf->p2p & P2P_MANAGE) {
140 if (wpabuf_resize(&beacon, 100) == 0) {
141 u8 *start, *p;
142 start = wpabuf_put(beacon, 0);
143 p = hostapd_eid_p2p_manage(hapd, start);
144 wpabuf_put(beacon, p - start);
145 }
146
147 if (wpabuf_resize(&proberesp, 100) == 0) {
148 u8 *start, *p;
149 start = wpabuf_put(proberesp, 0);
150 p = hostapd_eid_p2p_manage(hapd, start);
151 wpabuf_put(proberesp, p - start);
152 }
153 }
154 #endif /* CONFIG_P2P_MANAGER */
155
156 #ifdef CONFIG_WPS
157 if (hapd->conf->wps_state) {
158 struct wpabuf *a = wps_build_assoc_resp_ie();
159 add_buf(&assocresp, a);
160 wpabuf_free(a);
161 }
162 #endif /* CONFIG_WPS */
163
164 #ifdef CONFIG_P2P_MANAGER
165 if (hapd->conf->p2p & P2P_MANAGE) {
166 if (wpabuf_resize(&assocresp, 100) == 0) {
167 u8 *start, *p;
168 start = wpabuf_put(assocresp, 0);
169 p = hostapd_eid_p2p_manage(hapd, start);
170 wpabuf_put(assocresp, p - start);
171 }
172 }
173 #endif /* CONFIG_P2P_MANAGER */
174
175 #ifdef CONFIG_WIFI_DISPLAY
176 if (hapd->p2p_group) {
177 struct wpabuf *a;
178 a = p2p_group_assoc_resp_ie(hapd->p2p_group, P2P_SC_SUCCESS);
179 add_buf(&assocresp, a);
180 wpabuf_free(a);
181 }
182 #endif /* CONFIG_WIFI_DISPLAY */
183
184 #ifdef CONFIG_HS20
185 pos = hostapd_eid_hs20_indication(hapd, buf);
186 if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
187 add_buf_data(&proberesp, buf, pos - buf) < 0)
188 goto fail;
189
190 pos = hostapd_eid_osen(hapd, buf);
191 if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
192 add_buf_data(&proberesp, buf, pos - buf) < 0)
193 goto fail;
194 #endif /* CONFIG_HS20 */
195
196 #ifdef CONFIG_MBO
197 if (hapd->conf->mbo_enabled ||
198 OCE_STA_CFON_ENABLED(hapd) || OCE_AP_ENABLED(hapd)) {
199 pos = hostapd_eid_mbo(hapd, buf, sizeof(buf));
200 if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
201 add_buf_data(&proberesp, buf, pos - buf) < 0 ||
202 add_buf_data(&assocresp, buf, pos - buf) < 0)
203 goto fail;
204 }
205 #endif /* CONFIG_MBO */
206
207 #ifdef CONFIG_OWE
208 pos = hostapd_eid_owe_trans(hapd, buf, sizeof(buf));
209 if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
210 add_buf_data(&proberesp, buf, pos - buf) < 0)
211 goto fail;
212 #endif /* CONFIG_OWE */
213
214 add_buf(&beacon, hapd->conf->vendor_elements);
215 add_buf(&proberesp, hapd->conf->vendor_elements);
216 #ifdef CONFIG_TESTING_OPTIONS
217 add_buf(&proberesp, hapd->conf->presp_elements);
218 #endif /* CONFIG_TESTING_OPTIONS */
219 add_buf(&assocresp, hapd->conf->assocresp_elements);
220
221 *beacon_ret = beacon;
222 *proberesp_ret = proberesp;
223 *assocresp_ret = assocresp;
224
225 return 0;
226
227 fail:
228 wpabuf_free(beacon);
229 wpabuf_free(proberesp);
230 wpabuf_free(assocresp);
231 return -1;
232 }
233
234
hostapd_free_ap_extra_ies(struct hostapd_data * hapd,struct wpabuf * beacon,struct wpabuf * proberesp,struct wpabuf * assocresp)235 void hostapd_free_ap_extra_ies(struct hostapd_data *hapd,
236 struct wpabuf *beacon,
237 struct wpabuf *proberesp,
238 struct wpabuf *assocresp)
239 {
240 wpabuf_free(beacon);
241 wpabuf_free(proberesp);
242 wpabuf_free(assocresp);
243 }
244
245
hostapd_reset_ap_wps_ie(struct hostapd_data * hapd)246 int hostapd_reset_ap_wps_ie(struct hostapd_data *hapd)
247 {
248 if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
249 return 0;
250
251 return hapd->driver->set_ap_wps_ie(hapd->drv_priv, NULL, NULL, NULL);
252 }
253
254
hostapd_set_ap_wps_ie(struct hostapd_data * hapd)255 int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
256 {
257 struct wpabuf *beacon, *proberesp, *assocresp;
258 int ret;
259
260 if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
261 return 0;
262
263 if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) <
264 0)
265 return -1;
266
267 ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp,
268 assocresp);
269
270 hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
271
272 return ret;
273 }
274
275
hostapd_sta_is_link_sta(struct hostapd_data * hapd,struct sta_info * sta)276 bool hostapd_sta_is_link_sta(struct hostapd_data *hapd,
277 struct sta_info *sta)
278 {
279 #ifdef CONFIG_IEEE80211BE
280 if (ap_sta_is_mld(hapd, sta) &&
281 sta->mld_assoc_link_id != hapd->mld_link_id)
282 return true;
283 #endif /* CONFIG_IEEE80211BE */
284
285 return false;
286 }
287
288
hostapd_set_authorized(struct hostapd_data * hapd,struct sta_info * sta,int authorized)289 int hostapd_set_authorized(struct hostapd_data *hapd,
290 struct sta_info *sta, int authorized)
291 {
292 /*
293 * The WPA_STA_AUTHORIZED flag is relevant only for the MLD station and
294 * not to the link stations (as the authorization is done between the
295 * MLD peers). Thus, do not propagate the change to the driver for the
296 * link stations.
297 */
298 if (hostapd_sta_is_link_sta(hapd, sta)) {
299 wpa_printf(MSG_DEBUG,
300 "%s: Do not update link station flags (" MACSTR ")",
301 __func__, MAC2STR(sta->addr));
302 return 0;
303 }
304
305 if (authorized) {
306 return hostapd_sta_set_flags(hapd, sta->addr,
307 hostapd_sta_flags_to_drv(
308 sta->flags),
309 WPA_STA_AUTHORIZED, ~0);
310 }
311
312 return hostapd_sta_set_flags(hapd, sta->addr,
313 hostapd_sta_flags_to_drv(sta->flags),
314 0, ~WPA_STA_AUTHORIZED);
315 }
316
317
hostapd_set_sta_flags(struct hostapd_data * hapd,struct sta_info * sta)318 int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta)
319 {
320 int set_flags, total_flags, flags_and, flags_or;
321 total_flags = hostapd_sta_flags_to_drv(sta->flags);
322 set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP |
323 WPA_STA_AUTHORIZED;
324
325 /*
326 * All the station flags other than WPA_STA_SHORT_PREAMBLE are relevant
327 * only for the MLD station and not to the link stations (as these flags
328 * are related to the MLD state and not the link state). As for the
329 * WPA_STA_SHORT_PREAMBLE, since the station is an EHT station, it must
330 * support short preamble. Thus, do not propagate the change to the
331 * driver for the link stations.
332 */
333 if (hostapd_sta_is_link_sta(hapd, sta)) {
334 wpa_printf(MSG_DEBUG,
335 "%s: Do not update link station flags (" MACSTR ")",
336 __func__, MAC2STR(sta->addr));
337 return 0;
338 }
339
340 flags_or = total_flags & set_flags;
341 flags_and = total_flags | ~set_flags;
342 return hostapd_sta_set_flags(hapd, sta->addr, total_flags,
343 flags_or, flags_and);
344 }
345
346
hostapd_set_drv_ieee8021x(struct hostapd_data * hapd,const char * ifname,int enabled)347 int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
348 int enabled)
349 {
350 struct wpa_bss_params params;
351 os_memset(¶ms, 0, sizeof(params));
352 params.ifname = ifname;
353 params.enabled = enabled;
354 if (enabled) {
355 params.wpa = hapd->conf->wpa;
356 params.ieee802_1x = hapd->conf->ieee802_1x;
357 params.wpa_group = hapd->conf->wpa_group;
358 if ((hapd->conf->wpa & (WPA_PROTO_WPA | WPA_PROTO_RSN)) ==
359 (WPA_PROTO_WPA | WPA_PROTO_RSN))
360 params.wpa_pairwise = hapd->conf->wpa_pairwise |
361 hapd->conf->rsn_pairwise;
362 else if (hapd->conf->wpa & WPA_PROTO_RSN)
363 params.wpa_pairwise = hapd->conf->rsn_pairwise;
364 else if (hapd->conf->wpa & WPA_PROTO_WPA)
365 params.wpa_pairwise = hapd->conf->wpa_pairwise;
366 params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt;
367 params.rsn_preauth = hapd->conf->rsn_preauth;
368 params.ieee80211w = hapd->conf->ieee80211w;
369 }
370 return hostapd_set_ieee8021x(hapd, ¶ms);
371 }
372
373
hostapd_vlan_if_add(struct hostapd_data * hapd,const char * ifname)374 int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname)
375 {
376 char force_ifname[IFNAMSIZ];
377 u8 if_addr[ETH_ALEN];
378 return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, hapd->own_addr,
379 NULL, NULL, force_ifname, if_addr, NULL, 0);
380 }
381
382
hostapd_vlan_if_remove(struct hostapd_data * hapd,const char * ifname)383 int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname)
384 {
385 return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname);
386 }
387
388
hostapd_set_wds_sta(struct hostapd_data * hapd,char * ifname_wds,const u8 * addr,int aid,int val)389 int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds,
390 const u8 *addr, int aid, int val)
391 {
392 const char *bridge = NULL;
393
394 if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL)
395 return -1;
396 if (hapd->conf->wds_bridge[0])
397 bridge = hapd->conf->wds_bridge;
398 else if (hapd->conf->bridge[0])
399 bridge = hapd->conf->bridge;
400 return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
401 bridge, ifname_wds);
402 }
403
404
hostapd_add_sta_node(struct hostapd_data * hapd,const u8 * addr,u16 auth_alg)405 int hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr,
406 u16 auth_alg)
407 {
408 if (hapd->driver == NULL || hapd->driver->add_sta_node == NULL)
409 return -EOPNOTSUPP;
410 return hapd->driver->add_sta_node(hapd->drv_priv, addr, auth_alg);
411 }
412
413
hostapd_sta_auth(struct hostapd_data * hapd,const u8 * addr,u16 seq,u16 status,const u8 * ie,size_t len)414 int hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr,
415 u16 seq, u16 status, const u8 *ie, size_t len)
416 {
417 struct wpa_driver_sta_auth_params params;
418 #ifdef CONFIG_FILS
419 struct sta_info *sta;
420 #endif /* CONFIG_FILS */
421
422 if (hapd->driver == NULL || hapd->driver->sta_auth == NULL)
423 return 0;
424
425 os_memset(¶ms, 0, sizeof(params));
426
427 #ifdef CONFIG_FILS
428 sta = ap_get_sta(hapd, addr);
429 if (!sta) {
430 wpa_printf(MSG_DEBUG, "Station " MACSTR_SEC
431 " not found for sta_auth processing",
432 MAC2STR_SEC(addr));
433 return 0;
434 }
435
436 if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
437 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
438 sta->auth_alg == WLAN_AUTH_FILS_PK) {
439 params.fils_auth = 1;
440 wpa_auth_get_fils_aead_params(sta->wpa_sm, params.fils_anonce,
441 params.fils_snonce,
442 params.fils_kek,
443 ¶ms.fils_kek_len);
444 }
445 #endif /* CONFIG_FILS */
446
447 params.own_addr = hapd->own_addr;
448 params.addr = addr;
449 params.seq = seq;
450 params.status = status;
451 params.ie = ie;
452 params.len = len;
453
454 return hapd->driver->sta_auth(hapd->drv_priv, ¶ms);
455 }
456
457
hostapd_sta_assoc(struct hostapd_data * hapd,const u8 * addr,int reassoc,u16 status,const u8 * ie,size_t len)458 int hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr,
459 int reassoc, u16 status, const u8 *ie, size_t len)
460 {
461 if (hapd->driver == NULL || hapd->driver->sta_assoc == NULL)
462 return 0;
463 return hapd->driver->sta_assoc(hapd->drv_priv, hapd->own_addr, addr,
464 reassoc, status, ie, len);
465 }
466
467
hostapd_sta_add(struct hostapd_data * hapd,const u8 * addr,u16 aid,u16 capability,const u8 * supp_rates,size_t supp_rates_len,u16 listen_interval,const struct ieee80211_ht_capabilities * ht_capab,const struct ieee80211_vht_capabilities * vht_capab,const struct ieee80211_he_capabilities * he_capab,size_t he_capab_len,const struct ieee80211_eht_capabilities * eht_capab,size_t eht_capab_len,const struct ieee80211_he_6ghz_band_cap * he_6ghz_capab,u32 flags,u8 qosinfo,u8 vht_opmode,int supp_p2p_ps,int set,const u8 * link_addr,bool mld_link_sta)468 int hostapd_sta_add(struct hostapd_data *hapd,
469 const u8 *addr, u16 aid, u16 capability,
470 const u8 *supp_rates, size_t supp_rates_len,
471 u16 listen_interval,
472 const struct ieee80211_ht_capabilities *ht_capab,
473 const struct ieee80211_vht_capabilities *vht_capab,
474 const struct ieee80211_he_capabilities *he_capab,
475 size_t he_capab_len,
476 const struct ieee80211_eht_capabilities *eht_capab,
477 size_t eht_capab_len,
478 const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab,
479 u32 flags, u8 qosinfo, u8 vht_opmode, int supp_p2p_ps,
480 int set, const u8 *link_addr, bool mld_link_sta)
481 {
482 struct hostapd_sta_add_params params;
483
484 if (hapd->driver == NULL)
485 return 0;
486 if (hapd->driver->sta_add == NULL)
487 return 0;
488
489 os_memset(¶ms, 0, sizeof(params));
490 params.addr = addr;
491 params.aid = aid;
492 params.capability = capability;
493 params.supp_rates = supp_rates;
494 params.supp_rates_len = supp_rates_len;
495 params.listen_interval = listen_interval;
496 params.ht_capabilities = ht_capab;
497 params.vht_capabilities = vht_capab;
498 params.he_capab = he_capab;
499 params.he_capab_len = he_capab_len;
500 params.eht_capab = eht_capab;
501 params.eht_capab_len = eht_capab_len;
502 params.he_6ghz_capab = he_6ghz_capab;
503 params.vht_opmode_enabled = !!(flags & WLAN_STA_VHT_OPMODE_ENABLED);
504 params.vht_opmode = vht_opmode;
505 params.flags = hostapd_sta_flags_to_drv(flags);
506 params.qosinfo = qosinfo;
507 params.support_p2p_ps = supp_p2p_ps;
508 params.set = set;
509 params.mld_link_id = -1;
510
511 #ifdef CONFIG_IEEE80211BE
512 /*
513 * An AP MLD needs to always specify to what link the station needs
514 * to be added.
515 */
516 if (hapd->conf->mld_ap) {
517 params.mld_link_id = hapd->mld_link_id;
518 params.mld_link_addr = link_addr;
519 params.mld_link_sta = mld_link_sta;
520 }
521 #endif /* CONFIG_IEEE80211BE */
522
523 return hapd->driver->sta_add(hapd->drv_priv, ¶ms);
524 }
525
526
hostapd_add_tspec(struct hostapd_data * hapd,const u8 * addr,u8 * tspec_ie,size_t tspec_ielen)527 int hostapd_add_tspec(struct hostapd_data *hapd, const u8 *addr,
528 u8 *tspec_ie, size_t tspec_ielen)
529 {
530 if (hapd->driver == NULL || hapd->driver->add_tspec == NULL)
531 return 0;
532 return hapd->driver->add_tspec(hapd->drv_priv, addr, tspec_ie,
533 tspec_ielen);
534 }
535
536
hostapd_set_privacy(struct hostapd_data * hapd,int enabled)537 int hostapd_set_privacy(struct hostapd_data *hapd, int enabled)
538 {
539 if (hapd->driver == NULL || hapd->driver->set_privacy == NULL)
540 return 0;
541 return hapd->driver->set_privacy(hapd->drv_priv, enabled);
542 }
543
544
hostapd_set_generic_elem(struct hostapd_data * hapd,const u8 * elem,size_t elem_len)545 int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem,
546 size_t elem_len)
547 {
548 if (hapd->driver == NULL || hapd->driver->set_generic_elem == NULL)
549 return 0;
550 return hapd->driver->set_generic_elem(hapd->drv_priv, elem, elem_len);
551 }
552
553
hostapd_get_ssid(struct hostapd_data * hapd,u8 * buf,size_t len)554 int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len)
555 {
556 if (hapd->driver == NULL || hapd->driver->hapd_get_ssid == NULL)
557 return 0;
558 return hapd->driver->hapd_get_ssid(hapd->drv_priv, buf, len);
559 }
560
561
hostapd_set_ssid(struct hostapd_data * hapd,const u8 * buf,size_t len)562 int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len)
563 {
564 if (hapd->driver == NULL || hapd->driver->hapd_set_ssid == NULL)
565 return 0;
566 return hapd->driver->hapd_set_ssid(hapd->drv_priv, buf, len);
567 }
568
569
hostapd_if_add(struct hostapd_data * hapd,enum wpa_driver_if_type type,const char * ifname,const u8 * addr,void * bss_ctx,void ** drv_priv,char * force_ifname,u8 * if_addr,const char * bridge,int use_existing)570 int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
571 const char *ifname, const u8 *addr, void *bss_ctx,
572 void **drv_priv, char *force_ifname, u8 *if_addr,
573 const char *bridge, int use_existing)
574 {
575 if (hapd->driver == NULL || hapd->driver->if_add == NULL)
576 return -1;
577 return hapd->driver->if_add(hapd->drv_priv, type, ifname, addr,
578 bss_ctx, drv_priv, force_ifname, if_addr,
579 bridge, use_existing, 1);
580 }
581
582
583 #ifdef CONFIG_IEEE80211BE
hostapd_if_link_remove(struct hostapd_data * hapd,enum wpa_driver_if_type type,const char * ifname,u8 link_id)584 int hostapd_if_link_remove(struct hostapd_data *hapd,
585 enum wpa_driver_if_type type,
586 const char *ifname, u8 link_id)
587 {
588 if (!hapd->driver || !hapd->drv_priv || !hapd->driver->link_remove)
589 return -1;
590
591 return hapd->driver->link_remove(hapd->drv_priv, type, ifname,
592 hapd->mld_link_id);
593 }
594 #endif /* CONFIG_IEEE80211BE */
595
596
hostapd_if_remove(struct hostapd_data * hapd,enum wpa_driver_if_type type,const char * ifname)597 int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
598 const char *ifname)
599 {
600 if (hapd->driver == NULL || hapd->drv_priv == NULL ||
601 hapd->driver->if_remove == NULL)
602 return -1;
603
604 #ifdef CONFIG_IEEE80211BE
605 if (hapd->conf->mld_ap)
606 return hostapd_if_link_remove(hapd, type, ifname,
607 hapd->mld_link_id);
608 #endif /* CONFIG_IEEE80211BE */
609
610 return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
611 }
612
613
hostapd_set_ieee8021x(struct hostapd_data * hapd,struct wpa_bss_params * params)614 int hostapd_set_ieee8021x(struct hostapd_data *hapd,
615 struct wpa_bss_params *params)
616 {
617 if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL)
618 return 0;
619 return hapd->driver->set_ieee8021x(hapd->drv_priv, params);
620 }
621
622
hostapd_get_seqnum(const char * ifname,struct hostapd_data * hapd,const u8 * addr,int idx,int link_id,u8 * seq)623 int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
624 const u8 *addr, int idx, int link_id, u8 *seq)
625 {
626 if (hapd->driver == NULL || hapd->driver->get_seqnum == NULL)
627 return 0;
628 return hapd->driver->get_seqnum(ifname, hapd->drv_priv, addr, idx,
629 link_id, seq);
630 }
631
632
hostapd_flush(struct hostapd_data * hapd)633 int hostapd_flush(struct hostapd_data *hapd)
634 {
635 int link_id = -1;
636
637 if (hapd->driver == NULL || hapd->driver->flush == NULL)
638 return 0;
639
640 #ifdef CONFIG_IEEE80211BE
641 if (hapd->conf && hapd->conf->mld_ap)
642 link_id = hapd->mld_link_id;
643 #endif /* CONFIG_IEEE80211BE */
644
645 return hapd->driver->flush(hapd->drv_priv, link_id);
646 }
647
648
hostapd_set_freq(struct hostapd_data * hapd,enum hostapd_hw_mode mode,int freq,int channel,int edmg,u8 edmg_channel,int ht_enabled,int vht_enabled,int he_enabled,bool eht_enabled,int sec_channel_offset,int oper_chwidth,int center_segment0,int center_segment1)649 int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode,
650 int freq, int channel, int edmg, u8 edmg_channel,
651 int ht_enabled, int vht_enabled,
652 int he_enabled, bool eht_enabled,
653 int sec_channel_offset, int oper_chwidth,
654 int center_segment0, int center_segment1)
655 {
656 struct hostapd_freq_params data;
657 struct hostapd_hw_modes *cmode = hapd->iface->current_mode;
658
659 if (hostapd_set_freq_params(&data, mode, freq, channel, edmg,
660 edmg_channel, ht_enabled,
661 vht_enabled, he_enabled, eht_enabled,
662 sec_channel_offset, oper_chwidth,
663 center_segment0, center_segment1,
664 cmode ? cmode->vht_capab : 0,
665 cmode ?
666 &cmode->he_capab[IEEE80211_MODE_AP] : NULL,
667 cmode ?
668 &cmode->eht_capab[IEEE80211_MODE_AP] :
669 NULL, hostapd_get_punct_bitmap(hapd)))
670 return -1;
671
672 if (hapd->driver == NULL)
673 return 0;
674 if (hapd->driver->set_freq == NULL)
675 return 0;
676
677 data.link_id = -1;
678
679 #ifdef CONFIG_IEEE80211BE
680 if (hapd->conf->mld_ap) {
681 data.link_id = hapd->mld_link_id;
682 wpa_printf(MSG_DEBUG,
683 "hostapd_set_freq: link_id=%d", data.link_id);
684 }
685 #endif /* CONFIG_IEEE80211BE */
686
687 return hapd->driver->set_freq(hapd->drv_priv, &data);
688 }
689
hostapd_set_rts(struct hostapd_data * hapd,int rts)690 int hostapd_set_rts(struct hostapd_data *hapd, int rts)
691 {
692 if (hapd->driver == NULL || hapd->driver->set_rts == NULL)
693 return 0;
694 return hapd->driver->set_rts(hapd->drv_priv, rts);
695 }
696
697
hostapd_set_frag(struct hostapd_data * hapd,int frag)698 int hostapd_set_frag(struct hostapd_data *hapd, int frag)
699 {
700 if (hapd->driver == NULL || hapd->driver->set_frag == NULL)
701 return 0;
702 return hapd->driver->set_frag(hapd->drv_priv, frag);
703 }
704
705
hostapd_sta_set_flags(struct hostapd_data * hapd,u8 * addr,int total_flags,int flags_or,int flags_and)706 int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
707 int total_flags, int flags_or, int flags_and)
708 {
709 if (!hapd->driver || !hapd->drv_priv || !hapd->driver->sta_set_flags)
710 return 0;
711 return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags,
712 flags_or, flags_and);
713 }
714
715
hostapd_sta_set_airtime_weight(struct hostapd_data * hapd,const u8 * addr,unsigned int weight)716 int hostapd_sta_set_airtime_weight(struct hostapd_data *hapd, const u8 *addr,
717 unsigned int weight)
718 {
719 if (!hapd->driver || !hapd->driver->sta_set_airtime_weight)
720 return 0;
721 return hapd->driver->sta_set_airtime_weight(hapd->drv_priv, addr,
722 weight);
723 }
724
725
hostapd_set_country(struct hostapd_data * hapd,const char * country)726 int hostapd_set_country(struct hostapd_data *hapd, const char *country)
727 {
728 if (hapd->driver == NULL ||
729 hapd->driver->set_country == NULL)
730 return 0;
731 return hapd->driver->set_country(hapd->drv_priv, country);
732 }
733
734
hostapd_set_tx_queue_params(struct hostapd_data * hapd,int queue,int aifs,int cw_min,int cw_max,int burst_time)735 int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
736 int cw_min, int cw_max, int burst_time)
737 {
738 int link_id = -1;
739
740 if (hapd->driver == NULL || hapd->driver->set_tx_queue_params == NULL)
741 return 0;
742
743 #ifdef CONFIG_IEEE80211BE
744 if (hapd->conf->mld_ap)
745 link_id = hapd->mld_link_id;
746 #endif /* CONFIG_IEEE80211BE */
747
748 return hapd->driver->set_tx_queue_params(hapd->drv_priv, queue, aifs,
749 cw_min, cw_max, burst_time,
750 link_id);
751 }
752
753
754 struct hostapd_hw_modes *
hostapd_get_hw_feature_data(struct hostapd_data * hapd,u16 * num_modes,u16 * flags,u8 * dfs_domain)755 hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
756 u16 *flags, u8 *dfs_domain)
757 {
758 if (!hapd->driver || !hapd->driver->get_hw_feature_data ||
759 !hapd->drv_priv)
760 return NULL;
761 return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
762 flags, dfs_domain);
763 }
764
765
hostapd_driver_commit(struct hostapd_data * hapd)766 int hostapd_driver_commit(struct hostapd_data *hapd)
767 {
768 if (hapd->driver == NULL || hapd->driver->commit == NULL)
769 return 0;
770 return hapd->driver->commit(hapd->drv_priv);
771 }
772
773
hostapd_drv_none(struct hostapd_data * hapd)774 int hostapd_drv_none(struct hostapd_data *hapd)
775 {
776 return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0;
777 }
778
779
hostapd_drv_nl80211(struct hostapd_data * hapd)780 bool hostapd_drv_nl80211(struct hostapd_data *hapd)
781 {
782 return hapd->driver && os_strcmp(hapd->driver->name, "nl80211") == 0;
783 }
784
785
hostapd_driver_scan(struct hostapd_data * hapd,struct wpa_driver_scan_params * params)786 int hostapd_driver_scan(struct hostapd_data *hapd,
787 struct wpa_driver_scan_params *params)
788 {
789 if (hapd->driver && hapd->driver->scan2)
790 return hapd->driver->scan2(hapd->drv_priv, params);
791 return -1;
792 }
793
794
hostapd_driver_get_scan_results(struct hostapd_data * hapd)795 struct wpa_scan_results * hostapd_driver_get_scan_results(
796 struct hostapd_data *hapd)
797 {
798 if (hapd->driver && hapd->driver->get_scan_results)
799 return hapd->driver->get_scan_results(hapd->drv_priv, NULL);
800 if (hapd->driver && hapd->driver->get_scan_results2)
801 return hapd->driver->get_scan_results2(hapd->drv_priv);
802 return NULL;
803 }
804
805
hostapd_driver_set_noa(struct hostapd_data * hapd,u8 count,int start,int duration)806 int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
807 int duration)
808 {
809 if (hapd->driver && hapd->driver->set_noa)
810 return hapd->driver->set_noa(hapd->drv_priv, count, start,
811 duration);
812 return -1;
813 }
814
815
hostapd_drv_set_key(const char * ifname,struct hostapd_data * hapd,enum wpa_alg alg,const u8 * addr,int key_idx,int vlan_id,int set_tx,const u8 * seq,size_t seq_len,const u8 * key,size_t key_len,enum key_flag key_flag)816 int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
817 enum wpa_alg alg, const u8 *addr,
818 int key_idx, int vlan_id, int set_tx,
819 const u8 *seq, size_t seq_len,
820 const u8 *key, size_t key_len, enum key_flag key_flag)
821 {
822 struct wpa_driver_set_key_params params;
823
824 if (hapd->driver == NULL || hapd->driver->set_key == NULL)
825 return 0;
826
827 os_memset(¶ms, 0, sizeof(params));
828 params.ifname = ifname;
829 params.alg = alg;
830 params.addr = addr;
831 params.key_idx = key_idx;
832 params.set_tx = set_tx;
833 params.seq = seq;
834 params.seq_len = seq_len;
835 params.key = key;
836 params.key_len = key_len;
837 params.vlan_id = vlan_id;
838 params.key_flag = key_flag;
839 params.link_id = -1;
840
841 #ifdef CONFIG_IEEE80211BE
842 if (hapd->conf->mld_ap && !(key_flag & KEY_FLAG_PAIRWISE))
843 params.link_id = hapd->mld_link_id;
844 #endif /* CONFIG_IEEE80211BE */
845
846 return hapd->driver->set_key(hapd->drv_priv, ¶ms);
847 }
848
849
hostapd_drv_send_mlme(struct hostapd_data * hapd,const void * msg,size_t len,int noack,const u16 * csa_offs,size_t csa_offs_len,int no_encrypt)850 int hostapd_drv_send_mlme(struct hostapd_data *hapd,
851 const void *msg, size_t len, int noack,
852 const u16 *csa_offs, size_t csa_offs_len,
853 int no_encrypt)
854 {
855 int link_id = -1;
856
857 #ifdef CONFIG_IEEE80211BE
858 if (hapd->conf->mld_ap)
859 link_id = hapd->mld_link_id;
860 #endif /* CONFIG_IEEE80211BE */
861
862 if (!hapd->driver || !hapd->driver->send_mlme || !hapd->drv_priv)
863 return 0;
864 return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0,
865 csa_offs, csa_offs_len, no_encrypt, 0,
866 link_id);
867 }
868
869
hostapd_drv_sta_deauth(struct hostapd_data * hapd,const u8 * addr,int reason)870 int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
871 const u8 *addr, int reason)
872 {
873 int link_id = -1;
874 const u8 *own_addr = hapd->own_addr;
875
876 #ifdef CONFIG_IEEE80211BE
877 if (hapd->conf->mld_ap) {
878 struct sta_info *sta = ap_get_sta(hapd, addr);
879
880 link_id = hapd->mld_link_id;
881 if (ap_sta_is_mld(hapd, sta))
882 own_addr = hapd->mld->mld_addr;
883 }
884 #endif /* CONFIG_IEEE80211BE */
885
886 if (!hapd->driver || !hapd->driver->sta_deauth || !hapd->drv_priv)
887 return 0;
888 #ifdef CONFIG_P2P_CHR
889 wpa_supplicant_upload_go_p2p_state(hapd, addr,
890 P2P_INTERFACE_STATE_DISCONNECTED, reason);
891 #endif
892 return hapd->driver->sta_deauth(hapd->drv_priv, own_addr, addr,
893 reason, link_id);
894 }
895
896
hostapd_drv_sta_disassoc(struct hostapd_data * hapd,const u8 * addr,int reason)897 int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
898 const u8 *addr, int reason)
899 {
900 const u8 *own_addr = hapd->own_addr;
901
902 #ifdef CONFIG_IEEE80211BE
903 if (hapd->conf->mld_ap) {
904 struct sta_info *sta = ap_get_sta(hapd, addr);
905
906 if (ap_sta_is_mld(hapd, sta))
907 own_addr = hapd->mld->mld_addr;
908 }
909 #endif /* CONFIG_IEEE80211BE */
910
911 if (!hapd->driver || !hapd->driver->sta_disassoc || !hapd->drv_priv)
912 return 0;
913 #ifdef CONFIG_P2P_CHR
914 wpa_supplicant_upload_go_p2p_state(hapd, addr,
915 P2P_INTERFACE_STATE_DISCONNECTED, reason);
916 #endif
917 return hapd->driver->sta_disassoc(hapd->drv_priv, own_addr, addr,
918 reason);
919 }
920
921
hostapd_drv_wnm_oper(struct hostapd_data * hapd,enum wnm_oper oper,const u8 * peer,u8 * buf,u16 * buf_len)922 int hostapd_drv_wnm_oper(struct hostapd_data *hapd, enum wnm_oper oper,
923 const u8 *peer, u8 *buf, u16 *buf_len)
924 {
925 if (hapd->driver == NULL || hapd->driver->wnm_oper == NULL)
926 return -1;
927 return hapd->driver->wnm_oper(hapd->drv_priv, oper, peer, buf,
928 buf_len);
929 }
930
931
hapd_drv_send_action(struct hostapd_data * hapd,unsigned int freq,unsigned int wait,const u8 * dst,const u8 * data,size_t len,bool addr3_ap)932 static int hapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
933 unsigned int wait, const u8 *dst,
934 const u8 *data, size_t len, bool addr3_ap)
935 {
936 const u8 *own_addr = hapd->own_addr;
937 const u8 *bssid;
938 const u8 wildcard_bssid[ETH_ALEN] = {
939 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
940 };
941 struct sta_info *sta;
942
943 if (!hapd->driver || !hapd->driver->send_action || !hapd->drv_priv)
944 return 0;
945 bssid = hapd->own_addr;
946 if (!addr3_ap && !is_multicast_ether_addr(dst) &&
947 len > 0 && data[0] == WLAN_ACTION_PUBLIC) {
948 /*
949 * Public Action frames to a STA that is not a member of the BSS
950 * shall use wildcard BSSID value.
951 */
952 sta = ap_get_sta(hapd, dst);
953 if (!sta || !(sta->flags & WLAN_STA_ASSOC))
954 bssid = wildcard_bssid;
955 } else if (!addr3_ap && is_broadcast_ether_addr(dst) &&
956 len > 0 && data[0] == WLAN_ACTION_PUBLIC) {
957 /*
958 * The only current use case of Public Action frames with
959 * broadcast destination address is DPP PKEX. That case is
960 * directing all devices and not just the STAs within the BSS,
961 * so have to use the wildcard BSSID value.
962 */
963 bssid = wildcard_bssid;
964 #ifdef CONFIG_IEEE80211BE
965 } else if (hapd->conf->mld_ap) {
966 sta = ap_get_sta(hapd, dst);
967
968 if (ap_sta_is_mld(hapd, sta)) {
969 own_addr = hapd->mld->mld_addr;
970 bssid = own_addr;
971 }
972 #endif /* CONFIG_IEEE80211BE */
973 }
974
975 return hapd->driver->send_action(hapd->drv_priv, freq, wait, dst,
976 own_addr, bssid, data, len, 0);
977 }
978
979
hostapd_drv_send_action(struct hostapd_data * hapd,unsigned int freq,unsigned int wait,const u8 * dst,const u8 * data,size_t len)980 int hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
981 unsigned int wait, const u8 *dst, const u8 *data,
982 size_t len)
983 {
984 return hapd_drv_send_action(hapd, freq, wait, dst, data, len, false);
985 }
986
987
hostapd_drv_send_action_addr3_ap(struct hostapd_data * hapd,unsigned int freq,unsigned int wait,const u8 * dst,const u8 * data,size_t len)988 int hostapd_drv_send_action_addr3_ap(struct hostapd_data *hapd,
989 unsigned int freq,
990 unsigned int wait, const u8 *dst,
991 const u8 *data, size_t len)
992 {
993 return hapd_drv_send_action(hapd, freq, wait, dst, data, len, true);
994 }
995
996
hostapd_start_dfs_cac(struct hostapd_iface * iface,enum hostapd_hw_mode mode,int freq,int channel,int ht_enabled,int vht_enabled,int he_enabled,bool eht_enabled,int sec_channel_offset,int oper_chwidth,int center_segment0,int center_segment1,bool radar_background)997 int hostapd_start_dfs_cac(struct hostapd_iface *iface,
998 enum hostapd_hw_mode mode, int freq,
999 int channel, int ht_enabled, int vht_enabled,
1000 int he_enabled, bool eht_enabled,
1001 int sec_channel_offset, int oper_chwidth,
1002 int center_segment0, int center_segment1,
1003 bool radar_background)
1004 {
1005 struct hostapd_data *hapd = iface->bss[0];
1006 struct hostapd_freq_params data;
1007 int res;
1008 struct hostapd_hw_modes *cmode = iface->current_mode;
1009
1010 if (!hapd->driver || !hapd->driver->start_dfs_cac || !cmode)
1011 return 0;
1012
1013 if (!iface->conf->ieee80211h) {
1014 wpa_printf(MSG_ERROR, "Can't start DFS CAC, DFS functionality "
1015 "is not enabled");
1016 return -1;
1017 }
1018
1019 if (hostapd_set_freq_params(&data, mode, freq, channel, 0, 0,
1020 ht_enabled,
1021 vht_enabled, he_enabled, eht_enabled,
1022 sec_channel_offset,
1023 oper_chwidth, center_segment0,
1024 center_segment1,
1025 cmode->vht_capab,
1026 &cmode->he_capab[IEEE80211_MODE_AP],
1027 &cmode->eht_capab[IEEE80211_MODE_AP],
1028 hostapd_get_punct_bitmap(hapd))) {
1029 wpa_printf(MSG_ERROR, "Can't set freq params");
1030 return -1;
1031 }
1032 data.radar_background = radar_background;
1033
1034 res = hapd->driver->start_dfs_cac(hapd->drv_priv, &data);
1035 if (!res) {
1036 if (radar_background)
1037 iface->radar_background.cac_started = 1;
1038 else
1039 iface->cac_started = 1;
1040 os_get_reltime(&iface->dfs_cac_start);
1041 }
1042
1043 return res;
1044 }
1045
1046
hostapd_drv_set_qos_map(struct hostapd_data * hapd,const u8 * qos_map_set,u8 qos_map_set_len)1047 int hostapd_drv_set_qos_map(struct hostapd_data *hapd,
1048 const u8 *qos_map_set, u8 qos_map_set_len)
1049 {
1050 if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv ||
1051 !(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_QOS_MAPPING))
1052 return 0;
1053 return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set,
1054 qos_map_set_len);
1055 }
1056
1057
hostapd_get_hw_mode_any_channels(struct hostapd_data * hapd,struct hostapd_hw_modes * mode,int acs_ch_list_all,bool allow_disabled,int ** freq_list)1058 void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd,
1059 struct hostapd_hw_modes *mode,
1060 int acs_ch_list_all, bool allow_disabled,
1061 int **freq_list)
1062 {
1063 int i;
1064 bool is_no_ir = false;
1065
1066 for (i = 0; i < mode->num_channels; i++) {
1067 struct hostapd_channel_data *chan = &mode->channels[i];
1068
1069 if (!acs_ch_list_all &&
1070 (hapd->iface->conf->acs_freq_list.num &&
1071 !freq_range_list_includes(
1072 &hapd->iface->conf->acs_freq_list,
1073 chan->freq)))
1074 continue;
1075 if (!acs_ch_list_all &&
1076 (!hapd->iface->conf->acs_freq_list_present &&
1077 hapd->iface->conf->acs_ch_list.num &&
1078 !freq_range_list_includes(
1079 &hapd->iface->conf->acs_ch_list,
1080 chan->chan)))
1081 continue;
1082 if (is_6ghz_freq(chan->freq) &&
1083 ((hapd->iface->conf->acs_exclude_6ghz_non_psc &&
1084 !is_6ghz_psc_frequency(chan->freq)) ||
1085 (!hapd->iface->conf->ieee80211ax &&
1086 !hapd->iface->conf->ieee80211be)))
1087 continue;
1088 if ((!(chan->flag & HOSTAPD_CHAN_DISABLED) || allow_disabled) &&
1089 !(hapd->iface->conf->acs_exclude_dfs &&
1090 (chan->flag & HOSTAPD_CHAN_RADAR)) &&
1091 !(chan->max_tx_power < hapd->iface->conf->min_tx_power))
1092 int_array_add_unique(freq_list, chan->freq);
1093 else if ((chan->flag & HOSTAPD_CHAN_NO_IR) &&
1094 is_6ghz_freq(chan->freq))
1095 is_no_ir = true;
1096 }
1097
1098 hapd->iface->is_no_ir = is_no_ir;
1099 }
1100
1101
hostapd_get_ext_capa(struct hostapd_iface * iface)1102 void hostapd_get_ext_capa(struct hostapd_iface *iface)
1103 {
1104 struct hostapd_data *hapd = iface->bss[0];
1105
1106 if (!hapd->driver || !hapd->driver->get_ext_capab)
1107 return;
1108
1109 hapd->driver->get_ext_capab(hapd->drv_priv, WPA_IF_AP_BSS,
1110 &iface->extended_capa,
1111 &iface->extended_capa_mask,
1112 &iface->extended_capa_len);
1113 }
1114
1115
hostapd_get_mld_capa(struct hostapd_iface * iface)1116 void hostapd_get_mld_capa(struct hostapd_iface *iface)
1117 {
1118 struct hostapd_data *hapd = iface->bss[0];
1119
1120 if (!hapd->driver || !hapd->driver->get_mld_capab)
1121 return;
1122
1123 hapd->driver->get_mld_capab(hapd->drv_priv, WPA_IF_AP_BSS,
1124 &iface->mld_eml_capa,
1125 &iface->mld_mld_capa);
1126 }
1127
1128
1129 /**
1130 * hostapd_drv_do_acs - Start automatic channel selection
1131 * @hapd: BSS data for the device initiating ACS
1132 * Returns: 0 on success, -1 on failure, 1 on failure due to NO_IR (AFC)
1133 */
hostapd_drv_do_acs(struct hostapd_data * hapd)1134 int hostapd_drv_do_acs(struct hostapd_data *hapd)
1135 {
1136 struct drv_acs_params params;
1137 int ret, i, acs_ch_list_all = 0;
1138 struct hostapd_hw_modes *mode;
1139 int *freq_list = NULL;
1140 enum hostapd_hw_mode selected_mode;
1141
1142 if (hapd->driver == NULL || hapd->driver->do_acs == NULL)
1143 return 0;
1144
1145 os_memset(¶ms, 0, sizeof(params));
1146 params.hw_mode = hapd->iface->conf->hw_mode;
1147 params.link_id = -1;
1148 #ifdef CONFIG_IEEE80211BE
1149 if (hapd->conf->mld_ap && hapd->iconf->ieee80211be &&
1150 !hapd->conf->disable_11be)
1151 params.link_id = hapd->mld_link_id;
1152 #endif /* CONFIG_IEEE80211BE */
1153
1154 /*
1155 * If no chanlist config parameter is provided, include all enabled
1156 * channels of the selected hw_mode.
1157 */
1158 if (hapd->iface->conf->acs_freq_list_present)
1159 acs_ch_list_all = !hapd->iface->conf->acs_freq_list.num;
1160 else
1161 acs_ch_list_all = !hapd->iface->conf->acs_ch_list.num;
1162
1163 if (hapd->iface->current_mode)
1164 selected_mode = hapd->iface->current_mode->mode;
1165 else
1166 selected_mode = HOSTAPD_MODE_IEEE80211ANY;
1167
1168 for (i = 0; i < hapd->iface->num_hw_features; i++) {
1169 mode = &hapd->iface->hw_features[i];
1170 if (selected_mode != HOSTAPD_MODE_IEEE80211ANY &&
1171 selected_mode != mode->mode)
1172 continue;
1173 hostapd_get_hw_mode_any_channels(hapd, mode, acs_ch_list_all,
1174 false, &freq_list);
1175 }
1176
1177 if (!freq_list && hapd->iface->is_no_ir) {
1178 wpa_printf(MSG_ERROR,
1179 "NO_IR: Interface freq_list is empty. Failing do_acs.");
1180 return 1;
1181 }
1182
1183 params.freq_list = freq_list;
1184 params.edmg_enabled = hapd->iface->conf->enable_edmg;
1185
1186 params.ht_enabled = !!(hapd->iface->conf->ieee80211n);
1187 params.ht40_enabled = !!(hapd->iface->conf->ht_capab &
1188 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET);
1189 params.vht_enabled = !!(hapd->iface->conf->ieee80211ac);
1190 params.eht_enabled = !!(hapd->iface->conf->ieee80211be);
1191 params.ch_width = 20;
1192 if (hapd->iface->conf->ieee80211n && params.ht40_enabled)
1193 params.ch_width = 40;
1194
1195 /* Note: VHT20 is defined by combination of ht_capab & oper_chwidth
1196 */
1197 if ((hapd->iface->conf->ieee80211be ||
1198 hapd->iface->conf->ieee80211ax ||
1199 hapd->iface->conf->ieee80211ac) &&
1200 params.ht40_enabled) {
1201 enum oper_chan_width oper_chwidth;
1202
1203 oper_chwidth = hostapd_get_oper_chwidth(hapd->iface->conf);
1204 if (oper_chwidth == CONF_OPER_CHWIDTH_80MHZ)
1205 params.ch_width = 80;
1206 else if (oper_chwidth == CONF_OPER_CHWIDTH_160MHZ ||
1207 oper_chwidth == CONF_OPER_CHWIDTH_80P80MHZ)
1208 params.ch_width = 160;
1209 else if (oper_chwidth == CONF_OPER_CHWIDTH_320MHZ)
1210 params.ch_width = 320;
1211 }
1212
1213 if (hapd->iface->conf->op_class)
1214 params.ch_width = op_class_to_bandwidth(
1215 hapd->iface->conf->op_class);
1216 ret = hapd->driver->do_acs(hapd->drv_priv, ¶ms);
1217 os_free(freq_list);
1218
1219 return ret;
1220 }
1221
1222
hostapd_drv_update_dh_ie(struct hostapd_data * hapd,const u8 * peer,u16 reason_code,const u8 * ie,size_t ielen)1223 int hostapd_drv_update_dh_ie(struct hostapd_data *hapd, const u8 *peer,
1224 u16 reason_code, const u8 *ie, size_t ielen)
1225 {
1226 if (!hapd->driver || !hapd->driver->update_dh_ie || !hapd->drv_priv)
1227 return 0;
1228 return hapd->driver->update_dh_ie(hapd->drv_priv, peer, reason_code,
1229 ie, ielen);
1230 }
1231
1232
hostapd_drv_dpp_listen(struct hostapd_data * hapd,bool enable)1233 int hostapd_drv_dpp_listen(struct hostapd_data *hapd, bool enable)
1234 {
1235 if (!hapd->driver || !hapd->driver->dpp_listen || !hapd->drv_priv)
1236 return 0;
1237 return hapd->driver->dpp_listen(hapd->drv_priv, enable);
1238 }
1239
1240
1241 #ifdef CONFIG_PASN
hostapd_drv_set_secure_ranging_ctx(struct hostapd_data * hapd,const u8 * own_addr,const u8 * peer_addr,u32 cipher,u8 tk_len,const u8 * tk,u8 ltf_keyseed_len,const u8 * ltf_keyseed,u32 action)1242 int hostapd_drv_set_secure_ranging_ctx(struct hostapd_data *hapd,
1243 const u8 *own_addr, const u8 *peer_addr,
1244 u32 cipher, u8 tk_len, const u8 *tk,
1245 u8 ltf_keyseed_len,
1246 const u8 *ltf_keyseed, u32 action)
1247 {
1248 struct secure_ranging_params params;
1249
1250 if (!hapd->driver || !hapd->driver->set_secure_ranging_ctx)
1251 return 0;
1252
1253 os_memset(¶ms, 0, sizeof(params));
1254 params.own_addr = own_addr;
1255 params.peer_addr = peer_addr;
1256 params.cipher = cipher;
1257 params.tk_len = tk_len;
1258 params.tk = tk;
1259 params.ltf_keyseed_len = ltf_keyseed_len;
1260 params.ltf_keyseed = ltf_keyseed;
1261 params.action = action;
1262
1263 return hapd->driver->set_secure_ranging_ctx(hapd->drv_priv, ¶ms);
1264 }
1265 #endif /* CONFIG_PASN */
1266