📄 sanity.c
字号:
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
*pSsidLen = 0;
*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);
NdisMoveMemory(pApAddr, &Fr->Octet[4], 6);
eid_ptr = (PEID_STRUCT) &Fr->Octet[10];
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 (len=%d)\n", eid_ptr->Len);
return FALSE;
}
break;
case IE_SUPP_RATES:
if (eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES)
{
Sanity |= 0x02;
NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
*pRatesLen = eid_ptr->Len;
}
else
{
DBGPRINT(RT_DEBUG_TRACE, "PeerAssocReqSanity - wrong IE_SUPP_RATES (len=%d)\n", eid_ptr->Len);
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_TRACE, "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;
}
}
/*
==========================================================================
Description:
MLME message sanity check
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
BOOLEAN PeerDisassocReqSanity(
IN PRTMP_ADAPTER pAd,
IN VOID *Msg,
IN ULONG MsgLen,
OUT PUCHAR Addr2,
OUT USHORT *Reason)
{
PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
COPY_MAC_ADDR(Addr2, Fr->Hdr.Addr2);
NdisMoveMemory(Reason, &Fr->Octet[0], 2);
return TRUE;
}
/*
==========================================================================
Description:
MLME message sanity check
Return:
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
BOOLEAN PeerBeaconAndProbeRspSanity(
IN PRTMP_ADAPTER pAd,
IN VOID *Msg,
IN ULONG MsgLen,
OUT PUCHAR pAddr2,
OUT PUCHAR pBssid,
OUT CHAR Ssid[],
OUT UCHAR *pSsidLen,
OUT UCHAR *pBssType,
OUT USHORT *pBeaconPeriod,
OUT UCHAR *pChannel,
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 *LengthVIE,
OUT PNDIS_802_11_VARIABLE_IEs pVIE)
{
CHAR *Ptr;
PFRAME_802_11 pFrame;
PEID_STRUCT pEid;
UCHAR SubType;
UCHAR Sanity;
// 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
*pRalinkIe = 0;
*LengthVIE = 0;
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 = (PFRAME_802_11)Msg;
// get subtype from header
SubType = (UCHAR)pFrame->Hdr.FC.SubType;
// get Addr2 and BSSID from header
COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3);
Ptr = pFrame->Octet;
// get timestamp from payload and advance the pointer
NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN);
Ptr += TIMESTAMP_LEN;
// get beacon interval from payload and advance the pointer
NdisMoveMemory(pBeaconPeriod, Ptr, 2);
Ptr += 2;
// get capability info from payload and advance the pointer
NdisMoveMemory(pCapabilityInfo, Ptr, 2);
Ptr += 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(((UCHAR*)pEid + pEid->Len + 1) < ((UCHAR*)pFrame + MsgLen))
{
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_FH_PARM:
DBGPRINT(RT_DEBUG_TRACE, "PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n");
break;
case IE_DS_PARM:
if(pEid->Len == 1)
{
*pChannel = *pEid->Octet;
if (ChannelSanity(pAd, *pChannel) == 0)
{
DBGPRINT(RT_DEBUG_INFO, "PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (ch=%d)\n",*pChannel);
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:
break;
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];
}
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))
{
}
else if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6) && (pEid->Len == 7))
{
}
DBGPRINT(RT_DEBUG_INFO, "PeerBeaconAndProbeRspSanity - Receive IE_WPA\n");
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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -