blob: 3bca385ae7ba642fbe995a461f6145964b35fd7e [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * hostapd / Initialization and configuration
Dmitry Shmidt04949592012-07-19 12:16:46 -07003 * Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004 *
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07007 */
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 "radius/radius_client.h"
Dmitry Shmidt04949592012-07-19 12:16:46 -070015#include "radius/radius_das.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070016#include "drivers/driver.h"
17#include "hostapd.h"
18#include "authsrv.h"
19#include "sta_info.h"
20#include "accounting.h"
21#include "ap_list.h"
22#include "beacon.h"
23#include "iapp.h"
24#include "ieee802_1x.h"
25#include "ieee802_11_auth.h"
26#include "vlan_init.h"
27#include "wpa_auth.h"
28#include "wps_hostapd.h"
29#include "hw_features.h"
30#include "wpa_auth_glue.h"
31#include "ap_drv_ops.h"
32#include "ap_config.h"
33#include "p2p_hostapd.h"
Dmitry Shmidt04949592012-07-19 12:16:46 -070034#include "gas_serv.h"
Dmitry Shmidt051af732013-10-22 13:52:46 -070035#include "dfs.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070036
37
Dmitry Shmidt04949592012-07-19 12:16:46 -070038static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070039static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd);
Dmitry Shmidtc55524a2011-07-07 11:18:38 -070040static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070041
42extern int wpa_debug_level;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -070043extern struct wpa_driver_ops *wpa_drivers[];
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070044
45
Dmitry Shmidt04949592012-07-19 12:16:46 -070046int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
47 int (*cb)(struct hostapd_iface *iface,
48 void *ctx), void *ctx)
49{
50 size_t i;
51 int ret;
52
53 for (i = 0; i < interfaces->count; i++) {
54 ret = cb(interfaces->iface[i], ctx);
55 if (ret)
56 return ret;
57 }
58
59 return 0;
60}
61
62
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070063static void hostapd_reload_bss(struct hostapd_data *hapd)
64{
65#ifndef CONFIG_NO_RADIUS
66 radius_client_reconfig(hapd->radius, hapd->conf->radius);
67#endif /* CONFIG_NO_RADIUS */
68
69 if (hostapd_setup_wpa_psk(hapd->conf)) {
70 wpa_printf(MSG_ERROR, "Failed to re-configure WPA PSK "
71 "after reloading configuration");
72 }
73
74 if (hapd->conf->ieee802_1x || hapd->conf->wpa)
75 hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 1);
76 else
77 hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 0);
78
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080079 if (hapd->conf->wpa && hapd->wpa_auth == NULL) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070080 hostapd_setup_wpa(hapd);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080081 if (hapd->wpa_auth)
82 wpa_init_keys(hapd->wpa_auth);
83 } else if (hapd->conf->wpa) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070084 const u8 *wpa_ie;
85 size_t wpa_ie_len;
86 hostapd_reconfig_wpa(hapd);
87 wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len);
88 if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len))
89 wpa_printf(MSG_ERROR, "Failed to configure WPA IE for "
90 "the kernel driver.");
91 } else if (hapd->wpa_auth) {
92 wpa_deinit(hapd->wpa_auth);
93 hapd->wpa_auth = NULL;
94 hostapd_set_privacy(hapd, 0);
95 hostapd_setup_encryption(hapd->conf->iface, hapd);
96 hostapd_set_generic_elem(hapd, (u8 *) "", 0);
97 }
98
99 ieee802_11_set_beacon(hapd);
100 hostapd_update_wps(hapd);
101
102 if (hapd->conf->ssid.ssid_set &&
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700103 hostapd_set_ssid(hapd, hapd->conf->ssid.ssid,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700104 hapd->conf->ssid.ssid_len)) {
105 wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
106 /* try to continue */
107 }
108 wpa_printf(MSG_DEBUG, "Reconfigured interface %s", hapd->conf->iface);
109}
110
111
Dmitry Shmidt444d5672013-04-01 13:08:44 -0700112static void hostapd_clear_old(struct hostapd_iface *iface)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700113{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700114 size_t j;
115
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700116 /*
117 * Deauthenticate all stations since the new configuration may not
118 * allow them to use the BSS anymore.
119 */
120 for (j = 0; j < iface->num_bss; j++) {
Dmitry Shmidt04949592012-07-19 12:16:46 -0700121 hostapd_flush_old_stations(iface->bss[j],
122 WLAN_REASON_PREV_AUTH_NOT_VALID);
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700123 hostapd_broadcast_wep_clear(iface->bss[j]);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700124
125#ifndef CONFIG_NO_RADIUS
126 /* TODO: update dynamic data based on changed configuration
127 * items (e.g., open/close sockets, etc.) */
128 radius_client_flush(iface->bss[j]->radius, 0);
129#endif /* CONFIG_NO_RADIUS */
130 }
Dmitry Shmidt444d5672013-04-01 13:08:44 -0700131}
132
133
134int hostapd_reload_config(struct hostapd_iface *iface)
135{
136 struct hostapd_data *hapd = iface->bss[0];
137 struct hostapd_config *newconf, *oldconf;
138 size_t j;
139
140 if (iface->config_fname == NULL) {
141 /* Only in-memory config in use - assume it has been updated */
142 hostapd_clear_old(iface);
143 for (j = 0; j < iface->num_bss; j++)
144 hostapd_reload_bss(iface->bss[j]);
145 return 0;
146 }
147
148 if (iface->interfaces == NULL ||
149 iface->interfaces->config_read_cb == NULL)
150 return -1;
151 newconf = iface->interfaces->config_read_cb(iface->config_fname);
152 if (newconf == NULL)
153 return -1;
154
155 hostapd_clear_old(iface);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700156
157 oldconf = hapd->iconf;
158 iface->conf = newconf;
159
160 for (j = 0; j < iface->num_bss; j++) {
161 hapd = iface->bss[j];
162 hapd->iconf = newconf;
163 hapd->conf = &newconf->bss[j];
164 hostapd_reload_bss(hapd);
165 }
166
167 hostapd_config_free(oldconf);
168
169
170 return 0;
171}
172
173
174static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd,
175 char *ifname)
176{
177 int i;
178
179 for (i = 0; i < NUM_WEP_KEYS; i++) {
180 if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, NULL, i,
181 0, NULL, 0, NULL, 0)) {
182 wpa_printf(MSG_DEBUG, "Failed to clear default "
183 "encryption keys (ifname=%s keyidx=%d)",
184 ifname, i);
185 }
186 }
187#ifdef CONFIG_IEEE80211W
188 if (hapd->conf->ieee80211w) {
189 for (i = NUM_WEP_KEYS; i < NUM_WEP_KEYS + 2; i++) {
190 if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE,
191 NULL, i, 0, NULL,
192 0, NULL, 0)) {
193 wpa_printf(MSG_DEBUG, "Failed to clear "
194 "default mgmt encryption keys "
195 "(ifname=%s keyidx=%d)", ifname, i);
196 }
197 }
198 }
199#endif /* CONFIG_IEEE80211W */
200}
201
202
203static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd)
204{
205 hostapd_broadcast_key_clear_iface(hapd, hapd->conf->iface);
206 return 0;
207}
208
209
210static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
211{
212 int errors = 0, idx;
213 struct hostapd_ssid *ssid = &hapd->conf->ssid;
214
215 idx = ssid->wep.idx;
216 if (ssid->wep.default_len &&
217 hostapd_drv_set_key(hapd->conf->iface,
218 hapd, WPA_ALG_WEP, broadcast_ether_addr, idx,
219 1, NULL, 0, ssid->wep.key[idx],
220 ssid->wep.len[idx])) {
221 wpa_printf(MSG_WARNING, "Could not set WEP encryption.");
222 errors++;
223 }
224
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700225 return errors;
226}
227
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700228
Dmitry Shmidt04949592012-07-19 12:16:46 -0700229static void hostapd_free_hapd_data(struct hostapd_data *hapd)
230{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700231 iapp_deinit(hapd->iapp);
232 hapd->iapp = NULL;
233 accounting_deinit(hapd);
234 hostapd_deinit_wpa(hapd);
235 vlan_deinit(hapd);
236 hostapd_acl_deinit(hapd);
237#ifndef CONFIG_NO_RADIUS
238 radius_client_deinit(hapd->radius);
239 hapd->radius = NULL;
Dmitry Shmidt04949592012-07-19 12:16:46 -0700240 radius_das_deinit(hapd->radius_das);
241 hapd->radius_das = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700242#endif /* CONFIG_NO_RADIUS */
243
244 hostapd_deinit_wps(hapd);
245
246 authsrv_deinit(hapd);
247
248 if (hapd->interface_added &&
249 hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) {
250 wpa_printf(MSG_WARNING, "Failed to remove BSS interface %s",
251 hapd->conf->iface);
252 }
253
254 os_free(hapd->probereq_cb);
255 hapd->probereq_cb = NULL;
256
257#ifdef CONFIG_P2P
258 wpabuf_free(hapd->p2p_beacon_ie);
259 hapd->p2p_beacon_ie = NULL;
260 wpabuf_free(hapd->p2p_probe_resp_ie);
261 hapd->p2p_probe_resp_ie = NULL;
262#endif /* CONFIG_P2P */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800263
264 wpabuf_free(hapd->time_adv);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700265
266#ifdef CONFIG_INTERWORKING
267 gas_serv_deinit(hapd);
268#endif /* CONFIG_INTERWORKING */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800269
270#ifdef CONFIG_SQLITE
271 os_free(hapd->tmp_eap_user.identity);
272 os_free(hapd->tmp_eap_user.password);
273#endif /* CONFIG_SQLITE */
Dmitry Shmidt04949592012-07-19 12:16:46 -0700274}
275
276
277/**
278 * hostapd_cleanup - Per-BSS cleanup (deinitialization)
279 * @hapd: Pointer to BSS data
280 *
281 * This function is used to free all per-BSS data structures and resources.
282 * This gets called in a loop for each BSS between calls to
283 * hostapd_cleanup_iface_pre() and hostapd_cleanup_iface() when an interface
284 * is deinitialized. Most of the modules that are initialized in
285 * hostapd_setup_bss() are deinitialized here.
286 */
287static void hostapd_cleanup(struct hostapd_data *hapd)
288{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700289 if (hapd->iface->interfaces &&
290 hapd->iface->interfaces->ctrl_iface_deinit)
291 hapd->iface->interfaces->ctrl_iface_deinit(hapd);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700292 hostapd_free_hapd_data(hapd);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700293}
294
295
296/**
297 * hostapd_cleanup_iface_pre - Preliminary per-interface cleanup
298 * @iface: Pointer to interface data
299 *
300 * This function is called before per-BSS data structures are deinitialized
301 * with hostapd_cleanup().
302 */
303static void hostapd_cleanup_iface_pre(struct hostapd_iface *iface)
304{
305}
306
307
Dmitry Shmidt04949592012-07-19 12:16:46 -0700308static void hostapd_cleanup_iface_partial(struct hostapd_iface *iface)
309{
310 hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
311 iface->hw_features = NULL;
312 os_free(iface->current_rates);
313 iface->current_rates = NULL;
314 os_free(iface->basic_rates);
315 iface->basic_rates = NULL;
316 ap_list_deinit(iface);
317}
318
319
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700320/**
321 * hostapd_cleanup_iface - Complete per-interface cleanup
322 * @iface: Pointer to interface data
323 *
324 * This function is called after per-BSS data structures are deinitialized
325 * with hostapd_cleanup().
326 */
327static void hostapd_cleanup_iface(struct hostapd_iface *iface)
328{
Dmitry Shmidt04949592012-07-19 12:16:46 -0700329 hostapd_cleanup_iface_partial(iface);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700330 hostapd_config_free(iface->conf);
331 iface->conf = NULL;
332
333 os_free(iface->config_fname);
334 os_free(iface->bss);
335 os_free(iface);
336}
337
338
Dmitry Shmidt04949592012-07-19 12:16:46 -0700339static void hostapd_clear_wep(struct hostapd_data *hapd)
340{
341 if (hapd->drv_priv) {
342 hostapd_set_privacy(hapd, 0);
343 hostapd_broadcast_wep_clear(hapd);
344 }
345}
346
347
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700348static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd)
349{
350 int i;
351
352 hostapd_broadcast_wep_set(hapd);
353
354 if (hapd->conf->ssid.wep.default_len) {
355 hostapd_set_privacy(hapd, 1);
356 return 0;
357 }
358
Jouni Malinen75ecf522011-06-27 15:19:46 -0700359 /*
360 * When IEEE 802.1X is not enabled, the driver may need to know how to
361 * set authentication algorithms for static WEP.
362 */
363 hostapd_drv_set_authmode(hapd, hapd->conf->auth_algs);
364
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700365 for (i = 0; i < 4; i++) {
366 if (hapd->conf->ssid.wep.key[i] &&
367 hostapd_drv_set_key(iface, hapd, WPA_ALG_WEP, NULL, i,
368 i == hapd->conf->ssid.wep.idx, NULL, 0,
369 hapd->conf->ssid.wep.key[i],
370 hapd->conf->ssid.wep.len[i])) {
371 wpa_printf(MSG_WARNING, "Could not set WEP "
372 "encryption.");
373 return -1;
374 }
375 if (hapd->conf->ssid.wep.key[i] &&
376 i == hapd->conf->ssid.wep.idx)
377 hostapd_set_privacy(hapd, 1);
378 }
379
380 return 0;
381}
382
383
Dmitry Shmidt04949592012-07-19 12:16:46 -0700384static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700385{
386 int ret = 0;
387 u8 addr[ETH_ALEN];
388
389 if (hostapd_drv_none(hapd) || hapd->drv_priv == NULL)
390 return 0;
391
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800392 wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "Flushing old station entries");
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700393 if (hostapd_flush(hapd)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800394 wpa_msg(hapd->msg_ctx, MSG_WARNING, "Could not connect to "
395 "kernel driver");
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700396 ret = -1;
397 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800398 wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "Deauthenticate all stations");
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700399 os_memset(addr, 0xff, ETH_ALEN);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700400 hostapd_drv_sta_deauth(hapd, addr, reason);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700401 hostapd_free_stas(hapd);
402
403 return ret;
404}
405
406
407/**
408 * hostapd_validate_bssid_configuration - Validate BSSID configuration
409 * @iface: Pointer to interface data
410 * Returns: 0 on success, -1 on failure
411 *
412 * This function is used to validate that the configured BSSIDs are valid.
413 */
414static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface)
415{
416 u8 mask[ETH_ALEN] = { 0 };
417 struct hostapd_data *hapd = iface->bss[0];
418 unsigned int i = iface->conf->num_bss, bits = 0, j;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700419 int auto_addr = 0;
420
421 if (hostapd_drv_none(hapd))
422 return 0;
423
424 /* Generate BSSID mask that is large enough to cover the BSSIDs. */
425
426 /* Determine the bits necessary to cover the number of BSSIDs. */
427 for (i--; i; i >>= 1)
428 bits++;
429
430 /* Determine the bits necessary to any configured BSSIDs,
431 if they are higher than the number of BSSIDs. */
432 for (j = 0; j < iface->conf->num_bss; j++) {
433 if (hostapd_mac_comp_empty(iface->conf->bss[j].bssid) == 0) {
434 if (j)
435 auto_addr++;
436 continue;
437 }
438
439 for (i = 0; i < ETH_ALEN; i++) {
440 mask[i] |=
441 iface->conf->bss[j].bssid[i] ^
442 hapd->own_addr[i];
443 }
444 }
445
446 if (!auto_addr)
447 goto skip_mask_ext;
448
449 for (i = 0; i < ETH_ALEN && mask[i] == 0; i++)
450 ;
451 j = 0;
452 if (i < ETH_ALEN) {
453 j = (5 - i) * 8;
454
455 while (mask[i] != 0) {
456 mask[i] >>= 1;
457 j++;
458 }
459 }
460
461 if (bits < j)
462 bits = j;
463
464 if (bits > 40) {
465 wpa_printf(MSG_ERROR, "Too many bits in the BSSID mask (%u)",
466 bits);
467 return -1;
468 }
469
470 os_memset(mask, 0xff, ETH_ALEN);
471 j = bits / 8;
472 for (i = 5; i > 5 - j; i--)
473 mask[i] = 0;
474 j = bits % 8;
475 while (j--)
476 mask[i] <<= 1;
477
478skip_mask_ext:
479 wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR " (%d bits)",
480 (unsigned long) iface->conf->num_bss, MAC2STR(mask), bits);
481
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700482 if (!auto_addr)
483 return 0;
484
485 for (i = 0; i < ETH_ALEN; i++) {
486 if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) {
487 wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR
488 " for start address " MACSTR ".",
489 MAC2STR(mask), MAC2STR(hapd->own_addr));
490 wpa_printf(MSG_ERROR, "Start address must be the "
491 "first address in the block (i.e., addr "
492 "AND mask == addr).");
493 return -1;
494 }
495 }
496
497 return 0;
498}
499
500
501static int mac_in_conf(struct hostapd_config *conf, const void *a)
502{
503 size_t i;
504
505 for (i = 0; i < conf->num_bss; i++) {
506 if (hostapd_mac_comp(conf->bss[i].bssid, a) == 0) {
507 return 1;
508 }
509 }
510
511 return 0;
512}
513
514
Dmitry Shmidt04949592012-07-19 12:16:46 -0700515#ifndef CONFIG_NO_RADIUS
516
517static int hostapd_das_nas_mismatch(struct hostapd_data *hapd,
518 struct radius_das_attrs *attr)
519{
520 /* TODO */
521 return 0;
522}
523
524
525static struct sta_info * hostapd_das_find_sta(struct hostapd_data *hapd,
526 struct radius_das_attrs *attr)
527{
528 struct sta_info *sta = NULL;
529 char buf[128];
530
531 if (attr->sta_addr)
532 sta = ap_get_sta(hapd, attr->sta_addr);
533
534 if (sta == NULL && attr->acct_session_id &&
535 attr->acct_session_id_len == 17) {
536 for (sta = hapd->sta_list; sta; sta = sta->next) {
537 os_snprintf(buf, sizeof(buf), "%08X-%08X",
538 sta->acct_session_id_hi,
539 sta->acct_session_id_lo);
540 if (os_memcmp(attr->acct_session_id, buf, 17) == 0)
541 break;
542 }
543 }
544
545 if (sta == NULL && attr->cui) {
546 for (sta = hapd->sta_list; sta; sta = sta->next) {
547 struct wpabuf *cui;
548 cui = ieee802_1x_get_radius_cui(sta->eapol_sm);
549 if (cui && wpabuf_len(cui) == attr->cui_len &&
550 os_memcmp(wpabuf_head(cui), attr->cui,
551 attr->cui_len) == 0)
552 break;
553 }
554 }
555
556 if (sta == NULL && attr->user_name) {
557 for (sta = hapd->sta_list; sta; sta = sta->next) {
558 u8 *identity;
559 size_t identity_len;
560 identity = ieee802_1x_get_identity(sta->eapol_sm,
561 &identity_len);
562 if (identity &&
563 identity_len == attr->user_name_len &&
564 os_memcmp(identity, attr->user_name, identity_len)
565 == 0)
566 break;
567 }
568 }
569
570 return sta;
571}
572
573
574static enum radius_das_res
575hostapd_das_disconnect(void *ctx, struct radius_das_attrs *attr)
576{
577 struct hostapd_data *hapd = ctx;
578 struct sta_info *sta;
579
580 if (hostapd_das_nas_mismatch(hapd, attr))
581 return RADIUS_DAS_NAS_MISMATCH;
582
583 sta = hostapd_das_find_sta(hapd, attr);
584 if (sta == NULL)
585 return RADIUS_DAS_SESSION_NOT_FOUND;
586
587 hostapd_drv_sta_deauth(hapd, sta->addr,
588 WLAN_REASON_PREV_AUTH_NOT_VALID);
589 ap_sta_deauthenticate(hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID);
590
591 return RADIUS_DAS_SUCCESS;
592}
593
594#endif /* CONFIG_NO_RADIUS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700595
596
597/**
598 * hostapd_setup_bss - Per-BSS setup (initialization)
599 * @hapd: Pointer to BSS data
600 * @first: Whether this BSS is the first BSS of an interface
601 *
602 * This function is used to initialize all per-BSS data structures and
603 * resources. This gets called in a loop for each BSS when an interface is
604 * initialized. Most of the modules that are initialized here will be
605 * deinitialized in hostapd_cleanup().
606 */
607static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
608{
609 struct hostapd_bss_config *conf = hapd->conf;
610 u8 ssid[HOSTAPD_MAX_SSID_LEN + 1];
611 int ssid_len, set_ssid;
612 char force_ifname[IFNAMSIZ];
613 u8 if_addr[ETH_ALEN];
614
615 if (!first) {
616 if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0) {
617 /* Allocate the next available BSSID. */
618 do {
619 inc_byte_array(hapd->own_addr, ETH_ALEN);
620 } while (mac_in_conf(hapd->iconf, hapd->own_addr));
621 } else {
622 /* Allocate the configured BSSID. */
623 os_memcpy(hapd->own_addr, hapd->conf->bssid, ETH_ALEN);
624
625 if (hostapd_mac_comp(hapd->own_addr,
626 hapd->iface->bss[0]->own_addr) ==
627 0) {
628 wpa_printf(MSG_ERROR, "BSS '%s' may not have "
629 "BSSID set to the MAC address of "
630 "the radio", hapd->conf->iface);
631 return -1;
632 }
633 }
634
635 hapd->interface_added = 1;
636 if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS,
637 hapd->conf->iface, hapd->own_addr, hapd,
638 &hapd->drv_priv, force_ifname, if_addr,
639 hapd->conf->bridge[0] ? hapd->conf->bridge :
640 NULL)) {
641 wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID="
642 MACSTR ")", MAC2STR(hapd->own_addr));
643 return -1;
644 }
645 }
646
647 if (conf->wmm_enabled < 0)
648 conf->wmm_enabled = hapd->iconf->ieee80211n;
649
Dmitry Shmidt04949592012-07-19 12:16:46 -0700650 hostapd_flush_old_stations(hapd, WLAN_REASON_PREV_AUTH_NOT_VALID);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700651 hostapd_set_privacy(hapd, 0);
652
653 hostapd_broadcast_wep_clear(hapd);
654 if (hostapd_setup_encryption(hapd->conf->iface, hapd))
655 return -1;
656
657 /*
658 * Fetch the SSID from the system and use it or,
659 * if one was specified in the config file, verify they
660 * match.
661 */
662 ssid_len = hostapd_get_ssid(hapd, ssid, sizeof(ssid));
663 if (ssid_len < 0) {
664 wpa_printf(MSG_ERROR, "Could not read SSID from system");
665 return -1;
666 }
667 if (conf->ssid.ssid_set) {
668 /*
669 * If SSID is specified in the config file and it differs
670 * from what is being used then force installation of the
671 * new SSID.
672 */
673 set_ssid = (conf->ssid.ssid_len != (size_t) ssid_len ||
674 os_memcmp(conf->ssid.ssid, ssid, ssid_len) != 0);
675 } else {
676 /*
677 * No SSID in the config file; just use the one we got
678 * from the system.
679 */
680 set_ssid = 0;
681 conf->ssid.ssid_len = ssid_len;
682 os_memcpy(conf->ssid.ssid, ssid, conf->ssid.ssid_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700683 }
684
685 if (!hostapd_drv_none(hapd)) {
686 wpa_printf(MSG_ERROR, "Using interface %s with hwaddr " MACSTR
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700687 " and ssid \"%s\"",
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700688 hapd->conf->iface, MAC2STR(hapd->own_addr),
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700689 wpa_ssid_txt(hapd->conf->ssid.ssid,
690 hapd->conf->ssid.ssid_len));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700691 }
692
693 if (hostapd_setup_wpa_psk(conf)) {
694 wpa_printf(MSG_ERROR, "WPA-PSK setup failed.");
695 return -1;
696 }
697
698 /* Set SSID for the kernel driver (to be used in beacon and probe
699 * response frames) */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700700 if (set_ssid && hostapd_set_ssid(hapd, conf->ssid.ssid,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700701 conf->ssid.ssid_len)) {
702 wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
703 return -1;
704 }
705
706 if (wpa_debug_level == MSG_MSGDUMP)
707 conf->radius->msg_dumps = 1;
708#ifndef CONFIG_NO_RADIUS
709 hapd->radius = radius_client_init(hapd, conf->radius);
710 if (hapd->radius == NULL) {
711 wpa_printf(MSG_ERROR, "RADIUS client initialization failed.");
712 return -1;
713 }
Dmitry Shmidt04949592012-07-19 12:16:46 -0700714
715 if (hapd->conf->radius_das_port) {
716 struct radius_das_conf das_conf;
717 os_memset(&das_conf, 0, sizeof(das_conf));
718 das_conf.port = hapd->conf->radius_das_port;
719 das_conf.shared_secret = hapd->conf->radius_das_shared_secret;
720 das_conf.shared_secret_len =
721 hapd->conf->radius_das_shared_secret_len;
722 das_conf.client_addr = &hapd->conf->radius_das_client_addr;
723 das_conf.time_window = hapd->conf->radius_das_time_window;
724 das_conf.require_event_timestamp =
725 hapd->conf->radius_das_require_event_timestamp;
726 das_conf.ctx = hapd;
727 das_conf.disconnect = hostapd_das_disconnect;
728 hapd->radius_das = radius_das_init(&das_conf);
729 if (hapd->radius_das == NULL) {
730 wpa_printf(MSG_ERROR, "RADIUS DAS initialization "
731 "failed.");
732 return -1;
733 }
734 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700735#endif /* CONFIG_NO_RADIUS */
736
737 if (hostapd_acl_init(hapd)) {
738 wpa_printf(MSG_ERROR, "ACL initialization failed.");
739 return -1;
740 }
741 if (hostapd_init_wps(hapd, conf))
742 return -1;
743
744 if (authsrv_init(hapd) < 0)
745 return -1;
746
747 if (ieee802_1x_init(hapd)) {
748 wpa_printf(MSG_ERROR, "IEEE 802.1X initialization failed.");
749 return -1;
750 }
751
752 if (hapd->conf->wpa && hostapd_setup_wpa(hapd))
753 return -1;
754
755 if (accounting_init(hapd)) {
756 wpa_printf(MSG_ERROR, "Accounting initialization failed.");
757 return -1;
758 }
759
760 if (hapd->conf->ieee802_11f &&
761 (hapd->iapp = iapp_init(hapd, hapd->conf->iapp_iface)) == NULL) {
762 wpa_printf(MSG_ERROR, "IEEE 802.11F (IAPP) initialization "
763 "failed.");
764 return -1;
765 }
766
Dmitry Shmidt04949592012-07-19 12:16:46 -0700767#ifdef CONFIG_INTERWORKING
768 if (gas_serv_init(hapd)) {
769 wpa_printf(MSG_ERROR, "GAS server initialization failed");
770 return -1;
771 }
772#endif /* CONFIG_INTERWORKING */
773
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700774 if (hapd->iface->interfaces &&
775 hapd->iface->interfaces->ctrl_iface_init &&
776 hapd->iface->interfaces->ctrl_iface_init(hapd)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700777 wpa_printf(MSG_ERROR, "Failed to setup control interface");
778 return -1;
779 }
780
781 if (!hostapd_drv_none(hapd) && vlan_init(hapd)) {
782 wpa_printf(MSG_ERROR, "VLAN initialization failed.");
783 return -1;
784 }
785
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -0700786 if (!hapd->conf->start_disabled)
787 ieee802_11_set_beacon(hapd);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700788
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800789 if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0)
790 return -1;
791
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700792 if (hapd->driver && hapd->driver->set_operstate)
793 hapd->driver->set_operstate(hapd->drv_priv, 1);
794
795 return 0;
796}
797
798
799static void hostapd_tx_queue_params(struct hostapd_iface *iface)
800{
801 struct hostapd_data *hapd = iface->bss[0];
802 int i;
803 struct hostapd_tx_queue_params *p;
804
805 for (i = 0; i < NUM_TX_QUEUES; i++) {
806 p = &iface->conf->tx_queue[i];
807
808 if (hostapd_set_tx_queue_params(hapd, i, p->aifs, p->cwmin,
809 p->cwmax, p->burst)) {
810 wpa_printf(MSG_DEBUG, "Failed to set TX queue "
811 "parameters for queue %d.", i);
812 /* Continue anyway */
813 }
814 }
815}
816
817
Dmitry Shmidt8bae4132013-06-06 11:25:10 -0700818static int hostapd_set_acl_list(struct hostapd_data *hapd,
819 struct mac_acl_entry *mac_acl,
820 int n_entries, u8 accept_acl)
821{
822 struct hostapd_acl_params *acl_params;
823 int i, err;
824
825 acl_params = os_zalloc(sizeof(*acl_params) +
826 (n_entries * sizeof(acl_params->mac_acl[0])));
827 if (!acl_params)
828 return -ENOMEM;
829
830 for (i = 0; i < n_entries; i++)
831 os_memcpy(acl_params->mac_acl[i].addr, mac_acl[i].addr,
832 ETH_ALEN);
833
834 acl_params->acl_policy = accept_acl;
835 acl_params->num_mac_acl = n_entries;
836
837 err = hostapd_drv_set_acl(hapd, acl_params);
838
839 os_free(acl_params);
840
841 return err;
842}
843
844
845static void hostapd_set_acl(struct hostapd_data *hapd)
846{
847 struct hostapd_config *conf = hapd->iconf;
848 int err;
849 u8 accept_acl;
850
851 if (hapd->iface->drv_max_acl_mac_addrs == 0)
852 return;
853 if (!(conf->bss->num_accept_mac || conf->bss->num_deny_mac))
854 return;
855
856 if (conf->bss->macaddr_acl == DENY_UNLESS_ACCEPTED) {
857 if (conf->bss->num_accept_mac) {
858 accept_acl = 1;
859 err = hostapd_set_acl_list(hapd, conf->bss->accept_mac,
860 conf->bss->num_accept_mac,
861 accept_acl);
862 if (err) {
863 wpa_printf(MSG_DEBUG, "Failed to set accept acl");
864 return;
865 }
866 } else {
867 wpa_printf(MSG_DEBUG, "Mismatch between ACL Policy & Accept/deny lists file");
868 }
869 } else if (conf->bss->macaddr_acl == ACCEPT_UNLESS_DENIED) {
870 if (conf->bss->num_deny_mac) {
871 accept_acl = 0;
872 err = hostapd_set_acl_list(hapd, conf->bss->deny_mac,
873 conf->bss->num_deny_mac,
874 accept_acl);
875 if (err) {
876 wpa_printf(MSG_DEBUG, "Failed to set deny acl");
877 return;
878 }
879 } else {
880 wpa_printf(MSG_DEBUG, "Mismatch between ACL Policy & Accept/deny lists file");
881 }
882 }
883}
884
885
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700886static int setup_interface(struct hostapd_iface *iface)
887{
888 struct hostapd_data *hapd = iface->bss[0];
889 size_t i;
890 char country[4];
891
892 /*
893 * Make sure that all BSSes get configured with a pointer to the same
894 * driver interface.
895 */
896 for (i = 1; i < iface->num_bss; i++) {
897 iface->bss[i]->driver = hapd->driver;
898 iface->bss[i]->drv_priv = hapd->drv_priv;
899 }
900
901 if (hostapd_validate_bssid_configuration(iface))
902 return -1;
903
904 if (hapd->iconf->country[0] && hapd->iconf->country[1]) {
905 os_memcpy(country, hapd->iconf->country, 3);
906 country[3] = '\0';
907 if (hostapd_set_country(hapd, country) < 0) {
908 wpa_printf(MSG_ERROR, "Failed to set country code");
909 return -1;
910 }
911 }
912
913 if (hostapd_get_hw_features(iface)) {
914 /* Not all drivers support this yet, so continue without hw
915 * feature data. */
916 } else {
917 int ret = hostapd_select_hw_mode(iface);
918 if (ret < 0) {
919 wpa_printf(MSG_ERROR, "Could not select hw_mode and "
920 "channel. (%d)", ret);
921 return -1;
922 }
Dmitry Shmidt391c59f2013-09-03 12:16:28 -0700923 if (ret == 1) {
924 wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback (ACS)");
925 return 0;
926 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700927 ret = hostapd_check_ht_capab(iface);
928 if (ret < 0)
929 return -1;
930 if (ret == 1) {
931 wpa_printf(MSG_DEBUG, "Interface initialization will "
932 "be completed in a callback");
933 return 0;
934 }
Dmitry Shmidt051af732013-10-22 13:52:46 -0700935
936 if (iface->conf->ieee80211h)
937 wpa_printf(MSG_DEBUG, "DFS support is enabled");
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700938 }
939 return hostapd_setup_interface_complete(iface, 0);
940}
941
942
943int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
944{
945 struct hostapd_data *hapd = iface->bss[0];
946 size_t j;
947 u8 *prev_addr;
948
949 if (err) {
950 wpa_printf(MSG_ERROR, "Interface initialization failed");
951 eloop_terminate();
952 return -1;
953 }
954
955 wpa_printf(MSG_DEBUG, "Completing interface initialization");
956 if (hapd->iconf->channel) {
Dmitry Shmidt051af732013-10-22 13:52:46 -0700957#ifdef NEED_AP_MLME
958 int res;
959#endif /* NEED_AP_MLME */
960
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700961 iface->freq = hostapd_hw_get_freq(hapd, hapd->iconf->channel);
962 wpa_printf(MSG_DEBUG, "Mode: %s Channel: %d "
963 "Frequency: %d MHz",
964 hostapd_hw_mode_txt(hapd->iconf->hw_mode),
965 hapd->iconf->channel, iface->freq);
966
Dmitry Shmidt051af732013-10-22 13:52:46 -0700967#ifdef NEED_AP_MLME
968 /* Check DFS */
969 res = hostapd_handle_dfs(hapd);
970 if (res <= 0)
971 return res;
972#endif /* NEED_AP_MLME */
973
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700974 if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq,
975 hapd->iconf->channel,
976 hapd->iconf->ieee80211n,
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -0800977 hapd->iconf->ieee80211ac,
978 hapd->iconf->secondary_channel,
979 hapd->iconf->vht_oper_chwidth,
980 hapd->iconf->vht_oper_centr_freq_seg0_idx,
981 hapd->iconf->vht_oper_centr_freq_seg1_idx)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700982 wpa_printf(MSG_ERROR, "Could not set channel for "
983 "kernel driver");
984 return -1;
985 }
986 }
987
988 if (iface->current_mode) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800989 if (hostapd_prepare_rates(iface, iface->current_mode)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700990 wpa_printf(MSG_ERROR, "Failed to prepare rates "
991 "table.");
992 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
993 HOSTAPD_LEVEL_WARNING,
994 "Failed to prepare rates table.");
995 return -1;
996 }
997 }
998
999 if (hapd->iconf->rts_threshold > -1 &&
1000 hostapd_set_rts(hapd, hapd->iconf->rts_threshold)) {
1001 wpa_printf(MSG_ERROR, "Could not set RTS threshold for "
1002 "kernel driver");
1003 return -1;
1004 }
1005
1006 if (hapd->iconf->fragm_threshold > -1 &&
1007 hostapd_set_frag(hapd, hapd->iconf->fragm_threshold)) {
1008 wpa_printf(MSG_ERROR, "Could not set fragmentation threshold "
1009 "for kernel driver");
1010 return -1;
1011 }
1012
1013 prev_addr = hapd->own_addr;
1014
1015 for (j = 0; j < iface->num_bss; j++) {
1016 hapd = iface->bss[j];
1017 if (j)
1018 os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN);
1019 if (hostapd_setup_bss(hapd, j == 0))
1020 return -1;
1021 if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0)
1022 prev_addr = hapd->own_addr;
1023 }
1024
1025 hostapd_tx_queue_params(iface);
1026
1027 ap_list_init(iface);
1028
Dmitry Shmidt8bae4132013-06-06 11:25:10 -07001029 hostapd_set_acl(hapd);
1030
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001031 if (hostapd_driver_commit(hapd) < 0) {
1032 wpa_printf(MSG_ERROR, "%s: Failed to commit driver "
1033 "configuration", __func__);
1034 return -1;
1035 }
1036
Jouni Malinen87fd2792011-05-16 18:35:42 +03001037 /*
1038 * WPS UPnP module can be initialized only when the "upnp_iface" is up.
1039 * If "interface" and "upnp_iface" are the same (e.g., non-bridge
1040 * mode), the interface is up only after driver_commit, so initialize
1041 * WPS after driver_commit.
1042 */
1043 for (j = 0; j < iface->num_bss; j++) {
1044 if (hostapd_init_wps_complete(iface->bss[j]))
1045 return -1;
1046 }
1047
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001048 if (hapd->setup_complete_cb)
1049 hapd->setup_complete_cb(hapd->setup_complete_cb_ctx);
1050
1051 wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
1052 iface->bss[0]->conf->iface);
1053
1054 return 0;
1055}
1056
1057
1058/**
1059 * hostapd_setup_interface - Setup of an interface
1060 * @iface: Pointer to interface data.
1061 * Returns: 0 on success, -1 on failure
1062 *
1063 * Initializes the driver interface, validates the configuration,
1064 * and sets driver parameters based on the configuration.
1065 * Flushes old stations, sets the channel, encryption,
1066 * beacons, and WDS links based on the configuration.
1067 */
1068int hostapd_setup_interface(struct hostapd_iface *iface)
1069{
1070 int ret;
1071
1072 ret = setup_interface(iface);
1073 if (ret) {
1074 wpa_printf(MSG_ERROR, "%s: Unable to setup interface.",
1075 iface->bss[0]->conf->iface);
1076 return -1;
1077 }
1078
1079 return 0;
1080}
1081
1082
1083/**
1084 * hostapd_alloc_bss_data - Allocate and initialize per-BSS data
1085 * @hapd_iface: Pointer to interface data
1086 * @conf: Pointer to per-interface configuration
1087 * @bss: Pointer to per-BSS configuration for this BSS
1088 * Returns: Pointer to allocated BSS data
1089 *
1090 * This function is used to allocate per-BSS data structure. This data will be
1091 * freed after hostapd_cleanup() is called for it during interface
1092 * deinitialization.
1093 */
1094struct hostapd_data *
1095hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
1096 struct hostapd_config *conf,
1097 struct hostapd_bss_config *bss)
1098{
1099 struct hostapd_data *hapd;
1100
1101 hapd = os_zalloc(sizeof(*hapd));
1102 if (hapd == NULL)
1103 return NULL;
1104
1105 hapd->new_assoc_sta_cb = hostapd_new_assoc_sta;
1106 hapd->iconf = conf;
1107 hapd->conf = bss;
1108 hapd->iface = hapd_iface;
1109 hapd->driver = hapd->iconf->driver;
Dmitry Shmidt04949592012-07-19 12:16:46 -07001110 hapd->ctrl_sock = -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001111
1112 return hapd;
1113}
1114
1115
1116void hostapd_interface_deinit(struct hostapd_iface *iface)
1117{
1118 size_t j;
1119
1120 if (iface == NULL)
1121 return;
1122
1123 hostapd_cleanup_iface_pre(iface);
1124 for (j = 0; j < iface->num_bss; j++) {
1125 struct hostapd_data *hapd = iface->bss[j];
1126 hostapd_free_stas(hapd);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001127 hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
1128 hostapd_clear_wep(hapd);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001129 hostapd_cleanup(hapd);
1130 }
1131}
1132
1133
1134void hostapd_interface_free(struct hostapd_iface *iface)
1135{
1136 size_t j;
1137 for (j = 0; j < iface->num_bss; j++)
1138 os_free(iface->bss[j]);
1139 hostapd_cleanup_iface(iface);
1140}
1141
1142
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001143#ifdef HOSTAPD
1144
1145void hostapd_interface_deinit_free(struct hostapd_iface *iface)
1146{
1147 const struct wpa_driver_ops *driver;
1148 void *drv_priv;
1149 if (iface == NULL)
1150 return;
1151 driver = iface->bss[0]->driver;
1152 drv_priv = iface->bss[0]->drv_priv;
1153 hostapd_interface_deinit(iface);
1154 if (driver && driver->hapd_deinit && drv_priv)
1155 driver->hapd_deinit(drv_priv);
1156 hostapd_interface_free(iface);
1157}
1158
1159
1160int hostapd_enable_iface(struct hostapd_iface *hapd_iface)
1161{
1162 if (hapd_iface->bss[0]->drv_priv != NULL) {
1163 wpa_printf(MSG_ERROR, "Interface %s already enabled",
1164 hapd_iface->conf->bss[0].iface);
1165 return -1;
1166 }
1167
1168 wpa_printf(MSG_DEBUG, "Enable interface %s",
1169 hapd_iface->conf->bss[0].iface);
1170
1171 if (hapd_iface->interfaces == NULL ||
1172 hapd_iface->interfaces->driver_init == NULL ||
1173 hapd_iface->interfaces->driver_init(hapd_iface) ||
1174 hostapd_setup_interface(hapd_iface)) {
1175 hostapd_interface_deinit_free(hapd_iface);
1176 return -1;
1177 }
1178 return 0;
1179}
1180
1181
1182int hostapd_reload_iface(struct hostapd_iface *hapd_iface)
1183{
1184 size_t j;
1185
1186 wpa_printf(MSG_DEBUG, "Reload interface %s",
1187 hapd_iface->conf->bss[0].iface);
1188 for (j = 0; j < hapd_iface->num_bss; j++) {
1189 hostapd_flush_old_stations(hapd_iface->bss[j],
1190 WLAN_REASON_PREV_AUTH_NOT_VALID);
1191
1192#ifndef CONFIG_NO_RADIUS
1193 /* TODO: update dynamic data based on changed configuration
1194 * items (e.g., open/close sockets, etc.) */
1195 radius_client_flush(hapd_iface->bss[j]->radius, 0);
1196#endif /* CONFIG_NO_RADIUS */
1197
1198 hostapd_reload_bss(hapd_iface->bss[j]);
1199 }
1200 return 0;
1201}
1202
1203
1204int hostapd_disable_iface(struct hostapd_iface *hapd_iface)
1205{
1206 size_t j;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001207 const struct wpa_driver_ops *driver;
1208 void *drv_priv;
1209
1210 if (hapd_iface == NULL)
1211 return -1;
1212 driver = hapd_iface->bss[0]->driver;
1213 drv_priv = hapd_iface->bss[0]->drv_priv;
1214
1215 /* whatever hostapd_interface_deinit does */
1216 for (j = 0; j < hapd_iface->num_bss; j++) {
1217 struct hostapd_data *hapd = hapd_iface->bss[j];
1218 hostapd_free_stas(hapd);
1219 hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
1220 hostapd_clear_wep(hapd);
1221 hostapd_free_hapd_data(hapd);
1222 }
1223
1224 if (driver && driver->hapd_deinit && drv_priv) {
1225 driver->hapd_deinit(drv_priv);
1226 hapd_iface->bss[0]->drv_priv = NULL;
1227 }
1228
1229 /* From hostapd_cleanup_iface: These were initialized in
1230 * hostapd_setup_interface and hostapd_setup_interface_complete
1231 */
1232 hostapd_cleanup_iface_partial(hapd_iface);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001233
Dmitry Shmidt56052862013-10-04 10:23:25 -07001234 wpa_printf(MSG_DEBUG, "Interface %s disabled",
1235 hapd_iface->bss[0]->conf->iface);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001236 return 0;
1237}
1238
1239
1240static struct hostapd_iface *
1241hostapd_iface_alloc(struct hapd_interfaces *interfaces)
1242{
1243 struct hostapd_iface **iface, *hapd_iface;
1244
1245 iface = os_realloc_array(interfaces->iface, interfaces->count + 1,
1246 sizeof(struct hostapd_iface *));
1247 if (iface == NULL)
1248 return NULL;
1249 interfaces->iface = iface;
1250 hapd_iface = interfaces->iface[interfaces->count] =
1251 os_zalloc(sizeof(*hapd_iface));
1252 if (hapd_iface == NULL) {
1253 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for "
1254 "the interface", __func__);
1255 return NULL;
1256 }
1257 interfaces->count++;
1258 hapd_iface->interfaces = interfaces;
1259
1260 return hapd_iface;
1261}
1262
1263
1264static struct hostapd_config *
1265hostapd_config_alloc(struct hapd_interfaces *interfaces, const char *ifname,
1266 const char *ctrl_iface)
1267{
1268 struct hostapd_bss_config *bss;
1269 struct hostapd_config *conf;
1270
1271 /* Allocates memory for bss and conf */
1272 conf = hostapd_config_defaults();
1273 if (conf == NULL) {
1274 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for "
1275 "configuration", __func__);
1276 return NULL;
1277 }
1278
1279 conf->driver = wpa_drivers[0];
1280 if (conf->driver == NULL) {
1281 wpa_printf(MSG_ERROR, "No driver wrappers registered!");
1282 hostapd_config_free(conf);
1283 return NULL;
1284 }
1285
1286 bss = conf->last_bss = conf->bss;
1287
1288 os_strlcpy(bss->iface, ifname, sizeof(bss->iface));
1289 bss->ctrl_interface = os_strdup(ctrl_iface);
1290 if (bss->ctrl_interface == NULL) {
1291 hostapd_config_free(conf);
1292 return NULL;
1293 }
1294
1295 /* Reading configuration file skipped, will be done in SET!
1296 * From reading the configuration till the end has to be done in
1297 * SET
1298 */
1299 return conf;
1300}
1301
1302
1303static struct hostapd_iface * hostapd_data_alloc(
1304 struct hapd_interfaces *interfaces, struct hostapd_config *conf)
1305{
1306 size_t i;
1307 struct hostapd_iface *hapd_iface =
1308 interfaces->iface[interfaces->count - 1];
1309 struct hostapd_data *hapd;
1310
1311 hapd_iface->conf = conf;
1312 hapd_iface->num_bss = conf->num_bss;
1313
1314 hapd_iface->bss = os_zalloc(conf->num_bss *
1315 sizeof(struct hostapd_data *));
1316 if (hapd_iface->bss == NULL)
1317 return NULL;
1318
1319 for (i = 0; i < conf->num_bss; i++) {
1320 hapd = hapd_iface->bss[i] =
1321 hostapd_alloc_bss_data(hapd_iface, conf,
1322 &conf->bss[i]);
1323 if (hapd == NULL)
1324 return NULL;
1325 hapd->msg_ctx = hapd;
1326 }
1327
1328 hapd_iface->interfaces = interfaces;
1329
1330 return hapd_iface;
1331}
1332
1333
1334int hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf)
1335{
1336 struct hostapd_config *conf = NULL;
1337 struct hostapd_iface *hapd_iface = NULL;
1338 char *ptr;
1339 size_t i;
Dmitry Shmidt56052862013-10-04 10:23:25 -07001340 const char *conf_file = NULL;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001341
1342 ptr = os_strchr(buf, ' ');
1343 if (ptr == NULL)
1344 return -1;
1345 *ptr++ = '\0';
1346
Dmitry Shmidt56052862013-10-04 10:23:25 -07001347 if (os_strncmp(ptr, "config=", 7) == 0)
1348 conf_file = ptr + 7;
1349
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001350 for (i = 0; i < interfaces->count; i++) {
1351 if (!os_strcmp(interfaces->iface[i]->conf->bss[0].iface,
1352 buf)) {
1353 wpa_printf(MSG_INFO, "Cannot add interface - it "
1354 "already exists");
1355 return -1;
1356 }
1357 }
1358
1359 hapd_iface = hostapd_iface_alloc(interfaces);
1360 if (hapd_iface == NULL) {
1361 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
1362 "for interface", __func__);
1363 goto fail;
1364 }
1365
Dmitry Shmidt56052862013-10-04 10:23:25 -07001366 if (conf_file && interfaces->config_read_cb) {
1367 conf = interfaces->config_read_cb(conf_file);
1368 if (conf && conf->bss)
1369 os_strlcpy(conf->bss->iface, buf,
1370 sizeof(conf->bss->iface));
1371 } else
1372 conf = hostapd_config_alloc(interfaces, buf, ptr);
1373 if (conf == NULL || conf->bss == NULL) {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001374 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
1375 "for configuration", __func__);
1376 goto fail;
1377 }
1378
1379 hapd_iface = hostapd_data_alloc(interfaces, conf);
1380 if (hapd_iface == NULL) {
1381 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
1382 "for hostapd", __func__);
1383 goto fail;
1384 }
1385
1386 if (hapd_iface->interfaces &&
1387 hapd_iface->interfaces->ctrl_iface_init &&
1388 hapd_iface->interfaces->ctrl_iface_init(hapd_iface->bss[0])) {
1389 wpa_printf(MSG_ERROR, "%s: Failed to setup control "
1390 "interface", __func__);
1391 goto fail;
1392 }
1393 wpa_printf(MSG_INFO, "Add interface '%s'", conf->bss[0].iface);
1394
1395 return 0;
1396
1397fail:
1398 if (conf)
1399 hostapd_config_free(conf);
1400 if (hapd_iface) {
1401 os_free(hapd_iface->bss[interfaces->count]);
1402 os_free(hapd_iface);
1403 }
1404 return -1;
1405}
1406
1407
1408int hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf)
1409{
1410 struct hostapd_iface *hapd_iface;
1411 size_t i, k = 0;
1412
1413 for (i = 0; i < interfaces->count; i++) {
1414 hapd_iface = interfaces->iface[i];
1415 if (hapd_iface == NULL)
1416 return -1;
1417 if (!os_strcmp(hapd_iface->conf->bss[0].iface, buf)) {
1418 wpa_printf(MSG_INFO, "Remove interface '%s'", buf);
1419 hostapd_interface_deinit_free(hapd_iface);
1420 k = i;
1421 while (k < (interfaces->count - 1)) {
1422 interfaces->iface[k] =
1423 interfaces->iface[k + 1];
1424 k++;
1425 }
1426 interfaces->count--;
1427 return 0;
1428 }
1429 }
1430 return -1;
1431}
1432
1433#endif /* HOSTAPD */
1434
1435
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001436/**
1437 * hostapd_new_assoc_sta - Notify that a new station associated with the AP
1438 * @hapd: Pointer to BSS data
1439 * @sta: Pointer to the associated STA data
1440 * @reassoc: 1 to indicate this was a re-association; 0 = first association
1441 *
1442 * This function will be called whenever a station associates with the AP. It
1443 * can be called from ieee802_11.c for drivers that export MLME to hostapd and
1444 * from drv_callbacks.c based on driver events for drivers that take care of
1445 * management frames (IEEE 802.11 authentication and association) internally.
1446 */
1447void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
1448 int reassoc)
1449{
1450 if (hapd->tkip_countermeasures) {
1451 hostapd_drv_sta_deauth(hapd, sta->addr,
1452 WLAN_REASON_MICHAEL_MIC_FAILURE);
1453 return;
1454 }
1455
1456 hostapd_prune_associations(hapd, sta->addr);
1457
1458 /* IEEE 802.11F (IAPP) */
1459 if (hapd->conf->ieee802_11f)
1460 iapp_new_station(hapd->iapp, sta);
1461
1462#ifdef CONFIG_P2P
1463 if (sta->p2p_ie == NULL && !sta->no_p2p_set) {
1464 sta->no_p2p_set = 1;
1465 hapd->num_sta_no_p2p++;
1466 if (hapd->num_sta_no_p2p == 1)
1467 hostapd_p2p_non_p2p_sta_connected(hapd);
1468 }
1469#endif /* CONFIG_P2P */
1470
1471 /* Start accounting here, if IEEE 802.1X and WPA are not used.
1472 * IEEE 802.1X/WPA code will start accounting after the station has
1473 * been authorized. */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001474 if (!hapd->conf->ieee802_1x && !hapd->conf->wpa) {
1475 os_get_time(&sta->connected_time);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001476 accounting_sta_start(hapd, sta);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001477 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001478
1479 /* Start IEEE 802.1X authentication process for new stations */
1480 ieee802_1x_new_station(hapd, sta);
1481 if (reassoc) {
1482 if (sta->auth_alg != WLAN_AUTH_FT &&
1483 !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)))
1484 wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH);
1485 } else
1486 wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001487
1488 wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout "
1489 "for " MACSTR " (%d seconds - ap_max_inactivity)",
1490 __func__, MAC2STR(sta->addr),
1491 hapd->conf->ap_max_inactivity);
1492 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
1493 eloop_register_timeout(hapd->conf->ap_max_inactivity, 0,
1494 ap_handle_timer, hapd, sta);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001495}