示例#1
0
/********************************************************************************************************************
 *function:  construct ADDBAREQ frame
 *   input:  u8* 		dst 	//ADDBARsp frame's destination
 *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA_RSP.
 *   	     u16 		StatusCode  //status code.
 *  output:  none
 *  return:  sk_buff* 		skb     //return constructed skb to xmit
********************************************************************************************************************/
static struct sk_buff* ieee80211_ADDBA_Rsp( IN	struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, u16 StatusCode)
{
	OCTET_STRING	osADDBAFrame, tmp;

	FillOctetString(osADDBAFrame, Buffer, 0);
	*pLength = 0;

	ConstructMaFrameHdr(
					Adapter,
					Addr,
					ACT_CAT_BA,
					ACT_ADDBARSP,
					&osADDBAFrame	);

	// Dialog Token
	FillOctetString(tmp, &pBA->DialogToken, 1);
	PacketAppendData(&osADDBAFrame, tmp);

	// Status Code
	FillOctetString(tmp, &StatusCode, 2);
	PacketAppendData(&osADDBAFrame, tmp);

	// BA Parameter Set
	FillOctetString(tmp, &pBA->BaParamSet, 2);
	PacketAppendData(&osADDBAFrame, tmp);

	// BA Timeout Value
	FillOctetString(tmp, &pBA->BaTimeoutValue, 2);
	PacketAppendData(&osADDBAFrame, tmp);

