⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sanity.c

📁 经过修改的在uClinux2.6上正常运行的ralink rt2571芯片组的设备驱动程序.
💻 C
📖 第 1 页 / 共 3 页
字号:
        return FALSE;
    }
	else
	{
		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
	NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN);
	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) 
	{

		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:
				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;		    
                    }

					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;
					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;
					NdisMoveMemory(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);
					NdisMoveMemory(&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;		    
                    }

					NdisMoveMemory(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)
				{
					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;
						
			// 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;		    
                    }

					NdisMoveMemory(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:
        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -