📄 wpa_supplicant.c
字号:
wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'", wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); } wpa_supplicant_cancel_scan(wpa_s); /* Starting new association, so clear the possibly used WPA IE from the * previous association. */ wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);#ifdef IEEE8021X_EAPOL if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) { if (ssid->leap) { if (ssid->non_leap == 0) algs = AUTH_ALG_LEAP; else algs |= 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; wpa_printf(MSG_DEBUG, "Overriding auth_alg selection: 0x%x", algs); } wpa_drv_set_auth_alg(wpa_s, algs); if (bss && (bss->wpa_ie_len || bss->rsn_ie_len) && (ssid->key_mgmt & (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK))) { int try_opportunistic; try_opportunistic = ssid->proactive_key_caching && (ssid->proto & WPA_PROTO_RSN); if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, wpa_s->current_ssid, try_opportunistic) == 0) eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1); wpa_ie_len = sizeof(wpa_ie); if (wpa_supplicant_set_suites(wpa_s, bss, ssid, wpa_ie, &wpa_ie_len)) { wpa_printf(MSG_WARNING, "WPA: Failed to set WPA key " "management and encryption suites"); return; } } else if (ssid->key_mgmt & (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_WPA_NONE)) { wpa_ie_len = sizeof(wpa_ie); if (wpa_supplicant_set_suites(wpa_s, NULL, ssid, wpa_ie, &wpa_ie_len)) { wpa_printf(MSG_WARNING, "WPA: Failed to set WPA key " "management and encryption suites (no scan " "results)"); return; } } else { wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); wpa_ie_len = 0; } wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL); use_crypt = 1; cipher_pairwise = cipher_suite2driver(wpa_s->pairwise_cipher); cipher_group = cipher_suite2driver(wpa_s->group_cipher); if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE || wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) { if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) use_crypt = 0; for (i = 0; i < NUM_WEP_KEYS; i++) { if (ssid->wep_key_len[i]) { use_crypt = 1; wep_keys_set = 1; wpa_set_wep_key(wpa_s, i == ssid->wep_tx_keyidx, i, ssid->wep_key[i], ssid->wep_key_len[i]); } } }#ifdef IEEE8021X_EAPOL if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) { if ((ssid->eapol_flags & (EAPOL_FLAG_REQUIRE_KEY_UNICAST | EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 && !wep_keys_set) { use_crypt = 0; } else { /* Assume that dynamic WEP-104 keys will be used and * set cipher suites in order for drivers to expect * encryption. */ cipher_pairwise = cipher_group = CIPHER_WEP104; } }#endif /* IEEE8021X_EAPOL */ if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { /* Set the key before (and later after) association */ wpa_supplicant_set_wpa_none_key(wpa_s, ssid); } wpa_drv_set_drop_unencrypted(wpa_s, use_crypt); wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING); os_memset(¶ms, 0, sizeof(params)); if (bss) { params.bssid = bss->bssid; params.ssid = bss->ssid; params.ssid_len = bss->ssid_len; params.freq = bss->freq; } else { params.ssid = ssid->ssid; params.ssid_len = ssid->ssid_len; } if (ssid->mode == 1 && ssid->frequency > 0 && params.freq == 0) params.freq = ssid->frequency; /* Initial channel for IBSS */ params.wpa_ie = wpa_ie; params.wpa_ie_len = wpa_ie_len; params.pairwise_suite = cipher_pairwise; params.group_suite = cipher_group; params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt); params.auth_alg = algs; params.mode = ssid->mode; for (i = 0; i < NUM_WEP_KEYS; i++) { if (ssid->wep_key_len[i]) params.wep_key[i] = ssid->wep_key[i]; params.wep_key_len[i] = ssid->wep_key_len[i]; } params.wep_tx_keyidx = ssid->wep_tx_keyidx;#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; }#endif /* CONFIG_IEEE80211W */ if (wpa_s->use_client_mlme) ret = ieee80211_sta_associate(wpa_s, ¶ms); else ret = wpa_drv_associate(wpa_s, ¶ms); if (ret < 0) { wpa_msg(wpa_s, MSG_INFO, "Association request to the driver " "failed"); /* try to continue anyway; new association will be tried again * after timeout */ assoc_failed = 1; } if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { /* Set the key after the association just in case association * cleared the previously configured key. */ wpa_supplicant_set_wpa_none_key(wpa_s, ssid); /* No need to timeout authentication since there is no key * management. */ wpa_supplicant_cancel_auth_timeout(wpa_s); wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); } else { /* Timeout for IEEE 802.11 authentication and association */ int timeout; if (assoc_failed) timeout = 5; else if (wpa_s->conf->ap_scan == 1) timeout = 10; else timeout = 60; wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0); } if (wep_keys_set && wpa_drv_get_capa(wpa_s, &capa) == 0 && capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC) { /* Set static WEP keys again */ int j; for (j = 0; j < NUM_WEP_KEYS; j++) { if (ssid->wep_key_len[j]) { wpa_set_wep_key(wpa_s, j == ssid->wep_tx_keyidx, j, ssid->wep_key[j], ssid->wep_key_len[j]); } } } if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) { /* * Do not allow EAP session resumption between different * network configurations. */ eapol_sm_invalidate_cached_session(wpa_s->eapol); } wpa_s->current_ssid = ssid; wpa_sm_set_config(wpa_s->wpa, wpa_s->current_ssid); wpa_supplicant_initiate_eapol(wpa_s);}/** * wpa_supplicant_disassociate - Disassociate the current connection * @wpa_s: Pointer to wpa_supplicant data * @reason_code: IEEE 802.11 reason code for the disassociate frame * * This function is used to request %wpa_supplicant to disassociate with the * current AP. */void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s, int reason_code){ u8 *addr = NULL; if (os_memcmp(wpa_s->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) != 0) { if (wpa_s->use_client_mlme) ieee80211_sta_disassociate(wpa_s, reason_code); else wpa_drv_disassociate(wpa_s, wpa_s->bssid, reason_code); 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);}/** * wpa_supplicant_deauthenticate - Deauthenticate the current connection * @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 * 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 (os_memcmp(wpa_s->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) != 0) { if (wpa_s->use_client_mlme) ieee80211_sta_deauthenticate(wpa_s, reason_code); else wpa_drv_deauthenticate(wpa_s, wpa_s->bssid, reason_code); addr = wpa_s->bssid; } wpa_clear_keys(wpa_s, addr); 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);}/** * wpa_supplicant_get_scan_results - Get scan results * @wpa_s: Pointer to wpa_supplicant data * Returns: 0 on success, -1 on failure * * This function is request the current scan results from the driver and stores * a local copy of the results in wpa_s->scan_results. */int wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s){#define SCAN_AP_LIMIT 128 struct wpa_scan_result *results, *tmp; int num; results = os_malloc(SCAN_AP_LIMIT * sizeof(struct wpa_scan_result)); if (results == NULL) { wpa_printf(MSG_WARNING, "Failed to allocate memory for scan " "results"); return -1; } if (wpa_s->use_client_mlme) { num = ieee80211_sta_get_scan_results(wpa_s, results, SCAN_AP_LIMIT); } else num = wpa_drv_get_scan_results(wpa_s, results, SCAN_AP_LIMIT); wpa_printf(MSG_DEBUG, "Scan results: %d", num); if (num < 0) { wpa_printf(MSG_DEBUG, "Failed to get scan results"); os_free(results); return -1; } if (num > SCAN_AP_LIMIT) { wpa_printf(MSG_INFO, "Not enough room for all APs (%d < %d)", num, SCAN_AP_LIMIT); num = SCAN_AP_LIMIT; } /* Free unneeded memory for unused scan result entries */ tmp = os_realloc(results, num * sizeof(struct wpa_scan_result)); if (tmp || num == 0) { results = tmp; } os_free(wpa_s->scan_results); wpa_s->scan_results = results; wpa_s->num_scan_results = num; return 0;}#ifndef CONFIG_NO_WPAstatic int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s){ int i, ret = 0; struct wpa_scan_result *results, *curr = NULL; results = wpa_s->scan_results; if (results == NULL) { return -1; } for (i = 0; i < wpa_s->num_scan_results; i++) { struct wpa_ssid *ssid = wpa_s->current_ssid; if (os_memcmp(results[i].bssid, wpa_s->bssid, ETH_ALEN) != 0) continue; if (ssid == NULL || ((results[i].ssid_len == ssid->ssid_len && os_memcmp(results[i].ssid, ssid->ssid, ssid->ssid_len) == 0) || ssid->ssid_len == 0)) { curr = &results[i]; break; } } if (curr) { if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, curr->wpa_ie, curr->wpa_ie_len) || wpa_sm_set_ap_rsn_ie(wpa_s->wpa, curr->rsn_ie, curr->rsn_ie_len)) ret = -1; } else { ret = -1; } return ret;}static int wpa_supplicant_get_beacon_ie(void *ctx){ struct wpa_supplicant *wpa_s = ctx; if (wpa_get_beacon_ie(wpa_s) == 0) { return 0; } /* No WPA/RSN IE found in the cached scan results. Try to get updated * scan results from the driver. */ if (wpa_supplicant_get_scan_results(wpa_s) < 0) { return -1; } return wpa_get_beacon_ie(wpa_s);}#endif /* CONFIG_NO_WPA *//** * wpa_supplicant_get_ssid - Get a pointer to the current network structure * @wpa_s: Pointer to wpa_supplicant data * Returns: A pointer to the current network structure or %NULL on failure */struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s){ struct wpa_ssid *entry; u8 ssid[MAX_SSID_LEN]; int res; size_t ssid_len; u8 bssid[ETH_ALEN]; int wired; if (wpa_s->use_client_mlme) { if (ieee80211_sta_get_ssid(wpa_s, ssid, &ssid_len)) { wpa_printf(MSG_WARNING, "Could not read SSID from " "MLME."); return NULL; } } else { res = wpa_drv_get_ssid(wpa_s, ssid); if (res < 0) { wpa_printf(MSG_WARNING, "Could not read SSID from " "driver."); return NULL; } ssid_len = res; } if (wpa_s->use_client_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 && os_strcmp(wpa_s->driver->name, "wired") == 0; entry = wpa_s->conf->ssid; while (entry) { if (!entry->disabled && ((ssid_len == entry->ssid_len && os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) && (!entry->bssid_set || os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)) return entry; entry = entry->next; } return NULL;}#ifndef CONFIG_NO_WPAstatic u8 * _wpa_alloc_eapol(void *wpa_s, u8 type, const void *data, u16 data_len, size_t *msg_len, void **data_pos){ return wpa_alloc_eapol(wpa_s, type, data, data_len, msg_len, data_pos);}static int _wpa_ether_send(void *wpa_s, const u8 *dest, u16 proto, const u8 *buf, size_t len){ return wpa_ether_send(wpa_s, dest, proto, buf, len);}static void _wpa_supplicant_req_scan(void *wpa_s, int sec, int usec){ wpa_supplicant_req_scan(wpa_s, sec, usec);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -