📄 sanity.c
字号:
/*
***************************************************************************
* Ralink Tech Inc.
* 4F, No. 2 Technology 5th Rd.
* Science-based Industrial Park
* Hsin-chu, Taiwan, R.O.C.
*
* (c) Copyright 2002-2004, Ralink Technology, Inc.
*
* All rights reserved. Ralink's source code is an unpublished work and the
* use of a copyright notice does not imply otherwise. This source code
* contains confidential trade secret material of Ralink Tech. Any attemp
* or participation in deciphering, decoding, reverse engineering or in any
* way altering the source code is stricitly prohibited, unless the prior
* written consent of Ralink Technology, Inc. is obtained.
***************************************************************************
Module Name:
sanity.c
Abstract:
Revision History:
Who When What
-------- ---------- ----------------------------------------------
John Chang 2004-09-01 add WMM support
*/
#include "rt_config.h"
UCHAR WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
UCHAR RSN_OUI[] = {0x00, 0x0f, 0xac};
UCHAR WME_INFO_ELEM[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
UCHAR WME_PARM_ELEM[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
UCHAR Ccx2QosInfo[] = {0x00, 0x40, 0x96, 0x04};
UCHAR RALINK_OUI[] = {0x00, 0x0c, 0x43};
UCHAR RALINK_GET_CONFIG_OUI[] = {0x00, 0x0c, 0x43, 0x80};
/*
==========================================================================
Description:
MLME message sanity check
Return:
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)
{
MLME_SCAN_REQ_STRUCT *Info;
Info = (MLME_SCAN_REQ_STRUCT *)(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))
return TRUE;
else
{
DBGPRINT(RT_DEBUG_TRACE, "MlmeScanReqSanity fail - wrong BssType or ScanType\n");
return FALSE;
}
}
/*
==========================================================================
Description:
MLME message sanity check
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
BOOLEAN PeerAuthSanity(
IN PRTMP_ADAPTER pAd,
IN VOID *Msg,
IN ULONG MsgLen,
OUT PUCHAR pAddr1,
OUT PUCHAR pAddr2,
OUT USHORT *pAlg,
OUT USHORT *pSeq,
OUT USHORT *pStatus,
CHAR *pChlgText)
{
PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
COPY_MAC_ADDR(pAddr1, pFrame->Hdr.Addr1);
COPY_MAC_ADDR(pAddr2, 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;
}
}
/*
==========================================================================
Description:
MLME message sanity check
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
BOOLEAN PeerProbeReqSanity(
IN PRTMP_ADAPTER pAd,
IN VOID *Msg,
IN ULONG MsgLen,
OUT PUCHAR pAddr2,
OUT CHAR Ssid[],
OUT UCHAR *pSsidLen)
{
PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
CHAR *Ptr;
PEID_STRUCT eid_ptr;
// to prevent caller from using garbage output value
*pSsidLen = 0;
COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
if (pFrame->Octet[0] != IE_SSID || pFrame->Octet[1] > MAX_LEN_OF_SSID)
{
DBGPRINT(RT_DEBUG_TRACE, "PeerProbeReqSanity fail - wrong SSID IE\n");
return FALSE;
}
*pSsidLen = pFrame->Octet[1];
NdisMoveMemory(Ssid, &pFrame->Octet[2], *pSsidLen);
Ptr = pFrame->Octet;
eid_ptr = (PEID_STRUCT) Ptr;
// get variable fields from payload and advance the pointer
while(((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)pFrame + MsgLen))
{
switch(eid_ptr->Eid)
{
case IE_VENDOR_SPECIFIC:
if (NdisEqualMemory(eid_ptr->Octet, RALINK_GET_CONFIG_OUI, 4) && (eid_ptr->Len == 4))
{
pAd->PortCfg.bGetAPConfig = TRUE;
break;
}
default:
break;
}
eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
}
return TRUE;
}
UCHAR ChannelSanity(
IN PRTMP_ADAPTER pAd,
IN UCHAR channel)
{
INT i;
for (i = 0; i < pAd->ChannelListNum; i ++)
{
if (channel == pAd->ChannelList[i].Channel)
return 1;
}
return 0;
}
/*
==========================================================================
Description:
MLME message sanity check
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
BOOLEAN PeerAssocReqSanity(
IN PRTMP_ADAPTER pAd,
IN VOID *Msg,
IN ULONG MsgLen,
OUT PUCHAR pAddr1,
OUT PUCHAR pAddr2,
OUT USHORT *pCapabilityInfo,
OUT USHORT *pListenInterval,
OUT UCHAR *pSsidLen,
OUT char *Ssid,
OUT UCHAR *pRatesLen,
OUT UCHAR Rates[],
OUT UCHAR *RSN,
OUT UCHAR *pRSNLen,
OUT BOOLEAN *pbWmmCapable,
OUT ULONG *pRalinkIe)
{
CHAR *Ptr;
PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
PEID_STRUCT eid_ptr;
UCHAR Sanity = 0;
UCHAR WPA[4] = {0x00,0x50,0xf2,0x01};
MAC_TABLE_ENTRY *pEntry = (MAC_TABLE_ENTRY*)NULL;
// to prevent caller from using garbage output value
*pRatesLen = 0;
*pRSNLen = 0;
*pbWmmCapable = FALSE;
*pRalinkIe = 0;
COPY_MAC_ADDR(pAddr1, Fr->Hdr.Addr1);
COPY_MAC_ADDR(pAddr2, Fr->Hdr.Addr2);
Ptr = Fr->Octet;
NdisMoveMemory(pCapabilityInfo, &Fr->Octet[0], 2);
NdisMoveMemory(pListenInterval, &Fr->Octet[2], 2);
eid_ptr = (PEID_STRUCT) &Fr->Octet[4];
pEntry = MacTableLookup(pAd, pAddr2);
// get variable fields from payload and advance the pointer
while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen))
{
switch(eid_ptr->Eid)
{
case IE_SSID:
if(eid_ptr->Len <= MAX_LEN_OF_SSID)
{
Sanity |= 0x01;
NdisMoveMemory(Ssid, eid_ptr->Octet, eid_ptr->Len);
*pSsidLen = eid_ptr->Len;
}
else
{
DBGPRINT(RT_DEBUG_TRACE, "PeerAssocReqSanity - wrong IE_SSID\n");
return FALSE;
}
break;
case IE_SUPP_RATES:
if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0))
{
Sanity |= 0x02;
NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
*pRatesLen = eid_ptr->Len;
}
else
{
DBGPRINT(RT_DEBUG_TRACE, "PeerAssocReqSanity - wrong IE_SUPP_RATES\n");
return FALSE;
}
break;
case IE_EXT_SUPP_RATES:
if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
{
NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len);
*pRatesLen = (*pRatesLen) + eid_ptr->Len;
}
else
{
NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen));
*pRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
}
break;
case IE_WPA:
case IE_WPA2:
if (NdisEqualMemory(eid_ptr->Octet, RALINK_OUI, 3) && (eid_ptr->Len == 7))
{
*pRalinkIe = eid_ptr->Octet[3];
break;
}
// WMM_IE
if (NdisEqualMemory(eid_ptr->Octet, WME_INFO_ELEM, 6) && (eid_ptr->Len == 7))
{
*pbWmmCapable = TRUE;
if ((pEntry) && (pAd->PortCfg.bAPSDCapable))
{
QBSS_STA_INFO_PARM QosInfo;
QosInfo = *(PQBSS_STA_INFO_PARM) &eid_ptr->Octet[6];
pEntry->MaxSPLength = QosInfo.MaxSPLength;
pEntry->bAPSDCapablePerAC[QID_AC_BE] = QosInfo.UAPSD_AC_BE;
pEntry->bAPSDCapablePerAC[QID_AC_BK] = QosInfo.UAPSD_AC_BK;
pEntry->bAPSDCapablePerAC[QID_AC_VI] = QosInfo.UAPSD_AC_VI;
pEntry->bAPSDCapablePerAC[QID_AC_VO] = QosInfo.UAPSD_AC_VO;
if ((pEntry->bAPSDCapablePerAC[QID_AC_BE] == 0) && (pEntry->bAPSDCapablePerAC[QID_AC_BK] == 0) && (pEntry->bAPSDCapablePerAC[QID_AC_VI] == 0) && (pEntry->bAPSDCapablePerAC[QID_AC_VO] == 0))
{
CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_APSD_CAPABLE);
}
else
{
CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_APSD_CAPABLE);
}
}
break;
}
if ((!pEntry) || (pAd->PortCfg.MBSSID[pEntry->ApIdx].AuthMode < Ndis802_11AuthModeWPA))
break;
// If this IE did not begins with 00:0x50:0xf2:0x01, it would be proprietary. So we ignore
if (eid_ptr->Eid == IE_WPA)
{
if (!RTMPEqualMemory(eid_ptr->Octet, WPA, 4))
break;
}
if (eid_ptr->Len <= MAX_LEN_OF_RSNIE && eid_ptr->Len > MIN_LEN_OF_RSNIE)
{
*pRSNLen=eid_ptr->Len;
if (!RTMPCheckMcast(pAd, eid_ptr, pEntry))
{
DBGPRINT(RT_DEBUG_TRACE, " RTMPCheckMcast FAILED !!!! \n");
if (pEntry)
DisAssocAction( pAd, pEntry, SUBTYPE_DISASSOC, REASON_MCIPHER_NOT_VALID);
return FALSE;
}
if (!RTMPCheckUcast(pAd, eid_ptr, pEntry))
{
DBGPRINT(RT_DEBUG_TRACE, " RTMPCheckUcast FAILED !!!! \n");
if (pEntry)
DisAssocAction( pAd, pEntry, SUBTYPE_DISASSOC, REASON_UCIPHER_NOT_VALID);
return FALSE;
}
if (!RTMPCheckAUTH(pAd, eid_ptr, pEntry))
{
DBGPRINT(RT_DEBUG_TRACE, " RTMPCheckAUTH Method FAILED !!!! \n");
if (pEntry)
DisAssocAction( pAd, pEntry, SUBTYPE_DISASSOC, REASON_INVALID_IE);
return FALSE;
}
NdisMoveMemory(RSN, eid_ptr->Octet, eid_ptr->Len);
DBGPRINT(RT_DEBUG_INFO, "Receive IE_WPA : %x %x %x %x %x %x %x %x \n",\
eid_ptr->Octet[0],eid_ptr->Octet[1],eid_ptr->Octet[2],eid_ptr->Octet[3],eid_ptr->Octet[4],\
eid_ptr->Octet[5],eid_ptr->Octet[6],eid_ptr->Octet[7]);
}
else
{
*pRSNLen=0;
DBGPRINT(RT_DEBUG_TRACE, "PeerAssocReqSanity - missing IE_WPA)\n");
return FALSE;
break;
}
break;
default:
break;
}
eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
}
if (Sanity != 0x03)
{
DBGPRINT(RT_DEBUG_WARN, "PeerAssocReqSanity - missing mandatory field)\n");
return FALSE;
}
else
{
return TRUE;
}
}
BOOLEAN PeerReassocReqSanity(
IN PRTMP_ADAPTER pAd,
IN VOID *Msg,
IN ULONG MsgLen,
OUT PUCHAR pAddr1,
OUT PUCHAR pAddr2,
OUT USHORT *pCapabilityInfo,
OUT USHORT *pListenInterval,
OUT PUCHAR pApAddr,
OUT UCHAR *pSsidLen,
OUT char *Ssid,
OUT UCHAR *pRatesLen,
OUT UCHAR Rates[],
OUT UCHAR *RSN,
OUT UCHAR *pRSNLen,
OUT BOOLEAN *pbWmmCapable,
OUT ULONG *pRalinkIe)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -