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/ieee802_11_common.h"
14 #include "common/hw_features_common.h"
18 #include "ieee802_11.h"
20 #include "ap_config.h"
21 #include "p2p_hostapd.h"
24 #include "ap_drv_ops.h"
27 u32
hostapd_sta_flags_to_drv(u32 flags
)
30 if (flags
& WLAN_STA_AUTHORIZED
)
31 res
|= WPA_STA_AUTHORIZED
;
32 if (flags
& WLAN_STA_WMM
)
34 if (flags
& WLAN_STA_SHORT_PREAMBLE
)
35 res
|= WPA_STA_SHORT_PREAMBLE
;
36 if (flags
& WLAN_STA_MFP
)
38 if (flags
& WLAN_STA_AUTH
)
39 res
|= WPA_STA_AUTHENTICATED
;
40 if (flags
& WLAN_STA_ASSOC
)
41 res
|= WPA_STA_ASSOCIATED
;
46 static int add_buf(struct wpabuf
**dst
, const struct wpabuf
*src
)
50 if (wpabuf_resize(dst
, wpabuf_len(src
)) != 0)
52 wpabuf_put_buf(*dst
, src
);
57 static int add_buf_data(struct wpabuf
**dst
, const u8
*data
, size_t len
)
61 if (wpabuf_resize(dst
, len
) != 0)
63 wpabuf_put_data(*dst
, data
, len
);
68 int hostapd_build_ap_extra_ies(struct hostapd_data
*hapd
,
69 struct wpabuf
**beacon_ret
,
70 struct wpabuf
**proberesp_ret
,
71 struct wpabuf
**assocresp_ret
)
73 struct wpabuf
*beacon
= NULL
, *proberesp
= NULL
, *assocresp
= NULL
;
76 *beacon_ret
= *proberesp_ret
= *assocresp_ret
= NULL
;
79 pos
= hostapd_eid_time_adv(hapd
, pos
);
80 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0)
82 pos
= hostapd_eid_time_zone(hapd
, pos
);
83 if (add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
87 pos
= hostapd_eid_ext_capab(hapd
, pos
);
88 if (add_buf_data(&assocresp
, buf
, pos
- buf
) < 0)
90 pos
= hostapd_eid_interworking(hapd
, pos
);
91 pos
= hostapd_eid_adv_proto(hapd
, pos
);
92 pos
= hostapd_eid_roaming_consortium(hapd
, pos
);
93 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
94 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
98 if (add_buf(&beacon
, hapd
->iface
->fst_ies
) < 0 ||
99 add_buf(&proberesp
, hapd
->iface
->fst_ies
) < 0 ||
100 add_buf(&assocresp
, hapd
->iface
->fst_ies
) < 0)
102 #endif /* CONFIG_FST */
105 pos
= hostapd_eid_fils_indic(hapd
, buf
, 0);
106 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
107 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
109 #endif /* CONFIG_FILS */
111 pos
= hostapd_eid_rsnxe(hapd
, buf
, sizeof(buf
));
112 if (add_buf_data(&assocresp
, buf
, pos
- buf
) < 0)
115 if (add_buf(&beacon
, hapd
->wps_beacon_ie
) < 0 ||
116 add_buf(&proberesp
, hapd
->wps_probe_resp_ie
) < 0)
120 if (add_buf(&beacon
, hapd
->p2p_beacon_ie
) < 0 ||
121 add_buf(&proberesp
, hapd
->p2p_probe_resp_ie
) < 0)
123 #endif /* CONFIG_P2P */
125 #ifdef CONFIG_P2P_MANAGER
126 if (hapd
->conf
->p2p
& P2P_MANAGE
) {
127 if (wpabuf_resize(&beacon
, 100) == 0) {
129 start
= wpabuf_put(beacon
, 0);
130 p
= hostapd_eid_p2p_manage(hapd
, start
);
131 wpabuf_put(beacon
, p
- start
);
134 if (wpabuf_resize(&proberesp
, 100) == 0) {
136 start
= wpabuf_put(proberesp
, 0);
137 p
= hostapd_eid_p2p_manage(hapd
, start
);
138 wpabuf_put(proberesp
, p
- start
);
141 #endif /* CONFIG_P2P_MANAGER */
144 if (hapd
->conf
->wps_state
) {
145 struct wpabuf
*a
= wps_build_assoc_resp_ie();
146 add_buf(&assocresp
, a
);
149 #endif /* CONFIG_WPS */
151 #ifdef CONFIG_P2P_MANAGER
152 if (hapd
->conf
->p2p
& P2P_MANAGE
) {
153 if (wpabuf_resize(&assocresp
, 100) == 0) {
155 start
= wpabuf_put(assocresp
, 0);
156 p
= hostapd_eid_p2p_manage(hapd
, start
);
157 wpabuf_put(assocresp
, p
- start
);
160 #endif /* CONFIG_P2P_MANAGER */
162 #ifdef CONFIG_WIFI_DISPLAY
163 if (hapd
->p2p_group
) {
165 a
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, P2P_SC_SUCCESS
);
166 add_buf(&assocresp
, a
);
169 #endif /* CONFIG_WIFI_DISPLAY */
172 pos
= hostapd_eid_hs20_indication(hapd
, buf
);
173 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
174 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
177 pos
= hostapd_eid_osen(hapd
, buf
);
178 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
179 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
181 #endif /* CONFIG_HS20 */
184 if (hapd
->conf
->mbo_enabled
||
185 OCE_STA_CFON_ENABLED(hapd
) || OCE_AP_ENABLED(hapd
)) {
186 pos
= hostapd_eid_mbo(hapd
, buf
, sizeof(buf
));
187 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
188 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0 ||
189 add_buf_data(&assocresp
, buf
, pos
- buf
) < 0)
192 #endif /* CONFIG_MBO */
195 pos
= hostapd_eid_owe_trans(hapd
, buf
, sizeof(buf
));
196 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
197 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
199 #endif /* CONFIG_OWE */
201 add_buf(&beacon
, hapd
->conf
->vendor_elements
);
202 add_buf(&proberesp
, hapd
->conf
->vendor_elements
);
203 add_buf(&assocresp
, hapd
->conf
->assocresp_elements
);
205 *beacon_ret
= beacon
;
206 *proberesp_ret
= proberesp
;
207 *assocresp_ret
= assocresp
;
213 wpabuf_free(proberesp
);
214 wpabuf_free(assocresp
);
219 void hostapd_free_ap_extra_ies(struct hostapd_data
*hapd
,
220 struct wpabuf
*beacon
,
221 struct wpabuf
*proberesp
,
222 struct wpabuf
*assocresp
)
225 wpabuf_free(proberesp
);
226 wpabuf_free(assocresp
);
230 int hostapd_reset_ap_wps_ie(struct hostapd_data
*hapd
)
232 if (hapd
->driver
== NULL
|| hapd
->driver
->set_ap_wps_ie
== NULL
)
235 return hapd
->driver
->set_ap_wps_ie(hapd
->drv_priv
, NULL
, NULL
, NULL
);
239 int hostapd_set_ap_wps_ie(struct hostapd_data
*hapd
)
241 struct wpabuf
*beacon
, *proberesp
, *assocresp
;
244 if (hapd
->driver
== NULL
|| hapd
->driver
->set_ap_wps_ie
== NULL
)
247 if (hostapd_build_ap_extra_ies(hapd
, &beacon
, &proberesp
, &assocresp
) <
251 ret
= hapd
->driver
->set_ap_wps_ie(hapd
->drv_priv
, beacon
, proberesp
,
254 hostapd_free_ap_extra_ies(hapd
, beacon
, proberesp
, assocresp
);
260 int hostapd_set_authorized(struct hostapd_data
*hapd
,
261 struct sta_info
*sta
, int authorized
)
264 return hostapd_sta_set_flags(hapd
, sta
->addr
,
265 hostapd_sta_flags_to_drv(
267 WPA_STA_AUTHORIZED
, ~0);
270 return hostapd_sta_set_flags(hapd
, sta
->addr
,
271 hostapd_sta_flags_to_drv(sta
->flags
),
272 0, ~WPA_STA_AUTHORIZED
);
276 int hostapd_set_sta_flags(struct hostapd_data
*hapd
, struct sta_info
*sta
)
278 int set_flags
, total_flags
, flags_and
, flags_or
;
279 total_flags
= hostapd_sta_flags_to_drv(sta
->flags
);
280 set_flags
= WPA_STA_SHORT_PREAMBLE
| WPA_STA_WMM
| WPA_STA_MFP
;
281 if (((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
) ||
282 sta
->auth_alg
== WLAN_AUTH_FT
) &&
283 sta
->flags
& WLAN_STA_AUTHORIZED
)
284 set_flags
|= WPA_STA_AUTHORIZED
;
285 flags_or
= total_flags
& set_flags
;
286 flags_and
= total_flags
| ~set_flags
;
287 return hostapd_sta_set_flags(hapd
, sta
->addr
, total_flags
,
288 flags_or
, flags_and
);
292 int hostapd_set_drv_ieee8021x(struct hostapd_data
*hapd
, const char *ifname
,
295 struct wpa_bss_params params
;
296 os_memset(¶ms
, 0, sizeof(params
));
297 params
.ifname
= ifname
;
298 params
.enabled
= enabled
;
300 params
.wpa
= hapd
->conf
->wpa
;
301 params
.ieee802_1x
= hapd
->conf
->ieee802_1x
;
302 params
.wpa_group
= hapd
->conf
->wpa_group
;
303 if ((hapd
->conf
->wpa
& (WPA_PROTO_WPA
| WPA_PROTO_RSN
)) ==
304 (WPA_PROTO_WPA
| WPA_PROTO_RSN
))
305 params
.wpa_pairwise
= hapd
->conf
->wpa_pairwise
|
306 hapd
->conf
->rsn_pairwise
;
307 else if (hapd
->conf
->wpa
& WPA_PROTO_RSN
)
308 params
.wpa_pairwise
= hapd
->conf
->rsn_pairwise
;
309 else if (hapd
->conf
->wpa
& WPA_PROTO_WPA
)
310 params
.wpa_pairwise
= hapd
->conf
->wpa_pairwise
;
311 params
.wpa_key_mgmt
= hapd
->conf
->wpa_key_mgmt
;
312 params
.rsn_preauth
= hapd
->conf
->rsn_preauth
;
313 params
.ieee80211w
= hapd
->conf
->ieee80211w
;
315 return hostapd_set_ieee8021x(hapd
, ¶ms
);
319 int hostapd_vlan_if_add(struct hostapd_data
*hapd
, const char *ifname
)
321 char force_ifname
[IFNAMSIZ
];
322 u8 if_addr
[ETH_ALEN
];
323 return hostapd_if_add(hapd
, WPA_IF_AP_VLAN
, ifname
, hapd
->own_addr
,
324 NULL
, NULL
, force_ifname
, if_addr
, NULL
, 0);
328 int hostapd_vlan_if_remove(struct hostapd_data
*hapd
, const char *ifname
)
330 return hostapd_if_remove(hapd
, WPA_IF_AP_VLAN
, ifname
);
334 int hostapd_set_wds_sta(struct hostapd_data
*hapd
, char *ifname_wds
,
335 const u8
*addr
, int aid
, int val
)
337 const char *bridge
= NULL
;
339 if (hapd
->driver
== NULL
|| hapd
->driver
->set_wds_sta
== NULL
)
341 if (hapd
->conf
->wds_bridge
[0])
342 bridge
= hapd
->conf
->wds_bridge
;
343 else if (hapd
->conf
->bridge
[0])
344 bridge
= hapd
->conf
->bridge
;
345 return hapd
->driver
->set_wds_sta(hapd
->drv_priv
, addr
, aid
, val
,
350 int hostapd_add_sta_node(struct hostapd_data
*hapd
, const u8
*addr
,
353 if (hapd
->driver
== NULL
|| hapd
->driver
->add_sta_node
== NULL
)
355 return hapd
->driver
->add_sta_node(hapd
->drv_priv
, addr
, auth_alg
);
359 int hostapd_sta_auth(struct hostapd_data
*hapd
, const u8
*addr
,
360 u16 seq
, u16 status
, const u8
*ie
, size_t len
)
362 struct wpa_driver_sta_auth_params params
;
364 struct sta_info
*sta
;
365 #endif /* CONFIG_FILS */
367 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_auth
== NULL
)
370 os_memset(¶ms
, 0, sizeof(params
));
373 sta
= ap_get_sta(hapd
, addr
);
375 wpa_printf(MSG_DEBUG
, "Station " MACSTR
376 " not found for sta_auth processing",
381 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
382 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
383 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
384 params
.fils_auth
= 1;
385 wpa_auth_get_fils_aead_params(sta
->wpa_sm
, params
.fils_anonce
,
388 ¶ms
.fils_kek_len
);
390 #endif /* CONFIG_FILS */
392 params
.own_addr
= hapd
->own_addr
;
395 params
.status
= status
;
399 return hapd
->driver
->sta_auth(hapd
->drv_priv
, ¶ms
);
403 int hostapd_sta_assoc(struct hostapd_data
*hapd
, const u8
*addr
,
404 int reassoc
, u16 status
, const u8
*ie
, size_t len
)
406 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_assoc
== NULL
)
408 return hapd
->driver
->sta_assoc(hapd
->drv_priv
, hapd
->own_addr
, addr
,
409 reassoc
, status
, ie
, len
);
413 int hostapd_sta_add(struct hostapd_data
*hapd
,
414 const u8
*addr
, u16 aid
, u16 capability
,
415 const u8
*supp_rates
, size_t supp_rates_len
,
417 const struct ieee80211_ht_capabilities
*ht_capab
,
418 const struct ieee80211_vht_capabilities
*vht_capab
,
419 const struct ieee80211_he_capabilities
*he_capab
,
421 u32 flags
, u8 qosinfo
, u8 vht_opmode
, int supp_p2p_ps
,
424 struct hostapd_sta_add_params params
;
426 if (hapd
->driver
== NULL
)
428 if (hapd
->driver
->sta_add
== NULL
)
431 os_memset(¶ms
, 0, sizeof(params
));
434 params
.capability
= capability
;
435 params
.supp_rates
= supp_rates
;
436 params
.supp_rates_len
= supp_rates_len
;
437 params
.listen_interval
= listen_interval
;
438 params
.ht_capabilities
= ht_capab
;
439 params
.vht_capabilities
= vht_capab
;
440 params
.he_capab
= he_capab
;
441 params
.he_capab_len
= he_capab_len
;
442 params
.vht_opmode_enabled
= !!(flags
& WLAN_STA_VHT_OPMODE_ENABLED
);
443 params
.vht_opmode
= vht_opmode
;
444 params
.flags
= hostapd_sta_flags_to_drv(flags
);
445 params
.qosinfo
= qosinfo
;
446 params
.support_p2p_ps
= supp_p2p_ps
;
448 return hapd
->driver
->sta_add(hapd
->drv_priv
, ¶ms
);
452 int hostapd_add_tspec(struct hostapd_data
*hapd
, const u8
*addr
,
453 u8
*tspec_ie
, size_t tspec_ielen
)
455 if (hapd
->driver
== NULL
|| hapd
->driver
->add_tspec
== NULL
)
457 return hapd
->driver
->add_tspec(hapd
->drv_priv
, addr
, tspec_ie
,
462 int hostapd_set_privacy(struct hostapd_data
*hapd
, int enabled
)
464 if (hapd
->driver
== NULL
|| hapd
->driver
->set_privacy
== NULL
)
466 return hapd
->driver
->set_privacy(hapd
->drv_priv
, enabled
);
470 int hostapd_set_generic_elem(struct hostapd_data
*hapd
, const u8
*elem
,
473 if (hapd
->driver
== NULL
|| hapd
->driver
->set_generic_elem
== NULL
)
475 return hapd
->driver
->set_generic_elem(hapd
->drv_priv
, elem
, elem_len
);
479 int hostapd_get_ssid(struct hostapd_data
*hapd
, u8
*buf
, size_t len
)
481 if (hapd
->driver
== NULL
|| hapd
->driver
->hapd_get_ssid
== NULL
)
483 return hapd
->driver
->hapd_get_ssid(hapd
->drv_priv
, buf
, len
);
487 int hostapd_set_ssid(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
)
489 if (hapd
->driver
== NULL
|| hapd
->driver
->hapd_set_ssid
== NULL
)
491 return hapd
->driver
->hapd_set_ssid(hapd
->drv_priv
, buf
, len
);
495 int hostapd_if_add(struct hostapd_data
*hapd
, enum wpa_driver_if_type type
,
496 const char *ifname
, const u8
*addr
, void *bss_ctx
,
497 void **drv_priv
, char *force_ifname
, u8
*if_addr
,
498 const char *bridge
, int use_existing
)
500 if (hapd
->driver
== NULL
|| hapd
->driver
->if_add
== NULL
)
502 return hapd
->driver
->if_add(hapd
->drv_priv
, type
, ifname
, addr
,
503 bss_ctx
, drv_priv
, force_ifname
, if_addr
,
504 bridge
, use_existing
, 1);
508 int hostapd_if_remove(struct hostapd_data
*hapd
, enum wpa_driver_if_type type
,
511 if (hapd
->driver
== NULL
|| hapd
->drv_priv
== NULL
||
512 hapd
->driver
->if_remove
== NULL
)
514 return hapd
->driver
->if_remove(hapd
->drv_priv
, type
, ifname
);
518 int hostapd_set_ieee8021x(struct hostapd_data
*hapd
,
519 struct wpa_bss_params
*params
)
521 if (hapd
->driver
== NULL
|| hapd
->driver
->set_ieee8021x
== NULL
)
523 return hapd
->driver
->set_ieee8021x(hapd
->drv_priv
, params
);
527 int hostapd_get_seqnum(const char *ifname
, struct hostapd_data
*hapd
,
528 const u8
*addr
, int idx
, u8
*seq
)
530 if (hapd
->driver
== NULL
|| hapd
->driver
->get_seqnum
== NULL
)
532 return hapd
->driver
->get_seqnum(ifname
, hapd
->drv_priv
, addr
, idx
,
537 int hostapd_flush(struct hostapd_data
*hapd
)
539 if (hapd
->driver
== NULL
|| hapd
->driver
->flush
== NULL
)
541 return hapd
->driver
->flush(hapd
->drv_priv
);
545 int hostapd_set_freq(struct hostapd_data
*hapd
, enum hostapd_hw_mode mode
,
546 int freq
, int channel
, int edmg
, u8 edmg_channel
,
547 int ht_enabled
, int vht_enabled
,
549 int sec_channel_offset
, int oper_chwidth
,
550 int center_segment0
, int center_segment1
)
552 struct hostapd_freq_params data
;
553 struct hostapd_hw_modes
*cmode
= hapd
->iface
->current_mode
;
555 if (hostapd_set_freq_params(&data
, mode
, freq
, channel
, edmg
,
556 edmg_channel
, ht_enabled
,
557 vht_enabled
, he_enabled
, sec_channel_offset
,
559 center_segment0
, center_segment1
,
560 cmode
? cmode
->vht_capab
: 0,
562 &cmode
->he_capab
[IEEE80211_MODE_AP
] : NULL
))
565 if (hapd
->driver
== NULL
)
567 if (hapd
->driver
->set_freq
== NULL
)
569 return hapd
->driver
->set_freq(hapd
->drv_priv
, &data
);
572 int hostapd_set_rts(struct hostapd_data
*hapd
, int rts
)
574 if (hapd
->driver
== NULL
|| hapd
->driver
->set_rts
== NULL
)
576 return hapd
->driver
->set_rts(hapd
->drv_priv
, rts
);
580 int hostapd_set_frag(struct hostapd_data
*hapd
, int frag
)
582 if (hapd
->driver
== NULL
|| hapd
->driver
->set_frag
== NULL
)
584 return hapd
->driver
->set_frag(hapd
->drv_priv
, frag
);
588 int hostapd_sta_set_flags(struct hostapd_data
*hapd
, u8
*addr
,
589 int total_flags
, int flags_or
, int flags_and
)
591 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_set_flags
== NULL
)
593 return hapd
->driver
->sta_set_flags(hapd
->drv_priv
, addr
, total_flags
,
594 flags_or
, flags_and
);
598 int hostapd_sta_set_airtime_weight(struct hostapd_data
*hapd
, const u8
*addr
,
601 if (!hapd
->driver
|| !hapd
->driver
->sta_set_airtime_weight
)
603 return hapd
->driver
->sta_set_airtime_weight(hapd
->drv_priv
, addr
,
608 int hostapd_set_country(struct hostapd_data
*hapd
, const char *country
)
610 if (hapd
->driver
== NULL
||
611 hapd
->driver
->set_country
== NULL
)
613 return hapd
->driver
->set_country(hapd
->drv_priv
, country
);
617 int hostapd_set_tx_queue_params(struct hostapd_data
*hapd
, int queue
, int aifs
,
618 int cw_min
, int cw_max
, int burst_time
)
620 if (hapd
->driver
== NULL
|| hapd
->driver
->set_tx_queue_params
== NULL
)
622 return hapd
->driver
->set_tx_queue_params(hapd
->drv_priv
, queue
, aifs
,
623 cw_min
, cw_max
, burst_time
);
627 struct hostapd_hw_modes
*
628 hostapd_get_hw_feature_data(struct hostapd_data
*hapd
, u16
*num_modes
,
629 u16
*flags
, u8
*dfs_domain
)
631 if (hapd
->driver
== NULL
||
632 hapd
->driver
->get_hw_feature_data
== NULL
)
634 return hapd
->driver
->get_hw_feature_data(hapd
->drv_priv
, num_modes
,
639 int hostapd_driver_commit(struct hostapd_data
*hapd
)
641 if (hapd
->driver
== NULL
|| hapd
->driver
->commit
== NULL
)
643 return hapd
->driver
->commit(hapd
->drv_priv
);
647 int hostapd_drv_none(struct hostapd_data
*hapd
)
649 return hapd
->driver
&& os_strcmp(hapd
->driver
->name
, "none") == 0;
653 int hostapd_driver_scan(struct hostapd_data
*hapd
,
654 struct wpa_driver_scan_params
*params
)
656 if (hapd
->driver
&& hapd
->driver
->scan2
)
657 return hapd
->driver
->scan2(hapd
->drv_priv
, params
);
662 struct wpa_scan_results
* hostapd_driver_get_scan_results(
663 struct hostapd_data
*hapd
)
665 if (hapd
->driver
&& hapd
->driver
->get_scan_results2
)
666 return hapd
->driver
->get_scan_results2(hapd
->drv_priv
);
671 int hostapd_driver_set_noa(struct hostapd_data
*hapd
, u8 count
, int start
,
674 if (hapd
->driver
&& hapd
->driver
->set_noa
)
675 return hapd
->driver
->set_noa(hapd
->drv_priv
, count
, start
,
681 int hostapd_drv_set_key(const char *ifname
, struct hostapd_data
*hapd
,
682 enum wpa_alg alg
, const u8
*addr
,
683 int key_idx
, int vlan_id
, int set_tx
,
684 const u8
*seq
, size_t seq_len
,
685 const u8
*key
, size_t key_len
, enum key_flag key_flag
)
687 struct wpa_driver_set_key_params params
;
689 if (hapd
->driver
== NULL
|| hapd
->driver
->set_key
== NULL
)
692 os_memset(¶ms
, 0, sizeof(params
));
693 params
.ifname
= ifname
;
696 params
.key_idx
= key_idx
;
697 params
.set_tx
= set_tx
;
699 params
.seq_len
= seq_len
;
701 params
.key_len
= key_len
;
702 params
.vlan_id
= vlan_id
;
703 params
.key_flag
= key_flag
;
705 return hapd
->driver
->set_key(hapd
->drv_priv
, ¶ms
);
709 int hostapd_drv_send_mlme(struct hostapd_data
*hapd
,
710 const void *msg
, size_t len
, int noack
,
711 const u16
*csa_offs
, size_t csa_offs_len
,
714 if (!hapd
->driver
|| !hapd
->driver
->send_mlme
|| !hapd
->drv_priv
)
716 return hapd
->driver
->send_mlme(hapd
->drv_priv
, msg
, len
, noack
, 0,
717 csa_offs
, csa_offs_len
, no_encrypt
, 0);
721 int hostapd_drv_sta_deauth(struct hostapd_data
*hapd
,
722 const u8
*addr
, int reason
)
724 if (!hapd
->driver
|| !hapd
->driver
->sta_deauth
|| !hapd
->drv_priv
)
726 return hapd
->driver
->sta_deauth(hapd
->drv_priv
, hapd
->own_addr
, addr
,
731 int hostapd_drv_sta_disassoc(struct hostapd_data
*hapd
,
732 const u8
*addr
, int reason
)
734 if (!hapd
->driver
|| !hapd
->driver
->sta_disassoc
|| !hapd
->drv_priv
)
736 return hapd
->driver
->sta_disassoc(hapd
->drv_priv
, hapd
->own_addr
, addr
,
741 int hostapd_drv_wnm_oper(struct hostapd_data
*hapd
, enum wnm_oper oper
,
742 const u8
*peer
, u8
*buf
, u16
*buf_len
)
744 if (hapd
->driver
== NULL
|| hapd
->driver
->wnm_oper
== NULL
)
746 return hapd
->driver
->wnm_oper(hapd
->drv_priv
, oper
, peer
, buf
,
751 int hostapd_drv_send_action(struct hostapd_data
*hapd
, unsigned int freq
,
752 unsigned int wait
, const u8
*dst
, const u8
*data
,
756 const u8 wildcard_bssid
[ETH_ALEN
] = {
757 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
760 if (!hapd
->driver
|| !hapd
->driver
->send_action
|| !hapd
->drv_priv
)
762 bssid
= hapd
->own_addr
;
763 if (!is_multicast_ether_addr(dst
) &&
764 len
> 0 && data
[0] == WLAN_ACTION_PUBLIC
) {
765 struct sta_info
*sta
;
768 * Public Action frames to a STA that is not a member of the BSS
769 * shall use wildcard BSSID value.
771 sta
= ap_get_sta(hapd
, dst
);
772 if (!sta
|| !(sta
->flags
& WLAN_STA_ASSOC
))
773 bssid
= wildcard_bssid
;
774 } else if (is_broadcast_ether_addr(dst
) &&
775 len
> 0 && data
[0] == WLAN_ACTION_PUBLIC
) {
777 * The only current use case of Public Action frames with
778 * broadcast destination address is DPP PKEX. That case is
779 * directing all devices and not just the STAs within the BSS,
780 * so have to use the wildcard BSSID value.
782 bssid
= wildcard_bssid
;
784 return hapd
->driver
->send_action(hapd
->drv_priv
, freq
, wait
, dst
,
785 hapd
->own_addr
, bssid
, data
, len
, 0);
789 int hostapd_drv_send_action_addr3_ap(struct hostapd_data
*hapd
,
791 unsigned int wait
, const u8
*dst
,
792 const u8
*data
, size_t len
)
794 if (hapd
->driver
== NULL
|| hapd
->driver
->send_action
== NULL
)
796 return hapd
->driver
->send_action(hapd
->drv_priv
, freq
, wait
, dst
,
797 hapd
->own_addr
, hapd
->own_addr
, data
,
802 int hostapd_start_dfs_cac(struct hostapd_iface
*iface
,
803 enum hostapd_hw_mode mode
, int freq
,
804 int channel
, int ht_enabled
, int vht_enabled
,
806 int sec_channel_offset
, int oper_chwidth
,
807 int center_segment0
, int center_segment1
)
809 struct hostapd_data
*hapd
= iface
->bss
[0];
810 struct hostapd_freq_params data
;
812 struct hostapd_hw_modes
*cmode
= iface
->current_mode
;
814 if (!hapd
->driver
|| !hapd
->driver
->start_dfs_cac
|| !cmode
)
817 if (!iface
->conf
->ieee80211h
) {
818 wpa_printf(MSG_ERROR
, "Can't start DFS CAC, DFS functionality "
823 if (hostapd_set_freq_params(&data
, mode
, freq
, channel
, 0, 0,
825 vht_enabled
, he_enabled
, sec_channel_offset
,
826 oper_chwidth
, center_segment0
,
829 &cmode
->he_capab
[IEEE80211_MODE_AP
])) {
830 wpa_printf(MSG_ERROR
, "Can't set freq params");
834 res
= hapd
->driver
->start_dfs_cac(hapd
->drv_priv
, &data
);
836 iface
->cac_started
= 1;
837 os_get_reltime(&iface
->dfs_cac_start
);
844 int hostapd_drv_set_qos_map(struct hostapd_data
*hapd
,
845 const u8
*qos_map_set
, u8 qos_map_set_len
)
847 if (!hapd
->driver
|| !hapd
->driver
->set_qos_map
|| !hapd
->drv_priv
)
849 return hapd
->driver
->set_qos_map(hapd
->drv_priv
, qos_map_set
,
854 static void hostapd_get_hw_mode_any_channels(struct hostapd_data
*hapd
,
855 struct hostapd_hw_modes
*mode
,
861 for (i
= 0; i
< mode
->num_channels
; i
++) {
862 struct hostapd_channel_data
*chan
= &mode
->channels
[i
];
864 if (!acs_ch_list_all
&&
865 (hapd
->iface
->conf
->acs_freq_list
.num
&&
866 !freq_range_list_includes(
867 &hapd
->iface
->conf
->acs_freq_list
,
870 if (!acs_ch_list_all
&&
871 (!hapd
->iface
->conf
->acs_freq_list_present
&&
872 hapd
->iface
->conf
->acs_ch_list
.num
&&
873 !freq_range_list_includes(
874 &hapd
->iface
->conf
->acs_ch_list
,
877 if (is_6ghz_freq(chan
->freq
) &&
878 hapd
->iface
->conf
->acs_exclude_6ghz_non_psc
&&
879 !is_6ghz_psc_frequency(chan
->freq
))
881 if (!(chan
->flag
& HOSTAPD_CHAN_DISABLED
) &&
882 !(hapd
->iface
->conf
->acs_exclude_dfs
&&
883 (chan
->flag
& HOSTAPD_CHAN_RADAR
)))
884 int_array_add_unique(freq_list
, chan
->freq
);
889 void hostapd_get_ext_capa(struct hostapd_iface
*iface
)
891 struct hostapd_data
*hapd
= iface
->bss
[0];
893 if (!hapd
->driver
|| !hapd
->driver
->get_ext_capab
)
896 hapd
->driver
->get_ext_capab(hapd
->drv_priv
, WPA_IF_AP_BSS
,
897 &iface
->extended_capa
,
898 &iface
->extended_capa_mask
,
899 &iface
->extended_capa_len
);
903 int hostapd_drv_do_acs(struct hostapd_data
*hapd
)
905 struct drv_acs_params params
;
906 int ret
, i
, acs_ch_list_all
= 0;
907 struct hostapd_hw_modes
*mode
;
908 int *freq_list
= NULL
;
909 enum hostapd_hw_mode selected_mode
;
911 if (hapd
->driver
== NULL
|| hapd
->driver
->do_acs
== NULL
)
914 os_memset(¶ms
, 0, sizeof(params
));
915 params
.hw_mode
= hapd
->iface
->conf
->hw_mode
;
918 * If no chanlist config parameter is provided, include all enabled
919 * channels of the selected hw_mode.
921 if (hapd
->iface
->conf
->acs_freq_list_present
)
922 acs_ch_list_all
= !hapd
->iface
->conf
->acs_freq_list
.num
;
924 acs_ch_list_all
= !hapd
->iface
->conf
->acs_ch_list
.num
;
926 if (hapd
->iface
->current_mode
)
927 selected_mode
= hapd
->iface
->current_mode
->mode
;
929 selected_mode
= HOSTAPD_MODE_IEEE80211ANY
;
931 for (i
= 0; i
< hapd
->iface
->num_hw_features
; i
++) {
932 mode
= &hapd
->iface
->hw_features
[i
];
933 if (selected_mode
!= HOSTAPD_MODE_IEEE80211ANY
&&
934 selected_mode
!= mode
->mode
)
936 hostapd_get_hw_mode_any_channels(hapd
, mode
, acs_ch_list_all
,
940 params
.freq_list
= freq_list
;
942 params
.ht_enabled
= !!(hapd
->iface
->conf
->ieee80211n
);
943 params
.ht40_enabled
= !!(hapd
->iface
->conf
->ht_capab
&
944 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
);
945 params
.vht_enabled
= !!(hapd
->iface
->conf
->ieee80211ac
);
946 params
.ch_width
= 20;
947 if (hapd
->iface
->conf
->ieee80211n
&& params
.ht40_enabled
)
948 params
.ch_width
= 40;
950 /* Note: VHT20 is defined by combination of ht_capab & oper_chwidth
952 if ((hapd
->iface
->conf
->ieee80211ax
||
953 hapd
->iface
->conf
->ieee80211ac
) &&
954 params
.ht40_enabled
) {
955 u8 oper_chwidth
= hostapd_get_oper_chwidth(hapd
->iface
->conf
);
957 if (oper_chwidth
== CHANWIDTH_80MHZ
)
958 params
.ch_width
= 80;
959 else if (oper_chwidth
== CHANWIDTH_160MHZ
||
960 oper_chwidth
== CHANWIDTH_80P80MHZ
)
961 params
.ch_width
= 160;
964 if (hapd
->iface
->conf
->op_class
)
965 params
.ch_width
= op_class_to_bandwidth(
966 hapd
->iface
->conf
->op_class
);
967 ret
= hapd
->driver
->do_acs(hapd
->drv_priv
, ¶ms
);
974 int hostapd_drv_update_dh_ie(struct hostapd_data
*hapd
, const u8
*peer
,
975 u16 reason_code
, const u8
*ie
, size_t ielen
)
977 if (!hapd
->driver
|| !hapd
->driver
->update_dh_ie
|| !hapd
->drv_priv
)
979 return hapd
->driver
->update_dh_ie(hapd
->drv_priv
, peer
, reason_code
,