2 * hostapd - Driver operations
3 * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #include "utils/common.h"
12 #include "common/ieee802_11_defs.h"
13 #include "common/hw_features_common.h"
17 #include "ieee802_11.h"
19 #include "ap_config.h"
20 #include "p2p_hostapd.h"
23 #include "ap_drv_ops.h"
26 u32
hostapd_sta_flags_to_drv(u32 flags
)
29 if (flags
& WLAN_STA_AUTHORIZED
)
30 res
|= WPA_STA_AUTHORIZED
;
31 if (flags
& WLAN_STA_WMM
)
33 if (flags
& WLAN_STA_SHORT_PREAMBLE
)
34 res
|= WPA_STA_SHORT_PREAMBLE
;
35 if (flags
& WLAN_STA_MFP
)
37 if (flags
& WLAN_STA_AUTH
)
38 res
|= WPA_STA_AUTHENTICATED
;
39 if (flags
& WLAN_STA_ASSOC
)
40 res
|= WPA_STA_ASSOCIATED
;
45 static int add_buf(struct wpabuf
**dst
, const struct wpabuf
*src
)
49 if (wpabuf_resize(dst
, wpabuf_len(src
)) != 0)
51 wpabuf_put_buf(*dst
, src
);
56 static int add_buf_data(struct wpabuf
**dst
, const u8
*data
, size_t len
)
60 if (wpabuf_resize(dst
, len
) != 0)
62 wpabuf_put_data(*dst
, data
, len
);
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
)
72 struct wpabuf
*beacon
= NULL
, *proberesp
= NULL
, *assocresp
= NULL
;
75 *beacon_ret
= *proberesp_ret
= *assocresp_ret
= NULL
;
78 pos
= hostapd_eid_time_adv(hapd
, pos
);
79 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0)
81 pos
= hostapd_eid_time_zone(hapd
, pos
);
82 if (add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
86 pos
= hostapd_eid_ext_capab(hapd
, pos
);
87 if (add_buf_data(&assocresp
, buf
, pos
- buf
) < 0)
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)
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)
101 #endif /* CONFIG_FST */
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)
108 #endif /* CONFIG_FILS */
110 pos
= hostapd_eid_rsnxe(hapd
, buf
, sizeof(buf
));
111 if (add_buf_data(&assocresp
, buf
, pos
- buf
) < 0)
114 if (add_buf(&beacon
, hapd
->wps_beacon_ie
) < 0 ||
115 add_buf(&proberesp
, hapd
->wps_probe_resp_ie
) < 0)
119 if (add_buf(&beacon
, hapd
->p2p_beacon_ie
) < 0 ||
120 add_buf(&proberesp
, hapd
->p2p_probe_resp_ie
) < 0)
122 #endif /* CONFIG_P2P */
124 #ifdef CONFIG_P2P_MANAGER
125 if (hapd
->conf
->p2p
& P2P_MANAGE
) {
126 if (wpabuf_resize(&beacon
, 100) == 0) {
128 start
= wpabuf_put(beacon
, 0);
129 p
= hostapd_eid_p2p_manage(hapd
, start
);
130 wpabuf_put(beacon
, p
- start
);
133 if (wpabuf_resize(&proberesp
, 100) == 0) {
135 start
= wpabuf_put(proberesp
, 0);
136 p
= hostapd_eid_p2p_manage(hapd
, start
);
137 wpabuf_put(proberesp
, p
- start
);
140 #endif /* CONFIG_P2P_MANAGER */
143 if (hapd
->conf
->wps_state
) {
144 struct wpabuf
*a
= wps_build_assoc_resp_ie();
145 add_buf(&assocresp
, a
);
148 #endif /* CONFIG_WPS */
150 #ifdef CONFIG_P2P_MANAGER
151 if (hapd
->conf
->p2p
& P2P_MANAGE
) {
152 if (wpabuf_resize(&assocresp
, 100) == 0) {
154 start
= wpabuf_put(assocresp
, 0);
155 p
= hostapd_eid_p2p_manage(hapd
, start
);
156 wpabuf_put(assocresp
, p
- start
);
159 #endif /* CONFIG_P2P_MANAGER */
161 #ifdef CONFIG_WIFI_DISPLAY
162 if (hapd
->p2p_group
) {
164 a
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, P2P_SC_SUCCESS
);
165 add_buf(&assocresp
, a
);
168 #endif /* CONFIG_WIFI_DISPLAY */
171 pos
= hostapd_eid_hs20_indication(hapd
, buf
);
172 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
173 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
176 pos
= hostapd_eid_osen(hapd
, buf
);
177 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
178 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
180 #endif /* CONFIG_HS20 */
183 if (hapd
->conf
->mbo_enabled
||
184 OCE_STA_CFON_ENABLED(hapd
) || OCE_AP_ENABLED(hapd
)) {
185 pos
= hostapd_eid_mbo(hapd
, buf
, sizeof(buf
));
186 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
187 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0 ||
188 add_buf_data(&assocresp
, buf
, pos
- buf
) < 0)
191 #endif /* CONFIG_MBO */
194 pos
= hostapd_eid_owe_trans(hapd
, buf
, sizeof(buf
));
195 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
196 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
198 #endif /* CONFIG_OWE */
200 add_buf(&beacon
, hapd
->conf
->vendor_elements
);
201 add_buf(&proberesp
, hapd
->conf
->vendor_elements
);
202 add_buf(&assocresp
, hapd
->conf
->assocresp_elements
);
204 *beacon_ret
= beacon
;
205 *proberesp_ret
= proberesp
;
206 *assocresp_ret
= assocresp
;
212 wpabuf_free(proberesp
);
213 wpabuf_free(assocresp
);
218 void hostapd_free_ap_extra_ies(struct hostapd_data
*hapd
,
219 struct wpabuf
*beacon
,
220 struct wpabuf
*proberesp
,
221 struct wpabuf
*assocresp
)
224 wpabuf_free(proberesp
);
225 wpabuf_free(assocresp
);
229 int hostapd_reset_ap_wps_ie(struct hostapd_data
*hapd
)
231 if (hapd
->driver
== NULL
|| hapd
->driver
->set_ap_wps_ie
== NULL
)
234 return hapd
->driver
->set_ap_wps_ie(hapd
->drv_priv
, NULL
, NULL
, NULL
);
238 int hostapd_set_ap_wps_ie(struct hostapd_data
*hapd
)
240 struct wpabuf
*beacon
, *proberesp
, *assocresp
;
243 if (hapd
->driver
== NULL
|| hapd
->driver
->set_ap_wps_ie
== NULL
)
246 if (hostapd_build_ap_extra_ies(hapd
, &beacon
, &proberesp
, &assocresp
) <
250 ret
= hapd
->driver
->set_ap_wps_ie(hapd
->drv_priv
, beacon
, proberesp
,
253 hostapd_free_ap_extra_ies(hapd
, beacon
, proberesp
, assocresp
);
259 int hostapd_set_authorized(struct hostapd_data
*hapd
,
260 struct sta_info
*sta
, int authorized
)
263 return hostapd_sta_set_flags(hapd
, sta
->addr
,
264 hostapd_sta_flags_to_drv(
266 WPA_STA_AUTHORIZED
, ~0);
269 return hostapd_sta_set_flags(hapd
, sta
->addr
,
270 hostapd_sta_flags_to_drv(sta
->flags
),
271 0, ~WPA_STA_AUTHORIZED
);
275 int hostapd_set_sta_flags(struct hostapd_data
*hapd
, struct sta_info
*sta
)
277 int set_flags
, total_flags
, flags_and
, flags_or
;
278 total_flags
= hostapd_sta_flags_to_drv(sta
->flags
);
279 set_flags
= WPA_STA_SHORT_PREAMBLE
| WPA_STA_WMM
| WPA_STA_MFP
;
280 if (((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
) ||
281 sta
->auth_alg
== WLAN_AUTH_FT
) &&
282 sta
->flags
& WLAN_STA_AUTHORIZED
)
283 set_flags
|= WPA_STA_AUTHORIZED
;
284 flags_or
= total_flags
& set_flags
;
285 flags_and
= total_flags
| ~set_flags
;
286 return hostapd_sta_set_flags(hapd
, sta
->addr
, total_flags
,
287 flags_or
, flags_and
);
291 int hostapd_set_drv_ieee8021x(struct hostapd_data
*hapd
, const char *ifname
,
294 struct wpa_bss_params params
;
295 os_memset(¶ms
, 0, sizeof(params
));
296 params
.ifname
= ifname
;
297 params
.enabled
= enabled
;
299 params
.wpa
= hapd
->conf
->wpa
;
300 params
.ieee802_1x
= hapd
->conf
->ieee802_1x
;
301 params
.wpa_group
= hapd
->conf
->wpa_group
;
302 if ((hapd
->conf
->wpa
& (WPA_PROTO_WPA
| WPA_PROTO_RSN
)) ==
303 (WPA_PROTO_WPA
| WPA_PROTO_RSN
))
304 params
.wpa_pairwise
= hapd
->conf
->wpa_pairwise
|
305 hapd
->conf
->rsn_pairwise
;
306 else if (hapd
->conf
->wpa
& WPA_PROTO_RSN
)
307 params
.wpa_pairwise
= hapd
->conf
->rsn_pairwise
;
308 else if (hapd
->conf
->wpa
& WPA_PROTO_WPA
)
309 params
.wpa_pairwise
= hapd
->conf
->wpa_pairwise
;
310 params
.wpa_key_mgmt
= hapd
->conf
->wpa_key_mgmt
;
311 params
.rsn_preauth
= hapd
->conf
->rsn_preauth
;
312 params
.ieee80211w
= hapd
->conf
->ieee80211w
;
314 return hostapd_set_ieee8021x(hapd
, ¶ms
);
318 int hostapd_vlan_if_add(struct hostapd_data
*hapd
, const char *ifname
)
320 char force_ifname
[IFNAMSIZ
];
321 u8 if_addr
[ETH_ALEN
];
322 return hostapd_if_add(hapd
, WPA_IF_AP_VLAN
, ifname
, hapd
->own_addr
,
323 NULL
, NULL
, force_ifname
, if_addr
, NULL
, 0);
327 int hostapd_vlan_if_remove(struct hostapd_data
*hapd
, const char *ifname
)
329 return hostapd_if_remove(hapd
, WPA_IF_AP_VLAN
, ifname
);
333 int hostapd_set_wds_sta(struct hostapd_data
*hapd
, char *ifname_wds
,
334 const u8
*addr
, int aid
, int val
)
336 const char *bridge
= NULL
;
338 if (hapd
->driver
== NULL
|| hapd
->driver
->set_wds_sta
== NULL
)
340 if (hapd
->conf
->wds_bridge
[0])
341 bridge
= hapd
->conf
->wds_bridge
;
342 else if (hapd
->conf
->bridge
[0])
343 bridge
= hapd
->conf
->bridge
;
344 return hapd
->driver
->set_wds_sta(hapd
->drv_priv
, addr
, aid
, val
,
349 int hostapd_add_sta_node(struct hostapd_data
*hapd
, const u8
*addr
,
352 if (hapd
->driver
== NULL
|| hapd
->driver
->add_sta_node
== NULL
)
354 return hapd
->driver
->add_sta_node(hapd
->drv_priv
, addr
, auth_alg
);
358 int hostapd_sta_auth(struct hostapd_data
*hapd
, const u8
*addr
,
359 u16 seq
, u16 status
, const u8
*ie
, size_t len
)
361 struct wpa_driver_sta_auth_params params
;
363 struct sta_info
*sta
;
364 #endif /* CONFIG_FILS */
366 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_auth
== NULL
)
369 os_memset(¶ms
, 0, sizeof(params
));
372 sta
= ap_get_sta(hapd
, addr
);
374 wpa_printf(MSG_DEBUG
, "Station " MACSTR
375 " not found for sta_auth processing",
380 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
381 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
382 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
383 params
.fils_auth
= 1;
384 wpa_auth_get_fils_aead_params(sta
->wpa_sm
, params
.fils_anonce
,
387 ¶ms
.fils_kek_len
);
389 #endif /* CONFIG_FILS */
391 params
.own_addr
= hapd
->own_addr
;
394 params
.status
= status
;
398 return hapd
->driver
->sta_auth(hapd
->drv_priv
, ¶ms
);
402 int hostapd_sta_assoc(struct hostapd_data
*hapd
, const u8
*addr
,
403 int reassoc
, u16 status
, const u8
*ie
, size_t len
)
405 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_assoc
== NULL
)
407 return hapd
->driver
->sta_assoc(hapd
->drv_priv
, hapd
->own_addr
, addr
,
408 reassoc
, status
, ie
, len
);
412 int hostapd_sta_add(struct hostapd_data
*hapd
,
413 const u8
*addr
, u16 aid
, u16 capability
,
414 const u8
*supp_rates
, size_t supp_rates_len
,
416 const struct ieee80211_ht_capabilities
*ht_capab
,
417 const struct ieee80211_vht_capabilities
*vht_capab
,
418 const struct ieee80211_he_capabilities
*he_capab
,
420 u32 flags
, u8 qosinfo
, u8 vht_opmode
, int supp_p2p_ps
,
423 struct hostapd_sta_add_params params
;
425 if (hapd
->driver
== NULL
)
427 if (hapd
->driver
->sta_add
== NULL
)
430 os_memset(¶ms
, 0, sizeof(params
));
433 params
.capability
= capability
;
434 params
.supp_rates
= supp_rates
;
435 params
.supp_rates_len
= supp_rates_len
;
436 params
.listen_interval
= listen_interval
;
437 params
.ht_capabilities
= ht_capab
;
438 params
.vht_capabilities
= vht_capab
;
439 params
.he_capab
= he_capab
;
440 params
.he_capab_len
= he_capab_len
;
441 params
.vht_opmode_enabled
= !!(flags
& WLAN_STA_VHT_OPMODE_ENABLED
);
442 params
.vht_opmode
= vht_opmode
;
443 params
.flags
= hostapd_sta_flags_to_drv(flags
);
444 params
.qosinfo
= qosinfo
;
445 params
.support_p2p_ps
= supp_p2p_ps
;
447 return hapd
->driver
->sta_add(hapd
->drv_priv
, ¶ms
);
451 int hostapd_add_tspec(struct hostapd_data
*hapd
, const u8
*addr
,
452 u8
*tspec_ie
, size_t tspec_ielen
)
454 if (hapd
->driver
== NULL
|| hapd
->driver
->add_tspec
== NULL
)
456 return hapd
->driver
->add_tspec(hapd
->drv_priv
, addr
, tspec_ie
,
461 int hostapd_set_privacy(struct hostapd_data
*hapd
, int enabled
)
463 if (hapd
->driver
== NULL
|| hapd
->driver
->set_privacy
== NULL
)
465 return hapd
->driver
->set_privacy(hapd
->drv_priv
, enabled
);
469 int hostapd_set_generic_elem(struct hostapd_data
*hapd
, const u8
*elem
,
472 if (hapd
->driver
== NULL
|| hapd
->driver
->set_generic_elem
== NULL
)
474 return hapd
->driver
->set_generic_elem(hapd
->drv_priv
, elem
, elem_len
);
478 int hostapd_get_ssid(struct hostapd_data
*hapd
, u8
*buf
, size_t len
)
480 if (hapd
->driver
== NULL
|| hapd
->driver
->hapd_get_ssid
== NULL
)
482 return hapd
->driver
->hapd_get_ssid(hapd
->drv_priv
, buf
, len
);
486 int hostapd_set_ssid(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
)
488 if (hapd
->driver
== NULL
|| hapd
->driver
->hapd_set_ssid
== NULL
)
490 return hapd
->driver
->hapd_set_ssid(hapd
->drv_priv
, buf
, len
);
494 int hostapd_if_add(struct hostapd_data
*hapd
, enum wpa_driver_if_type type
,
495 const char *ifname
, const u8
*addr
, void *bss_ctx
,
496 void **drv_priv
, char *force_ifname
, u8
*if_addr
,
497 const char *bridge
, int use_existing
)
499 if (hapd
->driver
== NULL
|| hapd
->driver
->if_add
== NULL
)
501 return hapd
->driver
->if_add(hapd
->drv_priv
, type
, ifname
, addr
,
502 bss_ctx
, drv_priv
, force_ifname
, if_addr
,
503 bridge
, use_existing
, 1);
507 int hostapd_if_remove(struct hostapd_data
*hapd
, enum wpa_driver_if_type type
,
510 if (hapd
->driver
== NULL
|| hapd
->drv_priv
== NULL
||
511 hapd
->driver
->if_remove
== NULL
)
513 return hapd
->driver
->if_remove(hapd
->drv_priv
, type
, ifname
);
517 int hostapd_set_ieee8021x(struct hostapd_data
*hapd
,
518 struct wpa_bss_params
*params
)
520 if (hapd
->driver
== NULL
|| hapd
->driver
->set_ieee8021x
== NULL
)
522 return hapd
->driver
->set_ieee8021x(hapd
->drv_priv
, params
);
526 int hostapd_get_seqnum(const char *ifname
, struct hostapd_data
*hapd
,
527 const u8
*addr
, int idx
, u8
*seq
)
529 if (hapd
->driver
== NULL
|| hapd
->driver
->get_seqnum
== NULL
)
531 return hapd
->driver
->get_seqnum(ifname
, hapd
->drv_priv
, addr
, idx
,
536 int hostapd_flush(struct hostapd_data
*hapd
)
538 if (hapd
->driver
== NULL
|| hapd
->driver
->flush
== NULL
)
540 return hapd
->driver
->flush(hapd
->drv_priv
);
544 int hostapd_set_freq(struct hostapd_data
*hapd
, enum hostapd_hw_mode mode
,
545 int freq
, int channel
, int edmg
, u8 edmg_channel
,
546 int ht_enabled
, int vht_enabled
,
548 int sec_channel_offset
, int oper_chwidth
,
549 int center_segment0
, int center_segment1
)
551 struct hostapd_freq_params data
;
552 struct hostapd_hw_modes
*cmode
= hapd
->iface
->current_mode
;
554 if (hostapd_set_freq_params(&data
, mode
, freq
, channel
, edmg
,
555 edmg_channel
, ht_enabled
,
556 vht_enabled
, he_enabled
, sec_channel_offset
,
558 center_segment0
, center_segment1
,
559 cmode
? cmode
->vht_capab
: 0,
561 &cmode
->he_capab
[IEEE80211_MODE_AP
] : NULL
))
564 if (hapd
->driver
== NULL
)
566 if (hapd
->driver
->set_freq
== NULL
)
568 return hapd
->driver
->set_freq(hapd
->drv_priv
, &data
);
571 int hostapd_set_rts(struct hostapd_data
*hapd
, int rts
)
573 if (hapd
->driver
== NULL
|| hapd
->driver
->set_rts
== NULL
)
575 return hapd
->driver
->set_rts(hapd
->drv_priv
, rts
);
579 int hostapd_set_frag(struct hostapd_data
*hapd
, int frag
)
581 if (hapd
->driver
== NULL
|| hapd
->driver
->set_frag
== NULL
)
583 return hapd
->driver
->set_frag(hapd
->drv_priv
, frag
);
587 int hostapd_sta_set_flags(struct hostapd_data
*hapd
, u8
*addr
,
588 int total_flags
, int flags_or
, int flags_and
)
590 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_set_flags
== NULL
)
592 return hapd
->driver
->sta_set_flags(hapd
->drv_priv
, addr
, total_flags
,
593 flags_or
, flags_and
);
597 int hostapd_sta_set_airtime_weight(struct hostapd_data
*hapd
, const u8
*addr
,
600 if (!hapd
->driver
|| !hapd
->driver
->sta_set_airtime_weight
)
602 return hapd
->driver
->sta_set_airtime_weight(hapd
->drv_priv
, addr
,
607 int hostapd_set_country(struct hostapd_data
*hapd
, const char *country
)
609 if (hapd
->driver
== NULL
||
610 hapd
->driver
->set_country
== NULL
)
612 return hapd
->driver
->set_country(hapd
->drv_priv
, country
);
616 int hostapd_set_tx_queue_params(struct hostapd_data
*hapd
, int queue
, int aifs
,
617 int cw_min
, int cw_max
, int burst_time
)
619 if (hapd
->driver
== NULL
|| hapd
->driver
->set_tx_queue_params
== NULL
)
621 return hapd
->driver
->set_tx_queue_params(hapd
->drv_priv
, queue
, aifs
,
622 cw_min
, cw_max
, burst_time
);
626 struct hostapd_hw_modes
*
627 hostapd_get_hw_feature_data(struct hostapd_data
*hapd
, u16
*num_modes
,
628 u16
*flags
, u8
*dfs_domain
)
630 if (hapd
->driver
== NULL
||
631 hapd
->driver
->get_hw_feature_data
== NULL
)
633 return hapd
->driver
->get_hw_feature_data(hapd
->drv_priv
, num_modes
,
638 int hostapd_driver_commit(struct hostapd_data
*hapd
)
640 if (hapd
->driver
== NULL
|| hapd
->driver
->commit
== NULL
)
642 return hapd
->driver
->commit(hapd
->drv_priv
);
646 int hostapd_drv_none(struct hostapd_data
*hapd
)
648 return hapd
->driver
&& os_strcmp(hapd
->driver
->name
, "none") == 0;
652 int hostapd_driver_scan(struct hostapd_data
*hapd
,
653 struct wpa_driver_scan_params
*params
)
655 if (hapd
->driver
&& hapd
->driver
->scan2
)
656 return hapd
->driver
->scan2(hapd
->drv_priv
, params
);
661 struct wpa_scan_results
* hostapd_driver_get_scan_results(
662 struct hostapd_data
*hapd
)
664 if (hapd
->driver
&& hapd
->driver
->get_scan_results2
)
665 return hapd
->driver
->get_scan_results2(hapd
->drv_priv
);
670 int hostapd_driver_set_noa(struct hostapd_data
*hapd
, u8 count
, int start
,
673 if (hapd
->driver
&& hapd
->driver
->set_noa
)
674 return hapd
->driver
->set_noa(hapd
->drv_priv
, count
, start
,
680 int hostapd_drv_set_key(const char *ifname
, struct hostapd_data
*hapd
,
681 enum wpa_alg alg
, const u8
*addr
,
682 int key_idx
, int set_tx
,
683 const u8
*seq
, size_t seq_len
,
684 const u8
*key
, size_t key_len
)
686 if (hapd
->driver
== NULL
|| hapd
->driver
->set_key
== NULL
)
688 return hapd
->driver
->set_key(ifname
, hapd
->drv_priv
, alg
, addr
,
689 key_idx
, set_tx
, seq
, seq_len
, key
,
694 int hostapd_drv_send_mlme(struct hostapd_data
*hapd
,
695 const void *msg
, size_t len
, int noack
)
697 if (!hapd
->driver
|| !hapd
->driver
->send_mlme
|| !hapd
->drv_priv
)
699 return hapd
->driver
->send_mlme(hapd
->drv_priv
, msg
, len
, noack
, 0,
704 int hostapd_drv_send_mlme_csa(struct hostapd_data
*hapd
,
705 const void *msg
, size_t len
, int noack
,
706 const u16
*csa_offs
, size_t csa_offs_len
)
708 if (hapd
->driver
== NULL
|| hapd
->driver
->send_mlme
== NULL
)
710 return hapd
->driver
->send_mlme(hapd
->drv_priv
, msg
, len
, noack
, 0,
711 csa_offs
, csa_offs_len
);
715 int hostapd_drv_sta_deauth(struct hostapd_data
*hapd
,
716 const u8
*addr
, int reason
)
718 if (!hapd
->driver
|| !hapd
->driver
->sta_deauth
|| !hapd
->drv_priv
)
720 return hapd
->driver
->sta_deauth(hapd
->drv_priv
, hapd
->own_addr
, addr
,
725 int hostapd_drv_sta_disassoc(struct hostapd_data
*hapd
,
726 const u8
*addr
, int reason
)
728 if (!hapd
->driver
|| !hapd
->driver
->sta_disassoc
|| !hapd
->drv_priv
)
730 return hapd
->driver
->sta_disassoc(hapd
->drv_priv
, hapd
->own_addr
, addr
,
735 int hostapd_drv_wnm_oper(struct hostapd_data
*hapd
, enum wnm_oper oper
,
736 const u8
*peer
, u8
*buf
, u16
*buf_len
)
738 if (hapd
->driver
== NULL
|| hapd
->driver
->wnm_oper
== NULL
)
740 return hapd
->driver
->wnm_oper(hapd
->drv_priv
, oper
, peer
, buf
,
745 int hostapd_drv_send_action(struct hostapd_data
*hapd
, unsigned int freq
,
746 unsigned int wait
, const u8
*dst
, const u8
*data
,
750 const u8 wildcard_bssid
[ETH_ALEN
] = {
751 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
754 if (!hapd
->driver
|| !hapd
->driver
->send_action
|| !hapd
->drv_priv
)
756 bssid
= hapd
->own_addr
;
757 if (!is_multicast_ether_addr(dst
) &&
758 len
> 0 && data
[0] == WLAN_ACTION_PUBLIC
) {
759 struct sta_info
*sta
;
762 * Public Action frames to a STA that is not a member of the BSS
763 * shall use wildcard BSSID value.
765 sta
= ap_get_sta(hapd
, dst
);
766 if (!sta
|| !(sta
->flags
& WLAN_STA_ASSOC
))
767 bssid
= wildcard_bssid
;
768 } else if (is_broadcast_ether_addr(dst
) &&
769 len
> 0 && data
[0] == WLAN_ACTION_PUBLIC
) {
771 * The only current use case of Public Action frames with
772 * broadcast destination address is DPP PKEX. That case is
773 * directing all devices and not just the STAs within the BSS,
774 * so have to use the wildcard BSSID value.
776 bssid
= wildcard_bssid
;
778 return hapd
->driver
->send_action(hapd
->drv_priv
, freq
, wait
, dst
,
779 hapd
->own_addr
, bssid
, data
, len
, 0);
783 int hostapd_drv_send_action_addr3_ap(struct hostapd_data
*hapd
,
785 unsigned int wait
, const u8
*dst
,
786 const u8
*data
, size_t len
)
788 if (hapd
->driver
== NULL
|| hapd
->driver
->send_action
== NULL
)
790 return hapd
->driver
->send_action(hapd
->drv_priv
, freq
, wait
, dst
,
791 hapd
->own_addr
, hapd
->own_addr
, data
,
796 int hostapd_start_dfs_cac(struct hostapd_iface
*iface
,
797 enum hostapd_hw_mode mode
, int freq
,
798 int channel
, int ht_enabled
, int vht_enabled
,
800 int sec_channel_offset
, int oper_chwidth
,
801 int center_segment0
, int center_segment1
)
803 struct hostapd_data
*hapd
= iface
->bss
[0];
804 struct hostapd_freq_params data
;
806 struct hostapd_hw_modes
*cmode
= iface
->current_mode
;
808 if (!hapd
->driver
|| !hapd
->driver
->start_dfs_cac
|| !cmode
)
811 if (!iface
->conf
->ieee80211h
) {
812 wpa_printf(MSG_ERROR
, "Can't start DFS CAC, DFS functionality "
817 if (hostapd_set_freq_params(&data
, mode
, freq
, channel
, 0, 0,
819 vht_enabled
, he_enabled
, sec_channel_offset
,
820 oper_chwidth
, center_segment0
,
823 &cmode
->he_capab
[IEEE80211_MODE_AP
])) {
824 wpa_printf(MSG_ERROR
, "Can't set freq params");
828 res
= hapd
->driver
->start_dfs_cac(hapd
->drv_priv
, &data
);
830 iface
->cac_started
= 1;
831 os_get_reltime(&iface
->dfs_cac_start
);
838 int hostapd_drv_set_qos_map(struct hostapd_data
*hapd
,
839 const u8
*qos_map_set
, u8 qos_map_set_len
)
841 if (!hapd
->driver
|| !hapd
->driver
->set_qos_map
|| !hapd
->drv_priv
)
843 return hapd
->driver
->set_qos_map(hapd
->drv_priv
, qos_map_set
,
848 static void hostapd_get_hw_mode_any_channels(struct hostapd_data
*hapd
,
849 struct hostapd_hw_modes
*mode
,
855 for (i
= 0; i
< mode
->num_channels
; i
++) {
856 struct hostapd_channel_data
*chan
= &mode
->channels
[i
];
858 if ((acs_ch_list_all
||
859 freq_range_list_includes(&hapd
->iface
->conf
->acs_ch_list
,
861 !(chan
->flag
& HOSTAPD_CHAN_DISABLED
) &&
862 !(hapd
->iface
->conf
->acs_exclude_dfs
&&
863 (chan
->flag
& HOSTAPD_CHAN_RADAR
)))
864 int_array_add_unique(freq_list
, chan
->freq
);
869 void hostapd_get_ext_capa(struct hostapd_iface
*iface
)
871 struct hostapd_data
*hapd
= iface
->bss
[0];
873 if (!hapd
->driver
|| !hapd
->driver
->get_ext_capab
)
876 hapd
->driver
->get_ext_capab(hapd
->drv_priv
, WPA_IF_AP_BSS
,
877 &iface
->extended_capa
,
878 &iface
->extended_capa_mask
,
879 &iface
->extended_capa_len
);
883 int hostapd_drv_do_acs(struct hostapd_data
*hapd
)
885 struct drv_acs_params params
;
886 int ret
, i
, acs_ch_list_all
= 0;
887 struct hostapd_hw_modes
*mode
;
888 int *freq_list
= NULL
;
889 enum hostapd_hw_mode selected_mode
;
891 if (hapd
->driver
== NULL
|| hapd
->driver
->do_acs
== NULL
)
894 os_memset(¶ms
, 0, sizeof(params
));
895 params
.hw_mode
= hapd
->iface
->conf
->hw_mode
;
898 * If no chanlist config parameter is provided, include all enabled
899 * channels of the selected hw_mode.
901 if (!hapd
->iface
->conf
->acs_ch_list
.num
)
904 if (hapd
->iface
->current_mode
)
905 selected_mode
= hapd
->iface
->current_mode
->mode
;
907 selected_mode
= HOSTAPD_MODE_IEEE80211ANY
;
909 for (i
= 0; i
< hapd
->iface
->num_hw_features
; i
++) {
910 mode
= &hapd
->iface
->hw_features
[i
];
911 if (selected_mode
!= HOSTAPD_MODE_IEEE80211ANY
&&
912 selected_mode
!= mode
->mode
)
914 hostapd_get_hw_mode_any_channels(hapd
, mode
, acs_ch_list_all
,
918 params
.freq_list
= freq_list
;
920 params
.ht_enabled
= !!(hapd
->iface
->conf
->ieee80211n
);
921 params
.ht40_enabled
= !!(hapd
->iface
->conf
->ht_capab
&
922 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
);
923 params
.vht_enabled
= !!(hapd
->iface
->conf
->ieee80211ac
);
924 params
.ch_width
= 20;
925 if (hapd
->iface
->conf
->ieee80211n
&& params
.ht40_enabled
)
926 params
.ch_width
= 40;
928 /* Note: VHT20 is defined by combination of ht_capab & oper_chwidth
930 if ((hapd
->iface
->conf
->ieee80211ax
||
931 hapd
->iface
->conf
->ieee80211ac
) &&
932 params
.ht40_enabled
) {
933 u8 oper_chwidth
= hostapd_get_oper_chwidth(hapd
->iface
->conf
);
935 if (oper_chwidth
== CHANWIDTH_80MHZ
)
936 params
.ch_width
= 80;
937 else if (oper_chwidth
== CHANWIDTH_160MHZ
||
938 oper_chwidth
== CHANWIDTH_80P80MHZ
)
939 params
.ch_width
= 160;
942 ret
= hapd
->driver
->do_acs(hapd
->drv_priv
, ¶ms
);
949 int hostapd_drv_update_dh_ie(struct hostapd_data
*hapd
, const u8
*peer
,
950 u16 reason_code
, const u8
*ie
, size_t ielen
)
952 if (!hapd
->driver
|| !hapd
->driver
->update_dh_ie
|| !hapd
->drv_priv
)
954 return hapd
->driver
->update_dh_ie(hapd
->drv_priv
, peer
, reason_code
,