📄 ieee802_11.c
字号:
return; } HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "disassocation: STA=" MACSTR " reason_code=%d\n", MAC2STR(mgmt->sa), le_to_host16(mgmt->u.disassoc.reason_code)); if (hapd->assoc_ap_state != DO_NOT_ASSOC && memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0) { printf("Assoc AP " MACSTR " sent disassociation " "(reason_code=%d) - try to authenticate\n", MAC2STR(hapd->conf->assoc_ap_addr), le_to_host16(mgmt->u.disassoc.reason_code)); hapd->assoc_ap_state = AUTHENTICATE; ieee802_11_sta_authenticate(hapd, NULL); eloop_register_timeout(0, 500000, ieee802_11_sta_authenticate, hapd, NULL); return; } sta = ap_get_sta(hapd, mgmt->sa); if (sta == NULL) { printf("Station " MACSTR " trying to disassociate, but it " "is not associated.\n", MAC2STR(mgmt->sa)); return; } sta->flags &= ~WLAN_STA_ASSOC; wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "disassociated"); sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); /* Stop Accounting and IEEE 802.1X sessions, but leave the STA * authenticated. */ accounting_sta_stop(hapd, sta); ieee802_1x_free_station(sta); hostapd_sta_remove(hapd, sta->addr); if (sta->timeout_next == STA_NULLFUNC || sta->timeout_next == STA_DISASSOC) { sta->timeout_next = STA_DEAUTH; eloop_cancel_timeout(ap_handle_timer, hapd, sta); eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer, hapd, sta); }}static void handle_deauth(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt, size_t len){ struct sta_info *sta; if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.deauth)) { printf("handle_deauth - too short payload (len=%lu)\n", (unsigned long) len); return; } HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "deauthentication: STA=" MACSTR " reason_code=%d\n", MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code)); if (hapd->assoc_ap_state != DO_NOT_ASSOC && memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0) { printf("Assoc AP " MACSTR " sent deauthentication " "(reason_code=%d) - try to authenticate\n", MAC2STR(hapd->conf->assoc_ap_addr), le_to_host16(mgmt->u.deauth.reason_code)); hapd->assoc_ap_state = AUTHENTICATE; eloop_register_timeout(0, 500000, ieee802_11_sta_authenticate, hapd, NULL); return; } sta = ap_get_sta(hapd, mgmt->sa); if (sta == NULL) { printf("Station " MACSTR " trying to deauthenticate, but it " "is not authenticated.\n", MAC2STR(mgmt->sa)); return; } sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "deauthenticated"); sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); ap_free_sta(hapd, sta);}static void handle_beacon(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt, size_t len){ struct ieee802_11_elems elems; if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.beacon)) { printf("handle_beacon - too short payload (len=%lu)\n", (unsigned long) len); return; } (void) ieee802_11_parse_elems(hapd, mgmt->u.beacon.variable, len - (IEEE80211_HDRLEN + sizeof(mgmt->u.beacon)), &elems, 0); if (hapd->assoc_ap_state == WAIT_BEACON && memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0) { if (elems.ssid && elems.ssid_len <= 32) { memcpy(hapd->assoc_ap_ssid, elems.ssid, elems.ssid_len); hapd->assoc_ap_ssid[elems.ssid_len] = '\0'; hapd->assoc_ap_ssid_len = elems.ssid_len; } ieee802_11_sta_authenticate(hapd, NULL); } if (!HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_EXCESSIVE)) return; printf("Beacon from " MACSTR, MAC2STR(mgmt->sa)); if (elems.ssid) { printf(" SSID='"); ieee802_11_print_ssid(elems.ssid, elems.ssid_len); printf("'"); } if (elems.ds_params && elems.ds_params_len == 1) printf(" CHAN=%d", elems.ds_params[0]); printf("\n");}/** * ieee802_11_mgmt - process incoming IEEE 802.11 management frames * @hapd: hostapd BSS data structure (the BSS to which the management frame was * sent to) * @buf: management frame data (starting from IEEE 802.11 header) * @len: length of frame data in octets * @stype: management frame subtype from frame control field * * Process all incoming IEEE 802.11 management frames. This will be called for * each frame received from the kernel driver through wlan#ap interface. In * addition, it can be called to re-inserted pending frames (e.g., when using * external RADIUS server as an MAC ACL). */void ieee802_11_mgmt(struct hostapd_data *hapd, u8 *buf, size_t len, u16 stype){ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) buf; int broadcast; if (stype == WLAN_FC_STYPE_BEACON) { HOSTAPD_DEBUG(HOSTAPD_DEBUG_EXCESSIVE, "mgmt::beacon\n"); handle_beacon(hapd, mgmt, len); return; } broadcast = mgmt->bssid[0] == 0xff && mgmt->bssid[1] == 0xff && mgmt->bssid[2] == 0xff && mgmt->bssid[3] == 0xff && mgmt->bssid[4] == 0xff && mgmt->bssid[5] == 0xff; if (!broadcast && memcmp(mgmt->bssid, hapd->own_addr, ETH_ALEN) != 0 && (hapd->assoc_ap_state == DO_NOT_ASSOC || memcmp(mgmt->bssid, hapd->conf->assoc_ap_addr, ETH_ALEN) != 0)) { printf("MGMT: BSSID=" MACSTR " not our address\n", MAC2STR(mgmt->bssid)); return; } if (stype == WLAN_FC_STYPE_PROBE_REQ) { HOSTAPD_DEBUG(HOSTAPD_DEBUG_MSGDUMPS, "mgmt::probe_req\n"); handle_probe_req(hapd, mgmt, len); return; } if (memcmp(mgmt->da, hapd->own_addr, ETH_ALEN) != 0) { hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "MGMT: DA=" MACSTR " not our address", MAC2STR(mgmt->da)); return; } switch (stype) { case WLAN_FC_STYPE_AUTH: HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "mgmt::auth\n"); handle_auth(hapd, mgmt, len); break; case WLAN_FC_STYPE_ASSOC_REQ: HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "mgmt::assoc_req\n"); handle_assoc(hapd, mgmt, len, 0); break; case WLAN_FC_STYPE_ASSOC_RESP: HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "mgmt::assoc_resp\n"); handle_assoc_resp(hapd, mgmt, len); break; case WLAN_FC_STYPE_REASSOC_REQ: HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "mgmt::reassoc_req\n"); handle_assoc(hapd, mgmt, len, 1); break; case WLAN_FC_STYPE_DISASSOC: HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "mgmt::disassoc\n"); handle_disassoc(hapd, mgmt, len); break; case WLAN_FC_STYPE_DEAUTH: HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "mgmt::deauth\n"); handle_deauth(hapd, mgmt, len); break; default: hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "unknown mgmt frame subtype %d", stype); break; }}static void handle_auth_cb(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt, size_t len, int ok){ u16 auth_alg, auth_transaction, status_code; struct sta_info *sta; if (!ok) { hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_NOTICE, "did not acknowledge authentication response"); return; } if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { printf("handle_auth_cb - 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); sta = ap_get_sta(hapd, mgmt->da); if (!sta) { printf("handle_auth_cb: STA " MACSTR " not found\n", MAC2STR(mgmt->da)); return; } if (status_code == WLAN_STATUS_SUCCESS && ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) || (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) { hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "authenticated"); sta->flags |= WLAN_STA_AUTH; }}static void handle_assoc_cb(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt, size_t len, int reassoc, int ok){ u16 status; struct sta_info *sta; int new_assoc = 1; if (!ok) { hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "did not acknowledge association response"); return; } if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) : sizeof(mgmt->u.assoc_req))) { printf("handle_assoc_cb(reassoc=%d) - too short payload " "(len=%lu)\n", reassoc, (unsigned long) len); return; } if (reassoc) status = le_to_host16(mgmt->u.reassoc_resp.status_code); else status = le_to_host16(mgmt->u.assoc_resp.status_code); sta = ap_get_sta(hapd, mgmt->da); if (!sta) { printf("handle_assoc_cb: STA " MACSTR " not found\n", MAC2STR(mgmt->da)); return; } if (status != WLAN_STATUS_SUCCESS) goto fail; /* Stop previous accounting session, if one is started, and allocate * new session id for the new session. */ accounting_sta_stop(hapd, sta); accounting_sta_get_id(hapd, sta); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "associated (aid %d, accounting session %08X-%08X)", sta->aid, sta->acct_session_id_hi, sta->acct_session_id_lo); if (sta->flags & WLAN_STA_ASSOC) new_assoc = 0; sta->flags |= WLAN_STA_ASSOC; if (hostapd_sta_add(hapd->conf->iface, hapd, sta->addr, sta->aid, sta->capability, sta->supported_rates, sta->supported_rates_len, 0)) { hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_NOTICE, "Could not add STA to kernel driver"); } wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC); hostapd_new_assoc_sta(hapd, sta, !new_assoc); ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); fail: /* Copy of the association request is not needed anymore */ if (sta->last_assoc_req) { free(sta->last_assoc_req); sta->last_assoc_req = NULL; }}void ieee802_11_mgmt_cb(struct hostapd_data *hapd, u8 *buf, size_t len, u16 stype, int ok){ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) buf; switch (stype) { case WLAN_FC_STYPE_AUTH: HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "mgmt::auth cb\n"); handle_auth_cb(hapd, mgmt, len, ok); break; case WLAN_FC_STYPE_ASSOC_RESP: HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "mgmt::assoc_resp cb\n"); handle_assoc_cb(hapd, mgmt, len, 0, ok); break; case WLAN_FC_STYPE_REASSOC_RESP: HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "mgmt::reassoc_resp cb\n"); handle_assoc_cb(hapd, mgmt, len, 1, ok); break; default: printf("unknown mgmt cb frame subtype %d\n", stype); break; }}static void ieee80211_tkip_countermeasures_stop(void *eloop_ctx, void *timeout_ctx){ struct hostapd_data *hapd = eloop_ctx; hapd->tkip_countermeasures = 0; hostapd_set_countermeasures(hapd, 0); hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "TKIP countermeasures ended");}static void ieee80211_tkip_countermeasures_start(struct hostapd_data *hapd){ struct sta_info *sta; hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "TKIP countermeasures initiated"); wpa_auth_countermeasures_start(hapd->wpa_auth); hapd->tkip_countermeasures = 1; hostapd_set_countermeasures(hapd, 1); wpa_gtk_rekey(hapd->wpa_auth); eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop, hapd, NULL); eloop_register_timeout(60, 0, ieee80211_tkip_countermeasures_stop, hapd, NULL); for (sta = hapd->sta_list; sta != NULL; sta = sta->next) { hostapd_sta_deauth(hapd, sta->addr, WLAN_REASON_MICHAEL_MIC_FAILURE); sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_AUTHORIZED); hostapd_sta_remove(hapd, sta->addr); }}void ieee80211_michael_mic_failure(struct hostapd_data *hapd, const u8 *addr, int local){ time_t now; if (addr && local) { struct sta_info *sta = ap_get_sta(hapd, addr); if (sta != NULL) { wpa_auth_sta_local_mic_failure_report(sta->wpa_sm); hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "Michael MIC failure detected in " "received frame"); } else { HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "MLME-MICHAELMICFAILURE.indication " "for not associated STA (" MACSTR ") ignored\n", MAC2STR(addr)); return; } } time(&now); if (now > hapd->michael_mic_failure + 60) { hapd->michael_mic_failures = 1; } else { hapd->michael_mic_failures++; if (hapd->michael_mic_failures > 1) ieee80211_tkip_countermeasures_start(hapd); } hapd->michael_mic_failure = now;}int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen){ /* TODO */ return 0;}int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta, char *buf, size_t buflen){ /* TODO */ return 0;}#endif /* CONFIG_NATIVE_WINDOWS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -