2 * hostapd - Driver operations
3 * Copyright (c) 2009, 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.
18 #include "ap/hostapd.h"
19 #include "ap/ieee802_11.h"
20 #include "ap/sta_info.h"
22 #include "ap_drv_ops.h"
25 static int hostapd_sta_flags_to_drv(int flags)
28 if (flags & WLAN_STA_AUTHORIZED)
29 res |= WPA_STA_AUTHORIZED;
30 if (flags & WLAN_STA_WMM)
32 if (flags & WLAN_STA_SHORT_PREAMBLE)
33 res |= WPA_STA_SHORT_PREAMBLE;
34 if (flags & WLAN_STA_MFP)
40 static int hostapd_set_ap_wps_ie(struct hostapd_data *hapd,
41 const struct wpabuf *beacon,
42 const struct wpabuf *proberesp)
44 if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
46 return hapd->driver->set_ap_wps_ie(hapd->conf->iface, hapd->drv_priv,
51 static int hostapd_send_mgmt_frame(struct hostapd_data *hapd, const void *msg,
54 if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
56 return hapd->driver->send_mlme(hapd->drv_priv, msg, len);
60 static int hostapd_send_eapol(struct hostapd_data *hapd, const u8 *addr,
61 const u8 *data, size_t data_len, int encrypt)
63 if (hapd->driver == NULL || hapd->driver->hapd_send_eapol == NULL)
65 return hapd->driver->hapd_send_eapol(hapd->drv_priv, addr, data,
71 static int hostapd_set_authorized(struct hostapd_data *hapd,
72 struct sta_info *sta, int authorized)
75 return hostapd_sta_set_flags(hapd, sta->addr,
76 hostapd_sta_flags_to_drv(
78 WPA_STA_AUTHORIZED, ~0);
81 return hostapd_sta_set_flags(hapd, sta->addr,
82 hostapd_sta_flags_to_drv(sta->flags),
83 0, ~WPA_STA_AUTHORIZED);
87 static int hostapd_set_key(const char *ifname, struct hostapd_data *hapd,
88 wpa_alg alg, const u8 *addr, int key_idx,
89 int set_tx, const u8 *seq, size_t seq_len,
90 const u8 *key, size_t key_len)
92 if (hapd->driver == NULL || hapd->driver->set_key == NULL)
94 return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr,
95 key_idx, set_tx, seq, seq_len, key,
100 static int hostapd_read_sta_data(struct hostapd_data *hapd,
101 struct hostap_sta_driver_data *data,
104 if (hapd->driver == NULL || hapd->driver->read_sta_data == NULL)
106 return hapd->driver->read_sta_data(hapd->drv_priv, data, addr);
110 static int hostapd_sta_clear_stats(struct hostapd_data *hapd, const u8 *addr)
112 if (hapd->driver == NULL || hapd->driver->sta_clear_stats == NULL)
114 return hapd->driver->sta_clear_stats(hapd->drv_priv, addr);
118 static int hostapd_set_sta_flags(struct hostapd_data *hapd,
119 struct sta_info *sta)
121 int set_flags, total_flags, flags_and, flags_or;
122 total_flags = hostapd_sta_flags_to_drv(sta->flags);
123 set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP;
124 if (!hapd->conf->ieee802_1x && !hapd->conf->wpa &&
125 sta->flags & WLAN_STA_AUTHORIZED)
126 set_flags |= WPA_STA_AUTHORIZED;
127 flags_or = total_flags & set_flags;
128 flags_and = total_flags | ~set_flags;
129 return hostapd_sta_set_flags(hapd, sta->addr, total_flags,
130 flags_or, flags_and);
134 static int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd,
135 const char *ifname, int enabled)
137 struct wpa_bss_params params;
138 os_memset(¶ms, 0, sizeof(params));
139 params.ifname = ifname;
140 params.enabled = enabled;
142 params.wpa = hapd->conf->wpa;
143 params.ieee802_1x = hapd->conf->ieee802_1x;
144 params.wpa_group = hapd->conf->wpa_group;
145 params.wpa_pairwise = hapd->conf->wpa_pairwise;
146 params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt;
147 params.rsn_preauth = hapd->conf->rsn_preauth;
149 return hostapd_set_ieee8021x(hapd, ¶ms);
153 static int hostapd_set_radius_acl_auth(struct hostapd_data *hapd,
154 const u8 *mac, int accepted,
157 if (hapd->driver == NULL || hapd->driver->set_radius_acl_auth == NULL)
159 return hapd->driver->set_radius_acl_auth(hapd->drv_priv, mac, accepted,
164 static int hostapd_set_radius_acl_expire(struct hostapd_data *hapd,
167 if (hapd->driver == NULL ||
168 hapd->driver->set_radius_acl_expire == NULL)
170 return hapd->driver->set_radius_acl_expire(hapd->drv_priv, mac);
174 static int hostapd_set_bss_params(struct hostapd_data *hapd,
179 #ifdef CONFIG_IEEE80211N
180 u8 buf[60], *ht_capab, *ht_oper, *pos;
184 pos = hostapd_eid_ht_capabilities(hapd, pos);
186 pos = hostapd_eid_ht_operation(hapd, pos);
187 if (pos > ht_oper && ht_oper > ht_capab &&
188 hostapd_set_ht_params(hapd->conf->iface, hapd,
189 ht_capab + 2, ht_capab[1],
190 ht_oper + 2, ht_oper[1])) {
191 wpa_printf(MSG_ERROR, "Could not set HT capabilities "
192 "for kernel driver");
196 #endif /* CONFIG_IEEE80211N */
198 if (hostapd_set_cts_protect(hapd, use_protection)) {
199 wpa_printf(MSG_ERROR, "Failed to set CTS protect in kernel "
204 if (hapd->iface->current_mode &&
205 hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G &&
206 hostapd_set_short_slot_time(hapd,
207 hapd->iface->num_sta_no_short_slot_time
209 wpa_printf(MSG_ERROR, "Failed to set Short Slot Time option "
214 if (hapd->iface->num_sta_no_short_preamble == 0 &&
215 hapd->iconf->preamble == SHORT_PREAMBLE)
216 preamble = SHORT_PREAMBLE;
218 preamble = LONG_PREAMBLE;
219 if (hostapd_set_preamble(hapd, preamble)) {
220 wpa_printf(MSG_ERROR, "Could not set preamble for kernel "
229 static int hostapd_set_beacon(const char *ifname, struct hostapd_data *hapd,
230 const u8 *head, size_t head_len,
231 const u8 *tail, size_t tail_len, int dtim_period,
234 if (hapd->driver == NULL || hapd->driver->set_beacon == NULL)
236 return hapd->driver->set_beacon(ifname, hapd->drv_priv,
237 head, head_len, tail, tail_len,
238 dtim_period, beacon_int);
242 static int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname)
244 return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, NULL, NULL);
247 static int hostapd_vlan_if_remove(struct hostapd_data *hapd,
250 return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname);
254 static int hostapd_set_wds_sta(struct hostapd_data *hapd, const u8 *addr,
257 if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL)
259 return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val);
263 static int hostapd_set_sta_vlan(const char *ifname, struct hostapd_data *hapd,
264 const u8 *addr, int vlan_id)
266 if (hapd->driver == NULL || hapd->driver->set_sta_vlan == NULL)
268 return hapd->driver->set_sta_vlan(hapd->drv_priv, addr, ifname,
273 static int hostapd_get_inact_sec(struct hostapd_data *hapd, const u8 *addr)
275 if (hapd->driver == NULL || hapd->driver->get_inact_sec == NULL)
277 return hapd->driver->get_inact_sec(hapd->drv_priv, addr);
281 static int hostapd_sta_deauth(struct hostapd_data *hapd, const u8 *addr,
284 if (hapd->driver == NULL || hapd->driver->sta_deauth == NULL)
286 return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr,
291 static int hostapd_sta_disassoc(struct hostapd_data *hapd, const u8 *addr,
294 if (hapd->driver == NULL || hapd->driver->sta_disassoc == NULL)
296 return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr,
301 static int hostapd_sta_add(const char *ifname, struct hostapd_data *hapd,
302 const u8 *addr, u16 aid, u16 capability,
303 const u8 *supp_rates, size_t supp_rates_len,
305 const struct ieee80211_ht_capabilities *ht_capab)
307 struct hostapd_sta_add_params params;
309 if (hapd->driver == NULL)
311 if (hapd->driver->sta_add == NULL)
314 os_memset(¶ms, 0, sizeof(params));
317 params.capability = capability;
318 params.supp_rates = supp_rates;
319 params.supp_rates_len = supp_rates_len;
320 params.listen_interval = listen_interval;
321 params.ht_capabilities = ht_capab;
322 return hapd->driver->sta_add(ifname, hapd->drv_priv, ¶ms);
326 static int hostapd_sta_remove(struct hostapd_data *hapd, const u8 *addr)
328 if (hapd->driver == NULL || hapd->driver->sta_remove == NULL)
330 return hapd->driver->sta_remove(hapd->drv_priv, addr);
334 static int hostapd_set_countermeasures(struct hostapd_data *hapd, int enabled)
336 if (hapd->driver == NULL ||
337 hapd->driver->hapd_set_countermeasures == NULL)
339 return hapd->driver->hapd_set_countermeasures(hapd->drv_priv, enabled);
343 void hostapd_set_driver_ops(struct hostapd_driver_ops *ops)
345 ops->set_ap_wps_ie = hostapd_set_ap_wps_ie;
346 ops->send_mgmt_frame = hostapd_send_mgmt_frame;
347 ops->send_eapol = hostapd_send_eapol;
348 ops->set_authorized = hostapd_set_authorized;
349 ops->set_key = hostapd_set_key;
350 ops->read_sta_data = hostapd_read_sta_data;
351 ops->sta_clear_stats = hostapd_sta_clear_stats;
352 ops->set_sta_flags = hostapd_set_sta_flags;
353 ops->set_drv_ieee8021x = hostapd_set_drv_ieee8021x;
354 ops->set_radius_acl_auth = hostapd_set_radius_acl_auth;
355 ops->set_radius_acl_expire = hostapd_set_radius_acl_expire;
356 ops->set_bss_params = hostapd_set_bss_params;
357 ops->set_beacon = hostapd_set_beacon;
358 ops->vlan_if_add = hostapd_vlan_if_add;
359 ops->vlan_if_remove = hostapd_vlan_if_remove;
360 ops->set_wds_sta = hostapd_set_wds_sta;
361 ops->set_sta_vlan = hostapd_set_sta_vlan;
362 ops->get_inact_sec = hostapd_get_inact_sec;
363 ops->sta_deauth = hostapd_sta_deauth;
364 ops->sta_disassoc = hostapd_sta_disassoc;
365 ops->sta_add = hostapd_sta_add;
366 ops->sta_remove = hostapd_sta_remove;
367 ops->set_countermeasures = hostapd_set_countermeasures;