📄 mlme.c
字号:
pos = buf + len; len++; esupp_rates[1]++; } else if (supp_rates[1] == 8) { esupp_rates = pos; esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES; esupp_rates[1] = 1; pos = &esupp_rates[2]; } else { pos = buf + len; len++; supp_rates[1]++; } *pos = rate->rate / 5; } ieee80211_sta_tx(wpa_s, buf, len); os_free(buf);}static int ieee80211_sta_wep_configured(struct wpa_supplicant *wpa_s){#if 0 /* FIX */ if (sdata == NULL || sdata->default_key == NULL || sdata->default_key->alg != ALG_WEP) return 0; return 1;#else return 0;#endif}static void ieee80211_auth_completed(struct wpa_supplicant *wpa_s){ wpa_printf(MSG_DEBUG, "MLME: authenticated"); wpa_s->mlme.authenticated = 1; ieee80211_associate(wpa_s);}static void ieee80211_auth_challenge(struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len, struct ieee80211_rx_status *rx_status){ u8 *pos; struct ieee802_11_elems elems; wpa_printf(MSG_DEBUG, "MLME: replying to auth challenge"); pos = mgmt->u.auth.variable; if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) == ParseFailed) { wpa_printf(MSG_DEBUG, "MLME: failed to parse Auth(challenge)"); return; } if (elems.challenge == NULL) { wpa_printf(MSG_DEBUG, "MLME: no challenge IE in shared key " "auth frame"); return; } ieee80211_send_auth(wpa_s, 3, elems.challenge - 2, elems.challenge_len + 2, 1);}static void ieee80211_rx_mgmt_auth(struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len, struct ieee80211_rx_status *rx_status){ struct wpa_ssid *ssid = wpa_s->current_ssid; u16 auth_alg, auth_transaction, status_code; int adhoc; adhoc = ssid && ssid->mode == 1; if (wpa_s->mlme.state != IEEE80211_AUTHENTICATE && !adhoc) { wpa_printf(MSG_DEBUG, "MLME: authentication frame received " "from " MACSTR ", but not in authenticate state - " "ignored", MAC2STR(mgmt->sa)); return; } if (len < 24 + 6) { wpa_printf(MSG_DEBUG, "MLME: too short (%lu) authentication " "frame received from " MACSTR " - ignored", (unsigned long) len, MAC2STR(mgmt->sa)); return; } if (!adhoc && os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) { wpa_printf(MSG_DEBUG, "MLME: authentication frame received " "from unknown AP (SA=" MACSTR " BSSID=" MACSTR ") - ignored", MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid)); return; } if (adhoc && os_memcmp(wpa_s->bssid, mgmt->bssid, ETH_ALEN) != 0) { wpa_printf(MSG_DEBUG, "MLME: authentication frame received " "from unknown BSSID (SA=" MACSTR " BSSID=" MACSTR ") - ignored", MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid)); return; } auth_alg = le_to_host16(mgmt->u.auth.auth_alg); auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction); status_code = le_to_host16(mgmt->u.auth.status_code); wpa_printf(MSG_DEBUG, "MLME: RX authentication from " MACSTR " (alg=%d transaction=%d status=%d)", MAC2STR(mgmt->sa), auth_alg, auth_transaction, status_code); if (adhoc) { /* IEEE 802.11 standard does not require authentication in IBSS * networks and most implementations do not seem to use it. * However, try to reply to authentication attempts if someone * has actually implemented this. * TODO: Could implement shared key authentication. */ if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) { wpa_printf(MSG_DEBUG, "MLME: unexpected IBSS " "authentication frame (alg=%d " "transaction=%d)", auth_alg, auth_transaction); return; } ieee80211_send_auth(wpa_s, 2, NULL, 0, 0); } if (auth_alg != wpa_s->mlme.auth_alg || auth_transaction != wpa_s->mlme.auth_transaction) { wpa_printf(MSG_DEBUG, "MLME: unexpected authentication frame " "(alg=%d transaction=%d)", auth_alg, auth_transaction); return; } if (status_code != WLAN_STATUS_SUCCESS) { wpa_printf(MSG_DEBUG, "MLME: AP denied authentication " "(auth_alg=%d code=%d)", wpa_s->mlme.auth_alg, status_code); if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) { const int num_algs = 3; u8 algs[num_algs]; int i, pos; algs[0] = algs[1] = algs[2] = 0xff; if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_OPEN) algs[0] = WLAN_AUTH_OPEN; if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_SHARED_KEY) algs[1] = WLAN_AUTH_SHARED_KEY; if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_LEAP) algs[2] = WLAN_AUTH_LEAP; if (wpa_s->mlme.auth_alg == WLAN_AUTH_OPEN) pos = 0; else if (wpa_s->mlme.auth_alg == WLAN_AUTH_SHARED_KEY) pos = 1; else pos = 2; for (i = 0; i < num_algs; i++) { pos++; if (pos >= num_algs) pos = 0; if (algs[pos] == wpa_s->mlme.auth_alg || algs[pos] == 0xff) continue; if (algs[pos] == WLAN_AUTH_SHARED_KEY && !ieee80211_sta_wep_configured(wpa_s)) continue; wpa_s->mlme.auth_alg = algs[pos]; wpa_printf(MSG_DEBUG, "MLME: set auth_alg=%d " "for next try", wpa_s->mlme.auth_alg); break; } } return; } switch (wpa_s->mlme.auth_alg) { case WLAN_AUTH_OPEN: case WLAN_AUTH_LEAP: ieee80211_auth_completed(wpa_s); break; case WLAN_AUTH_SHARED_KEY: if (wpa_s->mlme.auth_transaction == 4) ieee80211_auth_completed(wpa_s); else ieee80211_auth_challenge(wpa_s, mgmt, len, rx_status); break; }}static void ieee80211_rx_mgmt_deauth(struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len, struct ieee80211_rx_status *rx_status){ u16 reason_code; if (len < 24 + 2) { wpa_printf(MSG_DEBUG, "MLME: too short (%lu) deauthentication " "frame received from " MACSTR " - ignored", (unsigned long) len, MAC2STR(mgmt->sa)); return; } if (os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) { wpa_printf(MSG_DEBUG, "MLME: deauthentication frame received " "from unknown AP (SA=" MACSTR " BSSID=" MACSTR ") - ignored", MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid)); return; } reason_code = le_to_host16(mgmt->u.deauth.reason_code); wpa_printf(MSG_DEBUG, "MLME: RX deauthentication from " MACSTR " (reason=%d)", MAC2STR(mgmt->sa), reason_code); if (wpa_s->mlme.authenticated) wpa_printf(MSG_DEBUG, "MLME: deauthenticated"); if (wpa_s->mlme.state == IEEE80211_AUTHENTICATE || wpa_s->mlme.state == IEEE80211_ASSOCIATE || wpa_s->mlme.state == IEEE80211_ASSOCIATED) { wpa_s->mlme.state = IEEE80211_AUTHENTICATE; ieee80211_reschedule_timer(wpa_s, IEEE80211_RETRY_AUTH_INTERVAL); } ieee80211_set_associated(wpa_s, 0); wpa_s->mlme.authenticated = 0;}static void ieee80211_rx_mgmt_disassoc(struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len, struct ieee80211_rx_status *rx_status){ u16 reason_code; if (len < 24 + 2) { wpa_printf(MSG_DEBUG, "MLME: too short (%lu) disassociation " "frame received from " MACSTR " - ignored", (unsigned long) len, MAC2STR(mgmt->sa)); return; } if (os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) { wpa_printf(MSG_DEBUG, "MLME: disassociation frame received " "from unknown AP (SA=" MACSTR " BSSID=" MACSTR ") - ignored", MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid)); return; } reason_code = le_to_host16(mgmt->u.disassoc.reason_code); wpa_printf(MSG_DEBUG, "MLME: RX disassociation from " MACSTR " (reason=%d)", MAC2STR(mgmt->sa), reason_code); if (wpa_s->mlme.associated) wpa_printf(MSG_DEBUG, "MLME: disassociated"); if (wpa_s->mlme.state == IEEE80211_ASSOCIATED) { wpa_s->mlme.state = IEEE80211_ASSOCIATE; ieee80211_reschedule_timer(wpa_s, IEEE80211_RETRY_AUTH_INTERVAL); } ieee80211_set_associated(wpa_s, 0);}static void ieee80211_rx_mgmt_assoc_resp(struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len, struct ieee80211_rx_status *rx_status, int reassoc){ u8 rates[32]; size_t rates_len; u16 capab_info, status_code, aid; struct ieee802_11_elems elems; u8 *pos; /* AssocResp and ReassocResp have identical structure, so process both * of them in this function. */ if (wpa_s->mlme.state != IEEE80211_ASSOCIATE) { wpa_printf(MSG_DEBUG, "MLME: association frame received from " MACSTR ", but not in associate state - ignored", MAC2STR(mgmt->sa)); return; } if (len < 24 + 6) { wpa_printf(MSG_DEBUG, "MLME: too short (%lu) association " "frame received from " MACSTR " - ignored", (unsigned long) len, MAC2STR(mgmt->sa)); return; } if (os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) { wpa_printf(MSG_DEBUG, "MLME: association frame received from " "unknown AP (SA=" MACSTR " BSSID=" MACSTR ") - " "ignored", MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid)); return; } capab_info = le_to_host16(mgmt->u.assoc_resp.capab_info); status_code = le_to_host16(mgmt->u.assoc_resp.status_code); aid = le_to_host16(mgmt->u.assoc_resp.aid); if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) wpa_printf(MSG_DEBUG, "MLME: invalid aid value %d; bits 15:14 " "not set", aid); aid &= ~(BIT(15) | BIT(14)); wpa_printf(MSG_DEBUG, "MLME: RX %sssocResp from " MACSTR " (capab=0x%x status=%d aid=%d)", reassoc ? "Rea" : "A", MAC2STR(mgmt->sa), capab_info, status_code, aid); if (status_code != WLAN_STATUS_SUCCESS) { wpa_printf(MSG_DEBUG, "MLME: AP denied association (code=%d)", status_code); return; } pos = mgmt->u.assoc_resp.variable; if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) == ParseFailed) { wpa_printf(MSG_DEBUG, "MLME: failed to parse AssocResp"); return; } if (elems.supp_rates == NULL) { wpa_printf(MSG_DEBUG, "MLME: no SuppRates element in " "AssocResp"); return; } wpa_printf(MSG_DEBUG, "MLME: associated"); wpa_s->mlme.aid = aid; wpa_s->mlme.ap_capab = capab_info; os_free(wpa_s->mlme.assocresp_ies); wpa_s->mlme.assocresp_ies_len = len - (pos - (u8 *) mgmt); wpa_s->mlme.assocresp_ies = os_malloc(wpa_s->mlme.assocresp_ies_len); if (wpa_s->mlme.assocresp_ies) { os_memcpy(wpa_s->mlme.assocresp_ies, pos, wpa_s->mlme.assocresp_ies_len); } ieee80211_set_associated(wpa_s, 1); rates_len = elems.supp_rates_len; if (rates_len > sizeof(rates)) rates_len = sizeof(rates); os_memcpy(rates, elems.supp_rates, rates_len); if (elems.ext_supp_rates) { size_t _len = elems.ext_supp_rates_len; if (_len > sizeof(rates) - rates_len) _len = sizeof(rates) - rates_len; os_memcpy(rates + rates_len, elems.ext_supp_rates, _len); rates_len += _len; } if (wpa_drv_set_bssid(wpa_s, wpa_s->bssid) < 0) { wpa_printf(MSG_DEBUG, "MLME: failed to set BSSID for the " "netstack"); } if (wpa_drv_set_ssid(wpa_s, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len) < 0) { wpa_printf(MSG_DEBUG, "MLME: failed to set SSID for the " "netstack"); } /* Remove STA entry before adding a new one just in case to avoid * problems with existing configuration (e.g., keys). */ wpa_drv_mlme_remove_sta(wpa_s, wpa_s->bssid); if (wpa_drv_mlme_add_sta(wpa_s, wpa_s->bssid, rates, rates_len) < 0) { wpa_printf(MSG_DEBUG, "MLME: failed to add STA entry to the " "netstack"); }#if 0 /* FIX? */ sta->assoc_ap = 1; if (elems.wmm_param && wpa_s->mlme.wmm_enabled) { sta->flags |= WLAN_STA_WME; ieee80211_sta_wmm_params(wpa_s, elems.wmm_param, elems.wmm_param_len); }#endif ieee80211_associated(wpa_s);}/* Caller must hold local->sta_bss_lock */static void __ieee80211_bss_hash_add(struct wpa_supplicant *wpa_s, struct ieee80211_sta_bss *bss){ bss->hnext = wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)]; wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)] = bss;}/* Caller must hold local->sta_bss_lock */static void __ieee80211_bss_hash_del(struct wpa_supplicant *wpa_s, struct ieee80211_sta_bss *bss){ struct ieee80211_sta_bss *b, *prev = NULL; b = wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)]; while (b) { if (b == bss) { if (prev == NULL) { wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)] = bss->hnext; } else { prev->hnext = bss->hnext; } break; } prev = b; b = b->hnext; }}static struct ieee80211_sta_bss *ieee80211_bss_add(struct wpa_supplicant *wpa_s, const u8 *bssid){ struct ieee80211_sta_bss *bss; bss = os_zalloc(sizeof(*bss)); if (bss == NULL) return NULL; os_memcpy(bss->bssid, bssid, ETH_ALEN); /* TODO: order by RSSI? */ bss->next = wpa_s->mlme.sta_bss_list; wpa_s->mlme.sta_bss_list = bss; __ieee80211_bss_hash_add(wpa_s, bss); return bss;}static struct ieee80211_sta_bss *ieee80211_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid){ struct ieee80211_sta_bss *bss; bss = wpa_s->mlme.sta_bss_hash[STA_HASH(bssid)]; while (bss) { if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0) break; bss = bss->hnext; } return bss;}static void ieee80211_bss_free(struct wpa_supplicant *wpa_s, struct ieee80211_sta_bss *bss){ __ieee80211_bss_hash_del(wpa_s, bss); os_free(bss->wpa_ie); os_free(bss->rsn_ie); os_free(bss->wmm_ie); os_free(bss);}static void ieee80211_bss_list_deinit(struct wpa_supplicant *wpa_s){ struct ieee80211_sta_bss *bss, *prev; bss = wpa_s->mlme.sta_bss_list; wpa_s->mlme.sta_bss_list = NULL; while (bss) { prev = bss; bss = bss->next; ieee80211_bss_free(wpa_s, prev); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -