/******************************************************************************************************************** *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; }
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") ); }
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; } } } }