]> git.ipfire.org Git - thirdparty/hostap.git/blame - hostapd/hostapd.c
Change set_ieee8021x driver op to use parameters structure
[thirdparty/hostap.git] / hostapd / hostapd.c
CommitLineData
6fc6879b
JM
1/*
2 * hostapd / Initialization and configuration
6f78f2fb 3 * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
6fc6879b
JM
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
11 *
12 * See README and COPYING for more details.
13 */
14
15#include "includes.h"
6fc6879b 16
4dbfe5c5 17#include "common.h"
6fc6879b 18#include "eloop.h"
03da66bd
JM
19#include "crypto/tls.h"
20#include "common/ieee802_11_defs.h"
21#include "eapol_auth/eapol_auth_sm.h"
e0e14a7b 22#include "eapol_auth/eapol_auth_sm_i.h"
03da66bd
JM
23#include "radius/radius_client.h"
24#include "radius/radius_server.h"
25#include "eap_server/eap_sim_db.h"
26#include "eap_server/eap.h"
27#include "eap_server/tncs.h"
28#include "l2_packet/l2_packet.h"
6fc6879b
JM
29#include "hostapd.h"
30#include "ieee802_1x.h"
6fc6879b
JM
31#include "beacon.h"
32#include "hw_features.h"
33#include "accounting.h"
6fc6879b 34#include "iapp.h"
6fc6879b 35#include "ieee802_11_auth.h"
bcd154c3 36#include "sta_flags.h"
6fc6879b 37#include "sta_info.h"
97234b50 38#include "ap_list.h"
bfddd95c 39#include "driver_i.h"
6fc6879b
JM
40#include "wpa.h"
41#include "preauth.h"
6fc6879b
JM
42#include "vlan_init.h"
43#include "ctrl_iface.h"
ad08c363 44#include "wps_hostapd.h"
81897f4c 45#include "tkip_countermeasures.h"
6fc6879b
JM
46
47
ad08c363
JM
48static int hostapd_flush_old_stations(struct hostapd_data *hapd);
49static int hostapd_setup_wpa(struct hostapd_data *hapd);
50static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd);
6fc6879b 51
6fc6879b 52extern int wpa_debug_level;
6fc6879b 53
95272a88
JM
54#if defined(EAP_SERVER_SIM) || defined(EAP_SERVER_AKA)
55#define EAP_SIM_DB
56#endif /* EAP_SERVER_SIM || EAP_SERVER_AKA */
57
6fc6879b 58
95272a88 59#ifdef EAP_SIM_DB
6fc6879b
JM
60static int hostapd_sim_db_cb_sta(struct hostapd_data *hapd,
61 struct sta_info *sta, void *ctx)
62{
63 if (eapol_auth_eap_pending_cb(sta->eapol_sm, ctx) == 0)
64 return 1;
65 return 0;
66}
67
68
69static void hostapd_sim_db_cb(void *ctx, void *session_ctx)
70{
71 struct hostapd_data *hapd = ctx;
74784010
JM
72 if (ap_for_each_sta(hapd, hostapd_sim_db_cb_sta, session_ctx) == 0) {
73#ifdef RADIUS_SERVER
6fc6879b 74 radius_server_eap_pending_cb(hapd->radius_srv, session_ctx);
74784010
JM
75#endif /* RADIUS_SERVER */
76 }
6fc6879b 77}
95272a88 78#endif /* EAP_SIM_DB */
6fc6879b
JM
79
80
6fc6879b
JM
81static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
82 struct wpa_auth_config *wconf)
83{
84 wconf->wpa = conf->wpa;
85 wconf->wpa_key_mgmt = conf->wpa_key_mgmt;
86 wconf->wpa_pairwise = conf->wpa_pairwise;
87 wconf->wpa_group = conf->wpa_group;
88 wconf->wpa_group_rekey = conf->wpa_group_rekey;
89 wconf->wpa_strict_rekey = conf->wpa_strict_rekey;
90 wconf->wpa_gmk_rekey = conf->wpa_gmk_rekey;
581a8cde 91 wconf->wpa_ptk_rekey = conf->wpa_ptk_rekey;
6fc6879b
JM
92 wconf->rsn_pairwise = conf->rsn_pairwise;
93 wconf->rsn_preauth = conf->rsn_preauth;
94 wconf->eapol_version = conf->eapol_version;
95 wconf->peerkey = conf->peerkey;
3ae0800c 96 wconf->wmm_enabled = conf->wmm_enabled;
bf98f7f3 97 wconf->okc = conf->okc;
6fc6879b
JM
98#ifdef CONFIG_IEEE80211W
99 wconf->ieee80211w = conf->ieee80211w;
100#endif /* CONFIG_IEEE80211W */
101#ifdef CONFIG_IEEE80211R
102 wconf->ssid_len = conf->ssid.ssid_len;
103 if (wconf->ssid_len > SSID_LEN)
104 wconf->ssid_len = SSID_LEN;
105 os_memcpy(wconf->ssid, conf->ssid.ssid, wconf->ssid_len);
106 os_memcpy(wconf->mobility_domain, conf->mobility_domain,
107 MOBILITY_DOMAIN_ID_LEN);
108 if (conf->nas_identifier &&
109 os_strlen(conf->nas_identifier) <= FT_R0KH_ID_MAX_LEN) {
110 wconf->r0_key_holder_len = os_strlen(conf->nas_identifier);
111 os_memcpy(wconf->r0_key_holder, conf->nas_identifier,
112 wconf->r0_key_holder_len);
113 }
114 os_memcpy(wconf->r1_key_holder, conf->r1_key_holder, FT_R1KH_ID_LEN);
115 wconf->r0_key_lifetime = conf->r0_key_lifetime;
116 wconf->reassociation_deadline = conf->reassociation_deadline;
117 wconf->r0kh_list = conf->r0kh_list;
118 wconf->r1kh_list = conf->r1kh_list;
119 wconf->pmk_r1_push = conf->pmk_r1_push;
120#endif /* CONFIG_IEEE80211R */
121}
122
123
ad08c363
JM
124int hostapd_reload_config(struct hostapd_iface *iface)
125{
126 struct hostapd_data *hapd = iface->bss[0];
127 struct hostapd_config *newconf, *oldconf;
128 struct wpa_auth_config wpa_auth_conf;
c213cc04 129 size_t j;
ad08c363
JM
130
131 newconf = hostapd_config_read(iface->config_fname);
132 if (newconf == NULL)
133 return -1;
134
135 /*
136 * Deauthenticate all stations since the new configuration may not
137 * allow them to use the BSS anymore.
138 */
c213cc04
JM
139 for (j = 0; j < iface->num_bss; j++)
140 hostapd_flush_old_stations(iface->bss[j]);
ad08c363 141
74784010 142#ifndef CONFIG_NO_RADIUS
ad08c363
JM
143 /* TODO: update dynamic data based on changed configuration
144 * items (e.g., open/close sockets, etc.) */
145 radius_client_flush(hapd->radius, 0);
74784010 146#endif /* CONFIG_NO_RADIUS */
ad08c363
JM
147
148 oldconf = hapd->iconf;
149 hapd->iconf = newconf;
150 hapd->conf = &newconf->bss[0];
151 iface->conf = newconf;
152
153 if (hostapd_setup_wpa_psk(hapd->conf)) {
154 wpa_printf(MSG_ERROR, "Failed to re-configure WPA PSK "
155 "after reloading configuration");
156 }
157
158 if (hapd->conf->wpa && hapd->wpa_auth == NULL)
159 hostapd_setup_wpa(hapd);
160 else if (hapd->conf->wpa) {
161 hostapd_wpa_auth_conf(&newconf->bss[0], &wpa_auth_conf);
162 wpa_reconfig(hapd->wpa_auth, &wpa_auth_conf);
163 } else if (hapd->wpa_auth) {
164 wpa_deinit(hapd->wpa_auth);
165 hapd->wpa_auth = NULL;
166 hostapd_set_privacy(hapd, 0);
167 hostapd_setup_encryption(hapd->conf->iface, hapd);
168 }
169
170 ieee802_11_set_beacon(hapd);
171
c813b695
JM
172 if (hapd->conf->ssid.ssid_set &&
173 hostapd_set_ssid(hapd, (u8 *) hapd->conf->ssid.ssid,
174 hapd->conf->ssid.ssid_len)) {
175 wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
176 /* try to continue */
177 }
178
179 if (hapd->conf->ieee802_1x || hapd->conf->wpa)
e3bd3912
JM
180 hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 1);
181 else
182 hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 0);
c813b695 183
ad08c363
JM
184 hostapd_config_free(oldconf);
185
186 wpa_printf(MSG_DEBUG, "Reconfigured interface %s", hapd->conf->iface);
187
188 return 0;
189}
190
191
5c333467 192int handle_reload_iface(struct hostapd_iface *iface, void *ctx)
6fc6879b 193{
5c333467
JM
194 if (hostapd_reload_config(iface) < 0) {
195 wpa_printf(MSG_WARNING, "Failed to read new configuration "
196 "file - continuing with old.");
6fc6879b 197 }
5c333467 198 return 0;
6fc6879b
JM
199}
200
201
6fc6879b
JM
202static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd,
203 char *ifname)
204{
205 int i;
206
207 for (i = 0; i < NUM_WEP_KEYS; i++) {
89d39d9d
JM
208 if (hostapd_set_key(ifname, hapd, WPA_ALG_NONE, NULL, i,
209 i == 0 ? 1 : 0, NULL, 0, NULL, 0)) {
bb305cbd
JM
210 wpa_printf(MSG_DEBUG, "Failed to clear default "
211 "encryption keys (ifname=%s keyidx=%d)",
212 ifname, i);
6fc6879b
JM
213 }
214 }
1aa5c134
JM
215#ifdef CONFIG_IEEE80211W
216 if (hapd->conf->ieee80211w) {
217 for (i = NUM_WEP_KEYS; i < NUM_WEP_KEYS + 2; i++) {
89d39d9d
JM
218 if (hostapd_set_key(ifname, hapd, WPA_ALG_NONE, NULL,
219 i, i == 0 ? 1 : 0, NULL, 0,
220 NULL, 0)) {
bb305cbd
JM
221 wpa_printf(MSG_DEBUG, "Failed to clear "
222 "default mgmt encryption keys "
223 "(ifname=%s keyidx=%d)", ifname, i);
1aa5c134
JM
224 }
225 }
226 }
227#endif /* CONFIG_IEEE80211W */
6fc6879b
JM
228}
229
230
231static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd)
232{
233 hostapd_broadcast_key_clear_iface(hapd, hapd->conf->iface);
234 return 0;
235}
236
237
238static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
239{
240 int errors = 0, idx;
241 struct hostapd_ssid *ssid = &hapd->conf->ssid;
242
243 idx = ssid->wep.idx;
244 if (ssid->wep.default_len &&
89d39d9d
JM
245 hostapd_set_key(hapd->conf->iface,
246 hapd, WPA_ALG_WEP, NULL, idx, idx == ssid->wep.idx,
247 NULL, 0, ssid->wep.key[idx], ssid->wep.len[idx])) {
bb305cbd 248 wpa_printf(MSG_WARNING, "Could not set WEP encryption.");
6fc6879b
JM
249 errors++;
250 }
251
252 if (ssid->dyn_vlan_keys) {
253 size_t i;
254 for (i = 0; i <= ssid->max_dyn_vlan_keys; i++) {
255 const char *ifname;
256 struct hostapd_wep_keys *key = ssid->dyn_vlan_keys[i];
257 if (key == NULL)
258 continue;
259 ifname = hostapd_get_vlan_id_ifname(hapd->conf->vlan,
260 i);
261 if (ifname == NULL)
262 continue;
263
264 idx = key->idx;
89d39d9d
JM
265 if (hostapd_set_key(ifname, hapd, WPA_ALG_WEP, NULL,
266 idx, idx == key->idx, NULL, 0,
267 key->key[idx], key->len[idx])) {
bb305cbd
JM
268 wpa_printf(MSG_WARNING, "Could not set "
269 "dynamic VLAN WEP encryption.");
6fc6879b
JM
270 errors++;
271 }
272 }
273 }
274
275 return errors;
276}
277
278/**
279 * hostapd_cleanup - Per-BSS cleanup (deinitialization)
280 * @hapd: Pointer to BSS data
281 *
282 * This function is used to free all per-BSS data structures and resources.
283 * This gets called in a loop for each BSS between calls to
284 * hostapd_cleanup_iface_pre() and hostapd_cleanup_iface() when an interface
285 * is deinitialized. Most of the modules that are initialized in
286 * hostapd_setup_bss() are deinitialized here.
287 */
288static void hostapd_cleanup(struct hostapd_data *hapd)
289{
290 hostapd_ctrl_iface_deinit(hapd);
291
6fc6879b
JM
292 iapp_deinit(hapd->iapp);
293 hapd->iapp = NULL;
294 accounting_deinit(hapd);
295 rsn_preauth_iface_deinit(hapd);
296 if (hapd->wpa_auth) {
297 wpa_deinit(hapd->wpa_auth);
298 hapd->wpa_auth = NULL;
299
300 if (hostapd_set_privacy(hapd, 0)) {
301 wpa_printf(MSG_DEBUG, "Could not disable "
302 "PrivacyInvoked for interface %s",
303 hapd->conf->iface);
304 }
305
306 if (hostapd_set_generic_elem(hapd, (u8 *) "", 0)) {
307 wpa_printf(MSG_DEBUG, "Could not remove generic "
308 "information element from interface %s",
309 hapd->conf->iface);
310 }
311 }
312 ieee802_1x_deinit(hapd);
313 vlan_deinit(hapd);
314 hostapd_acl_deinit(hapd);
74784010 315#ifndef CONFIG_NO_RADIUS
6fc6879b
JM
316 radius_client_deinit(hapd->radius);
317 hapd->radius = NULL;
74784010
JM
318#endif /* CONFIG_NO_RADIUS */
319#ifdef RADIUS_SERVER
6fc6879b
JM
320 radius_server_deinit(hapd->radius_srv);
321 hapd->radius_srv = NULL;
74784010 322#endif /* RADIUS_SERVER */
6fc6879b
JM
323
324#ifdef CONFIG_IEEE80211R
325 l2_packet_deinit(hapd->l2);
326#endif /* CONFIG_IEEE80211R */
327
ad08c363
JM
328 hostapd_deinit_wps(hapd);
329
6fc6879b
JM
330#ifdef EAP_TLS_FUNCS
331 if (hapd->ssl_ctx) {
332 tls_deinit(hapd->ssl_ctx);
333 hapd->ssl_ctx = NULL;
334 }
335#endif /* EAP_TLS_FUNCS */
336
5c90d476 337#if defined(EAP_SERVER_SIM) || defined(EAP_SERVER_AKA)
6fc6879b
JM
338 if (hapd->eap_sim_db_priv) {
339 eap_sim_db_deinit(hapd->eap_sim_db_priv);
340 hapd->eap_sim_db_priv = NULL;
341 }
5c90d476 342#endif /* EAP_SERVER_SIM || EAP_SERVER_AKA */
6fc6879b
JM
343
344 if (hapd->interface_added &&
22a7c9d7 345 hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) {
bb305cbd
JM
346 wpa_printf(MSG_WARNING, "Failed to remove BSS interface %s",
347 hapd->conf->iface);
6fc6879b 348 }
fa16028d
JM
349
350 os_free(hapd->probereq_cb);
351 hapd->probereq_cb = NULL;
6fc6879b
JM
352}
353
354
355/**
356 * hostapd_cleanup_iface_pre - Preliminary per-interface cleanup
357 * @iface: Pointer to interface data
358 *
359 * This function is called before per-BSS data structures are deinitialized
360 * with hostapd_cleanup().
361 */
362static void hostapd_cleanup_iface_pre(struct hostapd_iface *iface)
363{
364}
365
366
367/**
368 * hostapd_cleanup_iface - Complete per-interface cleanup
369 * @iface: Pointer to interface data
370 *
371 * This function is called after per-BSS data structures are deinitialized
372 * with hostapd_cleanup().
373 */
374static void hostapd_cleanup_iface(struct hostapd_iface *iface)
375{
376 hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
377 iface->hw_features = NULL;
378 os_free(iface->current_rates);
379 iface->current_rates = NULL;
380 ap_list_deinit(iface);
381 hostapd_config_free(iface->conf);
382 iface->conf = NULL;
383
384 os_free(iface->config_fname);
385 os_free(iface->bss);
386 os_free(iface);
387}
388
389
390static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd)
391{
392 int i;
393
394 hostapd_broadcast_wep_set(hapd);
395
396 if (hapd->conf->ssid.wep.default_len)
397 return 0;
398
399 for (i = 0; i < 4; i++) {
400 if (hapd->conf->ssid.wep.key[i] &&
89d39d9d
JM
401 hostapd_set_key(iface, hapd, WPA_ALG_WEP, NULL, i,
402 i == hapd->conf->ssid.wep.idx, NULL, 0,
403 hapd->conf->ssid.wep.key[i],
404 hapd->conf->ssid.wep.len[i])) {
bb305cbd
JM
405 wpa_printf(MSG_WARNING, "Could not set WEP "
406 "encryption.");
6fc6879b
JM
407 return -1;
408 }
409 if (hapd->conf->ssid.wep.key[i] &&
410 i == hapd->conf->ssid.wep.idx)
411 hostapd_set_privacy(hapd, 1);
412 }
413
414 return 0;
415}
416
417
418static int hostapd_flush_old_stations(struct hostapd_data *hapd)
419{
420 int ret = 0;
421
85141289
JM
422 if (hostapd_drv_none(hapd))
423 return 0;
424
6fc6879b
JM
425 wpa_printf(MSG_DEBUG, "Flushing old station entries");
426 if (hostapd_flush(hapd)) {
bb305cbd 427 wpa_printf(MSG_WARNING, "Could not connect to kernel driver.");
6fc6879b
JM
428 ret = -1;
429 }
430 wpa_printf(MSG_DEBUG, "Deauthenticate all stations");
9302c5e1
JM
431
432 /* New Prism2.5/3 STA firmware versions seem to have issues with this
433 * broadcast deauth frame. This gets the firmware in odd state where
434 * nothing works correctly, so let's skip sending this for the hostap
435 * driver. */
436 if (hapd->driver && os_strcmp(hapd->driver->name, "hostap") != 0) {
437 u8 addr[ETH_ALEN];
438 os_memset(addr, 0xff, ETH_ALEN);
439 hostapd_sta_deauth(hapd, addr,
440 WLAN_REASON_PREV_AUTH_NOT_VALID);
441 }
6fc6879b
JM
442
443 return ret;
444}
445
446
447static void hostapd_wpa_auth_logger(void *ctx, const u8 *addr,
448 logger_level level, const char *txt)
449{
71f04b3c 450#ifndef CONFIG_NO_HOSTAPD_LOGGER
6fc6879b
JM
451 struct hostapd_data *hapd = ctx;
452 int hlevel;
453
454 switch (level) {
455 case LOGGER_WARNING:
456 hlevel = HOSTAPD_LEVEL_WARNING;
457 break;
458 case LOGGER_INFO:
459 hlevel = HOSTAPD_LEVEL_INFO;
460 break;
461 case LOGGER_DEBUG:
462 default:
463 hlevel = HOSTAPD_LEVEL_DEBUG;
464 break;
465 }
466
467 hostapd_logger(hapd, addr, HOSTAPD_MODULE_WPA, hlevel, "%s", txt);
71f04b3c 468#endif /* CONFIG_NO_HOSTAPD_LOGGER */
6fc6879b
JM
469}
470
471
472static void hostapd_wpa_auth_disconnect(void *ctx, const u8 *addr,
473 u16 reason)
474{
475 struct hostapd_data *hapd = ctx;
476 struct sta_info *sta;
477
478 wpa_printf(MSG_DEBUG, "%s: WPA authenticator requests disconnect: "
479 "STA " MACSTR " reason %d",
480 __func__, MAC2STR(addr), reason);
481
482 sta = ap_get_sta(hapd, addr);
483 hostapd_sta_deauth(hapd, addr, reason);
484 if (sta == NULL)
485 return;
486 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_AUTHORIZED);
487 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
488 eloop_register_timeout(0, 0, ap_handle_timer, hapd, sta);
489 sta->timeout_next = STA_REMOVE;
490}
491
492
493static void hostapd_wpa_auth_mic_failure_report(void *ctx, const u8 *addr)
494{
495 struct hostapd_data *hapd = ctx;
81897f4c 496 michael_mic_failure(hapd, addr, 0);
6fc6879b
JM
497}
498
499
500static void hostapd_wpa_auth_set_eapol(void *ctx, const u8 *addr,
501 wpa_eapol_variable var, int value)
502{
503 struct hostapd_data *hapd = ctx;
504 struct sta_info *sta = ap_get_sta(hapd, addr);
505 if (sta == NULL)
506 return;
507 switch (var) {
508 case WPA_EAPOL_portEnabled:
509 ieee802_1x_notify_port_enabled(sta->eapol_sm, value);
510 break;
511 case WPA_EAPOL_portValid:
512 ieee802_1x_notify_port_valid(sta->eapol_sm, value);
513 break;
514 case WPA_EAPOL_authorized:
515 ieee802_1x_set_sta_authorized(hapd, sta, value);
516 break;
517 case WPA_EAPOL_portControl_Auto:
518 if (sta->eapol_sm)
519 sta->eapol_sm->portControl = Auto;
520 break;
521 case WPA_EAPOL_keyRun:
522 if (sta->eapol_sm)
523 sta->eapol_sm->keyRun = value ? TRUE : FALSE;
524 break;
525 case WPA_EAPOL_keyAvailable:
526 if (sta->eapol_sm)
527 sta->eapol_sm->eap_if->eapKeyAvailable =
528 value ? TRUE : FALSE;
529 break;
530 case WPA_EAPOL_keyDone:
531 if (sta->eapol_sm)
532 sta->eapol_sm->keyDone = value ? TRUE : FALSE;
533 break;
534 case WPA_EAPOL_inc_EapolFramesTx:
535 if (sta->eapol_sm)
536 sta->eapol_sm->dot1xAuthEapolFramesTx++;
537 break;
538 }
539}
540
541
542static int hostapd_wpa_auth_get_eapol(void *ctx, const u8 *addr,
543 wpa_eapol_variable var)
544{
545 struct hostapd_data *hapd = ctx;
546 struct sta_info *sta = ap_get_sta(hapd, addr);
547 if (sta == NULL || sta->eapol_sm == NULL)
548 return -1;
549 switch (var) {
550 case WPA_EAPOL_keyRun:
551 return sta->eapol_sm->keyRun;
552 case WPA_EAPOL_keyAvailable:
553 return sta->eapol_sm->eap_if->eapKeyAvailable;
554 default:
555 return -1;
556 }
557}
558
559
560static const u8 * hostapd_wpa_auth_get_psk(void *ctx, const u8 *addr,
561 const u8 *prev_psk)
562{
563 struct hostapd_data *hapd = ctx;
564 return hostapd_get_psk(hapd->conf, addr, prev_psk);
565}
566
567
568static int hostapd_wpa_auth_get_msk(void *ctx, const u8 *addr, u8 *msk,
569 size_t *len)
570{
571 struct hostapd_data *hapd = ctx;
572 const u8 *key;
573 size_t keylen;
574 struct sta_info *sta;
575
576 sta = ap_get_sta(hapd, addr);
577 if (sta == NULL)
578 return -1;
579
580 key = ieee802_1x_get_key(sta->eapol_sm, &keylen);
581 if (key == NULL)
582 return -1;
583
584 if (keylen > *len)
585 keylen = *len;
586 os_memcpy(msk, key, keylen);
587 *len = keylen;
588
589 return 0;
590}
591
592
89d39d9d 593static int hostapd_wpa_auth_set_key(void *ctx, int vlan_id, wpa_alg alg,
6fc6879b
JM
594 const u8 *addr, int idx, u8 *key,
595 size_t key_len)
596{
597 struct hostapd_data *hapd = ctx;
598 const char *ifname = hapd->conf->iface;
599
600 if (vlan_id > 0) {
601 ifname = hostapd_get_vlan_id_ifname(hapd->conf->vlan, vlan_id);
602 if (ifname == NULL)
603 return -1;
604 }
605
89d39d9d
JM
606 return hostapd_set_key(ifname, hapd, alg, addr, idx, 1, NULL, 0,
607 key, key_len);
6fc6879b
JM
608}
609
610
611static int hostapd_wpa_auth_get_seqnum(void *ctx, const u8 *addr, int idx,
612 u8 *seq)
613{
614 struct hostapd_data *hapd = ctx;
615 return hostapd_get_seqnum(hapd->conf->iface, hapd, addr, idx, seq);
616}
617
618
6fc6879b
JM
619static int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr,
620 const u8 *data, size_t data_len,
621 int encrypt)
622{
623 struct hostapd_data *hapd = ctx;
624 return hostapd_send_eapol(hapd, addr, data, data_len, encrypt);
625}
626
627
628static int hostapd_wpa_auth_for_each_sta(
629 void *ctx, int (*cb)(struct wpa_state_machine *sm, void *ctx),
630 void *cb_ctx)
631{
632 struct hostapd_data *hapd = ctx;
633 struct sta_info *sta;
634
635 for (sta = hapd->sta_list; sta; sta = sta->next) {
636 if (sta->wpa_sm && cb(sta->wpa_sm, cb_ctx))
637 return 1;
638 }
639 return 0;
640}
641
642
5c333467
JM
643struct wpa_auth_iface_iter_data {
644 int (*cb)(struct wpa_authenticator *sm, void *ctx);
645 void *cb_ctx;
646};
647
648static int wpa_auth_iface_iter(struct hostapd_iface *iface, void *ctx)
649{
650 struct wpa_auth_iface_iter_data *data = ctx;
651 size_t i;
652 for (i = 0; i < iface->num_bss; i++) {
653 if (data->cb(iface->bss[i]->wpa_auth, data->cb_ctx))
654 return 1;
655 }
656 return 0;
657}
658
659
bf98f7f3
JM
660static int hostapd_wpa_auth_for_each_auth(
661 void *ctx, int (*cb)(struct wpa_authenticator *sm, void *ctx),
662 void *cb_ctx)
663{
5c333467
JM
664 struct wpa_auth_iface_iter_data data;
665 data.cb = cb;
666 data.cb_ctx = cb_ctx;
667 return hostapd_for_each_interface(wpa_auth_iface_iter, &data);
bf98f7f3
JM
668}
669
670
6fc6879b
JM
671static int hostapd_wpa_auth_send_ether(void *ctx, const u8 *dst, u16 proto,
672 const u8 *data, size_t data_len)
673{
674 struct hostapd_data *hapd = ctx;
675
676 if (hapd->driver && hapd->driver->send_ether)
677 return hapd->driver->send_ether(hapd->drv_priv, dst,
678 hapd->own_addr, proto,
679 data, data_len);
680 if (hapd->l2 == NULL)
681 return -1;
682 return l2_packet_send(hapd->l2, dst, proto, data, data_len);
683}
684
685
686#ifdef CONFIG_IEEE80211R
687
688static int hostapd_wpa_auth_send_ft_action(void *ctx, const u8 *dst,
689 const u8 *data, size_t data_len)
690{
691 struct hostapd_data *hapd = ctx;
692 int res;
693 struct ieee80211_mgmt *m;
694 size_t mlen;
695 struct sta_info *sta;
696
697 sta = ap_get_sta(hapd, dst);
698 if (sta == NULL || sta->wpa_sm == NULL)
699 return -1;
700
701 m = os_zalloc(sizeof(*m) + data_len);
702 if (m == NULL)
703 return -1;
704 mlen = ((u8 *) &m->u - (u8 *) m) + data_len;
705 m->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
706 WLAN_FC_STYPE_ACTION);
707 os_memcpy(m->da, dst, ETH_ALEN);
708 os_memcpy(m->sa, hapd->own_addr, ETH_ALEN);
709 os_memcpy(m->bssid, hapd->own_addr, ETH_ALEN);
710 os_memcpy(&m->u, data, data_len);
711
83421302 712 res = hostapd_send_mgmt_frame(hapd, (u8 *) m, mlen);
6fc6879b
JM
713 os_free(m);
714 return res;
715}
716
717
718static struct wpa_state_machine *
719hostapd_wpa_auth_add_sta(void *ctx, const u8 *sta_addr)
720{
721 struct hostapd_data *hapd = ctx;
722 struct sta_info *sta;
723
724 sta = ap_sta_add(hapd, sta_addr);
725 if (sta == NULL)
726 return NULL;
727 if (sta->wpa_sm)
728 return sta->wpa_sm;
729
730 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr);
731 if (sta->wpa_sm == NULL) {
732 ap_free_sta(hapd, sta);
733 return NULL;
734 }
735 sta->auth_alg = WLAN_AUTH_FT;
736
737 return sta->wpa_sm;
738}
739
740
741static void hostapd_rrb_receive(void *ctx, const u8 *src_addr, const u8 *buf,
742 size_t len)
743{
744 struct hostapd_data *hapd = ctx;
745 wpa_ft_rrb_rx(hapd->wpa_auth, src_addr, buf, len);
746}
747
748#endif /* CONFIG_IEEE80211R */
749
750
751/**
752 * hostapd_validate_bssid_configuration - Validate BSSID configuration
753 * @iface: Pointer to interface data
754 * Returns: 0 on success, -1 on failure
755 *
756 * This function is used to validate that the configured BSSIDs are valid.
757 */
758static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface)
759{
760 u8 mask[ETH_ALEN] = { 0 };
761 struct hostapd_data *hapd = iface->bss[0];
762 unsigned int i = iface->conf->num_bss, bits = 0, j;
763 int res;
90ac1f9f 764 int auto_addr = 0;
6fc6879b 765
85141289
JM
766 if (hostapd_drv_none(hapd))
767 return 0;
768
6fc6879b
JM
769 /* Generate BSSID mask that is large enough to cover the BSSIDs. */
770
771 /* Determine the bits necessary to cover the number of BSSIDs. */
772 for (i--; i; i >>= 1)
773 bits++;
774
775 /* Determine the bits necessary to any configured BSSIDs,
776 if they are higher than the number of BSSIDs. */
777 for (j = 0; j < iface->conf->num_bss; j++) {
90ac1f9f
JM
778 if (hostapd_mac_comp_empty(iface->conf->bss[j].bssid) == 0) {
779 if (j)
780 auto_addr++;
6fc6879b 781 continue;
90ac1f9f 782 }
6fc6879b
JM
783
784 for (i = 0; i < ETH_ALEN; i++) {
785 mask[i] |=
786 iface->conf->bss[j].bssid[i] ^
787 hapd->own_addr[i];
788 }
789 }
790
90ac1f9f
JM
791 if (!auto_addr)
792 goto skip_mask_ext;
793
6fc6879b
JM
794 for (i = 0; i < ETH_ALEN && mask[i] == 0; i++)
795 ;
796 j = 0;
797 if (i < ETH_ALEN) {
798 j = (5 - i) * 8;
799
800 while (mask[i] != 0) {
801 mask[i] >>= 1;
802 j++;
803 }
804 }
805
806 if (bits < j)
807 bits = j;
808
90ac1f9f
JM
809 if (bits > 40) {
810 wpa_printf(MSG_ERROR, "Too many bits in the BSSID mask (%u)",
811 bits);
6fc6879b 812 return -1;
90ac1f9f 813 }
6fc6879b
JM
814
815 os_memset(mask, 0xff, ETH_ALEN);
816 j = bits / 8;
817 for (i = 5; i > 5 - j; i--)
818 mask[i] = 0;
819 j = bits % 8;
820 while (j--)
821 mask[i] <<= 1;
822
90ac1f9f 823skip_mask_ext:
6fc6879b
JM
824 wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR " (%d bits)",
825 (unsigned long) iface->conf->num_bss, MAC2STR(mask), bits);
826
827 res = hostapd_valid_bss_mask(hapd, hapd->own_addr, mask);
828 if (res == 0)
829 return 0;
830
831 if (res < 0) {
bb305cbd
JM
832 wpa_printf(MSG_ERROR, "Driver did not accept BSSID mask "
833 MACSTR " for start address " MACSTR ".",
834 MAC2STR(mask), MAC2STR(hapd->own_addr));
6fc6879b
JM
835 return -1;
836 }
837
90ac1f9f
JM
838 if (!auto_addr)
839 return 0;
840
6fc6879b
JM
841 for (i = 0; i < ETH_ALEN; i++) {
842 if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) {
bb305cbd
JM
843 wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR
844 " for start address " MACSTR ".",
845 MAC2STR(mask), MAC2STR(hapd->own_addr));
846 wpa_printf(MSG_ERROR, "Start address must be the "
847 "first address in the block (i.e., addr "
848 "AND mask == addr).");
6fc6879b
JM
849 return -1;
850 }
851 }
852
853 return 0;
854}
855
856
857static int mac_in_conf(struct hostapd_config *conf, const void *a)
858{
859 size_t i;
860
861 for (i = 0; i < conf->num_bss; i++) {
862 if (hostapd_mac_comp(conf->bss[i].bssid, a) == 0) {
863 return 1;
864 }
865 }
866
867 return 0;
868}
869
870
871static int hostapd_setup_wpa(struct hostapd_data *hapd)
872{
873 struct wpa_auth_config _conf;
874 struct wpa_auth_callbacks cb;
875 const u8 *wpa_ie;
876 size_t wpa_ie_len;
877
878 hostapd_wpa_auth_conf(hapd->conf, &_conf);
879 os_memset(&cb, 0, sizeof(cb));
880 cb.ctx = hapd;
881 cb.logger = hostapd_wpa_auth_logger;
882 cb.disconnect = hostapd_wpa_auth_disconnect;
883 cb.mic_failure_report = hostapd_wpa_auth_mic_failure_report;
884 cb.set_eapol = hostapd_wpa_auth_set_eapol;
885 cb.get_eapol = hostapd_wpa_auth_get_eapol;
886 cb.get_psk = hostapd_wpa_auth_get_psk;
887 cb.get_msk = hostapd_wpa_auth_get_msk;
888 cb.set_key = hostapd_wpa_auth_set_key;
889 cb.get_seqnum = hostapd_wpa_auth_get_seqnum;
6fc6879b
JM
890 cb.send_eapol = hostapd_wpa_auth_send_eapol;
891 cb.for_each_sta = hostapd_wpa_auth_for_each_sta;
bf98f7f3 892 cb.for_each_auth = hostapd_wpa_auth_for_each_auth;
6fc6879b
JM
893 cb.send_ether = hostapd_wpa_auth_send_ether;
894#ifdef CONFIG_IEEE80211R
895 cb.send_ft_action = hostapd_wpa_auth_send_ft_action;
896 cb.add_sta = hostapd_wpa_auth_add_sta;
897#endif /* CONFIG_IEEE80211R */
898 hapd->wpa_auth = wpa_init(hapd->own_addr, &_conf, &cb);
899 if (hapd->wpa_auth == NULL) {
bb305cbd 900 wpa_printf(MSG_ERROR, "WPA initialization failed.");
6fc6879b
JM
901 return -1;
902 }
903
904 if (hostapd_set_privacy(hapd, 1)) {
905 wpa_printf(MSG_ERROR, "Could not set PrivacyInvoked "
906 "for interface %s", hapd->conf->iface);
907 return -1;
908 }
909
910 wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len);
911 if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len)) {
912 wpa_printf(MSG_ERROR, "Failed to configure WPA IE for "
913 "the kernel driver.");
914 return -1;
915 }
916
917 if (rsn_preauth_iface_init(hapd)) {
bb305cbd
JM
918 wpa_printf(MSG_ERROR, "Initialization of RSN "
919 "pre-authentication failed.");
6fc6879b
JM
920 return -1;
921 }
922
923 return 0;
924
925}
926
927
74784010
JM
928#ifdef RADIUS_SERVER
929
930static int hostapd_radius_get_eap_user(void *ctx, const u8 *identity,
931 size_t identity_len, int phase2,
932 struct eap_user *user)
933{
934 const struct hostapd_eap_user *eap_user;
935 int i, count;
936
937 eap_user = hostapd_get_eap_user(ctx, identity, identity_len, phase2);
938 if (eap_user == NULL)
939 return -1;
940
941 if (user == NULL)
942 return 0;
943
944 os_memset(user, 0, sizeof(*user));
945 count = EAP_USER_MAX_METHODS;
946 if (count > EAP_MAX_METHODS)
947 count = EAP_MAX_METHODS;
948 for (i = 0; i < count; i++) {
949 user->methods[i].vendor = eap_user->methods[i].vendor;
950 user->methods[i].method = eap_user->methods[i].method;
951 }
952
953 if (eap_user->password) {
954 user->password = os_malloc(eap_user->password_len);
955 if (user->password == NULL)
956 return -1;
957 os_memcpy(user->password, eap_user->password,
958 eap_user->password_len);
959 user->password_len = eap_user->password_len;
960 user->password_hash = eap_user->password_hash;
961 }
962 user->force_version = eap_user->force_version;
963 user->ttls_auth = eap_user->ttls_auth;
964
965 return 0;
966}
967
968
6fc6879b
JM
969static int hostapd_setup_radius_srv(struct hostapd_data *hapd,
970 struct hostapd_bss_config *conf)
971{
972 struct radius_server_conf srv;
973 os_memset(&srv, 0, sizeof(srv));
974 srv.client_file = conf->radius_server_clients;
975 srv.auth_port = conf->radius_server_auth_port;
976 srv.conf_ctx = conf;
977 srv.eap_sim_db_priv = hapd->eap_sim_db_priv;
978 srv.ssl_ctx = hapd->ssl_ctx;
979 srv.pac_opaque_encr_key = conf->pac_opaque_encr_key;
980 srv.eap_fast_a_id = conf->eap_fast_a_id;
2d867244
JM
981 srv.eap_fast_a_id_len = conf->eap_fast_a_id_len;
982 srv.eap_fast_a_id_info = conf->eap_fast_a_id_info;
378eae5e 983 srv.eap_fast_prov = conf->eap_fast_prov;
a11c90a6
JM
984 srv.pac_key_lifetime = conf->pac_key_lifetime;
985 srv.pac_key_refresh_time = conf->pac_key_refresh_time;
6fc6879b 986 srv.eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
c3e258ae 987 srv.tnc = conf->tnc;
ad08c363 988 srv.wps = hapd->wps;
6fc6879b
JM
989 srv.ipv6 = conf->radius_server_ipv6;
990 srv.get_eap_user = hostapd_radius_get_eap_user;
65d50f0a
JM
991 srv.eap_req_id_text = conf->eap_req_id_text;
992 srv.eap_req_id_text_len = conf->eap_req_id_text_len;
6fc6879b
JM
993
994 hapd->radius_srv = radius_server_init(&srv);
995 if (hapd->radius_srv == NULL) {
bb305cbd 996 wpa_printf(MSG_ERROR, "RADIUS server initialization failed.");
6fc6879b
JM
997 return -1;
998 }
999
1000 return 0;
1001}
1002
74784010
JM
1003#endif /* RADIUS_SERVER */
1004
6fc6879b
JM
1005
1006/**
1007 * hostapd_setup_bss - Per-BSS setup (initialization)
1008 * @hapd: Pointer to BSS data
1009 * @first: Whether this BSS is the first BSS of an interface
1010 *
1011 * This function is used to initialize all per-BSS data structures and
1012 * resources. This gets called in a loop for each BSS when an interface is
1013 * initialized. Most of the modules that are initialized here will be
1014 * deinitialized in hostapd_cleanup().
1015 */
1016static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
1017{
1018 struct hostapd_bss_config *conf = hapd->conf;
1019 u8 ssid[HOSTAPD_MAX_SSID_LEN + 1];
1020 int ssid_len, set_ssid;
1021
1022 if (!first) {
1023 if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0) {
1024 /* Allocate the next available BSSID. */
1025 do {
1026 inc_byte_array(hapd->own_addr, ETH_ALEN);
1027 } while (mac_in_conf(hapd->iconf, hapd->own_addr));
1028 } else {
1029 /* Allocate the configured BSSID. */
1030 os_memcpy(hapd->own_addr, hapd->conf->bssid, ETH_ALEN);
1031
1032 if (hostapd_mac_comp(hapd->own_addr,
1033 hapd->iface->bss[0]->own_addr) ==
1034 0) {
bb305cbd
JM
1035 wpa_printf(MSG_ERROR, "BSS '%s' may not have "
1036 "BSSID set to the MAC address of "
1037 "the radio", hapd->conf->iface);
6fc6879b
JM
1038 return -1;
1039 }
1040 }
1041
1042 hapd->interface_added = 1;
22a7c9d7
JM
1043 if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS,
1044 hapd->conf->iface, hapd->own_addr)) {
bb305cbd
JM
1045 wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID="
1046 MACSTR ")", MAC2STR(hapd->own_addr));
6fc6879b
JM
1047 return -1;
1048 }
1049 }
1050
c213cc04
JM
1051 hostapd_flush_old_stations(hapd);
1052 hostapd_set_privacy(hapd, 0);
1053
1054 hostapd_broadcast_wep_clear(hapd);
1055 if (hostapd_setup_encryption(hapd->conf->iface, hapd))
1056 return -1;
1057
6fc6879b
JM
1058 /*
1059 * Fetch the SSID from the system and use it or,
1060 * if one was specified in the config file, verify they
1061 * match.
1062 */
1063 ssid_len = hostapd_get_ssid(hapd, ssid, sizeof(ssid));
1064 if (ssid_len < 0) {
bb305cbd 1065 wpa_printf(MSG_ERROR, "Could not read SSID from system");
6fc6879b
JM
1066 return -1;
1067 }
1068 if (conf->ssid.ssid_set) {
1069 /*
1070 * If SSID is specified in the config file and it differs
1071 * from what is being used then force installation of the
1072 * new SSID.
1073 */
1074 set_ssid = (conf->ssid.ssid_len != (size_t) ssid_len ||
1075 os_memcmp(conf->ssid.ssid, ssid, ssid_len) != 0);
1076 } else {
1077 /*
1078 * No SSID in the config file; just use the one we got
1079 * from the system.
1080 */
1081 set_ssid = 0;
1082 conf->ssid.ssid_len = ssid_len;
1083 os_memcpy(conf->ssid.ssid, ssid, conf->ssid.ssid_len);
1084 conf->ssid.ssid[conf->ssid.ssid_len] = '\0';
1085 }
1086
85141289 1087 if (!hostapd_drv_none(hapd)) {
bb305cbd
JM
1088 wpa_printf(MSG_ERROR, "Using interface %s with hwaddr " MACSTR
1089 " and ssid '%s'",
1090 hapd->conf->iface, MAC2STR(hapd->own_addr),
1091 hapd->conf->ssid.ssid);
85141289 1092 }
6fc6879b
JM
1093
1094 if (hostapd_setup_wpa_psk(conf)) {
bb305cbd 1095 wpa_printf(MSG_ERROR, "WPA-PSK setup failed.");
6fc6879b
JM
1096 return -1;
1097 }
1098
6fc6879b
JM
1099 /* Set SSID for the kernel driver (to be used in beacon and probe
1100 * response frames) */
1101 if (set_ssid && hostapd_set_ssid(hapd, (u8 *) conf->ssid.ssid,
1102 conf->ssid.ssid_len)) {
bb305cbd 1103 wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
6fc6879b
JM
1104 return -1;
1105 }
1106
1107 if (wpa_debug_level == MSG_MSGDUMP)
1108 conf->radius->msg_dumps = 1;
74784010 1109#ifndef CONFIG_NO_RADIUS
6fc6879b
JM
1110 hapd->radius = radius_client_init(hapd, conf->radius);
1111 if (hapd->radius == NULL) {
bb305cbd 1112 wpa_printf(MSG_ERROR, "RADIUS client initialization failed.");
6fc6879b
JM
1113 return -1;
1114 }
74784010 1115#endif /* CONFIG_NO_RADIUS */
6fc6879b
JM
1116
1117 if (hostapd_acl_init(hapd)) {
bb305cbd 1118 wpa_printf(MSG_ERROR, "ACL initialization failed.");
6fc6879b
JM
1119 return -1;
1120 }
ad08c363
JM
1121 if (hostapd_init_wps(hapd, conf))
1122 return -1;
6fc6879b
JM
1123
1124 if (ieee802_1x_init(hapd)) {
bb305cbd 1125 wpa_printf(MSG_ERROR, "IEEE 802.1X initialization failed.");
6fc6879b
JM
1126 return -1;
1127 }
1128
1129 if (hapd->conf->wpa && hostapd_setup_wpa(hapd))
1130 return -1;
1131
1132 if (accounting_init(hapd)) {
bb305cbd 1133 wpa_printf(MSG_ERROR, "Accounting initialization failed.");
6fc6879b
JM
1134 return -1;
1135 }
1136
1137 if (hapd->conf->ieee802_11f &&
1138 (hapd->iapp = iapp_init(hapd, hapd->conf->iapp_iface)) == NULL) {
bb305cbd
JM
1139 wpa_printf(MSG_ERROR, "IEEE 802.11F (IAPP) initialization "
1140 "failed.");
6fc6879b
JM
1141 return -1;
1142 }
1143
1144 if (hostapd_ctrl_iface_init(hapd)) {
bb305cbd 1145 wpa_printf(MSG_ERROR, "Failed to setup control interface");
6fc6879b
JM
1146 return -1;
1147 }
1148
85141289 1149 if (!hostapd_drv_none(hapd) && vlan_init(hapd)) {
bb305cbd 1150 wpa_printf(MSG_ERROR, "VLAN initialization failed.");
6fc6879b
JM
1151 return -1;
1152 }
1153
1154#ifdef CONFIG_IEEE80211R
85141289
JM
1155 if (!hostapd_drv_none(hapd)) {
1156 hapd->l2 = l2_packet_init(hapd->conf->iface, NULL, ETH_P_RRB,
1157 hostapd_rrb_receive, hapd, 0);
1158 if (hapd->l2 == NULL &&
1159 (hapd->driver == NULL ||
1160 hapd->driver->send_ether == NULL)) {
bb305cbd
JM
1161 wpa_printf(MSG_ERROR, "Failed to open l2_packet "
1162 "interface");
85141289
JM
1163 return -1;
1164 }
6fc6879b
JM
1165 }
1166#endif /* CONFIG_IEEE80211R */
1167
1168 ieee802_11_set_beacon(hapd);
1169
74784010 1170#ifdef RADIUS_SERVER
6fc6879b
JM
1171 if (conf->radius_server_clients &&
1172 hostapd_setup_radius_srv(hapd, conf))
1173 return -1;
74784010 1174#endif /* RADIUS_SERVER */
6fc6879b
JM
1175
1176 return 0;
1177}
1178
1179
990ec378
JM
1180static void hostapd_tx_queue_params(struct hostapd_iface *iface)
1181{
1182 struct hostapd_data *hapd = iface->bss[0];
1183 int i;
1184 struct hostapd_tx_queue_params *p;
1185
1186 for (i = 0; i < NUM_TX_QUEUES; i++) {
1187 p = &iface->conf->tx_queue[i];
1188
1189 if (!p->configured)
1190 continue;
1191
1192 if (hostapd_set_tx_queue_params(hapd, i, p->aifs, p->cwmin,
1193 p->cwmax, p->burst)) {
bb305cbd
JM
1194 wpa_printf(MSG_DEBUG, "Failed to set TX queue "
1195 "parameters for queue %d.", i);
990ec378
JM
1196 /* Continue anyway */
1197 }
1198 }
1199}
1200
1201
ddaa83eb 1202static int setup_interface(struct hostapd_iface *iface)
6fc6879b
JM
1203{
1204 struct hostapd_data *hapd = iface->bss[0];
1205 struct hostapd_bss_config *conf = hapd->conf;
1206 size_t i;
1207 char country[4];
1208 u8 *b = conf->bssid;
1209
1210 /*
1211 * Initialize the driver interface and make sure that all BSSes get
1212 * configured with a pointer to this driver interface.
1213 */
92f475b4
JM
1214 if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5]))
1215 b = NULL;
1216 hapd->drv_priv = hostapd_driver_init(hapd, b);
6fc6879b
JM
1217
1218 if (hapd->drv_priv == NULL) {
bb305cbd
JM
1219 wpa_printf(MSG_ERROR, "%s driver initialization failed.",
1220 hapd->driver ? hapd->driver->name : "Unknown");
6fc6879b
JM
1221 hapd->driver = NULL;
1222 return -1;
1223 }
1224 for (i = 0; i < iface->num_bss; i++) {
1225 iface->bss[i]->driver = hapd->driver;
1226 iface->bss[i]->drv_priv = hapd->drv_priv;
1227 }
1228
1229 if (hostapd_validate_bssid_configuration(iface))
1230 return -1;
1231
6f4071c0
JM
1232 if (hapd->iconf->country[0] && hapd->iconf->country[1]) {
1233 os_memcpy(country, hapd->iconf->country, 3);
1234 country[3] = '\0';
1235 if (hostapd_set_country(hapd, country) < 0) {
1236 wpa_printf(MSG_ERROR, "Failed to set country code");
1237 return -1;
1238 }
6fc6879b
JM
1239 }
1240
6fc6879b
JM
1241 if (hostapd_get_hw_features(iface)) {
1242 /* Not all drivers support this yet, so continue without hw
1243 * feature data. */
1244 } else {
ddaa83eb
JM
1245 int ret = hostapd_select_hw_mode(iface);
1246 if (ret < 0) {
bb305cbd
JM
1247 wpa_printf(MSG_ERROR, "Could not select hw_mode and "
1248 "channel. (%d)", ret);
ddaa83eb
JM
1249 return -1;
1250 }
ad1e68e6
JM
1251 ret = hostapd_check_ht_capab(iface);
1252 if (ret < 0)
1253 return -1;
1254 if (ret == 1) {
1255 wpa_printf(MSG_DEBUG, "Interface initialization will "
1256 "be completed in a callback");
1257 return 0;
1258 }
1259 }
1260 return hostapd_setup_interface_complete(iface, 0);
1261}
1262
1263
1264int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
1265{
1266 struct hostapd_data *hapd = iface->bss[0];
1267 int freq;
1268 size_t j;
1269 u8 *prev_addr;
1270
1271 if (err) {
1272 wpa_printf(MSG_ERROR, "Interface initialization failed");
1273 eloop_terminate();
1274 return -1;
6fc6879b
JM
1275 }
1276
ad1e68e6 1277 wpa_printf(MSG_DEBUG, "Completing interface initialization");
ddaa83eb
JM
1278 if (hapd->iconf->channel) {
1279 freq = hostapd_hw_get_freq(hapd, hapd->iconf->channel);
bb305cbd
JM
1280 wpa_printf(MSG_DEBUG, "Mode: %s Channel: %d "
1281 "Frequency: %d MHz",
1282 hostapd_hw_mode_txt(hapd->iconf->hw_mode),
1283 hapd->iconf->channel, freq);
6fc6879b 1284
95da9bbc 1285 if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, freq,
9c6d8e1d 1286 hapd->iconf->channel,
fe0f58fa 1287 hapd->iconf->ieee80211n,
95da9bbc 1288 hapd->iconf->secondary_channel)) {
bb305cbd
JM
1289 wpa_printf(MSG_ERROR, "Could not set channel for "
1290 "kernel driver");
ddaa83eb
JM
1291 return -1;
1292 }
1293 }
6fc6879b 1294
ddaa83eb
JM
1295 if (hapd->iconf->rts_threshold > -1 &&
1296 hostapd_set_rts(hapd, hapd->iconf->rts_threshold)) {
bb305cbd
JM
1297 wpa_printf(MSG_ERROR, "Could not set RTS threshold for "
1298 "kernel driver");
ddaa83eb
JM
1299 return -1;
1300 }
1301
1302 if (hapd->iconf->fragm_threshold > -1 &&
1303 hostapd_set_frag(hapd, hapd->iconf->fragm_threshold)) {
bb305cbd
JM
1304 wpa_printf(MSG_ERROR, "Could not set fragmentation threshold "
1305 "for kernel driver");
ddaa83eb
JM
1306 return -1;
1307 }
6fc6879b 1308
ddaa83eb
JM
1309 prev_addr = hapd->own_addr;
1310
1311 for (j = 0; j < iface->num_bss; j++) {
1312 hapd = iface->bss[j];
1313 if (j)
1314 os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN);
1315 if (hostapd_setup_bss(hapd, j == 0))
1316 return -1;
1317 if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0)
1318 prev_addr = hapd->own_addr;
1319 }
1320
1321 hostapd_tx_queue_params(iface);
1322
1323 ap_list_init(iface);
1324
1325 if (hostapd_driver_commit(hapd) < 0) {
1326 wpa_printf(MSG_ERROR, "%s: Failed to commit driver "
1327 "configuration", __func__);
1328 return -1;
1329 }
1330
ad1e68e6
JM
1331 wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
1332 iface->bss[0]->conf->iface);
1333
21db94c5 1334 return 0;
6fc6879b
JM
1335}
1336
1337
1338/**
ddaa83eb 1339 * hostapd_setup_interface - Setup of an interface
6fc6879b 1340 * @iface: Pointer to interface data.
ddaa83eb 1341 * Returns: 0 on success, -1 on failure
6fc6879b
JM
1342 *
1343 * Initializes the driver interface, validates the configuration,
1344 * and sets driver parameters based on the configuration.
ddaa83eb 1345 * Flushes old stations, sets the channel, encryption,
6fc6879b
JM
1346 * beacons, and WDS links based on the configuration.
1347 */
5c333467 1348int hostapd_setup_interface(struct hostapd_iface *iface)
6fc6879b 1349{
ddaa83eb
JM
1350 int ret;
1351
1352 ret = setup_interface(iface);
1353 if (ret) {
1354 wpa_printf(MSG_DEBUG, "%s: Unable to setup interface.",
6fc6879b 1355 iface->bss[0]->conf->iface);
ddaa83eb 1356 eloop_terminate();
6fc6879b
JM
1357 return -1;
1358 }
1359
6fc6879b
JM
1360 return 0;
1361}
1362
1363
6fc6879b
JM
1364/**
1365 * hostapd_alloc_bss_data - Allocate and initialize per-BSS data
1366 * @hapd_iface: Pointer to interface data
1367 * @conf: Pointer to per-interface configuration
1368 * @bss: Pointer to per-BSS configuration for this BSS
1369 * Returns: Pointer to allocated BSS data
1370 *
1371 * This function is used to allocate per-BSS data structure. This data will be
1372 * freed after hostapd_cleanup() is called for it during interface
1373 * deinitialization.
1374 */
b6a7859d 1375struct hostapd_data *
6fc6879b
JM
1376hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
1377 struct hostapd_config *conf,
1378 struct hostapd_bss_config *bss)
1379{
1380 struct hostapd_data *hapd;
1381
1382 hapd = os_zalloc(sizeof(*hapd));
1383 if (hapd == NULL)
1384 return NULL;
1385
1386 hapd->iconf = conf;
1387 hapd->conf = bss;
1388 hapd->iface = hapd_iface;
1389
6fc6879b
JM
1390#ifdef EAP_TLS_FUNCS
1391 if (hapd->conf->eap_server &&
1392 (hapd->conf->ca_cert || hapd->conf->server_cert ||
1393 hapd->conf->dh_file)) {
1394 struct tls_connection_params params;
1395
1396 hapd->ssl_ctx = tls_init(NULL);
1397 if (hapd->ssl_ctx == NULL) {
bb305cbd 1398 wpa_printf(MSG_ERROR, "Failed to initialize TLS");
6fc6879b
JM
1399 goto fail;
1400 }
1401
1402 os_memset(&params, 0, sizeof(params));
1403 params.ca_cert = hapd->conf->ca_cert;
1404 params.client_cert = hapd->conf->server_cert;
1405 params.private_key = hapd->conf->private_key;
1406 params.private_key_passwd = hapd->conf->private_key_passwd;
1407 params.dh_file = hapd->conf->dh_file;
1408
1409 if (tls_global_set_params(hapd->ssl_ctx, &params)) {
bb305cbd 1410 wpa_printf(MSG_ERROR, "Failed to set TLS parameters");
6fc6879b
JM
1411 goto fail;
1412 }
1413
1414 if (tls_global_set_verify(hapd->ssl_ctx,
1415 hapd->conf->check_crl)) {
bb305cbd 1416 wpa_printf(MSG_ERROR, "Failed to enable check_crl");
6fc6879b
JM
1417 goto fail;
1418 }
1419 }
1420#endif /* EAP_TLS_FUNCS */
1421
95272a88 1422#ifdef EAP_SIM_DB
6fc6879b
JM
1423 if (hapd->conf->eap_sim_db) {
1424 hapd->eap_sim_db_priv =
1425 eap_sim_db_init(hapd->conf->eap_sim_db,
1426 hostapd_sim_db_cb, hapd);
1427 if (hapd->eap_sim_db_priv == NULL) {
bb305cbd
JM
1428 wpa_printf(MSG_ERROR, "Failed to initialize EAP-SIM "
1429 "database interface");
6fc6879b
JM
1430 goto fail;
1431 }
1432 }
95272a88 1433#endif /* EAP_SIM_DB */
6fc6879b 1434
6fc6879b
JM
1435 hapd->driver = hapd->iconf->driver;
1436
1437 return hapd;
1438
95272a88 1439#if defined(EAP_TLS_FUNCS) || defined(EAP_SIM_DB)
6fc6879b
JM
1440fail:
1441#endif
1442 /* TODO: cleanup allocated resources(?) */
1443 os_free(hapd);
1444 return NULL;
1445}
1446
1447
5c333467 1448void hostapd_interface_deinit(struct hostapd_iface *iface)
5fa30f32
JM
1449{
1450 size_t j;
1451
1452 if (iface == NULL)
1453 return;
1454
1455 hostapd_cleanup_iface_pre(iface);
1456 for (j = 0; j < iface->num_bss; j++) {
1457 struct hostapd_data *hapd = iface->bss[j];
1458 hostapd_free_stas(hapd);
1459 hostapd_flush_old_stations(hapd);
1460 hostapd_cleanup(hapd);
1461 if (j == iface->num_bss - 1 && hapd->driver)
1462 hostapd_driver_deinit(hapd);
1463 }
1464 for (j = 0; j < iface->num_bss; j++)
1465 os_free(iface->bss[j]);
1466 hostapd_cleanup_iface(iface);
1467}
fa16028d
JM
1468
1469
1470int hostapd_register_probereq_cb(struct hostapd_data *hapd,
1471 void (*cb)(void *ctx, const u8 *sa,
1472 const u8 *ie, size_t ie_len),
1473 void *ctx)
1474{
1475 struct hostapd_probereq_cb *n;
1476
1477 n = os_realloc(hapd->probereq_cb, (hapd->num_probereq_cb + 1) *
1478 sizeof(struct hostapd_probereq_cb));
1479 if (n == NULL)
1480 return -1;
1481
1482 hapd->probereq_cb = n;
1483 n = &hapd->probereq_cb[hapd->num_probereq_cb];
1484 hapd->num_probereq_cb++;
1485
1486 n->cb = cb;
1487 n->ctx = ctx;
1488
1489 return 0;
1490}
e3bd3912
JM
1491
1492
1493int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
1494 int enabled)
1495{
1496 struct wpa_bss_params params;
1497 os_memset(&params, 0, sizeof(params));
1498 params.ifname = ifname;
1499 params.enabled = enabled;
1500 return hostapd_set_ieee8021x(hapd, &params);
1501}