📄 ieee802_11.c
字号:
if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) { wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored FT Action " "frame from unassociated STA " MACSTR, MAC2STR(mgmt->sa)); return; } if (wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action, len - IEEE80211_HDRLEN)) break; return; }#endif /* CONFIG_IEEE80211R */ case WLAN_ACTION_WMM: hostapd_wme_action(hapd, mgmt, len); return;#ifdef CONFIG_IEEE80211W case WLAN_ACTION_SA_QUERY: hostapd_sa_query_action(hapd, mgmt, len); return;#endif /* CONFIG_IEEE80211W */ } hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "handle_action - unknown action category %d or invalid " "frame", mgmt->u.action.category); if (!(mgmt->da[0] & 0x01) && !(mgmt->u.action.category & 0x80) && !(mgmt->sa[0] & 0x01)) { /* * IEEE 802.11-REVma/D9.0 - 7.3.1.11 * Return the Action frame to the source without change * except that MSB of the Category set to 1. */ wpa_printf(MSG_DEBUG, "IEEE 802.11: Return unknown Action " "frame back to sender"); os_memcpy(mgmt->da, mgmt->sa, ETH_ALEN); os_memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN); os_memcpy(mgmt->bssid, hapd->own_addr, ETH_ALEN); mgmt->u.action.category |= 0x80; hostapd_send_mgmt_frame(hapd, mgmt, len, 0); }}/** * 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 * @fi: meta data about received frame (signal level, etc.) * * 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 hostapd_frame_info *fi){ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) buf; int broadcast; if (stype == WLAN_FC_STYPE_BEACON) { handle_beacon(hapd, mgmt, len, fi); return; } if (fi && fi->passive_scan) 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 && os_memcmp(mgmt->bssid, hapd->own_addr, ETH_ALEN) != 0) { printf("MGMT: BSSID=" MACSTR " not our address\n", MAC2STR(mgmt->bssid)); return; } if (stype == WLAN_FC_STYPE_PROBE_REQ) { handle_probe_req(hapd, mgmt, len); return; } if (os_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: wpa_printf(MSG_DEBUG, "mgmt::auth"); handle_auth(hapd, mgmt, len); break; case WLAN_FC_STYPE_ASSOC_REQ: wpa_printf(MSG_DEBUG, "mgmt::assoc_req"); handle_assoc(hapd, mgmt, len, 0); break; case WLAN_FC_STYPE_REASSOC_REQ: wpa_printf(MSG_DEBUG, "mgmt::reassoc_req"); handle_assoc(hapd, mgmt, len, 1); break; case WLAN_FC_STYPE_DISASSOC: wpa_printf(MSG_DEBUG, "mgmt::disassoc"); handle_disassoc(hapd, mgmt, len); break; case WLAN_FC_STYPE_DEAUTH: wpa_printf(MSG_DEBUG, "mgmt::deauth"); handle_deauth(hapd, mgmt, len); break; case WLAN_FC_STYPE_ACTION: wpa_printf(MSG_DEBUG, "mgmt::action"); handle_action(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; }}#ifdef CONFIG_IEEE80211Nstatic voidhostapd_get_ht_capab(struct hostapd_data *hapd, struct ht_cap_ie *ht_cap_ie, struct ht_cap_ie *neg_ht_cap_ie){ os_memcpy(neg_ht_cap_ie, ht_cap_ie, sizeof(struct ht_cap_ie)); neg_ht_cap_ie->data.capabilities_info = ht_cap_ie->data.capabilities_info & hapd->iconf->ht_capab; neg_ht_cap_ie->data.capabilities_info &= ~HT_CAP_INFO_SMPS_DISABLED; if ((ht_cap_ie->data.capabilities_info & HT_CAP_INFO_SMPS_DISABLED) == (hapd->iconf->ht_capab & HT_CAP_INFO_SMPS_DISABLED)) neg_ht_cap_ie->data.capabilities_info |= hapd->iconf->ht_capab & HT_CAP_INFO_SMPS_DISABLED; else neg_ht_cap_ie->data.capabilities_info |= HT_CAP_INFO_SMPS_DISABLED; /* FIXME: Rx STBC needs to be handled specially */ neg_ht_cap_ie->data.capabilities_info &= ~HT_CAP_INFO_RX_STBC_MASK; neg_ht_cap_ie->data.capabilities_info |= hapd->iconf->ht_capab & HT_CAP_INFO_RX_STBC_MASK;}#endif /* CONFIG_IEEE80211N */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;#ifdef CONFIG_IEEE80211N struct ht_cap_ie ht_cap;#endif /* CONFIG_IEEE80211N */ struct ht_cap_ie *ht_cap_ptr = NULL; 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_resp) : sizeof(mgmt->u.assoc_resp))) { 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); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "associated (aid %d)", sta->aid); if (sta->flags & WLAN_STA_ASSOC) new_assoc = 0; sta->flags |= WLAN_STA_ASSOC; if (reassoc) mlme_reassociate_indication(hapd, sta); else mlme_associate_indication(hapd, sta);#ifdef CONFIG_IEEE80211N if (sta->flags & WLAN_STA_HT) { ht_cap_ptr = &ht_cap; hostapd_get_ht_capab(hapd, &sta->ht_capabilities, ht_cap_ptr); }#endif /* CONFIG_IEEE80211N */#ifdef CONFIG_IEEE80211W sta->sa_query_timed_out = 0;#endif /* CONFIG_IEEE80211W */ if (hostapd_sta_add(hapd->conf->iface, hapd, sta->addr, sta->aid, sta->capability, sta->supported_rates, sta->supported_rates_len, 0, sta->listen_interval, ht_cap_ptr)) { hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_NOTICE, "Could not add STA to kernel driver"); } if (sta->eapol_sm == NULL) { /* * This STA does not use RADIUS server for EAP authentication, * so bind it to the selected VLAN interface now, since the * interface selection is not going to change anymore. */ ap_sta_bind_vlan(hapd, sta, 0); } else if (sta->vlan_id) { /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */ ap_sta_bind_vlan(hapd, sta, 0); } if (sta->flags & WLAN_STA_SHORT_PREAMBLE) { hostapd_sta_set_flags(hapd, sta->addr, sta->flags, WLAN_STA_SHORT_PREAMBLE, ~0); } else { hostapd_sta_set_flags(hapd, sta->addr, sta->flags, 0, ~WLAN_STA_SHORT_PREAMBLE); } if (sta->auth_alg == WLAN_AUTH_FT) wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT); else 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) { os_free(sta->last_assoc_req); sta->last_assoc_req = NULL; }}/** * ieee802_11_mgmt_cb - Process management frame TX status callback * @hapd: hostapd BSS data structure (the BSS from which the management frame * was sent from) * @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 * @ok: Whether the frame was ACK'ed */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: wpa_printf(MSG_DEBUG, "mgmt::auth cb"); handle_auth_cb(hapd, mgmt, len, ok); break; case WLAN_FC_STYPE_ASSOC_RESP: wpa_printf(MSG_DEBUG, "mgmt::assoc_resp cb"); handle_assoc_cb(hapd, mgmt, len, 0, ok); break; case WLAN_FC_STYPE_REASSOC_RESP: wpa_printf(MSG_DEBUG, "mgmt::reassoc_resp cb"); handle_assoc_cb(hapd, mgmt, len, 1, ok); break; case WLAN_FC_STYPE_PROBE_RESP: wpa_printf(MSG_DEBUG, "mgmt::proberesp cb"); break; case WLAN_FC_STYPE_DEAUTH: /* ignore */ break; case WLAN_FC_STYPE_ACTION: wpa_printf(MSG_DEBUG, "mgmt::action cb"); 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"); mlme_michaelmicfailure_indication(hapd, addr); } else { wpa_printf(MSG_DEBUG, "MLME-MICHAELMICFAILURE.indication " "for not associated STA (" MACSTR ") ignored", 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 + -