/*
* WPA Supplicant
- * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include "common.h"
#include "eapol_supp/eapol_supp_sm.h"
#include "eap_peer/eap.h"
+#include "eap_server/eap_methods.h"
#include "wpa.h"
#include "eloop.h"
-#include "drivers/driver.h"
#include "config.h"
#include "l2_packet/l2_packet.h"
#include "wpa_supplicant_i.h"
+#include "driver_i.h"
#include "ctrl_iface.h"
#include "ctrl_iface_dbus.h"
#include "pcsc_funcs.h"
#include "ieee802_11_defs.h"
#include "blacklist.h"
#include "wpas_glue.h"
+#include "wps_supplicant.h"
+#include "ibss_rsn.h"
+#include "sme.h"
+#include "ap.h"
const char *wpa_supplicant_version =
"wpa_supplicant v" VERSION_STR "\n"
-"Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> and contributors";
+"Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi> and contributors";
const char *wpa_supplicant_license =
"This program is free software. You can distribute it and/or modify it\n"
"\n";
#endif /* CONFIG_NO_STDOUT_DEBUG */
-extern struct wpa_driver_ops *wpa_supplicant_drivers[];
-
extern int wpa_debug_level;
extern int wpa_debug_show_keys;
extern int wpa_debug_timestamp;
+extern struct wpa_driver_ops *wpa_drivers[];
/* Configure default/group WEP keys for static WEP */
static int wpa_set_wep_keys(struct wpa_supplicant *wpa_s,
int sec, int usec)
{
if (wpa_s->conf && wpa_s->conf->ap_scan == 0 &&
- wpa_s->driver && IS_WIRED(wpa_s->driver))
+ (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
return;
wpa_msg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec "
struct eapol_config eapol_conf;
struct wpa_ssid *ssid = wpa_s->current_ssid;
- if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
- eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
+#ifdef CONFIG_IBSS_RSN
+ if (ssid->mode == IEEE80211_MODE_IBSS &&
+ wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
+ wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
+ /*
+ * RSN IBSS authentication is per-STA and we can disable the
+ * per-BSSID EAPOL authentication.
+ */
+ eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
+ eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
+ return;
}
+#endif /* CONFIG_IBSS_RSN */
+
+ eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
+ eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
+
if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
EAPOL_REQUIRE_KEY_BROADCAST;
}
- if (wpa_s->conf && wpa_s->driver && IS_WIRED(wpa_s->driver)) {
+ if (wpa_s->conf && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
eapol_conf.required_keys = 0;
- }
}
if (wpa_s->conf)
eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
eapol_conf.workaround = ssid->eap_workaround;
eapol_conf.eap_disabled =
!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
- wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA;
+ wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
+ wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
#endif /* IEEE8021X_EAPOL */
}
{
int i;
- if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)
+ if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
+ wpa_s->key_mgmt = WPA_KEY_MGMT_WPS;
+ else if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)
wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
else
wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
wpa_supplicant_cancel_auth_timeout(wpa_s);
ieee80211_sta_deinit(wpa_s);
+
+ wpas_wps_deinit(wpa_s);
+
+#ifdef CONFIG_IBSS_RSN
+ ibss_rsn_deinit(wpa_s->ibss_rsn);
+ wpa_s->ibss_rsn = NULL;
+#endif /* CONFIG_IBSS_RSN */
+
+#ifdef CONFIG_SME
+ os_free(wpa_s->sme.ft_ies);
+ wpa_s->sme.ft_ies = NULL;
+ wpa_s->sme.ft_ies_len = 0;
+#endif /* CONFIG_SME */
+
+#ifdef CONFIG_AP
+ wpa_supplicant_ap_deinit(wpa_s);
+#endif /* CONFIG_AP */
}
return "INACTIVE";
case WPA_SCANNING:
return "SCANNING";
+ case WPA_AUTHENTICATING:
+ return "AUTHENTICATING";
case WPA_ASSOCIATING:
return "ASSOCIATING";
case WPA_ASSOCIATED:
wpa_supplicant_state_txt(wpa_s->wpa_state),
wpa_supplicant_state_txt(state));
+ if (state != WPA_SCANNING)
+ wpa_supplicant_notify_scanning(wpa_s, 0);
+
wpa_supplicant_dbus_notify_state_change(wpa_s, state,
wpa_s->wpa_state);
return KEY_MGMT_802_1X_SHA256;
case WPA_KEY_MGMT_PSK_SHA256:
return KEY_MGMT_PSK_SHA256;
+ case WPA_KEY_MGMT_WPS:
+ return KEY_MGMT_WPS;
case WPA_KEY_MGMT_PSK:
default:
return KEY_MGMT_PSK;
struct wpa_driver_capa capa;
int assoc_failed = 0;
+ if (ssid->mode == 2) {
+#ifdef CONFIG_AP
+ if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
+ wpa_printf(MSG_INFO, "Driver does not support AP "
+ "mode");
+ return;
+ }
+ wpa_supplicant_create_ap(wpa_s, ssid);
+#else /* CONFIG_AP */
+ wpa_printf(MSG_ERROR, "AP mode support not included in the "
+ "build");
+#endif /* CONFIG_AP */
+ return;
+ }
+
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) {
+ sme_authenticate(wpa_s, bss, ssid);
+ return;
+ }
+
wpa_s->reassociate = 0;
if (bss) {
#ifdef CONFIG_IEEE80211R
wpa_ft_prepare_auth_request(wpa_s->wpa);
}
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_WPS
+ } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
+ wpa_s->conf->ap_scan == 2 &&
+ (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
+ /* Use ap_scan==1 style network selection to find the network
+ */
+ wpa_s->scan_req = 2;
+ wpa_s->reassociate = 1;
+ wpa_supplicant_req_scan(wpa_s, 0, 0);
+ return;
+#endif /* CONFIG_WPS */
} else {
wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
"results)");
return;
}
+#ifdef CONFIG_WPS
+ } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
+ struct wpabuf *wps_ie;
+ wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
+ if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
+ wpa_ie_len = wpabuf_len(wps_ie);
+ os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
+ } else
+ wpa_ie_len = 0;
+ wpabuf_free(wps_ie);
+ wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
+#endif /* CONFIG_WPS */
} else {
wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
wpa_ie_len = 0;
wep_keys_set = 1;
}
}
+ if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
+ use_crypt = 0;
#ifdef IEEE8021X_EAPOL
if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
}
params.wep_tx_keyidx = ssid->wep_tx_keyidx;
- if (wpa_s->driver_4way_handshake &&
+ if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
(params.key_mgmt_suite == KEY_MGMT_PSK ||
params.key_mgmt_suite == KEY_MGMT_FT_PSK)) {
params.passphrase = ssid->passphrase;
params.psk = ssid->psk;
}
+ params.drop_unencrypted = use_crypt;
+
#ifdef CONFIG_IEEE80211W
switch (ssid->ieee80211w) {
case NO_IEEE80211W:
params.mgmt_frame_protection = MGMT_FRAME_PROTECTION_REQUIRED;
break;
}
+ if (ssid->ieee80211w != NO_IEEE80211W && bss) {
+ const u8 *rsn = wpa_scan_get_ie(bss, WLAN_EID_RSN);
+ struct wpa_ie_data ie;
+ if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
+ ie.capabilities &
+ (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
+ wpa_printf(MSG_DEBUG, "WPA: Selected AP supports MFP: "
+ "require MFP");
+ params.mgmt_frame_protection =
+ MGMT_FRAME_PROTECTION_REQUIRED;
+ }
+ }
#endif /* CONFIG_IEEE80211W */
- if (wpa_s->use_client_mlme)
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
ret = ieee80211_sta_associate(wpa_s, ¶ms);
else
ret = wpa_drv_associate(wpa_s, ¶ms);
* management. */
wpa_supplicant_cancel_auth_timeout(wpa_s);
wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+#ifdef CONFIG_IBSS_RSN
+ } else if (ssid->mode == IEEE80211_MODE_IBSS &&
+ wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
+ wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
+ ibss_rsn_set_psk(wpa_s->ibss_rsn, ssid->psk);
+ /*
+ * RSN IBSS authentication is per-STA and we can disable the
+ * per-BSSID authentication.
+ */
+ wpa_supplicant_cancel_auth_timeout(wpa_s);
+ wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+#endif /* CONFIG_IBSS_RSN */
} else {
/* Timeout for IEEE 802.11 authentication and association */
int timeout = 60;
{
u8 *addr = NULL;
if (!is_zero_ether_addr(wpa_s->bssid)) {
- if (wpa_s->use_client_mlme)
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
ieee80211_sta_disassociate(wpa_s, reason_code);
else
wpa_drv_disassociate(wpa_s, wpa_s->bssid, reason_code);
* @wpa_s: Pointer to wpa_supplicant data
* @reason_code: IEEE 802.11 reason code for the deauthenticate frame
*
- * This function is used to request %wpa_supplicant to disassociate with the
+ * This function is used to request %wpa_supplicant to deauthenticate from the
* current AP.
*/
void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
int reason_code)
{
u8 *addr = NULL;
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
if (!is_zero_ether_addr(wpa_s->bssid)) {
- if (wpa_s->use_client_mlme)
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
ieee80211_sta_deauthenticate(wpa_s, reason_code);
else
wpa_drv_deauthenticate(wpa_s, wpa_s->bssid,
addr = wpa_s->bssid;
}
wpa_clear_keys(wpa_s, addr);
+ wpa_supplicant_mark_disassoc(wpa_s);
wpa_s->current_ssid = NULL;
wpa_sm_set_config(wpa_s->wpa, NULL);
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
- eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
- eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
}
{
int ret;
- if (wpa_s->use_client_mlme) {
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) {
wpa_scan_results_free(wpa_s->scan_res);
wpa_s->scan_res = ieee80211_sta_get_scan_results(wpa_s);
if (wpa_s->scan_res == NULL) {
u8 bssid[ETH_ALEN];
int wired;
- if (wpa_s->use_client_mlme) {
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) {
if (ieee80211_sta_get_ssid(wpa_s, ssid, &ssid_len)) {
wpa_printf(MSG_WARNING, "Could not read SSID from "
"MLME.");
ssid_len = res;
}
- if (wpa_s->use_client_mlme)
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
os_memcpy(bssid, wpa_s->bssid, ETH_ALEN);
else if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
wpa_printf(MSG_WARNING, "Could not read BSSID from driver.");
return NULL;
}
- wired = wpa_s->conf->ap_scan == 0 && wpa_s->driver &&
- IS_WIRED(wpa_s->driver);
+ wired = wpa_s->conf->ap_scan == 0 &&
+ (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
entry = wpa_s->conf->ssid;
while (entry) {
(!entry->bssid_set ||
os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
return entry;
+#ifdef CONFIG_WPS
+ if (!entry->disabled &&
+ (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
+ (entry->ssid == NULL || entry->ssid_len == 0) &&
+ (!entry->bssid_set ||
+ os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
+ return entry;
+#endif /* CONFIG_WPS */
entry = entry->next;
}
const char *name)
{
int i;
+ size_t len;
+ const char *pos;
if (wpa_s == NULL)
return -1;
- if (wpa_supplicant_drivers[0] == NULL) {
+ if (wpa_drivers[0] == NULL) {
wpa_printf(MSG_ERROR, "No driver interfaces build into "
"wpa_supplicant.");
return -1;
if (name == NULL) {
/* default to first driver in the list */
- wpa_s->driver = wpa_supplicant_drivers[0];
+ wpa_s->driver = wpa_drivers[0];
return 0;
}
- for (i = 0; wpa_supplicant_drivers[i]; i++) {
- if (os_strcmp(name, wpa_supplicant_drivers[i]->name) == 0) {
- wpa_s->driver = wpa_supplicant_drivers[i];
+ pos = os_strchr(name, ',');
+ if (pos)
+ len = pos - name;
+ else
+ len = os_strlen(name);
+ for (i = 0; wpa_drivers[i]; i++) {
+ if (os_strlen(wpa_drivers[i]->name) == len &&
+ os_strncmp(name, wpa_drivers[i]->name, len) ==
+ 0) {
+ wpa_s->driver = wpa_drivers[i];
return 0;
}
}
- wpa_printf(MSG_ERROR, "Unsupported driver '%s'.\n", name);
+ wpa_printf(MSG_ERROR, "Unsupported driver '%s'.", name);
return -1;
}
wpa_printf(MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
+#ifdef CONFIG_AP
+ if (wpa_s->ap_iface) {
+ wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
+ return;
+ }
+#endif /* CONFIG_AP */
+
if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
wpa_printf(MSG_DEBUG, "Ignored received EAPOL frame since "
"no key management is configured");
}
if (wpa_s->eapol_received == 0 &&
- (!wpa_s->driver_4way_handshake ||
+ (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
wpa_s->wpa_state != WPA_COMPLETED)) {
/* Timeout for completing IEEE 802.1X and WPA authentication */
wpa_supplicant_req_auth_timeout(
wpa_s,
(wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) ?
+ wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
+ wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) ?
70 : 10, 0);
}
wpa_s->eapol_received++;
return;
}
+#ifdef CONFIG_IBSS_RSN
+ if (wpa_s->current_ssid &&
+ wpa_s->current_ssid->mode == IEEE80211_MODE_IBSS) {
+ ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
+ return;
+ }
+#endif /* CONFIG_IBSS_RSN */
+
/* Source address of the incoming EAPOL frame could be compared to the
* current BSSID. However, it is possible that a centralized
* Authenticator could be using another MAC address than the BSSID of
eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
return;
wpa_drv_poll(wpa_s);
- if (!wpa_s->driver_4way_handshake)
+ if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
/*
}
-void wpa_supplicant_sta_free_hw_features(struct wpa_hw_modes *hw_features,
- size_t num_hw_features)
-{
- ieee80211_sta_free_hw_features(hw_features, num_hw_features);
-}
-
-
void wpa_supplicant_sta_rx(void *ctx, const u8 *buf, size_t len,
struct ieee80211_rx_status *rx_status)
{
wpa_printf(MSG_DEBUG, "RSN: flushing PMKID list in the driver");
wpa_drv_flush_pmkid(wpa_s);
- wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
+ wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
wpa_supplicant_req_scan(wpa_s, interface_count, 100000);
interface_count++;
static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
struct wpa_interface *iface)
{
+ const char *ifname, *driver;
+ struct wpa_driver_capa capa;
+
wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
"'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
iface->confname ? iface->confname : "N/A",
iface->ctrl_interface ? iface->ctrl_interface : "N/A",
iface->bridge_ifname ? iface->bridge_ifname : "N/A");
- if (wpa_supplicant_set_driver(wpa_s, iface->driver) < 0) {
- return -1;
- }
-
if (iface->confname) {
#ifdef CONFIG_BACKEND_FILE
wpa_s->confname = os_rel2abs_path(iface->confname);
sizeof(wpa_s->bridge_ifname));
}
- return 0;
-}
-
-
-static int wpa_supplicant_init_iface2(struct wpa_supplicant *wpa_s)
-{
- const char *ifname;
- struct wpa_driver_capa capa;
-
- wpa_printf(MSG_DEBUG, "Initializing interface (2) '%s'",
- wpa_s->ifname);
-
/* RSNA Supplicant Key Management - INITIALIZE */
eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
* L2 receive handler so that association events are processed before
* EAPOL-Key packets if both become available for the same select()
* call. */
+ driver = iface->driver;
+next_driver:
+ if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
+ return -1;
+
wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
if (wpa_s->drv_priv == NULL) {
+ const char *pos;
+ pos = os_strchr(driver, ',');
+ if (pos) {
+ wpa_printf(MSG_DEBUG, "Failed to initialize driver "
+ "interface - try next driver wrapper");
+ driver = pos + 1;
+ goto next_driver;
+ }
wpa_printf(MSG_ERROR, "Failed to initialize driver interface");
return -1;
}
if (wpa_supplicant_driver_init(wpa_s) < 0)
return -1;
+ if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
+ wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
+ wpa_printf(MSG_DEBUG, "Failed to set country");
+ return -1;
+ }
+
wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
+ if (wpas_wps_init(wpa_s))
+ return -1;
+
if (wpa_supplicant_init_eapol(wpa_s) < 0)
return -1;
wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
}
if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
+ wpa_s->drv_flags = capa.flags;
if (capa.flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) {
- wpa_s->use_client_mlme = 1;
if (ieee80211_sta_init(wpa_s))
return -1;
}
- if (capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)
- wpa_s->driver_4way_handshake = 1;
+ wpa_s->max_scan_ssids = capa.max_scan_ssids;
+ }
+
+#ifdef CONFIG_IBSS_RSN
+ wpa_s->ibss_rsn = ibss_rsn_init(wpa_s);
+ if (!wpa_s->ibss_rsn) {
+ wpa_printf(MSG_DEBUG, "Failed to init IBSS RSN");
+ return -1;
}
+#endif /* CONFIG_IBSS_RSN */
return 0;
}
if (wpa_s == NULL)
return NULL;
- if (wpa_supplicant_init_iface(wpa_s, iface) ||
- wpa_supplicant_init_iface2(wpa_s)) {
+ if (wpa_supplicant_init_iface(wpa_s, iface)) {
wpa_printf(MSG_DEBUG, "Failed to add interface %s",
iface->ifname);
wpa_supplicant_deinit_iface(wpa_s);
struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
{
struct wpa_global *global;
- int ret;
+ int ret, i;
if (params == NULL)
return NULL;
wpa_debug_open_file(params->wpa_debug_file_path);
+ if (params->wpa_debug_syslog)
+ wpa_debug_open_syslog();
ret = eap_peer_register_methods();
if (ret) {
return NULL;
}
+#ifdef CONFIG_AP
+ ret = eap_server_register_methods();
+ if (ret) {
+ wpa_printf(MSG_ERROR, "Failed to register EAP server methods");
+ if (ret == -2)
+ wpa_printf(MSG_ERROR, "Two or more EAP methods used "
+ "the same EAP type.");
+ return NULL;
+ }
+#endif /* CONFIG_AP */
+
global = os_zalloc(sizeof(*global));
if (global == NULL)
return NULL;
}
}
+ for (i = 0; wpa_drivers[i]; i++)
+ global->drv_count++;
+ if (global->drv_count == 0) {
+ wpa_printf(MSG_ERROR, "No drivers enabled");
+ wpa_supplicant_deinit(global);
+ return NULL;
+ }
+ global->drv_priv = os_zalloc(global->drv_count * sizeof(void *));
+ if (global->drv_priv == NULL) {
+ wpa_supplicant_deinit(global);
+ return NULL;
+ }
+ for (i = 0; wpa_drivers[i]; i++) {
+ if (!wpa_drivers[i]->global_init)
+ continue;
+ global->drv_priv[i] = wpa_drivers[i]->global_init();
+ if (global->drv_priv[i] == NULL) {
+ wpa_printf(MSG_ERROR, "Failed to initialize driver "
+ "'%s'", wpa_drivers[i]->name);
+ wpa_supplicant_deinit(global);
+ return NULL;
+ }
+ }
+
return global;
}
*/
void wpa_supplicant_deinit(struct wpa_global *global)
{
+ int i;
+
if (global == NULL)
return;
wpa_supplicant_dbus_ctrl_iface_deinit(global->dbus_ctrl_iface);
eap_peer_unregister_methods();
+#ifdef CONFIG_AP
+ eap_server_unregister_methods();
+#endif /* CONFIG_AP */
+
+ for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
+ if (!global->drv_priv[i])
+ continue;
+ wpa_drivers[i]->global_deinit(global->drv_priv[i]);
+ }
+ os_free(global->drv_priv);
eloop_destroy();
os_free(global->params.ctrl_interface);
os_free(global);
+ wpa_debug_close_syslog();
wpa_debug_close_file();
}