📄 dpc.c
字号:
//[31:16]RcvByteCount ( not include 4-byte Status ) dwWbkStatus = *( (PDWORD)(skb->data) ); FrameSize = (UINT)(dwWbkStatus >> 16); FrameSize += 4; if (BytesToIndicate != FrameSize) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 1 \n"); return FALSE; } if ((BytesToIndicate > 2372)||(BytesToIndicate <= 40)) { // Frame Size error drop this packet. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 2 \n"); return FALSE; } pbyDAddress = (PBYTE)(skb->data); pbyRxSts = pbyDAddress+4; pbyRxRate = pbyDAddress+5; //real Frame Size = USBFrameSize -4WbkStatus - 4RxStatus - 8TSF - 4RSR - 4SQ3 - ?Padding //if SQ3 the range is 24~27, if no SQ3 the range is 20~23 //real Frame size in PLCPLength field. pwPLCP_Length = (PWORD) (pbyDAddress + 6); //Fix hardware bug => PLCP_Length error if ( ((BytesToIndicate - (*pwPLCP_Length)) > 27) || ((BytesToIndicate - (*pwPLCP_Length)) < 24) || (BytesToIndicate < (*pwPLCP_Length)) ) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong PLCP Length %x\n", (int) *pwPLCP_Length); ASSERT(0); return FALSE; } for ( ii=RATE_1M;ii<MAX_RATE;ii++) { if ( *pbyRxRate == abyVaildRate[ii] ) { break; } } if ( ii==MAX_RATE ) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong RxRate %x\n",(int) *pbyRxRate); return FALSE; } wPLCPwithPadding = ( (*pwPLCP_Length / 4) + ( (*pwPLCP_Length % 4) ? 1:0 ) ) *4; pqwTSFTime = (PQWORD) (pbyDAddress + 8 + wPLCPwithPadding);#ifdef Calcu_LinkQual if(pDevice->byBBType == BB_TYPE_11G) { pby3SQ = pbyDAddress + 8 + wPLCPwithPadding + 12; pbySQ = pby3SQ; } else { pbySQ = pbyDAddress + 8 + wPLCPwithPadding + 8; pby3SQ = pbySQ; }#else pbySQ = pbyDAddress + 8 + wPLCPwithPadding + 8;#endif pbyNewRsr = pbyDAddress + 8 + wPLCPwithPadding + 9; pbyRSSI = pbyDAddress + 8 + wPLCPwithPadding + 10; pbyRsr = pbyDAddress + 8 + wPLCPwithPadding + 11; FrameSize = *pwPLCP_Length; pbyFrame = pbyDAddress + 8; // update receive statistic counter STAvUpdateRDStatCounter(&pDevice->scStatistic, *pbyRsr, *pbyNewRsr, *pbyRxSts, *pbyRxRate, pbyFrame, FrameSize ); pMACHeader = (PS802_11Header) pbyFrame; if (!IS_MULTICAST_ADDRESS(pMACHeader->abyAddr1) && !IS_BROADCAST_ADDRESS(pMACHeader->abyAddr1)) { if ( WCTLbIsDuplicate(&(pDevice->sDupRxCache), (PS802_11Header) pbyFrame) ) { pDevice->s802_11Counter.FrameDuplicateCount++; return FALSE; } if ( !IS_ETH_ADDRESS_EQUAL (pDevice->abyCurrentNetAddr, pMACHeader->abyAddr1) ) { return FALSE; } } // Use for TKIP MIC s_vGetDASA(pbyFrame, &cbHeaderSize, &pDevice->sRxEthHeader); if (IS_ETH_ADDRESS_EQUAL((PBYTE)&(pDevice->sRxEthHeader.abySrcAddr[0]), pDevice->abyCurrentNetAddr)) return FALSE; if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) { p802_11Header = (PS802_11Header) (pbyFrame); // get SA NodeIndex if (BSSbIsSTAInNodeDB(pDevice, (PBYTE)(p802_11Header->abyAddr2), &iSANodeIndex)) { pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies; pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0; } } } if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex) == TRUE) { return FALSE; } } if (IS_FC_WEP(pbyFrame)) { BOOL bRxDecryOK = FALSE; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"rx WEP pkt\n"); bIsWEP = TRUE; if ((pDevice->bEnableHostWEP) && (iSANodeIndex >= 0)) { pKey = &STempKey; pKey->byCipherSuite = pMgmt->sNodeDBTable[iSANodeIndex].byCipherSuite; pKey->dwKeyIndex = pMgmt->sNodeDBTable[iSANodeIndex].dwKeyIndex; pKey->uKeyLength = pMgmt->sNodeDBTable[iSANodeIndex].uWepKeyLength; pKey->dwTSC47_16 = pMgmt->sNodeDBTable[iSANodeIndex].dwTSC47_16; pKey->wTSC15_0 = pMgmt->sNodeDBTable[iSANodeIndex].wTSC15_0; memcpy(pKey->abyKey, &pMgmt->sNodeDBTable[iSANodeIndex].abyWepKey[0], pKey->uKeyLength ); bRxDecryOK = s_bHostWepRxEncryption(pDevice, pbyFrame, FrameSize, pbyRsr, pMgmt->sNodeDBTable[iSANodeIndex].bOnFly, pKey, pbyNewRsr, &bExtIV, &wRxTSC15_0, &dwRxTSC47_16); } else { bRxDecryOK = s_bHandleRxEncryption(pDevice, pbyFrame, FrameSize, pbyRsr, pbyNewRsr, &pKey, &bExtIV, &wRxTSC15_0, &dwRxTSC47_16); } if (bRxDecryOK) { if ((*pbyNewRsr & NEWRSR_DECRYPTOK) == 0) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV Fail\n"); if ( (pMgmt->eAuthenMode == WMAC_AUTH_WPA) || (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) || (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) { pDevice->s802_11Counter.TKIPICVErrors++; } else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) { pDevice->s802_11Counter.CCMPDecryptErrors++; } else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_WEP)) {// pDevice->s802_11Counter.WEPICVErrorCount.QuadPart++; } } return FALSE; } } else { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WEP Func Fail\n"); return FALSE; } if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) FrameSize -= 8; // Message Integrity Code else FrameSize -= 4; // 4 is ICV } // // RX OK // //remove the CRC length FrameSize -= U_CRC_LEN; if ((BITbIsAllBitsOff(*pbyRsr, (RSR_ADDRBROAD | RSR_ADDRMULTI))) && // unicast address (IS_FRAGMENT_PKT((pbyFrame))) ) { // defragment bDeFragRx = WCTLbHandleFragment(pDevice, (PS802_11Header) (pbyFrame), FrameSize, bIsWEP, bExtIV); pDevice->s802_11Counter.ReceivedFragmentCount++; if (bDeFragRx) { // defrag complete // TODO skb, pbyFrame skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb; FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength; pbyFrame = skb->data + 8; } else { return FALSE; } } // // Management & Control frame Handle // if ((IS_TYPE_DATA((pbyFrame))) == FALSE) { // Handle Control & Manage Frame if (IS_TYPE_MGMT((pbyFrame))) { PBYTE pbyData1; PBYTE pbyData2; pRxPacket = &(pRCB->sMngPacket); pRxPacket->p80211Header = (PUWLAN_80211HDR)(pbyFrame); pRxPacket->cbMPDULen = FrameSize; pRxPacket->uRSSI = *pbyRSSI; pRxPacket->bySQ = *pbySQ; HIDWORD(pRxPacket->qwLocalTSF) = cpu_to_le32(HIDWORD(*pqwTSFTime)); LODWORD(pRxPacket->qwLocalTSF) = cpu_to_le32(LODWORD(*pqwTSFTime)); if (bIsWEP) { // strip IV pbyData1 = WLAN_HDR_A3_DATA_PTR(pbyFrame); pbyData2 = WLAN_HDR_A3_DATA_PTR(pbyFrame) + 4; for (ii = 0; ii < (FrameSize - 4); ii++) { *pbyData1 = *pbyData2; pbyData1++; pbyData2++; } } pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate); if ( *pbyRxSts == 0 ) { //Discard beacon packet which channel is 0 if ( (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_BEACON) || (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_PROBERESP) ) { return TRUE; } } pRxPacket->byRxChannel = (*pbyRxSts) >> 2; // hostap Deamon handle 802.11 management if (pDevice->bEnableHostapd) { skb->dev = pDevice->apdev; //skb->data += 4; //skb->tail += 4; skb->data += 8; skb->tail += 8; skb_put(skb, FrameSize);//2008-4-3 modify by Chester for wpa #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) skb->mac_header = skb->data;#else skb->mac.raw = skb->data;#endif skb->pkt_type = PACKET_OTHERHOST; skb->protocol = htons(ETH_P_802_2); memset(skb->cb, 0, sizeof(skb->cb)); netif_rx(skb); return TRUE; } // // Insert the RCB in the Recv Mng list // EnqueueRCB(pDevice->FirstRecvMngList, pDevice->LastRecvMngList, pRCBIndicate); pDevice->NumRecvMngList++; if ( bDeFragRx == FALSE) { pRCB->Ref++; } if (pDevice->bIsRxMngWorkItemQueued == FALSE) { pDevice->bIsRxMngWorkItemQueued = TRUE; tasklet_schedule(&pDevice->RxMngWorkItem); } } else { // Control Frame }; return FALSE; } else { if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { //In AP mode, hw only check addr1(BSSID or RA) if equal to local MAC. if (BITbIsBitOff(*pbyRsr, RSR_BSSIDOK)) { if (bDeFragRx) { if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n", pDevice->dev->name); } } return FALSE; } } else { // discard DATA packet while not associate || BSSID error if ((pDevice->bLinkPass == FALSE) || BITbIsBitOff(*pbyRsr, RSR_BSSIDOK)) { if (bDeFragRx) { if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n", pDevice->dev->name); } } return FALSE; } } } // Data frame Handle if (pDevice->bEnablePSMode) { if (IS_FC_MOREDATA((pbyFrame))) { if (BITbIsBitOn(*pbyRsr, RSR_ADDROK)) { //PSbSendPSPOLL((PSDevice)pDevice); } } else { if (pMgmt->bInTIMWake == TRUE) { pMgmt->bInTIMWake = FALSE; } } }; // Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps if (pDevice->bDiversityEnable && (FrameSize>50) && (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) && (pDevice->bLinkPass == TRUE)) { BBvAntennaDiversity(pDevice, s_byGetRateIdx(*pbyRxRate), 0); } // ++++++++ For BaseBand Algorithm +++++++++++++++ pDevice->uCurrRSSI = *pbyRSSI; pDevice->byCurrSQ = *pbySQ; // todo/* if ((*pbyRSSI != 0) && (pMgmt->pCurrBSS!=NULL)) { RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm); // Moniter if RSSI is too strong. pMgmt->pCurrBSS->byRSSIStatCnt++; pMgmt->pCurrBSS->byRSSIStatCnt %= RSSI_STAT_COUNT; pMgmt->pCurrBSS->ldBmAverage[pMgmt->pCurrBSS->byRSSIStatCnt] = ldBm; for(ii=0;ii<RSSI_STAT_COUNT;ii++) { if (pMgmt->pCurrBSS->ldBmAverage[ii] != 0) { pMgmt->pCurrBSS->ldBmMAX = max(pMgmt->pCurrBSS->ldBmAverage[ii], ldBm); } } }*/ // ----------------------------------------------- if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnable8021x == TRUE)){ BYTE abyMacHdr[24]; // Only 802.1x packet incoming allowed if (bIsWEP) cbIVOffset = 8; else cbIVOffset = 0; wEtherType = (skb->data[cbIVOffset + 8 + 24 + 6] << 8) | skb->data[cbIVOffset + 8 + 24 + 6 + 1]; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wEtherType = %04x \n", wEtherType); if (wEtherType == ETH_P_PAE) { skb->dev = pDevice->apdev; if (bIsWEP == TRUE) { // strip IV header(8) memcpy(&abyMacHdr[0], (skb->data + 8), 24); memcpy((skb->data + 8 + cbIVOffset), &abyMacHdr[0], 24); } skb->data += (cbIVOffset + 8); skb->tail += (cbIVOffset + 8); skb_put(skb, FrameSize);//2008-4-3 modify by Chester for wpa #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) skb->mac_header = skb->data;#else skb->mac.raw = skb->data;#endif skb->pkt_type = PACKET_OTHERHOST; skb->protocol = htons(ETH_P_802_2); memset(skb->cb, 0, sizeof(skb->cb)); netif_rx(skb); return TRUE; } // check if 802.1x authorized if (!(pMgmt->sNodeDBTable[iSANodeIndex].dwFlags & WLAN_STA_AUTHORIZED)) return FALSE; } if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -