X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=wpa_supplicant%2Fwpa_supplicant.c;h=d62937b514fed7216d56eb15125a466bb035e9f5;hb=dff0f701d0f280f93c5c7698ef0f8e16dbbe815a;hp=8a6f95ee8e9f68eb2898f741373bd319c0c02f10;hpb=d7dcba70bc1f55474fd7869a54c324ec4ea0b41a;p=libeap.git diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 8a6f95e..d62937b 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1,6 +1,6 @@ /* * WPA Supplicant - * Copyright (c) 2003-2009, Jouni Malinen + * Copyright (c) 2003-2010, Jouni Malinen * * 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 @@ -45,10 +45,11 @@ #include "notify.h" #include "bgscan.h" #include "bss.h" +#include "scan.h" const char *wpa_supplicant_version = "wpa_supplicant v" VERSION_STR "\n" -"Copyright (c) 2003-2009, Jouni Malinen and contributors"; +"Copyright (c) 2003-2010, Jouni Malinen and contributors"; const char *wpa_supplicant_license = "This program is free software. You can distribute it and/or modify it\n" @@ -379,6 +380,9 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) wpa_s->ctrl_iface = NULL; } if (wpa_s->conf != NULL) { + struct wpa_ssid *ssid; + for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) + wpas_notify_network_removed(wpa_s, ssid); wpa_config_free(wpa_s->conf); wpa_s->conf = NULL; } @@ -397,8 +401,6 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) wpa_s->wpa = NULL; wpa_blacklist_clear(wpa_s); - wpa_scan_results_free(wpa_s->scan_res); - wpa_s->scan_res = NULL; wpa_bss_deinit(wpa_s); wpa_supplicant_cancel_scan(wpa_s); @@ -518,6 +520,8 @@ const char * wpa_supplicant_state_txt(enum wpa_states state) void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, enum wpa_states state) { + enum wpa_states old_state = wpa_s->wpa_state; + wpa_printf(MSG_DEBUG, "State: %s -> %s", wpa_supplicant_state_txt(wpa_s->wpa_state), wpa_supplicant_state_txt(state)); @@ -525,8 +529,6 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, if (state != WPA_SCANNING) wpa_supplicant_notify_scanning(wpa_s, 0); - wpas_notify_state_changed(wpa_s, state, wpa_s->wpa_state); - if (state == WPA_COMPLETED && wpa_s->new_connection) { #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) struct wpa_ssid *ssid = wpa_s->current_ssid; @@ -546,6 +548,9 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, wpa_drv_set_operstate(wpa_s, 0); } wpa_s->wpa_state = state; + + if (wpa_s->wpa_state != old_state) + wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state); } @@ -581,12 +586,15 @@ static void wpa_supplicant_terminate(int sig, void *signal_ctx) static void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s) { enum wpa_states old_state = wpa_s->wpa_state; + wpa_s->pairwise_cipher = 0; wpa_s->group_cipher = 0; wpa_s->mgmt_group_cipher = 0; wpa_s->key_mgmt = 0; wpa_s->wpa_state = WPA_DISCONNECTED; - wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state); + + if (wpa_s->wpa_state != old_state) + wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state); } @@ -761,7 +769,7 @@ static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s, #ifdef CONFIG_IEEE80211W if (!(ie->capabilities & WPA_CAPABILITY_MFPC) && - ssid->ieee80211w == IEEE80211W_REQUIRED) { + ssid->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) { wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP " "that does not support management frame protection - " "reject"); @@ -788,8 +796,7 @@ static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s, * available). */ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, - struct wpa_scan_res *bss, - struct wpa_ssid *ssid, + struct wpa_bss *bss, struct wpa_ssid *ssid, u8 *wpa_ie, size_t *wpa_ie_len) { struct wpa_ie_data ie; @@ -797,8 +804,8 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, const u8 *bss_wpa, *bss_rsn; if (bss) { - bss_wpa = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); - bss_rsn = wpa_scan_get_ie(bss, WLAN_EID_RSN); + bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); + bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); } else bss_wpa = bss_rsn = NULL; @@ -831,7 +838,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, ie.key_mgmt = ssid->key_mgmt; #ifdef CONFIG_IEEE80211W ie.mgmt_group_cipher = - ssid->ieee80211w != NO_IEEE80211W ? + ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ? WPA_CIPHER_AES_128_CMAC : 0; #endif /* CONFIG_IEEE80211W */ wpa_printf(MSG_DEBUG, "WPA: Set cipher suites based " @@ -938,7 +945,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, #ifdef CONFIG_IEEE80211W sel = ie.mgmt_group_cipher; - if (ssid->ieee80211w == NO_IEEE80211W || + if (ssid->ieee80211w == NO_MGMT_FRAME_PROTECTION || !(ie.capabilities & WPA_CAPABILITY_MFPC)) sel = 0; if (sel & WPA_CIPHER_AES_128_CMAC) { @@ -977,12 +984,12 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, * This function is used to request %wpa_supplicant to associate with a BSS. */ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, - struct wpa_scan_res *bss, struct wpa_ssid *ssid) + struct wpa_bss *bss, struct wpa_ssid *ssid) { u8 wpa_ie[80]; size_t wpa_ie_len; int use_crypt, ret, i, bssid_changed; - int algs = AUTH_ALG_OPEN_SYSTEM; + int algs = WPA_AUTH_ALG_OPEN; enum wpa_cipher cipher_pairwise, cipher_group; struct wpa_driver_associate_params params; int wep_keys_set = 0; @@ -998,6 +1005,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, return; } wpa_supplicant_create_ap(wpa_s, ssid); + wpa_s->current_bss = bss; #else /* CONFIG_AP */ wpa_printf(MSG_ERROR, "AP mode support not included in the " "build"); @@ -1014,19 +1022,18 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, wpa_s->reassociate = 0; if (bss) { #ifdef CONFIG_IEEE80211R - const u8 *md = NULL; + const u8 *ie, *md = NULL; #endif /* CONFIG_IEEE80211R */ - const u8 *ie = wpa_scan_get_ie(bss, WLAN_EID_SSID); wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid), - ie ? wpa_ssid_txt(ie + 2, ie[1]) : "", bss->freq); + wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq); bssid_changed = !is_zero_ether_addr(wpa_s->bssid); os_memset(wpa_s->bssid, 0, ETH_ALEN); os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN); if (bssid_changed) wpas_notify_bssid_changed(wpa_s); #ifdef CONFIG_IEEE80211R - ie = wpa_scan_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN); + ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN); if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN) md = ie + 2; wpa_sm_set_ft_params(wpa_s->wpa, md, NULL, 0, NULL); @@ -1061,27 +1068,21 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) { if (ssid->leap) { if (ssid->non_leap == 0) - algs = AUTH_ALG_LEAP; + algs = WPA_AUTH_ALG_LEAP; else - algs |= AUTH_ALG_LEAP; + algs |= WPA_AUTH_ALG_LEAP; } } #endif /* IEEE8021X_EAPOL */ wpa_printf(MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs); if (ssid->auth_alg) { - algs = 0; - if (ssid->auth_alg & WPA_AUTH_ALG_OPEN) - algs |= AUTH_ALG_OPEN_SYSTEM; - if (ssid->auth_alg & WPA_AUTH_ALG_SHARED) - algs |= AUTH_ALG_SHARED_KEY; - if (ssid->auth_alg & WPA_AUTH_ALG_LEAP) - algs |= AUTH_ALG_LEAP; + algs = ssid->auth_alg; wpa_printf(MSG_DEBUG, "Overriding auth_alg selection: 0x%x", algs); } - if (bss && (wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) || - wpa_scan_get_ie(bss, WLAN_EID_RSN)) && + if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) || + wpa_bss_get_ie(bss, WLAN_EID_RSN)) && (ssid->key_mgmt & (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_FT_PSK | @@ -1171,10 +1172,9 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING); os_memset(¶ms, 0, sizeof(params)); if (bss) { - const u8 *ie = wpa_scan_get_ie(bss, WLAN_EID_SSID); params.bssid = bss->bssid; - params.ssid = ie ? ie + 2 : (u8 *) ""; - params.ssid_len = ie ? ie[1] : 0; + params.ssid = bss->ssid; + params.ssid_len = bss->ssid_len; params.freq = bss->freq; } else { params.ssid = ssid->ssid; @@ -1208,19 +1208,9 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, params.drop_unencrypted = use_crypt; #ifdef CONFIG_IEEE80211W - switch (ssid->ieee80211w) { - case NO_IEEE80211W: - params.mgmt_frame_protection = NO_MGMT_FRAME_PROTECTION; - break; - case IEEE80211W_OPTIONAL: - params.mgmt_frame_protection = MGMT_FRAME_PROTECTION_OPTIONAL; - break; - case IEEE80211W_REQUIRED: - 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); + params.mgmt_frame_protection = ssid->ieee80211w; + if (ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION && bss) { + const u8 *rsn = wpa_bss_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 & @@ -1293,6 +1283,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, } old_ssid = wpa_s->current_ssid; wpa_s->current_ssid = ssid; + wpa_s->current_bss = bss; wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid); wpa_supplicant_initiate_eapol(wpa_s); if (old_ssid != wpa_s->current_ssid) @@ -1325,6 +1316,7 @@ void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s, wpa_supplicant_mark_disassoc(wpa_s); old_ssid = wpa_s->current_ssid; wpa_s->current_ssid = NULL; + wpa_s->current_bss = NULL; wpa_sm_set_config(wpa_s->wpa, NULL); eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); if (old_ssid != wpa_s->current_ssid) @@ -1358,6 +1350,7 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s, wpa_supplicant_mark_disassoc(wpa_s); old_ssid = wpa_s->current_ssid; wpa_s->current_ssid = NULL; + wpa_s->current_bss = NULL; wpa_sm_set_config(wpa_s->wpa, NULL); eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); if (old_ssid != wpa_s->current_ssid) @@ -1553,43 +1546,12 @@ int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level, wpa_debug_timestamp = debug_timestamp ? 1 : 0; wpa_debug_show_keys = debug_show_keys ? 1 : 0; - if (wpa_debug_level != old_level || - wpa_debug_timestamp != old_timestamp || - wpa_debug_show_keys != old_show_keys) - wpas_notify_debug_params_changed(global); - - return 0; -} - - -/** - * wpa_supplicant_get_scan_results - Get scan results - * @wpa_s: Pointer to wpa_supplicant data - * Returns: 0 on success, -1 on failure - * - * This function request the current scan results from the driver and updates - * the local BSS list wpa_s->bss. - */ -int wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s) -{ - size_t i; - - wpa_scan_results_free(wpa_s->scan_res); - if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) - wpa_s->scan_res = ieee80211_sta_get_scan_results(wpa_s); - else - wpa_s->scan_res = wpa_drv_get_scan_results2(wpa_s); - if (wpa_s->scan_res == NULL) { - wpa_printf(MSG_DEBUG, "Failed to get scan results"); - return -1; - } - - wpa_scan_sort_results(wpa_s->scan_res); - - wpa_bss_update_start(wpa_s); - for (i = 0; i < wpa_s->scan_res->num; i++) - wpa_bss_update_scan_res(wpa_s, wpa_s->scan_res->res[i]); - wpa_bss_update_end(wpa_s); + if (wpa_debug_level != old_level) + wpas_notify_debug_level_changed(global); + if (wpa_debug_timestamp != old_timestamp) + wpas_notify_debug_timestamp_changed(global); + if (wpa_debug_show_keys != old_show_keys) + wpas_notify_debug_show_keys_changed(global); return 0; } @@ -1701,6 +1663,20 @@ static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s, } +/** + * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant + * @ctx: Context pointer (wpa_s); this is the ctx variable registered + * with struct wpa_driver_ops::init() + * @src_addr: Source address of the EAPOL frame + * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header) + * @len: Length of the EAPOL data + * + * This function is called for each received EAPOL frame. Most driver + * interfaces rely on more generic OS mechanism for receiving frames through + * l2_packet, but if such a mechanism is not available, the driver wrapper may + * take care of received EAPOL frames and deliver them to the core supplicant + * code by calling this function. + */ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) { @@ -1798,14 +1774,6 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, } -void wpa_supplicant_sta_rx(void *ctx, const u8 *buf, size_t len, - struct ieee80211_rx_status *rx_status) -{ - struct wpa_supplicant *wpa_s = ctx; - ieee80211_sta_rx(wpa_s, buf, len, rx_status); -} - - /** * wpa_supplicant_driver_init - Initialize driver interface parameters * @wpa_s: Pointer to wpa_supplicant data @@ -2112,11 +2080,11 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s, wpa_clear_keys(wpa_s, NULL); } + wpa_supplicant_cleanup(wpa_s); + if (notify) wpas_notify_iface_removed(wpa_s); - wpa_supplicant_cleanup(wpa_s); - if (wpa_s->drv_priv) wpa_drv_deinit(wpa_s); } @@ -2139,6 +2107,7 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global, { struct wpa_supplicant *wpa_s; struct wpa_interface t_iface; + struct wpa_ssid *ssid; if (global == NULL || iface == NULL) return NULL; @@ -2179,6 +2148,9 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global, return NULL; } + for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) + wpas_notify_network_added(wpa_s, ssid); + wpa_s->next = global->ifaces; global->ifaces = wpa_s;