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"); if (hapd->wpa_auth) hapd->wpa_auth->dot11RSNATKIPCounterMeasuresInvoked++; hapd->tkip_countermeasures = 1; /* The following line of code is redundant, it will cause * driver crash */ /*hostapd_set_countermeasures(hapd, 1); */ wpa_gtk_rekey(hapd); 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); } }
/* This function will be called whenever a station associates with the AP */ void hostapd_new_assoc_sta(hostapd *hapd, struct sta_info *sta, int reassoc) { if (hapd->tkip_countermeasures) { hostapd_sta_deauth(hapd, sta->addr, WLAN_REASON_MICHAEL_MIC_FAILURE); return; } /* IEEE 802.11F (IAPP) */ if (hapd->conf->ieee802_11f) iapp_new_station(hapd->iapp, sta); /* Start accounting here, if IEEE 802.1X and WPA are not used. * IEEE 802.1X/WPA code will start accounting after the station has * been authorized. */ if (!hapd->conf->ieee802_1x && !hapd->conf->wpa) accounting_sta_start(hapd, sta); /* Start IEEE 802.1X authentication process for new stations */ ieee802_1x_new_station(hapd, sta); if (reassoc) wpa_sm_event(hapd, sta, WPA_REAUTH); else wpa_new_station(hapd, sta); }
STATIC void jswP2Failed(struct jsw_session *js, jsw_event_t event) { struct hostapd_data *hapd = js->hapd; struct sta_info *sta = js->sta; hostapd_logger(js->hapd, js->sta->addr, HOSTAPD_MODULE_JS, HOSTAPD_LEVEL_WARNING, "JS P2 failed"); hostapd_sta_deauth(hapd, sta->addr, WLAN_REASON_UNSPECIFIED); js_free_station(sta); }
static void hostapd_deauth_all_stas(hostapd *hapd) { #if 0 u8 addr[ETH_ALEN]; memset(addr, 0xff, ETH_ALEN); hostapd_sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID); #else /* New Prism2.5/3 STA firmware versions seem to have issues with this * broadcast deauth frame. This gets the firmware in odd state where * nothing works correctly, so let's skip sending this for a while * until the issue has been resolved. */ #endif }
/* This function will be called whenever a station associates with the AP */ void hostapd_new_assoc_sta(hostapd *hapd, struct sta_info *sta) { if (hapd->tkip_countermeasures) { hostapd_sta_deauth(hapd, sta->addr, WLAN_REASON_MICHAEL_MIC_FAILURE); return; } /* IEEE 802.11F (IAPP) */ if (hapd->conf->ieee802_11f) iapp_new_station(hapd->iapp, sta); /* Start accounting here, if IEEE 802.1X is not used. IEEE 802.1X code * will start accounting after the station has been authorized. */ if (!hapd->conf->ieee802_1x) accounting_sta_start(hapd, sta); #ifdef JUMPSTART if (hapd->conf->js_p1) { /* Only one STA at a time to attempt Jumpstart */ if (!hapd->jsw_profile->p1_in_progress) { hapd->jsw_profile->p1_in_progress = 1; HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "JUMPSTART: " MACSTR " %s: starting P1\n", MAC2STR(sta->addr), __func__); js_p1_new_station(hapd, sta); /* Start the JS state machine */ smSendEvent(sta->js_session, JSW_EVENT_ASSOC); } else { HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "JUMPSTART: " MACSTR "%s: P1 running with another STA." " Disassoc\n", MAC2STR(sta->addr), __func__); hostapd_sta_disassoc(hapd, sta->addr, WLAN_REASON_UNSPECIFIED); } return; } #endif /* JUMPSTART */ /* Start IEEE 802.1x authentication process for new stations */ ieee802_1x_new_station(hapd, sta); wpa_new_station(hapd, sta); }
void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx) { hostapd *hapd = eloop_ctx; struct sta_info *sta = timeout_ctx; if (!(sta->flags & WLAN_STA_AUTH)) return; hostapd_sta_deauth(hapd, sta->addr, WLAN_REASON_PREV_AUTH_NOT_VALID); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "deauthenticated due to " "session timeout"); sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_SESSION_TIMEOUT; ap_free_sta(hapd, sta); }
static void mac_auth_disconnect(struct hostapd_data * hapd, struct sta_info * sta) { if(hapd == NULL || hapd->iface == NULL || hapd->iface->pstWtp == NULL || sta == NULL){ ModuleLogMsg(APP_MODULE_HOSTAPD, APP_FATAL, "%s, point is NULL.\n", __func__) ; return ; } ModuleLogMsg(APP_MODULE_HOSTAPD, APP_DETAIL, "%s, sta(%u/%u/%u/"MACSTR"): disconnect.\n", __func__, hapd->iface->pstWtp->usWtpId, hapd->iface->interface_id, hapd->vap_id, MAC2STR(sta->addr)) ; hostapd_sta_deauth(hapd, sta->addr, WLAN_REASON_MAC_AUTH_FAILED | WLAN_REASON_UNSPECIFIED) ; sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_AUTHORIZED | WLAN_STA_AUTHORIZED_MAC); eloop_cancel_timeout(ap_handle_timer, hapd, sta); eloop_register_timeout(0, 0, ap_handle_timer, hapd, sta); sta->timeout_next = STA_REMOVE; }
void ap_handle_timer(void *eloop_ctx, void *timeout_ctx) { hostapd *hapd = eloop_ctx; struct sta_info *sta = timeout_ctx; unsigned long next_time = 0; if (sta->timeout_next == STA_REMOVE) { hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "deauthenticated due to " "local deauth request"); ap_free_sta(hapd, sta); return; } if ((sta->flags & WLAN_STA_ASSOC) && (sta->timeout_next == STA_NULLFUNC || sta->timeout_next == STA_DISASSOC)) { int inactive_sec; HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Checking STA " MACSTR " inactivity:\n", MAC2STR(sta->addr)); inactive_sec = hostapd_get_inact_sec(hapd, sta->addr); if (inactive_sec == -1) { printf(" Could not get station info from kernel " "driver for " MACSTR ".\n", MAC2STR(sta->addr)); } else if (inactive_sec < AP_MAX_INACTIVITY && sta->flags & WLAN_STA_ASSOC) { /* station activity detected; reset timeout state */ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " Station has been active\n"); sta->timeout_next = STA_NULLFUNC; next_time = AP_MAX_INACTIVITY - inactive_sec; } } if ((sta->flags & WLAN_STA_ASSOC) && sta->timeout_next == STA_DISASSOC && !(sta->flags & WLAN_STA_PENDING_POLL)) { HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " Station has ACKed data poll\n"); /* data nullfunc frame poll did not produce TX errors; assume * station ACKed it */ sta->timeout_next = STA_NULLFUNC; next_time = AP_MAX_INACTIVITY; } if (next_time) { eloop_register_timeout(next_time, 0, ap_handle_timer, hapd, sta); return; } if (sta->timeout_next == STA_NULLFUNC && (sta->flags & WLAN_STA_ASSOC)) { /* send data frame to poll STA and check whether this frame * is ACKed */ struct ieee80211_hdr hdr; HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " Polling STA with data frame\n"); sta->flags |= WLAN_STA_PENDING_POLL; /* FIX: WLAN_FC_STYPE_NULLFUNC would be more appropriate, but * it is apparently not retried so TX Exc events are not * received for it */ memset(&hdr, 0, sizeof(hdr)); hdr.frame_control = IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_DATA); hdr.frame_control |= host_to_le16(BIT(1)); hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS); memcpy(hdr.IEEE80211_DA_FROMDS, sta->addr, ETH_ALEN); memcpy(hdr.IEEE80211_BSSID_FROMDS, hapd->own_addr, ETH_ALEN); memcpy(hdr.IEEE80211_SA_FROMDS, hapd->own_addr, ETH_ALEN); if (hostapd_send_mgmt_frame(hapd, &hdr, sizeof(hdr), 0) < 0) perror("ap_handle_timer: send"); } else if (sta->timeout_next != STA_REMOVE) { int deauth = sta->timeout_next == STA_DEAUTH; printf(" Sending %s info to STA " MACSTR "\n", deauth ? "deauthentication" : "disassociation", MAC2STR(sta->addr)); if (deauth) { hostapd_sta_deauth(hapd, sta->addr, WLAN_REASON_PREV_AUTH_NOT_VALID); } else { hostapd_sta_disassoc( hapd, sta->addr, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); } } switch (sta->timeout_next) { case STA_NULLFUNC: sta->timeout_next = STA_DISASSOC; eloop_register_timeout(AP_DISASSOC_DELAY, 0, ap_handle_timer, hapd, sta); break; case STA_DISASSOC: sta->flags &= ~WLAN_STA_ASSOC; ieee802_1x_set_port_enabled(hapd, sta, 0); if (!sta->acct_terminate_cause) sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT; accounting_sta_stop(hapd, sta); ieee802_1x_free_station(sta); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "disassociated due to " "inactivity"); sta->timeout_next = STA_DEAUTH; eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer, hapd, sta); break; case STA_DEAUTH: case STA_REMOVE: hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "deauthenticated due to " "inactivity"); if (!sta->acct_terminate_cause) sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT; ap_free_sta(hapd, sta); break; } }
static void handle_data(struct hostapd_data *hapd, u8 *buf, size_t len, u16 stype) { struct ieee80211_hdr *hdr; u16 fc, ethertype; u8 *pos, *sa; size_t left; struct sta_info *sta; if (len < sizeof(struct ieee80211_hdr)) return; hdr = (struct ieee80211_hdr *) buf; fc = le_to_host16(hdr->frame_control); if ((fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) != WLAN_FC_TODS) { printf("Not ToDS data frame (fc=0x%04x)\n", fc); return; } sa = hdr->addr2; sta = ap_get_sta(hapd, sa); if (!sta || !(sta->flags & WLAN_STA_ASSOC)) { printf("Data frame from not associated STA " MACSTR "\n", MAC2STR(sa)); if (sta && (sta->flags & WLAN_STA_AUTH)) hostapd_sta_disassoc( hapd, sa, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); else hostapd_sta_deauth( hapd, sa, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); return; } pos = (u8 *) (hdr + 1); left = len - sizeof(*hdr); if (left < sizeof(rfc1042_header)) { printf("Too short data frame\n"); return; } if (memcmp(pos, rfc1042_header, sizeof(rfc1042_header)) != 0) { printf("Data frame with no RFC1042 header\n"); return; } pos += sizeof(rfc1042_header); left -= sizeof(rfc1042_header); if (left < 2) { printf("No ethertype in data frame\n"); return; } ethertype = WPA_GET_BE16(pos); pos += 2; left -= 2; switch (ethertype) { case ETH_P_PAE: ieee802_1x_receive(hapd, sa, pos, left); break; default: printf("Unknown ethertype 0x%04x in data frame\n", ethertype); break; } }