2 * hostapd - Driver operations
3 * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
15 #include "utils/includes.h"
17 #include "utils/common.h"
18 #include "drivers/driver.h"
19 #include "common/ieee802_11_defs.h"
21 #include "ieee802_11.h"
23 #include "ap_config.h"
24 #include "ap_drv_ops.h"
27 static int hostapd_sta_flags_to_drv(int 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
)
42 static int hostapd_set_ap_wps_ie(struct hostapd_data
*hapd
)
44 struct wpabuf
*beacon
, *proberesp
;
47 if (hapd
->driver
== NULL
|| hapd
->driver
->set_ap_wps_ie
== NULL
)
50 beacon
= hapd
->wps_beacon_ie
;
51 proberesp
= hapd
->wps_probe_resp_ie
;
53 ret
= hapd
->driver
->set_ap_wps_ie(hapd
->drv_priv
, beacon
, proberesp
);
59 static int hostapd_send_mgmt_frame(struct hostapd_data
*hapd
, const void *msg
,
62 if (hapd
->driver
== NULL
|| hapd
->driver
->send_mlme
== NULL
)
64 return hapd
->driver
->send_mlme(hapd
->drv_priv
, msg
, len
);
68 static int hostapd_send_eapol(struct hostapd_data
*hapd
, const u8
*addr
,
69 const u8
*data
, size_t data_len
, int encrypt
)
71 if (hapd
->driver
== NULL
|| hapd
->driver
->hapd_send_eapol
== NULL
)
73 return hapd
->driver
->hapd_send_eapol(hapd
->drv_priv
, addr
, data
,
79 static int hostapd_set_authorized(struct hostapd_data
*hapd
,
80 struct sta_info
*sta
, int authorized
)
83 return hostapd_sta_set_flags(hapd
, sta
->addr
,
84 hostapd_sta_flags_to_drv(
86 WPA_STA_AUTHORIZED
, ~0);
89 return hostapd_sta_set_flags(hapd
, sta
->addr
,
90 hostapd_sta_flags_to_drv(sta
->flags
),
91 0, ~WPA_STA_AUTHORIZED
);
95 static int hostapd_set_key(const char *ifname
, struct hostapd_data
*hapd
,
96 enum wpa_alg alg
, const u8
*addr
, int key_idx
,
97 int set_tx
, const u8
*seq
, size_t seq_len
,
98 const u8
*key
, size_t key_len
)
100 if (hapd
->driver
== NULL
|| hapd
->driver
->set_key
== NULL
)
102 return hapd
->driver
->set_key(ifname
, hapd
->drv_priv
, alg
, addr
,
103 key_idx
, set_tx
, seq
, seq_len
, key
,
108 static int hostapd_read_sta_data(struct hostapd_data
*hapd
,
109 struct hostap_sta_driver_data
*data
,
112 if (hapd
->driver
== NULL
|| hapd
->driver
->read_sta_data
== NULL
)
114 return hapd
->driver
->read_sta_data(hapd
->drv_priv
, data
, addr
);
118 static int hostapd_sta_clear_stats(struct hostapd_data
*hapd
, const u8
*addr
)
120 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_clear_stats
== NULL
)
122 return hapd
->driver
->sta_clear_stats(hapd
->drv_priv
, addr
);
126 static int hostapd_set_sta_flags(struct hostapd_data
*hapd
,
127 struct sta_info
*sta
)
129 int set_flags
, total_flags
, flags_and
, flags_or
;
130 total_flags
= hostapd_sta_flags_to_drv(sta
->flags
);
131 set_flags
= WPA_STA_SHORT_PREAMBLE
| WPA_STA_WMM
| WPA_STA_MFP
;
132 if (((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
) ||
133 sta
->auth_alg
== WLAN_AUTH_FT
) &&
134 sta
->flags
& WLAN_STA_AUTHORIZED
)
135 set_flags
|= WPA_STA_AUTHORIZED
;
136 flags_or
= total_flags
& set_flags
;
137 flags_and
= total_flags
| ~set_flags
;
138 return hostapd_sta_set_flags(hapd
, sta
->addr
, total_flags
,
139 flags_or
, flags_and
);
143 static int hostapd_set_drv_ieee8021x(struct hostapd_data
*hapd
,
144 const char *ifname
, int enabled
)
146 struct wpa_bss_params params
;
147 os_memset(¶ms
, 0, sizeof(params
));
148 params
.ifname
= ifname
;
149 params
.enabled
= enabled
;
151 params
.wpa
= hapd
->conf
->wpa
;
152 params
.ieee802_1x
= hapd
->conf
->ieee802_1x
;
153 params
.wpa_group
= hapd
->conf
->wpa_group
;
154 params
.wpa_pairwise
= hapd
->conf
->wpa_pairwise
;
155 params
.wpa_key_mgmt
= hapd
->conf
->wpa_key_mgmt
;
156 params
.rsn_preauth
= hapd
->conf
->rsn_preauth
;
158 return hostapd_set_ieee8021x(hapd
, ¶ms
);
162 static int hostapd_set_radius_acl_auth(struct hostapd_data
*hapd
,
163 const u8
*mac
, int accepted
,
166 if (hapd
->driver
== NULL
|| hapd
->driver
->set_radius_acl_auth
== NULL
)
168 return hapd
->driver
->set_radius_acl_auth(hapd
->drv_priv
, mac
, accepted
,
173 static int hostapd_set_radius_acl_expire(struct hostapd_data
*hapd
,
176 if (hapd
->driver
== NULL
||
177 hapd
->driver
->set_radius_acl_expire
== NULL
)
179 return hapd
->driver
->set_radius_acl_expire(hapd
->drv_priv
, mac
);
183 static int hostapd_set_bss_params(struct hostapd_data
*hapd
,
188 #ifdef CONFIG_IEEE80211N
189 u8 buf
[60], *ht_capab
, *ht_oper
, *pos
;
193 pos
= hostapd_eid_ht_capabilities(hapd
, pos
);
195 pos
= hostapd_eid_ht_operation(hapd
, pos
);
196 if (pos
> ht_oper
&& ht_oper
> ht_capab
&&
197 hostapd_set_ht_params(hapd
, ht_capab
+ 2, ht_capab
[1],
198 ht_oper
+ 2, ht_oper
[1])) {
199 wpa_printf(MSG_ERROR
, "Could not set HT capabilities "
200 "for kernel driver");
204 #endif /* CONFIG_IEEE80211N */
206 if (hostapd_set_cts_protect(hapd
, use_protection
)) {
207 wpa_printf(MSG_ERROR
, "Failed to set CTS protect in kernel "
212 if (hapd
->iface
->current_mode
&&
213 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
214 hostapd_set_short_slot_time(hapd
,
215 hapd
->iface
->num_sta_no_short_slot_time
217 wpa_printf(MSG_ERROR
, "Failed to set Short Slot Time option "
222 if (hapd
->iface
->num_sta_no_short_preamble
== 0 &&
223 hapd
->iconf
->preamble
== SHORT_PREAMBLE
)
224 preamble
= SHORT_PREAMBLE
;
226 preamble
= LONG_PREAMBLE
;
227 if (hostapd_set_preamble(hapd
, preamble
)) {
228 wpa_printf(MSG_ERROR
, "Could not set preamble for kernel "
237 static int hostapd_set_beacon(struct hostapd_data
*hapd
,
238 const u8
*head
, size_t head_len
,
239 const u8
*tail
, size_t tail_len
, int dtim_period
,
242 if (hapd
->driver
== NULL
|| hapd
->driver
->set_beacon
== NULL
)
244 return hapd
->driver
->set_beacon(hapd
->drv_priv
,
245 head
, head_len
, tail
, tail_len
,
246 dtim_period
, beacon_int
);
250 static int hostapd_vlan_if_add(struct hostapd_data
*hapd
, const char *ifname
)
252 char force_ifname
[IFNAMSIZ
];
253 u8 if_addr
[ETH_ALEN
];
254 return hostapd_if_add(hapd
, WPA_IF_AP_VLAN
, ifname
, NULL
, NULL
, NULL
,
255 force_ifname
, if_addr
);
258 static int hostapd_vlan_if_remove(struct hostapd_data
*hapd
,
261 return hostapd_if_remove(hapd
, WPA_IF_AP_VLAN
, ifname
);
265 static int hostapd_set_wds_sta(struct hostapd_data
*hapd
, const u8
*addr
,
268 if (hapd
->driver
== NULL
|| hapd
->driver
->set_wds_sta
== NULL
)
270 return hapd
->driver
->set_wds_sta(hapd
->drv_priv
, addr
, aid
, val
);
274 static int hostapd_set_sta_vlan(const char *ifname
, struct hostapd_data
*hapd
,
275 const u8
*addr
, int vlan_id
)
277 if (hapd
->driver
== NULL
|| hapd
->driver
->set_sta_vlan
== NULL
)
279 return hapd
->driver
->set_sta_vlan(hapd
->drv_priv
, addr
, ifname
,
284 static int hostapd_get_inact_sec(struct hostapd_data
*hapd
, const u8
*addr
)
286 if (hapd
->driver
== NULL
|| hapd
->driver
->get_inact_sec
== NULL
)
288 return hapd
->driver
->get_inact_sec(hapd
->drv_priv
, addr
);
292 static int hostapd_sta_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
295 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_deauth
== NULL
)
297 return hapd
->driver
->sta_deauth(hapd
->drv_priv
, hapd
->own_addr
, addr
,
302 static int hostapd_sta_disassoc(struct hostapd_data
*hapd
, const u8
*addr
,
305 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_disassoc
== NULL
)
307 return hapd
->driver
->sta_disassoc(hapd
->drv_priv
, hapd
->own_addr
, addr
,
312 static int hostapd_sta_add(struct hostapd_data
*hapd
,
313 const u8
*addr
, u16 aid
, u16 capability
,
314 const u8
*supp_rates
, size_t supp_rates_len
,
316 const struct ieee80211_ht_capabilities
*ht_capab
)
318 struct hostapd_sta_add_params params
;
320 if (hapd
->driver
== NULL
)
322 if (hapd
->driver
->sta_add
== NULL
)
325 os_memset(¶ms
, 0, sizeof(params
));
328 params
.capability
= capability
;
329 params
.supp_rates
= supp_rates
;
330 params
.supp_rates_len
= supp_rates_len
;
331 params
.listen_interval
= listen_interval
;
332 params
.ht_capabilities
= ht_capab
;
333 return hapd
->driver
->sta_add(hapd
->drv_priv
, ¶ms
);
337 static int hostapd_sta_remove(struct hostapd_data
*hapd
, const u8
*addr
)
339 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_remove
== NULL
)
341 return hapd
->driver
->sta_remove(hapd
->drv_priv
, addr
);
345 static int hostapd_set_countermeasures(struct hostapd_data
*hapd
, int enabled
)
347 if (hapd
->driver
== NULL
||
348 hapd
->driver
->hapd_set_countermeasures
== NULL
)
350 return hapd
->driver
->hapd_set_countermeasures(hapd
->drv_priv
, enabled
);
354 void hostapd_set_driver_ops(struct hostapd_driver_ops
*ops
)
356 ops
->set_ap_wps_ie
= hostapd_set_ap_wps_ie
;
357 ops
->send_mgmt_frame
= hostapd_send_mgmt_frame
;
358 ops
->send_eapol
= hostapd_send_eapol
;
359 ops
->set_authorized
= hostapd_set_authorized
;
360 ops
->set_key
= hostapd_set_key
;
361 ops
->read_sta_data
= hostapd_read_sta_data
;
362 ops
->sta_clear_stats
= hostapd_sta_clear_stats
;
363 ops
->set_sta_flags
= hostapd_set_sta_flags
;
364 ops
->set_drv_ieee8021x
= hostapd_set_drv_ieee8021x
;
365 ops
->set_radius_acl_auth
= hostapd_set_radius_acl_auth
;
366 ops
->set_radius_acl_expire
= hostapd_set_radius_acl_expire
;
367 ops
->set_bss_params
= hostapd_set_bss_params
;
368 ops
->set_beacon
= hostapd_set_beacon
;
369 ops
->vlan_if_add
= hostapd_vlan_if_add
;
370 ops
->vlan_if_remove
= hostapd_vlan_if_remove
;
371 ops
->set_wds_sta
= hostapd_set_wds_sta
;
372 ops
->set_sta_vlan
= hostapd_set_sta_vlan
;
373 ops
->get_inact_sec
= hostapd_get_inact_sec
;
374 ops
->sta_deauth
= hostapd_sta_deauth
;
375 ops
->sta_disassoc
= hostapd_sta_disassoc
;
376 ops
->sta_add
= hostapd_sta_add
;
377 ops
->sta_remove
= hostapd_sta_remove
;
378 ops
->set_countermeasures
= hostapd_set_countermeasures
;
382 int hostapd_set_privacy(struct hostapd_data
*hapd
, int enabled
)
384 if (hapd
->driver
== NULL
|| hapd
->driver
->set_privacy
== NULL
)
386 return hapd
->driver
->set_privacy(hapd
->drv_priv
, enabled
);
390 int hostapd_set_generic_elem(struct hostapd_data
*hapd
, const u8
*elem
,
393 if (hapd
->driver
== NULL
|| hapd
->driver
->set_generic_elem
== NULL
)
395 return hapd
->driver
->set_generic_elem(hapd
->drv_priv
, elem
, elem_len
);
399 int hostapd_get_ssid(struct hostapd_data
*hapd
, u8
*buf
, size_t len
)
401 if (hapd
->driver
== NULL
|| hapd
->driver
->hapd_get_ssid
== NULL
)
403 return hapd
->driver
->hapd_get_ssid(hapd
->drv_priv
, buf
, len
);
407 int hostapd_set_ssid(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
)
409 if (hapd
->driver
== NULL
|| hapd
->driver
->hapd_set_ssid
== NULL
)
411 return hapd
->driver
->hapd_set_ssid(hapd
->drv_priv
, buf
, len
);
415 int hostapd_if_add(struct hostapd_data
*hapd
, enum wpa_driver_if_type type
,
416 const char *ifname
, const u8
*addr
, void *bss_ctx
,
417 void **drv_priv
, char *force_ifname
, u8
*if_addr
)
419 if (hapd
->driver
== NULL
|| hapd
->driver
->if_add
== NULL
)
421 return hapd
->driver
->if_add(hapd
->drv_priv
, type
, ifname
, addr
,
422 bss_ctx
, drv_priv
, force_ifname
, if_addr
);
426 int hostapd_if_remove(struct hostapd_data
*hapd
, enum wpa_driver_if_type type
,
429 if (hapd
->driver
== NULL
|| hapd
->driver
->if_remove
== NULL
)
431 return hapd
->driver
->if_remove(hapd
->drv_priv
, type
, ifname
);
435 int hostapd_set_ieee8021x(struct hostapd_data
*hapd
,
436 struct wpa_bss_params
*params
)
438 if (hapd
->driver
== NULL
|| hapd
->driver
->set_ieee8021x
== NULL
)
440 return hapd
->driver
->set_ieee8021x(hapd
->drv_priv
, params
);
444 int hostapd_get_seqnum(const char *ifname
, struct hostapd_data
*hapd
,
445 const u8
*addr
, int idx
, u8
*seq
)
447 if (hapd
->driver
== NULL
|| hapd
->driver
->get_seqnum
== NULL
)
449 return hapd
->driver
->get_seqnum(ifname
, hapd
->drv_priv
, addr
, idx
,
454 int hostapd_flush(struct hostapd_data
*hapd
)
456 if (hapd
->driver
== NULL
|| hapd
->driver
->flush
== NULL
)
458 return hapd
->driver
->flush(hapd
->drv_priv
);
462 int hostapd_set_freq(struct hostapd_data
*hapd
, int mode
, int freq
,
463 int channel
, int ht_enabled
, int sec_channel_offset
)
465 struct hostapd_freq_params data
;
466 if (hapd
->driver
== NULL
)
468 if (hapd
->driver
->set_freq
== NULL
)
470 os_memset(&data
, 0, sizeof(data
));
473 data
.channel
= channel
;
474 data
.ht_enabled
= ht_enabled
;
475 data
.sec_channel_offset
= sec_channel_offset
;
476 return hapd
->driver
->set_freq(hapd
->drv_priv
, &data
);
479 int hostapd_set_rts(struct hostapd_data
*hapd
, int rts
)
481 if (hapd
->driver
== NULL
|| hapd
->driver
->set_rts
== NULL
)
483 return hapd
->driver
->set_rts(hapd
->drv_priv
, rts
);
487 int hostapd_set_frag(struct hostapd_data
*hapd
, int frag
)
489 if (hapd
->driver
== NULL
|| hapd
->driver
->set_frag
== NULL
)
491 return hapd
->driver
->set_frag(hapd
->drv_priv
, frag
);
495 int hostapd_sta_set_flags(struct hostapd_data
*hapd
, u8
*addr
,
496 int total_flags
, int flags_or
, int flags_and
)
498 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_set_flags
== NULL
)
500 return hapd
->driver
->sta_set_flags(hapd
->drv_priv
, addr
, total_flags
,
501 flags_or
, flags_and
);
505 int hostapd_set_rate_sets(struct hostapd_data
*hapd
, int *supp_rates
,
506 int *basic_rates
, int mode
)
508 if (hapd
->driver
== NULL
|| hapd
->driver
->set_rate_sets
== NULL
)
510 return hapd
->driver
->set_rate_sets(hapd
->drv_priv
, supp_rates
,
515 int hostapd_set_country(struct hostapd_data
*hapd
, const char *country
)
517 if (hapd
->driver
== NULL
||
518 hapd
->driver
->set_country
== NULL
)
520 return hapd
->driver
->set_country(hapd
->drv_priv
, country
);
524 int hostapd_set_cts_protect(struct hostapd_data
*hapd
, int value
)
526 if (hapd
->driver
== NULL
|| hapd
->driver
->set_cts_protect
== NULL
)
528 return hapd
->driver
->set_cts_protect(hapd
->drv_priv
, value
);
532 int hostapd_set_preamble(struct hostapd_data
*hapd
, int value
)
534 if (hapd
->driver
== NULL
|| hapd
->driver
->set_preamble
== NULL
)
536 return hapd
->driver
->set_preamble(hapd
->drv_priv
, value
);
540 int hostapd_set_short_slot_time(struct hostapd_data
*hapd
, int value
)
542 if (hapd
->driver
== NULL
|| hapd
->driver
->set_short_slot_time
== NULL
)
544 return hapd
->driver
->set_short_slot_time(hapd
->drv_priv
, value
);
548 int hostapd_set_tx_queue_params(struct hostapd_data
*hapd
, int queue
, int aifs
,
549 int cw_min
, int cw_max
, int burst_time
)
551 if (hapd
->driver
== NULL
|| hapd
->driver
->set_tx_queue_params
== NULL
)
553 return hapd
->driver
->set_tx_queue_params(hapd
->drv_priv
, queue
, aifs
,
554 cw_min
, cw_max
, burst_time
);
558 int hostapd_valid_bss_mask(struct hostapd_data
*hapd
, const u8
*addr
,
561 if (hapd
->driver
== NULL
|| hapd
->driver
->valid_bss_mask
== NULL
)
563 return hapd
->driver
->valid_bss_mask(hapd
->drv_priv
, addr
, mask
);
567 struct hostapd_hw_modes
*
568 hostapd_get_hw_feature_data(struct hostapd_data
*hapd
, u16
*num_modes
,
571 if (hapd
->driver
== NULL
||
572 hapd
->driver
->get_hw_feature_data
== NULL
)
574 return hapd
->driver
->get_hw_feature_data(hapd
->drv_priv
, num_modes
,
579 int hostapd_driver_commit(struct hostapd_data
*hapd
)
581 if (hapd
->driver
== NULL
|| hapd
->driver
->commit
== NULL
)
583 return hapd
->driver
->commit(hapd
->drv_priv
);
587 int hostapd_set_ht_params(struct hostapd_data
*hapd
,
588 const u8
*ht_capab
, size_t ht_capab_len
,
589 const u8
*ht_oper
, size_t ht_oper_len
)
591 if (hapd
->driver
== NULL
|| hapd
->driver
->set_ht_params
== NULL
||
592 ht_capab
== NULL
|| ht_oper
== NULL
)
594 return hapd
->driver
->set_ht_params(hapd
->drv_priv
,
595 ht_capab
, ht_capab_len
,
596 ht_oper
, ht_oper_len
);
600 int hostapd_drv_none(struct hostapd_data
*hapd
)
602 return hapd
->driver
&& os_strcmp(hapd
->driver
->name
, "none") == 0;
606 int hostapd_driver_scan(struct hostapd_data
*hapd
,
607 struct wpa_driver_scan_params
*params
)
609 if (hapd
->driver
&& hapd
->driver
->scan2
)
610 return hapd
->driver
->scan2(hapd
->drv_priv
, params
);
615 struct wpa_scan_results
* hostapd_driver_get_scan_results(
616 struct hostapd_data
*hapd
)
618 if (hapd
->driver
&& hapd
->driver
->get_scan_results2
)
619 return hapd
->driver
->get_scan_results2(hapd
->drv_priv
);