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