diff options
Diffstat (limited to 'drivers/staging/rt2860/common/cmm_sanity.c')
-rw-r--r-- | drivers/staging/rt2860/common/cmm_sanity.c | 1635 |
1 files changed, 893 insertions, 742 deletions
diff --git a/drivers/staging/rt2860/common/cmm_sanity.c b/drivers/staging/rt2860/common/cmm_sanity.c index 85855f7f38c..6b003c90344 100644 --- a/drivers/staging/rt2860/common/cmm_sanity.c +++ b/drivers/staging/rt2860/common/cmm_sanity.c @@ -36,17 +36,16 @@ */ #include "../rt_config.h" +extern u8 CISCO_OUI[]; -extern UCHAR CISCO_OUI[]; - -extern UCHAR WPA_OUI[]; -extern UCHAR RSN_OUI[]; -extern UCHAR WME_INFO_ELEM[]; -extern UCHAR WME_PARM_ELEM[]; -extern UCHAR Ccx2QosInfo[]; -extern UCHAR RALINK_OUI[]; -extern UCHAR BROADCOM_OUI[]; -extern UCHAR WPS_OUI[]; +extern u8 WPA_OUI[]; +extern u8 RSN_OUI[]; +extern u8 WME_INFO_ELEM[]; +extern u8 WME_PARM_ELEM[]; +extern u8 Ccx2QosInfo[]; +extern u8 RALINK_OUI[]; +extern u8 BROADCOM_OUI[]; +extern u8 WPS_OUI[]; /* ========================================================================== @@ -59,35 +58,32 @@ extern UCHAR WPS_OUI[]; ========================================================================== */ -BOOLEAN MlmeAddBAReqSanity( - IN PRTMP_ADAPTER pAd, - IN VOID *Msg, - IN ULONG MsgLen, - OUT PUCHAR pAddr2) +BOOLEAN MlmeAddBAReqSanity(struct rt_rtmp_adapter *pAd, + void * Msg, unsigned long MsgLen, u8 *pAddr2) { - PMLME_ADDBA_REQ_STRUCT pInfo; + struct rt_mlme_addba_req *pInfo; - pInfo = (MLME_ADDBA_REQ_STRUCT *)Msg; + pInfo = (struct rt_mlme_addba_req *)Msg; - if ((MsgLen != sizeof(MLME_ADDBA_REQ_STRUCT))) - { - DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - message lenght not correct.\n")); - return FALSE; - } + if ((MsgLen != sizeof(struct rt_mlme_addba_req))) { + DBGPRINT(RT_DEBUG_TRACE, + ("MlmeAddBAReqSanity fail - message lenght not correct.\n")); + return FALSE; + } - if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE)) - { - DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n")); - return FALSE; - } + if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE)) { + DBGPRINT(RT_DEBUG_TRACE, + ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n")); + return FALSE; + } - if ((pInfo->pAddr[0]&0x01) == 0x01) - { - DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - broadcast address not support BA\n")); - return FALSE; - } + if ((pInfo->pAddr[0] & 0x01) == 0x01) { + DBGPRINT(RT_DEBUG_TRACE, + ("MlmeAddBAReqSanity fail - broadcast address not support BA\n")); + return FALSE; + } - return TRUE; + return TRUE; } /* @@ -101,131 +97,133 @@ BOOLEAN MlmeAddBAReqSanity( ========================================================================== */ -BOOLEAN MlmeDelBAReqSanity( - IN PRTMP_ADAPTER pAd, - IN VOID *Msg, - IN ULONG MsgLen) +BOOLEAN MlmeDelBAReqSanity(struct rt_rtmp_adapter *pAd, void * Msg, unsigned long MsgLen) { - MLME_DELBA_REQ_STRUCT *pInfo; - pInfo = (MLME_DELBA_REQ_STRUCT *)Msg; - - if ((MsgLen != sizeof(MLME_DELBA_REQ_STRUCT))) - { - DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - message lenght not correct.\n")); - return FALSE; - } - - if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE)) - { - DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n")); - return FALSE; - } - - if ((pInfo->TID & 0xf0)) - { - DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n")); - return FALSE; - } - - if (NdisEqualMemory(pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr, MAC_ADDR_LEN) == 0) - { - DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n")); - return FALSE; - } - - return TRUE; + struct rt_mlme_delba_req *pInfo; + pInfo = (struct rt_mlme_delba_req *)Msg; + + if ((MsgLen != sizeof(struct rt_mlme_delba_req))) { + DBGPRINT(RT_DEBUG_ERROR, + ("MlmeDelBAReqSanity fail - message lenght not correct.\n")); + return FALSE; + } + + if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE)) { + DBGPRINT(RT_DEBUG_ERROR, + ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n")); + return FALSE; + } + + if ((pInfo->TID & 0xf0)) { + DBGPRINT(RT_DEBUG_ERROR, + ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n")); + return FALSE; + } + + if (NdisEqualMemory + (pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr, + MAC_ADDR_LEN) == 0) { + DBGPRINT(RT_DEBUG_ERROR, + ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n")); + return FALSE; + } + + return TRUE; } -BOOLEAN PeerAddBAReqActionSanity( - IN PRTMP_ADAPTER pAd, - IN VOID *pMsg, - IN ULONG MsgLen, - OUT PUCHAR pAddr2) +BOOLEAN PeerAddBAReqActionSanity(struct rt_rtmp_adapter *pAd, + void * pMsg, + unsigned long MsgLen, u8 *pAddr2) { - PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg; - PFRAME_ADDBA_REQ pAddFrame; - pAddFrame = (PFRAME_ADDBA_REQ)(pMsg); - if (MsgLen < (sizeof(FRAME_ADDBA_REQ))) - { - DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n", MsgLen)); + struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) pMsg; + struct rt_frame_addba_req * pAddFrame; + pAddFrame = (struct rt_frame_addba_req *) (pMsg); + if (MsgLen < (sizeof(struct rt_frame_addba_req))) { + DBGPRINT(RT_DEBUG_ERROR, + ("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n", + MsgLen)); return FALSE; } - // we support immediate BA. - *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm)); + /* we support immediate BA. */ + *(u16 *) (&pAddFrame->BaParm) = + cpu2le16(*(u16 *) (&pAddFrame->BaParm)); pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue); pAddFrame->BaStartSeq.word = cpu2le16(pAddFrame->BaStartSeq.word); - if (pAddFrame->BaParm.BAPolicy != IMMED_BA) - { - DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy)); - DBGPRINT(RT_DEBUG_ERROR,("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n", pAddFrame->BaParm.TID, pAddFrame->BaParm.BufSize, pAddFrame->BaParm.AMSDUSupported)); + if (pAddFrame->BaParm.BAPolicy != IMMED_BA) { + DBGPRINT(RT_DEBUG_ERROR, + ("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n", + pAddFrame->BaParm.BAPolicy)); + DBGPRINT(RT_DEBUG_ERROR, + ("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n", + pAddFrame->BaParm.TID, pAddFrame->BaParm.BufSize, + pAddFrame->BaParm.AMSDUSupported)); return FALSE; } - - // we support immediate BA. - if (pAddFrame->BaParm.TID &0xfff0) - { - DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request incorrect TID = %d\n", pAddFrame->BaParm.TID)); + /* we support immediate BA. */ + if (pAddFrame->BaParm.TID & 0xfff0) { + DBGPRINT(RT_DEBUG_ERROR, + ("PeerAddBAReqActionSanity: ADDBA Request incorrect TID = %d\n", + pAddFrame->BaParm.TID)); return FALSE; } COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); return TRUE; } -BOOLEAN PeerAddBARspActionSanity( - IN PRTMP_ADAPTER pAd, - IN VOID *pMsg, - IN ULONG MsgLen) +BOOLEAN PeerAddBARspActionSanity(struct rt_rtmp_adapter *pAd, + void * pMsg, unsigned long MsgLen) { - PFRAME_ADDBA_RSP pAddFrame; + struct rt_frame_addba_rsp * pAddFrame; - pAddFrame = (PFRAME_ADDBA_RSP)(pMsg); - if (MsgLen < (sizeof(FRAME_ADDBA_RSP))) - { - DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n", MsgLen)); + pAddFrame = (struct rt_frame_addba_rsp *) (pMsg); + if (MsgLen < (sizeof(struct rt_frame_addba_rsp))) { + DBGPRINT(RT_DEBUG_ERROR, + ("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n", + MsgLen)); return FALSE; } - // we support immediate BA. - *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm)); + /* we support immediate BA. */ + *(u16 *) (&pAddFrame->BaParm) = + cpu2le16(*(u16 *) (&pAddFrame->BaParm)); pAddFrame->StatusCode = cpu2le16(pAddFrame->StatusCode); pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue); - if (pAddFrame->BaParm.BAPolicy != IMMED_BA) - { - DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy)); + if (pAddFrame->BaParm.BAPolicy != IMMED_BA) { + DBGPRINT(RT_DEBUG_ERROR, + ("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n", + pAddFrame->BaParm.BAPolicy)); return FALSE; } - - // we support immediate BA. - if (pAddFrame->BaParm.TID &0xfff0) - { - DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response incorrect TID = %d\n", pAddFrame->BaParm.TID)); + /* we support immediate BA. */ + if (pAddFrame->BaParm.TID & 0xfff0) { + DBGPRINT(RT_DEBUG_ERROR, + ("PeerAddBARspActionSanity: ADDBA Response incorrect TID = %d\n", + pAddFrame->BaParm.TID)); return FALSE; } return TRUE; } -BOOLEAN PeerDelBAActionSanity( - IN PRTMP_ADAPTER pAd, - IN UCHAR Wcid, - IN VOID *pMsg, - IN ULONG MsgLen ) +BOOLEAN PeerDelBAActionSanity(struct rt_rtmp_adapter *pAd, + u8 Wcid, void * pMsg, unsigned long MsgLen) { - //PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg; - PFRAME_DELBA_REQ pDelFrame; - if (MsgLen != (sizeof(FRAME_DELBA_REQ))) + /*struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *)pMsg; */ + struct rt_frame_delba_req * pDelFrame; + if (MsgLen != (sizeof(struct rt_frame_delba_req))) return FALSE; if (Wcid >= MAX_LEN_OF_MAC_TABLE) return FALSE; - pDelFrame = (PFRAME_DELBA_REQ)(pMsg); + pDelFrame = (struct rt_frame_delba_req *) (pMsg); - *(USHORT *)(&pDelFrame->DelbaParm) = cpu2le16(*(USHORT *)(&pDelFrame->DelbaParm)); + *(u16 *) (&pDelFrame->DelbaParm) = + cpu2le16(*(u16 *) (&pDelFrame->DelbaParm)); pDelFrame->ReasonCode = cpu2le16(pDelFrame->ReasonCode); - if (pDelFrame->DelbaParm.TID &0xfff0) + if (pDelFrame->DelbaParm.TID & 0xfff0) return FALSE; return TRUE; @@ -242,472 +240,469 @@ BOOLEAN PeerDelBAActionSanity( ========================================================================== */ -BOOLEAN PeerBeaconAndProbeRspSanity( - IN PRTMP_ADAPTER pAd, - IN VOID *Msg, - IN ULONG MsgLen, - IN UCHAR MsgChannel, - OUT PUCHAR pAddr2, - OUT PUCHAR pBssid, - OUT CHAR Ssid[], - OUT UCHAR *pSsidLen, - OUT UCHAR *pBssType, - OUT USHORT *pBeaconPeriod, - OUT UCHAR *pChannel, - OUT UCHAR *pNewChannel, - OUT LARGE_INTEGER *pTimestamp, - OUT CF_PARM *pCfParm, - OUT USHORT *pAtimWin, - OUT USHORT *pCapabilityInfo, - OUT UCHAR *pErp, - OUT UCHAR *pDtimCount, - OUT UCHAR *pDtimPeriod, - OUT UCHAR *pBcastFlag, - OUT UCHAR *pMessageToMe, - OUT UCHAR SupRate[], - OUT UCHAR *pSupRateLen, - OUT UCHAR ExtRate[], - OUT UCHAR *pExtRateLen, - OUT UCHAR *pCkipFlag, - OUT UCHAR *pAironetCellPowerLimit, - OUT PEDCA_PARM pEdcaParm, - OUT PQBSS_LOAD_PARM pQbssLoad, - OUT PQOS_CAPABILITY_PARM pQosCapability, - OUT ULONG *pRalinkIe, - OUT UCHAR *pHtCapabilityLen, - OUT UCHAR *pPreNHtCapabilityLen, - OUT HT_CAPABILITY_IE *pHtCapability, - OUT UCHAR *AddHtInfoLen, - OUT ADD_HT_INFO_IE *AddHtInfo, - OUT UCHAR *NewExtChannelOffset, // Ht extension channel offset(above or below) - OUT USHORT *LengthVIE, - OUT PNDIS_802_11_VARIABLE_IEs pVIE) +BOOLEAN PeerBeaconAndProbeRspSanity(struct rt_rtmp_adapter *pAd, void * Msg, unsigned long MsgLen, u8 MsgChannel, u8 *pAddr2, u8 *pBssid, char Ssid[], u8 * pSsidLen, u8 * pBssType, u16 * pBeaconPeriod, u8 * pChannel, u8 * pNewChannel, OUT LARGE_INTEGER * pTimestamp, struct rt_cf_parm * pCfParm, u16 * pAtimWin, u16 * pCapabilityInfo, u8 * pErp, u8 * pDtimCount, u8 * pDtimPeriod, u8 * pBcastFlag, u8 * pMessageToMe, u8 SupRate[], u8 * pSupRateLen, u8 ExtRate[], u8 * pExtRateLen, u8 * pCkipFlag, u8 * pAironetCellPowerLimit, struct rt_edca_parm *pEdcaParm, struct rt_qbss_load_parm *pQbssLoad, struct rt_qos_capability_parm *pQosCapability, unsigned long * pRalinkIe, u8 * pHtCapabilityLen, u8 * pPreNHtCapabilityLen, struct rt_ht_capability_ie * pHtCapability, u8 * AddHtInfoLen, struct rt_add_ht_info_ie * AddHtInfo, u8 * NewExtChannelOffset, /* Ht extension channel offset(above or below) */ + u16 * LengthVIE, + struct rt_ndis_802_11_variable_ies *pVIE) { - CHAR *Ptr; - CHAR TimLen; - PFRAME_802_11 pFrame; - PEID_STRUCT pEid; - UCHAR SubType; - UCHAR Sanity; - //UCHAR ECWMin, ECWMax; - //MAC_CSR9_STRUC Csr9; - ULONG Length = 0; - - // For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel - // 1. If the AP is 11n enabled, then check the control channel. - // 2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!!) - UCHAR CtrlChannel = 0; - - // Add for 3 necessary EID field check - Sanity = 0; - - *pAtimWin = 0; - *pErp = 0; - *pDtimCount = 0; - *pDtimPeriod = 0; - *pBcastFlag = 0; - *pMessageToMe = 0; - *pExtRateLen = 0; - *pCkipFlag = 0; // Default of CkipFlag is 0 - *pAironetCellPowerLimit = 0xFF; // Default of AironetCellPowerLimit is 0xFF - *LengthVIE = 0; // Set the length of VIE to init value 0 - *pHtCapabilityLen = 0; // Set the length of VIE to init value 0 + u8 *Ptr; + u8 TimLen; + struct rt_frame_802_11 * pFrame; + struct rt_eid * pEid; + u8 SubType; + u8 Sanity; + /*u8 ECWMin, ECWMax; */ + /*MAC_CSR9_STRUC Csr9; */ + unsigned long Length = 0; + + /* For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel */ + /* 1. If the AP is 11n enabled, then check the control channel. */ + /* 2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!) */ + u8 CtrlChannel = 0; + + /* Add for 3 necessary EID field check */ + Sanity = 0; + + *pAtimWin = 0; + *pErp = 0; + *pDtimCount = 0; + *pDtimPeriod = 0; + *pBcastFlag = 0; + *pMessageToMe = 0; + *pExtRateLen = 0; + *pCkipFlag = 0; /* Default of CkipFlag is 0 */ + *pAironetCellPowerLimit = 0xFF; /* Default of AironetCellPowerLimit is 0xFF */ + *LengthVIE = 0; /* Set the length of VIE to init value 0 */ + *pHtCapabilityLen = 0; /* Set the length of VIE to init value 0 */ if (pAd->OpMode == OPMODE_STA) - *pPreNHtCapabilityLen = 0; // Set the length of VIE to init value 0 - *AddHtInfoLen = 0; // Set the length of VIE to init value 0 - *pRalinkIe = 0; - *pNewChannel = 0; - *NewExtChannelOffset = 0xff; //Default 0xff means no such IE - pCfParm->bValid = FALSE; // default: no IE_CF found - pQbssLoad->bValid = FALSE; // default: no IE_QBSS_LOAD found - pEdcaParm->bValid = FALSE; // default: no IE_EDCA_PARAMETER found - pQosCapability->bValid = FALSE; // default: no IE_QOS_CAPABILITY found + *pPreNHtCapabilityLen = 0; /* Set the length of VIE to init value 0 */ + *AddHtInfoLen = 0; /* Set the length of VIE to init value 0 */ + *pRalinkIe = 0; + *pNewChannel = 0; + *NewExtChannelOffset = 0xff; /*Default 0xff means no such IE */ + pCfParm->bValid = FALSE; /* default: no IE_CF found */ + pQbssLoad->bValid = FALSE; /* default: no IE_QBSS_LOAD found */ + pEdcaParm->bValid = FALSE; /* default: no IE_EDCA_PARAMETER found */ + pQosCapability->bValid = FALSE; /* default: no IE_QOS_CAPABILITY found */ + + pFrame = (struct rt_frame_802_11 *) Msg; + + /* get subtype from header */ + SubType = (u8)pFrame->Hdr.FC.SubType; + + /* get Addr2 and BSSID from header */ + COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); + COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3); - pFrame = (PFRAME_802_11)Msg; + Ptr = pFrame->Octet; + Length += LENGTH_802_11; - // get subtype from header - SubType = (UCHAR)pFrame->Hdr.FC.SubType; + /* get timestamp from payload and advance the pointer */ + NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN); - // get Addr2 and BSSID from header - COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); - COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3); + pTimestamp->u.LowPart = cpu2le32(pTimestamp->u.LowPart); + pTimestamp->u.HighPart = cpu2le32(pTimestamp->u.HighPart); - Ptr = pFrame->Octet; - Length += LENGTH_802_11; + Ptr += TIMESTAMP_LEN; + Length += TIMESTAMP_LEN; - // get timestamp from payload and advance the pointer - NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN); + /* get beacon interval from payload and advance the pointer */ + NdisMoveMemory(pBeaconPeriod, Ptr, 2); + Ptr += 2; + Length += 2; - pTimestamp->u.LowPart = cpu2le32(pTimestamp->u.LowPart); - pTimestamp->u.HighPart = cpu2le32(pTimestamp->u.HighPart); + /* get capability info from payload and advance the pointer */ + NdisMoveMemory(pCapabilityInfo, Ptr, 2); + Ptr += 2; + Length += 2; + + if (CAP_IS_ESS_ON(*pCapabilityInfo)) + *pBssType = BSS_INFRA; + else + *pBssType = BSS_ADHOC; + + pEid = (struct rt_eid *) Ptr; + + /* get variable fields from payload and advance the pointer */ + while ((Length + 2 + pEid->Len) <= MsgLen) { + /* */ + /* Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow. */ + /* */ + if ((*LengthVIE + pEid->Len + 2) >= MAX_VIE_LEN) { + DBGPRINT(RT_DEBUG_WARN, + ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n", + (*LengthVIE + pEid->Len + 2), MAX_VIE_LEN)); + break; + } - Ptr += TIMESTAMP_LEN; - Length += TIMESTAMP_LEN; - - // get beacon interval from payload and advance the pointer - NdisMoveMemory(pBeaconPeriod, Ptr, 2); - Ptr += 2; - Length += 2; - - // get capability info from payload and advance the pointer - NdisMoveMemory(pCapabilityInfo, Ptr, 2); - Ptr += 2; - Length += 2; - - if (CAP_IS_ESS_ON(*pCapabilityInfo)) - *pBssType = BSS_INFRA; - else - *pBssType = BSS_ADHOC; - - pEid = (PEID_STRUCT) Ptr; - - // get variable fields from payload and advance the pointer - while ((Length + 2 + pEid->Len) <= MsgLen) - { - // - // Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow. - // - if ((*LengthVIE + pEid->Len + 2) >= MAX_VIE_LEN) - { - DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n", - (*LengthVIE + pEid->Len + 2), MAX_VIE_LEN)); - break; - } - - switch(pEid->Eid) - { - case IE_SSID: - // Already has one SSID EID in this beacon, ignore the second one - if (Sanity & 0x1) - break; - if(pEid->Len <= MAX_LEN_OF_SSID) - { - NdisMoveMemory(Ssid, pEid->Octet, pEid->Len); - *pSsidLen = pEid->Len; - Sanity |= 0x1; - } - else - { - DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len)); - return FALSE; - } - break; - - case IE_SUPP_RATES: - if(pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) - { - Sanity |= 0x2; - NdisMoveMemory(SupRate, pEid->Octet, pEid->Len); - *pSupRateLen = pEid->Len; - - // TODO: 2004-09-14 not a good design here, cause it exclude extra rates - // from ScanTab. We should report as is. And filter out unsupported - // rates in MlmeAux. - // Check against the supported rates - // RTMPCheckRates(pAd, SupRate, pSupRateLen); - } - else - { - DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n",pEid->Len)); - return FALSE; - } - break; - - case IE_HT_CAP: - if (pEid->Len >= SIZE_HT_CAP_IE) //Note: allow extension.!! + switch (pEid->Eid) { + case IE_SSID: + /* Already has one SSID EID in this beacon, ignore the second one */ + if (Sanity & 0x1) + break; + if (pEid->Len <= MAX_LEN_OF_SSID) { + NdisMoveMemory(Ssid, pEid->Octet, pEid->Len); + *pSsidLen = pEid->Len; + Sanity |= 0x1; + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n", + pEid->Len)); + return FALSE; + } + break; + + case IE_SUPP_RATES: + if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) { + Sanity |= 0x2; + NdisMoveMemory(SupRate, pEid->Octet, pEid->Len); + *pSupRateLen = pEid->Len; + + /* TODO: 2004-09-14 not a good design here, cause it exclude extra rates */ + /* from ScanTab. We should report as is. And filter out unsupported */ + /* rates in MlmeAux. */ + /* Check against the supported rates */ + /* RTMPCheckRates(pAd, SupRate, pSupRateLen); */ + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n", + pEid->Len)); + return FALSE; + } + break; + + case IE_HT_CAP: + if (pEid->Len >= SIZE_HT_CAP_IE) /*Note: allow extension! */ { - NdisMoveMemory(pHtCapability, pEid->Octet, sizeof(HT_CAPABILITY_IE)); - *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes. + NdisMoveMemory(pHtCapability, pEid->Octet, + sizeof(struct rt_ht_capability_ie)); + *pHtCapabilityLen = SIZE_HT_CAP_IE; /* Nnow we only support 26 bytes. */ - *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo)); - *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo)); + *(u16 *) (&pHtCapability->HtCapInfo) = + cpu2le16(*(u16 *) + (&pHtCapability->HtCapInfo)); + *(u16 *) (&pHtCapability->ExtHtCapInfo) = + cpu2le16(*(u16 *) + (&pHtCapability->ExtHtCapInfo)); { - *pPreNHtCapabilityLen = 0; // Nnow we only support 26 bytes. + *pPreNHtCapabilityLen = 0; /* Nnow we only support 26 bytes. */ - Ptr = (PUCHAR) pVIE; - NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2); + Ptr = (u8 *)pVIE; + NdisMoveMemory(Ptr + *LengthVIE, + &pEid->Eid, + pEid->Len + 2); *LengthVIE += (pEid->Len + 2); } - } - else - { - DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n", pEid->Len)); + } else { + DBGPRINT(RT_DEBUG_WARN, + ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n", + pEid->Len)); } - break; - case IE_ADD_HT: - if (pEid->Len >= sizeof(ADD_HT_INFO_IE)) - { - // This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only - // copy first sizeof(ADD_HT_INFO_IE) - NdisMoveMemory(AddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE)); + break; + case IE_ADD_HT: + if (pEid->Len >= sizeof(struct rt_add_ht_info_ie)) { + /* This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only */ + /* copy first sizeof(struct rt_add_ht_info_ie) */ + NdisMoveMemory(AddHtInfo, pEid->Octet, + sizeof(struct rt_add_ht_info_ie)); *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; CtrlChannel = AddHtInfo->ControlChan; - *(USHORT *)(&AddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo2)); - *(USHORT *)(&AddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo3)); + *(u16 *) (&AddHtInfo->AddHtInfo2) = + cpu2le16(*(u16 *) + (&AddHtInfo->AddHtInfo2)); + *(u16 *) (&AddHtInfo->AddHtInfo3) = + cpu2le16(*(u16 *) + (&AddHtInfo->AddHtInfo3)); { - Ptr = (PUCHAR) pVIE; - NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2); - *LengthVIE += (pEid->Len + 2); + Ptr = (u8 *)pVIE; + NdisMoveMemory(Ptr + *LengthVIE, + &pEid->Eid, + pEid->Len + 2); + *LengthVIE += (pEid->Len + 2); } - } - else - { - DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n")); + } else { + DBGPRINT(RT_DEBUG_WARN, + ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n")); } - break; - case IE_SECONDARY_CH_OFFSET: - if (pEid->Len == 1) - { + break; + case IE_SECONDARY_CH_OFFSET: + if (pEid->Len == 1) { *NewExtChannelOffset = pEid->Octet[0]; - } - else - { - DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n")); + } else { + DBGPRINT(RT_DEBUG_WARN, + ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n")); } - break; - case IE_FH_PARM: - DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n")); - break; + break; + case IE_FH_PARM: + DBGPRINT(RT_DEBUG_TRACE, + ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n")); + break; - case IE_DS_PARM: - if(pEid->Len == 1) - { - *pChannel = *pEid->Octet; + case IE_DS_PARM: + if (pEid->Len == 1) { + *pChannel = *pEid->Octet; - { - if (ChannelSanity(pAd, *pChannel) == 0) - { + { + if (ChannelSanity(pAd, *pChannel) == 0) { - return FALSE; - } + return FALSE; } + } + + Sanity |= 0x4; + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n", + pEid->Len)); + return FALSE; + } + break; + + case IE_CF_PARM: + if (pEid->Len == 6) { + pCfParm->bValid = TRUE; + pCfParm->CfpCount = pEid->Octet[0]; + pCfParm->CfpPeriod = pEid->Octet[1]; + pCfParm->CfpMaxDuration = + pEid->Octet[2] + 256 * pEid->Octet[3]; + pCfParm->CfpDurRemaining = + pEid->Octet[4] + 256 * pEid->Octet[5]; + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n")); + return FALSE; + } + break; + + case IE_IBSS_PARM: + if (pEid->Len == 2) { + NdisMoveMemory(pAtimWin, pEid->Octet, + pEid->Len); + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n")); + return FALSE; + } + break; + + case IE_TIM: + if (INFRA_ON(pAd) && SubType == SUBTYPE_BEACON) { + GetTimBit((char *)pEid, pAd->StaActive.Aid, + &TimLen, pBcastFlag, pDtimCount, + pDtimPeriod, pMessageToMe); + } + break; + case IE_CHANNEL_SWITCH_ANNOUNCEMENT: + if (pEid->Len == 3) { + *pNewChannel = pEid->Octet[1]; /*extract new channel number */ + } + break; + + /* New for WPA */ + /* CCX v2 has the same IE, we need to parse that too */ + /* Wifi WMM use the same IE vale, need to parse that too */ + /* case IE_WPA: */ + case IE_VENDOR_SPECIFIC: + /* Check Broadcom/Atheros 802.11n OUI version, for HT Capability IE. */ + /* This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan. */ + /*if (NdisEqualMemory(pEid->Octet, BROADCOM_OUI, 3) && (pEid->Len >= 4)) + { + if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 30)) + { + { + NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(struct rt_ht_capability_ie)); + *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes. + } + } + if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 26)) + { + { + NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(struct rt_add_ht_info_ie)); + *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; // Nnow we only support 26 bytes. + } + } + } + */ + /* Check the OUI version, filter out non-standard usage */ + if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3) + && (pEid->Len == 7)) { + /**pRalinkIe = pEid->Octet[3]; */ + if (pEid->Octet[3] != 0) + *pRalinkIe = pEid->Octet[3]; + else + *pRalinkIe = 0xf0000000; /* Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag. */ + } + /* This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan. */ + + /* Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP, */ + /* Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE */ + else if ((*pHtCapabilityLen == 0) + && NdisEqualMemory(pEid->Octet, PRE_N_HT_OUI, + 3) && (pEid->Len >= 4) + && (pAd->OpMode == OPMODE_STA)) { + if ((pEid->Octet[3] == OUI_PREN_HT_CAP) + && (pEid->Len >= 30) + && (*pHtCapabilityLen == 0)) { + NdisMoveMemory(pHtCapability, + &pEid->Octet[4], + sizeof + (struct rt_ht_capability_ie)); + *pPreNHtCapabilityLen = SIZE_HT_CAP_IE; + } + + if ((pEid->Octet[3] == OUI_PREN_ADD_HT) + && (pEid->Len >= 26)) { + NdisMoveMemory(AddHtInfo, + &pEid->Octet[4], + sizeof(struct rt_add_ht_info_ie)); + *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; + } + } else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) { + /* Copy to pVIE which will report to microsoft bssid list. */ + Ptr = (u8 *)pVIE; + NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, + pEid->Len + 2); + *LengthVIE += (pEid->Len + 2); + } else + if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) + && (pEid->Len == 24)) { + u8 *ptr; + int i; + + /* parsing EDCA parameters */ + pEdcaParm->bValid = TRUE; + pEdcaParm->bQAck = FALSE; /* pEid->Octet[0] & 0x10; */ + pEdcaParm->bQueueRequest = FALSE; /* pEid->Octet[0] & 0x20; */ + pEdcaParm->bTxopRequest = FALSE; /* pEid->Octet[0] & 0x40; */ + pEdcaParm->EdcaUpdateCount = + pEid->Octet[6] & 0x0f; + pEdcaParm->bAPSDCapable = + (pEid->Octet[6] & 0x80) ? 1 : 0; + ptr = &pEid->Octet[8]; + for (i = 0; i < 4; i++) { + u8 aci = (*ptr & 0x60) >> 5; /* b5~6 is AC INDEX */ + pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); /* b5 is ACM */ + pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; /* b0~3 is AIFSN */ + pEdcaParm->Cwmin[aci] = *(ptr + 1) & 0x0f; /* b0~4 is Cwmin */ + pEdcaParm->Cwmax[aci] = *(ptr + 1) >> 4; /* b5~8 is Cwmax */ + pEdcaParm->Txop[aci] = *(ptr + 2) + 256 * (*(ptr + 3)); /* in unit of 32-us */ + ptr += 4; /* point to next AC */ + } + } else + if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6) + && (pEid->Len == 7)) { + /* parsing EDCA parameters */ + pEdcaParm->bValid = TRUE; + pEdcaParm->bQAck = FALSE; /* pEid->Octet[0] & 0x10; */ + pEdcaParm->bQueueRequest = FALSE; /* pEid->Octet[0] & 0x20; */ + pEdcaParm->bTxopRequest = FALSE; /* pEid->Octet[0] & 0x40; */ + pEdcaParm->EdcaUpdateCount = + pEid->Octet[6] & 0x0f; + pEdcaParm->bAPSDCapable = + (pEid->Octet[6] & 0x80) ? 1 : 0; + + /* use default EDCA parameter */ + pEdcaParm->bACM[QID_AC_BE] = 0; + pEdcaParm->Aifsn[QID_AC_BE] = 3; + pEdcaParm->Cwmin[QID_AC_BE] = CW_MIN_IN_BITS; + pEdcaParm->Cwmax[QID_AC_BE] = CW_MAX_IN_BITS; + pEdcaParm->Txop[QID_AC_BE] = 0; + + pEdcaParm->bACM[QID_AC_BK] = 0; + pEdcaParm->Aifsn[QID_AC_BK] = 7; + pEdcaParm->Cwmin[QID_AC_BK] = CW_MIN_IN_BITS; + pEdcaParm->Cwmax[QID_AC_BK] = CW_MAX_IN_BITS; + pEdcaParm->Txop[QID_AC_BK] = 0; + + pEdcaParm->bACM[QID_AC_VI] = 0; + pEdcaParm->Aifsn[QID_AC_VI] = 2; + pEdcaParm->Cwmin[QID_AC_VI] = + CW_MIN_IN_BITS - 1; + pEdcaParm->Cwmax[QID_AC_VI] = CW_MAX_IN_BITS; + pEdcaParm->Txop[QID_AC_VI] = 96; /* AC_VI: 96*32us ~= 3ms */ + + pEdcaParm->bACM[QID_AC_VO] = 0; + pEdcaParm->Aifsn[QID_AC_VO] = 2; + pEdcaParm->Cwmin[QID_AC_VO] = + CW_MIN_IN_BITS - 2; + pEdcaParm->Cwmax[QID_AC_VO] = + CW_MAX_IN_BITS - 1; + pEdcaParm->Txop[QID_AC_VO] = 48; /* AC_VO: 48*32us ~= 1.5ms */ + } + + break; + + case IE_EXT_SUPP_RATES: + if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) { + NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len); + *pExtRateLen = pEid->Len; + + /* TODO: 2004-09-14 not a good design here, cause it exclude extra rates */ + /* from ScanTab. We should report as is. And filter out unsupported */ + /* rates in MlmeAux. */ + /* Check against the supported rates */ + /* RTMPCheckRates(pAd, ExtRate, pExtRateLen); */ + } + break; + + case IE_ERP: + if (pEid->Len == 1) { + *pErp = (u8)pEid->Octet[0]; + } + break; + + case IE_AIRONET_CKIP: + /* 0. Check Aironet IE length, it must be larger or equal to 28 */ + /* Cisco AP350 used length as 28 */ + /* Cisco AP12XX used length as 30 */ + if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2)) + break; + + /* 1. Copy CKIP flag byte to buffer for process */ + *pCkipFlag = *(pEid->Octet + 8); + break; + + case IE_AP_TX_POWER: + /* AP Control of Client Transmit Power */ + /*0. Check Aironet IE length, it must be 6 */ + if (pEid->Len != 0x06) + break; + + /* Get cell power limit in dBm */ + if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1) + *pAironetCellPowerLimit = *(pEid->Octet + 4); + break; + + /* WPA2 & 802.11i RSN */ + case IE_RSN: + /* There is no OUI for version anymore, check the group cipher OUI before copying */ + if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3)) { + /* Copy to pVIE which will report to microsoft bssid list. */ + Ptr = (u8 *)pVIE; + NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, + pEid->Len + 2); + *LengthVIE += (pEid->Len + 2); + } + break; + + default: + break; + } - Sanity |= 0x4; - } - else - { - DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",pEid->Len)); - return FALSE; - } - break; - - case IE_CF_PARM: - if(pEid->Len == 6) - { - pCfParm->bValid = TRUE; - pCfParm->CfpCount = pEid->Octet[0]; - pCfParm->CfpPeriod = pEid->Octet[1]; - pCfParm->CfpMaxDuration = pEid->Octet[2] + 256 * pEid->Octet[3]; - pCfParm->CfpDurRemaining = pEid->Octet[4] + 256 * pEid->Octet[5]; - } - else - { - DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n")); - return FALSE; - } - break; - - case IE_IBSS_PARM: - if(pEid->Len == 2) - { - NdisMoveMemory(pAtimWin, pEid->Octet, pEid->Len); - } - else - { - DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n")); - return FALSE; - } - break; - - case IE_TIM: - if(INFRA_ON(pAd) && SubType == SUBTYPE_BEACON) - { - GetTimBit((PUCHAR)pEid, pAd->StaActive.Aid, &TimLen, pBcastFlag, pDtimCount, pDtimPeriod, pMessageToMe); - } - break; - - case IE_CHANNEL_SWITCH_ANNOUNCEMENT: - if(pEid->Len == 3) - { - *pNewChannel = pEid->Octet[1]; //extract new channel number - } - break; - - // New for WPA - // CCX v2 has the same IE, we need to parse that too - // Wifi WMM use the same IE vale, need to parse that too - // case IE_WPA: - case IE_VENDOR_SPECIFIC: - // Check the OUI version, filter out non-standard usage - if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3) && (pEid->Len == 7)) - { - //*pRalinkIe = pEid->Octet[3]; - if (pEid->Octet[3] != 0) - *pRalinkIe = pEid->Octet[3]; - else - *pRalinkIe = 0xf0000000; // Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag. - } - // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan. - - // Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP, - // Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE - else if ((*pHtCapabilityLen == 0) && NdisEqualMemory(pEid->Octet, PRE_N_HT_OUI, 3) && (pEid->Len >= 4) && (pAd->OpMode == OPMODE_STA)) - { - if ((pEid->Octet[3] == OUI_PREN_HT_CAP) && (pEid->Len >= 30) && (*pHtCapabilityLen == 0)) - { - NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE)); - *pPreNHtCapabilityLen = SIZE_HT_CAP_IE; - } - - if ((pEid->Octet[3] == OUI_PREN_ADD_HT) && (pEid->Len >= 26)) - { - NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE)); - *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; - } - } - else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) - { - // Copy to pVIE which will report to microsoft bssid list. - Ptr = (PUCHAR) pVIE; - NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2); - *LengthVIE += (pEid->Len + 2); - } - else if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24)) - { - PUCHAR ptr; - int i; - - // parsing EDCA parameters - pEdcaParm->bValid = TRUE; - pEdcaParm->bQAck = FALSE; // pEid->Octet[0] & 0x10; - pEdcaParm->bQueueRequest = FALSE; // pEid->Octet[0] & 0x20; - pEdcaParm->bTxopRequest = FALSE; // pEid->Octet[0] & 0x40; - pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f; - pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0; - ptr = &pEid->Octet[8]; - for (i=0; i<4; i++) - { - UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX - pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); // b5 is ACM - pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; // b0~3 is AIFSN - pEdcaParm->Cwmin[aci] = *(ptr+1) & 0x0f; // b0~4 is Cwmin - pEdcaParm->Cwmax[aci] = *(ptr+1) >> 4; // b5~8 is Cwmax - pEdcaParm->Txop[aci] = *(ptr+2) + 256 * (*(ptr+3)); // in unit of 32-us - ptr += 4; // point to next AC - } - } - else if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6) && (pEid->Len == 7)) - { - // parsing EDCA parameters - pEdcaParm->bValid = TRUE; - pEdcaParm->bQAck = FALSE; // pEid->Octet[0] & 0x10; - pEdcaParm->bQueueRequest = FALSE; // pEid->Octet[0] & 0x20; - pEdcaParm->bTxopRequest = FALSE; // pEid->Octet[0] & 0x40; - pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f; - pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0; - - // use default EDCA parameter - pEdcaParm->bACM[QID_AC_BE] = 0; - pEdcaParm->Aifsn[QID_AC_BE] = 3; - pEdcaParm->Cwmin[QID_AC_BE] = CW_MIN_IN_BITS; - pEdcaParm->Cwmax[QID_AC_BE] = CW_MAX_IN_BITS; - pEdcaParm->Txop[QID_AC_BE] = 0; - - pEdcaParm->bACM[QID_AC_BK] = 0; - pEdcaParm->Aifsn[QID_AC_BK] = 7; - pEdcaParm->Cwmin[QID_AC_BK] = CW_MIN_IN_BITS; - pEdcaParm->Cwmax[QID_AC_BK] = CW_MAX_IN_BITS; - pEdcaParm->Txop[QID_AC_BK] = 0; - - pEdcaParm->bACM[QID_AC_VI] = 0; - pEdcaParm->Aifsn[QID_AC_VI] = 2; - pEdcaParm->Cwmin[QID_AC_VI] = CW_MIN_IN_BITS-1; - pEdcaParm->Cwmax[QID_AC_VI] = CW_MAX_IN_BITS; - pEdcaParm->Txop[QID_AC_VI] = 96; // AC_VI: 96*32us ~= 3ms - - pEdcaParm->bACM[QID_AC_VO] = 0; - pEdcaParm->Aifsn[QID_AC_VO] = 2; - pEdcaParm->Cwmin[QID_AC_VO] = CW_MIN_IN_BITS-2; - pEdcaParm->Cwmax[QID_AC_VO] = CW_MAX_IN_BITS-1; - pEdcaParm->Txop[QID_AC_VO] = 48; // AC_VO: 48*32us ~= 1.5ms - } - break; - - case IE_EXT_SUPP_RATES: - if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) - { - NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len); - *pExtRateLen = pEid->Len; - - // TODO: 2004-09-14 not a good design here, cause it exclude extra rates - // from ScanTab. We should report as is. And filter out unsupported - // rates in MlmeAux. - // Check against the supported rates - // RTMPCheckRates(pAd, ExtRate, pExtRateLen); - } - break; - - case IE_ERP: - if (pEid->Len == 1) - { - *pErp = (UCHAR)pEid->Octet[0]; - } - break; - - case IE_AIRONET_CKIP: - // 0. Check Aironet IE length, it must be larger or equal to 28 - // Cisco AP350 used length as 28 - // Cisco AP12XX used length as 30 - if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2)) - break; - - // 1. Copy CKIP flag byte to buffer for process - *pCkipFlag = *(pEid->Octet + 8); - break; - - case IE_AP_TX_POWER: - // AP Control of Client Transmit Power - //0. Check Aironet IE length, it must be 6 - if (pEid->Len != 0x06) - break; - - // Get cell power limit in dBm - if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1) - *pAironetCellPowerLimit = *(pEid->Octet + 4); - break; - - // WPA2 & 802.11i RSN - case IE_RSN: - // There is no OUI for version anymore, check the group cipher OUI before copying - if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3)) - { - // Copy to pVIE which will report to microsoft bssid list. - Ptr = (PUCHAR) pVIE; - NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2); - *LengthVIE += (pEid->Len + 2); - } - break; - - default: - break; - } - - Length = Length + 2 + pEid->Len; // Eid[1] + Len[1]+ content[Len] - pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len); - } - - // For some 11a AP. it did not have the channel EID, patch here + Length = Length + 2 + pEid->Len; /* Eid[1] + Len[1]+ content[Len] */ + pEid = (struct rt_eid *) ((u8 *) pEid + 2 + pEid->Len); + } + + /* For some 11a AP. it did not have the channel EID, patch here */ { - UCHAR LatchRfChannel = MsgChannel; - if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0)) - { + u8 LatchRfChannel = MsgChannel; + if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0)) { if (CtrlChannel != 0) *pChannel = CtrlChannel; else @@ -716,13 +711,12 @@ BOOLEAN PeerBeaconAndProbeRspSanity( } } - if (Sanity != 0x7) - { - DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity)); + if (Sanity != 0x7) { + DBGPRINT(RT_DEBUG_LOUD, + ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", + Sanity)); return FALSE; - } - else - { + } else { return TRUE; } @@ -736,51 +730,42 @@ BOOLEAN PeerBeaconAndProbeRspSanity( TRUE if all parameters are OK, FALSE otherwise ========================================================================== */ -BOOLEAN MlmeScanReqSanity( - IN PRTMP_ADAPTER pAd, - IN VOID *Msg, - IN ULONG MsgLen, - OUT UCHAR *pBssType, - OUT CHAR Ssid[], - OUT UCHAR *pSsidLen, - OUT UCHAR *pScanType) +BOOLEAN MlmeScanReqSanity(struct rt_rtmp_adapter *pAd, + void * Msg, + unsigned long MsgLen, + u8 * pBssType, + char Ssid[], + u8 * pSsidLen, u8 * pScanType) { - MLME_SCAN_REQ_STRUCT *Info; + struct rt_mlme_scan_req *Info; - Info = (MLME_SCAN_REQ_STRUCT *)(Msg); + Info = (struct rt_mlme_scan_req *)(Msg); *pBssType = Info->BssType; *pSsidLen = Info->SsidLen; NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen); *pScanType = Info->ScanType; - if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC || *pBssType == BSS_ANY) - && (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE - || *pScanType == SCAN_CISCO_PASSIVE || *pScanType == SCAN_CISCO_ACTIVE - || *pScanType == SCAN_CISCO_CHANNEL_LOAD || *pScanType == SCAN_CISCO_NOISE - )) - { + if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC + || *pBssType == BSS_ANY) + && (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE)) { return TRUE; - } - else - { - DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqSanity fail - wrong BssType or ScanType\n")); + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("MlmeScanReqSanity fail - wrong BssType or ScanType\n")); return FALSE; } } -// IRQL = DISPATCH_LEVEL -UCHAR ChannelSanity( - IN PRTMP_ADAPTER pAd, - IN UCHAR channel) +/* IRQL = DISPATCH_LEVEL */ +u8 ChannelSanity(struct rt_rtmp_adapter *pAd, u8 channel) { - int i; - - for (i = 0; i < pAd->ChannelListNum; i ++) - { - if (channel == pAd->ChannelList[i].Channel) - return 1; - } - return 0; + int i; + + for (i = 0; i < pAd->ChannelListNum; i++) { + if (channel == pAd->ChannelList[i].Channel) + return 1; + } + return 0; } /* @@ -794,19 +779,17 @@ UCHAR ChannelSanity( ========================================================================== */ -BOOLEAN PeerDeauthSanity( - IN PRTMP_ADAPTER pAd, - IN VOID *Msg, - IN ULONG MsgLen, - OUT PUCHAR pAddr2, - OUT USHORT *pReason) +BOOLEAN PeerDeauthSanity(struct rt_rtmp_adapter *pAd, + void * Msg, + unsigned long MsgLen, + u8 *pAddr2, u16 * pReason) { - PFRAME_802_11 pFrame = (PFRAME_802_11)Msg; + struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg; - COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); - NdisMoveMemory(pReason, &pFrame->Octet[0], 2); + COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); + NdisMoveMemory(pReason, &pFrame->Octet[0], 2); - return TRUE; + return TRUE; } /* @@ -820,58 +803,46 @@ BOOLEAN PeerDeauthSanity( ========================================================================== */ -BOOLEAN PeerAuthSanity( - IN PRTMP_ADAPTER pAd, - IN VOID *Msg, - IN ULONG MsgLen, - OUT PUCHAR pAddr, - OUT USHORT *pAlg, - OUT USHORT *pSeq, - OUT USHORT *pStatus, - CHAR *pChlgText) +BOOLEAN PeerAuthSanity(struct rt_rtmp_adapter *pAd, + void * Msg, + unsigned long MsgLen, + u8 *pAddr, + u16 * pAlg, + u16 * pSeq, + u16 * pStatus, char * pChlgText) { - PFRAME_802_11 pFrame = (PFRAME_802_11)Msg; - - COPY_MAC_ADDR(pAddr, pFrame->Hdr.Addr2); - NdisMoveMemory(pAlg, &pFrame->Octet[0], 2); - NdisMoveMemory(pSeq, &pFrame->Octet[2], 2); - NdisMoveMemory(pStatus, &pFrame->Octet[4], 2); - - if ((*pAlg == Ndis802_11AuthModeOpen) - ) - { - if (*pSeq == 1 || *pSeq == 2) - { - return TRUE; - } - else - { - DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n")); - return FALSE; - } - } - else if (*pAlg == Ndis802_11AuthModeShared) - { - if (*pSeq == 1 || *pSeq == 4) - { - return TRUE; - } - else if (*pSeq == 2 || *pSeq == 3) - { - NdisMoveMemory(pChlgText, &pFrame->Octet[8], CIPHER_TEXT_LEN); - return TRUE; - } - else - { - DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n")); - return FALSE; - } - } - else - { - DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong algorithm\n")); - return FALSE; - } + struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg; + + COPY_MAC_ADDR(pAddr, pFrame->Hdr.Addr2); + NdisMoveMemory(pAlg, &pFrame->Octet[0], 2); + NdisMoveMemory(pSeq, &pFrame->Octet[2], 2); + NdisMoveMemory(pStatus, &pFrame->Octet[4], 2); + + if (*pAlg == AUTH_MODE_OPEN) { + if (*pSeq == 1 || *pSeq == 2) { + return TRUE; + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("PeerAuthSanity fail - wrong Seg#\n")); + return FALSE; + } + } else if (*pAlg == AUTH_MODE_KEY) { + if (*pSeq == 1 || *pSeq == 4) { + return TRUE; + } else if (*pSeq == 2 || *pSeq == 3) { + NdisMoveMemory(pChlgText, &pFrame->Octet[8], + CIPHER_TEXT_LEN); + return TRUE; + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("PeerAuthSanity fail - wrong Seg#\n")); + return FALSE; + } + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("PeerAuthSanity fail - wrong algorithm\n")); + return FALSE; + } } /* @@ -882,32 +853,27 @@ BOOLEAN PeerAuthSanity( TRUE if all parameters are OK, FALSE otherwise ========================================================================== */ -BOOLEAN MlmeAuthReqSanity( - IN PRTMP_ADAPTER pAd, - IN VOID *Msg, - IN ULONG MsgLen, - OUT PUCHAR pAddr, - OUT ULONG *pTimeout, - OUT USHORT *pAlg) +BOOLEAN MlmeAuthReqSanity(struct rt_rtmp_adapter *pAd, + void * Msg, + unsigned long MsgLen, + u8 *pAddr, + unsigned long * pTimeout, u16 * pAlg) { - MLME_AUTH_REQ_STRUCT *pInfo; - - pInfo = (MLME_AUTH_REQ_STRUCT *)Msg; - COPY_MAC_ADDR(pAddr, pInfo->Addr); - *pTimeout = pInfo->Timeout; - *pAlg = pInfo->Alg; - - if (((*pAlg == Ndis802_11AuthModeShared) ||(*pAlg == Ndis802_11AuthModeOpen) - ) && - ((*pAddr & 0x01) == 0)) - { - return TRUE; - } - else - { - DBGPRINT(RT_DEBUG_TRACE, ("MlmeAuthReqSanity fail - wrong algorithm\n")); - return FALSE; - } + struct rt_mlme_auth_req *pInfo; + + pInfo = (struct rt_mlme_auth_req *)Msg; + COPY_MAC_ADDR(pAddr, pInfo->Addr); + *pTimeout = pInfo->Timeout; + *pAlg = pInfo->Alg; + + if (((*pAlg == AUTH_MODE_KEY) || (*pAlg == AUTH_MODE_OPEN) + ) && ((*pAddr & 0x01) == 0)) { + return TRUE; + } else { + DBGPRINT(RT_DEBUG_TRACE, + ("MlmeAuthReqSanity fail - wrong algorithm\n")); + return FALSE; + } } /* @@ -921,24 +887,22 @@ BOOLEAN MlmeAuthReqSanity( ========================================================================== */ -BOOLEAN MlmeAssocReqSanity( - IN PRTMP_ADAPTER pAd, - IN VOID *Msg, - IN ULONG MsgLen, - OUT PUCHAR pApAddr, - OUT USHORT *pCapabilityInfo, - OUT ULONG *pTimeout, - OUT USHORT *pListenIntv) +BOOLEAN MlmeAssocReqSanity(struct rt_rtmp_adapter *pAd, + void * Msg, + unsigned long MsgLen, + u8 *pApAddr, + u16 * pCapabilityInfo, + unsigned long * pTimeout, u16 * pListenIntv) { - MLME_ASSOC_REQ_STRUCT *pInfo; + struct rt_mlme_assoc_req *pInfo; - pInfo = (MLME_ASSOC_REQ_STRUCT *)Msg; - *pTimeout = pInfo->Timeout; // timeout - COPY_MAC_ADDR(pApAddr, pInfo->Addr); // AP address - *pCapabilityInfo = pInfo->CapabilityInfo; // capability info - *pListenIntv = pInfo->ListenIntv; + pInfo = (struct rt_mlme_assoc_req *)Msg; + *pTimeout = pInfo->Timeout; /* timeout */ + COPY_MAC_ADDR(pApAddr, pInfo->Addr); /* AP address */ + *pCapabilityInfo = pInfo->CapabilityInfo; /* capability info */ + *pListenIntv = pInfo->ListenIntv; - return TRUE; + return TRUE; } /* @@ -952,19 +916,17 @@ BOOLEAN MlmeAssocReqSanity( ========================================================================== */ -BOOLEAN PeerDisassocSanity( - IN PRTMP_ADAPTER pAd, - IN VOID *Msg, - IN ULONG MsgLen, - OUT PUCHAR pAddr2, - OUT USHORT *pReason) +BOOLEAN PeerDisassocSanity(struct rt_rtmp_adapter *pAd, + void * Msg, + unsigned long MsgLen, + u8 *pAddr2, u16 * pReason) { - PFRAME_802_11 pFrame = (PFRAME_802_11)Msg; + struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg; - COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); - NdisMoveMemory(pReason, &pFrame->Octet[0], 2); + COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); + NdisMoveMemory(pReason, &pFrame->Octet[0], 2); - return TRUE; + return TRUE; } /* @@ -984,71 +946,260 @@ BOOLEAN PeerDisassocSanity( ======================================================================== */ -NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity( - IN PBSS_ENTRY pBss) +NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(struct rt_bss_entry *pBss) { - NDIS_802_11_NETWORK_TYPE NetWorkType; - UCHAR rate, i; + NDIS_802_11_NETWORK_TYPE NetWorkType; + u8 rate, i; NetWorkType = Ndis802_11DS; - if (pBss->Channel <= 14) - { - // - // First check support Rate. - // - for (i = 0; i < pBss->SupRateLen; i++) - { - rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit - if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22)) - { + if (pBss->Channel <= 14) { + /* */ + /* First check support Rate. */ + /* */ + for (i = 0; i < pBss->SupRateLen; i++) { + rate = pBss->SupRate[i] & 0x7f; /* Mask out basic rate set bit */ + if ((rate == 2) || (rate == 4) || (rate == 11) + || (rate == 22)) { continue; - } - else - { - // - // Otherwise (even rate > 108) means Ndis802_11OFDM24 - // + } else { + /* */ + /* Otherwise (even rate > 108) means Ndis802_11OFDM24 */ + /* */ NetWorkType = Ndis802_11OFDM24; break; } } - // - // Second check Extend Rate. - // - if (NetWorkType != Ndis802_11OFDM24) - { - for (i = 0; i < pBss->ExtRateLen; i++) - { - rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit - if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22)) - { + /* */ + /* Second check Extend Rate. */ + /* */ + if (NetWorkType != Ndis802_11OFDM24) { + for (i = 0; i < pBss->ExtRateLen; i++) { + rate = pBss->SupRate[i] & 0x7f; /* Mask out basic rate set bit */ + if ((rate == 2) || (rate == 4) || (rate == 11) + || (rate == 22)) { continue; - } - else - { - // - // Otherwise (even rate > 108) means Ndis802_11OFDM24 - // + } else { + /* */ + /* Otherwise (even rate > 108) means Ndis802_11OFDM24 */ + /* */ NetWorkType = Ndis802_11OFDM24; break; } } } - } - else - { + } else { NetWorkType = Ndis802_11OFDM5; } - if (pBss->HtCapabilityLen != 0) - { - if (NetWorkType == Ndis802_11OFDM5) - NetWorkType = Ndis802_11OFDM5_N; - else - NetWorkType = Ndis802_11OFDM24_N; - } + if (pBss->HtCapabilityLen != 0) { + if (NetWorkType == Ndis802_11OFDM5) + NetWorkType = Ndis802_11OFDM5_N; + else + NetWorkType = Ndis802_11OFDM24_N; + } return NetWorkType; } + +/* + ========================================================================== + Description: + Check the validity of the received EAPoL frame + Return: + TRUE if all parameters are OK, + FALSE otherwise + ========================================================================== + */ +BOOLEAN PeerWpaMessageSanity(struct rt_rtmp_adapter *pAd, + struct rt_eapol_packet * pMsg, + unsigned long MsgLen, + u8 MsgType, struct rt_mac_table_entry *pEntry) +{ + u8 mic[LEN_KEY_DESC_MIC], digest[80], KEYDATA[MAX_LEN_OF_RSNIE]; + BOOLEAN bReplayDiff = FALSE; + BOOLEAN bWPA2 = FALSE; + struct rt_key_info EapolKeyInfo; + u8 GroupKeyIndex = 0; + + NdisZeroMemory(mic, sizeof(mic)); + NdisZeroMemory(digest, sizeof(digest)); + NdisZeroMemory(KEYDATA, sizeof(KEYDATA)); + NdisZeroMemory((u8 *)& EapolKeyInfo, sizeof(EapolKeyInfo)); + + NdisMoveMemory((u8 *)& EapolKeyInfo, + (u8 *)& pMsg->KeyDesc.KeyInfo, sizeof(struct rt_key_info)); + + *((u16 *) & EapolKeyInfo) = cpu2le16(*((u16 *) & EapolKeyInfo)); + + /* Choose WPA2 or not */ + if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) + || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) + bWPA2 = TRUE; + + /* 0. Check MsgType */ + if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1)) { + DBGPRINT(RT_DEBUG_ERROR, + ("The message type is invalid(%d)! \n", MsgType)); + return FALSE; + } + /* 1. Replay counter check */ + if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1) /* For supplicant */ + { + /* First validate replay counter, only accept message with larger replay counter. */ + /* Let equal pass, some AP start with all zero replay counter */ + u8 ZeroReplay[LEN_KEY_DESC_REPLAY]; + + NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY); + if ((RTMPCompareMemory + (pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, + LEN_KEY_DESC_REPLAY) != 1) + && + (RTMPCompareMemory + (pMsg->KeyDesc.ReplayCounter, ZeroReplay, + LEN_KEY_DESC_REPLAY) != 0)) { + bReplayDiff = TRUE; + } + } else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2) /* For authenticator */ + { + /* check Replay Counter coresponds to MSG from authenticator, otherwise discard */ + if (!NdisEqualMemory + (pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, + LEN_KEY_DESC_REPLAY)) { + bReplayDiff = TRUE; + } + } + /* Replay Counter different condition */ + if (bReplayDiff) { + /* send wireless event - for replay counter different */ + if (pAd->CommonCfg.bWirelessEvent) + RTMPSendWirelessEvent(pAd, + IW_REPLAY_COUNTER_DIFF_EVENT_FLAG, + pEntry->Addr, pEntry->apidx, 0); + + if (MsgType < EAPOL_GROUP_MSG_1) { + DBGPRINT(RT_DEBUG_ERROR, + ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n", + MsgType)); + } else { + DBGPRINT(RT_DEBUG_ERROR, + ("Replay Counter Different in group msg %d of 2-way handshake!\n", + (MsgType - EAPOL_PAIR_MSG_4))); + } + + hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter, + LEN_KEY_DESC_REPLAY); + hex_dump("Current replay counter ", pEntry->R_Counter, + LEN_KEY_DESC_REPLAY); + return FALSE; + } + /* 2. Verify MIC except Pairwise Msg1 */ + if (MsgType != EAPOL_PAIR_MSG_1) { + u8 rcvd_mic[LEN_KEY_DESC_MIC]; + + /* Record the received MIC for check later */ + NdisMoveMemory(rcvd_mic, pMsg->KeyDesc.KeyMic, + LEN_KEY_DESC_MIC); + NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); + + if (EapolKeyInfo.KeyDescVer == DESC_TYPE_TKIP) /* TKIP */ + { + HMAC_MD5(pEntry->PTK, LEN_EAP_MICK, (u8 *)pMsg, + MsgLen, mic, MD5_DIGEST_SIZE); + } else if (EapolKeyInfo.KeyDescVer == DESC_TYPE_AES) /* AES */ + { + HMAC_SHA1(pEntry->PTK, LEN_EAP_MICK, (u8 *)pMsg, + MsgLen, digest, SHA1_DIGEST_SIZE); + NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC); + } + + if (!NdisEqualMemory(rcvd_mic, mic, LEN_KEY_DESC_MIC)) { + /* send wireless event - for MIC different */ + if (pAd->CommonCfg.bWirelessEvent) + RTMPSendWirelessEvent(pAd, + IW_MIC_DIFF_EVENT_FLAG, + pEntry->Addr, + pEntry->apidx, 0); + + if (MsgType < EAPOL_GROUP_MSG_1) { + DBGPRINT(RT_DEBUG_ERROR, + ("MIC Different in pairwise msg %d of 4-way handshake!\n", + MsgType)); + } else { + DBGPRINT(RT_DEBUG_ERROR, + ("MIC Different in group msg %d of 2-way handshake!\n", + (MsgType - EAPOL_PAIR_MSG_4))); + } + + hex_dump("Received MIC", rcvd_mic, LEN_KEY_DESC_MIC); + hex_dump("Desired MIC", mic, LEN_KEY_DESC_MIC); + + return FALSE; + } + } + /* 1. Decrypt the Key Data field if GTK is included. */ + /* 2. Extract the context of the Key Data field if it exist. */ + /* The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is clear. */ + /* The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted. */ + if (CONV_ARRARY_TO_u16(pMsg->KeyDesc.KeyDataLen) > 0) { + /* Decrypt this field */ + if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) + || (MsgType == EAPOL_GROUP_MSG_1)) { + if ((EapolKeyInfo.KeyDescVer == DESC_TYPE_AES)) { + /* AES */ + AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA, + CONV_ARRARY_TO_u16(pMsg-> + KeyDesc. + KeyDataLen), + pMsg->KeyDesc.KeyData); + } else { + int i; + u8 Key[32]; + /* Decrypt TKIP GTK */ + /* Construct 32 bytes RC4 Key */ + NdisMoveMemory(Key, pMsg->KeyDesc.KeyIv, 16); + NdisMoveMemory(&Key[16], &pEntry->PTK[16], 16); + ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, + 32); + /*discard first 256 bytes */ + for (i = 0; i < 256; i++) + ARCFOUR_BYTE(&pAd->PrivateInfo. + WEPCONTEXT); + /* Decrypt GTK. Becareful, there is no ICV to check the result is correct or not */ + ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, + KEYDATA, pMsg->KeyDesc.KeyData, + CONV_ARRARY_TO_u16(pMsg-> + KeyDesc. + KeyDataLen)); + } + + if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)) + GroupKeyIndex = EapolKeyInfo.KeyIndex; + + } else if ((MsgType == EAPOL_PAIR_MSG_2) + || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2)) { + NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData, + CONV_ARRARY_TO_u16(pMsg->KeyDesc. + KeyDataLen)); + } else { + + return TRUE; + } + + /* Parse Key Data field to */ + /* 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2) */ + /* 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2 */ + /* 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2) */ + if (!RTMPParseEapolKeyData(pAd, KEYDATA, + CONV_ARRARY_TO_u16(pMsg->KeyDesc. + KeyDataLen), + GroupKeyIndex, MsgType, bWPA2, + pEntry)) { + return FALSE; + } + } + + return TRUE; + +} |