Branch data Line data Source code
1 : : /*
2 : : * WPA Supplicant - Basic AP mode support routines
3 : : * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
4 : : * Copyright (c) 2009, Atheros Communications
5 : : *
6 : : * This software may be distributed under the terms of the BSD license.
7 : : * See README for more details.
8 : : */
9 : :
10 : : #include "utils/includes.h"
11 : :
12 : : #include "utils/common.h"
13 : : #include "utils/eloop.h"
14 : : #include "utils/uuid.h"
15 : : #include "common/ieee802_11_defs.h"
16 : : #include "common/wpa_ctrl.h"
17 : : #include "eapol_supp/eapol_supp_sm.h"
18 : : #include "ap/hostapd.h"
19 : : #include "ap/ap_config.h"
20 : : #include "ap/ap_drv_ops.h"
21 : : #ifdef NEED_AP_MLME
22 : : #include "ap/ieee802_11.h"
23 : : #endif /* NEED_AP_MLME */
24 : : #include "ap/beacon.h"
25 : : #include "ap/ieee802_1x.h"
26 : : #include "ap/wps_hostapd.h"
27 : : #include "ap/ctrl_iface_ap.h"
28 : : #include "wps/wps.h"
29 : : #include "common/ieee802_11_defs.h"
30 : : #include "config_ssid.h"
31 : : #include "config.h"
32 : : #include "wpa_supplicant_i.h"
33 : : #include "driver_i.h"
34 : : #include "p2p_supplicant.h"
35 : : #include "ap.h"
36 : : #include "ap/sta_info.h"
37 : : #include "notify.h"
38 : :
39 : :
40 : : #ifdef CONFIG_WPS
41 : : static void wpas_wps_ap_pin_timeout(void *eloop_data, void *user_ctx);
42 : : #endif /* CONFIG_WPS */
43 : :
44 : :
45 : : #ifdef CONFIG_IEEE80211N
46 : 0 : static void wpas_conf_ap_vht(struct wpa_supplicant *wpa_s,
47 : : struct hostapd_config *conf,
48 : : struct hostapd_hw_modes *mode)
49 : : {
50 : 0 : u8 center_chan = 0;
51 : 0 : u8 channel = conf->channel;
52 : :
53 [ # # ]: 0 : if (!conf->secondary_channel)
54 : 0 : goto no_vht;
55 : :
56 : 0 : center_chan = wpas_p2p_get_vht80_center(wpa_s, mode, channel);
57 [ # # ]: 0 : if (!center_chan)
58 : 0 : goto no_vht;
59 : :
60 : : /* Use 80 MHz channel */
61 : 0 : conf->vht_oper_chwidth = 1;
62 : 0 : conf->vht_oper_centr_freq_seg0_idx = center_chan;
63 : 0 : return;
64 : :
65 : : no_vht:
66 : 0 : conf->vht_oper_centr_freq_seg0_idx =
67 : 0 : channel + conf->secondary_channel * 2;
68 : : }
69 : : #endif /* CONFIG_IEEE80211N */
70 : :
71 : :
72 : 55 : static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
73 : : struct wpa_ssid *ssid,
74 : : struct hostapd_config *conf)
75 : : {
76 : 55 : struct hostapd_bss_config *bss = conf->bss[0];
77 : :
78 : 55 : conf->driver = wpa_s->driver;
79 : :
80 : 55 : os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface));
81 : :
82 : 55 : conf->hw_mode = ieee80211_freq_to_chan(ssid->frequency,
83 : : &conf->channel);
84 [ - + ]: 55 : if (conf->hw_mode == NUM_HOSTAPD_MODES) {
85 : 0 : wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz",
86 : : ssid->frequency);
87 : 0 : return -1;
88 : : }
89 : :
90 : : /* TODO: enable HT40 if driver supports it;
91 : : * drop to 11b if driver does not support 11g */
92 : :
93 : : #ifdef CONFIG_IEEE80211N
94 : : /*
95 : : * Enable HT20 if the driver supports it, by setting conf->ieee80211n
96 : : * and a mask of allowed capabilities within conf->ht_capab.
97 : : * Using default config settings for: conf->ht_op_mode_fixed,
98 : : * conf->secondary_channel, conf->require_ht
99 : : */
100 [ + - ]: 55 : if (wpa_s->hw.modes) {
101 : 55 : struct hostapd_hw_modes *mode = NULL;
102 : 55 : int i, no_ht = 0;
103 [ + - ]: 55 : for (i = 0; i < wpa_s->hw.num_modes; i++) {
104 [ + - ]: 55 : if (wpa_s->hw.modes[i].mode == conf->hw_mode) {
105 : 55 : mode = &wpa_s->hw.modes[i];
106 : 55 : break;
107 : : }
108 : : }
109 : :
110 : : #ifdef CONFIG_HT_OVERRIDES
111 : : if (ssid->disable_ht) {
112 : : conf->ieee80211n = 0;
113 : : conf->ht_capab = 0;
114 : : no_ht = 1;
115 : : }
116 : : #endif /* CONFIG_HT_OVERRIDES */
117 : :
118 [ + - ][ + - ]: 55 : if (!no_ht && mode && mode->ht_capab) {
[ + - ]
119 : 55 : conf->ieee80211n = 1;
120 : : #ifdef CONFIG_P2P
121 [ - + ][ # # ]: 55 : if (conf->hw_mode == HOSTAPD_MODE_IEEE80211A &&
122 : 0 : (mode->ht_capab &
123 [ # # ]: 0 : HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
124 : 0 : ssid->ht40)
125 : 0 : conf->secondary_channel =
126 : 0 : wpas_p2p_get_ht40_mode(wpa_s, mode,
127 : 0 : conf->channel);
128 [ - + ]: 55 : if (conf->secondary_channel)
129 : 0 : conf->ht_capab |=
130 : : HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
131 : : #endif /* CONFIG_P2P */
132 : :
133 : : /*
134 : : * white-list capabilities that won't cause issues
135 : : * to connecting stations, while leaving the current
136 : : * capabilities intact (currently disabled SMPS).
137 : : */
138 : 55 : conf->ht_capab |= mode->ht_capab &
139 : : (HT_CAP_INFO_GREEN_FIELD |
140 : : HT_CAP_INFO_SHORT_GI20MHZ |
141 : : HT_CAP_INFO_SHORT_GI40MHZ |
142 : : HT_CAP_INFO_RX_STBC_MASK |
143 : : HT_CAP_INFO_MAX_AMSDU_SIZE);
144 : :
145 [ + - ][ - + ]: 55 : if (mode->vht_capab && ssid->vht) {
146 : 0 : conf->ieee80211ac = 1;
147 : 0 : wpas_conf_ap_vht(wpa_s, conf, mode);
148 : : }
149 : : }
150 : : }
151 : : #endif /* CONFIG_IEEE80211N */
152 : :
153 : : #ifdef CONFIG_P2P
154 [ + - ][ + + ]: 55 : if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G &&
155 [ + - ]: 32 : (ssid->mode == WPAS_MODE_P2P_GO ||
156 : 32 : ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)) {
157 : : /* Remove 802.11b rates from supported and basic rate sets */
158 : 55 : int *list = os_malloc(4 * sizeof(int));
159 [ + - ]: 55 : if (list) {
160 : 55 : list[0] = 60;
161 : 55 : list[1] = 120;
162 : 55 : list[2] = 240;
163 : 55 : list[3] = -1;
164 : : }
165 : 55 : conf->basic_rates = list;
166 : :
167 : 55 : list = os_malloc(9 * sizeof(int));
168 [ + - ]: 55 : if (list) {
169 : 55 : list[0] = 60;
170 : 55 : list[1] = 90;
171 : 55 : list[2] = 120;
172 : 55 : list[3] = 180;
173 : 55 : list[4] = 240;
174 : 55 : list[5] = 360;
175 : 55 : list[6] = 480;
176 : 55 : list[7] = 540;
177 : 55 : list[8] = -1;
178 : : }
179 : 55 : conf->supported_rates = list;
180 : : }
181 : :
182 : 55 : bss->isolate = !wpa_s->conf->p2p_intra_bss;
183 : 55 : bss->force_per_enrollee_psk = wpa_s->global->p2p_per_sta_psk;
184 : : #endif /* CONFIG_P2P */
185 : :
186 [ - + ]: 55 : if (ssid->ssid_len == 0) {
187 : 0 : wpa_printf(MSG_ERROR, "No SSID configured for AP mode");
188 : 0 : return -1;
189 : : }
190 : 55 : os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len);
191 : 55 : bss->ssid.ssid_len = ssid->ssid_len;
192 : 55 : bss->ssid.ssid_set = 1;
193 : :
194 : 55 : bss->ignore_broadcast_ssid = ssid->ignore_broadcast_ssid;
195 : :
196 [ + - ]: 55 : if (ssid->auth_alg)
197 : 55 : bss->auth_algs = ssid->auth_alg;
198 : :
199 [ + - ]: 55 : if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt))
200 : 55 : bss->wpa = ssid->proto;
201 : 55 : bss->wpa_key_mgmt = ssid->key_mgmt;
202 : 55 : bss->wpa_pairwise = ssid->pairwise_cipher;
203 [ + - ]: 55 : if (ssid->psk_set) {
204 : 55 : os_free(bss->ssid.wpa_psk);
205 : 55 : bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
206 [ - + ]: 55 : if (bss->ssid.wpa_psk == NULL)
207 : 0 : return -1;
208 : 55 : os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN);
209 : 55 : bss->ssid.wpa_psk->group = 1;
210 [ # # ]: 0 : } else if (ssid->passphrase) {
211 : 0 : bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase);
212 [ # # ][ # # ]: 0 : } else if (ssid->wep_key_len[0] || ssid->wep_key_len[1] ||
[ # # ]
213 [ # # ]: 0 : ssid->wep_key_len[2] || ssid->wep_key_len[3]) {
214 : 0 : struct hostapd_wep_keys *wep = &bss->ssid.wep;
215 : : int i;
216 [ # # ]: 0 : for (i = 0; i < NUM_WEP_KEYS; i++) {
217 [ # # ]: 0 : if (ssid->wep_key_len[i] == 0)
218 : 0 : continue;
219 : 0 : wep->key[i] = os_malloc(ssid->wep_key_len[i]);
220 [ # # ]: 0 : if (wep->key[i] == NULL)
221 : 0 : return -1;
222 : 0 : os_memcpy(wep->key[i], ssid->wep_key[i],
223 : : ssid->wep_key_len[i]);
224 : 0 : wep->len[i] = ssid->wep_key_len[i];
225 : : }
226 : 0 : wep->idx = ssid->wep_tx_keyidx;
227 : 0 : wep->keys_set = 1;
228 : : }
229 : :
230 [ + - ]: 55 : if (ssid->ap_max_inactivity)
231 : 55 : bss->ap_max_inactivity = ssid->ap_max_inactivity;
232 : :
233 [ - + ]: 55 : if (ssid->dtim_period)
234 : 0 : bss->dtim_period = ssid->dtim_period;
235 [ - + ]: 55 : else if (wpa_s->conf->dtim_period)
236 : 0 : bss->dtim_period = wpa_s->conf->dtim_period;
237 : :
238 [ - + ]: 55 : if (ssid->beacon_int)
239 : 0 : conf->beacon_int = ssid->beacon_int;
240 [ - + ]: 55 : else if (wpa_s->conf->beacon_int)
241 : 0 : conf->beacon_int = wpa_s->conf->beacon_int;
242 : :
243 [ + - ][ + - ]: 55 : if ((bss->wpa & 2) && bss->rsn_pairwise == 0)
244 : 55 : bss->rsn_pairwise = bss->wpa_pairwise;
245 : 55 : bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa, bss->wpa_pairwise,
246 : : bss->rsn_pairwise);
247 : :
248 [ + - ][ - + ]: 55 : if (bss->wpa && bss->ieee802_1x)
249 : 0 : bss->ssid.security_policy = SECURITY_WPA;
250 [ + - ]: 55 : else if (bss->wpa)
251 : 55 : bss->ssid.security_policy = SECURITY_WPA_PSK;
252 [ # # ]: 0 : else if (bss->ieee802_1x) {
253 : 0 : int cipher = WPA_CIPHER_NONE;
254 : 0 : bss->ssid.security_policy = SECURITY_IEEE_802_1X;
255 : 0 : bss->ssid.wep.default_len = bss->default_wep_key_len;
256 [ # # ]: 0 : if (bss->default_wep_key_len)
257 : 0 : cipher = bss->default_wep_key_len >= 13 ?
258 [ # # ]: 0 : WPA_CIPHER_WEP104 : WPA_CIPHER_WEP40;
259 : 0 : bss->wpa_group = cipher;
260 : 0 : bss->wpa_pairwise = cipher;
261 : 0 : bss->rsn_pairwise = cipher;
262 [ # # ]: 0 : } else if (bss->ssid.wep.keys_set) {
263 : 0 : int cipher = WPA_CIPHER_WEP40;
264 [ # # ]: 0 : if (bss->ssid.wep.len[0] >= 13)
265 : 0 : cipher = WPA_CIPHER_WEP104;
266 : 0 : bss->ssid.security_policy = SECURITY_STATIC_WEP;
267 : 0 : bss->wpa_group = cipher;
268 : 0 : bss->wpa_pairwise = cipher;
269 : 0 : bss->rsn_pairwise = cipher;
270 : : } else {
271 : 0 : bss->ssid.security_policy = SECURITY_PLAINTEXT;
272 : 0 : bss->wpa_group = WPA_CIPHER_NONE;
273 : 0 : bss->wpa_pairwise = WPA_CIPHER_NONE;
274 : 0 : bss->rsn_pairwise = WPA_CIPHER_NONE;
275 : : }
276 : :
277 [ + - ][ + - ]: 55 : if (bss->wpa_group_rekey < 86400 && (bss->wpa & 2) &&
[ - + ]
278 [ # # ]: 0 : (bss->wpa_group == WPA_CIPHER_CCMP ||
279 [ # # ]: 0 : bss->wpa_group == WPA_CIPHER_GCMP ||
280 [ # # ]: 0 : bss->wpa_group == WPA_CIPHER_CCMP_256 ||
281 : 0 : bss->wpa_group == WPA_CIPHER_GCMP_256)) {
282 : : /*
283 : : * Strong ciphers do not need frequent rekeying, so increase
284 : : * the default GTK rekeying period to 24 hours.
285 : : */
286 : 55 : bss->wpa_group_rekey = 86400;
287 : : }
288 : :
289 : : #ifdef CONFIG_WPS
290 : : /*
291 : : * Enable WPS by default for open and WPA/WPA2-Personal network, but
292 : : * require user interaction to actually use it. Only the internal
293 : : * Registrar is supported.
294 : : */
295 [ - + ][ # # ]: 55 : if (bss->ssid.security_policy != SECURITY_WPA_PSK &&
296 : 0 : bss->ssid.security_policy != SECURITY_PLAINTEXT)
297 : 0 : goto no_wps;
298 : : #ifdef CONFIG_WPS2
299 [ + - ][ + - ]: 55 : if (bss->ssid.security_policy == SECURITY_WPA_PSK &&
300 [ + - ]: 55 : (!(bss->rsn_pairwise & WPA_CIPHER_CCMP) || !(bss->wpa & 2)))
301 : : goto no_wps; /* WPS2 does not allow WPA/TKIP-only
302 : : * configuration */
303 : : #endif /* CONFIG_WPS2 */
304 : 55 : bss->eap_server = 1;
305 : :
306 [ + - ]: 55 : if (!ssid->ignore_broadcast_ssid)
307 : 55 : bss->wps_state = 2;
308 : :
309 : 55 : bss->ap_setup_locked = 2;
310 [ - + ]: 55 : if (wpa_s->conf->config_methods)
311 : 0 : bss->config_methods = os_strdup(wpa_s->conf->config_methods);
312 : 55 : os_memcpy(bss->device_type, wpa_s->conf->device_type,
313 : : WPS_DEV_TYPE_LEN);
314 [ + - ]: 55 : if (wpa_s->conf->device_name) {
315 : 55 : bss->device_name = os_strdup(wpa_s->conf->device_name);
316 : 55 : bss->friendly_name = os_strdup(wpa_s->conf->device_name);
317 : : }
318 [ - + ]: 55 : if (wpa_s->conf->manufacturer)
319 : 0 : bss->manufacturer = os_strdup(wpa_s->conf->manufacturer);
320 [ - + ]: 55 : if (wpa_s->conf->model_name)
321 : 0 : bss->model_name = os_strdup(wpa_s->conf->model_name);
322 [ - + ]: 55 : if (wpa_s->conf->model_number)
323 : 0 : bss->model_number = os_strdup(wpa_s->conf->model_number);
324 [ - + ]: 55 : if (wpa_s->conf->serial_number)
325 : 0 : bss->serial_number = os_strdup(wpa_s->conf->serial_number);
326 [ + - ]: 55 : if (is_nil_uuid(wpa_s->conf->uuid))
327 : 55 : os_memcpy(bss->uuid, wpa_s->wps->uuid, WPS_UUID_LEN);
328 : : else
329 : 0 : os_memcpy(bss->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);
330 : 55 : os_memcpy(bss->os_version, wpa_s->conf->os_version, 4);
331 : 55 : bss->pbc_in_m1 = wpa_s->conf->pbc_in_m1;
332 : : no_wps:
333 : : #endif /* CONFIG_WPS */
334 : :
335 [ - + ][ # # ]: 55 : if (wpa_s->max_stations &&
336 : 0 : wpa_s->max_stations < wpa_s->conf->max_num_sta)
337 : 0 : bss->max_num_sta = wpa_s->max_stations;
338 : : else
339 : 55 : bss->max_num_sta = wpa_s->conf->max_num_sta;
340 : :
341 : 55 : bss->disassoc_low_ack = wpa_s->conf->disassoc_low_ack;
342 : :
343 [ - + ]: 55 : if (wpa_s->conf->ap_vendor_elements) {
344 : 0 : bss->vendor_elements =
345 : 0 : wpabuf_dup(wpa_s->conf->ap_vendor_elements);
346 : : }
347 : :
348 : 55 : return 0;
349 : : }
350 : :
351 : :
352 : 0 : static void ap_public_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
353 : : {
354 : : #ifdef CONFIG_P2P
355 : 0 : struct wpa_supplicant *wpa_s = ctx;
356 : : const struct ieee80211_mgmt *mgmt;
357 : : size_t hdr_len;
358 : :
359 : 0 : mgmt = (const struct ieee80211_mgmt *) buf;
360 : 0 : hdr_len = (const u8 *) &mgmt->u.action.u.vs_public_action.action - buf;
361 [ # # ]: 0 : if (hdr_len > len)
362 : 0 : return;
363 : 0 : wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
364 : 0 : mgmt->u.action.category,
365 : : &mgmt->u.action.u.vs_public_action.action,
366 : : len - hdr_len, freq);
367 : : #endif /* CONFIG_P2P */
368 : : }
369 : :
370 : :
371 : 60 : static void ap_wps_event_cb(void *ctx, enum wps_event event,
372 : : union wps_event_data *data)
373 : : {
374 : : #ifdef CONFIG_P2P
375 : 60 : struct wpa_supplicant *wpa_s = ctx;
376 : :
377 [ - + ]: 60 : if (event == WPS_EV_FAIL) {
378 : 0 : struct wps_event_fail *fail = &data->fail;
379 : :
380 [ # # ][ # # ]: 0 : if (wpa_s->parent && wpa_s->parent != wpa_s &&
[ # # ]
381 : 0 : wpa_s == wpa_s->global->p2p_group_formation) {
382 : : /*
383 : : * src/ap/wps_hostapd.c has already sent this on the
384 : : * main interface, so only send on the parent interface
385 : : * here if needed.
386 : : */
387 : 0 : wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
388 : : "msg=%d config_error=%d",
389 : 0 : fail->msg, fail->config_error);
390 : : }
391 : 0 : wpas_p2p_wps_failed(wpa_s, fail);
392 : : }
393 : : #endif /* CONFIG_P2P */
394 : 60 : }
395 : :
396 : :
397 : 120 : static void ap_sta_authorized_cb(void *ctx, const u8 *mac_addr,
398 : : int authorized, const u8 *p2p_dev_addr)
399 : : {
400 : 120 : wpas_notify_sta_authorized(ctx, mac_addr, authorized, p2p_dev_addr);
401 : 120 : }
402 : :
403 : :
404 : : #ifdef CONFIG_P2P
405 : 8 : static void ap_new_psk_cb(void *ctx, const u8 *mac_addr, const u8 *p2p_dev_addr,
406 : : const u8 *psk, size_t psk_len)
407 : : {
408 : :
409 : 8 : struct wpa_supplicant *wpa_s = ctx;
410 [ + - ][ - + ]: 8 : if (wpa_s->ap_iface == NULL || wpa_s->current_ssid == NULL)
411 : 8 : return;
412 : 8 : wpas_p2p_new_psk_cb(wpa_s, mac_addr, p2p_dev_addr, psk, psk_len);
413 : : }
414 : : #endif /* CONFIG_P2P */
415 : :
416 : :
417 : 0 : static int ap_vendor_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
418 : : {
419 : : #ifdef CONFIG_P2P
420 : 0 : struct wpa_supplicant *wpa_s = ctx;
421 : : const struct ieee80211_mgmt *mgmt;
422 : : size_t hdr_len;
423 : :
424 : 0 : mgmt = (const struct ieee80211_mgmt *) buf;
425 : 0 : hdr_len = (const u8 *) &mgmt->u.action.u.vs_public_action.action - buf;
426 [ # # ]: 0 : if (hdr_len > len)
427 : 0 : return -1;
428 : 0 : wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
429 : 0 : mgmt->u.action.category,
430 : : &mgmt->u.action.u.vs_public_action.action,
431 : : len - hdr_len, freq);
432 : : #endif /* CONFIG_P2P */
433 : 0 : return 0;
434 : : }
435 : :
436 : :
437 : 100 : static int ap_probe_req_rx(void *ctx, const u8 *sa, const u8 *da,
438 : : const u8 *bssid, const u8 *ie, size_t ie_len,
439 : : int ssi_signal)
440 : : {
441 : : #ifdef CONFIG_P2P
442 : 100 : struct wpa_supplicant *wpa_s = ctx;
443 : 100 : return wpas_p2p_probe_req_rx(wpa_s, sa, da, bssid, ie, ie_len,
444 : : ssi_signal);
445 : : #else /* CONFIG_P2P */
446 : : return 0;
447 : : #endif /* CONFIG_P2P */
448 : : }
449 : :
450 : :
451 : 52 : static void ap_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
452 : : const u8 *uuid_e)
453 : : {
454 : : #ifdef CONFIG_P2P
455 : 52 : struct wpa_supplicant *wpa_s = ctx;
456 : 52 : wpas_p2p_wps_success(wpa_s, mac_addr, 1);
457 : : #endif /* CONFIG_P2P */
458 : 52 : }
459 : :
460 : :
461 : 55 : static void wpas_ap_configured_cb(void *ctx)
462 : : {
463 : 55 : struct wpa_supplicant *wpa_s = ctx;
464 : :
465 : 55 : wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
466 : :
467 [ + - ]: 55 : if (wpa_s->ap_configured_cb)
468 : 55 : wpa_s->ap_configured_cb(wpa_s->ap_configured_cb_ctx,
469 : : wpa_s->ap_configured_cb_data);
470 : 55 : }
471 : :
472 : :
473 : 55 : int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
474 : : struct wpa_ssid *ssid)
475 : : {
476 : : struct wpa_driver_associate_params params;
477 : : struct hostapd_iface *hapd_iface;
478 : : struct hostapd_config *conf;
479 : : size_t i;
480 : :
481 [ + - ][ - + ]: 55 : if (ssid->ssid == NULL || ssid->ssid_len == 0) {
482 : 0 : wpa_printf(MSG_ERROR, "No SSID configured for AP mode");
483 : 0 : return -1;
484 : : }
485 : :
486 : 55 : wpa_supplicant_ap_deinit(wpa_s);
487 : :
488 : 55 : wpa_printf(MSG_DEBUG, "Setting up AP (SSID='%s')",
489 : 55 : wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
490 : :
491 : 55 : os_memset(¶ms, 0, sizeof(params));
492 : 55 : params.ssid = ssid->ssid;
493 : 55 : params.ssid_len = ssid->ssid_len;
494 [ - - + - ]: 55 : switch (ssid->mode) {
495 : : case WPAS_MODE_INFRA:
496 : 0 : params.mode = IEEE80211_MODE_INFRA;
497 : 0 : break;
498 : : case WPAS_MODE_IBSS:
499 : 0 : params.mode = IEEE80211_MODE_IBSS;
500 : 0 : break;
501 : : case WPAS_MODE_AP:
502 : : case WPAS_MODE_P2P_GO:
503 : : case WPAS_MODE_P2P_GROUP_FORMATION:
504 : 55 : params.mode = IEEE80211_MODE_AP;
505 : 55 : break;
506 : : }
507 [ - + ]: 55 : if (ssid->frequency == 0)
508 : 0 : ssid->frequency = 2462; /* default channel 11 */
509 : 55 : params.freq = ssid->frequency;
510 : :
511 : 55 : params.wpa_proto = ssid->proto;
512 [ + - ]: 55 : if (ssid->key_mgmt & WPA_KEY_MGMT_PSK)
513 : 55 : wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
514 : : else
515 : 0 : wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
516 : 55 : params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt);
517 : :
518 : 55 : wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(ssid->pairwise_cipher,
519 : : 1);
520 [ - + ]: 55 : if (wpa_s->pairwise_cipher < 0) {
521 : 0 : wpa_printf(MSG_WARNING, "WPA: Failed to select pairwise "
522 : : "cipher.");
523 : 0 : return -1;
524 : : }
525 : 55 : params.pairwise_suite =
526 : 55 : wpa_cipher_to_suite_driver(wpa_s->pairwise_cipher);
527 : 55 : params.group_suite = params.pairwise_suite;
528 : :
529 : : #ifdef CONFIG_P2P
530 [ + + ][ + - ]: 55 : if (ssid->mode == WPAS_MODE_P2P_GO ||
531 : 32 : ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
532 : 55 : params.p2p = 1;
533 : : #endif /* CONFIG_P2P */
534 : :
535 [ - + ]: 55 : if (wpa_s->parent->set_ap_uapsd)
536 : 0 : params.uapsd = wpa_s->parent->ap_uapsd;
537 : : else
538 : 55 : params.uapsd = -1;
539 : :
540 [ - + ]: 55 : if (wpa_drv_associate(wpa_s, ¶ms) < 0) {
541 : 0 : wpa_msg(wpa_s, MSG_INFO, "Failed to start AP functionality");
542 : 0 : return -1;
543 : : }
544 : :
545 : 55 : wpa_s->ap_iface = hapd_iface = os_zalloc(sizeof(*wpa_s->ap_iface));
546 [ - + ]: 55 : if (hapd_iface == NULL)
547 : 0 : return -1;
548 : 55 : hapd_iface->owner = wpa_s;
549 : 55 : hapd_iface->drv_flags = wpa_s->drv_flags;
550 : 55 : hapd_iface->probe_resp_offloads = wpa_s->probe_resp_offloads;
551 : 55 : hapd_iface->extended_capa = wpa_s->extended_capa;
552 : 55 : hapd_iface->extended_capa_mask = wpa_s->extended_capa_mask;
553 : 55 : hapd_iface->extended_capa_len = wpa_s->extended_capa_len;
554 : :
555 : 55 : wpa_s->ap_iface->conf = conf = hostapd_config_defaults();
556 [ - + ]: 55 : if (conf == NULL) {
557 : 0 : wpa_supplicant_ap_deinit(wpa_s);
558 : 0 : return -1;
559 : : }
560 : :
561 : 55 : os_memcpy(wpa_s->ap_iface->conf->wmm_ac_params,
562 : : wpa_s->conf->wmm_ac_params,
563 : : sizeof(wpa_s->conf->wmm_ac_params));
564 : :
565 [ - + ]: 55 : if (params.uapsd > 0) {
566 : 0 : conf->bss[0]->wmm_enabled = 1;
567 : 0 : conf->bss[0]->wmm_uapsd = 1;
568 : : }
569 : :
570 [ - + ]: 55 : if (wpa_supplicant_conf_ap(wpa_s, ssid, conf)) {
571 : 0 : wpa_printf(MSG_ERROR, "Failed to create AP configuration");
572 : 0 : wpa_supplicant_ap_deinit(wpa_s);
573 : 0 : return -1;
574 : : }
575 : :
576 : : #ifdef CONFIG_P2P
577 [ + + ]: 55 : if (ssid->mode == WPAS_MODE_P2P_GO)
578 : 23 : conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER;
579 [ + - ]: 32 : else if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
580 : 32 : conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER |
581 : : P2P_GROUP_FORMATION;
582 : : #endif /* CONFIG_P2P */
583 : :
584 : 55 : hapd_iface->num_bss = conf->num_bss;
585 : 55 : hapd_iface->bss = os_calloc(conf->num_bss,
586 : : sizeof(struct hostapd_data *));
587 [ - + ]: 55 : if (hapd_iface->bss == NULL) {
588 : 0 : wpa_supplicant_ap_deinit(wpa_s);
589 : 0 : return -1;
590 : : }
591 : :
592 [ + + ]: 110 : for (i = 0; i < conf->num_bss; i++) {
593 : 110 : hapd_iface->bss[i] =
594 : 55 : hostapd_alloc_bss_data(hapd_iface, conf,
595 : 55 : conf->bss[i]);
596 [ - + ]: 55 : if (hapd_iface->bss[i] == NULL) {
597 : 0 : wpa_supplicant_ap_deinit(wpa_s);
598 : 0 : return -1;
599 : : }
600 : :
601 : 55 : hapd_iface->bss[i]->msg_ctx = wpa_s;
602 : 55 : hapd_iface->bss[i]->msg_ctx_parent = wpa_s->parent;
603 : 55 : hapd_iface->bss[i]->public_action_cb = ap_public_action_rx;
604 : 55 : hapd_iface->bss[i]->public_action_cb_ctx = wpa_s;
605 : 55 : hapd_iface->bss[i]->vendor_action_cb = ap_vendor_action_rx;
606 : 55 : hapd_iface->bss[i]->vendor_action_cb_ctx = wpa_s;
607 : 55 : hostapd_register_probereq_cb(hapd_iface->bss[i],
608 : : ap_probe_req_rx, wpa_s);
609 : 55 : hapd_iface->bss[i]->wps_reg_success_cb = ap_wps_reg_success_cb;
610 : 55 : hapd_iface->bss[i]->wps_reg_success_cb_ctx = wpa_s;
611 : 55 : hapd_iface->bss[i]->wps_event_cb = ap_wps_event_cb;
612 : 55 : hapd_iface->bss[i]->wps_event_cb_ctx = wpa_s;
613 : 55 : hapd_iface->bss[i]->sta_authorized_cb = ap_sta_authorized_cb;
614 : 55 : hapd_iface->bss[i]->sta_authorized_cb_ctx = wpa_s;
615 : : #ifdef CONFIG_P2P
616 : 55 : hapd_iface->bss[i]->new_psk_cb = ap_new_psk_cb;
617 : 55 : hapd_iface->bss[i]->new_psk_cb_ctx = wpa_s;
618 : 55 : hapd_iface->bss[i]->p2p = wpa_s->global->p2p;
619 : 55 : hapd_iface->bss[i]->p2p_group = wpas_p2p_group_init(wpa_s,
620 : : ssid);
621 : : #endif /* CONFIG_P2P */
622 : 55 : hapd_iface->bss[i]->setup_complete_cb = wpas_ap_configured_cb;
623 : 55 : hapd_iface->bss[i]->setup_complete_cb_ctx = wpa_s;
624 : : }
625 : :
626 : 55 : os_memcpy(hapd_iface->bss[0]->own_addr, wpa_s->own_addr, ETH_ALEN);
627 : 55 : hapd_iface->bss[0]->driver = wpa_s->driver;
628 : 55 : hapd_iface->bss[0]->drv_priv = wpa_s->drv_priv;
629 : :
630 : 55 : wpa_s->current_ssid = ssid;
631 : 55 : eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
632 : 55 : os_memcpy(wpa_s->bssid, wpa_s->own_addr, ETH_ALEN);
633 : 55 : wpa_s->assoc_freq = ssid->frequency;
634 : :
635 [ - + ]: 55 : if (hostapd_setup_interface(wpa_s->ap_iface)) {
636 : 0 : wpa_printf(MSG_ERROR, "Failed to initialize AP interface");
637 : 0 : wpa_supplicant_ap_deinit(wpa_s);
638 : 0 : return -1;
639 : : }
640 : :
641 : 55 : return 0;
642 : : }
643 : :
644 : :
645 : 1194 : void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s)
646 : : {
647 : : #ifdef CONFIG_WPS
648 : 1194 : eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
649 : : #endif /* CONFIG_WPS */
650 : :
651 [ + + ]: 1194 : if (wpa_s->ap_iface == NULL)
652 : 1194 : return;
653 : :
654 : 55 : wpa_s->current_ssid = NULL;
655 : 55 : eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
656 : 55 : wpa_s->assoc_freq = 0;
657 : : #ifdef CONFIG_P2P
658 [ + - ]: 55 : if (wpa_s->ap_iface->bss)
659 : 55 : wpa_s->ap_iface->bss[0]->p2p_group = NULL;
660 : 55 : wpas_p2p_group_deinit(wpa_s);
661 : : #endif /* CONFIG_P2P */
662 : 55 : hostapd_interface_deinit(wpa_s->ap_iface);
663 : 55 : hostapd_interface_free(wpa_s->ap_iface);
664 : 55 : wpa_s->ap_iface = NULL;
665 : 55 : wpa_drv_deinit_ap(wpa_s);
666 : : }
667 : :
668 : :
669 : 0 : void ap_tx_status(void *ctx, const u8 *addr,
670 : : const u8 *buf, size_t len, int ack)
671 : : {
672 : : #ifdef NEED_AP_MLME
673 : 0 : struct wpa_supplicant *wpa_s = ctx;
674 : 0 : hostapd_tx_status(wpa_s->ap_iface->bss[0], addr, buf, len, ack);
675 : : #endif /* NEED_AP_MLME */
676 : 0 : }
677 : :
678 : :
679 : 504 : void ap_eapol_tx_status(void *ctx, const u8 *dst,
680 : : const u8 *data, size_t len, int ack)
681 : : {
682 : : #ifdef NEED_AP_MLME
683 : 504 : struct wpa_supplicant *wpa_s = ctx;
684 : 504 : hostapd_tx_status(wpa_s->ap_iface->bss[0], dst, data, len, ack);
685 : : #endif /* NEED_AP_MLME */
686 : 504 : }
687 : :
688 : :
689 : 0 : void ap_client_poll_ok(void *ctx, const u8 *addr)
690 : : {
691 : : #ifdef NEED_AP_MLME
692 : 0 : struct wpa_supplicant *wpa_s = ctx;
693 [ # # ]: 0 : if (wpa_s->ap_iface)
694 : 0 : hostapd_client_poll_ok(wpa_s->ap_iface->bss[0], addr);
695 : : #endif /* NEED_AP_MLME */
696 : 0 : }
697 : :
698 : :
699 : 0 : void ap_rx_from_unknown_sta(void *ctx, const u8 *addr, int wds)
700 : : {
701 : : #ifdef NEED_AP_MLME
702 : 0 : struct wpa_supplicant *wpa_s = ctx;
703 : 0 : ieee802_11_rx_from_unknown(wpa_s->ap_iface->bss[0], addr, wds);
704 : : #endif /* NEED_AP_MLME */
705 : 0 : }
706 : :
707 : :
708 : 591 : void ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt)
709 : : {
710 : : #ifdef NEED_AP_MLME
711 : 591 : struct wpa_supplicant *wpa_s = ctx;
712 : : struct hostapd_frame_info fi;
713 : 591 : os_memset(&fi, 0, sizeof(fi));
714 : 591 : fi.datarate = rx_mgmt->datarate;
715 : 591 : fi.ssi_signal = rx_mgmt->ssi_signal;
716 : 591 : ieee802_11_mgmt(wpa_s->ap_iface->bss[0], rx_mgmt->frame,
717 : : rx_mgmt->frame_len, &fi);
718 : : #endif /* NEED_AP_MLME */
719 : 591 : }
720 : :
721 : :
722 : 347 : void ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok)
723 : : {
724 : : #ifdef NEED_AP_MLME
725 : 347 : struct wpa_supplicant *wpa_s = ctx;
726 : 347 : ieee802_11_mgmt_cb(wpa_s->ap_iface->bss[0], buf, len, stype, ok);
727 : : #endif /* NEED_AP_MLME */
728 : 347 : }
729 : :
730 : :
731 : 452 : void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
732 : : const u8 *src_addr, const u8 *buf, size_t len)
733 : : {
734 : 452 : ieee802_1x_receive(wpa_s->ap_iface->bss[0], src_addr, buf, len);
735 : 452 : }
736 : :
737 : :
738 : : #ifdef CONFIG_WPS
739 : :
740 : 4 : int wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
741 : : const u8 *p2p_dev_addr)
742 : : {
743 [ - + ]: 4 : if (!wpa_s->ap_iface)
744 : 0 : return -1;
745 : 4 : return hostapd_wps_button_pushed(wpa_s->ap_iface->bss[0],
746 : : p2p_dev_addr);
747 : : }
748 : :
749 : :
750 : 0 : int wpa_supplicant_ap_wps_cancel(struct wpa_supplicant *wpa_s)
751 : : {
752 : : struct wps_registrar *reg;
753 : 0 : int reg_sel = 0, wps_sta = 0;
754 : :
755 [ # # ][ # # ]: 0 : if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]->wps)
756 : 0 : return -1;
757 : :
758 : 0 : reg = wpa_s->ap_iface->bss[0]->wps->registrar;
759 : 0 : reg_sel = wps_registrar_wps_cancel(reg);
760 : 0 : wps_sta = ap_for_each_sta(wpa_s->ap_iface->bss[0],
761 : : ap_sta_wps_cancel, NULL);
762 : :
763 [ # # ][ # # ]: 0 : if (!reg_sel && !wps_sta) {
764 : 0 : wpa_printf(MSG_DEBUG, "No WPS operation in progress at this "
765 : : "time");
766 : 0 : return -1;
767 : : }
768 : :
769 : : /*
770 : : * There are 2 cases to return wps cancel as success:
771 : : * 1. When wps cancel was initiated but no connection has been
772 : : * established with client yet.
773 : : * 2. Client is in the middle of exchanging WPS messages.
774 : : */
775 : :
776 : 0 : return 0;
777 : : }
778 : :
779 : :
780 : 48 : int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
781 : : const char *pin, char *buf, size_t buflen,
782 : : int timeout)
783 : : {
784 : 48 : int ret, ret_len = 0;
785 : :
786 [ - + ]: 48 : if (!wpa_s->ap_iface)
787 : 0 : return -1;
788 : :
789 [ - + ]: 48 : if (pin == NULL) {
790 : 0 : unsigned int rpin = wps_generate_pin();
791 : 0 : ret_len = os_snprintf(buf, buflen, "%08d", rpin);
792 : 0 : pin = buf;
793 : : } else
794 : 48 : ret_len = os_snprintf(buf, buflen, "%s", pin);
795 : :
796 : 48 : ret = hostapd_wps_add_pin(wpa_s->ap_iface->bss[0], bssid, "any", pin,
797 : : timeout);
798 [ - + ]: 48 : if (ret)
799 : 0 : return -1;
800 : 48 : return ret_len;
801 : : }
802 : :
803 : :
804 : 0 : static void wpas_wps_ap_pin_timeout(void *eloop_data, void *user_ctx)
805 : : {
806 : 0 : struct wpa_supplicant *wpa_s = eloop_data;
807 : 0 : wpa_printf(MSG_DEBUG, "WPS: AP PIN timed out");
808 : 0 : wpas_wps_ap_pin_disable(wpa_s);
809 : 0 : }
810 : :
811 : :
812 : 0 : static void wpas_wps_ap_pin_enable(struct wpa_supplicant *wpa_s, int timeout)
813 : : {
814 : : struct hostapd_data *hapd;
815 : :
816 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
817 : 0 : return;
818 : 0 : hapd = wpa_s->ap_iface->bss[0];
819 : 0 : wpa_printf(MSG_DEBUG, "WPS: Enabling AP PIN (timeout=%d)", timeout);
820 : 0 : hapd->ap_pin_failures = 0;
821 : 0 : eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
822 [ # # ]: 0 : if (timeout > 0)
823 : 0 : eloop_register_timeout(timeout, 0,
824 : : wpas_wps_ap_pin_timeout, wpa_s, NULL);
825 : : }
826 : :
827 : :
828 : 0 : void wpas_wps_ap_pin_disable(struct wpa_supplicant *wpa_s)
829 : : {
830 : : struct hostapd_data *hapd;
831 : :
832 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
833 : 0 : return;
834 : 0 : wpa_printf(MSG_DEBUG, "WPS: Disabling AP PIN");
835 : 0 : hapd = wpa_s->ap_iface->bss[0];
836 : 0 : os_free(hapd->conf->ap_pin);
837 : 0 : hapd->conf->ap_pin = NULL;
838 : 0 : eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
839 : : }
840 : :
841 : :
842 : 0 : const char * wpas_wps_ap_pin_random(struct wpa_supplicant *wpa_s, int timeout)
843 : : {
844 : : struct hostapd_data *hapd;
845 : : unsigned int pin;
846 : : char pin_txt[9];
847 : :
848 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
849 : 0 : return NULL;
850 : 0 : hapd = wpa_s->ap_iface->bss[0];
851 : 0 : pin = wps_generate_pin();
852 : 0 : os_snprintf(pin_txt, sizeof(pin_txt), "%08u", pin);
853 : 0 : os_free(hapd->conf->ap_pin);
854 : 0 : hapd->conf->ap_pin = os_strdup(pin_txt);
855 [ # # ]: 0 : if (hapd->conf->ap_pin == NULL)
856 : 0 : return NULL;
857 : 0 : wpas_wps_ap_pin_enable(wpa_s, timeout);
858 : :
859 : 0 : return hapd->conf->ap_pin;
860 : : }
861 : :
862 : :
863 : 0 : const char * wpas_wps_ap_pin_get(struct wpa_supplicant *wpa_s)
864 : : {
865 : : struct hostapd_data *hapd;
866 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
867 : 0 : return NULL;
868 : 0 : hapd = wpa_s->ap_iface->bss[0];
869 : 0 : return hapd->conf->ap_pin;
870 : : }
871 : :
872 : :
873 : 0 : int wpas_wps_ap_pin_set(struct wpa_supplicant *wpa_s, const char *pin,
874 : : int timeout)
875 : : {
876 : : struct hostapd_data *hapd;
877 : : char pin_txt[9];
878 : : int ret;
879 : :
880 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
881 : 0 : return -1;
882 : 0 : hapd = wpa_s->ap_iface->bss[0];
883 : 0 : ret = os_snprintf(pin_txt, sizeof(pin_txt), "%s", pin);
884 [ # # ][ # # ]: 0 : if (ret < 0 || ret >= (int) sizeof(pin_txt))
885 : 0 : return -1;
886 : 0 : os_free(hapd->conf->ap_pin);
887 : 0 : hapd->conf->ap_pin = os_strdup(pin_txt);
888 [ # # ]: 0 : if (hapd->conf->ap_pin == NULL)
889 : 0 : return -1;
890 : 0 : wpas_wps_ap_pin_enable(wpa_s, timeout);
891 : :
892 : 0 : return 0;
893 : : }
894 : :
895 : :
896 : 0 : void wpa_supplicant_ap_pwd_auth_fail(struct wpa_supplicant *wpa_s)
897 : : {
898 : : struct hostapd_data *hapd;
899 : :
900 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
901 : 0 : return;
902 : 0 : hapd = wpa_s->ap_iface->bss[0];
903 : :
904 : : /*
905 : : * Registrar failed to prove its knowledge of the AP PIN. Disable AP
906 : : * PIN if this happens multiple times to slow down brute force attacks.
907 : : */
908 : 0 : hapd->ap_pin_failures++;
909 : 0 : wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u",
910 : : hapd->ap_pin_failures);
911 [ # # ]: 0 : if (hapd->ap_pin_failures < 3)
912 : 0 : return;
913 : :
914 : 0 : wpa_printf(MSG_DEBUG, "WPS: Disable AP PIN");
915 : 0 : hapd->ap_pin_failures = 0;
916 : 0 : os_free(hapd->conf->ap_pin);
917 : 0 : hapd->conf->ap_pin = NULL;
918 : : }
919 : :
920 : :
921 : : #ifdef CONFIG_WPS_NFC
922 : :
923 : 0 : struct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
924 : : int ndef)
925 : : {
926 : : struct hostapd_data *hapd;
927 : :
928 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
929 : 0 : return NULL;
930 : 0 : hapd = wpa_s->ap_iface->bss[0];
931 : 0 : return hostapd_wps_nfc_config_token(hapd, ndef);
932 : : }
933 : :
934 : :
935 : 0 : struct wpabuf * wpas_ap_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
936 : : int ndef)
937 : : {
938 : : struct hostapd_data *hapd;
939 : :
940 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
941 : 0 : return NULL;
942 : 0 : hapd = wpa_s->ap_iface->bss[0];
943 : 0 : return hostapd_wps_nfc_hs_cr(hapd, ndef);
944 : : }
945 : :
946 : : #endif /* CONFIG_WPS_NFC */
947 : :
948 : : #endif /* CONFIG_WPS */
949 : :
950 : :
951 : : #ifdef CONFIG_CTRL_IFACE
952 : :
953 : 0 : int ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s,
954 : : char *buf, size_t buflen)
955 : : {
956 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
957 : 0 : return -1;
958 : 0 : return hostapd_ctrl_iface_sta_first(wpa_s->ap_iface->bss[0],
959 : : buf, buflen);
960 : : }
961 : :
962 : :
963 : 0 : int ap_ctrl_iface_sta(struct wpa_supplicant *wpa_s, const char *txtaddr,
964 : : char *buf, size_t buflen)
965 : : {
966 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
967 : 0 : return -1;
968 : 0 : return hostapd_ctrl_iface_sta(wpa_s->ap_iface->bss[0], txtaddr,
969 : : buf, buflen);
970 : : }
971 : :
972 : :
973 : 0 : int ap_ctrl_iface_sta_next(struct wpa_supplicant *wpa_s, const char *txtaddr,
974 : : char *buf, size_t buflen)
975 : : {
976 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
977 : 0 : return -1;
978 : 0 : return hostapd_ctrl_iface_sta_next(wpa_s->ap_iface->bss[0], txtaddr,
979 : : buf, buflen);
980 : : }
981 : :
982 : :
983 : 0 : int ap_ctrl_iface_sta_disassociate(struct wpa_supplicant *wpa_s,
984 : : const char *txtaddr)
985 : : {
986 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
987 : 0 : return -1;
988 : 0 : return hostapd_ctrl_iface_disassociate(wpa_s->ap_iface->bss[0],
989 : : txtaddr);
990 : : }
991 : :
992 : :
993 : 0 : int ap_ctrl_iface_sta_deauthenticate(struct wpa_supplicant *wpa_s,
994 : : const char *txtaddr)
995 : : {
996 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
997 : 0 : return -1;
998 : 0 : return hostapd_ctrl_iface_deauthenticate(wpa_s->ap_iface->bss[0],
999 : : txtaddr);
1000 : : }
1001 : :
1002 : :
1003 : 22 : int ap_ctrl_iface_wpa_get_status(struct wpa_supplicant *wpa_s, char *buf,
1004 : : size_t buflen, int verbose)
1005 : : {
1006 : 22 : char *pos = buf, *end = buf + buflen;
1007 : : int ret;
1008 : : struct hostapd_bss_config *conf;
1009 : :
1010 [ - + ]: 22 : if (wpa_s->ap_iface == NULL)
1011 : 0 : return -1;
1012 : :
1013 : 22 : conf = wpa_s->ap_iface->bss[0]->conf;
1014 [ - + ]: 22 : if (conf->wpa == 0)
1015 : 0 : return 0;
1016 : :
1017 : 22 : ret = os_snprintf(pos, end - pos,
1018 : : "pairwise_cipher=%s\n"
1019 : : "group_cipher=%s\n"
1020 : : "key_mgmt=%s\n",
1021 : : wpa_cipher_txt(conf->rsn_pairwise),
1022 : : wpa_cipher_txt(conf->wpa_group),
1023 : : wpa_key_mgmt_txt(conf->wpa_key_mgmt,
1024 : : conf->wpa));
1025 [ + - ][ - + ]: 22 : if (ret < 0 || ret >= end - pos)
1026 : 0 : return pos - buf;
1027 : 22 : pos += ret;
1028 : 22 : return pos - buf;
1029 : : }
1030 : :
1031 : : #endif /* CONFIG_CTRL_IFACE */
1032 : :
1033 : :
1034 : 296 : int wpa_supplicant_ap_update_beacon(struct wpa_supplicant *wpa_s)
1035 : : {
1036 : 296 : struct hostapd_iface *iface = wpa_s->ap_iface;
1037 : 296 : struct wpa_ssid *ssid = wpa_s->current_ssid;
1038 : : struct hostapd_data *hapd;
1039 : :
1040 [ + + ][ + - ]: 296 : if (ssid == NULL || wpa_s->ap_iface == NULL ||
[ + - ]
1041 [ - + ]: 218 : ssid->mode == WPAS_MODE_INFRA ||
1042 : 218 : ssid->mode == WPAS_MODE_IBSS)
1043 : 78 : return -1;
1044 : :
1045 : : #ifdef CONFIG_P2P
1046 [ + + ]: 218 : if (ssid->mode == WPAS_MODE_P2P_GO)
1047 : 186 : iface->conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER;
1048 [ + - ]: 32 : else if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
1049 : 32 : iface->conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER |
1050 : : P2P_GROUP_FORMATION;
1051 : : #endif /* CONFIG_P2P */
1052 : :
1053 : 218 : hapd = iface->bss[0];
1054 [ - + ]: 218 : if (hapd->drv_priv == NULL)
1055 : 0 : return -1;
1056 : 218 : ieee802_11_set_beacons(iface);
1057 : 218 : hostapd_set_ap_wps_ie(hapd);
1058 : :
1059 : 296 : return 0;
1060 : : }
1061 : :
1062 : :
1063 : 1 : int ap_switch_channel(struct wpa_supplicant *wpa_s,
1064 : : struct csa_settings *settings)
1065 : : {
1066 : : #ifdef NEED_AP_MLME
1067 [ + - ][ - + ]: 1 : if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
1068 : 0 : return -1;
1069 : :
1070 : 1 : return hostapd_switch_channel(wpa_s->ap_iface->bss[0], settings);
1071 : : #else /* NEED_AP_MLME */
1072 : : return -1;
1073 : : #endif /* NEED_AP_MLME */
1074 : : }
1075 : :
1076 : :
1077 : 1 : int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos)
1078 : : {
1079 : : struct csa_settings settings;
1080 : 1 : int ret = hostapd_parse_csa_settings(pos, &settings);
1081 : :
1082 [ - + ]: 1 : if (ret)
1083 : 0 : return ret;
1084 : :
1085 : 1 : return ap_switch_channel(wpa_s, &settings);
1086 : : }
1087 : :
1088 : :
1089 : 0 : void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
1090 : : int offset, int width, int cf1, int cf2)
1091 : : {
1092 [ # # ]: 0 : if (!wpa_s->ap_iface)
1093 : 0 : return;
1094 : :
1095 : 0 : wpa_s->assoc_freq = freq;
1096 : 0 : hostapd_event_ch_switch(wpa_s->ap_iface->bss[0], freq, ht, offset, width, cf1, cf1);
1097 : : }
1098 : :
1099 : :
1100 : 64 : int wpa_supplicant_ap_mac_addr_filter(struct wpa_supplicant *wpa_s,
1101 : : const u8 *addr)
1102 : : {
1103 : : struct hostapd_data *hapd;
1104 : : struct hostapd_bss_config *conf;
1105 : :
1106 [ - + ]: 64 : if (!wpa_s->ap_iface)
1107 : 0 : return -1;
1108 : :
1109 [ + + ]: 64 : if (addr)
1110 : 32 : wpa_printf(MSG_DEBUG, "AP: Set MAC address filter: " MACSTR,
1111 : 192 : MAC2STR(addr));
1112 : : else
1113 : 32 : wpa_printf(MSG_DEBUG, "AP: Clear MAC address filter");
1114 : :
1115 : 64 : hapd = wpa_s->ap_iface->bss[0];
1116 : 64 : conf = hapd->conf;
1117 : :
1118 : 64 : os_free(conf->accept_mac);
1119 : 64 : conf->accept_mac = NULL;
1120 : 64 : conf->num_accept_mac = 0;
1121 : 64 : os_free(conf->deny_mac);
1122 : 64 : conf->deny_mac = NULL;
1123 : 64 : conf->num_deny_mac = 0;
1124 : :
1125 [ + + ]: 64 : if (addr == NULL) {
1126 : 32 : conf->macaddr_acl = ACCEPT_UNLESS_DENIED;
1127 : 32 : return 0;
1128 : : }
1129 : :
1130 : 32 : conf->macaddr_acl = DENY_UNLESS_ACCEPTED;
1131 : 32 : conf->accept_mac = os_zalloc(sizeof(struct mac_acl_entry));
1132 [ - + ]: 32 : if (conf->accept_mac == NULL)
1133 : 0 : return -1;
1134 : 32 : os_memcpy(conf->accept_mac[0].addr, addr, ETH_ALEN);
1135 : 32 : conf->num_accept_mac = 1;
1136 : :
1137 : 64 : return 0;
1138 : : }
|