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 : 59 : static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
73 : : struct wpa_ssid *ssid,
74 : : struct hostapd_config *conf)
75 : : {
76 : 59 : struct hostapd_bss_config *bss = conf->bss[0];
77 : :
78 : 59 : conf->driver = wpa_s->driver;
79 : :
80 : 59 : os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface));
81 : :
82 : 59 : conf->hw_mode = ieee80211_freq_to_chan(ssid->frequency,
83 : : &conf->channel);
84 [ - + ]: 59 : 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 [ + - ]: 59 : if (wpa_s->hw.modes) {
101 : 59 : struct hostapd_hw_modes *mode = NULL;
102 : 59 : int i, no_ht = 0;
103 [ + - ]: 59 : for (i = 0; i < wpa_s->hw.num_modes; i++) {
104 [ + - ]: 59 : if (wpa_s->hw.modes[i].mode == conf->hw_mode) {
105 : 59 : mode = &wpa_s->hw.modes[i];
106 : 59 : 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 [ + - ][ + - ]: 59 : if (!no_ht && mode && mode->ht_capab) {
[ + - ]
119 : 59 : conf->ieee80211n = 1;
120 : : #ifdef CONFIG_P2P
121 [ - + ][ # # ]: 59 : 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 [ - + ]: 59 : 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 : 59 : 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 [ + - ][ - + ]: 59 : 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 [ + - ][ + + ]: 59 : if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G &&
155 [ + + ]: 36 : (ssid->mode == WPAS_MODE_P2P_GO ||
156 : 36 : ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)) {
157 : : /* Remove 802.11b rates from supported and basic rate sets */
158 : 57 : int *list = os_malloc(4 * sizeof(int));
159 [ + - ]: 57 : if (list) {
160 : 57 : list[0] = 60;
161 : 57 : list[1] = 120;
162 : 57 : list[2] = 240;
163 : 57 : list[3] = -1;
164 : : }
165 : 57 : conf->basic_rates = list;
166 : :
167 : 57 : list = os_malloc(9 * sizeof(int));
168 [ + - ]: 57 : if (list) {
169 : 57 : list[0] = 60;
170 : 57 : list[1] = 90;
171 : 57 : list[2] = 120;
172 : 57 : list[3] = 180;
173 : 57 : list[4] = 240;
174 : 57 : list[5] = 360;
175 : 57 : list[6] = 480;
176 : 57 : list[7] = 540;
177 : 57 : list[8] = -1;
178 : : }
179 : 57 : conf->supported_rates = list;
180 : : }
181 : :
182 : 59 : bss->isolate = !wpa_s->conf->p2p_intra_bss;
183 : 59 : bss->force_per_enrollee_psk = wpa_s->global->p2p_per_sta_psk;
184 : : #endif /* CONFIG_P2P */
185 : :
186 [ - + ]: 59 : if (ssid->ssid_len == 0) {
187 : 0 : wpa_printf(MSG_ERROR, "No SSID configured for AP mode");
188 : 0 : return -1;
189 : : }
190 : 59 : os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len);
191 : 59 : bss->ssid.ssid_len = ssid->ssid_len;
192 : 59 : bss->ssid.ssid_set = 1;
193 : :
194 : 59 : bss->ignore_broadcast_ssid = ssid->ignore_broadcast_ssid;
195 : :
196 [ + + ]: 59 : if (ssid->auth_alg)
197 : 57 : bss->auth_algs = ssid->auth_alg;
198 : :
199 [ + + ]: 59 : if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt))
200 : 58 : bss->wpa = ssid->proto;
201 : 59 : bss->wpa_key_mgmt = ssid->key_mgmt;
202 : 59 : bss->wpa_pairwise = ssid->pairwise_cipher;
203 [ + + ]: 59 : if (ssid->psk_set) {
204 : 58 : os_free(bss->ssid.wpa_psk);
205 : 58 : bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
206 [ - + ]: 58 : if (bss->ssid.wpa_psk == NULL)
207 : 0 : return -1;
208 : 58 : os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN);
209 : 58 : bss->ssid.wpa_psk->group = 1;
210 [ - + ]: 1 : } else if (ssid->passphrase) {
211 : 0 : bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase);
212 [ + - ][ + - ]: 1 : } else if (ssid->wep_key_len[0] || ssid->wep_key_len[1] ||
[ + - ]
213 [ - + ]: 1 : 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 [ + + ]: 59 : if (ssid->ap_max_inactivity)
231 : 57 : bss->ap_max_inactivity = ssid->ap_max_inactivity;
232 : :
233 [ - + ]: 59 : if (ssid->dtim_period)
234 : 0 : bss->dtim_period = ssid->dtim_period;
235 [ - + ]: 59 : else if (wpa_s->conf->dtim_period)
236 : 0 : bss->dtim_period = wpa_s->conf->dtim_period;
237 : :
238 [ - + ]: 59 : if (ssid->beacon_int)
239 : 0 : conf->beacon_int = ssid->beacon_int;
240 [ - + ]: 59 : else if (wpa_s->conf->beacon_int)
241 : 0 : conf->beacon_int = wpa_s->conf->beacon_int;
242 : :
243 [ + + ][ + - ]: 59 : if ((bss->wpa & 2) && bss->rsn_pairwise == 0)
244 : 58 : bss->rsn_pairwise = bss->wpa_pairwise;
245 : 59 : bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa, bss->wpa_pairwise,
246 : : bss->rsn_pairwise);
247 : :
248 [ + + ][ - + ]: 59 : if (bss->wpa && bss->ieee802_1x)
249 : 0 : bss->ssid.security_policy = SECURITY_WPA;
250 [ + + ]: 59 : else if (bss->wpa)
251 : 58 : bss->ssid.security_policy = SECURITY_WPA_PSK;
252 [ - + ]: 1 : 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 [ - + ]: 1 : } 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 : 1 : bss->ssid.security_policy = SECURITY_PLAINTEXT;
272 : 1 : bss->wpa_group = WPA_CIPHER_NONE;
273 : 1 : bss->wpa_pairwise = WPA_CIPHER_NONE;
274 : 1 : bss->rsn_pairwise = WPA_CIPHER_NONE;
275 : : }
276 : :
277 [ + - ][ + + ]: 59 : 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 : 58 : 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 [ + + ][ - + ]: 59 : if (bss->ssid.security_policy != SECURITY_WPA_PSK &&
296 : 1 : bss->ssid.security_policy != SECURITY_PLAINTEXT)
297 : 0 : goto no_wps;
298 : : #ifdef CONFIG_WPS2
299 [ + + ][ + - ]: 59 : if (bss->ssid.security_policy == SECURITY_WPA_PSK &&
300 [ + - ]: 58 : (!(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 : 59 : bss->eap_server = 1;
305 : :
306 [ + - ]: 59 : if (!ssid->ignore_broadcast_ssid)
307 : 59 : bss->wps_state = 2;
308 : :
309 : 59 : bss->ap_setup_locked = 2;
310 [ - + ]: 59 : if (wpa_s->conf->config_methods)
311 : 0 : bss->config_methods = os_strdup(wpa_s->conf->config_methods);
312 : 59 : os_memcpy(bss->device_type, wpa_s->conf->device_type,
313 : : WPS_DEV_TYPE_LEN);
314 [ + + ]: 59 : if (wpa_s->conf->device_name) {
315 : 56 : bss->device_name = os_strdup(wpa_s->conf->device_name);
316 : 56 : bss->friendly_name = os_strdup(wpa_s->conf->device_name);
317 : : }
318 [ - + ]: 59 : if (wpa_s->conf->manufacturer)
319 : 0 : bss->manufacturer = os_strdup(wpa_s->conf->manufacturer);
320 [ - + ]: 59 : if (wpa_s->conf->model_name)
321 : 0 : bss->model_name = os_strdup(wpa_s->conf->model_name);
322 [ - + ]: 59 : if (wpa_s->conf->model_number)
323 : 0 : bss->model_number = os_strdup(wpa_s->conf->model_number);
324 [ - + ]: 59 : if (wpa_s->conf->serial_number)
325 : 0 : bss->serial_number = os_strdup(wpa_s->conf->serial_number);
326 [ + - ]: 59 : if (is_nil_uuid(wpa_s->conf->uuid))
327 : 59 : 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 : 59 : os_memcpy(bss->os_version, wpa_s->conf->os_version, 4);
331 : 59 : bss->pbc_in_m1 = wpa_s->conf->pbc_in_m1;
332 : : no_wps:
333 : : #endif /* CONFIG_WPS */
334 : :
335 [ - + ][ # # ]: 59 : 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 : 59 : bss->max_num_sta = wpa_s->conf->max_num_sta;
340 : :
341 : 59 : bss->disassoc_low_ack = wpa_s->conf->disassoc_low_ack;
342 : :
343 [ - + ]: 59 : 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 : 59 : return 0;
349 : : }
350 : :
351 : :
352 : 22 : static void ap_public_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
353 : : {
354 : : #ifdef CONFIG_P2P
355 : 22 : struct wpa_supplicant *wpa_s = ctx;
356 : : const struct ieee80211_mgmt *mgmt;
357 : : size_t hdr_len;
358 : :
359 : 22 : mgmt = (const struct ieee80211_mgmt *) buf;
360 : 22 : hdr_len = (const u8 *) &mgmt->u.action.u.vs_public_action.action - buf;
361 [ - + ]: 22 : if (hdr_len > len)
362 : 22 : return;
363 : 22 : wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
364 : 22 : 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 : 62 : static void ap_wps_event_cb(void *ctx, enum wps_event event,
372 : : union wps_event_data *data)
373 : : {
374 : : #ifdef CONFIG_P2P
375 : 62 : struct wpa_supplicant *wpa_s = ctx;
376 : :
377 [ - + ]: 62 : 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 : 62 : }
395 : :
396 : :
397 : 130 : static void ap_sta_authorized_cb(void *ctx, const u8 *mac_addr,
398 : : int authorized, const u8 *p2p_dev_addr)
399 : : {
400 : 130 : wpas_notify_sta_authorized(ctx, mac_addr, authorized, p2p_dev_addr);
401 : 130 : }
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 : 1 : static int ap_vendor_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
418 : : {
419 : : #ifdef CONFIG_P2P
420 : 1 : struct wpa_supplicant *wpa_s = ctx;
421 : : const struct ieee80211_mgmt *mgmt;
422 : : size_t hdr_len;
423 : :
424 : 1 : mgmt = (const struct ieee80211_mgmt *) buf;
425 : 1 : hdr_len = (const u8 *) &mgmt->u.action.u.vs_public_action.action - buf;
426 [ - + ]: 1 : if (hdr_len > len)
427 : 0 : return -1;
428 : 1 : wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
429 : 1 : mgmt->u.action.category,
430 : : &mgmt->u.action.u.vs_public_action.action,
431 : : len - hdr_len, freq);
432 : : #endif /* CONFIG_P2P */
433 : 1 : return 0;
434 : : }
435 : :
436 : :
437 : 105 : 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 : 105 : struct wpa_supplicant *wpa_s = ctx;
443 : 105 : 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 : 54 : static void ap_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
452 : : const u8 *uuid_e)
453 : : {
454 : : #ifdef CONFIG_P2P
455 : 54 : struct wpa_supplicant *wpa_s = ctx;
456 : 54 : wpas_p2p_wps_success(wpa_s, mac_addr, 1);
457 : : #endif /* CONFIG_P2P */
458 : 54 : }
459 : :
460 : :
461 : 59 : static void wpas_ap_configured_cb(void *ctx)
462 : : {
463 : 59 : struct wpa_supplicant *wpa_s = ctx;
464 : :
465 : 59 : wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
466 : :
467 [ + + ]: 59 : if (wpa_s->ap_configured_cb)
468 : 57 : wpa_s->ap_configured_cb(wpa_s->ap_configured_cb_ctx,
469 : : wpa_s->ap_configured_cb_data);
470 : 59 : }
471 : :
472 : :
473 : 59 : 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 [ + - ][ - + ]: 59 : 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 : 59 : wpa_supplicant_ap_deinit(wpa_s);
487 : :
488 : 59 : wpa_printf(MSG_DEBUG, "Setting up AP (SSID='%s')",
489 : 59 : wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
490 : :
491 : 59 : os_memset(¶ms, 0, sizeof(params));
492 : 59 : params.ssid = ssid->ssid;
493 : 59 : params.ssid_len = ssid->ssid_len;
494 [ - - + - ]: 59 : 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 : 59 : params.mode = IEEE80211_MODE_AP;
505 : 59 : break;
506 : : }
507 [ - + ]: 59 : if (ssid->frequency == 0)
508 : 0 : ssid->frequency = 2462; /* default channel 11 */
509 : 59 : params.freq = ssid->frequency;
510 : :
511 : 59 : params.wpa_proto = ssid->proto;
512 [ + + ]: 59 : if (ssid->key_mgmt & WPA_KEY_MGMT_PSK)
513 : 58 : wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
514 : : else
515 : 1 : wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
516 : 59 : params.key_mgmt_suite = wpa_s->key_mgmt;
517 : :
518 : 59 : wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(ssid->pairwise_cipher,
519 : : 1);
520 [ - + ]: 59 : 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 : 59 : params.pairwise_suite = wpa_s->pairwise_cipher;
526 : 59 : params.group_suite = params.pairwise_suite;
527 : :
528 : : #ifdef CONFIG_P2P
529 [ + + ][ + + ]: 59 : if (ssid->mode == WPAS_MODE_P2P_GO ||
530 : 36 : ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
531 : 57 : params.p2p = 1;
532 : : #endif /* CONFIG_P2P */
533 : :
534 [ - + ]: 59 : if (wpa_s->parent->set_ap_uapsd)
535 : 0 : params.uapsd = wpa_s->parent->ap_uapsd;
536 : : else
537 : 59 : params.uapsd = -1;
538 : :
539 [ - + ]: 59 : if (wpa_drv_associate(wpa_s, ¶ms) < 0) {
540 : 0 : wpa_msg(wpa_s, MSG_INFO, "Failed to start AP functionality");
541 : 0 : return -1;
542 : : }
543 : :
544 : 59 : wpa_s->ap_iface = hapd_iface = os_zalloc(sizeof(*wpa_s->ap_iface));
545 [ - + ]: 59 : if (hapd_iface == NULL)
546 : 0 : return -1;
547 : 59 : hapd_iface->owner = wpa_s;
548 : 59 : hapd_iface->drv_flags = wpa_s->drv_flags;
549 : 59 : hapd_iface->probe_resp_offloads = wpa_s->probe_resp_offloads;
550 : 59 : hapd_iface->extended_capa = wpa_s->extended_capa;
551 : 59 : hapd_iface->extended_capa_mask = wpa_s->extended_capa_mask;
552 : 59 : hapd_iface->extended_capa_len = wpa_s->extended_capa_len;
553 : :
554 : 59 : wpa_s->ap_iface->conf = conf = hostapd_config_defaults();
555 [ - + ]: 59 : if (conf == NULL) {
556 : 0 : wpa_supplicant_ap_deinit(wpa_s);
557 : 0 : return -1;
558 : : }
559 : :
560 : 59 : os_memcpy(wpa_s->ap_iface->conf->wmm_ac_params,
561 : : wpa_s->conf->wmm_ac_params,
562 : : sizeof(wpa_s->conf->wmm_ac_params));
563 : :
564 [ - + ]: 59 : if (params.uapsd > 0) {
565 : 0 : conf->bss[0]->wmm_enabled = 1;
566 : 0 : conf->bss[0]->wmm_uapsd = 1;
567 : : }
568 : :
569 [ - + ]: 59 : if (wpa_supplicant_conf_ap(wpa_s, ssid, conf)) {
570 : 0 : wpa_printf(MSG_ERROR, "Failed to create AP configuration");
571 : 0 : wpa_supplicant_ap_deinit(wpa_s);
572 : 0 : return -1;
573 : : }
574 : :
575 : : #ifdef CONFIG_P2P
576 [ + + ]: 59 : if (ssid->mode == WPAS_MODE_P2P_GO)
577 : 23 : conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER;
578 [ + + ]: 36 : else if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
579 : 34 : conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER |
580 : : P2P_GROUP_FORMATION;
581 : : #endif /* CONFIG_P2P */
582 : :
583 : 59 : hapd_iface->num_bss = conf->num_bss;
584 : 59 : hapd_iface->bss = os_calloc(conf->num_bss,
585 : : sizeof(struct hostapd_data *));
586 [ - + ]: 59 : if (hapd_iface->bss == NULL) {
587 : 0 : wpa_supplicant_ap_deinit(wpa_s);
588 : 0 : return -1;
589 : : }
590 : :
591 [ + + ]: 118 : for (i = 0; i < conf->num_bss; i++) {
592 : 118 : hapd_iface->bss[i] =
593 : 59 : hostapd_alloc_bss_data(hapd_iface, conf,
594 : 59 : conf->bss[i]);
595 [ - + ]: 59 : if (hapd_iface->bss[i] == NULL) {
596 : 0 : wpa_supplicant_ap_deinit(wpa_s);
597 : 0 : return -1;
598 : : }
599 : :
600 : 59 : hapd_iface->bss[i]->msg_ctx = wpa_s;
601 : 59 : hapd_iface->bss[i]->msg_ctx_parent = wpa_s->parent;
602 : 59 : hapd_iface->bss[i]->public_action_cb = ap_public_action_rx;
603 : 59 : hapd_iface->bss[i]->public_action_cb_ctx = wpa_s;
604 : 59 : hapd_iface->bss[i]->vendor_action_cb = ap_vendor_action_rx;
605 : 59 : hapd_iface->bss[i]->vendor_action_cb_ctx = wpa_s;
606 : 59 : hostapd_register_probereq_cb(hapd_iface->bss[i],
607 : : ap_probe_req_rx, wpa_s);
608 : 59 : hapd_iface->bss[i]->wps_reg_success_cb = ap_wps_reg_success_cb;
609 : 59 : hapd_iface->bss[i]->wps_reg_success_cb_ctx = wpa_s;
610 : 59 : hapd_iface->bss[i]->wps_event_cb = ap_wps_event_cb;
611 : 59 : hapd_iface->bss[i]->wps_event_cb_ctx = wpa_s;
612 : 59 : hapd_iface->bss[i]->sta_authorized_cb = ap_sta_authorized_cb;
613 : 59 : hapd_iface->bss[i]->sta_authorized_cb_ctx = wpa_s;
614 : : #ifdef CONFIG_P2P
615 : 59 : hapd_iface->bss[i]->new_psk_cb = ap_new_psk_cb;
616 : 59 : hapd_iface->bss[i]->new_psk_cb_ctx = wpa_s;
617 : 59 : hapd_iface->bss[i]->p2p = wpa_s->global->p2p;
618 : 59 : hapd_iface->bss[i]->p2p_group = wpas_p2p_group_init(wpa_s,
619 : : ssid);
620 : : #endif /* CONFIG_P2P */
621 : 59 : hapd_iface->bss[i]->setup_complete_cb = wpas_ap_configured_cb;
622 : 59 : hapd_iface->bss[i]->setup_complete_cb_ctx = wpa_s;
623 : : }
624 : :
625 : 59 : os_memcpy(hapd_iface->bss[0]->own_addr, wpa_s->own_addr, ETH_ALEN);
626 : 59 : hapd_iface->bss[0]->driver = wpa_s->driver;
627 : 59 : hapd_iface->bss[0]->drv_priv = wpa_s->drv_priv;
628 : :
629 : 59 : wpa_s->current_ssid = ssid;
630 : 59 : eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
631 : 59 : os_memcpy(wpa_s->bssid, wpa_s->own_addr, ETH_ALEN);
632 : 59 : wpa_s->assoc_freq = ssid->frequency;
633 : :
634 [ - + ]: 59 : if (hostapd_setup_interface(wpa_s->ap_iface)) {
635 : 0 : wpa_printf(MSG_ERROR, "Failed to initialize AP interface");
636 : 0 : wpa_supplicant_ap_deinit(wpa_s);
637 : 0 : return -1;
638 : : }
639 : :
640 : 59 : return 0;
641 : : }
642 : :
643 : :
644 : 1487 : void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s)
645 : : {
646 : : #ifdef CONFIG_WPS
647 : 1487 : eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
648 : : #endif /* CONFIG_WPS */
649 : :
650 [ + + ]: 1487 : if (wpa_s->ap_iface == NULL)
651 : 1487 : return;
652 : :
653 : 59 : wpa_s->current_ssid = NULL;
654 : 59 : eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
655 : 59 : wpa_s->assoc_freq = 0;
656 : : #ifdef CONFIG_P2P
657 [ + - ]: 59 : if (wpa_s->ap_iface->bss)
658 : 59 : wpa_s->ap_iface->bss[0]->p2p_group = NULL;
659 : 59 : wpas_p2p_group_deinit(wpa_s);
660 : : #endif /* CONFIG_P2P */
661 : 59 : hostapd_interface_deinit(wpa_s->ap_iface);
662 : 59 : hostapd_interface_free(wpa_s->ap_iface);
663 : 59 : wpa_s->ap_iface = NULL;
664 : 59 : wpa_drv_deinit_ap(wpa_s);
665 : : }
666 : :
667 : :
668 : 2 : void ap_tx_status(void *ctx, const u8 *addr,
669 : : const u8 *buf, size_t len, int ack)
670 : : {
671 : : #ifdef NEED_AP_MLME
672 : 2 : struct wpa_supplicant *wpa_s = ctx;
673 : 2 : hostapd_tx_status(wpa_s->ap_iface->bss[0], addr, buf, len, ack);
674 : : #endif /* NEED_AP_MLME */
675 : 2 : }
676 : :
677 : :
678 : 524 : void ap_eapol_tx_status(void *ctx, const u8 *dst,
679 : : const u8 *data, size_t len, int ack)
680 : : {
681 : : #ifdef NEED_AP_MLME
682 : 524 : struct wpa_supplicant *wpa_s = ctx;
683 : 524 : hostapd_tx_status(wpa_s->ap_iface->bss[0], dst, data, len, ack);
684 : : #endif /* NEED_AP_MLME */
685 : 524 : }
686 : :
687 : :
688 : 0 : void ap_client_poll_ok(void *ctx, const u8 *addr)
689 : : {
690 : : #ifdef NEED_AP_MLME
691 : 0 : struct wpa_supplicant *wpa_s = ctx;
692 [ # # ]: 0 : if (wpa_s->ap_iface)
693 : 0 : hostapd_client_poll_ok(wpa_s->ap_iface->bss[0], addr);
694 : : #endif /* NEED_AP_MLME */
695 : 0 : }
696 : :
697 : :
698 : 0 : void ap_rx_from_unknown_sta(void *ctx, const u8 *addr, int wds)
699 : : {
700 : : #ifdef NEED_AP_MLME
701 : 0 : struct wpa_supplicant *wpa_s = ctx;
702 : 0 : ieee802_11_rx_from_unknown(wpa_s->ap_iface->bss[0], addr, wds);
703 : : #endif /* NEED_AP_MLME */
704 : 0 : }
705 : :
706 : :
707 : 643 : void ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt)
708 : : {
709 : : #ifdef NEED_AP_MLME
710 : 643 : struct wpa_supplicant *wpa_s = ctx;
711 : : struct hostapd_frame_info fi;
712 : 643 : os_memset(&fi, 0, sizeof(fi));
713 : 643 : fi.datarate = rx_mgmt->datarate;
714 : 643 : fi.ssi_signal = rx_mgmt->ssi_signal;
715 : 643 : ieee802_11_mgmt(wpa_s->ap_iface->bss[0], rx_mgmt->frame,
716 : : rx_mgmt->frame_len, &fi);
717 : : #endif /* NEED_AP_MLME */
718 : 643 : }
719 : :
720 : :
721 : 368 : void ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok)
722 : : {
723 : : #ifdef NEED_AP_MLME
724 : 368 : struct wpa_supplicant *wpa_s = ctx;
725 : 368 : ieee802_11_mgmt_cb(wpa_s->ap_iface->bss[0], buf, len, stype, ok);
726 : : #endif /* NEED_AP_MLME */
727 : 368 : }
728 : :
729 : :
730 : 473 : void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
731 : : const u8 *src_addr, const u8 *buf, size_t len)
732 : : {
733 : 473 : ieee802_1x_receive(wpa_s->ap_iface->bss[0], src_addr, buf, len);
734 : 473 : }
735 : :
736 : :
737 : : #ifdef CONFIG_WPS
738 : :
739 : 4 : int wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
740 : : const u8 *p2p_dev_addr)
741 : : {
742 [ - + ]: 4 : if (!wpa_s->ap_iface)
743 : 0 : return -1;
744 : 4 : return hostapd_wps_button_pushed(wpa_s->ap_iface->bss[0],
745 : : p2p_dev_addr);
746 : : }
747 : :
748 : :
749 : 0 : int wpa_supplicant_ap_wps_cancel(struct wpa_supplicant *wpa_s)
750 : : {
751 : : struct wps_registrar *reg;
752 : 0 : int reg_sel = 0, wps_sta = 0;
753 : :
754 [ # # ][ # # ]: 0 : if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]->wps)
755 : 0 : return -1;
756 : :
757 : 0 : reg = wpa_s->ap_iface->bss[0]->wps->registrar;
758 : 0 : reg_sel = wps_registrar_wps_cancel(reg);
759 : 0 : wps_sta = ap_for_each_sta(wpa_s->ap_iface->bss[0],
760 : : ap_sta_wps_cancel, NULL);
761 : :
762 [ # # ][ # # ]: 0 : if (!reg_sel && !wps_sta) {
763 : 0 : wpa_printf(MSG_DEBUG, "No WPS operation in progress at this "
764 : : "time");
765 : 0 : return -1;
766 : : }
767 : :
768 : : /*
769 : : * There are 2 cases to return wps cancel as success:
770 : : * 1. When wps cancel was initiated but no connection has been
771 : : * established with client yet.
772 : : * 2. Client is in the middle of exchanging WPS messages.
773 : : */
774 : :
775 : 0 : return 0;
776 : : }
777 : :
778 : :
779 : 50 : int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
780 : : const char *pin, char *buf, size_t buflen,
781 : : int timeout)
782 : : {
783 : 50 : int ret, ret_len = 0;
784 : :
785 [ - + ]: 50 : if (!wpa_s->ap_iface)
786 : 0 : return -1;
787 : :
788 [ - + ]: 50 : if (pin == NULL) {
789 : 0 : unsigned int rpin = wps_generate_pin();
790 : 0 : ret_len = os_snprintf(buf, buflen, "%08d", rpin);
791 : 0 : pin = buf;
792 : : } else
793 : 50 : ret_len = os_snprintf(buf, buflen, "%s", pin);
794 : :
795 : 50 : ret = hostapd_wps_add_pin(wpa_s->ap_iface->bss[0], bssid, "any", pin,
796 : : timeout);
797 [ - + ]: 50 : if (ret)
798 : 0 : return -1;
799 : 50 : return ret_len;
800 : : }
801 : :
802 : :
803 : 0 : static void wpas_wps_ap_pin_timeout(void *eloop_data, void *user_ctx)
804 : : {
805 : 0 : struct wpa_supplicant *wpa_s = eloop_data;
806 : 0 : wpa_printf(MSG_DEBUG, "WPS: AP PIN timed out");
807 : 0 : wpas_wps_ap_pin_disable(wpa_s);
808 : 0 : }
809 : :
810 : :
811 : 0 : static void wpas_wps_ap_pin_enable(struct wpa_supplicant *wpa_s, int timeout)
812 : : {
813 : : struct hostapd_data *hapd;
814 : :
815 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
816 : 0 : return;
817 : 0 : hapd = wpa_s->ap_iface->bss[0];
818 : 0 : wpa_printf(MSG_DEBUG, "WPS: Enabling AP PIN (timeout=%d)", timeout);
819 : 0 : hapd->ap_pin_failures = 0;
820 : 0 : eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
821 [ # # ]: 0 : if (timeout > 0)
822 : 0 : eloop_register_timeout(timeout, 0,
823 : : wpas_wps_ap_pin_timeout, wpa_s, NULL);
824 : : }
825 : :
826 : :
827 : 0 : void wpas_wps_ap_pin_disable(struct wpa_supplicant *wpa_s)
828 : : {
829 : : struct hostapd_data *hapd;
830 : :
831 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
832 : 0 : return;
833 : 0 : wpa_printf(MSG_DEBUG, "WPS: Disabling AP PIN");
834 : 0 : hapd = wpa_s->ap_iface->bss[0];
835 : 0 : os_free(hapd->conf->ap_pin);
836 : 0 : hapd->conf->ap_pin = NULL;
837 : 0 : eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
838 : : }
839 : :
840 : :
841 : 0 : const char * wpas_wps_ap_pin_random(struct wpa_supplicant *wpa_s, int timeout)
842 : : {
843 : : struct hostapd_data *hapd;
844 : : unsigned int pin;
845 : : char pin_txt[9];
846 : :
847 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
848 : 0 : return NULL;
849 : 0 : hapd = wpa_s->ap_iface->bss[0];
850 : 0 : pin = wps_generate_pin();
851 : 0 : os_snprintf(pin_txt, sizeof(pin_txt), "%08u", pin);
852 : 0 : os_free(hapd->conf->ap_pin);
853 : 0 : hapd->conf->ap_pin = os_strdup(pin_txt);
854 [ # # ]: 0 : if (hapd->conf->ap_pin == NULL)
855 : 0 : return NULL;
856 : 0 : wpas_wps_ap_pin_enable(wpa_s, timeout);
857 : :
858 : 0 : return hapd->conf->ap_pin;
859 : : }
860 : :
861 : :
862 : 0 : const char * wpas_wps_ap_pin_get(struct wpa_supplicant *wpa_s)
863 : : {
864 : : struct hostapd_data *hapd;
865 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
866 : 0 : return NULL;
867 : 0 : hapd = wpa_s->ap_iface->bss[0];
868 : 0 : return hapd->conf->ap_pin;
869 : : }
870 : :
871 : :
872 : 0 : int wpas_wps_ap_pin_set(struct wpa_supplicant *wpa_s, const char *pin,
873 : : int timeout)
874 : : {
875 : : struct hostapd_data *hapd;
876 : : char pin_txt[9];
877 : : int ret;
878 : :
879 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
880 : 0 : return -1;
881 : 0 : hapd = wpa_s->ap_iface->bss[0];
882 : 0 : ret = os_snprintf(pin_txt, sizeof(pin_txt), "%s", pin);
883 [ # # ][ # # ]: 0 : if (ret < 0 || ret >= (int) sizeof(pin_txt))
884 : 0 : return -1;
885 : 0 : os_free(hapd->conf->ap_pin);
886 : 0 : hapd->conf->ap_pin = os_strdup(pin_txt);
887 [ # # ]: 0 : if (hapd->conf->ap_pin == NULL)
888 : 0 : return -1;
889 : 0 : wpas_wps_ap_pin_enable(wpa_s, timeout);
890 : :
891 : 0 : return 0;
892 : : }
893 : :
894 : :
895 : 0 : void wpa_supplicant_ap_pwd_auth_fail(struct wpa_supplicant *wpa_s)
896 : : {
897 : : struct hostapd_data *hapd;
898 : :
899 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
900 : 0 : return;
901 : 0 : hapd = wpa_s->ap_iface->bss[0];
902 : :
903 : : /*
904 : : * Registrar failed to prove its knowledge of the AP PIN. Disable AP
905 : : * PIN if this happens multiple times to slow down brute force attacks.
906 : : */
907 : 0 : hapd->ap_pin_failures++;
908 : 0 : wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u",
909 : : hapd->ap_pin_failures);
910 [ # # ]: 0 : if (hapd->ap_pin_failures < 3)
911 : 0 : return;
912 : :
913 : 0 : wpa_printf(MSG_DEBUG, "WPS: Disable AP PIN");
914 : 0 : hapd->ap_pin_failures = 0;
915 : 0 : os_free(hapd->conf->ap_pin);
916 : 0 : hapd->conf->ap_pin = NULL;
917 : : }
918 : :
919 : :
920 : : #ifdef CONFIG_WPS_NFC
921 : :
922 : 0 : struct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
923 : : int ndef)
924 : : {
925 : : struct hostapd_data *hapd;
926 : :
927 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
928 : 0 : return NULL;
929 : 0 : hapd = wpa_s->ap_iface->bss[0];
930 : 0 : return hostapd_wps_nfc_config_token(hapd, ndef);
931 : : }
932 : :
933 : :
934 : 0 : struct wpabuf * wpas_ap_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
935 : : int ndef)
936 : : {
937 : : struct hostapd_data *hapd;
938 : :
939 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
940 : 0 : return NULL;
941 : 0 : hapd = wpa_s->ap_iface->bss[0];
942 : 0 : return hostapd_wps_nfc_hs_cr(hapd, ndef);
943 : : }
944 : :
945 : : #endif /* CONFIG_WPS_NFC */
946 : :
947 : : #endif /* CONFIG_WPS */
948 : :
949 : :
950 : : #ifdef CONFIG_CTRL_IFACE
951 : :
952 : 0 : int ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s,
953 : : char *buf, size_t buflen)
954 : : {
955 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
956 : 0 : return -1;
957 : 0 : return hostapd_ctrl_iface_sta_first(wpa_s->ap_iface->bss[0],
958 : : buf, buflen);
959 : : }
960 : :
961 : :
962 : 0 : int ap_ctrl_iface_sta(struct wpa_supplicant *wpa_s, const char *txtaddr,
963 : : char *buf, size_t buflen)
964 : : {
965 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
966 : 0 : return -1;
967 : 0 : return hostapd_ctrl_iface_sta(wpa_s->ap_iface->bss[0], txtaddr,
968 : : buf, buflen);
969 : : }
970 : :
971 : :
972 : 0 : int ap_ctrl_iface_sta_next(struct wpa_supplicant *wpa_s, const char *txtaddr,
973 : : char *buf, size_t buflen)
974 : : {
975 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
976 : 0 : return -1;
977 : 0 : return hostapd_ctrl_iface_sta_next(wpa_s->ap_iface->bss[0], txtaddr,
978 : : buf, buflen);
979 : : }
980 : :
981 : :
982 : 0 : int ap_ctrl_iface_sta_disassociate(struct wpa_supplicant *wpa_s,
983 : : const char *txtaddr)
984 : : {
985 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
986 : 0 : return -1;
987 : 0 : return hostapd_ctrl_iface_disassociate(wpa_s->ap_iface->bss[0],
988 : : txtaddr);
989 : : }
990 : :
991 : :
992 : 0 : int ap_ctrl_iface_sta_deauthenticate(struct wpa_supplicant *wpa_s,
993 : : const char *txtaddr)
994 : : {
995 [ # # ]: 0 : if (wpa_s->ap_iface == NULL)
996 : 0 : return -1;
997 : 0 : return hostapd_ctrl_iface_deauthenticate(wpa_s->ap_iface->bss[0],
998 : : txtaddr);
999 : : }
1000 : :
1001 : :
1002 : 22 : int ap_ctrl_iface_wpa_get_status(struct wpa_supplicant *wpa_s, char *buf,
1003 : : size_t buflen, int verbose)
1004 : : {
1005 : 22 : char *pos = buf, *end = buf + buflen;
1006 : : int ret;
1007 : : struct hostapd_bss_config *conf;
1008 : :
1009 [ - + ]: 22 : if (wpa_s->ap_iface == NULL)
1010 : 0 : return -1;
1011 : :
1012 : 22 : conf = wpa_s->ap_iface->bss[0]->conf;
1013 [ - + ]: 22 : if (conf->wpa == 0)
1014 : 0 : return 0;
1015 : :
1016 : 22 : ret = os_snprintf(pos, end - pos,
1017 : : "pairwise_cipher=%s\n"
1018 : : "group_cipher=%s\n"
1019 : : "key_mgmt=%s\n",
1020 : : wpa_cipher_txt(conf->rsn_pairwise),
1021 : : wpa_cipher_txt(conf->wpa_group),
1022 : : wpa_key_mgmt_txt(conf->wpa_key_mgmt,
1023 : : conf->wpa));
1024 [ + - ][ - + ]: 22 : if (ret < 0 || ret >= end - pos)
1025 : 0 : return pos - buf;
1026 : 22 : pos += ret;
1027 : 22 : return pos - buf;
1028 : : }
1029 : :
1030 : : #endif /* CONFIG_CTRL_IFACE */
1031 : :
1032 : :
1033 : 307 : int wpa_supplicant_ap_update_beacon(struct wpa_supplicant *wpa_s)
1034 : : {
1035 : 307 : struct hostapd_iface *iface = wpa_s->ap_iface;
1036 : 307 : struct wpa_ssid *ssid = wpa_s->current_ssid;
1037 : : struct hostapd_data *hapd;
1038 : :
1039 [ + + ][ + - ]: 307 : if (ssid == NULL || wpa_s->ap_iface == NULL ||
[ + - ]
1040 [ - + ]: 227 : ssid->mode == WPAS_MODE_INFRA ||
1041 : 227 : ssid->mode == WPAS_MODE_IBSS)
1042 : 80 : return -1;
1043 : :
1044 : : #ifdef CONFIG_P2P
1045 [ + + ]: 227 : if (ssid->mode == WPAS_MODE_P2P_GO)
1046 : 193 : iface->conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER;
1047 [ + - ]: 34 : else if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
1048 : 34 : iface->conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER |
1049 : : P2P_GROUP_FORMATION;
1050 : : #endif /* CONFIG_P2P */
1051 : :
1052 : 227 : hapd = iface->bss[0];
1053 [ - + ]: 227 : if (hapd->drv_priv == NULL)
1054 : 0 : return -1;
1055 : 227 : ieee802_11_set_beacons(iface);
1056 : 227 : hostapd_set_ap_wps_ie(hapd);
1057 : :
1058 : 307 : return 0;
1059 : : }
1060 : :
1061 : :
1062 : 1 : int ap_switch_channel(struct wpa_supplicant *wpa_s,
1063 : : struct csa_settings *settings)
1064 : : {
1065 : : #ifdef NEED_AP_MLME
1066 [ + - ][ - + ]: 1 : if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
1067 : 0 : return -1;
1068 : :
1069 : 1 : return hostapd_switch_channel(wpa_s->ap_iface->bss[0], settings);
1070 : : #else /* NEED_AP_MLME */
1071 : : return -1;
1072 : : #endif /* NEED_AP_MLME */
1073 : : }
1074 : :
1075 : :
1076 : 1 : int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos)
1077 : : {
1078 : : struct csa_settings settings;
1079 : 1 : int ret = hostapd_parse_csa_settings(pos, &settings);
1080 : :
1081 [ - + ]: 1 : if (ret)
1082 : 0 : return ret;
1083 : :
1084 : 1 : return ap_switch_channel(wpa_s, &settings);
1085 : : }
1086 : :
1087 : :
1088 : 0 : void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
1089 : : int offset, int width, int cf1, int cf2)
1090 : : {
1091 [ # # ]: 0 : if (!wpa_s->ap_iface)
1092 : 0 : return;
1093 : :
1094 : 0 : wpa_s->assoc_freq = freq;
1095 : 0 : hostapd_event_ch_switch(wpa_s->ap_iface->bss[0], freq, ht, offset, width, cf1, cf1);
1096 : : }
1097 : :
1098 : :
1099 : 68 : int wpa_supplicant_ap_mac_addr_filter(struct wpa_supplicant *wpa_s,
1100 : : const u8 *addr)
1101 : : {
1102 : : struct hostapd_data *hapd;
1103 : : struct hostapd_bss_config *conf;
1104 : :
1105 [ - + ]: 68 : if (!wpa_s->ap_iface)
1106 : 0 : return -1;
1107 : :
1108 [ + + ]: 68 : if (addr)
1109 : 34 : wpa_printf(MSG_DEBUG, "AP: Set MAC address filter: " MACSTR,
1110 : 204 : MAC2STR(addr));
1111 : : else
1112 : 34 : wpa_printf(MSG_DEBUG, "AP: Clear MAC address filter");
1113 : :
1114 : 68 : hapd = wpa_s->ap_iface->bss[0];
1115 : 68 : conf = hapd->conf;
1116 : :
1117 : 68 : os_free(conf->accept_mac);
1118 : 68 : conf->accept_mac = NULL;
1119 : 68 : conf->num_accept_mac = 0;
1120 : 68 : os_free(conf->deny_mac);
1121 : 68 : conf->deny_mac = NULL;
1122 : 68 : conf->num_deny_mac = 0;
1123 : :
1124 [ + + ]: 68 : if (addr == NULL) {
1125 : 34 : conf->macaddr_acl = ACCEPT_UNLESS_DENIED;
1126 : 34 : return 0;
1127 : : }
1128 : :
1129 : 34 : conf->macaddr_acl = DENY_UNLESS_ACCEPTED;
1130 : 34 : conf->accept_mac = os_zalloc(sizeof(struct mac_acl_entry));
1131 [ - + ]: 34 : if (conf->accept_mac == NULL)
1132 : 0 : return -1;
1133 : 34 : os_memcpy(conf->accept_mac[0].addr, addr, ETH_ALEN);
1134 : 34 : conf->num_accept_mac = 1;
1135 : :
1136 : 68 : return 0;
1137 : : }
|