xref: /freebsd/contrib/wpa/src/ap/ap_drv_ops.c (revision f05cddf940dbfc5b657f5e9beb9de2c31e509e5b)
1e28a4053SRui Paulo /*
2e28a4053SRui Paulo  * hostapd - Driver operations
3e28a4053SRui Paulo  * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
4e28a4053SRui Paulo  *
5*f05cddf9SRui Paulo  * This software may be distributed under the terms of the BSD license.
6*f05cddf9SRui Paulo  * See README for more details.
7e28a4053SRui Paulo  */
8e28a4053SRui Paulo 
9e28a4053SRui Paulo #include "utils/includes.h"
10e28a4053SRui Paulo 
11e28a4053SRui Paulo #include "utils/common.h"
12e28a4053SRui Paulo #include "drivers/driver.h"
13e28a4053SRui Paulo #include "common/ieee802_11_defs.h"
14*f05cddf9SRui Paulo #include "wps/wps.h"
15*f05cddf9SRui Paulo #include "p2p/p2p.h"
16e28a4053SRui Paulo #include "hostapd.h"
17e28a4053SRui Paulo #include "ieee802_11.h"
18e28a4053SRui Paulo #include "sta_info.h"
19e28a4053SRui Paulo #include "ap_config.h"
20*f05cddf9SRui Paulo #include "p2p_hostapd.h"
21*f05cddf9SRui Paulo #include "hs20.h"
22e28a4053SRui Paulo #include "ap_drv_ops.h"
23e28a4053SRui Paulo 
24e28a4053SRui Paulo 
25*f05cddf9SRui Paulo u32 hostapd_sta_flags_to_drv(u32 flags)
26e28a4053SRui Paulo {
27e28a4053SRui Paulo 	int res = 0;
28e28a4053SRui Paulo 	if (flags & WLAN_STA_AUTHORIZED)
29e28a4053SRui Paulo 		res |= WPA_STA_AUTHORIZED;
30e28a4053SRui Paulo 	if (flags & WLAN_STA_WMM)
31e28a4053SRui Paulo 		res |= WPA_STA_WMM;
32e28a4053SRui Paulo 	if (flags & WLAN_STA_SHORT_PREAMBLE)
33e28a4053SRui Paulo 		res |= WPA_STA_SHORT_PREAMBLE;
34e28a4053SRui Paulo 	if (flags & WLAN_STA_MFP)
35e28a4053SRui Paulo 		res |= WPA_STA_MFP;
36e28a4053SRui Paulo 	return res;
37e28a4053SRui Paulo }
38e28a4053SRui Paulo 
39e28a4053SRui Paulo 
40*f05cddf9SRui Paulo int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
41*f05cddf9SRui Paulo 			       struct wpabuf **beacon_ret,
42*f05cddf9SRui Paulo 			       struct wpabuf **proberesp_ret,
43*f05cddf9SRui Paulo 			       struct wpabuf **assocresp_ret)
44e28a4053SRui Paulo {
45*f05cddf9SRui Paulo 	struct wpabuf *beacon = NULL, *proberesp = NULL, *assocresp = NULL;
46*f05cddf9SRui Paulo 	u8 buf[200], *pos;
47*f05cddf9SRui Paulo 
48*f05cddf9SRui Paulo 	*beacon_ret = *proberesp_ret = *assocresp_ret = NULL;
49*f05cddf9SRui Paulo 
50*f05cddf9SRui Paulo 	pos = buf;
51*f05cddf9SRui Paulo 	pos = hostapd_eid_time_adv(hapd, pos);
52*f05cddf9SRui Paulo 	if (pos != buf) {
53*f05cddf9SRui Paulo 		if (wpabuf_resize(&beacon, pos - buf) != 0)
54*f05cddf9SRui Paulo 			goto fail;
55*f05cddf9SRui Paulo 		wpabuf_put_data(beacon, buf, pos - buf);
56*f05cddf9SRui Paulo 	}
57*f05cddf9SRui Paulo 	pos = hostapd_eid_time_zone(hapd, pos);
58*f05cddf9SRui Paulo 	if (pos != buf) {
59*f05cddf9SRui Paulo 		if (wpabuf_resize(&proberesp, pos - buf) != 0)
60*f05cddf9SRui Paulo 			goto fail;
61*f05cddf9SRui Paulo 		wpabuf_put_data(proberesp, buf, pos - buf);
62*f05cddf9SRui Paulo 	}
63*f05cddf9SRui Paulo 
64*f05cddf9SRui Paulo 	pos = buf;
65*f05cddf9SRui Paulo 	pos = hostapd_eid_ext_capab(hapd, pos);
66*f05cddf9SRui Paulo 	if (pos != buf) {
67*f05cddf9SRui Paulo 		if (wpabuf_resize(&assocresp, pos - buf) != 0)
68*f05cddf9SRui Paulo 			goto fail;
69*f05cddf9SRui Paulo 		wpabuf_put_data(assocresp, buf, pos - buf);
70*f05cddf9SRui Paulo 	}
71*f05cddf9SRui Paulo 	pos = hostapd_eid_interworking(hapd, pos);
72*f05cddf9SRui Paulo 	pos = hostapd_eid_adv_proto(hapd, pos);
73*f05cddf9SRui Paulo 	pos = hostapd_eid_roaming_consortium(hapd, pos);
74*f05cddf9SRui Paulo 	if (pos != buf) {
75*f05cddf9SRui Paulo 		if (wpabuf_resize(&beacon, pos - buf) != 0)
76*f05cddf9SRui Paulo 			goto fail;
77*f05cddf9SRui Paulo 		wpabuf_put_data(beacon, buf, pos - buf);
78*f05cddf9SRui Paulo 
79*f05cddf9SRui Paulo 		if (wpabuf_resize(&proberesp, pos - buf) != 0)
80*f05cddf9SRui Paulo 			goto fail;
81*f05cddf9SRui Paulo 		wpabuf_put_data(proberesp, buf, pos - buf);
82*f05cddf9SRui Paulo 	}
83*f05cddf9SRui Paulo 
84*f05cddf9SRui Paulo 	if (hapd->wps_beacon_ie) {
85*f05cddf9SRui Paulo 		if (wpabuf_resize(&beacon, wpabuf_len(hapd->wps_beacon_ie)) <
86*f05cddf9SRui Paulo 		    0)
87*f05cddf9SRui Paulo 			goto fail;
88*f05cddf9SRui Paulo 		wpabuf_put_buf(beacon, hapd->wps_beacon_ie);
89*f05cddf9SRui Paulo 	}
90*f05cddf9SRui Paulo 
91*f05cddf9SRui Paulo 	if (hapd->wps_probe_resp_ie) {
92*f05cddf9SRui Paulo 		if (wpabuf_resize(&proberesp,
93*f05cddf9SRui Paulo 				  wpabuf_len(hapd->wps_probe_resp_ie)) < 0)
94*f05cddf9SRui Paulo 			goto fail;
95*f05cddf9SRui Paulo 		wpabuf_put_buf(proberesp, hapd->wps_probe_resp_ie);
96*f05cddf9SRui Paulo 	}
97*f05cddf9SRui Paulo 
98*f05cddf9SRui Paulo #ifdef CONFIG_P2P
99*f05cddf9SRui Paulo 	if (hapd->p2p_beacon_ie) {
100*f05cddf9SRui Paulo 		if (wpabuf_resize(&beacon, wpabuf_len(hapd->p2p_beacon_ie)) <
101*f05cddf9SRui Paulo 		    0)
102*f05cddf9SRui Paulo 			goto fail;
103*f05cddf9SRui Paulo 		wpabuf_put_buf(beacon, hapd->p2p_beacon_ie);
104*f05cddf9SRui Paulo 	}
105*f05cddf9SRui Paulo 
106*f05cddf9SRui Paulo 	if (hapd->p2p_probe_resp_ie) {
107*f05cddf9SRui Paulo 		if (wpabuf_resize(&proberesp,
108*f05cddf9SRui Paulo 				  wpabuf_len(hapd->p2p_probe_resp_ie)) < 0)
109*f05cddf9SRui Paulo 			goto fail;
110*f05cddf9SRui Paulo 		wpabuf_put_buf(proberesp, hapd->p2p_probe_resp_ie);
111*f05cddf9SRui Paulo 	}
112*f05cddf9SRui Paulo #endif /* CONFIG_P2P */
113*f05cddf9SRui Paulo 
114*f05cddf9SRui Paulo #ifdef CONFIG_P2P_MANAGER
115*f05cddf9SRui Paulo 	if (hapd->conf->p2p & P2P_MANAGE) {
116*f05cddf9SRui Paulo 		if (wpabuf_resize(&beacon, 100) == 0) {
117*f05cddf9SRui Paulo 			u8 *start, *p;
118*f05cddf9SRui Paulo 			start = wpabuf_put(beacon, 0);
119*f05cddf9SRui Paulo 			p = hostapd_eid_p2p_manage(hapd, start);
120*f05cddf9SRui Paulo 			wpabuf_put(beacon, p - start);
121*f05cddf9SRui Paulo 		}
122*f05cddf9SRui Paulo 
123*f05cddf9SRui Paulo 		if (wpabuf_resize(&proberesp, 100) == 0) {
124*f05cddf9SRui Paulo 			u8 *start, *p;
125*f05cddf9SRui Paulo 			start = wpabuf_put(proberesp, 0);
126*f05cddf9SRui Paulo 			p = hostapd_eid_p2p_manage(hapd, start);
127*f05cddf9SRui Paulo 			wpabuf_put(proberesp, p - start);
128*f05cddf9SRui Paulo 		}
129*f05cddf9SRui Paulo 	}
130*f05cddf9SRui Paulo #endif /* CONFIG_P2P_MANAGER */
131*f05cddf9SRui Paulo 
132*f05cddf9SRui Paulo #ifdef CONFIG_WPS2
133*f05cddf9SRui Paulo 	if (hapd->conf->wps_state) {
134*f05cddf9SRui Paulo 		struct wpabuf *a = wps_build_assoc_resp_ie();
135*f05cddf9SRui Paulo 		if (a && wpabuf_resize(&assocresp, wpabuf_len(a)) == 0)
136*f05cddf9SRui Paulo 			wpabuf_put_buf(assocresp, a);
137*f05cddf9SRui Paulo 		wpabuf_free(a);
138*f05cddf9SRui Paulo 	}
139*f05cddf9SRui Paulo #endif /* CONFIG_WPS2 */
140*f05cddf9SRui Paulo 
141*f05cddf9SRui Paulo #ifdef CONFIG_P2P_MANAGER
142*f05cddf9SRui Paulo 	if (hapd->conf->p2p & P2P_MANAGE) {
143*f05cddf9SRui Paulo 		if (wpabuf_resize(&assocresp, 100) == 0) {
144*f05cddf9SRui Paulo 			u8 *start, *p;
145*f05cddf9SRui Paulo 			start = wpabuf_put(assocresp, 0);
146*f05cddf9SRui Paulo 			p = hostapd_eid_p2p_manage(hapd, start);
147*f05cddf9SRui Paulo 			wpabuf_put(assocresp, p - start);
148*f05cddf9SRui Paulo 		}
149*f05cddf9SRui Paulo 	}
150*f05cddf9SRui Paulo #endif /* CONFIG_P2P_MANAGER */
151*f05cddf9SRui Paulo 
152*f05cddf9SRui Paulo #ifdef CONFIG_WIFI_DISPLAY
153*f05cddf9SRui Paulo 	if (hapd->p2p_group) {
154*f05cddf9SRui Paulo 		struct wpabuf *a;
155*f05cddf9SRui Paulo 		a = p2p_group_assoc_resp_ie(hapd->p2p_group, P2P_SC_SUCCESS);
156*f05cddf9SRui Paulo 		if (a && wpabuf_resize(&assocresp, wpabuf_len(a)) == 0)
157*f05cddf9SRui Paulo 			wpabuf_put_buf(assocresp, a);
158*f05cddf9SRui Paulo 		wpabuf_free(a);
159*f05cddf9SRui Paulo 	}
160*f05cddf9SRui Paulo #endif /* CONFIG_WIFI_DISPLAY */
161*f05cddf9SRui Paulo 
162*f05cddf9SRui Paulo #ifdef CONFIG_HS20
163*f05cddf9SRui Paulo 	pos = buf;
164*f05cddf9SRui Paulo 	pos = hostapd_eid_hs20_indication(hapd, pos);
165*f05cddf9SRui Paulo 	if (pos != buf) {
166*f05cddf9SRui Paulo 		if (wpabuf_resize(&beacon, pos - buf) != 0)
167*f05cddf9SRui Paulo 			goto fail;
168*f05cddf9SRui Paulo 		wpabuf_put_data(beacon, buf, pos - buf);
169*f05cddf9SRui Paulo 
170*f05cddf9SRui Paulo 		if (wpabuf_resize(&proberesp, pos - buf) != 0)
171*f05cddf9SRui Paulo 			goto fail;
172*f05cddf9SRui Paulo 		wpabuf_put_data(proberesp, buf, pos - buf);
173*f05cddf9SRui Paulo 	}
174*f05cddf9SRui Paulo #endif /* CONFIG_HS20 */
175*f05cddf9SRui Paulo 
176*f05cddf9SRui Paulo 	*beacon_ret = beacon;
177*f05cddf9SRui Paulo 	*proberesp_ret = proberesp;
178*f05cddf9SRui Paulo 	*assocresp_ret = assocresp;
179*f05cddf9SRui Paulo 
180*f05cddf9SRui Paulo 	return 0;
181*f05cddf9SRui Paulo 
182*f05cddf9SRui Paulo fail:
183*f05cddf9SRui Paulo 	wpabuf_free(beacon);
184*f05cddf9SRui Paulo 	wpabuf_free(proberesp);
185*f05cddf9SRui Paulo 	wpabuf_free(assocresp);
186*f05cddf9SRui Paulo 	return -1;
187*f05cddf9SRui Paulo }
188*f05cddf9SRui Paulo 
189*f05cddf9SRui Paulo 
190*f05cddf9SRui Paulo void hostapd_free_ap_extra_ies(struct hostapd_data *hapd,
191*f05cddf9SRui Paulo 			       struct wpabuf *beacon,
192*f05cddf9SRui Paulo 			       struct wpabuf *proberesp,
193*f05cddf9SRui Paulo 			       struct wpabuf *assocresp)
194*f05cddf9SRui Paulo {
195*f05cddf9SRui Paulo 	wpabuf_free(beacon);
196*f05cddf9SRui Paulo 	wpabuf_free(proberesp);
197*f05cddf9SRui Paulo 	wpabuf_free(assocresp);
198*f05cddf9SRui Paulo }
199*f05cddf9SRui Paulo 
200*f05cddf9SRui Paulo 
201*f05cddf9SRui Paulo int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
202*f05cddf9SRui Paulo {
203*f05cddf9SRui Paulo 	struct wpabuf *beacon, *proberesp, *assocresp;
204e28a4053SRui Paulo 	int ret;
205e28a4053SRui Paulo 
206e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
207e28a4053SRui Paulo 		return 0;
208e28a4053SRui Paulo 
209*f05cddf9SRui Paulo 	if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) <
210*f05cddf9SRui Paulo 	    0)
211*f05cddf9SRui Paulo 		return -1;
212e28a4053SRui Paulo 
213*f05cddf9SRui Paulo 	ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp,
214*f05cddf9SRui Paulo 					  assocresp);
215*f05cddf9SRui Paulo 
216*f05cddf9SRui Paulo 	hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
217e28a4053SRui Paulo 
218e28a4053SRui Paulo 	return ret;
219e28a4053SRui Paulo }
220e28a4053SRui Paulo 
221e28a4053SRui Paulo 
222*f05cddf9SRui Paulo int hostapd_set_authorized(struct hostapd_data *hapd,
223e28a4053SRui Paulo 			   struct sta_info *sta, int authorized)
224e28a4053SRui Paulo {
225e28a4053SRui Paulo 	if (authorized) {
226e28a4053SRui Paulo 		return hostapd_sta_set_flags(hapd, sta->addr,
227e28a4053SRui Paulo 					     hostapd_sta_flags_to_drv(
228e28a4053SRui Paulo 						     sta->flags),
229e28a4053SRui Paulo 					     WPA_STA_AUTHORIZED, ~0);
230e28a4053SRui Paulo 	}
231e28a4053SRui Paulo 
232e28a4053SRui Paulo 	return hostapd_sta_set_flags(hapd, sta->addr,
233e28a4053SRui Paulo 				     hostapd_sta_flags_to_drv(sta->flags),
234e28a4053SRui Paulo 				     0, ~WPA_STA_AUTHORIZED);
235e28a4053SRui Paulo }
236e28a4053SRui Paulo 
237e28a4053SRui Paulo 
238*f05cddf9SRui Paulo int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta)
239e28a4053SRui Paulo {
240e28a4053SRui Paulo 	int set_flags, total_flags, flags_and, flags_or;
241e28a4053SRui Paulo 	total_flags = hostapd_sta_flags_to_drv(sta->flags);
242e28a4053SRui Paulo 	set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP;
243e28a4053SRui Paulo 	if (((!hapd->conf->ieee802_1x && !hapd->conf->wpa) ||
244e28a4053SRui Paulo 	     sta->auth_alg == WLAN_AUTH_FT) &&
245e28a4053SRui Paulo 	    sta->flags & WLAN_STA_AUTHORIZED)
246e28a4053SRui Paulo 		set_flags |= WPA_STA_AUTHORIZED;
247e28a4053SRui Paulo 	flags_or = total_flags & set_flags;
248e28a4053SRui Paulo 	flags_and = total_flags | ~set_flags;
249e28a4053SRui Paulo 	return hostapd_sta_set_flags(hapd, sta->addr, total_flags,
250e28a4053SRui Paulo 				     flags_or, flags_and);
251e28a4053SRui Paulo }
252e28a4053SRui Paulo 
253e28a4053SRui Paulo 
254*f05cddf9SRui Paulo int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
255*f05cddf9SRui Paulo 			      int enabled)
256e28a4053SRui Paulo {
257e28a4053SRui Paulo 	struct wpa_bss_params params;
258e28a4053SRui Paulo 	os_memset(&params, 0, sizeof(params));
259e28a4053SRui Paulo 	params.ifname = ifname;
260e28a4053SRui Paulo 	params.enabled = enabled;
261e28a4053SRui Paulo 	if (enabled) {
262e28a4053SRui Paulo 		params.wpa = hapd->conf->wpa;
263e28a4053SRui Paulo 		params.ieee802_1x = hapd->conf->ieee802_1x;
264e28a4053SRui Paulo 		params.wpa_group = hapd->conf->wpa_group;
265e28a4053SRui Paulo 		params.wpa_pairwise = hapd->conf->wpa_pairwise;
266e28a4053SRui Paulo 		params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt;
267e28a4053SRui Paulo 		params.rsn_preauth = hapd->conf->rsn_preauth;
268*f05cddf9SRui Paulo #ifdef CONFIG_IEEE80211W
269*f05cddf9SRui Paulo 		params.ieee80211w = hapd->conf->ieee80211w;
270*f05cddf9SRui Paulo #endif /* CONFIG_IEEE80211W */
271e28a4053SRui Paulo 	}
272e28a4053SRui Paulo 	return hostapd_set_ieee8021x(hapd, &params);
273e28a4053SRui Paulo }
274e28a4053SRui Paulo 
275e28a4053SRui Paulo 
276*f05cddf9SRui Paulo int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname)
277e28a4053SRui Paulo {
278e28a4053SRui Paulo 	char force_ifname[IFNAMSIZ];
279e28a4053SRui Paulo 	u8 if_addr[ETH_ALEN];
280*f05cddf9SRui Paulo 	return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, hapd->own_addr,
281*f05cddf9SRui Paulo 			      NULL, NULL, force_ifname, if_addr, NULL);
282e28a4053SRui Paulo }
283e28a4053SRui Paulo 
284*f05cddf9SRui Paulo 
285*f05cddf9SRui Paulo int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname)
286e28a4053SRui Paulo {
287e28a4053SRui Paulo 	return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname);
288e28a4053SRui Paulo }
289e28a4053SRui Paulo 
290e28a4053SRui Paulo 
291*f05cddf9SRui Paulo int hostapd_set_wds_sta(struct hostapd_data *hapd, const u8 *addr, int aid,
292*f05cddf9SRui Paulo 			int val)
293e28a4053SRui Paulo {
294*f05cddf9SRui Paulo 	const char *bridge = NULL;
295*f05cddf9SRui Paulo 
296e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL)
297e28a4053SRui Paulo 		return 0;
298*f05cddf9SRui Paulo 	if (hapd->conf->wds_bridge[0])
299*f05cddf9SRui Paulo 		bridge = hapd->conf->wds_bridge;
300*f05cddf9SRui Paulo 	else if (hapd->conf->bridge[0])
301*f05cddf9SRui Paulo 		bridge = hapd->conf->bridge;
302*f05cddf9SRui Paulo 	return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
303*f05cddf9SRui Paulo 					 bridge);
304e28a4053SRui Paulo }
305e28a4053SRui Paulo 
306e28a4053SRui Paulo 
307*f05cddf9SRui Paulo int hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr,
308*f05cddf9SRui Paulo 			 u16 auth_alg)
309e28a4053SRui Paulo {
310*f05cddf9SRui Paulo 	if (hapd->driver == NULL || hapd->driver->add_sta_node == NULL)
311e28a4053SRui Paulo 		return 0;
312*f05cddf9SRui Paulo 	return hapd->driver->add_sta_node(hapd->drv_priv, addr, auth_alg);
313e28a4053SRui Paulo }
314e28a4053SRui Paulo 
315e28a4053SRui Paulo 
316*f05cddf9SRui Paulo int hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr,
317*f05cddf9SRui Paulo 		     u16 seq, u16 status, const u8 *ie, size_t len)
318e28a4053SRui Paulo {
319*f05cddf9SRui Paulo 	if (hapd->driver == NULL || hapd->driver->sta_auth == NULL)
320e28a4053SRui Paulo 		return 0;
321*f05cddf9SRui Paulo 	return hapd->driver->sta_auth(hapd->drv_priv, hapd->own_addr, addr,
322*f05cddf9SRui Paulo 				      seq, status, ie, len);
323e28a4053SRui Paulo }
324e28a4053SRui Paulo 
325e28a4053SRui Paulo 
326*f05cddf9SRui Paulo int hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr,
327*f05cddf9SRui Paulo 		      int reassoc, u16 status, const u8 *ie, size_t len)
328e28a4053SRui Paulo {
329*f05cddf9SRui Paulo 	if (hapd->driver == NULL || hapd->driver->sta_assoc == NULL)
330e28a4053SRui Paulo 		return 0;
331*f05cddf9SRui Paulo 	return hapd->driver->sta_assoc(hapd->drv_priv, hapd->own_addr, addr,
332*f05cddf9SRui Paulo 				       reassoc, status, ie, len);
333e28a4053SRui Paulo }
334e28a4053SRui Paulo 
335e28a4053SRui Paulo 
336*f05cddf9SRui Paulo int hostapd_sta_add(struct hostapd_data *hapd,
337e28a4053SRui Paulo 		    const u8 *addr, u16 aid, u16 capability,
338e28a4053SRui Paulo 		    const u8 *supp_rates, size_t supp_rates_len,
339e28a4053SRui Paulo 		    u16 listen_interval,
340*f05cddf9SRui Paulo 		    const struct ieee80211_ht_capabilities *ht_capab,
341*f05cddf9SRui Paulo 		    u32 flags, u8 qosinfo)
342e28a4053SRui Paulo {
343e28a4053SRui Paulo 	struct hostapd_sta_add_params params;
344e28a4053SRui Paulo 
345e28a4053SRui Paulo 	if (hapd->driver == NULL)
346e28a4053SRui Paulo 		return 0;
347e28a4053SRui Paulo 	if (hapd->driver->sta_add == NULL)
348e28a4053SRui Paulo 		return 0;
349e28a4053SRui Paulo 
350e28a4053SRui Paulo 	os_memset(&params, 0, sizeof(params));
351e28a4053SRui Paulo 	params.addr = addr;
352e28a4053SRui Paulo 	params.aid = aid;
353e28a4053SRui Paulo 	params.capability = capability;
354e28a4053SRui Paulo 	params.supp_rates = supp_rates;
355e28a4053SRui Paulo 	params.supp_rates_len = supp_rates_len;
356e28a4053SRui Paulo 	params.listen_interval = listen_interval;
357e28a4053SRui Paulo 	params.ht_capabilities = ht_capab;
358*f05cddf9SRui Paulo 	params.flags = hostapd_sta_flags_to_drv(flags);
359*f05cddf9SRui Paulo 	params.qosinfo = qosinfo;
360e28a4053SRui Paulo 	return hapd->driver->sta_add(hapd->drv_priv, &params);
361e28a4053SRui Paulo }
362e28a4053SRui Paulo 
363e28a4053SRui Paulo 
364*f05cddf9SRui Paulo int hostapd_add_tspec(struct hostapd_data *hapd, const u8 *addr,
365*f05cddf9SRui Paulo 		      u8 *tspec_ie, size_t tspec_ielen)
366e28a4053SRui Paulo {
367*f05cddf9SRui Paulo 	if (hapd->driver == NULL || hapd->driver->add_tspec == NULL)
368e28a4053SRui Paulo 		return 0;
369*f05cddf9SRui Paulo 	return hapd->driver->add_tspec(hapd->drv_priv, addr, tspec_ie,
370*f05cddf9SRui Paulo 				       tspec_ielen);
371e28a4053SRui Paulo }
372e28a4053SRui Paulo 
373e28a4053SRui Paulo 
374e28a4053SRui Paulo int hostapd_set_privacy(struct hostapd_data *hapd, int enabled)
375e28a4053SRui Paulo {
376e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_privacy == NULL)
377e28a4053SRui Paulo 		return 0;
378e28a4053SRui Paulo 	return hapd->driver->set_privacy(hapd->drv_priv, enabled);
379e28a4053SRui Paulo }
380e28a4053SRui Paulo 
381e28a4053SRui Paulo 
382e28a4053SRui Paulo int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem,
383e28a4053SRui Paulo 			     size_t elem_len)
384e28a4053SRui Paulo {
385e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_generic_elem == NULL)
386e28a4053SRui Paulo 		return 0;
387e28a4053SRui Paulo 	return hapd->driver->set_generic_elem(hapd->drv_priv, elem, elem_len);
388e28a4053SRui Paulo }
389e28a4053SRui Paulo 
390e28a4053SRui Paulo 
391e28a4053SRui Paulo int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len)
392e28a4053SRui Paulo {
393e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->hapd_get_ssid == NULL)
394e28a4053SRui Paulo 		return 0;
395e28a4053SRui Paulo 	return hapd->driver->hapd_get_ssid(hapd->drv_priv, buf, len);
396e28a4053SRui Paulo }
397e28a4053SRui Paulo 
398e28a4053SRui Paulo 
399e28a4053SRui Paulo int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len)
400e28a4053SRui Paulo {
401e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->hapd_set_ssid == NULL)
402e28a4053SRui Paulo 		return 0;
403e28a4053SRui Paulo 	return hapd->driver->hapd_set_ssid(hapd->drv_priv, buf, len);
404e28a4053SRui Paulo }
405e28a4053SRui Paulo 
406e28a4053SRui Paulo 
407e28a4053SRui Paulo int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
408e28a4053SRui Paulo 		   const char *ifname, const u8 *addr, void *bss_ctx,
409*f05cddf9SRui Paulo 		   void **drv_priv, char *force_ifname, u8 *if_addr,
410*f05cddf9SRui Paulo 		   const char *bridge)
411e28a4053SRui Paulo {
412e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->if_add == NULL)
413e28a4053SRui Paulo 		return -1;
414e28a4053SRui Paulo 	return hapd->driver->if_add(hapd->drv_priv, type, ifname, addr,
415*f05cddf9SRui Paulo 				    bss_ctx, drv_priv, force_ifname, if_addr,
416*f05cddf9SRui Paulo 				    bridge);
417e28a4053SRui Paulo }
418e28a4053SRui Paulo 
419e28a4053SRui Paulo 
420e28a4053SRui Paulo int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
421e28a4053SRui Paulo 		      const char *ifname)
422e28a4053SRui Paulo {
423e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->if_remove == NULL)
424e28a4053SRui Paulo 		return -1;
425e28a4053SRui Paulo 	return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
426e28a4053SRui Paulo }
427e28a4053SRui Paulo 
428e28a4053SRui Paulo 
429e28a4053SRui Paulo int hostapd_set_ieee8021x(struct hostapd_data *hapd,
430e28a4053SRui Paulo 			  struct wpa_bss_params *params)
431e28a4053SRui Paulo {
432e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL)
433e28a4053SRui Paulo 		return 0;
434e28a4053SRui Paulo 	return hapd->driver->set_ieee8021x(hapd->drv_priv, params);
435e28a4053SRui Paulo }
436e28a4053SRui Paulo 
437e28a4053SRui Paulo 
438e28a4053SRui Paulo int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
439e28a4053SRui Paulo 		       const u8 *addr, int idx, u8 *seq)
440e28a4053SRui Paulo {
441e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->get_seqnum == NULL)
442e28a4053SRui Paulo 		return 0;
443e28a4053SRui Paulo 	return hapd->driver->get_seqnum(ifname, hapd->drv_priv, addr, idx,
444e28a4053SRui Paulo 					seq);
445e28a4053SRui Paulo }
446e28a4053SRui Paulo 
447e28a4053SRui Paulo 
448e28a4053SRui Paulo int hostapd_flush(struct hostapd_data *hapd)
449e28a4053SRui Paulo {
450e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->flush == NULL)
451e28a4053SRui Paulo 		return 0;
452e28a4053SRui Paulo 	return hapd->driver->flush(hapd->drv_priv);
453e28a4053SRui Paulo }
454e28a4053SRui Paulo 
455e28a4053SRui Paulo 
456e28a4053SRui Paulo int hostapd_set_freq(struct hostapd_data *hapd, int mode, int freq,
457e28a4053SRui Paulo 		     int channel, int ht_enabled, int sec_channel_offset)
458e28a4053SRui Paulo {
459e28a4053SRui Paulo 	struct hostapd_freq_params data;
460e28a4053SRui Paulo 	if (hapd->driver == NULL)
461e28a4053SRui Paulo 		return 0;
462e28a4053SRui Paulo 	if (hapd->driver->set_freq == NULL)
463e28a4053SRui Paulo 		return 0;
464e28a4053SRui Paulo 	os_memset(&data, 0, sizeof(data));
465e28a4053SRui Paulo 	data.mode = mode;
466e28a4053SRui Paulo 	data.freq = freq;
467e28a4053SRui Paulo 	data.channel = channel;
468e28a4053SRui Paulo 	data.ht_enabled = ht_enabled;
469e28a4053SRui Paulo 	data.sec_channel_offset = sec_channel_offset;
470e28a4053SRui Paulo 	return hapd->driver->set_freq(hapd->drv_priv, &data);
471e28a4053SRui Paulo }
472e28a4053SRui Paulo 
473e28a4053SRui Paulo int hostapd_set_rts(struct hostapd_data *hapd, int rts)
474e28a4053SRui Paulo {
475e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_rts == NULL)
476e28a4053SRui Paulo 		return 0;
477e28a4053SRui Paulo 	return hapd->driver->set_rts(hapd->drv_priv, rts);
478e28a4053SRui Paulo }
479e28a4053SRui Paulo 
480e28a4053SRui Paulo 
481e28a4053SRui Paulo int hostapd_set_frag(struct hostapd_data *hapd, int frag)
482e28a4053SRui Paulo {
483e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_frag == NULL)
484e28a4053SRui Paulo 		return 0;
485e28a4053SRui Paulo 	return hapd->driver->set_frag(hapd->drv_priv, frag);
486e28a4053SRui Paulo }
487e28a4053SRui Paulo 
488e28a4053SRui Paulo 
489e28a4053SRui Paulo int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
490e28a4053SRui Paulo 			  int total_flags, int flags_or, int flags_and)
491e28a4053SRui Paulo {
492e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL)
493e28a4053SRui Paulo 		return 0;
494e28a4053SRui Paulo 	return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags,
495e28a4053SRui Paulo 					   flags_or, flags_and);
496e28a4053SRui Paulo }
497e28a4053SRui Paulo 
498e28a4053SRui Paulo 
499e28a4053SRui Paulo int hostapd_set_country(struct hostapd_data *hapd, const char *country)
500e28a4053SRui Paulo {
501e28a4053SRui Paulo 	if (hapd->driver == NULL ||
502e28a4053SRui Paulo 	    hapd->driver->set_country == NULL)
503e28a4053SRui Paulo 		return 0;
504e28a4053SRui Paulo 	return hapd->driver->set_country(hapd->drv_priv, country);
505e28a4053SRui Paulo }
506e28a4053SRui Paulo 
507e28a4053SRui Paulo 
508e28a4053SRui Paulo int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
509e28a4053SRui Paulo 				int cw_min, int cw_max, int burst_time)
510e28a4053SRui Paulo {
511e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_tx_queue_params == NULL)
512e28a4053SRui Paulo 		return 0;
513e28a4053SRui Paulo 	return hapd->driver->set_tx_queue_params(hapd->drv_priv, queue, aifs,
514e28a4053SRui Paulo 						 cw_min, cw_max, burst_time);
515e28a4053SRui Paulo }
516e28a4053SRui Paulo 
517e28a4053SRui Paulo 
518e28a4053SRui Paulo struct hostapd_hw_modes *
519e28a4053SRui Paulo hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
520e28a4053SRui Paulo 			    u16 *flags)
521e28a4053SRui Paulo {
522e28a4053SRui Paulo 	if (hapd->driver == NULL ||
523e28a4053SRui Paulo 	    hapd->driver->get_hw_feature_data == NULL)
524e28a4053SRui Paulo 		return NULL;
525e28a4053SRui Paulo 	return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
526e28a4053SRui Paulo 						 flags);
527e28a4053SRui Paulo }
528e28a4053SRui Paulo 
529e28a4053SRui Paulo 
530e28a4053SRui Paulo int hostapd_driver_commit(struct hostapd_data *hapd)
531e28a4053SRui Paulo {
532e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->commit == NULL)
533e28a4053SRui Paulo 		return 0;
534e28a4053SRui Paulo 	return hapd->driver->commit(hapd->drv_priv);
535e28a4053SRui Paulo }
536e28a4053SRui Paulo 
537e28a4053SRui Paulo 
538e28a4053SRui Paulo int hostapd_drv_none(struct hostapd_data *hapd)
539e28a4053SRui Paulo {
540e28a4053SRui Paulo 	return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0;
541e28a4053SRui Paulo }
542e28a4053SRui Paulo 
543e28a4053SRui Paulo 
544e28a4053SRui Paulo int hostapd_driver_scan(struct hostapd_data *hapd,
545e28a4053SRui Paulo 			struct wpa_driver_scan_params *params)
546e28a4053SRui Paulo {
547e28a4053SRui Paulo 	if (hapd->driver && hapd->driver->scan2)
548e28a4053SRui Paulo 		return hapd->driver->scan2(hapd->drv_priv, params);
549e28a4053SRui Paulo 	return -1;
550e28a4053SRui Paulo }
551e28a4053SRui Paulo 
552e28a4053SRui Paulo 
553e28a4053SRui Paulo struct wpa_scan_results * hostapd_driver_get_scan_results(
554e28a4053SRui Paulo 	struct hostapd_data *hapd)
555e28a4053SRui Paulo {
556e28a4053SRui Paulo 	if (hapd->driver && hapd->driver->get_scan_results2)
557e28a4053SRui Paulo 		return hapd->driver->get_scan_results2(hapd->drv_priv);
558e28a4053SRui Paulo 	return NULL;
559e28a4053SRui Paulo }
560*f05cddf9SRui Paulo 
561*f05cddf9SRui Paulo 
562*f05cddf9SRui Paulo int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
563*f05cddf9SRui Paulo 			   int duration)
564*f05cddf9SRui Paulo {
565*f05cddf9SRui Paulo 	if (hapd->driver && hapd->driver->set_noa)
566*f05cddf9SRui Paulo 		return hapd->driver->set_noa(hapd->drv_priv, count, start,
567*f05cddf9SRui Paulo 					     duration);
568*f05cddf9SRui Paulo 	return -1;
569*f05cddf9SRui Paulo }
570*f05cddf9SRui Paulo 
571*f05cddf9SRui Paulo 
572*f05cddf9SRui Paulo int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
573*f05cddf9SRui Paulo 			enum wpa_alg alg, const u8 *addr,
574*f05cddf9SRui Paulo 			int key_idx, int set_tx,
575*f05cddf9SRui Paulo 			const u8 *seq, size_t seq_len,
576*f05cddf9SRui Paulo 			const u8 *key, size_t key_len)
577*f05cddf9SRui Paulo {
578*f05cddf9SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_key == NULL)
579*f05cddf9SRui Paulo 		return 0;
580*f05cddf9SRui Paulo 	return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr,
581*f05cddf9SRui Paulo 				     key_idx, set_tx, seq, seq_len, key,
582*f05cddf9SRui Paulo 				     key_len);
583*f05cddf9SRui Paulo }
584*f05cddf9SRui Paulo 
585*f05cddf9SRui Paulo 
586*f05cddf9SRui Paulo int hostapd_drv_send_mlme(struct hostapd_data *hapd,
587*f05cddf9SRui Paulo 			  const void *msg, size_t len, int noack)
588*f05cddf9SRui Paulo {
589*f05cddf9SRui Paulo 	if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
590*f05cddf9SRui Paulo 		return 0;
591*f05cddf9SRui Paulo 	return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack);
592*f05cddf9SRui Paulo }
593*f05cddf9SRui Paulo 
594*f05cddf9SRui Paulo 
595*f05cddf9SRui Paulo int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
596*f05cddf9SRui Paulo 			   const u8 *addr, int reason)
597*f05cddf9SRui Paulo {
598*f05cddf9SRui Paulo 	if (hapd->driver == NULL || hapd->driver->sta_deauth == NULL)
599*f05cddf9SRui Paulo 		return 0;
600*f05cddf9SRui Paulo 	return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr,
601*f05cddf9SRui Paulo 					reason);
602*f05cddf9SRui Paulo }
603*f05cddf9SRui Paulo 
604*f05cddf9SRui Paulo 
605*f05cddf9SRui Paulo int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
606*f05cddf9SRui Paulo 			     const u8 *addr, int reason)
607*f05cddf9SRui Paulo {
608*f05cddf9SRui Paulo 	if (hapd->driver == NULL || hapd->driver->sta_disassoc == NULL)
609*f05cddf9SRui Paulo 		return 0;
610*f05cddf9SRui Paulo 	return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr,
611*f05cddf9SRui Paulo 					  reason);
612*f05cddf9SRui Paulo }
613*f05cddf9SRui Paulo 
614*f05cddf9SRui Paulo 
615*f05cddf9SRui Paulo int hostapd_drv_wnm_oper(struct hostapd_data *hapd, enum wnm_oper oper,
616*f05cddf9SRui Paulo 			 const u8 *peer, u8 *buf, u16 *buf_len)
617*f05cddf9SRui Paulo {
618*f05cddf9SRui Paulo 	if (hapd->driver == NULL || hapd->driver->wnm_oper == NULL)
619*f05cddf9SRui Paulo 		return 0;
620*f05cddf9SRui Paulo 	return hapd->driver->wnm_oper(hapd->drv_priv, oper, peer, buf,
621*f05cddf9SRui Paulo 				      buf_len);
622*f05cddf9SRui Paulo }
623*f05cddf9SRui Paulo 
624*f05cddf9SRui Paulo 
625*f05cddf9SRui Paulo int hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
626*f05cddf9SRui Paulo 			    unsigned int wait, const u8 *dst, const u8 *data,
627*f05cddf9SRui Paulo 			    size_t len)
628*f05cddf9SRui Paulo {
629*f05cddf9SRui Paulo 	if (hapd->driver == NULL || hapd->driver->send_action == NULL)
630*f05cddf9SRui Paulo 		return 0;
631*f05cddf9SRui Paulo 	return hapd->driver->send_action(hapd->drv_priv, freq, wait, dst,
632*f05cddf9SRui Paulo 					 hapd->own_addr, hapd->own_addr, data,
633*f05cddf9SRui Paulo 					 len, 0);
634*f05cddf9SRui Paulo }
635