INT CFG80211_ApStaDel( IN VOID *pAdCB, IN UCHAR *pMac) { PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB; MAC_TABLE_ENTRY *pEntry; if (pMac == NULL) { #ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE /* From WCID=2 */ if (INFRA_ON(pAd)) ;//P2PMacTableReset(pAd); else #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */ MacTableReset(pAd); } else { pEntry = MacTableLookup(pAd, pMac); if (pEntry) { MlmeDeAuthAction(pAd, pEntry, REASON_NO_LONGER_VALID, FALSE); } else DBGPRINT(RT_DEBUG_ERROR, ("Can't find pEntry in ApStaDel\n")); } }
INT CFG80211_ApStaDel( IN VOID *pAdCB, IN UCHAR *pMac) { PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB; MAC_TABLE_ENTRY *pEntry; // INT startWcid = 1; if (pMac == NULL) { #ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE /* From WCID=2 */ if (INFRA_ON(pAd)) startWcid = 2; #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */ MacTableReset(pAd); } else { pEntry = MacTableLookup(pAd, pMac); if (pEntry) { MlmeDeAuthAction(pAd, pEntry, REASON_NO_LONGER_VALID, FALSE); } else MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR,("Can't find pEntry(%02x:%02x:%02x:%02x:%02x:%02x) in ApStaDel\n", PRINT_MAC(pMac))); } return 0; }
/* ======================================================================== Routine Description: Sending EAP Req. frame to station in authenticating state. These frames come from Authenticator deamon. Arguments: pAdapter Pointer to our adapter pPacket Pointer to outgoing EAP frame body + 8023 Header Len length of pPacket Return Value: None ======================================================================== */ VOID WpaSend(struct rtmp_adapter *pAdapter, u8 *pPacket, ULONG Len) { PEAP_HDR pEapHdr; u8 Addr[MAC_ADDR_LEN]; u8 Header802_3[LENGTH_802_3]; MAC_TABLE_ENTRY *pEntry; u8 *pData; memmove(Addr, pPacket, 6); memmove(Header802_3, pPacket, LENGTH_802_3); pEapHdr = (EAP_HDR*)(pPacket + LENGTH_802_3); pData = (pPacket + LENGTH_802_3); if ((pEntry = MacTableLookup(pAdapter, Addr)) == NULL) { return; } /* Send EAP frame to STA */ if (((pEntry->AuthMode >= Ndis802_11AuthModeWPA) && (pEapHdr->ProType != EAPOLKey)) || (pAdapter->ApCfg.MBSSID[pEntry->apidx].wdev.IEEE8021X == true)) RTMPToWirelessSta(pAdapter, pEntry, Header802_3, LENGTH_802_3, pData, Len - LENGTH_802_3, (pEntry->PortSecured == WPA_802_1X_PORT_SECURED) ? false : true); if (RTMPEqualMemory((pPacket+12), EAPOL, 2)) { switch (pEapHdr->code) { case EAP_CODE_REQUEST: if ((pEntry->WpaState >= AS_PTKINITDONE) && (pEapHdr->ProType == EAPPacket)) { pEntry->WpaState = AS_AUTHENTICATION; DBGPRINT(RT_DEBUG_TRACE, ("Start to re-authentication by 802.1x daemon\n")); } break; /* After receiving EAP_SUCCESS, trigger state machine */ case EAP_CODE_SUCCESS: if ((pEntry->AuthMode >= Ndis802_11AuthModeWPA) && (pEapHdr->ProType != EAPOLKey)) { DBGPRINT(RT_DEBUG_TRACE,("Send EAP_CODE_SUCCESS\n\n")); if (pEntry->Sst == SST_ASSOC) { pEntry->WpaState = AS_INITPMK; /* Only set the expire and counters */ pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR; WPAStart4WayHS(pAdapter, pEntry, PEER_MSG1_RETRY_EXEC_INTV); } } else { pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; pEntry->WpaState = AS_PTKINITDONE; pAdapter->ApCfg.MBSSID[pEntry->apidx].wdev.PortSecured = WPA_802_1X_PORT_SECURED; pEntry->PortSecured = WPA_802_1X_PORT_SECURED; DBGPRINT(RT_DEBUG_TRACE,("IEEE8021X-WEP : Send EAP_CODE_SUCCESS\n\n")); } break; case EAP_CODE_FAILURE: break; default: break; } } else { DBGPRINT(RT_DEBUG_TRACE, ("Send Deauth, Reason : REASON_NO_LONGER_VALID\n")); MlmeDeAuthAction(pAdapter, pEntry, REASON_NO_LONGER_VALID, false); } }
VOID WPARetryExec( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { MAC_TABLE_ENTRY *pEntry = (MAC_TABLE_ENTRY *)FunctionContext; if ((pEntry) && IS_ENTRY_CLIENT(pEntry)) { struct rtmp_adapter *pAd = (struct rtmp_adapter *)pEntry->pAd; pEntry->ReTryCounter++; DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec---> ReTryCounter=%d, WpaState=%d \n", pEntry->ReTryCounter, pEntry->WpaState)); switch (pEntry->AuthMode) { case Ndis802_11AuthModeWPA: case Ndis802_11AuthModeWPAPSK: case Ndis802_11AuthModeWPA2: case Ndis802_11AuthModeWPA2PSK: /* 1. GTK already retried, give up and disconnect client. */ if (pEntry->ReTryCounter > (GROUP_MSG1_RETRY_TIMER_CTR + 1)) { /* send wireless event - for group key handshaking timeout */ RTMPSendWirelessEvent(pAd, IW_GROUP_HS_TIMEOUT_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::Group Key HS exceed retry count, Disassociate client, pEntry->ReTryCounter %d\n", pEntry->ReTryCounter)); MlmeDeAuthAction(pAd, pEntry, REASON_GROUP_KEY_HS_TIMEOUT, false); } /* 2. Retry GTK. */ else if (pEntry->ReTryCounter > GROUP_MSG1_RETRY_TIMER_CTR) { DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::ReTry 2-way group-key Handshake \n")); if (pEntry->GTKState == REKEY_NEGOTIATING) { WPAStart2WayGroupHS(pAd, pEntry); RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV); } } /* 3. 4-way message 1 retried more than three times. Disconnect client */ else if (pEntry->ReTryCounter > (PEER_MSG1_RETRY_TIMER_CTR + 3)) { /* send wireless event - for pairwise key handshaking timeout */ RTMPSendWirelessEvent(pAd, IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::MSG1 timeout, pEntry->ReTryCounter = %d\n", pEntry->ReTryCounter)); MlmeDeAuthAction(pAd, pEntry, REASON_4_WAY_TIMEOUT, false); } /* 4. Retry 4 way message 1, the last try, the timeout is 3 sec for EAPOL-Start */ else if (pEntry->ReTryCounter == (PEER_MSG1_RETRY_TIMER_CTR + 3)) { DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::Retry MSG1, the last try\n")); WPAStart4WayHS(pAd , pEntry, PEER_MSG3_RETRY_EXEC_INTV); } /* 4. Retry 4 way message 1 */ else if (pEntry->ReTryCounter < (PEER_MSG1_RETRY_TIMER_CTR + 3)) { if ((pEntry->WpaState == AS_PTKSTART) || (pEntry->WpaState == AS_INITPSK) || (pEntry->WpaState == AS_INITPMK)) { DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::ReTry MSG1 of 4-way Handshake\n")); WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV); } } break; default: break; } } }
/* ========================================================================== Description: Function to handle countermeasures active attack. Init 60-sec timer if necessary. Return: ========================================================================== */ VOID HandleCounterMeasure(struct rtmp_adapter *pAd, MAC_TABLE_ENTRY *pEntry) { INT i; bool Cancelled; if (!pEntry) return; /* Todo by AlbertY - Not support currently in ApClient-link */ if (IS_ENTRY_APCLI(pEntry)) return; /* if entry not set key done, ignore this RX MIC ERROR */ if ((pEntry->WpaState < AS_PTKINITDONE) || (pEntry->GTKState != REKEY_ESTABLISHED)) return; DBGPRINT(RT_DEBUG_TRACE, ("HandleCounterMeasure ===> \n")); /* record which entry causes this MIC error, if this entry sends disauth/disassoc, AP doesn't need to log the CM */ pEntry->CMTimerRunning = true; pAd->ApCfg.MICFailureCounter++; /* send wireless event - for MIC error */ RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pEntry->Addr, 0, 0); if (pAd->ApCfg.CMTimerRunning == true) { DBGPRINT(RT_DEBUG_ERROR, ("Receive CM Attack Twice within 60 seconds ====>>> \n")); /* send wireless event - for counter measures */ RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pEntry->Addr, 0, 0); ApLogEvent(pAd, pEntry->Addr, EVENT_COUNTER_M); /* renew GTK */ GenRandom(pAd, pAd->ApCfg.MBSSID[pEntry->apidx].wdev.bssid, pAd->ApCfg.MBSSID[pEntry->apidx].GNonce); /* Cancel CounterMeasure Timer */ RTMPCancelTimer(&pAd->ApCfg.CounterMeasureTimer, &Cancelled); pAd->ApCfg.CMTimerRunning = false; for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) { /* happened twice within 60 sec, AP SENDS disaccociate all associated STAs. All STA's transition to State 2 */ if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[i])) { MlmeDeAuthAction(pAd, &pAd->MacTab.Content[i], REASON_MIC_FAILURE, false); } } /* Further, ban all Class 3 DATA transportation for a period 0f 60 sec disallow new association , too */ pAd->ApCfg.BANClass3Data = true; /* check how many entry left... should be zero */ /*pAd->ApCfg.MBSSID[pEntry->apidx].GKeyDoneStations = pAd->MacTab.Size; */ /*DBGPRINT(RT_DEBUG_TRACE, ("GKeyDoneStations=%d \n", pAd->ApCfg.MBSSID[pEntry->apidx].GKeyDoneStations)); */ } RTMPSetTimer(&pAd->ApCfg.CounterMeasureTimer, 60 * MLME_TASK_EXEC_INTV * MLME_TASK_EXEC_MULTIPLE); pAd->ApCfg.CMTimerRunning = true; pAd->ApCfg.PrevaMICFailTime = pAd->ApCfg.aMICFailTime; RTMP_GetCurrentSystemTime(&pAd->ApCfg.aMICFailTime); }
VOID WPARetryExec( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { MAC_TABLE_ENTRY *pEntry = (MAC_TABLE_ENTRY *)FunctionContext; if ((pEntry) && IS_ENTRY_CLIENT(pEntry)) { PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pEntry->pAd; pEntry->ReTryCounter++; DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec---> ReTryCounter=%d, WpaState=%d \n", pEntry->ReTryCounter, pEntry->WpaState)); switch (pEntry->AuthMode) { case Ndis802_11AuthModeWPA: case Ndis802_11AuthModeWPAPSK: case Ndis802_11AuthModeWPA2: case Ndis802_11AuthModeWPA2PSK: /* 1. GTK already retried, give up and disconnect client. */ if (pEntry->ReTryCounter > (GROUP_MSG1_RETRY_TIMER_CTR + 1)) { /* send wireless event - for group key handshaking timeout */ RTMPSendWirelessEvent(pAd, IW_GROUP_HS_TIMEOUT_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::Group Key HS exceed retry count, Disassociate client, pEntry->ReTryCounter %d\n", pEntry->ReTryCounter)); MlmeDeAuthAction(pAd, pEntry, REASON_GROUP_KEY_HS_TIMEOUT, FALSE); } /* 2. Retry GTK. */ else if (pEntry->ReTryCounter > GROUP_MSG1_RETRY_TIMER_CTR) { DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::ReTry 2-way group-key Handshake \n")); if (pEntry->GTKState == REKEY_NEGOTIATING) { WPAStart2WayGroupHS(pAd, pEntry); RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV); } } /* 3. 4-way message 1 retried more than three times. Disconnect client */ else if (pEntry->ReTryCounter > (PEER_MSG1_RETRY_TIMER_CTR + 3)) { /* send wireless event - for pairwise key handshaking timeout */ RTMPSendWirelessEvent(pAd, IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::MSG1 timeout, pEntry->ReTryCounter = %d\n", pEntry->ReTryCounter)); MlmeDeAuthAction(pAd, pEntry, REASON_4_WAY_TIMEOUT, FALSE); } /* 4. Retry 4 way message 1, the last try, the timeout is 3 sec for EAPOL-Start */ else if (pEntry->ReTryCounter == (PEER_MSG1_RETRY_TIMER_CTR + 3)) { DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::Retry MSG1, the last try\n")); WPAStart4WayHS(pAd , pEntry, PEER_MSG3_RETRY_EXEC_INTV); } /* 4. Retry 4 way message 1 */ else if (pEntry->ReTryCounter < (PEER_MSG1_RETRY_TIMER_CTR + 3)) { if ((pEntry->WpaState == AS_PTKSTART) || (pEntry->WpaState == AS_INITPSK) || (pEntry->WpaState == AS_INITPMK)) { DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::ReTry MSG1 of 4-way Handshake\n")); WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV); } } break; default: break; } } #ifdef APCLI_SUPPORT else if ((pEntry) && IS_ENTRY_APCLI(pEntry)) { if (pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) { PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pEntry->pAd; if (pEntry->wdev_idx < MAX_APCLI_NUM) { UCHAR ifIndex = pEntry->wdev_idx; DBGPRINT(RT_DEBUG_TRACE, ("(%s) ApCli interface[%d] startdown.\n", __FUNCTION__, ifIndex)); #ifdef MAC_REPEATER_SUPPORT if ((pEntry->bReptCli) && (pAd->ApCfg.bMACRepeaterEn == TRUE)) ifIndex = (64 + ifIndex*MAX_EXT_MAC_ADDR_SIZE + pEntry->MatchReptCliIdx); #endif /* MAC_REPEATER_SUPPORT */ #ifdef MAC_REPEATER_SUPPORT if ( (pAd->ApCfg.bMACRepeaterEn == TRUE) && (pEntry->bReptCli)) { RTMPRemoveRepeaterDisconnectEntry(pAd, pEntry->wdev_idx, pEntry->MatchReptCliIdx); RTMPRemoveRepeaterEntry(pAd, pEntry->wdev_idx, pEntry->MatchReptCliIdx); } else MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DISCONNECT_REQ, 0, NULL, ifIndex); #endif /* MAC_REPEATER_SUPPORT */ } } } #endif /* APCLI_SUPPORT */ }