📄 ieee802_11.c
字号:
size_t len){ u16 auth_alg, auth_transaction, status_code; u16 resp = WLAN_STATUS_SUCCESS; struct sta_info *sta = NULL; int res; u16 fc; u8 *challenge = NULL; u32 session_timeout, acct_interim_interval; int vlan_id = 0; if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { printf("handle_auth - too short payload (len=%lu)\n", (unsigned long) len); 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); fc = le_to_host16(mgmt->frame_control); if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) + 2 + WLAN_AUTH_CHALLENGE_LEN && mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE && mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN) challenge = &mgmt->u.auth.variable[2]; HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "authentication: STA=" MACSTR " auth_alg=%d " "auth_transaction=%d status_code=%d wep=%d%s\n", MAC2STR(mgmt->sa), auth_alg, auth_transaction, status_code, !!(fc & WLAN_FC_ISWEP), challenge ? " challenge" : ""); if (hapd->assoc_ap_state == AUTHENTICATE && auth_transaction == 2 && memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0 && memcmp(mgmt->bssid, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0) { if (status_code != 0) { printf("Authentication (as station) with AP " MACSTR " failed (status_code=%d)\n", MAC2STR(hapd->conf->assoc_ap_addr), status_code); return; } printf("Authenticated (as station) with AP " MACSTR "\n", MAC2STR(hapd->conf->assoc_ap_addr)); ieee802_11_sta_associate(hapd, NULL); return; } if (hapd->tkip_countermeasures) { resp = WLAN_REASON_MICHAEL_MIC_FAILURE; goto fail; } if (!(((hapd->conf->auth_algs & HOSTAPD_AUTH_OPEN) && auth_alg == WLAN_AUTH_OPEN) || ((hapd->conf->auth_algs & HOSTAPD_AUTH_SHARED_KEY) && auth_alg == WLAN_AUTH_SHARED_KEY))) { printf("Unsupported authentication algorithm (%d)\n", auth_alg); resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG; goto fail; } if (!(auth_transaction == 1 || (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) { printf("Unknown authentication transaction number (%d)\n", auth_transaction); resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION; goto fail; } if (memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) { printf("Station " MACSTR " not allowed to authenticate.\n", MAC2STR(mgmt->sa)); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len, &session_timeout, &acct_interim_interval, &vlan_id); if (res == HOSTAPD_ACL_REJECT) { printf("Station " MACSTR " not allowed to authenticate.\n", MAC2STR(mgmt->sa)); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } if (res == HOSTAPD_ACL_PENDING) { HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Authentication frame " "from " MACSTR " waiting for an external " "authentication\n", MAC2STR(mgmt->sa)); /* Authentication code will re-send the authentication frame * after it has received (and cached) information from the * external source. */ return; } sta = ap_sta_add(hapd, mgmt->sa); if (!sta) { resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } if (vlan_id > 0) { sta->vlan_id = vlan_id; hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id); } sta->flags &= ~WLAN_STA_PREAUTH; ieee802_1x_notify_pre_auth(sta->eapol_sm, 0); if (hapd->conf->radius->acct_interim_interval == 0 && acct_interim_interval) sta->acct_interim_interval = acct_interim_interval; if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT) ap_sta_session_timeout(hapd, sta, session_timeout); else ap_sta_no_session_timeout(hapd, sta); switch (auth_alg) { case WLAN_AUTH_OPEN: hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "authentication OK (open system)");#ifdef IEEE80211_REQUIRE_AUTH_ACK /* Station will be marked authenticated if it ACKs the * authentication reply. */#else sta->flags |= WLAN_STA_AUTH; wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);#endif break; case WLAN_AUTH_SHARED_KEY: resp = auth_shared_key(hapd, sta, auth_transaction, challenge, fc & WLAN_FC_ISWEP); break; } fail: send_auth_reply(hapd, mgmt, auth_alg, auth_transaction + 1, resp, sta ? sta->challenge : NULL);}static void handle_assoc(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt, size_t len, int reassoc){ u16 capab_info, listen_interval; u16 resp = WLAN_STATUS_SUCCESS; u8 *pos, *wpa_ie; size_t wpa_ie_len; int send_deauth = 0, send_len, left; struct sta_info *sta; struct ieee802_11_elems elems; if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) : sizeof(mgmt->u.assoc_req))) { printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)" "\n", reassoc, (unsigned long) len); return; } if (reassoc) { capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info); listen_interval = le_to_host16( mgmt->u.reassoc_req.listen_interval); HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "reassociation request: STA=" MACSTR " capab_info=0x%02x " "listen_interval=%d current_ap=" MACSTR "\n", MAC2STR(mgmt->sa), capab_info, listen_interval, MAC2STR(mgmt->u.reassoc_req.current_ap)); left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req)); pos = mgmt->u.reassoc_req.variable; } else { capab_info = le_to_host16(mgmt->u.assoc_req.capab_info); listen_interval = le_to_host16( mgmt->u.assoc_req.listen_interval); HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "association request: STA=" MACSTR " capab_info=0x%02x listen_interval=%d\n", MAC2STR(mgmt->sa), capab_info, listen_interval); left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req)); pos = mgmt->u.assoc_req.variable; } sta = ap_get_sta(hapd, mgmt->sa); if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) { printf("STA " MACSTR " trying to associate before " "authentication\n", MAC2STR(mgmt->sa)); if (sta) { printf(" sta: addr=" MACSTR " aid=%d flags=0x%04x\n", MAC2STR(sta->addr), sta->aid, sta->flags); } send_deauth = 1; resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } if (hapd->tkip_countermeasures) { resp = WLAN_REASON_MICHAEL_MIC_FAILURE; goto fail; } sta->capability = capab_info; /* followed by SSID and Supported rates */ if (ieee802_11_parse_elems(hapd, pos, left, &elems, 1) == ParseFailed || !elems.ssid) { printf("STA " MACSTR " sent invalid association request\n", MAC2STR(sta->addr)); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } if (elems.ssid_len != hapd->conf->ssid.ssid_len || memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) != 0) { printf("Station " MACSTR " tried to associate with " "unknown SSID '", MAC2STR(sta->addr)); ieee802_11_print_ssid(elems.ssid, elems.ssid_len); printf("'\n"); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } if (!elems.supp_rates) { hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "No supported rates element in AssocReq"); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } if (elems.supp_rates_len > sizeof(sta->supported_rates)) { hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "Invalid supported rates element length %d", elems.supp_rates_len); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } memset(sta->supported_rates, 0, sizeof(sta->supported_rates)); memcpy(sta->supported_rates, elems.supp_rates, elems.supp_rates_len); sta->supported_rates_len = elems.supp_rates_len; if (elems.ext_supp_rates) { if (elems.supp_rates_len + elems.ext_supp_rates_len > sizeof(sta->supported_rates)) { hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "Invalid supported rates element length" " %d+%d", elems.supp_rates_len, elems.ext_supp_rates_len); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } memcpy(sta->supported_rates + elems.supp_rates_len, elems.ext_supp_rates, elems.ext_supp_rates_len); sta->supported_rates_len += elems.ext_supp_rates_len; } if ((hapd->conf->wpa & HOSTAPD_WPA_VERSION_WPA2) && elems.rsn_ie) { wpa_ie = elems.rsn_ie; wpa_ie_len = elems.rsn_ie_len; } else if ((hapd->conf->wpa & HOSTAPD_WPA_VERSION_WPA) && elems.wpa_ie) { wpa_ie = elems.wpa_ie; wpa_ie_len = elems.wpa_ie_len; } else { wpa_ie = NULL; wpa_ie_len = 0; } if (hapd->conf->wpa && wpa_ie == NULL) { printf("STA " MACSTR ": No WPA/RSN IE in association " "request\n", MAC2STR(sta->addr)); resp = WLAN_STATUS_INVALID_IE; goto fail; } if (hapd->conf->wpa) { int res; wpa_ie -= 2; wpa_ie_len += 2; if (sta->wpa_sm == NULL) sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr); if (sta->wpa_sm == NULL) { printf("Failed to initialize WPA state machine\n"); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, wpa_ie, wpa_ie_len); if (res == WPA_INVALID_GROUP) resp = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; else if (res == WPA_INVALID_PAIRWISE) resp = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; else if (res == WPA_INVALID_AKMP) resp = WLAN_STATUS_AKMP_NOT_VALID; else if (res == WPA_ALLOC_FAIL) resp = WLAN_STATUS_UNSPECIFIED_FAILURE; else if (res != WPA_IE_OK) resp = WLAN_STATUS_INVALID_IE; if (resp != WLAN_STATUS_SUCCESS) goto fail; } /* get a unique AID */ if (sta->aid > 0) { HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " old AID %d\n", sta->aid); } else { for (sta->aid = 1; sta->aid <= MAX_AID_TABLE_SIZE; sta->aid++) if (hapd->sta_aid[sta->aid - 1] == NULL) break; if (sta->aid > MAX_AID_TABLE_SIZE) { sta->aid = 0; resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; printf(" no room for more AIDs\n"); goto fail; } else { hapd->sta_aid[sta->aid - 1] = sta; HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " new AID %d\n", sta->aid); } } hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "association OK (aid %d)", sta->aid); /* Station will be marked associated, after it acknowledges AssocResp */ if (sta->last_assoc_req) free(sta->last_assoc_req); sta->last_assoc_req = (struct ieee80211_mgmt *) malloc(len); if (sta->last_assoc_req) memcpy(sta->last_assoc_req, mgmt, len); /* Make sure that the previously registered inactivity timer will not * remove the STA immediately. */ sta->timeout_next = STA_NULLFUNC; fail: /* use the queued buffer for transmission because it is large enough * and not needed anymore */ mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, (send_deauth ? WLAN_FC_STYPE_DEAUTH : (reassoc ? WLAN_FC_STYPE_REASSOC_RESP : WLAN_FC_STYPE_ASSOC_RESP))); memcpy(mgmt->da, mgmt->sa, ETH_ALEN); memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN); /* Addr3 = BSSID - already set */ send_len = IEEE80211_HDRLEN; if (send_deauth) { send_len += sizeof(mgmt->u.deauth); mgmt->u.deauth.reason_code = host_to_le16(resp); } else { u8 *p; send_len += sizeof(mgmt->u.assoc_resp); mgmt->u.assoc_resp.capab_info = host_to_le16(hostapd_own_capab_info(hapd, sta, 0)); mgmt->u.assoc_resp.status_code = host_to_le16(resp); mgmt->u.assoc_resp.aid = host_to_le16((sta ? sta->aid : 0) | BIT(14) | BIT(15)); /* Supported rates */ p = hostapd_eid_supp_rates(hapd, mgmt->u.assoc_resp.variable); /* Extended supported rates */ p = hostapd_eid_ext_supp_rates(hapd, p); send_len += p - mgmt->u.assoc_resp.variable; /* Request TX callback */ mgmt->frame_control |= host_to_le16(BIT(1)); } if (hostapd_send_mgmt_frame(hapd, mgmt, send_len, 0) < 0) perror("handle_assoc: send");}static void handle_assoc_resp(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt, size_t len){ u16 status_code, aid; if (hapd->assoc_ap_state != ASSOCIATE) { printf("Unexpected association response received from " MACSTR "\n", MAC2STR(mgmt->sa)); return; } if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_resp)) { printf("handle_assoc_resp - too short payload (len=%lu)\n", (unsigned long) len); return; } if (memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) != 0 || memcmp(mgmt->bssid, hapd->conf->assoc_ap_addr, ETH_ALEN) != 0) { printf("Received association response from unexpected address " "(SA=" MACSTR " BSSID=" MACSTR "\n", MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid)); return; } status_code = le_to_host16(mgmt->u.assoc_resp.status_code); aid = le_to_host16(mgmt->u.assoc_resp.aid); aid &= ~(BIT(14) | BIT(15)); if (status_code != 0) { printf("Association (as station) with AP " MACSTR " failed " "(status_code=%d)\n", MAC2STR(hapd->conf->assoc_ap_addr), status_code); /* Try to authenticate again */ hapd->assoc_ap_state = AUTHENTICATE; eloop_register_timeout(5, 0, ieee802_11_sta_authenticate, hapd, NULL); } printf("Associated (as station) with AP " MACSTR " (aid=%d)\n", MAC2STR(hapd->conf->assoc_ap_addr), aid); hapd->assoc_ap_aid = aid; hapd->assoc_ap_state = ASSOCIATED; if (hostapd_set_assoc_ap(hapd, hapd->conf->assoc_ap_addr)) { printf("Could not set associated AP address to kernel " "driver.\n"); }}static void handle_disassoc(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt, size_t len){ struct sta_info *sta; if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) { printf("handle_disassoc - too short payload (len=%lu)\n", (unsigned long) len);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -