Line data Source code
1 : /*
2 : * hostapd / Initialization and configuration
3 : * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
4 : *
5 : * This software may be distributed under the terms of the BSD license.
6 : * See README for more details.
7 : */
8 :
9 : #include "utils/includes.h"
10 :
11 : #include "utils/common.h"
12 : #include "utils/eloop.h"
13 : #include "common/ieee802_11_defs.h"
14 : #include "common/wpa_ctrl.h"
15 : #include "radius/radius_client.h"
16 : #include "radius/radius_das.h"
17 : #include "eap_server/tncs.h"
18 : #include "eapol_auth/eapol_auth_sm.h"
19 : #include "eapol_auth/eapol_auth_sm_i.h"
20 : #include "hostapd.h"
21 : #include "authsrv.h"
22 : #include "sta_info.h"
23 : #include "accounting.h"
24 : #include "ap_list.h"
25 : #include "beacon.h"
26 : #include "iapp.h"
27 : #include "ieee802_1x.h"
28 : #include "ieee802_11_auth.h"
29 : #include "vlan_init.h"
30 : #include "wpa_auth.h"
31 : #include "wps_hostapd.h"
32 : #include "hw_features.h"
33 : #include "wpa_auth_glue.h"
34 : #include "ap_drv_ops.h"
35 : #include "ap_config.h"
36 : #include "p2p_hostapd.h"
37 : #include "gas_serv.h"
38 : #include "dfs.h"
39 : #include "ieee802_11.h"
40 : #include "bss_load.h"
41 : #include "x_snoop.h"
42 : #include "dhcp_snoop.h"
43 : #include "ndisc_snoop.h"
44 :
45 :
46 : static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason);
47 : static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd);
48 : static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd);
49 : static int setup_interface2(struct hostapd_iface *iface);
50 : static void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx);
51 :
52 :
53 2731 : int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
54 : int (*cb)(struct hostapd_iface *iface,
55 : void *ctx), void *ctx)
56 : {
57 : size_t i;
58 : int ret;
59 :
60 5768 : for (i = 0; i < interfaces->count; i++) {
61 3296 : ret = cb(interfaces->iface[i], ctx);
62 3296 : if (ret)
63 259 : return ret;
64 : }
65 :
66 2472 : return 0;
67 : }
68 :
69 :
70 19 : static void hostapd_reload_bss(struct hostapd_data *hapd)
71 : {
72 : struct hostapd_ssid *ssid;
73 :
74 : #ifndef CONFIG_NO_RADIUS
75 19 : radius_client_reconfig(hapd->radius, hapd->conf->radius);
76 : #endif /* CONFIG_NO_RADIUS */
77 :
78 19 : ssid = &hapd->conf->ssid;
79 19 : if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next &&
80 1 : ssid->wpa_passphrase_set && ssid->wpa_passphrase) {
81 : /*
82 : * Force PSK to be derived again since SSID or passphrase may
83 : * have changed.
84 : */
85 1 : hostapd_config_clear_wpa_psk(&hapd->conf->ssid.wpa_psk);
86 : }
87 19 : if (hostapd_setup_wpa_psk(hapd->conf)) {
88 0 : wpa_printf(MSG_ERROR, "Failed to re-configure WPA PSK "
89 : "after reloading configuration");
90 : }
91 :
92 19 : if (hapd->conf->ieee802_1x || hapd->conf->wpa)
93 17 : hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 1);
94 : else
95 2 : hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 0);
96 :
97 19 : if ((hapd->conf->wpa || hapd->conf->osen) && hapd->wpa_auth == NULL) {
98 15 : hostapd_setup_wpa(hapd);
99 30 : if (hapd->wpa_auth)
100 15 : wpa_init_keys(hapd->wpa_auth);
101 4 : } else if (hapd->conf->wpa) {
102 : const u8 *wpa_ie;
103 : size_t wpa_ie_len;
104 2 : hostapd_reconfig_wpa(hapd);
105 2 : wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len);
106 2 : if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len))
107 0 : wpa_printf(MSG_ERROR, "Failed to configure WPA IE for "
108 : "the kernel driver.");
109 2 : } else if (hapd->wpa_auth) {
110 1 : wpa_deinit(hapd->wpa_auth);
111 1 : hapd->wpa_auth = NULL;
112 1 : hostapd_set_privacy(hapd, 0);
113 1 : hostapd_setup_encryption(hapd->conf->iface, hapd);
114 1 : hostapd_set_generic_elem(hapd, (u8 *) "", 0);
115 : }
116 :
117 19 : ieee802_11_set_beacon(hapd);
118 19 : hostapd_update_wps(hapd);
119 :
120 38 : if (hapd->conf->ssid.ssid_set &&
121 19 : hostapd_set_ssid(hapd, hapd->conf->ssid.ssid,
122 19 : hapd->conf->ssid.ssid_len)) {
123 0 : wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
124 : /* try to continue */
125 : }
126 19 : wpa_printf(MSG_DEBUG, "Reconfigured interface %s", hapd->conf->iface);
127 19 : }
128 :
129 :
130 19 : static void hostapd_clear_old(struct hostapd_iface *iface)
131 : {
132 : size_t j;
133 :
134 : /*
135 : * Deauthenticate all stations since the new configuration may not
136 : * allow them to use the BSS anymore.
137 : */
138 38 : for (j = 0; j < iface->num_bss; j++) {
139 19 : hostapd_flush_old_stations(iface->bss[j],
140 : WLAN_REASON_PREV_AUTH_NOT_VALID);
141 19 : hostapd_broadcast_wep_clear(iface->bss[j]);
142 :
143 : #ifndef CONFIG_NO_RADIUS
144 : /* TODO: update dynamic data based on changed configuration
145 : * items (e.g., open/close sockets, etc.) */
146 19 : radius_client_flush(iface->bss[j]->radius, 0);
147 : #endif /* CONFIG_NO_RADIUS */
148 : }
149 19 : }
150 :
151 :
152 17 : int hostapd_reload_config(struct hostapd_iface *iface)
153 : {
154 17 : struct hostapd_data *hapd = iface->bss[0];
155 : struct hostapd_config *newconf, *oldconf;
156 : size_t j;
157 :
158 17 : if (iface->config_fname == NULL) {
159 : /* Only in-memory config in use - assume it has been updated */
160 16 : hostapd_clear_old(iface);
161 32 : for (j = 0; j < iface->num_bss; j++)
162 16 : hostapd_reload_bss(iface->bss[j]);
163 16 : return 0;
164 : }
165 :
166 2 : if (iface->interfaces == NULL ||
167 1 : iface->interfaces->config_read_cb == NULL)
168 0 : return -1;
169 1 : newconf = iface->interfaces->config_read_cb(iface->config_fname);
170 1 : if (newconf == NULL)
171 0 : return -1;
172 :
173 1 : hostapd_clear_old(iface);
174 :
175 1 : oldconf = hapd->iconf;
176 1 : iface->conf = newconf;
177 :
178 2 : for (j = 0; j < iface->num_bss; j++) {
179 1 : hapd = iface->bss[j];
180 1 : hapd->iconf = newconf;
181 1 : hapd->iconf->channel = oldconf->channel;
182 1 : hapd->iconf->secondary_channel = oldconf->secondary_channel;
183 1 : hapd->iconf->ieee80211n = oldconf->ieee80211n;
184 1 : hapd->iconf->ieee80211ac = oldconf->ieee80211ac;
185 1 : hapd->iconf->ht_capab = oldconf->ht_capab;
186 1 : hapd->iconf->vht_capab = oldconf->vht_capab;
187 1 : hapd->iconf->vht_oper_chwidth = oldconf->vht_oper_chwidth;
188 2 : hapd->iconf->vht_oper_centr_freq_seg0_idx =
189 1 : oldconf->vht_oper_centr_freq_seg0_idx;
190 2 : hapd->iconf->vht_oper_centr_freq_seg1_idx =
191 1 : oldconf->vht_oper_centr_freq_seg1_idx;
192 1 : hapd->conf = newconf->bss[j];
193 1 : hostapd_reload_bss(hapd);
194 : }
195 :
196 1 : hostapd_config_free(oldconf);
197 :
198 :
199 1 : return 0;
200 : }
201 :
202 :
203 1496 : static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd,
204 : char *ifname)
205 : {
206 : int i;
207 :
208 7480 : for (i = 0; i < NUM_WEP_KEYS; i++) {
209 5984 : if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, NULL, i,
210 : 0, NULL, 0, NULL, 0)) {
211 12 : wpa_printf(MSG_DEBUG, "Failed to clear default "
212 : "encryption keys (ifname=%s keyidx=%d)",
213 : ifname, i);
214 : }
215 : }
216 : #ifdef CONFIG_IEEE80211W
217 1496 : if (hapd->conf->ieee80211w) {
218 462 : for (i = NUM_WEP_KEYS; i < NUM_WEP_KEYS + 2; i++) {
219 308 : if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE,
220 : NULL, i, 0, NULL,
221 : 0, NULL, 0)) {
222 0 : wpa_printf(MSG_DEBUG, "Failed to clear "
223 : "default mgmt encryption keys "
224 : "(ifname=%s keyidx=%d)", ifname, i);
225 : }
226 : }
227 : }
228 : #endif /* CONFIG_IEEE80211W */
229 1496 : }
230 :
231 :
232 1496 : static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd)
233 : {
234 1496 : hostapd_broadcast_key_clear_iface(hapd, hapd->conf->iface);
235 1496 : return 0;
236 : }
237 :
238 :
239 1389 : static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
240 : {
241 1389 : int errors = 0, idx;
242 1389 : struct hostapd_ssid *ssid = &hapd->conf->ssid;
243 :
244 1389 : idx = ssid->wep.idx;
245 1391 : if (ssid->wep.default_len &&
246 4 : hostapd_drv_set_key(hapd->conf->iface,
247 : hapd, WPA_ALG_WEP, broadcast_ether_addr, idx,
248 2 : 1, NULL, 0, ssid->wep.key[idx],
249 : ssid->wep.len[idx])) {
250 2 : wpa_printf(MSG_WARNING, "Could not set WEP encryption.");
251 2 : errors++;
252 : }
253 :
254 1389 : return errors;
255 : }
256 :
257 :
258 1558 : static void hostapd_free_hapd_data(struct hostapd_data *hapd)
259 : {
260 1558 : os_free(hapd->probereq_cb);
261 1558 : hapd->probereq_cb = NULL;
262 :
263 : #ifdef CONFIG_P2P
264 345 : wpabuf_free(hapd->p2p_beacon_ie);
265 345 : hapd->p2p_beacon_ie = NULL;
266 345 : wpabuf_free(hapd->p2p_probe_resp_ie);
267 345 : hapd->p2p_probe_resp_ie = NULL;
268 : #endif /* CONFIG_P2P */
269 :
270 1558 : if (!hapd->started) {
271 170 : wpa_printf(MSG_ERROR, "%s: Interface %s wasn't started",
272 170 : __func__, hapd->conf->iface);
273 1728 : return;
274 : }
275 1388 : hapd->started = 0;
276 :
277 1388 : wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
278 1388 : iapp_deinit(hapd->iapp);
279 1388 : hapd->iapp = NULL;
280 1388 : accounting_deinit(hapd);
281 1388 : hostapd_deinit_wpa(hapd);
282 1388 : vlan_deinit(hapd);
283 1388 : hostapd_acl_deinit(hapd);
284 : #ifndef CONFIG_NO_RADIUS
285 1043 : radius_client_deinit(hapd->radius);
286 1043 : hapd->radius = NULL;
287 1043 : radius_das_deinit(hapd->radius_das);
288 1043 : hapd->radius_das = NULL;
289 : #endif /* CONFIG_NO_RADIUS */
290 :
291 1388 : hostapd_deinit_wps(hapd);
292 :
293 1388 : authsrv_deinit(hapd);
294 :
295 1388 : if (hapd->interface_added) {
296 42 : hapd->interface_added = 0;
297 42 : if (hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) {
298 0 : wpa_printf(MSG_WARNING,
299 : "Failed to remove BSS interface %s",
300 0 : hapd->conf->iface);
301 0 : hapd->interface_added = 1;
302 : } else {
303 : /*
304 : * Since this was a dynamically added interface, the
305 : * driver wrapper may have removed its internal instance
306 : * and hapd->drv_priv is not valid anymore.
307 : */
308 42 : hapd->drv_priv = NULL;
309 : }
310 : }
311 :
312 1388 : wpabuf_free(hapd->time_adv);
313 :
314 : #ifdef CONFIG_INTERWORKING
315 1388 : gas_serv_deinit(hapd);
316 : #endif /* CONFIG_INTERWORKING */
317 :
318 1388 : bss_load_update_deinit(hapd);
319 1388 : ndisc_snoop_deinit(hapd);
320 1388 : dhcp_snoop_deinit(hapd);
321 1388 : x_snoop_deinit(hapd);
322 :
323 : #ifdef CONFIG_SQLITE
324 1043 : bin_clear_free(hapd->tmp_eap_user.identity,
325 : hapd->tmp_eap_user.identity_len);
326 1043 : bin_clear_free(hapd->tmp_eap_user.password,
327 : hapd->tmp_eap_user.password_len);
328 : #endif /* CONFIG_SQLITE */
329 :
330 : #ifdef CONFIG_MESH
331 345 : wpabuf_free(hapd->mesh_pending_auth);
332 345 : hapd->mesh_pending_auth = NULL;
333 : #endif /* CONFIG_MESH */
334 : }
335 :
336 :
337 : /**
338 : * hostapd_cleanup - Per-BSS cleanup (deinitialization)
339 : * @hapd: Pointer to BSS data
340 : *
341 : * This function is used to free all per-BSS data structures and resources.
342 : * Most of the modules that are initialized in hostapd_setup_bss() are
343 : * deinitialized here.
344 : */
345 1476 : static void hostapd_cleanup(struct hostapd_data *hapd)
346 : {
347 1476 : wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s))", __func__, hapd,
348 1476 : hapd->conf->iface);
349 2607 : if (hapd->iface->interfaces &&
350 1131 : hapd->iface->interfaces->ctrl_iface_deinit)
351 1131 : hapd->iface->interfaces->ctrl_iface_deinit(hapd);
352 1476 : hostapd_free_hapd_data(hapd);
353 1476 : }
354 :
355 :
356 1531 : static void hostapd_cleanup_iface_partial(struct hostapd_iface *iface)
357 : {
358 1531 : wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
359 : #ifdef CONFIG_IEEE80211N
360 : #ifdef NEED_AP_MLME
361 1531 : hostapd_stop_setup_timers(iface);
362 : #endif /* NEED_AP_MLME */
363 : #endif /* CONFIG_IEEE80211N */
364 1531 : hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
365 1531 : iface->hw_features = NULL;
366 1531 : os_free(iface->current_rates);
367 1531 : iface->current_rates = NULL;
368 1531 : os_free(iface->basic_rates);
369 1531 : iface->basic_rates = NULL;
370 1531 : ap_list_deinit(iface);
371 1531 : }
372 :
373 :
374 : /**
375 : * hostapd_cleanup_iface - Complete per-interface cleanup
376 : * @iface: Pointer to interface data
377 : *
378 : * This function is called after per-BSS data structures are deinitialized
379 : * with hostapd_cleanup().
380 : */
381 1460 : static void hostapd_cleanup_iface(struct hostapd_iface *iface)
382 : {
383 1460 : wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
384 1460 : eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
385 :
386 1460 : hostapd_cleanup_iface_partial(iface);
387 1460 : hostapd_config_free(iface->conf);
388 1460 : iface->conf = NULL;
389 :
390 1460 : os_free(iface->config_fname);
391 1460 : os_free(iface->bss);
392 1460 : wpa_printf(MSG_DEBUG, "%s: free iface=%p", __func__, iface);
393 1460 : os_free(iface);
394 1460 : }
395 :
396 :
397 1550 : static void hostapd_clear_wep(struct hostapd_data *hapd)
398 : {
399 1550 : if (hapd->drv_priv && !hapd->iface->driver_ap_teardown) {
400 89 : hostapd_set_privacy(hapd, 0);
401 89 : hostapd_broadcast_wep_clear(hapd);
402 : }
403 1550 : }
404 :
405 :
406 1389 : static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd)
407 : {
408 : int i;
409 :
410 1389 : hostapd_broadcast_wep_set(hapd);
411 :
412 1389 : if (hapd->conf->ssid.wep.default_len) {
413 2 : hostapd_set_privacy(hapd, 1);
414 2 : return 0;
415 : }
416 :
417 : /*
418 : * When IEEE 802.1X is not enabled, the driver may need to know how to
419 : * set authentication algorithms for static WEP.
420 : */
421 1387 : hostapd_drv_set_authmode(hapd, hapd->conf->auth_algs);
422 :
423 6935 : for (i = 0; i < 4; i++) {
424 5563 : if (hapd->conf->ssid.wep.key[i] &&
425 30 : hostapd_drv_set_key(iface, hapd, WPA_ALG_WEP, NULL, i,
426 15 : i == hapd->conf->ssid.wep.idx, NULL, 0,
427 15 : hapd->conf->ssid.wep.key[i],
428 15 : hapd->conf->ssid.wep.len[i])) {
429 0 : wpa_printf(MSG_WARNING, "Could not set WEP "
430 : "encryption.");
431 0 : return -1;
432 : }
433 5563 : if (hapd->conf->ssid.wep.key[i] &&
434 15 : i == hapd->conf->ssid.wep.idx)
435 13 : hostapd_set_privacy(hapd, 1);
436 : }
437 :
438 1387 : return 0;
439 : }
440 :
441 :
442 2646 : static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason)
443 : {
444 2646 : int ret = 0;
445 : u8 addr[ETH_ALEN];
446 :
447 2646 : if (hostapd_drv_none(hapd) || hapd->drv_priv == NULL)
448 174 : return 0;
449 :
450 2472 : if (!hapd->iface->driver_ap_teardown) {
451 1165 : wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
452 : "Flushing old station entries");
453 :
454 1165 : if (hostapd_flush(hapd)) {
455 32 : wpa_msg(hapd->msg_ctx, MSG_WARNING,
456 : "Could not connect to kernel driver");
457 32 : ret = -1;
458 : }
459 : }
460 2472 : wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "Deauthenticate all stations");
461 2472 : os_memset(addr, 0xff, ETH_ALEN);
462 2472 : hostapd_drv_sta_deauth(hapd, addr, reason);
463 2472 : hostapd_free_stas(hapd);
464 :
465 2472 : return ret;
466 : }
467 :
468 :
469 1550 : static void hostapd_bss_deinit_no_free(struct hostapd_data *hapd)
470 : {
471 1550 : hostapd_free_stas(hapd);
472 1550 : hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
473 1550 : hostapd_clear_wep(hapd);
474 1550 : }
475 :
476 :
477 : /**
478 : * hostapd_validate_bssid_configuration - Validate BSSID configuration
479 : * @iface: Pointer to interface data
480 : * Returns: 0 on success, -1 on failure
481 : *
482 : * This function is used to validate that the configured BSSIDs are valid.
483 : */
484 1356 : static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface)
485 : {
486 1356 : u8 mask[ETH_ALEN] = { 0 };
487 1356 : struct hostapd_data *hapd = iface->bss[0];
488 1356 : unsigned int i = iface->conf->num_bss, bits = 0, j;
489 1356 : int auto_addr = 0;
490 :
491 1356 : if (hostapd_drv_none(hapd))
492 10 : return 0;
493 :
494 : /* Generate BSSID mask that is large enough to cover the BSSIDs. */
495 :
496 : /* Determine the bits necessary to cover the number of BSSIDs. */
497 1357 : for (i--; i; i >>= 1)
498 11 : bits++;
499 :
500 : /* Determine the bits necessary to any configured BSSIDs,
501 : if they are higher than the number of BSSIDs. */
502 2703 : for (j = 0; j < iface->conf->num_bss; j++) {
503 1357 : if (hostapd_mac_comp_empty(iface->conf->bss[j]->bssid) == 0) {
504 1302 : if (j)
505 4 : auto_addr++;
506 1302 : continue;
507 : }
508 :
509 385 : for (i = 0; i < ETH_ALEN; i++) {
510 660 : mask[i] |=
511 330 : iface->conf->bss[j]->bssid[i] ^
512 330 : hapd->own_addr[i];
513 : }
514 : }
515 :
516 1346 : if (!auto_addr)
517 1342 : goto skip_mask_ext;
518 :
519 4 : for (i = 0; i < ETH_ALEN && mask[i] == 0; i++)
520 : ;
521 4 : j = 0;
522 4 : if (i < ETH_ALEN) {
523 0 : j = (5 - i) * 8;
524 :
525 0 : while (mask[i] != 0) {
526 0 : mask[i] >>= 1;
527 0 : j++;
528 : }
529 : }
530 :
531 4 : if (bits < j)
532 0 : bits = j;
533 :
534 4 : if (bits > 40) {
535 0 : wpa_printf(MSG_ERROR, "Too many bits in the BSSID mask (%u)",
536 : bits);
537 0 : return -1;
538 : }
539 :
540 4 : os_memset(mask, 0xff, ETH_ALEN);
541 4 : j = bits / 8;
542 4 : for (i = 5; i > 5 - j; i--)
543 0 : mask[i] = 0;
544 4 : j = bits % 8;
545 12 : while (j--)
546 4 : mask[i] <<= 1;
547 :
548 : skip_mask_ext:
549 9422 : wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR " (%d bits)",
550 9422 : (unsigned long) iface->conf->num_bss, MAC2STR(mask), bits);
551 :
552 1346 : if (!auto_addr)
553 1342 : return 0;
554 :
555 28 : for (i = 0; i < ETH_ALEN; i++) {
556 24 : if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) {
557 0 : wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR
558 : " for start address " MACSTR ".",
559 0 : MAC2STR(mask), MAC2STR(hapd->own_addr));
560 0 : wpa_printf(MSG_ERROR, "Start address must be the "
561 : "first address in the block (i.e., addr "
562 : "AND mask == addr).");
563 0 : return -1;
564 : }
565 : }
566 :
567 4 : return 0;
568 : }
569 :
570 :
571 0 : static int mac_in_conf(struct hostapd_config *conf, const void *a)
572 : {
573 : size_t i;
574 :
575 0 : for (i = 0; i < conf->num_bss; i++) {
576 0 : if (hostapd_mac_comp(conf->bss[i]->bssid, a) == 0) {
577 0 : return 1;
578 : }
579 : }
580 :
581 0 : return 0;
582 : }
583 :
584 :
585 : #ifndef CONFIG_NO_RADIUS
586 :
587 22 : static int hostapd_das_nas_mismatch(struct hostapd_data *hapd,
588 : struct radius_das_attrs *attr)
589 : {
590 33 : if (attr->nas_identifier &&
591 22 : (!hapd->conf->nas_identifier ||
592 11 : os_strlen(hapd->conf->nas_identifier) !=
593 21 : attr->nas_identifier_len ||
594 10 : os_memcmp(hapd->conf->nas_identifier, attr->nas_identifier,
595 : attr->nas_identifier_len) != 0)) {
596 1 : wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-Identifier mismatch");
597 1 : return 1;
598 : }
599 :
600 30 : if (attr->nas_ip_addr &&
601 18 : (hapd->conf->own_ip_addr.af != AF_INET ||
602 9 : os_memcmp(&hapd->conf->own_ip_addr.u.v4, attr->nas_ip_addr, 4) !=
603 : 0)) {
604 1 : wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IP-Address mismatch");
605 1 : return 1;
606 : }
607 :
608 : #ifdef CONFIG_IPV6
609 20 : if (attr->nas_ipv6_addr &&
610 0 : (hapd->conf->own_ip_addr.af != AF_INET6 ||
611 0 : os_memcmp(&hapd->conf->own_ip_addr.u.v6, attr->nas_ipv6_addr, 16)
612 : != 0)) {
613 0 : wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IPv6-Address mismatch");
614 0 : return 1;
615 : }
616 : #endif /* CONFIG_IPV6 */
617 :
618 20 : return 0;
619 : }
620 :
621 :
622 20 : static struct sta_info * hostapd_das_find_sta(struct hostapd_data *hapd,
623 : struct radius_das_attrs *attr,
624 : int *multi)
625 : {
626 : struct sta_info *selected, *sta;
627 : char buf[128];
628 20 : int num_attr = 0;
629 : int count;
630 :
631 20 : *multi = 0;
632 :
633 43 : for (sta = hapd->sta_list; sta; sta = sta->next)
634 23 : sta->radius_das_match = 1;
635 :
636 20 : if (attr->sta_addr) {
637 6 : num_attr++;
638 6 : sta = ap_get_sta(hapd, attr->sta_addr);
639 6 : if (!sta) {
640 3 : wpa_printf(MSG_DEBUG,
641 : "RADIUS DAS: No Calling-Station-Id match");
642 3 : return NULL;
643 : }
644 :
645 3 : selected = sta;
646 8 : for (sta = hapd->sta_list; sta; sta = sta->next) {
647 5 : if (sta != selected)
648 2 : sta->radius_das_match = 0;
649 : }
650 3 : wpa_printf(MSG_DEBUG, "RADIUS DAS: Calling-Station-Id match");
651 : }
652 :
653 17 : if (attr->acct_session_id) {
654 3 : num_attr++;
655 3 : if (attr->acct_session_id_len != 17) {
656 1 : wpa_printf(MSG_DEBUG,
657 : "RADIUS DAS: Acct-Session-Id cannot match");
658 1 : return NULL;
659 : }
660 2 : count = 0;
661 :
662 4 : for (sta = hapd->sta_list; sta; sta = sta->next) {
663 2 : if (!sta->radius_das_match)
664 0 : continue;
665 2 : os_snprintf(buf, sizeof(buf), "%08X-%08X",
666 : sta->acct_session_id_hi,
667 : sta->acct_session_id_lo);
668 2 : if (os_memcmp(attr->acct_session_id, buf, 17) != 0)
669 1 : sta->radius_das_match = 0;
670 : else
671 1 : count++;
672 : }
673 :
674 2 : if (count == 0) {
675 1 : wpa_printf(MSG_DEBUG,
676 : "RADIUS DAS: No matches remaining after Acct-Session-Id check");
677 1 : return NULL;
678 : }
679 1 : wpa_printf(MSG_DEBUG, "RADIUS DAS: Acct-Session-Id match");
680 : }
681 :
682 15 : if (attr->acct_multi_session_id) {
683 4 : num_attr++;
684 4 : if (attr->acct_multi_session_id_len != 17) {
685 1 : wpa_printf(MSG_DEBUG,
686 : "RADIUS DAS: Acct-Multi-Session-Id cannot match");
687 1 : return NULL;
688 : }
689 3 : count = 0;
690 :
691 7 : for (sta = hapd->sta_list; sta; sta = sta->next) {
692 4 : if (!sta->radius_das_match)
693 0 : continue;
694 8 : if (!sta->eapol_sm ||
695 4 : !sta->eapol_sm->acct_multi_session_id_hi) {
696 0 : sta->radius_das_match = 0;
697 0 : continue;
698 : }
699 8 : os_snprintf(buf, sizeof(buf), "%08X+%08X",
700 4 : sta->eapol_sm->acct_multi_session_id_hi,
701 4 : sta->eapol_sm->acct_multi_session_id_lo);
702 4 : if (os_memcmp(attr->acct_multi_session_id, buf, 17) !=
703 : 0)
704 3 : sta->radius_das_match = 0;
705 : else
706 1 : count++;
707 : }
708 :
709 3 : if (count == 0) {
710 2 : wpa_printf(MSG_DEBUG,
711 : "RADIUS DAS: No matches remaining after Acct-Multi-Session-Id check");
712 2 : return NULL;
713 : }
714 1 : wpa_printf(MSG_DEBUG,
715 : "RADIUS DAS: Acct-Multi-Session-Id match");
716 : }
717 :
718 12 : if (attr->cui) {
719 3 : num_attr++;
720 3 : count = 0;
721 :
722 6 : for (sta = hapd->sta_list; sta; sta = sta->next) {
723 : struct wpabuf *cui;
724 :
725 3 : if (!sta->radius_das_match)
726 0 : continue;
727 3 : cui = ieee802_1x_get_radius_cui(sta->eapol_sm);
728 4 : if (!cui || wpabuf_len(cui) != attr->cui_len ||
729 1 : os_memcmp(wpabuf_head(cui), attr->cui,
730 : attr->cui_len) != 0)
731 2 : sta->radius_das_match = 0;
732 : else
733 1 : count++;
734 : }
735 :
736 3 : if (count == 0) {
737 2 : wpa_printf(MSG_DEBUG,
738 : "RADIUS DAS: No matches remaining after Chargeable-User-Identity check");
739 2 : return NULL;
740 : }
741 1 : wpa_printf(MSG_DEBUG,
742 : "RADIUS DAS: Chargeable-User-Identity match");
743 : }
744 :
745 10 : if (attr->user_name) {
746 5 : num_attr++;
747 5 : count = 0;
748 :
749 14 : for (sta = hapd->sta_list; sta; sta = sta->next) {
750 : u8 *identity;
751 : size_t identity_len;
752 :
753 9 : if (!sta->radius_das_match)
754 2 : continue;
755 7 : identity = ieee802_1x_get_identity(sta->eapol_sm,
756 : &identity_len);
757 14 : if (!identity ||
758 11 : identity_len != attr->user_name_len ||
759 4 : os_memcmp(identity, attr->user_name, identity_len)
760 : != 0)
761 3 : sta->radius_das_match = 0;
762 : else
763 4 : count++;
764 : }
765 :
766 5 : if (count == 0) {
767 2 : wpa_printf(MSG_DEBUG,
768 : "RADIUS DAS: No matches remaining after User-Name check");
769 2 : return NULL;
770 : }
771 3 : wpa_printf(MSG_DEBUG,
772 : "RADIUS DAS: User-Name match");
773 : }
774 :
775 8 : if (num_attr == 0) {
776 : /*
777 : * In theory, we could match all current associations, but it
778 : * seems safer to just reject requests that do not include any
779 : * session identification attributes.
780 : */
781 1 : wpa_printf(MSG_DEBUG,
782 : "RADIUS DAS: No session identification attributes included");
783 1 : return NULL;
784 : }
785 :
786 7 : selected = NULL;
787 18 : for (sta = hapd->sta_list; sta; sta = sta->next) {
788 12 : if (sta->radius_das_match) {
789 8 : if (selected) {
790 1 : *multi = 1;
791 1 : return NULL;
792 : }
793 7 : selected = sta;
794 : }
795 : }
796 :
797 6 : return selected;
798 : }
799 :
800 :
801 13 : static int hostapd_das_disconnect_pmksa(struct hostapd_data *hapd,
802 : struct radius_das_attrs *attr)
803 : {
804 13 : if (!hapd->wpa_auth)
805 0 : return -1;
806 13 : return wpa_auth_radius_das_disconnect_pmksa(hapd->wpa_auth, attr);
807 : }
808 :
809 :
810 : static enum radius_das_res
811 22 : hostapd_das_disconnect(void *ctx, struct radius_das_attrs *attr)
812 : {
813 22 : struct hostapd_data *hapd = ctx;
814 : struct sta_info *sta;
815 : int multi;
816 :
817 22 : if (hostapd_das_nas_mismatch(hapd, attr))
818 2 : return RADIUS_DAS_NAS_MISMATCH;
819 :
820 20 : sta = hostapd_das_find_sta(hapd, attr, &multi);
821 20 : if (sta == NULL) {
822 14 : if (multi) {
823 1 : wpa_printf(MSG_DEBUG,
824 : "RADIUS DAS: Multiple sessions match - not supported");
825 1 : return RADIUS_DAS_MULTI_SESSION_MATCH;
826 : }
827 13 : if (hostapd_das_disconnect_pmksa(hapd, attr) == 0) {
828 4 : wpa_printf(MSG_DEBUG,
829 : "RADIUS DAS: PMKSA cache entry matched");
830 4 : return RADIUS_DAS_SUCCESS;
831 : }
832 9 : wpa_printf(MSG_DEBUG, "RADIUS DAS: No matching session found");
833 9 : return RADIUS_DAS_SESSION_NOT_FOUND;
834 : }
835 :
836 36 : wpa_printf(MSG_DEBUG, "RADIUS DAS: Found a matching session " MACSTR
837 36 : " - disconnecting", MAC2STR(sta->addr));
838 6 : wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
839 :
840 6 : hostapd_drv_sta_deauth(hapd, sta->addr,
841 : WLAN_REASON_PREV_AUTH_NOT_VALID);
842 6 : ap_sta_deauthenticate(hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID);
843 :
844 6 : return RADIUS_DAS_SUCCESS;
845 : }
846 :
847 : #endif /* CONFIG_NO_RADIUS */
848 :
849 :
850 : /**
851 : * hostapd_setup_bss - Per-BSS setup (initialization)
852 : * @hapd: Pointer to BSS data
853 : * @first: Whether this BSS is the first BSS of an interface; -1 = not first,
854 : * but interface may exist
855 : *
856 : * This function is used to initialize all per-BSS data structures and
857 : * resources. This gets called in a loop for each BSS when an interface is
858 : * initialized. Most of the modules that are initialized here will be
859 : * deinitialized in hostapd_cleanup().
860 : */
861 1388 : static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
862 : {
863 1388 : struct hostapd_bss_config *conf = hapd->conf;
864 : u8 ssid[HOSTAPD_MAX_SSID_LEN + 1];
865 : int ssid_len, set_ssid;
866 : char force_ifname[IFNAMSIZ];
867 : u8 if_addr[ETH_ALEN];
868 1388 : int flush_old_stations = 1;
869 :
870 1388 : wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s), first=%d)",
871 1388 : __func__, hapd, conf->iface, first);
872 :
873 : #ifdef EAP_SERVER_TNC
874 1043 : if (conf->tnc && tncs_global_init() < 0) {
875 0 : wpa_printf(MSG_ERROR, "Failed to initialize TNCS");
876 0 : return -1;
877 : }
878 : #endif /* EAP_SERVER_TNC */
879 :
880 1388 : if (hapd->started) {
881 0 : wpa_printf(MSG_ERROR, "%s: Interface %s was already started",
882 0 : __func__, conf->iface);
883 0 : return -1;
884 : }
885 1388 : hapd->started = 1;
886 :
887 1388 : if (!first || first == -1) {
888 42 : if (hostapd_mac_comp_empty(conf->bssid) == 0) {
889 : /* Allocate the next available BSSID. */
890 : do {
891 0 : inc_byte_array(hapd->own_addr, ETH_ALEN);
892 0 : } while (mac_in_conf(hapd->iconf, hapd->own_addr));
893 : } else {
894 : /* Allocate the configured BSSID. */
895 42 : os_memcpy(hapd->own_addr, conf->bssid, ETH_ALEN);
896 :
897 42 : if (hostapd_mac_comp(hapd->own_addr,
898 42 : hapd->iface->bss[0]->own_addr) ==
899 : 0) {
900 0 : wpa_printf(MSG_ERROR, "BSS '%s' may not have "
901 : "BSSID set to the MAC address of "
902 0 : "the radio", conf->iface);
903 0 : return -1;
904 : }
905 : }
906 :
907 42 : hapd->interface_added = 1;
908 126 : if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS,
909 42 : conf->iface, hapd->own_addr, hapd,
910 : &hapd->drv_priv, force_ifname, if_addr,
911 42 : conf->bridge[0] ? conf->bridge : NULL,
912 : first == -1)) {
913 0 : wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID="
914 0 : MACSTR ")", MAC2STR(hapd->own_addr));
915 0 : hapd->interface_added = 0;
916 0 : return -1;
917 : }
918 : }
919 :
920 1388 : if (conf->wmm_enabled < 0)
921 1070 : conf->wmm_enabled = hapd->iconf->ieee80211n;
922 :
923 : #ifdef CONFIG_MESH
924 345 : if (hapd->iface->mconf == NULL)
925 311 : flush_old_stations = 0;
926 : #endif /* CONFIG_MESH */
927 :
928 1388 : if (flush_old_stations)
929 1077 : hostapd_flush_old_stations(hapd,
930 : WLAN_REASON_PREV_AUTH_NOT_VALID);
931 1388 : hostapd_set_privacy(hapd, 0);
932 :
933 1388 : hostapd_broadcast_wep_clear(hapd);
934 1388 : if (hostapd_setup_encryption(conf->iface, hapd))
935 0 : return -1;
936 :
937 : /*
938 : * Fetch the SSID from the system and use it or,
939 : * if one was specified in the config file, verify they
940 : * match.
941 : */
942 1388 : ssid_len = hostapd_get_ssid(hapd, ssid, sizeof(ssid));
943 1388 : if (ssid_len < 0) {
944 0 : wpa_printf(MSG_ERROR, "Could not read SSID from system");
945 0 : return -1;
946 : }
947 1388 : if (conf->ssid.ssid_set) {
948 : /*
949 : * If SSID is specified in the config file and it differs
950 : * from what is being used then force installation of the
951 : * new SSID.
952 : */
953 1344 : set_ssid = (conf->ssid.ssid_len != (size_t) ssid_len ||
954 0 : os_memcmp(conf->ssid.ssid, ssid, ssid_len) != 0);
955 : } else {
956 : /*
957 : * No SSID in the config file; just use the one we got
958 : * from the system.
959 : */
960 44 : set_ssid = 0;
961 44 : conf->ssid.ssid_len = ssid_len;
962 44 : os_memcpy(conf->ssid.ssid, ssid, conf->ssid.ssid_len);
963 : }
964 :
965 1388 : if (!hostapd_drv_none(hapd)) {
966 12402 : wpa_printf(MSG_ERROR, "Using interface %s with hwaddr " MACSTR
967 : " and ssid \"%s\"",
968 9646 : conf->iface, MAC2STR(hapd->own_addr),
969 1378 : wpa_ssid_txt(conf->ssid.ssid, conf->ssid.ssid_len));
970 : }
971 :
972 1388 : if (hostapd_setup_wpa_psk(conf)) {
973 4 : wpa_printf(MSG_ERROR, "WPA-PSK setup failed.");
974 4 : return -1;
975 : }
976 :
977 : /* Set SSID for the kernel driver (to be used in beacon and probe
978 : * response frames) */
979 1384 : if (set_ssid && hostapd_set_ssid(hapd, conf->ssid.ssid,
980 : conf->ssid.ssid_len)) {
981 0 : wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
982 0 : return -1;
983 : }
984 :
985 1384 : if (wpa_debug_level <= MSG_MSGDUMP)
986 1384 : conf->radius->msg_dumps = 1;
987 : #ifndef CONFIG_NO_RADIUS
988 1039 : hapd->radius = radius_client_init(hapd, conf->radius);
989 1039 : if (hapd->radius == NULL) {
990 0 : wpa_printf(MSG_ERROR, "RADIUS client initialization failed.");
991 0 : return -1;
992 : }
993 :
994 1039 : if (conf->radius_das_port) {
995 : struct radius_das_conf das_conf;
996 2 : os_memset(&das_conf, 0, sizeof(das_conf));
997 2 : das_conf.port = conf->radius_das_port;
998 2 : das_conf.shared_secret = conf->radius_das_shared_secret;
999 2 : das_conf.shared_secret_len =
1000 2 : conf->radius_das_shared_secret_len;
1001 2 : das_conf.client_addr = &conf->radius_das_client_addr;
1002 2 : das_conf.time_window = conf->radius_das_time_window;
1003 2 : das_conf.require_event_timestamp =
1004 2 : conf->radius_das_require_event_timestamp;
1005 2 : das_conf.ctx = hapd;
1006 2 : das_conf.disconnect = hostapd_das_disconnect;
1007 2 : hapd->radius_das = radius_das_init(&das_conf);
1008 2 : if (hapd->radius_das == NULL) {
1009 0 : wpa_printf(MSG_ERROR, "RADIUS DAS initialization "
1010 : "failed.");
1011 0 : return -1;
1012 : }
1013 : }
1014 : #endif /* CONFIG_NO_RADIUS */
1015 :
1016 1384 : if (hostapd_acl_init(hapd)) {
1017 0 : wpa_printf(MSG_ERROR, "ACL initialization failed.");
1018 0 : return -1;
1019 : }
1020 1384 : if (hostapd_init_wps(hapd, conf))
1021 0 : return -1;
1022 :
1023 1384 : if (authsrv_init(hapd) < 0)
1024 0 : return -1;
1025 :
1026 1384 : if (ieee802_1x_init(hapd)) {
1027 0 : wpa_printf(MSG_ERROR, "IEEE 802.1X initialization failed.");
1028 0 : return -1;
1029 : }
1030 :
1031 1384 : if ((conf->wpa || conf->osen) && hostapd_setup_wpa(hapd))
1032 0 : return -1;
1033 :
1034 1384 : if (accounting_init(hapd)) {
1035 1 : wpa_printf(MSG_ERROR, "Accounting initialization failed.");
1036 1 : return -1;
1037 : }
1038 :
1039 1383 : if (conf->ieee802_11f &&
1040 0 : (hapd->iapp = iapp_init(hapd, conf->iapp_iface)) == NULL) {
1041 0 : wpa_printf(MSG_ERROR, "IEEE 802.11F (IAPP) initialization "
1042 : "failed.");
1043 0 : return -1;
1044 : }
1045 :
1046 : #ifdef CONFIG_INTERWORKING
1047 1383 : if (gas_serv_init(hapd)) {
1048 0 : wpa_printf(MSG_ERROR, "GAS server initialization failed");
1049 0 : return -1;
1050 : }
1051 :
1052 1384 : if (conf->qos_map_set_len &&
1053 1 : hostapd_drv_set_qos_map(hapd, conf->qos_map_set,
1054 1 : conf->qos_map_set_len)) {
1055 0 : wpa_printf(MSG_ERROR, "Failed to initialize QoS Map");
1056 0 : return -1;
1057 : }
1058 : #endif /* CONFIG_INTERWORKING */
1059 :
1060 1383 : if (conf->bss_load_update_period && bss_load_update_init(hapd)) {
1061 0 : wpa_printf(MSG_ERROR, "BSS Load initialization failed");
1062 0 : return -1;
1063 : }
1064 :
1065 1383 : if (conf->proxy_arp) {
1066 7 : if (x_snoop_init(hapd)) {
1067 2 : wpa_printf(MSG_ERROR,
1068 : "Generic snooping infrastructure initialization failed");
1069 2 : return -1;
1070 : }
1071 :
1072 5 : if (dhcp_snoop_init(hapd)) {
1073 0 : wpa_printf(MSG_ERROR,
1074 : "DHCP snooping initialization failed");
1075 0 : return -1;
1076 : }
1077 :
1078 5 : if (ndisc_snoop_init(hapd)) {
1079 0 : wpa_printf(MSG_ERROR,
1080 : "Neighbor Discovery snooping initialization failed");
1081 0 : return -1;
1082 : }
1083 : }
1084 :
1085 1381 : if (!hostapd_drv_none(hapd) && vlan_init(hapd)) {
1086 0 : wpa_printf(MSG_ERROR, "VLAN initialization failed.");
1087 0 : return -1;
1088 : }
1089 :
1090 1381 : if (!conf->start_disabled && ieee802_11_set_beacon(hapd) < 0)
1091 3 : return -1;
1092 :
1093 1378 : if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0)
1094 0 : return -1;
1095 :
1096 1378 : if (hapd->driver && hapd->driver->set_operstate)
1097 1368 : hapd->driver->set_operstate(hapd->drv_priv, 1);
1098 :
1099 1378 : return 0;
1100 : }
1101 :
1102 :
1103 1337 : static void hostapd_tx_queue_params(struct hostapd_iface *iface)
1104 : {
1105 1337 : struct hostapd_data *hapd = iface->bss[0];
1106 : int i;
1107 : struct hostapd_tx_queue_params *p;
1108 :
1109 : #ifdef CONFIG_MESH
1110 345 : if (iface->mconf == NULL)
1111 656 : return;
1112 : #endif /* CONFIG_MESH */
1113 :
1114 5130 : for (i = 0; i < NUM_TX_QUEUES; i++) {
1115 4104 : p = &iface->conf->tx_queue[i];
1116 :
1117 4104 : if (hostapd_set_tx_queue_params(hapd, i, p->aifs, p->cwmin,
1118 : p->cwmax, p->burst)) {
1119 136 : wpa_printf(MSG_DEBUG, "Failed to set TX queue "
1120 : "parameters for queue %d.", i);
1121 : /* Continue anyway */
1122 : }
1123 : }
1124 992 : }
1125 :
1126 :
1127 0 : static int hostapd_set_acl_list(struct hostapd_data *hapd,
1128 : struct mac_acl_entry *mac_acl,
1129 : int n_entries, u8 accept_acl)
1130 : {
1131 : struct hostapd_acl_params *acl_params;
1132 : int i, err;
1133 :
1134 0 : acl_params = os_zalloc(sizeof(*acl_params) +
1135 0 : (n_entries * sizeof(acl_params->mac_acl[0])));
1136 0 : if (!acl_params)
1137 0 : return -ENOMEM;
1138 :
1139 0 : for (i = 0; i < n_entries; i++)
1140 0 : os_memcpy(acl_params->mac_acl[i].addr, mac_acl[i].addr,
1141 : ETH_ALEN);
1142 :
1143 0 : acl_params->acl_policy = accept_acl;
1144 0 : acl_params->num_mac_acl = n_entries;
1145 :
1146 0 : err = hostapd_drv_set_acl(hapd, acl_params);
1147 :
1148 0 : os_free(acl_params);
1149 :
1150 0 : return err;
1151 : }
1152 :
1153 :
1154 1337 : static void hostapd_set_acl(struct hostapd_data *hapd)
1155 : {
1156 1337 : struct hostapd_config *conf = hapd->iconf;
1157 : int err;
1158 : u8 accept_acl;
1159 :
1160 1337 : if (hapd->iface->drv_max_acl_mac_addrs == 0)
1161 1337 : return;
1162 :
1163 0 : if (conf->bss[0]->macaddr_acl == DENY_UNLESS_ACCEPTED) {
1164 0 : accept_acl = 1;
1165 0 : err = hostapd_set_acl_list(hapd, conf->bss[0]->accept_mac,
1166 0 : conf->bss[0]->num_accept_mac,
1167 : accept_acl);
1168 0 : if (err) {
1169 0 : wpa_printf(MSG_DEBUG, "Failed to set accept acl");
1170 0 : return;
1171 : }
1172 0 : } else if (conf->bss[0]->macaddr_acl == ACCEPT_UNLESS_DENIED) {
1173 0 : accept_acl = 0;
1174 0 : err = hostapd_set_acl_list(hapd, conf->bss[0]->deny_mac,
1175 0 : conf->bss[0]->num_deny_mac,
1176 : accept_acl);
1177 0 : if (err) {
1178 0 : wpa_printf(MSG_DEBUG, "Failed to set deny acl");
1179 0 : return;
1180 : }
1181 : }
1182 : }
1183 :
1184 :
1185 37 : static int start_ctrl_iface_bss(struct hostapd_data *hapd)
1186 : {
1187 74 : if (!hapd->iface->interfaces ||
1188 37 : !hapd->iface->interfaces->ctrl_iface_init)
1189 0 : return 0;
1190 :
1191 37 : if (hapd->iface->interfaces->ctrl_iface_init(hapd)) {
1192 0 : wpa_printf(MSG_ERROR,
1193 : "Failed to setup control interface for %s",
1194 0 : hapd->conf->iface);
1195 0 : return -1;
1196 : }
1197 :
1198 37 : return 0;
1199 : }
1200 :
1201 :
1202 2420 : static int start_ctrl_iface(struct hostapd_iface *iface)
1203 : {
1204 : size_t i;
1205 :
1206 2420 : if (!iface->interfaces || !iface->interfaces->ctrl_iface_init)
1207 345 : return 0;
1208 :
1209 4157 : for (i = 0; i < iface->num_bss; i++) {
1210 2088 : struct hostapd_data *hapd = iface->bss[i];
1211 2088 : if (iface->interfaces->ctrl_iface_init(hapd)) {
1212 6 : wpa_printf(MSG_ERROR,
1213 : "Failed to setup control interface for %s",
1214 6 : hapd->conf->iface);
1215 6 : return -1;
1216 : }
1217 : }
1218 :
1219 2069 : return 0;
1220 : }
1221 :
1222 :
1223 0 : static void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx)
1224 : {
1225 0 : struct hostapd_iface *iface = eloop_ctx;
1226 :
1227 0 : if (!iface->wait_channel_update) {
1228 0 : wpa_printf(MSG_INFO, "Channel list update timeout, but interface was not waiting for it");
1229 0 : return;
1230 : }
1231 :
1232 : /*
1233 : * It is possible that the existing channel list is acceptable, so try
1234 : * to proceed.
1235 : */
1236 0 : wpa_printf(MSG_DEBUG, "Channel list update timeout - try to continue anyway");
1237 0 : setup_interface2(iface);
1238 : }
1239 :
1240 :
1241 1499 : void hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator)
1242 : {
1243 1499 : if (!iface->wait_channel_update || initiator != REGDOM_SET_BY_USER)
1244 2962 : return;
1245 :
1246 36 : wpa_printf(MSG_DEBUG, "Channel list updated - continue setup");
1247 36 : eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
1248 36 : setup_interface2(iface);
1249 : }
1250 :
1251 :
1252 1356 : static int setup_interface(struct hostapd_iface *iface)
1253 : {
1254 1356 : struct hostapd_data *hapd = iface->bss[0];
1255 : size_t i;
1256 :
1257 : /*
1258 : * It is possible that setup_interface() is called after the interface
1259 : * was disabled etc., in which case driver_ap_teardown is possibly set
1260 : * to 1. Clear it here so any other key/station deletion, which is not
1261 : * part of a teardown flow, would also call the relevant driver
1262 : * callbacks.
1263 : */
1264 1356 : iface->driver_ap_teardown = 0;
1265 :
1266 1356 : if (!iface->phy[0]) {
1267 1330 : const char *phy = hostapd_drv_get_radio_name(hapd);
1268 1330 : if (phy) {
1269 1320 : wpa_printf(MSG_DEBUG, "phy: %s", phy);
1270 1320 : os_strlcpy(iface->phy, phy, sizeof(iface->phy));
1271 : }
1272 : }
1273 :
1274 : /*
1275 : * Make sure that all BSSes get configured with a pointer to the same
1276 : * driver interface.
1277 : */
1278 1363 : for (i = 1; i < iface->num_bss; i++) {
1279 7 : iface->bss[i]->driver = hapd->driver;
1280 7 : iface->bss[i]->drv_priv = hapd->drv_priv;
1281 : }
1282 :
1283 1356 : if (hostapd_validate_bssid_configuration(iface))
1284 0 : return -1;
1285 :
1286 : /*
1287 : * Initialize control interfaces early to allow external monitoring of
1288 : * channel setup operations that may take considerable amount of time
1289 : * especially for DFS cases.
1290 : */
1291 1356 : if (start_ctrl_iface(iface))
1292 0 : return -1;
1293 :
1294 1356 : if (hapd->iconf->country[0] && hapd->iconf->country[1]) {
1295 : char country[4], previous_country[4];
1296 :
1297 46 : hostapd_set_state(iface, HAPD_IFACE_COUNTRY_UPDATE);
1298 46 : if (hostapd_get_country(hapd, previous_country) < 0)
1299 0 : previous_country[0] = '\0';
1300 :
1301 46 : os_memcpy(country, hapd->iconf->country, 3);
1302 46 : country[3] = '\0';
1303 46 : if (hostapd_set_country(hapd, country) < 0) {
1304 0 : wpa_printf(MSG_ERROR, "Failed to set country code");
1305 36 : return -1;
1306 : }
1307 :
1308 46 : wpa_printf(MSG_DEBUG, "Previous country code %s, new country code %s",
1309 : previous_country, country);
1310 :
1311 46 : if (os_strncmp(previous_country, country, 2) != 0) {
1312 36 : wpa_printf(MSG_DEBUG, "Continue interface setup after channel list update");
1313 36 : iface->wait_channel_update = 1;
1314 36 : eloop_register_timeout(5, 0,
1315 : channel_list_update_timeout,
1316 : iface, NULL);
1317 36 : return 0;
1318 : }
1319 : }
1320 :
1321 1320 : return setup_interface2(iface);
1322 : }
1323 :
1324 :
1325 1356 : static int setup_interface2(struct hostapd_iface *iface)
1326 : {
1327 1356 : iface->wait_channel_update = 0;
1328 :
1329 1356 : if (hostapd_get_hw_features(iface)) {
1330 : /* Not all drivers support this yet, so continue without hw
1331 : * feature data. */
1332 : } else {
1333 1346 : int ret = hostapd_select_hw_mode(iface);
1334 1346 : if (ret < 0) {
1335 2 : wpa_printf(MSG_ERROR, "Could not select hw_mode and "
1336 : "channel. (%d)", ret);
1337 2 : goto fail;
1338 : }
1339 1344 : if (ret == 1) {
1340 10 : wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback (ACS)");
1341 10 : return 0;
1342 : }
1343 1334 : ret = hostapd_check_ht_capab(iface);
1344 1334 : if (ret < 0)
1345 2 : goto fail;
1346 1332 : if (ret == 1) {
1347 44 : wpa_printf(MSG_DEBUG, "Interface initialization will "
1348 : "be completed in a callback");
1349 44 : return 0;
1350 : }
1351 :
1352 1288 : if (iface->conf->ieee80211h)
1353 6 : wpa_printf(MSG_DEBUG, "DFS support is enabled");
1354 : }
1355 1298 : return hostapd_setup_interface_complete(iface, 0);
1356 :
1357 : fail:
1358 4 : hostapd_set_state(iface, HAPD_IFACE_DISABLED);
1359 4 : wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
1360 4 : if (iface->interfaces && iface->interfaces->terminate_on_error)
1361 0 : eloop_terminate();
1362 4 : return -1;
1363 : }
1364 :
1365 :
1366 : /**
1367 : * hostapd_setup_interface_complete - Complete interface setup
1368 : *
1369 : * This function is called when previous steps in the interface setup has been
1370 : * completed. This can also start operations, e.g., DFS, that will require
1371 : * additional processing before interface is ready to be enabled. Such
1372 : * operations will call this function from eloop callbacks when finished.
1373 : */
1374 1359 : int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
1375 : {
1376 1359 : struct hostapd_data *hapd = iface->bss[0];
1377 : size_t j;
1378 : u8 *prev_addr;
1379 1359 : int delay_apply_cfg = 0;
1380 1359 : int res_dfs_offload = 0;
1381 :
1382 1359 : if (err)
1383 0 : goto fail;
1384 :
1385 1359 : wpa_printf(MSG_DEBUG, "Completing interface initialization");
1386 1359 : if (iface->conf->channel) {
1387 : #ifdef NEED_AP_MLME
1388 : int res;
1389 : #endif /* NEED_AP_MLME */
1390 :
1391 1349 : iface->freq = hostapd_hw_get_freq(hapd, iface->conf->channel);
1392 4047 : wpa_printf(MSG_DEBUG, "Mode: %s Channel: %d "
1393 : "Frequency: %d MHz",
1394 1349 : hostapd_hw_mode_txt(iface->conf->hw_mode),
1395 1349 : iface->conf->channel, iface->freq);
1396 :
1397 : #ifdef NEED_AP_MLME
1398 : /* Handle DFS only if it is not offloaded to the driver */
1399 1349 : if (!(iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)) {
1400 : /* Check DFS */
1401 1349 : res = hostapd_handle_dfs(iface);
1402 1349 : if (res <= 0) {
1403 13 : if (res < 0)
1404 1 : goto fail;
1405 12 : return res;
1406 : }
1407 : } else {
1408 : /* If DFS is offloaded to the driver */
1409 0 : res_dfs_offload = hostapd_handle_dfs_offload(iface);
1410 0 : if (res_dfs_offload <= 0) {
1411 0 : if (res_dfs_offload < 0)
1412 0 : goto fail;
1413 : } else {
1414 0 : wpa_printf(MSG_DEBUG,
1415 : "Proceed with AP/channel setup");
1416 : /*
1417 : * If this is a DFS channel, move to completing
1418 : * AP setup.
1419 : */
1420 0 : if (res_dfs_offload == 1)
1421 0 : goto dfs_offload;
1422 : /* Otherwise fall through. */
1423 : }
1424 : }
1425 : #endif /* NEED_AP_MLME */
1426 :
1427 : #ifdef CONFIG_MESH
1428 345 : if (iface->mconf != NULL) {
1429 34 : wpa_printf(MSG_DEBUG,
1430 : "%s: Mesh configuration will be applied while joining the mesh network",
1431 34 : iface->bss[0]->conf->iface);
1432 34 : delay_apply_cfg = 1;
1433 : }
1434 : #endif /* CONFIG_MESH */
1435 :
1436 2638 : if (!delay_apply_cfg &&
1437 9114 : hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq,
1438 1302 : hapd->iconf->channel,
1439 1302 : hapd->iconf->ieee80211n,
1440 1302 : hapd->iconf->ieee80211ac,
1441 1302 : hapd->iconf->secondary_channel,
1442 1302 : hapd->iconf->vht_oper_chwidth,
1443 1302 : hapd->iconf->vht_oper_centr_freq_seg0_idx,
1444 1302 : hapd->iconf->vht_oper_centr_freq_seg1_idx)) {
1445 0 : wpa_printf(MSG_ERROR, "Could not set channel for "
1446 : "kernel driver");
1447 0 : goto fail;
1448 : }
1449 : }
1450 :
1451 1346 : if (iface->current_mode) {
1452 1336 : if (hostapd_prepare_rates(iface, iface->current_mode)) {
1453 0 : wpa_printf(MSG_ERROR, "Failed to prepare rates "
1454 : "table.");
1455 0 : hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
1456 : HOSTAPD_LEVEL_WARNING,
1457 : "Failed to prepare rates table.");
1458 0 : goto fail;
1459 : }
1460 : }
1461 :
1462 1347 : if (hapd->iconf->rts_threshold > -1 &&
1463 1 : hostapd_set_rts(hapd, hapd->iconf->rts_threshold)) {
1464 0 : wpa_printf(MSG_ERROR, "Could not set RTS threshold for "
1465 : "kernel driver");
1466 0 : goto fail;
1467 : }
1468 :
1469 1349 : if (hapd->iconf->fragm_threshold > -1 &&
1470 3 : hostapd_set_frag(hapd, hapd->iconf->fragm_threshold)) {
1471 0 : wpa_printf(MSG_ERROR, "Could not set fragmentation threshold "
1472 : "for kernel driver");
1473 0 : goto fail;
1474 : }
1475 :
1476 1346 : prev_addr = hapd->own_addr;
1477 :
1478 2691 : for (j = 0; j < iface->num_bss; j++) {
1479 1354 : hapd = iface->bss[j];
1480 1354 : if (j)
1481 8 : os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN);
1482 1354 : if (hostapd_setup_bss(hapd, j == 0)) {
1483 : do {
1484 9 : hapd = iface->bss[j];
1485 9 : hostapd_bss_deinit_no_free(hapd);
1486 9 : hostapd_free_hapd_data(hapd);
1487 9 : } while (j-- > 0);
1488 9 : goto fail;
1489 : }
1490 1345 : if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0)
1491 1291 : prev_addr = hapd->own_addr;
1492 : }
1493 1337 : hapd = iface->bss[0];
1494 :
1495 1337 : hostapd_tx_queue_params(iface);
1496 :
1497 1337 : ap_list_init(iface);
1498 :
1499 1337 : hostapd_set_acl(hapd);
1500 :
1501 1337 : if (hostapd_driver_commit(hapd) < 0) {
1502 0 : wpa_printf(MSG_ERROR, "%s: Failed to commit driver "
1503 : "configuration", __func__);
1504 0 : goto fail;
1505 : }
1506 :
1507 : /*
1508 : * WPS UPnP module can be initialized only when the "upnp_iface" is up.
1509 : * If "interface" and "upnp_iface" are the same (e.g., non-bridge
1510 : * mode), the interface is up only after driver_commit, so initialize
1511 : * WPS after driver_commit.
1512 : */
1513 2682 : for (j = 0; j < iface->num_bss; j++) {
1514 1345 : if (hostapd_init_wps_complete(iface->bss[j]))
1515 0 : goto fail;
1516 : }
1517 :
1518 1337 : if ((iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
1519 : !res_dfs_offload) {
1520 : /*
1521 : * If freq is DFS, and DFS is offloaded to the driver, then wait
1522 : * for CAC to complete.
1523 : */
1524 0 : wpa_printf(MSG_DEBUG, "%s: Wait for CAC to complete", __func__);
1525 0 : return res_dfs_offload;
1526 : }
1527 :
1528 : #ifdef NEED_AP_MLME
1529 : dfs_offload:
1530 : #endif /* NEED_AP_MLME */
1531 1337 : hostapd_set_state(iface, HAPD_IFACE_ENABLED);
1532 1337 : wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_ENABLED);
1533 1337 : if (hapd->setup_complete_cb)
1534 311 : hapd->setup_complete_cb(hapd->setup_complete_cb_ctx);
1535 :
1536 1337 : wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
1537 1337 : iface->bss[0]->conf->iface);
1538 1337 : if (iface->interfaces && iface->interfaces->terminate_on_error > 0)
1539 10 : iface->interfaces->terminate_on_error--;
1540 :
1541 1337 : return 0;
1542 :
1543 : fail:
1544 10 : wpa_printf(MSG_ERROR, "Interface initialization failed");
1545 10 : hostapd_set_state(iface, HAPD_IFACE_DISABLED);
1546 10 : wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
1547 10 : if (iface->interfaces && iface->interfaces->terminate_on_error)
1548 0 : eloop_terminate();
1549 10 : return -1;
1550 : }
1551 :
1552 :
1553 : /**
1554 : * hostapd_setup_interface - Setup of an interface
1555 : * @iface: Pointer to interface data.
1556 : * Returns: 0 on success, -1 on failure
1557 : *
1558 : * Initializes the driver interface, validates the configuration,
1559 : * and sets driver parameters based on the configuration.
1560 : * Flushes old stations, sets the channel, encryption,
1561 : * beacons, and WDS links based on the configuration.
1562 : *
1563 : * If interface setup requires more time, e.g., to perform HT co-ex scans, ACS,
1564 : * or DFS operations, this function returns 0 before such operations have been
1565 : * completed. The pending operations are registered into eloop and will be
1566 : * completed from eloop callbacks. Those callbacks end up calling
1567 : * hostapd_setup_interface_complete() once setup has been completed.
1568 : */
1569 1356 : int hostapd_setup_interface(struct hostapd_iface *iface)
1570 : {
1571 : int ret;
1572 :
1573 1356 : ret = setup_interface(iface);
1574 1356 : if (ret) {
1575 12 : wpa_printf(MSG_ERROR, "%s: Unable to setup interface.",
1576 12 : iface->bss[0]->conf->iface);
1577 12 : return -1;
1578 : }
1579 :
1580 1344 : return 0;
1581 : }
1582 :
1583 :
1584 : /**
1585 : * hostapd_alloc_bss_data - Allocate and initialize per-BSS data
1586 : * @hapd_iface: Pointer to interface data
1587 : * @conf: Pointer to per-interface configuration
1588 : * @bss: Pointer to per-BSS configuration for this BSS
1589 : * Returns: Pointer to allocated BSS data
1590 : *
1591 : * This function is used to allocate per-BSS data structure. This data will be
1592 : * freed after hostapd_cleanup() is called for it during interface
1593 : * deinitialization.
1594 : */
1595 : struct hostapd_data *
1596 1446 : hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
1597 : struct hostapd_config *conf,
1598 : struct hostapd_bss_config *bss)
1599 : {
1600 : struct hostapd_data *hapd;
1601 :
1602 1446 : hapd = os_zalloc(sizeof(*hapd));
1603 1446 : if (hapd == NULL)
1604 4 : return NULL;
1605 :
1606 1442 : hapd->new_assoc_sta_cb = hostapd_new_assoc_sta;
1607 1442 : hapd->iconf = conf;
1608 1442 : hapd->conf = bss;
1609 1442 : hapd->iface = hapd_iface;
1610 1442 : hapd->driver = hapd->iconf->driver;
1611 1442 : hapd->ctrl_sock = -1;
1612 :
1613 1442 : return hapd;
1614 : }
1615 :
1616 :
1617 1468 : static void hostapd_bss_deinit(struct hostapd_data *hapd)
1618 : {
1619 1468 : wpa_printf(MSG_DEBUG, "%s: deinit bss %s", __func__,
1620 1468 : hapd->conf->iface);
1621 1468 : hostapd_bss_deinit_no_free(hapd);
1622 1468 : wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
1623 1468 : hostapd_cleanup(hapd);
1624 1468 : }
1625 :
1626 :
1627 1426 : void hostapd_interface_deinit(struct hostapd_iface *iface)
1628 : {
1629 : int j;
1630 :
1631 1426 : wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
1632 1426 : if (iface == NULL)
1633 1426 : return;
1634 :
1635 1426 : hostapd_set_state(iface, HAPD_IFACE_DISABLED);
1636 :
1637 : #ifdef CONFIG_IEEE80211N
1638 : #ifdef NEED_AP_MLME
1639 1426 : hostapd_stop_setup_timers(iface);
1640 1426 : eloop_cancel_timeout(ap_ht2040_timeout, iface, NULL);
1641 : #endif /* NEED_AP_MLME */
1642 : #endif /* CONFIG_IEEE80211N */
1643 1426 : eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
1644 1426 : iface->wait_channel_update = 0;
1645 :
1646 2857 : for (j = iface->num_bss - 1; j >= 0; j--)
1647 1431 : hostapd_bss_deinit(iface->bss[j]);
1648 : }
1649 :
1650 :
1651 1426 : void hostapd_interface_free(struct hostapd_iface *iface)
1652 : {
1653 : size_t j;
1654 1426 : wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
1655 2857 : for (j = 0; j < iface->num_bss; j++) {
1656 1431 : wpa_printf(MSG_DEBUG, "%s: free hapd %p",
1657 1431 : __func__, iface->bss[j]);
1658 1431 : os_free(iface->bss[j]);
1659 : }
1660 1426 : hostapd_cleanup_iface(iface);
1661 1426 : }
1662 :
1663 :
1664 : /**
1665 : * hostapd_init - Allocate and initialize per-interface data
1666 : * @config_file: Path to the configuration file
1667 : * Returns: Pointer to the allocated interface data or %NULL on failure
1668 : *
1669 : * This function is used to allocate main data structures for per-interface
1670 : * data. The allocated data buffer will be freed by calling
1671 : * hostapd_cleanup_iface().
1672 : */
1673 27 : struct hostapd_iface * hostapd_init(struct hapd_interfaces *interfaces,
1674 : const char *config_file)
1675 : {
1676 27 : struct hostapd_iface *hapd_iface = NULL;
1677 27 : struct hostapd_config *conf = NULL;
1678 : struct hostapd_data *hapd;
1679 : size_t i;
1680 :
1681 27 : hapd_iface = os_zalloc(sizeof(*hapd_iface));
1682 27 : if (hapd_iface == NULL)
1683 2 : goto fail;
1684 :
1685 25 : hapd_iface->config_fname = os_strdup(config_file);
1686 25 : if (hapd_iface->config_fname == NULL)
1687 1 : goto fail;
1688 :
1689 24 : conf = interfaces->config_read_cb(hapd_iface->config_fname);
1690 24 : if (conf == NULL)
1691 0 : goto fail;
1692 24 : hapd_iface->conf = conf;
1693 :
1694 24 : hapd_iface->num_bss = conf->num_bss;
1695 24 : hapd_iface->bss = os_calloc(conf->num_bss,
1696 : sizeof(struct hostapd_data *));
1697 24 : if (hapd_iface->bss == NULL)
1698 0 : goto fail;
1699 :
1700 48 : for (i = 0; i < conf->num_bss; i++) {
1701 48 : hapd = hapd_iface->bss[i] =
1702 24 : hostapd_alloc_bss_data(hapd_iface, conf,
1703 24 : conf->bss[i]);
1704 24 : if (hapd == NULL)
1705 0 : goto fail;
1706 24 : hapd->msg_ctx = hapd;
1707 : }
1708 :
1709 24 : return hapd_iface;
1710 :
1711 : fail:
1712 3 : wpa_printf(MSG_ERROR, "Failed to set up interface with %s",
1713 : config_file);
1714 3 : if (conf)
1715 0 : hostapd_config_free(conf);
1716 3 : if (hapd_iface) {
1717 1 : os_free(hapd_iface->config_fname);
1718 1 : os_free(hapd_iface->bss);
1719 1 : wpa_printf(MSG_DEBUG, "%s: free iface %p",
1720 : __func__, hapd_iface);
1721 1 : os_free(hapd_iface);
1722 : }
1723 3 : return NULL;
1724 : }
1725 :
1726 :
1727 38 : static int ifname_in_use(struct hapd_interfaces *interfaces, const char *ifname)
1728 : {
1729 : size_t i, j;
1730 :
1731 77 : for (i = 0; i < interfaces->count; i++) {
1732 40 : struct hostapd_iface *iface = interfaces->iface[i];
1733 208 : for (j = 0; j < iface->num_bss; j++) {
1734 169 : struct hostapd_data *hapd = iface->bss[j];
1735 169 : if (os_strcmp(ifname, hapd->conf->iface) == 0)
1736 1 : return 1;
1737 : }
1738 : }
1739 :
1740 37 : return 0;
1741 : }
1742 :
1743 :
1744 : /**
1745 : * hostapd_interface_init_bss - Read configuration file and init BSS data
1746 : *
1747 : * This function is used to parse configuration file for a BSS. This BSS is
1748 : * added to an existing interface sharing the same radio (if any) or a new
1749 : * interface is created if this is the first interface on a radio. This
1750 : * allocate memory for the BSS. No actual driver operations are started.
1751 : *
1752 : * This is similar to hostapd_interface_init(), but for a case where the
1753 : * configuration is used to add a single BSS instead of all BSSes for a radio.
1754 : */
1755 : struct hostapd_iface *
1756 56 : hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy,
1757 : const char *config_fname, int debug)
1758 : {
1759 56 : struct hostapd_iface *new_iface = NULL, *iface = NULL;
1760 : struct hostapd_data *hapd;
1761 : int k;
1762 : size_t i, bss_idx;
1763 :
1764 56 : if (!phy || !*phy)
1765 0 : return NULL;
1766 :
1767 64 : for (i = 0; i < interfaces->count; i++) {
1768 47 : if (os_strcmp(interfaces->iface[i]->phy, phy) == 0) {
1769 39 : iface = interfaces->iface[i];
1770 39 : break;
1771 : }
1772 : }
1773 :
1774 56 : wpa_printf(MSG_INFO, "Configuration file: %s (phy %s)%s",
1775 : config_fname, phy, iface ? "" : " --> new PHY");
1776 56 : if (iface) {
1777 : struct hostapd_config *conf;
1778 : struct hostapd_bss_config **tmp_conf;
1779 : struct hostapd_data **tmp_bss;
1780 : struct hostapd_bss_config *bss;
1781 : const char *ifname;
1782 :
1783 : /* Add new BSS to existing iface */
1784 39 : conf = interfaces->config_read_cb(config_fname);
1785 39 : if (conf == NULL)
1786 1 : return NULL;
1787 38 : if (conf->num_bss > 1) {
1788 0 : wpa_printf(MSG_ERROR, "Multiple BSSes specified in BSS-config");
1789 0 : hostapd_config_free(conf);
1790 0 : return NULL;
1791 : }
1792 :
1793 38 : ifname = conf->bss[0]->iface;
1794 38 : if (ifname[0] != '\0' && ifname_in_use(interfaces, ifname)) {
1795 1 : wpa_printf(MSG_ERROR,
1796 : "Interface name %s already in use", ifname);
1797 1 : hostapd_config_free(conf);
1798 1 : return NULL;
1799 : }
1800 :
1801 74 : tmp_conf = os_realloc_array(
1802 74 : iface->conf->bss, iface->conf->num_bss + 1,
1803 : sizeof(struct hostapd_bss_config *));
1804 37 : tmp_bss = os_realloc_array(iface->bss, iface->num_bss + 1,
1805 : sizeof(struct hostapd_data *));
1806 37 : if (tmp_bss)
1807 37 : iface->bss = tmp_bss;
1808 37 : if (tmp_conf) {
1809 37 : iface->conf->bss = tmp_conf;
1810 37 : iface->conf->last_bss = tmp_conf[0];
1811 : }
1812 37 : if (tmp_bss == NULL || tmp_conf == NULL) {
1813 0 : hostapd_config_free(conf);
1814 0 : return NULL;
1815 : }
1816 37 : bss = iface->conf->bss[iface->conf->num_bss] = conf->bss[0];
1817 37 : iface->conf->num_bss++;
1818 :
1819 37 : hapd = hostapd_alloc_bss_data(iface, iface->conf, bss);
1820 37 : if (hapd == NULL) {
1821 0 : iface->conf->num_bss--;
1822 0 : hostapd_config_free(conf);
1823 0 : return NULL;
1824 : }
1825 37 : iface->conf->last_bss = bss;
1826 37 : iface->bss[iface->num_bss] = hapd;
1827 37 : hapd->msg_ctx = hapd;
1828 :
1829 37 : bss_idx = iface->num_bss++;
1830 37 : conf->num_bss--;
1831 37 : conf->bss[0] = NULL;
1832 37 : hostapd_config_free(conf);
1833 : } else {
1834 : /* Add a new iface with the first BSS */
1835 17 : new_iface = iface = hostapd_init(interfaces, config_fname);
1836 17 : if (!iface)
1837 3 : return NULL;
1838 14 : os_strlcpy(iface->phy, phy, sizeof(iface->phy));
1839 14 : iface->interfaces = interfaces;
1840 14 : bss_idx = 0;
1841 : }
1842 :
1843 51 : for (k = 0; k < debug; k++) {
1844 0 : if (iface->bss[bss_idx]->conf->logger_stdout_level > 0)
1845 0 : iface->bss[bss_idx]->conf->logger_stdout_level--;
1846 : }
1847 :
1848 51 : if (iface->conf->bss[bss_idx]->iface[0] == '\0' &&
1849 0 : !hostapd_drv_none(iface->bss[bss_idx])) {
1850 0 : wpa_printf(MSG_ERROR, "Interface name not specified in %s",
1851 : config_fname);
1852 0 : if (new_iface)
1853 0 : hostapd_interface_deinit_free(new_iface);
1854 0 : return NULL;
1855 : }
1856 :
1857 51 : return iface;
1858 : }
1859 :
1860 :
1861 1081 : void hostapd_interface_deinit_free(struct hostapd_iface *iface)
1862 : {
1863 : const struct wpa_driver_ops *driver;
1864 : void *drv_priv;
1865 :
1866 1081 : wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
1867 1081 : if (iface == NULL)
1868 1081 : return;
1869 2162 : wpa_printf(MSG_DEBUG, "%s: num_bss=%u conf->num_bss=%u",
1870 1081 : __func__, (unsigned int) iface->num_bss,
1871 1081 : (unsigned int) iface->conf->num_bss);
1872 1081 : driver = iface->bss[0]->driver;
1873 1081 : drv_priv = iface->bss[0]->drv_priv;
1874 1081 : hostapd_interface_deinit(iface);
1875 1081 : wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
1876 : __func__, driver, drv_priv);
1877 1081 : if (driver && driver->hapd_deinit && drv_priv) {
1878 928 : driver->hapd_deinit(drv_priv);
1879 928 : iface->bss[0]->drv_priv = NULL;
1880 : }
1881 1081 : hostapd_interface_free(iface);
1882 : }
1883 :
1884 :
1885 83 : static void hostapd_deinit_driver(const struct wpa_driver_ops *driver,
1886 : void *drv_priv,
1887 : struct hostapd_iface *hapd_iface)
1888 : {
1889 : size_t j;
1890 :
1891 83 : wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
1892 : __func__, driver, drv_priv);
1893 83 : if (driver && driver->hapd_deinit && drv_priv) {
1894 83 : driver->hapd_deinit(drv_priv);
1895 168 : for (j = 0; j < hapd_iface->num_bss; j++) {
1896 85 : wpa_printf(MSG_DEBUG, "%s:bss[%d]->drv_priv=%p",
1897 : __func__, (int) j,
1898 85 : hapd_iface->bss[j]->drv_priv);
1899 85 : if (hapd_iface->bss[j]->drv_priv == drv_priv)
1900 83 : hapd_iface->bss[j]->drv_priv = NULL;
1901 : }
1902 : }
1903 83 : }
1904 :
1905 :
1906 1012 : int hostapd_enable_iface(struct hostapd_iface *hapd_iface)
1907 : {
1908 : size_t j;
1909 :
1910 1012 : if (hapd_iface->bss[0]->drv_priv != NULL) {
1911 0 : wpa_printf(MSG_ERROR, "Interface %s already enabled",
1912 0 : hapd_iface->conf->bss[0]->iface);
1913 0 : return -1;
1914 : }
1915 :
1916 1012 : wpa_printf(MSG_DEBUG, "Enable interface %s",
1917 1012 : hapd_iface->conf->bss[0]->iface);
1918 :
1919 2031 : for (j = 0; j < hapd_iface->num_bss; j++)
1920 1019 : hostapd_set_security_params(hapd_iface->conf->bss[j], 1);
1921 1012 : if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
1922 8 : wpa_printf(MSG_INFO, "Invalid configuration - cannot enable");
1923 8 : return -1;
1924 : }
1925 :
1926 2008 : if (hapd_iface->interfaces == NULL ||
1927 2008 : hapd_iface->interfaces->driver_init == NULL ||
1928 1004 : hapd_iface->interfaces->driver_init(hapd_iface))
1929 17 : return -1;
1930 :
1931 987 : if (hostapd_setup_interface(hapd_iface)) {
1932 11 : hostapd_deinit_driver(hapd_iface->bss[0]->driver,
1933 11 : hapd_iface->bss[0]->drv_priv,
1934 : hapd_iface);
1935 11 : return -1;
1936 : }
1937 :
1938 976 : return 0;
1939 : }
1940 :
1941 :
1942 2 : int hostapd_reload_iface(struct hostapd_iface *hapd_iface)
1943 : {
1944 : size_t j;
1945 :
1946 2 : wpa_printf(MSG_DEBUG, "Reload interface %s",
1947 2 : hapd_iface->conf->bss[0]->iface);
1948 4 : for (j = 0; j < hapd_iface->num_bss; j++)
1949 2 : hostapd_set_security_params(hapd_iface->conf->bss[j], 1);
1950 2 : if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
1951 0 : wpa_printf(MSG_ERROR, "Updated configuration is invalid");
1952 0 : return -1;
1953 : }
1954 2 : hostapd_clear_old(hapd_iface);
1955 4 : for (j = 0; j < hapd_iface->num_bss; j++)
1956 2 : hostapd_reload_bss(hapd_iface->bss[j]);
1957 :
1958 2 : return 0;
1959 : }
1960 :
1961 :
1962 77 : int hostapd_disable_iface(struct hostapd_iface *hapd_iface)
1963 : {
1964 : size_t j;
1965 : const struct wpa_driver_ops *driver;
1966 : void *drv_priv;
1967 :
1968 77 : if (hapd_iface == NULL)
1969 0 : return -1;
1970 :
1971 77 : if (hapd_iface->bss[0]->drv_priv == NULL) {
1972 6 : wpa_printf(MSG_INFO, "Interface %s already disabled",
1973 6 : hapd_iface->conf->bss[0]->iface);
1974 6 : return -1;
1975 : }
1976 :
1977 71 : wpa_msg(hapd_iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
1978 71 : driver = hapd_iface->bss[0]->driver;
1979 71 : drv_priv = hapd_iface->bss[0]->drv_priv;
1980 :
1981 71 : hapd_iface->driver_ap_teardown =
1982 71 : !!(hapd_iface->drv_flags &
1983 : WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
1984 :
1985 : /* same as hostapd_interface_deinit without deinitializing ctrl-iface */
1986 144 : for (j = 0; j < hapd_iface->num_bss; j++) {
1987 73 : struct hostapd_data *hapd = hapd_iface->bss[j];
1988 73 : hostapd_bss_deinit_no_free(hapd);
1989 73 : hostapd_free_hapd_data(hapd);
1990 : }
1991 :
1992 71 : hostapd_deinit_driver(driver, drv_priv, hapd_iface);
1993 :
1994 : /* From hostapd_cleanup_iface: These were initialized in
1995 : * hostapd_setup_interface and hostapd_setup_interface_complete
1996 : */
1997 71 : hostapd_cleanup_iface_partial(hapd_iface);
1998 :
1999 71 : wpa_printf(MSG_DEBUG, "Interface %s disabled",
2000 71 : hapd_iface->bss[0]->conf->iface);
2001 71 : hostapd_set_state(hapd_iface, HAPD_IFACE_DISABLED);
2002 71 : return 0;
2003 : }
2004 :
2005 :
2006 : static struct hostapd_iface *
2007 1099 : hostapd_iface_alloc(struct hapd_interfaces *interfaces)
2008 : {
2009 : struct hostapd_iface **iface, *hapd_iface;
2010 :
2011 1099 : iface = os_realloc_array(interfaces->iface, interfaces->count + 1,
2012 : sizeof(struct hostapd_iface *));
2013 1099 : if (iface == NULL)
2014 4 : return NULL;
2015 1095 : interfaces->iface = iface;
2016 2190 : hapd_iface = interfaces->iface[interfaces->count] =
2017 1095 : os_zalloc(sizeof(*hapd_iface));
2018 1095 : if (hapd_iface == NULL) {
2019 4 : wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for "
2020 : "the interface", __func__);
2021 4 : return NULL;
2022 : }
2023 1091 : interfaces->count++;
2024 1091 : hapd_iface->interfaces = interfaces;
2025 :
2026 1091 : return hapd_iface;
2027 : }
2028 :
2029 :
2030 : static struct hostapd_config *
2031 1088 : hostapd_config_alloc(struct hapd_interfaces *interfaces, const char *ifname,
2032 : const char *ctrl_iface)
2033 : {
2034 : struct hostapd_bss_config *bss;
2035 : struct hostapd_config *conf;
2036 :
2037 : /* Allocates memory for bss and conf */
2038 1088 : conf = hostapd_config_defaults();
2039 1088 : if (conf == NULL) {
2040 17 : wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for "
2041 : "configuration", __func__);
2042 17 : return NULL;
2043 : }
2044 :
2045 1071 : conf->driver = wpa_drivers[0];
2046 1071 : if (conf->driver == NULL) {
2047 0 : wpa_printf(MSG_ERROR, "No driver wrappers registered!");
2048 0 : hostapd_config_free(conf);
2049 0 : return NULL;
2050 : }
2051 :
2052 1071 : bss = conf->last_bss = conf->bss[0];
2053 :
2054 1071 : os_strlcpy(bss->iface, ifname, sizeof(bss->iface));
2055 1071 : bss->ctrl_interface = os_strdup(ctrl_iface);
2056 1071 : if (bss->ctrl_interface == NULL) {
2057 3 : hostapd_config_free(conf);
2058 3 : return NULL;
2059 : }
2060 :
2061 : /* Reading configuration file skipped, will be done in SET!
2062 : * From reading the configuration till the end has to be done in
2063 : * SET
2064 : */
2065 1068 : return conf;
2066 : }
2067 :
2068 :
2069 1071 : static int hostapd_data_alloc(struct hostapd_iface *hapd_iface,
2070 : struct hostapd_config *conf)
2071 : {
2072 : size_t i;
2073 : struct hostapd_data *hapd;
2074 :
2075 1071 : hapd_iface->bss = os_calloc(conf->num_bss,
2076 : sizeof(struct hostapd_data *));
2077 1071 : if (hapd_iface->bss == NULL)
2078 3 : return -1;
2079 :
2080 2138 : for (i = 0; i < conf->num_bss; i++) {
2081 2148 : hapd = hapd_iface->bss[i] =
2082 1074 : hostapd_alloc_bss_data(hapd_iface, conf, conf->bss[i]);
2083 1074 : if (hapd == NULL) {
2084 8 : while (i > 0) {
2085 0 : i--;
2086 0 : os_free(hapd_iface->bss[i]);
2087 0 : hapd_iface->bss[i] = NULL;
2088 : }
2089 4 : os_free(hapd_iface->bss);
2090 4 : hapd_iface->bss = NULL;
2091 4 : return -1;
2092 : }
2093 1070 : hapd->msg_ctx = hapd;
2094 : }
2095 :
2096 1064 : hapd_iface->conf = conf;
2097 1064 : hapd_iface->num_bss = conf->num_bss;
2098 :
2099 1064 : return 0;
2100 : }
2101 :
2102 :
2103 1155 : int hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf)
2104 : {
2105 1155 : struct hostapd_config *conf = NULL;
2106 1155 : struct hostapd_iface *hapd_iface = NULL, *new_iface = NULL;
2107 : struct hostapd_data *hapd;
2108 : char *ptr;
2109 : size_t i, j;
2110 1155 : const char *conf_file = NULL, *phy_name = NULL;
2111 :
2112 1155 : if (os_strncmp(buf, "bss_config=", 11) == 0) {
2113 : char *pos;
2114 56 : phy_name = buf + 11;
2115 56 : pos = os_strchr(phy_name, ':');
2116 56 : if (!pos)
2117 0 : return -1;
2118 56 : *pos++ = '\0';
2119 56 : conf_file = pos;
2120 56 : if (!os_strlen(conf_file))
2121 0 : return -1;
2122 :
2123 56 : hapd_iface = hostapd_interface_init_bss(interfaces, phy_name,
2124 : conf_file, 0);
2125 56 : if (!hapd_iface)
2126 5 : return -1;
2127 55 : for (j = 0; j < interfaces->count; j++) {
2128 41 : if (interfaces->iface[j] == hapd_iface)
2129 37 : break;
2130 : }
2131 51 : if (j == interfaces->count) {
2132 : struct hostapd_iface **tmp;
2133 14 : tmp = os_realloc_array(interfaces->iface,
2134 14 : interfaces->count + 1,
2135 : sizeof(struct hostapd_iface *));
2136 14 : if (!tmp) {
2137 0 : hostapd_interface_deinit_free(hapd_iface);
2138 0 : return -1;
2139 : }
2140 14 : interfaces->iface = tmp;
2141 14 : interfaces->iface[interfaces->count++] = hapd_iface;
2142 14 : new_iface = hapd_iface;
2143 : }
2144 :
2145 51 : if (new_iface) {
2146 14 : if (interfaces->driver_init(hapd_iface))
2147 0 : goto fail;
2148 :
2149 14 : if (hostapd_setup_interface(hapd_iface)) {
2150 2 : hostapd_deinit_driver(
2151 1 : hapd_iface->bss[0]->driver,
2152 1 : hapd_iface->bss[0]->drv_priv,
2153 : hapd_iface);
2154 1 : goto fail;
2155 : }
2156 : } else {
2157 : /* Assign new BSS with bss[0]'s driver info */
2158 37 : hapd = hapd_iface->bss[hapd_iface->num_bss - 1];
2159 37 : hapd->driver = hapd_iface->bss[0]->driver;
2160 37 : hapd->drv_priv = hapd_iface->bss[0]->drv_priv;
2161 37 : os_memcpy(hapd->own_addr, hapd_iface->bss[0]->own_addr,
2162 : ETH_ALEN);
2163 :
2164 74 : if (start_ctrl_iface_bss(hapd) < 0 ||
2165 71 : (hapd_iface->state == HAPD_IFACE_ENABLED &&
2166 34 : hostapd_setup_bss(hapd, -1))) {
2167 1 : hostapd_cleanup(hapd);
2168 1 : hapd_iface->bss[hapd_iface->num_bss - 1] = NULL;
2169 1 : hapd_iface->conf->num_bss--;
2170 1 : hapd_iface->num_bss--;
2171 1 : wpa_printf(MSG_DEBUG, "%s: free hapd %p %s",
2172 1 : __func__, hapd, hapd->conf->iface);
2173 1 : hostapd_config_free_bss(hapd->conf);
2174 1 : hapd->conf = NULL;
2175 1 : os_free(hapd);
2176 1 : return -1;
2177 : }
2178 : }
2179 49 : return 0;
2180 : }
2181 :
2182 1099 : ptr = os_strchr(buf, ' ');
2183 1099 : if (ptr == NULL)
2184 0 : return -1;
2185 1099 : *ptr++ = '\0';
2186 :
2187 1099 : if (os_strncmp(ptr, "config=", 7) == 0)
2188 3 : conf_file = ptr + 7;
2189 :
2190 1382 : for (i = 0; i < interfaces->count; i++) {
2191 283 : if (!os_strcmp(interfaces->iface[i]->conf->bss[0]->iface,
2192 : buf)) {
2193 0 : wpa_printf(MSG_INFO, "Cannot add interface - it "
2194 : "already exists");
2195 0 : return -1;
2196 : }
2197 : }
2198 :
2199 1099 : hapd_iface = hostapd_iface_alloc(interfaces);
2200 1099 : if (hapd_iface == NULL) {
2201 8 : wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
2202 : "for interface", __func__);
2203 8 : goto fail;
2204 : }
2205 1091 : new_iface = hapd_iface;
2206 :
2207 1091 : if (conf_file && interfaces->config_read_cb) {
2208 3 : conf = interfaces->config_read_cb(conf_file);
2209 6 : if (conf && conf->bss)
2210 3 : os_strlcpy(conf->bss[0]->iface, buf,
2211 : sizeof(conf->bss[0]->iface));
2212 : } else
2213 1088 : conf = hostapd_config_alloc(interfaces, buf, ptr);
2214 1091 : if (conf == NULL || conf->bss == NULL) {
2215 20 : wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
2216 : "for configuration", __func__);
2217 20 : goto fail;
2218 : }
2219 :
2220 1071 : if (hostapd_data_alloc(hapd_iface, conf) < 0) {
2221 7 : wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
2222 : "for hostapd", __func__);
2223 7 : goto fail;
2224 : }
2225 1064 : conf = NULL;
2226 :
2227 1064 : if (start_ctrl_iface(hapd_iface) < 0)
2228 6 : goto fail;
2229 :
2230 1058 : wpa_printf(MSG_INFO, "Add interface '%s'",
2231 1058 : hapd_iface->conf->bss[0]->iface);
2232 :
2233 1058 : return 0;
2234 :
2235 : fail:
2236 42 : if (conf)
2237 7 : hostapd_config_free(conf);
2238 42 : if (hapd_iface) {
2239 34 : if (hapd_iface->bss) {
2240 14 : for (i = 0; i < hapd_iface->num_bss; i++) {
2241 7 : hapd = hapd_iface->bss[i];
2242 7 : if (!hapd)
2243 0 : continue;
2244 14 : if (hapd_iface->interfaces &&
2245 7 : hapd_iface->interfaces->ctrl_iface_deinit)
2246 7 : hapd_iface->interfaces->
2247 7 : ctrl_iface_deinit(hapd);
2248 7 : wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)",
2249 7 : __func__, hapd_iface->bss[i],
2250 7 : hapd->conf->iface);
2251 7 : hostapd_cleanup(hapd);
2252 7 : os_free(hapd);
2253 7 : hapd_iface->bss[i] = NULL;
2254 : }
2255 7 : os_free(hapd_iface->bss);
2256 7 : hapd_iface->bss = NULL;
2257 : }
2258 34 : if (new_iface) {
2259 34 : interfaces->count--;
2260 34 : interfaces->iface[interfaces->count] = NULL;
2261 : }
2262 34 : hostapd_cleanup_iface(hapd_iface);
2263 : }
2264 42 : return -1;
2265 : }
2266 :
2267 :
2268 39 : static int hostapd_remove_bss(struct hostapd_iface *iface, unsigned int idx)
2269 : {
2270 : size_t i;
2271 :
2272 39 : wpa_printf(MSG_INFO, "Remove BSS '%s'", iface->conf->bss[idx]->iface);
2273 :
2274 : /* Remove hostapd_data only if it has already been initialized */
2275 39 : if (idx < iface->num_bss) {
2276 37 : struct hostapd_data *hapd = iface->bss[idx];
2277 :
2278 37 : hostapd_bss_deinit(hapd);
2279 37 : wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)",
2280 37 : __func__, hapd, hapd->conf->iface);
2281 37 : hostapd_config_free_bss(hapd->conf);
2282 37 : hapd->conf = NULL;
2283 37 : os_free(hapd);
2284 :
2285 37 : iface->num_bss--;
2286 :
2287 160 : for (i = idx; i < iface->num_bss; i++)
2288 123 : iface->bss[i] = iface->bss[i + 1];
2289 : } else {
2290 2 : hostapd_config_free_bss(iface->conf->bss[idx]);
2291 2 : iface->conf->bss[idx] = NULL;
2292 : }
2293 :
2294 39 : iface->conf->num_bss--;
2295 162 : for (i = idx; i < iface->conf->num_bss; i++)
2296 123 : iface->conf->bss[i] = iface->conf->bss[i + 1];
2297 :
2298 39 : return 0;
2299 : }
2300 :
2301 :
2302 5705 : int hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf)
2303 : {
2304 : struct hostapd_iface *hapd_iface;
2305 5705 : size_t i, j, k = 0;
2306 :
2307 7785 : for (i = 0; i < interfaces->count; i++) {
2308 3190 : hapd_iface = interfaces->iface[i];
2309 3190 : if (hapd_iface == NULL)
2310 0 : return -1;
2311 3190 : if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
2312 1071 : wpa_printf(MSG_INFO, "Remove interface '%s'", buf);
2313 1071 : hapd_iface->driver_ap_teardown =
2314 1071 : !!(hapd_iface->drv_flags &
2315 : WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
2316 :
2317 1071 : hostapd_interface_deinit_free(hapd_iface);
2318 1071 : k = i;
2319 2235 : while (k < (interfaces->count - 1)) {
2320 186 : interfaces->iface[k] =
2321 93 : interfaces->iface[k + 1];
2322 93 : k++;
2323 : }
2324 1071 : interfaces->count--;
2325 1071 : return 0;
2326 : }
2327 :
2328 4248 : for (j = 0; j < hapd_iface->conf->num_bss; j++) {
2329 2168 : if (!os_strcmp(hapd_iface->conf->bss[j]->iface, buf)) {
2330 39 : hapd_iface->driver_ap_teardown =
2331 39 : !(hapd_iface->drv_flags &
2332 : WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
2333 39 : return hostapd_remove_bss(hapd_iface, j);
2334 : }
2335 : }
2336 : }
2337 4595 : return -1;
2338 : }
2339 :
2340 :
2341 : /**
2342 : * hostapd_new_assoc_sta - Notify that a new station associated with the AP
2343 : * @hapd: Pointer to BSS data
2344 : * @sta: Pointer to the associated STA data
2345 : * @reassoc: 1 to indicate this was a re-association; 0 = first association
2346 : *
2347 : * This function will be called whenever a station associates with the AP. It
2348 : * can be called from ieee802_11.c for drivers that export MLME to hostapd and
2349 : * from drv_callbacks.c based on driver events for drivers that take care of
2350 : * management frames (IEEE 802.11 authentication and association) internally.
2351 : */
2352 2554 : void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
2353 : int reassoc)
2354 : {
2355 2554 : if (hapd->tkip_countermeasures) {
2356 0 : hostapd_drv_sta_deauth(hapd, sta->addr,
2357 : WLAN_REASON_MICHAEL_MIC_FAILURE);
2358 2554 : return;
2359 : }
2360 :
2361 2554 : hostapd_prune_associations(hapd, sta->addr);
2362 :
2363 : /* IEEE 802.11F (IAPP) */
2364 2554 : if (hapd->conf->ieee802_11f)
2365 0 : iapp_new_station(hapd->iapp, sta);
2366 :
2367 : #ifdef CONFIG_P2P
2368 406 : if (sta->p2p_ie == NULL && !sta->no_p2p_set) {
2369 30 : sta->no_p2p_set = 1;
2370 30 : hapd->num_sta_no_p2p++;
2371 30 : if (hapd->num_sta_no_p2p == 1)
2372 26 : hostapd_p2p_non_p2p_sta_connected(hapd);
2373 : }
2374 : #endif /* CONFIG_P2P */
2375 :
2376 : /* Start accounting here, if IEEE 802.1X and WPA are not used.
2377 : * IEEE 802.1X/WPA code will start accounting after the station has
2378 : * been authorized. */
2379 2554 : if (!hapd->conf->ieee802_1x && !hapd->conf->wpa && !hapd->conf->osen) {
2380 349 : ap_sta_set_authorized(hapd, sta, 1);
2381 349 : os_get_reltime(&sta->connected_time);
2382 349 : accounting_sta_start(hapd, sta);
2383 : }
2384 :
2385 : /* Start IEEE 802.1X authentication process for new stations */
2386 2554 : ieee802_1x_new_station(hapd, sta);
2387 2554 : if (reassoc) {
2388 16 : if (sta->auth_alg != WLAN_AUTH_FT &&
2389 8 : !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)))
2390 8 : wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH);
2391 : } else
2392 2546 : wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);
2393 :
2394 2554 : if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) {
2395 17878 : wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout "
2396 : "for " MACSTR " (%d seconds - ap_max_inactivity)",
2397 15324 : __func__, MAC2STR(sta->addr),
2398 2554 : hapd->conf->ap_max_inactivity);
2399 2554 : eloop_cancel_timeout(ap_handle_timer, hapd, sta);
2400 2554 : eloop_register_timeout(hapd->conf->ap_max_inactivity, 0,
2401 : ap_handle_timer, hapd, sta);
2402 : }
2403 : }
2404 :
2405 :
2406 6314 : const char * hostapd_state_text(enum hostapd_iface_state s)
2407 : {
2408 6314 : switch (s) {
2409 : case HAPD_IFACE_UNINITIALIZED:
2410 1427 : return "UNINITIALIZED";
2411 : case HAPD_IFACE_DISABLED:
2412 1595 : return "DISABLED";
2413 : case HAPD_IFACE_COUNTRY_UPDATE:
2414 92 : return "COUNTRY_UPDATE";
2415 : case HAPD_IFACE_ACS:
2416 27 : return "ACS";
2417 : case HAPD_IFACE_HT_SCAN:
2418 101 : return "HT_SCAN";
2419 : case HAPD_IFACE_DFS:
2420 36 : return "DFS";
2421 : case HAPD_IFACE_ENABLED:
2422 3036 : return "ENABLED";
2423 : }
2424 :
2425 0 : return "UNKNOWN";
2426 : }
2427 :
2428 :
2429 2964 : void hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s)
2430 : {
2431 5928 : wpa_printf(MSG_INFO, "%s: interface state %s->%s",
2432 2964 : iface->conf->bss[0]->iface, hostapd_state_text(iface->state),
2433 : hostapd_state_text(s));
2434 2964 : iface->state = s;
2435 2964 : }
2436 :
2437 :
2438 : #ifdef NEED_AP_MLME
2439 :
2440 46 : static void free_beacon_data(struct beacon_data *beacon)
2441 : {
2442 46 : os_free(beacon->head);
2443 46 : beacon->head = NULL;
2444 46 : os_free(beacon->tail);
2445 46 : beacon->tail = NULL;
2446 46 : os_free(beacon->probe_resp);
2447 46 : beacon->probe_resp = NULL;
2448 46 : os_free(beacon->beacon_ies);
2449 46 : beacon->beacon_ies = NULL;
2450 46 : os_free(beacon->proberesp_ies);
2451 46 : beacon->proberesp_ies = NULL;
2452 46 : os_free(beacon->assocresp_ies);
2453 46 : beacon->assocresp_ies = NULL;
2454 46 : }
2455 :
2456 :
2457 46 : static int hostapd_build_beacon_data(struct hostapd_data *hapd,
2458 : struct beacon_data *beacon)
2459 : {
2460 : struct wpabuf *beacon_extra, *proberesp_extra, *assocresp_extra;
2461 : struct wpa_driver_ap_params params;
2462 : int ret;
2463 :
2464 46 : os_memset(beacon, 0, sizeof(*beacon));
2465 46 : ret = ieee802_11_build_ap_params(hapd, ¶ms);
2466 46 : if (ret < 0)
2467 0 : return ret;
2468 :
2469 46 : ret = hostapd_build_ap_extra_ies(hapd, &beacon_extra,
2470 : &proberesp_extra,
2471 : &assocresp_extra);
2472 46 : if (ret)
2473 0 : goto free_ap_params;
2474 :
2475 46 : ret = -1;
2476 46 : beacon->head = os_malloc(params.head_len);
2477 46 : if (!beacon->head)
2478 0 : goto free_ap_extra_ies;
2479 :
2480 46 : os_memcpy(beacon->head, params.head, params.head_len);
2481 46 : beacon->head_len = params.head_len;
2482 :
2483 46 : beacon->tail = os_malloc(params.tail_len);
2484 46 : if (!beacon->tail)
2485 0 : goto free_beacon;
2486 :
2487 46 : os_memcpy(beacon->tail, params.tail, params.tail_len);
2488 46 : beacon->tail_len = params.tail_len;
2489 :
2490 46 : if (params.proberesp != NULL) {
2491 0 : beacon->probe_resp = os_malloc(params.proberesp_len);
2492 0 : if (!beacon->probe_resp)
2493 0 : goto free_beacon;
2494 :
2495 0 : os_memcpy(beacon->probe_resp, params.proberesp,
2496 : params.proberesp_len);
2497 0 : beacon->probe_resp_len = params.proberesp_len;
2498 : }
2499 :
2500 : /* copy the extra ies */
2501 46 : if (beacon_extra) {
2502 46 : beacon->beacon_ies = os_malloc(wpabuf_len(beacon_extra));
2503 46 : if (!beacon->beacon_ies)
2504 0 : goto free_beacon;
2505 :
2506 46 : os_memcpy(beacon->beacon_ies,
2507 : beacon_extra->buf, wpabuf_len(beacon_extra));
2508 46 : beacon->beacon_ies_len = wpabuf_len(beacon_extra);
2509 : }
2510 :
2511 46 : if (proberesp_extra) {
2512 46 : beacon->proberesp_ies =
2513 46 : os_malloc(wpabuf_len(proberesp_extra));
2514 46 : if (!beacon->proberesp_ies)
2515 0 : goto free_beacon;
2516 :
2517 46 : os_memcpy(beacon->proberesp_ies, proberesp_extra->buf,
2518 : wpabuf_len(proberesp_extra));
2519 46 : beacon->proberesp_ies_len = wpabuf_len(proberesp_extra);
2520 : }
2521 :
2522 46 : if (assocresp_extra) {
2523 46 : beacon->assocresp_ies =
2524 46 : os_malloc(wpabuf_len(assocresp_extra));
2525 46 : if (!beacon->assocresp_ies)
2526 0 : goto free_beacon;
2527 :
2528 46 : os_memcpy(beacon->assocresp_ies, assocresp_extra->buf,
2529 : wpabuf_len(assocresp_extra));
2530 46 : beacon->assocresp_ies_len = wpabuf_len(assocresp_extra);
2531 : }
2532 :
2533 46 : ret = 0;
2534 : free_beacon:
2535 : /* if the function fails, the caller should not free beacon data */
2536 46 : if (ret)
2537 0 : free_beacon_data(beacon);
2538 :
2539 : free_ap_extra_ies:
2540 46 : hostapd_free_ap_extra_ies(hapd, beacon_extra, proberesp_extra,
2541 : assocresp_extra);
2542 : free_ap_params:
2543 46 : ieee802_11_free_ap_params(¶ms);
2544 46 : return ret;
2545 : }
2546 :
2547 :
2548 : /*
2549 : * TODO: This flow currently supports only changing frequency within the
2550 : * same hw_mode. Any other changes to MAC parameters or provided settings (even
2551 : * width) are not supported.
2552 : */
2553 46 : static int hostapd_change_config_freq(struct hostapd_data *hapd,
2554 : struct hostapd_config *conf,
2555 : struct hostapd_freq_params *params,
2556 : struct hostapd_freq_params *old_params)
2557 : {
2558 : int channel;
2559 :
2560 46 : if (!params->channel) {
2561 : /* check if the new channel is supported by hw */
2562 21 : params->channel = hostapd_hw_get_channel(hapd, params->freq);
2563 : }
2564 :
2565 46 : channel = params->channel;
2566 46 : if (!channel)
2567 0 : return -1;
2568 :
2569 : /* if a pointer to old_params is provided we save previous state */
2570 46 : if (old_params) {
2571 23 : old_params->channel = conf->channel;
2572 23 : old_params->ht_enabled = conf->ieee80211n;
2573 23 : old_params->sec_channel_offset = conf->secondary_channel;
2574 : }
2575 :
2576 46 : conf->channel = channel;
2577 46 : conf->ieee80211n = params->ht_enabled;
2578 46 : conf->secondary_channel = params->sec_channel_offset;
2579 :
2580 : /* TODO: maybe call here hostapd_config_check here? */
2581 :
2582 46 : return 0;
2583 : }
2584 :
2585 :
2586 23 : static int hostapd_fill_csa_settings(struct hostapd_data *hapd,
2587 : struct csa_settings *settings)
2588 : {
2589 23 : struct hostapd_iface *iface = hapd->iface;
2590 : struct hostapd_freq_params old_freq;
2591 : int ret;
2592 :
2593 23 : os_memset(&old_freq, 0, sizeof(old_freq));
2594 23 : if (!iface || !iface->freq || hapd->csa_in_progress)
2595 0 : return -1;
2596 :
2597 23 : ret = hostapd_change_config_freq(iface->bss[0], iface->conf,
2598 : &settings->freq_params,
2599 : &old_freq);
2600 23 : if (ret)
2601 0 : return ret;
2602 :
2603 23 : ret = hostapd_build_beacon_data(hapd, &settings->beacon_after);
2604 :
2605 : /* change back the configuration */
2606 23 : hostapd_change_config_freq(iface->bss[0], iface->conf,
2607 : &old_freq, NULL);
2608 :
2609 23 : if (ret)
2610 0 : return ret;
2611 :
2612 : /* set channel switch parameters for csa ie */
2613 23 : hapd->cs_freq_params = settings->freq_params;
2614 23 : hapd->cs_count = settings->cs_count;
2615 23 : hapd->cs_block_tx = settings->block_tx;
2616 :
2617 23 : ret = hostapd_build_beacon_data(hapd, &settings->beacon_csa);
2618 23 : if (ret) {
2619 0 : free_beacon_data(&settings->beacon_after);
2620 0 : return ret;
2621 : }
2622 :
2623 23 : settings->counter_offset_beacon = hapd->cs_c_off_beacon;
2624 23 : settings->counter_offset_presp = hapd->cs_c_off_proberesp;
2625 :
2626 23 : return 0;
2627 : }
2628 :
2629 :
2630 23 : void hostapd_cleanup_cs_params(struct hostapd_data *hapd)
2631 : {
2632 23 : os_memset(&hapd->cs_freq_params, 0, sizeof(hapd->cs_freq_params));
2633 23 : hapd->cs_count = 0;
2634 23 : hapd->cs_block_tx = 0;
2635 23 : hapd->cs_c_off_beacon = 0;
2636 23 : hapd->cs_c_off_proberesp = 0;
2637 23 : hapd->csa_in_progress = 0;
2638 23 : }
2639 :
2640 :
2641 23 : int hostapd_switch_channel(struct hostapd_data *hapd,
2642 : struct csa_settings *settings)
2643 : {
2644 : int ret;
2645 :
2646 23 : if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA)) {
2647 0 : wpa_printf(MSG_INFO, "CSA is not supported");
2648 0 : return -1;
2649 : }
2650 :
2651 23 : ret = hostapd_fill_csa_settings(hapd, settings);
2652 23 : if (ret)
2653 0 : return ret;
2654 :
2655 23 : ret = hostapd_drv_switch_channel(hapd, settings);
2656 23 : free_beacon_data(&settings->beacon_csa);
2657 23 : free_beacon_data(&settings->beacon_after);
2658 :
2659 23 : if (ret) {
2660 : /* if we failed, clean cs parameters */
2661 2 : hostapd_cleanup_cs_params(hapd);
2662 2 : return ret;
2663 : }
2664 :
2665 21 : hapd->csa_in_progress = 1;
2666 21 : return 0;
2667 : }
2668 :
2669 :
2670 : void
2671 0 : hostapd_switch_channel_fallback(struct hostapd_iface *iface,
2672 : const struct hostapd_freq_params *freq_params)
2673 : {
2674 0 : int vht_seg0_idx = 0, vht_seg1_idx = 0, vht_bw = VHT_CHANWIDTH_USE_HT;
2675 : unsigned int i;
2676 :
2677 0 : wpa_printf(MSG_DEBUG, "Restarting all CSA-related BSSes");
2678 :
2679 0 : if (freq_params->center_freq1)
2680 0 : vht_seg0_idx = 36 + (freq_params->center_freq1 - 5180) / 5;
2681 0 : if (freq_params->center_freq2)
2682 0 : vht_seg1_idx = 36 + (freq_params->center_freq2 - 5180) / 5;
2683 :
2684 0 : switch (freq_params->bandwidth) {
2685 : case 0:
2686 : case 20:
2687 : case 40:
2688 0 : vht_bw = VHT_CHANWIDTH_USE_HT;
2689 0 : break;
2690 : case 80:
2691 0 : if (freq_params->center_freq2)
2692 0 : vht_bw = VHT_CHANWIDTH_80P80MHZ;
2693 : else
2694 0 : vht_bw = VHT_CHANWIDTH_80MHZ;
2695 0 : break;
2696 : case 160:
2697 0 : vht_bw = VHT_CHANWIDTH_160MHZ;
2698 0 : break;
2699 : default:
2700 0 : wpa_printf(MSG_WARNING, "Unknown CSA bandwidth: %d",
2701 : freq_params->bandwidth);
2702 0 : break;
2703 : }
2704 :
2705 0 : iface->freq = freq_params->freq;
2706 0 : iface->conf->channel = freq_params->channel;
2707 0 : iface->conf->secondary_channel = freq_params->sec_channel_offset;
2708 0 : iface->conf->vht_oper_centr_freq_seg0_idx = vht_seg0_idx;
2709 0 : iface->conf->vht_oper_centr_freq_seg1_idx = vht_seg1_idx;
2710 0 : iface->conf->vht_oper_chwidth = vht_bw;
2711 0 : iface->conf->ieee80211n = freq_params->ht_enabled;
2712 0 : iface->conf->ieee80211ac = freq_params->vht_enabled;
2713 :
2714 : /*
2715 : * cs_params must not be cleared earlier because the freq_params
2716 : * argument may actually point to one of these.
2717 : */
2718 0 : for (i = 0; i < iface->num_bss; i++)
2719 0 : hostapd_cleanup_cs_params(iface->bss[i]);
2720 :
2721 0 : hostapd_disable_iface(iface);
2722 0 : hostapd_enable_iface(iface);
2723 0 : }
2724 :
2725 : #endif /* NEED_AP_MLME */
|