	*pLength = osADDBAFrame.Length;
}
//
// Parsing Information Elements.
//
// This function is used to search the WPS Fragment IE
// In WPS 2.0. It wil content more then 2 IE is the forment
// DD-Len-00-50-f2-04-xxxxx-DD-Len-00-50-f2-04
//
u1Byte
PacketGetElementNum(
	IN	OCTET_STRING	packet,
	IN	ELEMENT_ID		ID,
	IN	OUI_TYPE		OUIType,
	IN	u1Byte			OUISubType
	)
{
	u2Byte			offset;
	OCTET_STRING	IEs;
	OCTET_STRING	ret={0,0};	// used for return
	u1Byte 			IENum = 0;

	if(!PacketGetIeOffset(&packet, &offset))
	{
		return 0;
	}
	
	if(offset < packet.Length)
	{
		pu1Byte	pIE;
		u2Byte IELen = (packet.Length - offset);
		
		pIE = (packet.Octet + offset);
		FillOctetString(IEs, pIE,IELen);

		RT_PRINT_DATA(COMP_WPS, DBG_TRACE, "The IE in the packet :\n", pIE, IELen);
		do
		{
			ret= IEGetElement(IEs, ID, OUIType, OUISubType);
			if(ret.Length > 0)
			{
				IENum++;
				RT_TRACE(COMP_WPS, DBG_TRACE,("We find a WPS IE in probe or beacon Fragment num is %d \n",IENum));
				IELen = IELen - ((u2Byte)(ret.Octet - pIE) + ret.Length);
				pIE = (ret.Octet + ret.Length);			
				FillOctetString(IEs, pIE,IELen);			
				RT_PRINT_DATA(COMP_WPS, DBG_TRACE, "The IE after WPS IE in the packet :\n", pIE, IELen);
			}
			else
			{
				RT_TRACE(COMP_WPS, DBG_TRACE,("There is no WPS IE in the probe or beacon\n"));				
			}
		}
		while(ret.Length != 0);
		
		return IENum;
	}
	else
	{
		return IENum;
	}
}
//
// Parsing Information Elements.
//
// Added a parameter "OUISubType" and rewrited by Annie, 2005-11-08,
// since the element ID of WPA-IE and WMM-IE are the same(0xDD=221).
//
OCTET_STRING 
PacketGetElement(
	IN	OCTET_STRING	packet,
	IN	ELEMENT_ID		ID,
	IN	OUI_TYPE		OUIType,
	IN	u1Byte			OUISubType
	)
{
	u2Byte			offset;
	OCTET_STRING	IEs;
	OCTET_STRING	ret={0,0};	// used for return

	if(!PacketGetIeOffset(&packet, &offset))
		return ret;

	if(offset < packet.Length)
	{
		FillOctetString(IEs, (packet.Octet + offset), (packet.Length - offset));
		return IEGetElement(IEs, ID, OUIType, OUISubType);
	}
	else
	{
		return ret;
	}
}
// 
// Description:
//	Get the number of IE elements and extract the interested element for return.
// Arguments:
//	[in] IEs -
//		The IE elements to be retrived.
// 	[in] ID -
//		The referenced element ID in the IEs to be extracted.
// 	[in] OUIType -
//		Vendor specified OUI to be determined in the element.
//	[in] OUISubType -
//		The oui subtype of the element
// Return:
//	The number of the IEs.
// Revised by Bruce, 2012-03-26.
//
u1Byte
IEGetElementNum(
	IN	OCTET_STRING	IEs,
	IN	ELEMENT_ID		ID,
	IN	OUI_TYPE		OUIType,
	IN	u1Byte			OUISubType
	)
{
	u1Byte 			IENum = 0;
	OCTET_STRING	osTmp, osSingleIE;
	u2Byte			offset = 0;
	
	do
	{
		if(offset >= IEs.Length)
			break;

		FillOctetString(osTmp, IEs.Octet + offset, (IEs.Length - offset));
		
		osSingleIE = IEGetElement(osTmp, ID, OUIType, OUISubType);
		if(osSingleIE.Length > 0)
		{
			IENum ++;

			offset += (SIZE_EID_AND_LEN + osSingleIE.Length);
		}
		else
		{
			break;
		}
	}
	while(TRUE);
		
	return IENum;
}
示例#5
0
VOID
WPS_ConstructBeaconFrame(
	IN		PADAPTER	Adapter
	)
{
	//
	// Simple config IE. by CCW - copy from 818x
	//
	PMGNT_INFO			pMgntInfo = &(Adapter->MgntInfo);
	PSIMPLE_CONFIG_T	pSimpleConfig ;
	OCTET_STRING		SimpleConfigInfo;
	PMGNT_INFO 			pDefaultMgntInfo;

	if(ACTING_AS_IBSS(Adapter))
		return;

	if(!ACTING_AS_AP(Adapter))
		return;
	
	pDefaultMgntInfo = &(GetDefaultAdapter(Adapter)->MgntInfo);

	pSimpleConfig = GET_SIMPLE_CONFIG(pDefaultMgntInfo);
	
	if( ((pSimpleConfig->WpsIeVersion < SUPPORT_WPS_INFO_VERSION) || (wps_IsWPSIEReady(Adapter) == FALSE)) && pSimpleConfig->IELen > 0)
	{	// Original method carrying WPS IE
		RT_TRACE(COMP_WPS, DBG_TRACE, ("AP Construct Beacon \n"));
		FillOctetString(SimpleConfigInfo, pSimpleConfig->IEBuf, pSimpleConfig->IELen);
		PacketMakeElement( &pMgntInfo->beaconframe, EID_Vendor, SimpleConfigInfo);
	}
	else if(pSimpleConfig->WpsIeVersion == SUPPORT_WPS_INFO_VERSION)
	{
		FillOctetString(SimpleConfigInfo, pSimpleConfig->ieBeaconBuf, pSimpleConfig->ieBeaconLen);
		if(pSimpleConfig->ieBeaconLen > 0)
			PacketAppendData(&pMgntInfo->beaconframe, SimpleConfigInfo);
	}
		
}
// 
// Description:
//	Parse the IE elements and extract the interested element for return.
// Arguments:
//	IEs -
//		The IE elements to be retrived.
// 	ID -
//		The referenced element ID in the IEs to be extracted.
// 	OUISubType -
//		Vendor specified OUI to be determined in the element.
// Revised by Bruce, 2009-02-12.
//
OCTET_STRING 
IEGetElement(
	IN	OCTET_STRING	IEs,
	IN	ELEMENT_ID		ID,
	IN	OUI_TYPE		OUIType,
	IN	u1Byte			OUISubType
	)
{
	u2Byte			offset = 0;
	u2Byte			length = IEs.Length;
	OCTET_STRING	ret={0,0};	// used for return
	u1Byte			temp;
	BOOLEAN 		bIEMatched = FALSE;
	OCTET_STRING	osOuiSub;
	u1Byte			MaxElementLen;

	static u1Byte	WPATag[] = {0x00, 0x50, 0xf2, 0x01};
	static u1Byte	WMMTag[] = {0x00, 0x50, 0xf2, 0x02};				// Added by Annie, 2005-11-08.
	static u1Byte	Simpleconf[]={0x00, 0x50, 0xF2, 0x04};				//added by David, 2006-10-02
	static u1Byte	CcxRmCapTag[] = {0x00, 0x40, 0x96, 0x01};			// For CCX 2 S36, Radio Management Capability element, 2006.05.15, by rcnjko.
	static u1Byte	CcxVerNumTag[] = {0x00, 0x40, 0x96, 0x03};			// For CCX 2 S38, WLAN Device Version Number element. Annie, 2006-08-20.
	static u1Byte	WPA2GTKTag[] = {0x00, 0x0f, 0xac, 0x01};			// For MAC GTK data IE by CCW
	static u1Byte	CcxTsmTag[] = {0x00, 0x40, 0x96, 0x07};				// For CCX4 S56, Traffic Stream Metrics, 070615, by rcnjko.
	static u1Byte	CcxSSIDLTag[] = {0x00, 0x50, 0xf2, 0x05};
	static u1Byte	RealtekTurboModeTag[] = {0x00, 0xE0, 0x4C, 0x01};	// Added by Annie, 2005-12-27
	static u1Byte	RealtekAggModeTag[] = {0x00, 0xe0, 0x4c, 0x02};
	static u1Byte	RealtekBTIOTModeTag[] = {0x00, 0xe0, 0x4c, 0x03};	// Add for BT IOT 
	static u1Byte	RealtekBtHsTag[] = {0x00, 0xe0, 0x4c, 0x04};		// Add for BT HS 	
	static u1Byte	Epigram[] = {0x00,0x90,0x4c};
	static u1Byte	EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x033};			// For 11n EWC definition, 2007.07.17, by Emily
	static u1Byte	EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x034};			// For 11n EWC definition, 2007.07.17, by Emily	
	static u1Byte	Epigram11ACCap[] = {0x00, 0x90, 0x4c, 0x04, 0x08, 0xBF, 0x0C};	// For 11ac Epigram definition
	static u1Byte	BroadcomCap_1[] = {0x00, 0x10, 0x18};
	static u1Byte	BroadcomCap_2[] = {0x00, 0x0a, 0xf7};
	static u1Byte	BroadcomCap_3[] = {0x00, 0x05, 0xb5};
	static u1Byte	BroadcomLinksysE4200Cap_1[] = {0x00, 0x10, 0x18,0x02,0x00,0xf0,0x3c};  // for Linksys E4200
	static u1Byte	BroadcomLinksysE4200Cap_2[] = {0x00, 0x10, 0x18,0x02,0x01,0xf0,0x3c};
	static u1Byte	BroadcomLinksysE4200Cap_3[] = {0x00, 0x10, 0x18,0x02,0x00,0xf0,0x2c};
	static u1Byte	CiscoCap[] = {0x00, 0x40, 0x96};			// For Cisco AP IOT issue, by Emily
	static u1Byte	MeruCap[] = {0x00, 0x0c, 0xe6};
	static u1Byte	RalinkCap[] ={0x00, 0x0c, 0x43};
	static u1Byte	AtherosCap_1[] = {0x00,0x03,0x7F};
	static u1Byte	AtherosCap_2[] = {0x00,0x13,0x74};
	static u1Byte	MarvellCap[] = {0x00, 0x50, 0x43};
	static u1Byte	AirgoCap[] = {0x00, 0x0a, 0xf5};
	static u1Byte	CcxSFA[] = {0x00, 0x40, 0x96, 0x14};
	static u1Byte	CcxDiagReqReason[] = {0x00, 0x40, 0x96, 0x12};
	static u1Byte	CcxMHDR[] = {0x00, 0x40, 0x96, 0x10};
	static u1Byte	P2P_OUI_WITH_TYPE[] = {0x50, 0x6F, 0x9A, WLAN_PA_VENDOR_SPECIFIC};
	static u1Byte	WFD_OUI_WITH_TYPE[] = {0x50, 0x6F, 0x9A, WFD_OUI_TYPE};
	static u1Byte	NAN_OUI_WITH_TYPE[] = {0x50, 0x6F, 0x9A, 0x13}; 
	static u1Byte	RealtekTDLSTag[] = {0x00, 0xe0, 0x4c, 0x03};

	//Mix mode can't get DHCP in MacOS Driver. CCW revice offset 2008-04-15
	//offset = 12;

	do
	{
		if( (offset + 2) >= length )
		{
			return ret;
		}
		
		temp = IEs.Octet[offset];	// Get current Element ID.

		if( temp == ID )
		{
			if( ID == EID_Vendor )
			{ // EID_Vendor(=0xDD=221): Vendor Specific, currently we have to consider WPA and WMM Information Element.
				switch(OUIType)
				{
					case OUI_SUB_WPA:
						FillOctetString(osOuiSub, WPATag,  sizeof(WPATag));
						break;
					case OUI_SUB_WPA2GTK:
						FillOctetString(osOuiSub, WPA2GTKTag,  sizeof(WPA2GTKTag));
						break;
						
					case OUI_SUB_CCX_TSM:
						FillOctetString(osOuiSub, CcxTsmTag,  sizeof(CcxTsmTag));
						break;

					case OUI_SUB_SSIDL:
						FillOctetString(osOuiSub, CcxSSIDLTag,	sizeof(CcxSSIDLTag));
						break;

					case OUI_SUB_WMM:
						FillOctetString(osOuiSub, WMMTag,  sizeof(WMMTag));
							break;

					case OUI_SUB_REALTEK_TURBO:
						FillOctetString(osOuiSub, RealtekTurboModeTag,	sizeof(RealtekTurboModeTag));
						break;

					case OUI_SUB_REALTEK_AGG:
						FillOctetString(osOuiSub, RealtekAggModeTag, sizeof(RealtekAggModeTag));
						break;

					case OUI_SUB_SimpleConfig:
						FillOctetString(osOuiSub, Simpleconf,  sizeof(Simpleconf));
						break;

					case OUI_SUB_CCX_RM_CAP:
						FillOctetString(osOuiSub, CcxRmCapTag,	sizeof(CcxRmCapTag));
						break;

					case OUI_SUB_CCX_VER_NUM:
						FillOctetString(osOuiSub, CcxVerNumTag,  sizeof(CcxVerNumTag));
						break;
						
					case OUI_SUB_EPIG_IE:
						FillOctetString(osOuiSub, Epigram,  sizeof(Epigram));
						break;

					case OUI_SUB_11N_EWC_HT_CAP:
						FillOctetString(osOuiSub, EWC11NHTCap,	sizeof(EWC11NHTCap));
						break;

					case OUI_SUB_11N_EWC_HT_INFO:
						FillOctetString(osOuiSub, EWC11NHTInfo,  sizeof(EWC11NHTInfo));
						break;

					case OUI_SUB_11AC_EPIG_VHT_CAP:
						FillOctetString(osOuiSub, Epigram11ACCap,  sizeof(Epigram11ACCap));
						break;

					case OUI_SUB_BROADCOM_IE_1:
						FillOctetString(osOuiSub, BroadcomCap_1,  sizeof(BroadcomCap_1));						
						break;
						
					case OUI_SUB_BROADCOM_IE_2:
						FillOctetString(osOuiSub, BroadcomCap_2,  sizeof(BroadcomCap_2));						
						break;
						
					case OUI_SUB_BROADCOM_IE_3:
						FillOctetString(osOuiSub, BroadcomCap_3,  sizeof(BroadcomCap_3));						
						break;
						
					case OUI_SUB_BROADCOM_LINKSYSE4200_IE_1:
						FillOctetString(osOuiSub, BroadcomLinksysE4200Cap_1,  sizeof(BroadcomLinksysE4200Cap_1));						
						break;
						
					case OUI_SUB_BROADCOM_LINKSYSE4200_IE_2:
						FillOctetString(osOuiSub, BroadcomLinksysE4200Cap_2,  sizeof(BroadcomLinksysE4200Cap_2));						
						break;
						
					case OUI_SUB_BROADCOM_LINKSYSE4200_IE_3:
						FillOctetString(osOuiSub, BroadcomLinksysE4200Cap_3,  sizeof(BroadcomLinksysE4200Cap_3));						
						break;			

					case OUI_SUB_CISCO_IE:
						FillOctetString(osOuiSub, CiscoCap, sizeof(CiscoCap));
						break;

					case OUI_SUB_MERU_IE:
						FillOctetString(osOuiSub, MeruCap, sizeof(MeruCap));
						break;

					case OUI_SUB_RALINK_IE:
						FillOctetString(osOuiSub, RalinkCap, sizeof(RalinkCap));
						break;
						
					case OUI_SUB_ATHEROS_IE_1:
						FillOctetString(osOuiSub, AtherosCap_1, sizeof(AtherosCap_1));
						break;
						
					case OUI_SUB_ATHEROS_IE_2:
						FillOctetString(osOuiSub, AtherosCap_2, sizeof(AtherosCap_2));
						break;
						
					case OUI_SUB_MARVELL:
						FillOctetString(osOuiSub, MarvellCap, sizeof(MarvellCap));
						break;
						
					case OUI_SUB_AIRGO:
						FillOctetString(osOuiSub, AirgoCap, sizeof(AirgoCap));
						break;	
						
					case OUI_SUB_CCX_SFA:
						FillOctetString(osOuiSub, CcxSFA, sizeof(CcxSFA));
						break;
						
					case OUI_SUB_CCX_DIAG_REQ_REASON:
						FillOctetString(osOuiSub, CcxDiagReqReason, sizeof(CcxDiagReqReason));
						break;

					case OUI_SUB_CCX_MFP_MHDR:
						FillOctetString(osOuiSub, CcxMHDR, sizeof(CcxMHDR));
						break;
						
					case OUI_SUB_WIFI_DIRECT:
						FillOctetString(osOuiSub, P2P_OUI_WITH_TYPE, sizeof(P2P_OUI_WITH_TYPE));
						break;

					case OUI_SUB_WIFI_DISPLAY:
						FillOctetString(osOuiSub, WFD_OUI_WITH_TYPE, sizeof(WFD_OUI_WITH_TYPE));
						break;
						
					case OUI_SUB_NAN:
						FillOctetString(osOuiSub, NAN_OUI_WITH_TYPE, sizeof(NAN_OUI_WITH_TYPE));
						break;
							
					case OUI_SUB_REALTEK_TDLS:
						FillOctetString(osOuiSub, RealtekTDLSTag, sizeof(RealtekTDLSTag));
						break;
						
					case OUI_SUB_REALTEK_BT_IOT :
						FillOctetString(osOuiSub, RealtekBTIOTModeTag, sizeof(RealtekBTIOTModeTag));
						break;

					case OUI_SUB_REALTEK_BT_HS:
						FillOctetString(osOuiSub, RealtekBtHsTag, sizeof(RealtekBtHsTag));
						break;
						
					default:
						FillOctetString(osOuiSub, NULL, 0);
						break;
				}
				if( osOuiSub.Length > 0 && (length >= (offset + 2 + osOuiSub.Length)) ) // Prevent malicious attack.
				{
					if( PlatformCompareMemory(
						(IEs.Octet + offset + 2), 
						osOuiSub.Octet, 
						osOuiSub.Length) == 0 )
					{ // OUI field and subtype field are matched
						bIEMatched = TRUE;

						//
						// 060801, Isaiah:
						// [UAPSD Logo] Marvel AP has similar element, [DD 07 00 50 F2 02 05 01 24].
						//
						if( (OUI_SUB_WMM == OUIType) && 
							(length >= (offset + 2 + osOuiSub.Length + 1)) )
						{ // WMM-IE Matched!
						 	u1Byte WmmSubtype = *(IEs.Octet+offset+2+sizeof(WMMTag));

							if(WmmSubtype != OUISubType)
								bIEMatched = FALSE;
						}
					}
				}
			}
			else	
			{ // Other ID: Matched!
				bIEMatched = TRUE;
			}
		}

		if(bIEMatched &&
			(length >= offset + 2 + IEs.Octet[offset+1]) ) // Prevent malicious attack.
		{ // IE matched! break to return.
			//
			// Get the length of current IE.
			// We also perform length checking here to pervent malicious attack.	
			//
			switch(ID)
			{
			case EID_SsId:
				MaxElementLen = MAX_SSID_LEN;
				break;
			case EID_SupRates:
				MaxElementLen = 12; //Because Belkin 11AC  on g Mode only has 12 Octets in this IE
				break;
			case EID_FHParms:
				MaxElementLen = MAX_FH_PARM_LEN;
				break;
			case EID_DSParms:
				MaxElementLen = MAX_DS_PARM_LEN;
				break;
			case EID_CFParms:
				MaxElementLen = MAX_CF_PARM_LEN;
				break;
			case EID_Tim:
				MaxElementLen = MAX_TIM_PARM_LEN;
				break;
			case EID_IbssParms:
				MaxElementLen = MAX_IBSS_PARM_LEN;
				break;
			case EID_QBSSLoad:
				MaxElementLen = MAX_QBSS_LOAD_LEN;
				break;
			case EID_EDCAParms:
				MaxElementLen = MAX_EDCA_PARM_LEN;
				break;
			case EID_TSpec:
				MaxElementLen = MAX_TSPEC_LEN;
				break;
			case EID_Schedule:
				MaxElementLen = MAX_SCHEDULE_LEN;
				break;
			case EID_Ctext:
				MaxElementLen = MAX_CTEXT_LEN;
				break;
			case EID_ERPInfo:
				MaxElementLen = MAX_ERP_INFO_LEN;
				break;
			case EID_TSDelay:
				MaxElementLen = MAX_TS_DELAY_LEN;
				break;
			case EID_TCLASProc:
				MaxElementLen = MAX_TC_PROC_LEN;
				break;
			case EID_HTCapability:
				MaxElementLen = MAX_HT_CAP_LEN;
				break;
			case EID_HTInfo:
				MaxElementLen = MAX_HT_INFO_LEN;
				break;
			case EID_QoSCap:
				MaxElementLen = MAX_QOS_CAP;
				break;
			case EID_ExtSupRates:
				MaxElementLen = MAX_EXT_SUP_RATE_LEN;
				break;

			case EID_WAPI:
				MaxElementLen = MAX_WAPI_IE_LEN;
				break;
			case EID_LinkIdentifier:
				MaxElementLen = MAX_LINKID_LEN;
				break;
			case EID_SupportedChannels:
				MaxElementLen = MAX_SUPCHNL_LEN;
				break;
			case EID_SupRegulatory:
				MaxElementLen = MAX_SUPREGULATORY_LEN;
				break;
			case EID_SecondaryChnlOffset:
				MaxElementLen = MAX_SECONDARYOFFSET_LEN;
				break;
			case EID_ChnlSwitchTimeing:
				MaxElementLen = MAX_CHNLSWITCHTIMING_LEN;
				break;
			case EID_VHTCapability:
				MaxElementLen = MAX_VHT_CAP_LEN;
				break;
			default:
				MaxElementLen = MAX_IE_LEN;
				break;
			}
			ret.Length = (IEs.Octet[offset+1] <= MaxElementLen) ? IEs.Octet[offset+1] : MaxElementLen;

			//
			// Get pointer to the first byte (ElementID and length are not included).
			//
			ret.Octet = IEs.Octet + offset + 2;

			break;
		}
		else
		{ // Different.
			temp = IEs.Octet[offset+1]; 		// Get the length of current IE.
			offset += (temp+2); 				// Jump to the position of length of next IE. (2 byte is for the ID and length field.)
		}
	}while(1);

	return ret;
}
PADAPTER
MultiPortFeedPacketToMultipleAdapter(
	PADAPTER	pAdapter,
	PRT_RFD		pRfd
)
{
	// NOTE: --------------------------------------------------------------
	//  If only single adapter is needed, return that adapter.
	// --------------------------------------------------------------------

	PADAPTER pDefaultAdapter = GetDefaultAdapter(pAdapter);
	PMULTIPORT_COMMON_CONTEXT pMultiPortCommon = MultiPortGetCommonContext(pDefaultAdapter);
	PADAPTER pExtAdapter = NULL;
	PRT_RFD pExtRfd = NULL;
	u4Byte i = 0;
	RT_STATUS rtStatus = RT_STATUS_SUCCESS;
	
	// Assertion Check Variable
	u4Byte uCurrentCloneRFDs;
	
	// Target List 
	u4Byte uTargetAdapter = 0;
	PADAPTER TargetList[10];


	// Single MPDU
	OCTET_STRING frame = {NULL, 0};
	FillOctetString(frame, pRfd->Buffer.VirtualAddress, pRfd->PacketLength);

	if(pRfd->Status.bHwError)
	{
		RT_TRACE(COMP_RECV, DBG_TRACE, ("MultiPortFeedPacketToMultipleAdapter(): Return because bHwError is true.\n"));
		return NULL;
	}

	// Information Source: pRfd Status Checking -------------------------------------------------------
	RT_ASSERT(pRfd->Buffer.VirtualAddress != NULL, ("Error: pRfd->Buffer.VirtualAddress is NULL!\n"));
	RT_ASSERT(pRfd->Buffer.Length != 0, ("Error: pRfd->Buffer.Length is 0!\n"));
	RT_ASSERT(pRfd->PacketLength <= pRfd->Buffer.Length, ("Error: Packet Too Long!\n"));
	// ------------------------------------------------------------------------------------------

	// Clone RFD Status Checking ----------------------------------------------------------------------------------------------------------------------
	PlatformAcquireSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
	uCurrentCloneRFDs = pMultiPortCommon->uCloneRfdIdleQueueSize + pMultiPortCommon->uCloneRfdBusyQueueSize;
	RT_ASSERT(uCurrentCloneRFDs == pMultiPortCommon->uNumberOfCloneRfds, 	("Failure: Some Clone RFDs are Lost!uCurrentCloneRFDs=%d\n", uCurrentCloneRFDs));
	PlatformReleaseSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
	// ---------------------------------------------------------------------------------------------------------------------------------------------


	// Get the target adapter list -----------------------------------------------------------------------------
	uTargetAdapter = MultiPortGetTargetAdapterList(pAdapter, pRfd, frame, TargetList, sizeof(TargetList) / sizeof(PADAPTER));
	//RT_TRACE(COMP_INIT, DBG_TRACE, ("%s: uTargetAdapter: %d \n", __FUNCTION__, uTargetAdapter));
	
	if(uTargetAdapter == 0)
	{
		// Free the original RFD since the RFD is not necessary
		RT_TRACE(COMP_INIT, DBG_TRACE, ("%s: No Target Adapter Found!\n", __FUNCTION__));
		return NULL;
	}
	else if(uTargetAdapter == 1)
	{
		// Single adapter is needed. Do not free the original RFD, and run the original path
		return TargetList[0];
	}
	// ----------------------------------------------------------------------------------------------------


	// Send to each adapter
	for(i = 0; i < uTargetAdapter; i++)
	{
		// Get the target adapter element
		pExtAdapter = TargetList[i];

		PlatformAcquireSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
		if(RTIsListEmpty(&pMultiPortCommon->CloneRfdIdleQueue))
		{			
			PlatformReleaseSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
			RT_TRACE(COMP_INIT, DBG_SERIOUS, ("%s: No enough Clone RFD!\n", __FUNCTION__));
			break;
		}

		// Acquire an idle Clone RFD and initialize the Clone RFD -----------------------------------------
		pExtRfd = (PRT_RFD) RTRemoveHeadListWithCnt(
				&pMultiPortCommon->CloneRfdIdleQueue, 
				&pMultiPortCommon->uCloneRfdIdleQueueSize
			);

		// + Clone the original information
		PlatformZeroMemory(pExtRfd, sizeof(RT_RFD));
		PlatformMoveMemory(pExtRfd, pRfd, sizeof(RT_RFD));	

		// + Record the needed memory length 
		pExtRfd->mbCloneRfdDataBuffer.Length = pRfd->Buffer.Length;

		// + Allocate the memory based on the needed memory length above
		rtStatus = DrvIFAssociateRFD(pDefaultAdapter, pExtRfd);
		
		if(rtStatus != RT_STATUS_SUCCESS)
		{
			// Return the CloneRFD resource
			RTInsertTailListWithCnt(
				&pMultiPortCommon->CloneRfdIdleQueue, 
				&pExtRfd->List, 
				&pMultiPortCommon->uCloneRfdIdleQueueSize
			);
			PlatformReleaseSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
			//RT_TRACE(COMP_INIT, DBG_SERIOUS, ("%s: No enough memory!\n", __FUNCTION__));
			break;
		}

		//Sinda 20150903, Should assign Buffer's address according to it is clone RFD.
		if(IsCloneRFD(pDefaultAdapter, pExtRfd))
		{
			// + Attach the memory to the CloneRFD
			pExtRfd->Buffer.VirtualAddress = pExtRfd->mbCloneRfdDataBuffer.Buffer;
			pExtRfd->Buffer.Length = pExtRfd->mbCloneRfdDataBuffer.Length;
		}

#if RX_AGGREGATION
		//   + No Next RFD
		pExtRfd->NextRfd = NULL;

		//  + Only Single MPDU Packet
		pExtRfd->nTotalFrag = 1;

		//   + No Parent RFD
		pExtRfd->ParentRfd = NULL;

		//   + Not in the USB temp RFD list: pAdapter->RfdTmpList
		pExtRfd->bIsTemp = FALSE;
#endif

		//	Please be careful to handle pRfd->Buffer.VirtualAddress offset.
		//	+ Move data
		PlatformMoveMemory(
				pExtRfd->Buffer.VirtualAddress,
				pRfd->Buffer.VirtualAddress - pAdapter->HalFunc.GetRxPacketShiftBytesHandler(pRfd), 
				(pRfd->PacketLength + pAdapter->HalFunc.GetRxPacketShiftBytesHandler(pRfd))>pAdapter->MAX_RECEIVE_BUFFER_SIZE? pAdapter->MAX_RECEIVE_BUFFER_SIZE:(pRfd->PacketLength + pAdapter->HalFunc.GetRxPacketShiftBytesHandler(pRfd))
			);

		//   + Get shifted bytes of starting address of 802.11 header (Sync the memory offset)
		pExtRfd->Buffer.VirtualAddress += pAdapter->HalFunc.GetRxPacketShiftBytesHandler(pRfd);
	 	// -------------------------------------------------------------------------------------

		// Insert into busy Clone RFD queue
		RTInsertHeadListWithCnt(
				&pMultiPortCommon->CloneRfdBusyQueue, 
				&pExtRfd->List, 
				&pMultiPortCommon->uCloneRfdBusyQueueSize
			);

		PlatformReleaseSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
		// Iteration Flag
		pExtRfd->bFeedPacketToSingleAdapter = TRUE;

		// The pExtRfd will be free in ProcessReceivedPacket()
		ProcessReceivedPacketForEachPortSpecific(pExtAdapter, pExtRfd);
	}


	// Free the original RFD since the CloneRFD is adopted.
	return NULL;
}
// Description: According received EAPOL-key, enter the next state.
// Output: void
// Modify: Annie, 2005-07-02
//		Discard using condition pKeyMgnt->bPTKInstalled.
//		Instead, I add a macro KeyMgntStateIsWaitingEAPOLKey to check the state.
void 
Authenticator_OnEAPOLKeyRecvd(
	IN	PADAPTER				Adapter,
	IN	PAUTH_PKEY_MGNT_TAG	pKeyMgnt,
	IN	OCTET_STRING			pdu
	)
{
	PMGNT_INFO			pMgntInfo = &Adapter->MgntInfo;
	PAUTH_GLOBAL_KEY_TAG	pGlInfo = &pMgntInfo->globalKeyInfo;
	PRT_WLAN_STA		pEntry = pKeyMgnt->pWLanSTA;
	pu1Byte				pSTA_addr = Frame_pSaddr(pdu);
	pu1Byte				pAP_addr = Frame_pDaddr(pdu);
	PEAPOL_KEY_STRUCT	eapol_key_recvd;
	OCTET_STRING		SNonce;
	OCTET_STRING		RSNIE;
	MsgType				msg_type = type_unknow;

	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("===> Authenticator_OnEAPOLKeyRecvd()\n") );

	pKeyMgnt->EvntID = ASMEID_EAPOLKeyRecvd;

	FillOctetString(pGlInfo->EapolKeyMsgRecvd,								\
		pGlInfo->EAPOLMsgRecvd.Octet+LIB1X_EAPOL_HDRLEN,					\
		pGlInfo->EAPOLMsgRecvd.Length-LIB1X_EAPOL_HDRLEN );				\

	eapol_key_recvd = (PEAPOL_KEY_STRUCT)pGlInfo->EapolKeyMsgRecvd.Octet;

	//PRINT_DATA( ("EapolKeyMsgRecvd: "), pGlInfo->EapolKeyMsgRecvd.Octet, pGlInfo->EapolKeyMsgRecvd.Length);
	RSNIE.Octet = NULL;
	RSNIE.Length = 0;
	
	// Get the message number.
	if( Message_KeyType(pGlInfo->EapolKeyMsgRecvd) == type_Pairwise )
	{
		if( (Message_Error(pGlInfo->EapolKeyMsgRecvd) == 1) &&
			(Message_Request(pGlInfo->EapolKeyMsgRecvd) == 1))
		{			
			//Enter integrity failure state...			
			Authenticator_StateINTEGRITYFAILURE(Adapter, pEntry);	
		}

		if( (eapol_key_recvd->key_info[0]==0x01 && eapol_key_recvd->key_info[1]==0x09) ||
		    ( eapol_key_recvd->key_info[0]==0x01 && eapol_key_recvd->key_info[1]==0x0a) ||
		    ( eapol_key_recvd->key_info[0]==0x03 && eapol_key_recvd->key_info[1]==0x0a) ||
		    ( eapol_key_recvd->key_info[0]==0x03 && eapol_key_recvd->key_info[1]==0x09) )
		{
			if( pMgntInfo->SecurityInfo.SecLvl == RT_SEC_LVL_WPA)
			RSNIE = EAPOLkeyGetRSNIE( pGlInfo->EapolKeyMsgRecvd, EID_Vendor );
			else if( pMgntInfo->SecurityInfo.SecLvl == RT_SEC_LVL_WPA2)
				RSNIE = EAPOLkeyGetRSNIE( pGlInfo->EapolKeyMsgRecvd, EID_WPA2 );
				
			if( RSNIE.Length != 0 )
				msg_type = type_4way2nd;		// with RSNIE: msg 2 (159 or 161)
			else
				msg_type = type_4way4th;		// msg 4 (135)
		}
		else
		{
			RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("unknow pairwise EAPOL-key: info=0x%X-0x%X\n", eapol_key_recvd->key_info[0], eapol_key_recvd->key_info[1]) );
		}
	}
	else
	{
		// [AnnieNote] Windows zero-config may send 2-way message as 03-01.
		//
		//if( eapol_key_recvd->key_info[0]==0x03 && eapol_key_recvd->key_info[1]==0x11 )	// if group key index is fixed 1, key information is 03-11.
		//	msg_type = type_2way2nd;			// group key msg2 (155)
		//else
		//	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("unknow group EAPOL-key: info=0x%X-0x%X\n", eapol_key_recvd->key_info[0], eapol_key_recvd->key_info[1]) );
		
		msg_type = type_2way2nd;
	}

	// Check state.
	if( KeyMgntStateIsWaitingEAPOLKey(pKeyMgnt) )
	{

		if( 	(pKeyMgnt->PrState==ASMPS_PTKSTART && msg_type==type_4way2nd ) ||
			( pKeyMgnt->PrState==ASMPS_PTKINITNEGOTIATING && msg_type==type_4way2nd ))
		{
			RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("Recvd 4-way message 2\n"));
			pKeyMgnt->TimeoutCtr = 0;

			//  AnnieTODO: if (1)k is pairwise and (2)MICVerified , then enter ASMPS_PTKINITNEGOTIATING state
			//  TODO: MIC Verify
			SNonce = Message_KeyNonce( pGlInfo->EapolKeyMsgRecvd );
			CopyMem( pKeyMgnt->SNonce, SNonce.Octet, KEY_NONCE_LEN );

			
			CalcPTK( pAP_addr, pSTA_addr, pKeyMgnt->ANonce, pKeyMgnt->SNonce,
					 pGlInfo->PMK, PMK_LEN, pKeyMgnt->PTK_update, PTK_LEN );

			if(!CheckEapolMIC(Adapter , pGlInfo->EAPOLMsgRecvd , pKeyMgnt->PTK_update , KEY_MIC_LEN ))
			{
				SendDeauthentication( Adapter, pSTA_addr , mic_failure );
				PlatformStallExecution(100);
				RT_TRACE_F(COMP_AP, DBG_TRACE, ("AsocEntry_RemoveStation\n"));
				
				AsocEntry_RemoveStation( Adapter , pSTA_addr);
				RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("MIC erroe\n"));
				return;
			 }


			Authenticator_StatePTKINITNEGOTIATING(Adapter, pEntry);
		}
		else if( pKeyMgnt->PrState==ASMPS_PTKINITNEGOTIATING && msg_type==type_4way4th )
		{
			RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("Recvd 4-way message 4\n"));
			pKeyMgnt->TimeoutCtr = 0;

			// if (1)k is pairwise and (2)MICVerified , then enter ASMPS_PTKINITDONE state
			if(!CheckEapolMIC(Adapter , pGlInfo->EAPOLMsgRecvd , pKeyMgnt->PTK_update , KEY_MIC_LEN ))
			{
				SendDeauthentication( Adapter, pSTA_addr , mic_failure );
				PlatformStallExecution(100);
				RT_TRACE_F(COMP_AP, DBG_TRACE, ("AsocEntry_RemoveStation case 2\n"));
				
				AsocEntry_RemoveStation( Adapter , pSTA_addr);
				RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("MIC erroe\n"));
				return;
			 }

			PlatformMoveMemory(&pEntry->perSTAKeyInfo.RxIV, &((PEAPOL_KEY_STRUCT)eapol_key_recvd)->key_rsc[0], 6);
			pEntry->perSTAKeyInfo.RxIV &= UINT64_C(0x0000ffffffffffff);
			//RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("pEntry->perSTAKeyInfo.RxIV = 0x%16"i64fmt"x", pEntry->perSTAKeyInfo.RxIV));

			Authenticator_StatePTKINITDONE(Adapter, pEntry);		
		}
		else if(  pKeyMgnt->GrState == ASMGS_REKEYNEGOTIATING && msg_type==type_2way2nd )
		{
			RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("Recvd 2-way message 2\n"));
			pKeyMgnt->TimeoutCtr = 0;

			//  if (1)k is group and (2)MICVerified , then enter ASMGS_REKEYESTABLISHED state
			// 2012/01/17 CCW If 4-way check is ok, we need not to check 2-way again.
			/*
			if(!CheckEapolMIC(Adapter , pGlInfo->EAPOLMsgRecvd , pKeyMgnt->PTK_update , KEY_MIC_LEN ))
			{
				SendDeauthentication( Adapter, pSTA_addr , mic_failure );
				PlatformStallExecution(100);
				AsocEntry_RemoveStation( Adapter , pSTA_addr);
				RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("MIC erroe\n"));
				return;
			}
			*/
			Authenticator_StateREKEYESTABLISHED(Adapter, pEntry);
		}
		else
		{
			RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("Authenticator_OnEAPOLKeyRecvd(): Unexpected case: PrState=%d, GrState=%d, msg_type=%d\n",
											pKeyMgnt->PrState, pKeyMgnt->GrState, msg_type ) );
		}

	}
	else
	{
		RT_TRACE(COMP_AUTHENTICATOR, DBG_LOUD, ("Authenticator_OnEAPOLKeyRecvd(): Unexpected State!!\n"));
		RT_TRACE(COMP_AUTHENTICATOR, DBG_LOUD, ("--- TimeoutCounter:%d, PairwiseKeyState:%d, GroupKeyState:%d ---\n", pKeyMgnt->TimeoutCtr, pKeyMgnt->PrState, pKeyMgnt->GrState));
	}

	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("<=== Authenticator_OnEAPOLKeyRecvd()\n") );

}
示例#9
0
VOID
WPS_AppendElement(
	IN	PADAPTER			Adapter,
	IN	POCTET_STRING		posFrame,
	IN	BOOLEAN				bCheckFrag,
	IN	WPS_INFO_OPCODE	frameType
	)
{
	PSIMPLE_CONFIG_T	pSimpleConfig = GET_SIMPLE_CONFIG(&(GetDefaultAdapter(Adapter)->MgntInfo));
	OCTET_STRING		SimpleConfigInfo;	

	FunctionIn(COMP_WPS);
	#if 0
	if(bCheckFrag)
	{
		// WPS 2.0 Support IE Fragment	for Testbed function
		if(pSimpleConfig->bFragmentIE && pSimpleConfig->IELen <= MAX_SIMPLE_CONFIG_IE_LEN)
		{
			u1Byte tempBuf[MAX_SIMPLE_CONFIG_IE_LEN];
			pu1Byte currPtr;
			pu1Byte currPtrAftOui;
			RT_TRACE(COMP_WPS,DBG_LOUD,("ConstructProbeRequest: in Fragment IE\n"));
			PlatformZeroMemory(tempBuf, MAX_SIMPLE_CONFIG_IE_LEN);
			//Copy the OUI
			currPtr = pSimpleConfig->IEBuf;
			//Tesplan to copy the first octet in the first fragment
			PlatformMoveMemory(tempBuf, currPtr, SIZE_OUI + SIZE_OUI_TYPE);
			currPtr += (SIZE_OUI + SIZE_OUI_TYPE); 
			currPtrAftOui = &tempBuf[SIZE_OUI + SIZE_OUI_TYPE];

			// the first octet
			PlatformMoveMemory(currPtrAftOui, currPtr, 1);
			currPtr += 1;
			FillOctetString(SimpleConfigInfo,tempBuf,(SIZE_OUI + SIZE_OUI_TYPE +1));
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);
						
			// the rest octet			
			PlatformZeroMemory(currPtrAftOui, 1);
			PlatformMoveMemory(currPtrAftOui, currPtr, (pSimpleConfig->IELen-(SIZE_OUI + SIZE_OUI_TYPE)-1) );

			FillOctetString(SimpleConfigInfo,tempBuf,(pSimpleConfig->IELen-1));
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);

		}
		else if(pSimpleConfig->IELen > MAX_SIMPLE_CONFIG_IE_LEN)
		{
			u1Byte tempBuf[MAX_SIMPLE_CONFIG_IE_LEN];
			pu1Byte currPtr;
			pu1Byte currPtrAftOui;
			PlatformZeroMemory(tempBuf, MAX_SIMPLE_CONFIG_IE_LEN);
			//Copy the OUI
			currPtr = pSimpleConfig->IEBuf;
			//Tesplan to copy the first octet in the first fragment
			PlatformMoveMemory(tempBuf, currPtr, SIZE_OUI + SIZE_OUI_TYPE);
			currPtr += (SIZE_OUI + SIZE_OUI_TYPE); 
			currPtrAftOui = &tempBuf[SIZE_OUI + SIZE_OUI_TYPE];

			// the first fragment
			PlatformMoveMemory(currPtrAftOui, currPtr, (MAX_SIMPLE_CONFIG_IE_LEN - (SIZE_OUI + SIZE_OUI_TYPE)));
			currPtr += (MAX_SIMPLE_CONFIG_IE_LEN - (SIZE_OUI + SIZE_OUI_TYPE));
			FillOctetString(SimpleConfigInfo,tempBuf,(MAX_SIMPLE_CONFIG_IE_LEN - (SIZE_OUI + SIZE_OUI_TYPE)));
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);
						
			// the rest octet			
			PlatformZeroMemory(currPtrAftOui, (MAX_SIMPLE_CONFIG_IE_LEN - (SIZE_OUI + SIZE_OUI_TYPE)));
			PlatformMoveMemory(currPtrAftOui, currPtr, (pSimpleConfig->IELen-MAX_SIMPLE_CONFIG_IE_LEN) );

			FillOctetString(SimpleConfigInfo,tempBuf,(pSimpleConfig->IELen-MAX_SIMPLE_CONFIG_IE_LEN));
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);
			
		}
		else
		{
			FillOctetString(SimpleConfigInfo, pSimpleConfig->IEBuf, pSimpleConfig->IELen);
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);
		}
	}
	else
	#endif
	{
		if(((pSimpleConfig->WpsIeVersion < SUPPORT_WPS_INFO_VERSION) || (wps_IsWPSIEReady(Adapter) == FALSE)) && pSimpleConfig->IELen > 0)
		{
			FillOctetString(SimpleConfigInfo, pSimpleConfig->IEBuf, pSimpleConfig->IELen);
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);
		}
		else if(pSimpleConfig->WpsIeVersion == SUPPORT_WPS_INFO_VERSION)
		{
			switch(frameType)
			{
				case WPS_INFO_ASOCREQ_IE:
				{
					FillOctetString(SimpleConfigInfo, pSimpleConfig->ieAsocReqBuf, pSimpleConfig->ieAsocReqLen);
					if(pSimpleConfig->ieAsocReqLen > 0)
						PacketAppendData(posFrame, SimpleConfigInfo);
				}
				break;

				case WPS_INFO_ASOCRSP_IE:
				{
					FillOctetString(SimpleConfigInfo, pSimpleConfig->ieAsocRspBuf, pSimpleConfig->ieAsocRspLen);
					if(pSimpleConfig->ieAsocRspLen > 0)
						PacketAppendData(posFrame, SimpleConfigInfo);
				}
				break;
				
				case WPS_INFO_PROBEREQ_IE:
				{
					FillOctetString(SimpleConfigInfo, pSimpleConfig->ieProbeReqBuf, pSimpleConfig->ieProbeReqLen);
					if(pSimpleConfig->ieProbeReqLen > 0)
						PacketAppendData(posFrame, SimpleConfigInfo);
				}
				break;

				case WPS_INFO_PROBERSP_IE:
				{
					FillOctetString(SimpleConfigInfo, pSimpleConfig->ieProbeRspBuf, pSimpleConfig->ieProbeRspLen);
					if(pSimpleConfig->ieProbeRspLen > 0)
						PacketAppendData(posFrame, SimpleConfigInfo);
				}
				break;

				default: //for MacOS warning.
					break;

			}
		}
	}
}