xref: /freebsd/contrib/wpa/src/ap/ap_drv_ops.c (revision e28a4053b110e06768631ac8401ed4a3c05e68a5)
1*e28a4053SRui Paulo /*
2*e28a4053SRui Paulo  * hostapd - Driver operations
3*e28a4053SRui Paulo  * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
4*e28a4053SRui Paulo  *
5*e28a4053SRui Paulo  * This program is free software; you can redistribute it and/or modify
6*e28a4053SRui Paulo  * it under the terms of the GNU General Public License version 2 as
7*e28a4053SRui Paulo  * published by the Free Software Foundation.
8*e28a4053SRui Paulo  *
9*e28a4053SRui Paulo  * Alternatively, this software may be distributed under the terms of BSD
10*e28a4053SRui Paulo  * license.
11*e28a4053SRui Paulo  *
12*e28a4053SRui Paulo  * See README and COPYING for more details.
13*e28a4053SRui Paulo  */
14*e28a4053SRui Paulo 
15*e28a4053SRui Paulo #include "utils/includes.h"
16*e28a4053SRui Paulo 
17*e28a4053SRui Paulo #include "utils/common.h"
18*e28a4053SRui Paulo #include "drivers/driver.h"
19*e28a4053SRui Paulo #include "common/ieee802_11_defs.h"
20*e28a4053SRui Paulo #include "hostapd.h"
21*e28a4053SRui Paulo #include "ieee802_11.h"
22*e28a4053SRui Paulo #include "sta_info.h"
23*e28a4053SRui Paulo #include "ap_config.h"
24*e28a4053SRui Paulo #include "ap_drv_ops.h"
25*e28a4053SRui Paulo 
26*e28a4053SRui Paulo 
27*e28a4053SRui Paulo static int hostapd_sta_flags_to_drv(int flags)
28*e28a4053SRui Paulo {
29*e28a4053SRui Paulo 	int res = 0;
30*e28a4053SRui Paulo 	if (flags & WLAN_STA_AUTHORIZED)
31*e28a4053SRui Paulo 		res |= WPA_STA_AUTHORIZED;
32*e28a4053SRui Paulo 	if (flags & WLAN_STA_WMM)
33*e28a4053SRui Paulo 		res |= WPA_STA_WMM;
34*e28a4053SRui Paulo 	if (flags & WLAN_STA_SHORT_PREAMBLE)
35*e28a4053SRui Paulo 		res |= WPA_STA_SHORT_PREAMBLE;
36*e28a4053SRui Paulo 	if (flags & WLAN_STA_MFP)
37*e28a4053SRui Paulo 		res |= WPA_STA_MFP;
38*e28a4053SRui Paulo 	return res;
39*e28a4053SRui Paulo }
40*e28a4053SRui Paulo 
41*e28a4053SRui Paulo 
42*e28a4053SRui Paulo static int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
43*e28a4053SRui Paulo {
44*e28a4053SRui Paulo 	struct wpabuf *beacon, *proberesp;
45*e28a4053SRui Paulo 	int ret;
46*e28a4053SRui Paulo 
47*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
48*e28a4053SRui Paulo 		return 0;
49*e28a4053SRui Paulo 
50*e28a4053SRui Paulo 	beacon = hapd->wps_beacon_ie;
51*e28a4053SRui Paulo 	proberesp = hapd->wps_probe_resp_ie;
52*e28a4053SRui Paulo 
53*e28a4053SRui Paulo 	ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp);
54*e28a4053SRui Paulo 
55*e28a4053SRui Paulo 	return ret;
56*e28a4053SRui Paulo }
57*e28a4053SRui Paulo 
58*e28a4053SRui Paulo 
59*e28a4053SRui Paulo static int hostapd_send_mgmt_frame(struct hostapd_data *hapd, const void *msg,
60*e28a4053SRui Paulo 			   size_t len)
61*e28a4053SRui Paulo {
62*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
63*e28a4053SRui Paulo 		return 0;
64*e28a4053SRui Paulo 	return hapd->driver->send_mlme(hapd->drv_priv, msg, len);
65*e28a4053SRui Paulo }
66*e28a4053SRui Paulo 
67*e28a4053SRui Paulo 
68*e28a4053SRui Paulo static int hostapd_send_eapol(struct hostapd_data *hapd, const u8 *addr,
69*e28a4053SRui Paulo 			      const u8 *data, size_t data_len, int encrypt)
70*e28a4053SRui Paulo {
71*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->hapd_send_eapol == NULL)
72*e28a4053SRui Paulo 		return 0;
73*e28a4053SRui Paulo 	return hapd->driver->hapd_send_eapol(hapd->drv_priv, addr, data,
74*e28a4053SRui Paulo 					     data_len, encrypt,
75*e28a4053SRui Paulo 					     hapd->own_addr);
76*e28a4053SRui Paulo }
77*e28a4053SRui Paulo 
78*e28a4053SRui Paulo 
79*e28a4053SRui Paulo static int hostapd_set_authorized(struct hostapd_data *hapd,
80*e28a4053SRui Paulo 				  struct sta_info *sta, int authorized)
81*e28a4053SRui Paulo {
82*e28a4053SRui Paulo 	if (authorized) {
83*e28a4053SRui Paulo 		return hostapd_sta_set_flags(hapd, sta->addr,
84*e28a4053SRui Paulo 					     hostapd_sta_flags_to_drv(
85*e28a4053SRui Paulo 						     sta->flags),
86*e28a4053SRui Paulo 					     WPA_STA_AUTHORIZED, ~0);
87*e28a4053SRui Paulo 	}
88*e28a4053SRui Paulo 
89*e28a4053SRui Paulo 	return hostapd_sta_set_flags(hapd, sta->addr,
90*e28a4053SRui Paulo 				     hostapd_sta_flags_to_drv(sta->flags),
91*e28a4053SRui Paulo 				     0, ~WPA_STA_AUTHORIZED);
92*e28a4053SRui Paulo }
93*e28a4053SRui Paulo 
94*e28a4053SRui Paulo 
95*e28a4053SRui Paulo static int hostapd_set_key(const char *ifname, struct hostapd_data *hapd,
96*e28a4053SRui Paulo 			   enum wpa_alg alg, const u8 *addr, int key_idx,
97*e28a4053SRui Paulo 			   int set_tx, const u8 *seq, size_t seq_len,
98*e28a4053SRui Paulo 			   const u8 *key, size_t key_len)
99*e28a4053SRui Paulo {
100*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_key == NULL)
101*e28a4053SRui Paulo 		return 0;
102*e28a4053SRui Paulo 	return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr,
103*e28a4053SRui Paulo 				     key_idx, set_tx, seq, seq_len, key,
104*e28a4053SRui Paulo 				     key_len);
105*e28a4053SRui Paulo }
106*e28a4053SRui Paulo 
107*e28a4053SRui Paulo 
108*e28a4053SRui Paulo static int hostapd_read_sta_data(struct hostapd_data *hapd,
109*e28a4053SRui Paulo 				 struct hostap_sta_driver_data *data,
110*e28a4053SRui Paulo 				 const u8 *addr)
111*e28a4053SRui Paulo {
112*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->read_sta_data == NULL)
113*e28a4053SRui Paulo 		return -1;
114*e28a4053SRui Paulo 	return hapd->driver->read_sta_data(hapd->drv_priv, data, addr);
115*e28a4053SRui Paulo }
116*e28a4053SRui Paulo 
117*e28a4053SRui Paulo 
118*e28a4053SRui Paulo static int hostapd_sta_clear_stats(struct hostapd_data *hapd, const u8 *addr)
119*e28a4053SRui Paulo {
120*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->sta_clear_stats == NULL)
121*e28a4053SRui Paulo 		return 0;
122*e28a4053SRui Paulo 	return hapd->driver->sta_clear_stats(hapd->drv_priv, addr);
123*e28a4053SRui Paulo }
124*e28a4053SRui Paulo 
125*e28a4053SRui Paulo 
126*e28a4053SRui Paulo static int hostapd_set_sta_flags(struct hostapd_data *hapd,
127*e28a4053SRui Paulo 				 struct sta_info *sta)
128*e28a4053SRui Paulo {
129*e28a4053SRui Paulo 	int set_flags, total_flags, flags_and, flags_or;
130*e28a4053SRui Paulo 	total_flags = hostapd_sta_flags_to_drv(sta->flags);
131*e28a4053SRui Paulo 	set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP;
132*e28a4053SRui Paulo 	if (((!hapd->conf->ieee802_1x && !hapd->conf->wpa) ||
133*e28a4053SRui Paulo 	     sta->auth_alg == WLAN_AUTH_FT) &&
134*e28a4053SRui Paulo 	    sta->flags & WLAN_STA_AUTHORIZED)
135*e28a4053SRui Paulo 		set_flags |= WPA_STA_AUTHORIZED;
136*e28a4053SRui Paulo 	flags_or = total_flags & set_flags;
137*e28a4053SRui Paulo 	flags_and = total_flags | ~set_flags;
138*e28a4053SRui Paulo 	return hostapd_sta_set_flags(hapd, sta->addr, total_flags,
139*e28a4053SRui Paulo 				     flags_or, flags_and);
140*e28a4053SRui Paulo }
141*e28a4053SRui Paulo 
142*e28a4053SRui Paulo 
143*e28a4053SRui Paulo static int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd,
144*e28a4053SRui Paulo 				     const char *ifname, int enabled)
145*e28a4053SRui Paulo {
146*e28a4053SRui Paulo 	struct wpa_bss_params params;
147*e28a4053SRui Paulo 	os_memset(&params, 0, sizeof(params));
148*e28a4053SRui Paulo 	params.ifname = ifname;
149*e28a4053SRui Paulo 	params.enabled = enabled;
150*e28a4053SRui Paulo 	if (enabled) {
151*e28a4053SRui Paulo 		params.wpa = hapd->conf->wpa;
152*e28a4053SRui Paulo 		params.ieee802_1x = hapd->conf->ieee802_1x;
153*e28a4053SRui Paulo 		params.wpa_group = hapd->conf->wpa_group;
154*e28a4053SRui Paulo 		params.wpa_pairwise = hapd->conf->wpa_pairwise;
155*e28a4053SRui Paulo 		params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt;
156*e28a4053SRui Paulo 		params.rsn_preauth = hapd->conf->rsn_preauth;
157*e28a4053SRui Paulo 	}
158*e28a4053SRui Paulo 	return hostapd_set_ieee8021x(hapd, &params);
159*e28a4053SRui Paulo }
160*e28a4053SRui Paulo 
161*e28a4053SRui Paulo 
162*e28a4053SRui Paulo static int hostapd_set_radius_acl_auth(struct hostapd_data *hapd,
163*e28a4053SRui Paulo 				       const u8 *mac, int accepted,
164*e28a4053SRui Paulo 				       u32 session_timeout)
165*e28a4053SRui Paulo {
166*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_radius_acl_auth == NULL)
167*e28a4053SRui Paulo 		return 0;
168*e28a4053SRui Paulo 	return hapd->driver->set_radius_acl_auth(hapd->drv_priv, mac, accepted,
169*e28a4053SRui Paulo 						 session_timeout);
170*e28a4053SRui Paulo }
171*e28a4053SRui Paulo 
172*e28a4053SRui Paulo 
173*e28a4053SRui Paulo static int hostapd_set_radius_acl_expire(struct hostapd_data *hapd,
174*e28a4053SRui Paulo 					 const u8 *mac)
175*e28a4053SRui Paulo {
176*e28a4053SRui Paulo 	if (hapd->driver == NULL ||
177*e28a4053SRui Paulo 	    hapd->driver->set_radius_acl_expire == NULL)
178*e28a4053SRui Paulo 		return 0;
179*e28a4053SRui Paulo 	return hapd->driver->set_radius_acl_expire(hapd->drv_priv, mac);
180*e28a4053SRui Paulo }
181*e28a4053SRui Paulo 
182*e28a4053SRui Paulo 
183*e28a4053SRui Paulo static int hostapd_set_bss_params(struct hostapd_data *hapd,
184*e28a4053SRui Paulo 				  int use_protection)
185*e28a4053SRui Paulo {
186*e28a4053SRui Paulo 	int ret = 0;
187*e28a4053SRui Paulo 	int preamble;
188*e28a4053SRui Paulo #ifdef CONFIG_IEEE80211N
189*e28a4053SRui Paulo 	u8 buf[60], *ht_capab, *ht_oper, *pos;
190*e28a4053SRui Paulo 
191*e28a4053SRui Paulo 	pos = buf;
192*e28a4053SRui Paulo 	ht_capab = pos;
193*e28a4053SRui Paulo 	pos = hostapd_eid_ht_capabilities(hapd, pos);
194*e28a4053SRui Paulo 	ht_oper = pos;
195*e28a4053SRui Paulo 	pos = hostapd_eid_ht_operation(hapd, pos);
196*e28a4053SRui Paulo 	if (pos > ht_oper && ht_oper > ht_capab &&
197*e28a4053SRui Paulo 	    hostapd_set_ht_params(hapd, ht_capab + 2, ht_capab[1],
198*e28a4053SRui Paulo 				  ht_oper + 2, ht_oper[1])) {
199*e28a4053SRui Paulo 		wpa_printf(MSG_ERROR, "Could not set HT capabilities "
200*e28a4053SRui Paulo 			   "for kernel driver");
201*e28a4053SRui Paulo 		ret = -1;
202*e28a4053SRui Paulo 	}
203*e28a4053SRui Paulo 
204*e28a4053SRui Paulo #endif /* CONFIG_IEEE80211N */
205*e28a4053SRui Paulo 
206*e28a4053SRui Paulo 	if (hostapd_set_cts_protect(hapd, use_protection)) {
207*e28a4053SRui Paulo 		wpa_printf(MSG_ERROR, "Failed to set CTS protect in kernel "
208*e28a4053SRui Paulo 			   "driver");
209*e28a4053SRui Paulo 		ret = -1;
210*e28a4053SRui Paulo 	}
211*e28a4053SRui Paulo 
212*e28a4053SRui Paulo 	if (hapd->iface->current_mode &&
213*e28a4053SRui Paulo 	    hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G &&
214*e28a4053SRui Paulo 	    hostapd_set_short_slot_time(hapd,
215*e28a4053SRui Paulo 					hapd->iface->num_sta_no_short_slot_time
216*e28a4053SRui Paulo 					> 0 ? 0 : 1)) {
217*e28a4053SRui Paulo 		wpa_printf(MSG_ERROR, "Failed to set Short Slot Time option "
218*e28a4053SRui Paulo 			   "in kernel driver");
219*e28a4053SRui Paulo 		ret = -1;
220*e28a4053SRui Paulo 	}
221*e28a4053SRui Paulo 
222*e28a4053SRui Paulo 	if (hapd->iface->num_sta_no_short_preamble == 0 &&
223*e28a4053SRui Paulo 	    hapd->iconf->preamble == SHORT_PREAMBLE)
224*e28a4053SRui Paulo 		preamble = SHORT_PREAMBLE;
225*e28a4053SRui Paulo 	else
226*e28a4053SRui Paulo 		preamble = LONG_PREAMBLE;
227*e28a4053SRui Paulo 	if (hostapd_set_preamble(hapd, preamble)) {
228*e28a4053SRui Paulo 		wpa_printf(MSG_ERROR, "Could not set preamble for kernel "
229*e28a4053SRui Paulo 			   "driver");
230*e28a4053SRui Paulo 		ret = -1;
231*e28a4053SRui Paulo 	}
232*e28a4053SRui Paulo 
233*e28a4053SRui Paulo 	return ret;
234*e28a4053SRui Paulo }
235*e28a4053SRui Paulo 
236*e28a4053SRui Paulo 
237*e28a4053SRui Paulo static int hostapd_set_beacon(struct hostapd_data *hapd,
238*e28a4053SRui Paulo 			      const u8 *head, size_t head_len,
239*e28a4053SRui Paulo 			      const u8 *tail, size_t tail_len, int dtim_period,
240*e28a4053SRui Paulo 			      int beacon_int)
241*e28a4053SRui Paulo {
242*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_beacon == NULL)
243*e28a4053SRui Paulo 		return 0;
244*e28a4053SRui Paulo 	return hapd->driver->set_beacon(hapd->drv_priv,
245*e28a4053SRui Paulo 					head, head_len, tail, tail_len,
246*e28a4053SRui Paulo 					dtim_period, beacon_int);
247*e28a4053SRui Paulo }
248*e28a4053SRui Paulo 
249*e28a4053SRui Paulo 
250*e28a4053SRui Paulo static int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname)
251*e28a4053SRui Paulo {
252*e28a4053SRui Paulo 	char force_ifname[IFNAMSIZ];
253*e28a4053SRui Paulo 	u8 if_addr[ETH_ALEN];
254*e28a4053SRui Paulo 	return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, NULL, NULL, NULL,
255*e28a4053SRui Paulo 			      force_ifname, if_addr);
256*e28a4053SRui Paulo }
257*e28a4053SRui Paulo 
258*e28a4053SRui Paulo static int hostapd_vlan_if_remove(struct hostapd_data *hapd,
259*e28a4053SRui Paulo 				  const char *ifname)
260*e28a4053SRui Paulo {
261*e28a4053SRui Paulo 	return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname);
262*e28a4053SRui Paulo }
263*e28a4053SRui Paulo 
264*e28a4053SRui Paulo 
265*e28a4053SRui Paulo static int hostapd_set_wds_sta(struct hostapd_data *hapd, const u8 *addr,
266*e28a4053SRui Paulo 			       int aid, int val)
267*e28a4053SRui Paulo {
268*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL)
269*e28a4053SRui Paulo 		return 0;
270*e28a4053SRui Paulo 	return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val);
271*e28a4053SRui Paulo }
272*e28a4053SRui Paulo 
273*e28a4053SRui Paulo 
274*e28a4053SRui Paulo static int hostapd_set_sta_vlan(const char *ifname, struct hostapd_data *hapd,
275*e28a4053SRui Paulo 				const u8 *addr, int vlan_id)
276*e28a4053SRui Paulo {
277*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_sta_vlan == NULL)
278*e28a4053SRui Paulo 		return 0;
279*e28a4053SRui Paulo 	return hapd->driver->set_sta_vlan(hapd->drv_priv, addr, ifname,
280*e28a4053SRui Paulo 					  vlan_id);
281*e28a4053SRui Paulo }
282*e28a4053SRui Paulo 
283*e28a4053SRui Paulo 
284*e28a4053SRui Paulo static int hostapd_get_inact_sec(struct hostapd_data *hapd, const u8 *addr)
285*e28a4053SRui Paulo {
286*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->get_inact_sec == NULL)
287*e28a4053SRui Paulo 		return 0;
288*e28a4053SRui Paulo 	return hapd->driver->get_inact_sec(hapd->drv_priv, addr);
289*e28a4053SRui Paulo }
290*e28a4053SRui Paulo 
291*e28a4053SRui Paulo 
292*e28a4053SRui Paulo static int hostapd_sta_deauth(struct hostapd_data *hapd, const u8 *addr,
293*e28a4053SRui Paulo 			      int reason)
294*e28a4053SRui Paulo {
295*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->sta_deauth == NULL)
296*e28a4053SRui Paulo 		return 0;
297*e28a4053SRui Paulo 	return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr,
298*e28a4053SRui Paulo 					reason);
299*e28a4053SRui Paulo }
300*e28a4053SRui Paulo 
301*e28a4053SRui Paulo 
302*e28a4053SRui Paulo static int hostapd_sta_disassoc(struct hostapd_data *hapd, const u8 *addr,
303*e28a4053SRui Paulo 				int reason)
304*e28a4053SRui Paulo {
305*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->sta_disassoc == NULL)
306*e28a4053SRui Paulo 		return 0;
307*e28a4053SRui Paulo 	return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr,
308*e28a4053SRui Paulo 					  reason);
309*e28a4053SRui Paulo }
310*e28a4053SRui Paulo 
311*e28a4053SRui Paulo 
312*e28a4053SRui Paulo static int hostapd_sta_add(struct hostapd_data *hapd,
313*e28a4053SRui Paulo 			   const u8 *addr, u16 aid, u16 capability,
314*e28a4053SRui Paulo 			   const u8 *supp_rates, size_t supp_rates_len,
315*e28a4053SRui Paulo 			   u16 listen_interval,
316*e28a4053SRui Paulo 			   const struct ieee80211_ht_capabilities *ht_capab)
317*e28a4053SRui Paulo {
318*e28a4053SRui Paulo 	struct hostapd_sta_add_params params;
319*e28a4053SRui Paulo 
320*e28a4053SRui Paulo 	if (hapd->driver == NULL)
321*e28a4053SRui Paulo 		return 0;
322*e28a4053SRui Paulo 	if (hapd->driver->sta_add == NULL)
323*e28a4053SRui Paulo 		return 0;
324*e28a4053SRui Paulo 
325*e28a4053SRui Paulo 	os_memset(&params, 0, sizeof(params));
326*e28a4053SRui Paulo 	params.addr = addr;
327*e28a4053SRui Paulo 	params.aid = aid;
328*e28a4053SRui Paulo 	params.capability = capability;
329*e28a4053SRui Paulo 	params.supp_rates = supp_rates;
330*e28a4053SRui Paulo 	params.supp_rates_len = supp_rates_len;
331*e28a4053SRui Paulo 	params.listen_interval = listen_interval;
332*e28a4053SRui Paulo 	params.ht_capabilities = ht_capab;
333*e28a4053SRui Paulo 	return hapd->driver->sta_add(hapd->drv_priv, &params);
334*e28a4053SRui Paulo }
335*e28a4053SRui Paulo 
336*e28a4053SRui Paulo 
337*e28a4053SRui Paulo static int hostapd_sta_remove(struct hostapd_data *hapd, const u8 *addr)
338*e28a4053SRui Paulo {
339*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->sta_remove == NULL)
340*e28a4053SRui Paulo 		return 0;
341*e28a4053SRui Paulo 	return hapd->driver->sta_remove(hapd->drv_priv, addr);
342*e28a4053SRui Paulo }
343*e28a4053SRui Paulo 
344*e28a4053SRui Paulo 
345*e28a4053SRui Paulo static int hostapd_set_countermeasures(struct hostapd_data *hapd, int enabled)
346*e28a4053SRui Paulo {
347*e28a4053SRui Paulo 	if (hapd->driver == NULL ||
348*e28a4053SRui Paulo 	    hapd->driver->hapd_set_countermeasures == NULL)
349*e28a4053SRui Paulo 		return 0;
350*e28a4053SRui Paulo 	return hapd->driver->hapd_set_countermeasures(hapd->drv_priv, enabled);
351*e28a4053SRui Paulo }
352*e28a4053SRui Paulo 
353*e28a4053SRui Paulo 
354*e28a4053SRui Paulo void hostapd_set_driver_ops(struct hostapd_driver_ops *ops)
355*e28a4053SRui Paulo {
356*e28a4053SRui Paulo 	ops->set_ap_wps_ie = hostapd_set_ap_wps_ie;
357*e28a4053SRui Paulo 	ops->send_mgmt_frame = hostapd_send_mgmt_frame;
358*e28a4053SRui Paulo 	ops->send_eapol = hostapd_send_eapol;
359*e28a4053SRui Paulo 	ops->set_authorized = hostapd_set_authorized;
360*e28a4053SRui Paulo 	ops->set_key = hostapd_set_key;
361*e28a4053SRui Paulo 	ops->read_sta_data = hostapd_read_sta_data;
362*e28a4053SRui Paulo 	ops->sta_clear_stats = hostapd_sta_clear_stats;
363*e28a4053SRui Paulo 	ops->set_sta_flags = hostapd_set_sta_flags;
364*e28a4053SRui Paulo 	ops->set_drv_ieee8021x = hostapd_set_drv_ieee8021x;
365*e28a4053SRui Paulo 	ops->set_radius_acl_auth = hostapd_set_radius_acl_auth;
366*e28a4053SRui Paulo 	ops->set_radius_acl_expire = hostapd_set_radius_acl_expire;
367*e28a4053SRui Paulo 	ops->set_bss_params = hostapd_set_bss_params;
368*e28a4053SRui Paulo 	ops->set_beacon = hostapd_set_beacon;
369*e28a4053SRui Paulo 	ops->vlan_if_add = hostapd_vlan_if_add;
370*e28a4053SRui Paulo 	ops->vlan_if_remove = hostapd_vlan_if_remove;
371*e28a4053SRui Paulo 	ops->set_wds_sta = hostapd_set_wds_sta;
372*e28a4053SRui Paulo 	ops->set_sta_vlan = hostapd_set_sta_vlan;
373*e28a4053SRui Paulo 	ops->get_inact_sec = hostapd_get_inact_sec;
374*e28a4053SRui Paulo 	ops->sta_deauth = hostapd_sta_deauth;
375*e28a4053SRui Paulo 	ops->sta_disassoc = hostapd_sta_disassoc;
376*e28a4053SRui Paulo 	ops->sta_add = hostapd_sta_add;
377*e28a4053SRui Paulo 	ops->sta_remove = hostapd_sta_remove;
378*e28a4053SRui Paulo 	ops->set_countermeasures = hostapd_set_countermeasures;
379*e28a4053SRui Paulo }
380*e28a4053SRui Paulo 
381*e28a4053SRui Paulo 
382*e28a4053SRui Paulo int hostapd_set_privacy(struct hostapd_data *hapd, int enabled)
383*e28a4053SRui Paulo {
384*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_privacy == NULL)
385*e28a4053SRui Paulo 		return 0;
386*e28a4053SRui Paulo 	return hapd->driver->set_privacy(hapd->drv_priv, enabled);
387*e28a4053SRui Paulo }
388*e28a4053SRui Paulo 
389*e28a4053SRui Paulo 
390*e28a4053SRui Paulo int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem,
391*e28a4053SRui Paulo 			     size_t elem_len)
392*e28a4053SRui Paulo {
393*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_generic_elem == NULL)
394*e28a4053SRui Paulo 		return 0;
395*e28a4053SRui Paulo 	return hapd->driver->set_generic_elem(hapd->drv_priv, elem, elem_len);
396*e28a4053SRui Paulo }
397*e28a4053SRui Paulo 
398*e28a4053SRui Paulo 
399*e28a4053SRui Paulo int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len)
400*e28a4053SRui Paulo {
401*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->hapd_get_ssid == NULL)
402*e28a4053SRui Paulo 		return 0;
403*e28a4053SRui Paulo 	return hapd->driver->hapd_get_ssid(hapd->drv_priv, buf, len);
404*e28a4053SRui Paulo }
405*e28a4053SRui Paulo 
406*e28a4053SRui Paulo 
407*e28a4053SRui Paulo int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len)
408*e28a4053SRui Paulo {
409*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->hapd_set_ssid == NULL)
410*e28a4053SRui Paulo 		return 0;
411*e28a4053SRui Paulo 	return hapd->driver->hapd_set_ssid(hapd->drv_priv, buf, len);
412*e28a4053SRui Paulo }
413*e28a4053SRui Paulo 
414*e28a4053SRui Paulo 
415*e28a4053SRui Paulo int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
416*e28a4053SRui Paulo 		   const char *ifname, const u8 *addr, void *bss_ctx,
417*e28a4053SRui Paulo 		   void **drv_priv, char *force_ifname, u8 *if_addr)
418*e28a4053SRui Paulo {
419*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->if_add == NULL)
420*e28a4053SRui Paulo 		return -1;
421*e28a4053SRui Paulo 	return hapd->driver->if_add(hapd->drv_priv, type, ifname, addr,
422*e28a4053SRui Paulo 				    bss_ctx, drv_priv, force_ifname, if_addr);
423*e28a4053SRui Paulo }
424*e28a4053SRui Paulo 
425*e28a4053SRui Paulo 
426*e28a4053SRui Paulo int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
427*e28a4053SRui Paulo 		      const char *ifname)
428*e28a4053SRui Paulo {
429*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->if_remove == NULL)
430*e28a4053SRui Paulo 		return -1;
431*e28a4053SRui Paulo 	return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
432*e28a4053SRui Paulo }
433*e28a4053SRui Paulo 
434*e28a4053SRui Paulo 
435*e28a4053SRui Paulo int hostapd_set_ieee8021x(struct hostapd_data *hapd,
436*e28a4053SRui Paulo 			  struct wpa_bss_params *params)
437*e28a4053SRui Paulo {
438*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL)
439*e28a4053SRui Paulo 		return 0;
440*e28a4053SRui Paulo 	return hapd->driver->set_ieee8021x(hapd->drv_priv, params);
441*e28a4053SRui Paulo }
442*e28a4053SRui Paulo 
443*e28a4053SRui Paulo 
444*e28a4053SRui Paulo int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
445*e28a4053SRui Paulo 		       const u8 *addr, int idx, u8 *seq)
446*e28a4053SRui Paulo {
447*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->get_seqnum == NULL)
448*e28a4053SRui Paulo 		return 0;
449*e28a4053SRui Paulo 	return hapd->driver->get_seqnum(ifname, hapd->drv_priv, addr, idx,
450*e28a4053SRui Paulo 					seq);
451*e28a4053SRui Paulo }
452*e28a4053SRui Paulo 
453*e28a4053SRui Paulo 
454*e28a4053SRui Paulo int hostapd_flush(struct hostapd_data *hapd)
455*e28a4053SRui Paulo {
456*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->flush == NULL)
457*e28a4053SRui Paulo 		return 0;
458*e28a4053SRui Paulo 	return hapd->driver->flush(hapd->drv_priv);
459*e28a4053SRui Paulo }
460*e28a4053SRui Paulo 
461*e28a4053SRui Paulo 
462*e28a4053SRui Paulo int hostapd_set_freq(struct hostapd_data *hapd, int mode, int freq,
463*e28a4053SRui Paulo 		     int channel, int ht_enabled, int sec_channel_offset)
464*e28a4053SRui Paulo {
465*e28a4053SRui Paulo 	struct hostapd_freq_params data;
466*e28a4053SRui Paulo 	if (hapd->driver == NULL)
467*e28a4053SRui Paulo 		return 0;
468*e28a4053SRui Paulo 	if (hapd->driver->set_freq == NULL)
469*e28a4053SRui Paulo 		return 0;
470*e28a4053SRui Paulo 	os_memset(&data, 0, sizeof(data));
471*e28a4053SRui Paulo 	data.mode = mode;
472*e28a4053SRui Paulo 	data.freq = freq;
473*e28a4053SRui Paulo 	data.channel = channel;
474*e28a4053SRui Paulo 	data.ht_enabled = ht_enabled;
475*e28a4053SRui Paulo 	data.sec_channel_offset = sec_channel_offset;
476*e28a4053SRui Paulo 	return hapd->driver->set_freq(hapd->drv_priv, &data);
477*e28a4053SRui Paulo }
478*e28a4053SRui Paulo 
479*e28a4053SRui Paulo int hostapd_set_rts(struct hostapd_data *hapd, int rts)
480*e28a4053SRui Paulo {
481*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_rts == NULL)
482*e28a4053SRui Paulo 		return 0;
483*e28a4053SRui Paulo 	return hapd->driver->set_rts(hapd->drv_priv, rts);
484*e28a4053SRui Paulo }
485*e28a4053SRui Paulo 
486*e28a4053SRui Paulo 
487*e28a4053SRui Paulo int hostapd_set_frag(struct hostapd_data *hapd, int frag)
488*e28a4053SRui Paulo {
489*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_frag == NULL)
490*e28a4053SRui Paulo 		return 0;
491*e28a4053SRui Paulo 	return hapd->driver->set_frag(hapd->drv_priv, frag);
492*e28a4053SRui Paulo }
493*e28a4053SRui Paulo 
494*e28a4053SRui Paulo 
495*e28a4053SRui Paulo int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
496*e28a4053SRui Paulo 			  int total_flags, int flags_or, int flags_and)
497*e28a4053SRui Paulo {
498*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL)
499*e28a4053SRui Paulo 		return 0;
500*e28a4053SRui Paulo 	return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags,
501*e28a4053SRui Paulo 					   flags_or, flags_and);
502*e28a4053SRui Paulo }
503*e28a4053SRui Paulo 
504*e28a4053SRui Paulo 
505*e28a4053SRui Paulo int hostapd_set_rate_sets(struct hostapd_data *hapd, int *supp_rates,
506*e28a4053SRui Paulo 			  int *basic_rates, int mode)
507*e28a4053SRui Paulo {
508*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_rate_sets == NULL)
509*e28a4053SRui Paulo 		return 0;
510*e28a4053SRui Paulo 	return hapd->driver->set_rate_sets(hapd->drv_priv, supp_rates,
511*e28a4053SRui Paulo 					   basic_rates, mode);
512*e28a4053SRui Paulo }
513*e28a4053SRui Paulo 
514*e28a4053SRui Paulo 
515*e28a4053SRui Paulo int hostapd_set_country(struct hostapd_data *hapd, const char *country)
516*e28a4053SRui Paulo {
517*e28a4053SRui Paulo 	if (hapd->driver == NULL ||
518*e28a4053SRui Paulo 	    hapd->driver->set_country == NULL)
519*e28a4053SRui Paulo 		return 0;
520*e28a4053SRui Paulo 	return hapd->driver->set_country(hapd->drv_priv, country);
521*e28a4053SRui Paulo }
522*e28a4053SRui Paulo 
523*e28a4053SRui Paulo 
524*e28a4053SRui Paulo int hostapd_set_cts_protect(struct hostapd_data *hapd, int value)
525*e28a4053SRui Paulo {
526*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_cts_protect == NULL)
527*e28a4053SRui Paulo 		return 0;
528*e28a4053SRui Paulo 	return hapd->driver->set_cts_protect(hapd->drv_priv, value);
529*e28a4053SRui Paulo }
530*e28a4053SRui Paulo 
531*e28a4053SRui Paulo 
532*e28a4053SRui Paulo int hostapd_set_preamble(struct hostapd_data *hapd, int value)
533*e28a4053SRui Paulo {
534*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_preamble == NULL)
535*e28a4053SRui Paulo 		return 0;
536*e28a4053SRui Paulo 	return hapd->driver->set_preamble(hapd->drv_priv, value);
537*e28a4053SRui Paulo }
538*e28a4053SRui Paulo 
539*e28a4053SRui Paulo 
540*e28a4053SRui Paulo int hostapd_set_short_slot_time(struct hostapd_data *hapd, int value)
541*e28a4053SRui Paulo {
542*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_short_slot_time == NULL)
543*e28a4053SRui Paulo 		return 0;
544*e28a4053SRui Paulo 	return hapd->driver->set_short_slot_time(hapd->drv_priv, value);
545*e28a4053SRui Paulo }
546*e28a4053SRui Paulo 
547*e28a4053SRui Paulo 
548*e28a4053SRui Paulo int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
549*e28a4053SRui Paulo 				int cw_min, int cw_max, int burst_time)
550*e28a4053SRui Paulo {
551*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_tx_queue_params == NULL)
552*e28a4053SRui Paulo 		return 0;
553*e28a4053SRui Paulo 	return hapd->driver->set_tx_queue_params(hapd->drv_priv, queue, aifs,
554*e28a4053SRui Paulo 						 cw_min, cw_max, burst_time);
555*e28a4053SRui Paulo }
556*e28a4053SRui Paulo 
557*e28a4053SRui Paulo 
558*e28a4053SRui Paulo int hostapd_valid_bss_mask(struct hostapd_data *hapd, const u8 *addr,
559*e28a4053SRui Paulo 			   const u8 *mask)
560*e28a4053SRui Paulo {
561*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->valid_bss_mask == NULL)
562*e28a4053SRui Paulo 		return 1;
563*e28a4053SRui Paulo 	return hapd->driver->valid_bss_mask(hapd->drv_priv, addr, mask);
564*e28a4053SRui Paulo }
565*e28a4053SRui Paulo 
566*e28a4053SRui Paulo 
567*e28a4053SRui Paulo struct hostapd_hw_modes *
568*e28a4053SRui Paulo hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
569*e28a4053SRui Paulo 			    u16 *flags)
570*e28a4053SRui Paulo {
571*e28a4053SRui Paulo 	if (hapd->driver == NULL ||
572*e28a4053SRui Paulo 	    hapd->driver->get_hw_feature_data == NULL)
573*e28a4053SRui Paulo 		return NULL;
574*e28a4053SRui Paulo 	return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
575*e28a4053SRui Paulo 						 flags);
576*e28a4053SRui Paulo }
577*e28a4053SRui Paulo 
578*e28a4053SRui Paulo 
579*e28a4053SRui Paulo int hostapd_driver_commit(struct hostapd_data *hapd)
580*e28a4053SRui Paulo {
581*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->commit == NULL)
582*e28a4053SRui Paulo 		return 0;
583*e28a4053SRui Paulo 	return hapd->driver->commit(hapd->drv_priv);
584*e28a4053SRui Paulo }
585*e28a4053SRui Paulo 
586*e28a4053SRui Paulo 
587*e28a4053SRui Paulo int hostapd_set_ht_params(struct hostapd_data *hapd,
588*e28a4053SRui Paulo 			  const u8 *ht_capab, size_t ht_capab_len,
589*e28a4053SRui Paulo 			  const u8 *ht_oper, size_t ht_oper_len)
590*e28a4053SRui Paulo {
591*e28a4053SRui Paulo 	if (hapd->driver == NULL || hapd->driver->set_ht_params == NULL ||
592*e28a4053SRui Paulo 	    ht_capab == NULL || ht_oper == NULL)
593*e28a4053SRui Paulo 		return 0;
594*e28a4053SRui Paulo 	return hapd->driver->set_ht_params(hapd->drv_priv,
595*e28a4053SRui Paulo 					   ht_capab, ht_capab_len,
596*e28a4053SRui Paulo 					   ht_oper, ht_oper_len);
597*e28a4053SRui Paulo }
598*e28a4053SRui Paulo 
599*e28a4053SRui Paulo 
600*e28a4053SRui Paulo int hostapd_drv_none(struct hostapd_data *hapd)
601*e28a4053SRui Paulo {
602*e28a4053SRui Paulo 	return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0;
603*e28a4053SRui Paulo }
604*e28a4053SRui Paulo 
605*e28a4053SRui Paulo 
606*e28a4053SRui Paulo int hostapd_driver_scan(struct hostapd_data *hapd,
607*e28a4053SRui Paulo 			struct wpa_driver_scan_params *params)
608*e28a4053SRui Paulo {
609*e28a4053SRui Paulo 	if (hapd->driver && hapd->driver->scan2)
610*e28a4053SRui Paulo 		return hapd->driver->scan2(hapd->drv_priv, params);
611*e28a4053SRui Paulo 	return -1;
612*e28a4053SRui Paulo }
613*e28a4053SRui Paulo 
614*e28a4053SRui Paulo 
615*e28a4053SRui Paulo struct wpa_scan_results * hostapd_driver_get_scan_results(
616*e28a4053SRui Paulo 	struct hostapd_data *hapd)
617*e28a4053SRui Paulo {
618*e28a4053SRui Paulo 	if (hapd->driver && hapd->driver->get_scan_results2)
619*e28a4053SRui Paulo 		return hapd->driver->get_scan_results2(hapd->drv_priv);
620*e28a4053SRui Paulo 	return NULL;
621*e28a4053SRui Paulo }
622