📄 sanity.c
字号:
if ((pAd->PortCfg.AdhocMode == 2) && (RateLen < 8)) return (FALSE); } 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 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 *LengthVIE, OUT PNDIS_802_11_VARIABLE_IEs pVIE){ CHAR *Ptr, TimLen; PFRAME_802_11 pFrame; PEID_STRUCT pEid; UCHAR SubType; UCHAR Sanity; ULONG Length = 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 *pRalinkIe = 0; *pNewChannel = 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; Length += LENGTH_802_11; // get timestamp from payload and advance the pointer memcpy(pTimestamp, Ptr, TIMESTAMP_LEN); Ptr += TIMESTAMP_LEN; Length += TIMESTAMP_LEN; // get beacon interval from payload and advance the pointer *pBeaconPeriod = *(USHORT *)(Ptr); Ptr += 2; Length += 2; // get capability info from payload and advance the pointer *pCapabilityInfo = *(USHORT *)(Ptr); 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) { 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) { memcpy(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; memcpy(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) { *pAtimWin = le16_to_cpup((PUSHORT)pEid->Octet); } 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->ActiveCfg.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 // 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]; } else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) { // Copy to pVIE used by driver, wpa supplicant and ui Ptr = (PUCHAR) pVIE; // 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; } memcpy(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; 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; // 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 }#if WPA_SUPPLICANT_SUPPORT else if (NdisEqualMemory(pEid->Octet, WSC_OUI, 4) && (SubType == SUBTYPE_BEACON) && (pAd->PortCfg.Send_Beacon == TRUE)) { union iwreq_data wrqu; char buf[560] = {0}; pAd->PortCfg.WscIEBeacon.ValueLen = pEid->Len - 4; memcpy(pAd->PortCfg.WscIEBeacon.Value, &pEid->Octet[4], pEid->Len - 4); //Send WSC beacon to wpa_supplicant memset(&wrqu, 0, sizeof(wrqu)); sprintf(buf, "WSCBEACON=<%d>", pAd->PortCfg.WscIEBeacon.ValueLen); wrqu.data.length = strlen(buf); memcpy(&buf[wrqu.data.length], pAd->PortCfg.WscIEBeacon.Value, pAd->PortCfg.WscIEBeacon.ValueLen); wrqu.data.length += pAd->PortCfg.WscIEBeacon.ValueLen; wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, buf); //COPY_MAC_ADDR(pAd->PortCfg.MBSSID[pAd->IoctlIF].WscIEProbRspAddr2, pAddr2); //return FALSE; }#endif else { // Gemtek ask us to pass other vendor's IE for their applications Ptr = (PUCHAR) pVIE; // 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; } memcpy(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2); *LengthVIE += (pEid->Len + 2); } DBGPRINT(RT_DEBUG_INFO, "PeerBeaconAndProbeRspSanity - Receive IE_WPA\n"); break; case IE_EXT_SUPP_RATES: if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) { memcpy(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; // 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 used by driver, wpa supplicant and ui Ptr = (PUCHAR) pVIE; // 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; } memcpy(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2); *LengthVIE += (pEid->Len + 2); } DBGPRINT(RT_DEBUG_INFO, "IE_RSN length = %d\n", pEid->Len); break;#if 0 case IE_QBSS_LOAD: if (pEid->Len == 5) { pQbssLoad->bValid = TRUE; pQbssLoad->StaNum = pEid->Octet[0] + pEid->Octet[1] * 256; pQbssLoad->ChannelUtilization = pEid->Octet[2]; pQbssLoad->RemainingAdmissionControl = pEid->Octet[3] + pEid->Octet[4] * 256; } break; case IE_EDCA_PARAMETER: if (pEid->Len == 18) { PUCHAR ptr; int i; pEdcaParm->bValid = TRUE; pEdcaParm->bQAck = pEid->Octet[0] & 0x10; pEdcaParm->bQueueRequest = pEid->Octet[0] & 0x20; pEdcaParm->bTxopRequest = pEid->Octet[0] & 0x40;// pEdcaParm->bMoreDataAck = pEid->Octet[0] & 0x80; pEdcaParm->EdcaUpdateCount = pEid->Octet[0] & 0x0f; ptr = &pEid->Octet[2]; 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 } } break; case IE_QOS_CAPABILITY: // this IE contains redundant information as stated in EDCA_IE if (pEid->Len == 1) { pQosCapability->bValid = TRUE; pQosCapability->bQAck = pEid->Octet[0] & 0x01; pQosCapability->bQueueRequest = pEid->Octet[0] & 0x02; pQosCapability->bTxopRequest = pEid->Octet[0] & 0x04;// pQosCapability->bMoreDataAck = pEid->Octet[0] & 0x08; pQosCapability->EdcaUpdateCount = pEid->Octet[0] >> 4; } break;#endif default: // Unknown IE, do nothing!!! DBGPRINT(RT_DEBUG_INFO, "PeerBeaconAndProbeRspSanity - unrecognized EID = %d\n", pEid->Eid); 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 if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x04) == 0)) { *pChannel = pAd->LatchRfRegs.Channel; Sanity |= 0x4; } if (Sanity != 0x7) { DBGPRINT(RT_DEBUG_WARN, "PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity); return FALSE; } else { return TRUE; }}/* ========================================================================== Description: ========================================================================== */BOOLEAN GetTimBit( IN CHAR *Ptr, IN USHORT Aid,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -