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

📄 dpc.c

📁 VIA VT6655 x86下的Linux Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
    BOOL            bExtIV = FALSE;
    PBYTE           pbyRxSts;
    PBYTE           pbyRxRate;
    PBYTE           pbySQ;    
    UINT            cbHeaderSize;    
    PSKeyItem       pKey = NULL;
    WORD            wRxTSC15_0 = 0;
    DWORD           dwRxTSC47_16 = 0;        
    SKeyItem        STempKey;  
    // 802.11h RPI
    DWORD           dwDuration = 0;
    LONG            ldBm = 0;
    LONG            ldBmThreshold = 0;      
    

//    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- device_receive_frame---\n");
#ifdef PRIVATE_OBJ
    skb = &(pRDInfo->ref_skb);
#else    
    skb = pRDInfo->skb;
#endif    
    pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma,
                     pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
                     
    pwFrameSize = (PWORD)(skb->data + 2);
    FrameSize = cpu_to_le16(pCurrRD->m_rd1RD1.wReqCount) - cpu_to_le16(pCurrRD->m_rd0RD0.wResCount);

    // Max: 2312Payload + 30HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR
    // Min (ACK): 10HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR
    if ((FrameSize > 2364)||(FrameSize <= 32)) {
        // Frame Size error drop this packet.
        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 1 \n");
        return FALSE;
    }    
        
    pbyRxSts = (PBYTE) (skb->data);
    pbyRxRate = (PBYTE) (skb->data + 1);
    pbyRsr = (PBYTE) (skb->data + FrameSize - 1);
    pbyRSSI = (PBYTE) (skb->data + FrameSize - 2);
    pbyNewRsr = (PBYTE) (skb->data + FrameSize - 3);
    pbySQ = (PBYTE) (skb->data + FrameSize - 4);
    pqwTSFTime = (PQWORD) (skb->data + FrameSize - 12);
    pbyFrame = (PBYTE)(skb->data + 4);

    // get packet size
    FrameSize = cpu_to_le16(*pwFrameSize);

    if ((FrameSize > 2346)|(FrameSize < 14)) { // Max: 2312Payload + 30HD +4CRC
                                               // Min: 14 bytes ACK             
        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 2 \n");
        return FALSE;                                                  
    }
    // update receive statistic counter
    STAvUpdateRDStatCounter(&pDevice->scStatistic,
                            *pbyRsr,
                            *pbyNewRsr,
                            *pbyRxRate,
                            pbyFrame,
                            FrameSize);    
                            
    if (pDevice->bMeasureInProgress == TRUE) {
        if ((*pbyRsr & RSR_CRCOK) != 0) {
            pDevice->byBasicMap |= 0x01;
        }
        dwDuration = (FrameSize << 4);
        dwDuration /= acbyRxRate[*pbyRxRate%MAX_RATE];
        if (*pbyRxRate <= RATE_11M) {
            if (BITbIsBitOn(*pbyRxSts, 0x01)) {
                // long preamble
                dwDuration += 192;
            } else {
                // short preamble
                dwDuration += 96;
            }
        } else {
            dwDuration += 16;
        }
        RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm);
        ldBmThreshold = -57;
        for (ii = 7; ii > 0;) {
            if (ldBm > ldBmThreshold) {
                break;
            }
            ldBmThreshold -= 5;
            ii--;
        }
        pDevice->dwRPIs[ii] += dwDuration;
        return FALSE;
    }        
                                            
    if (!IS_MULTICAST_ADDRESS(pbyFrame) && !IS_BROADCAST_ADDRESS(pbyFrame)) {
        if (WCTLbIsDuplicate(&(pDevice->sDupRxCache), (PS802_11Header) (skb->data + 4))) {
            pDevice->s802_11Counter.FrameDuplicateCount++;
            return FALSE;
        }    
    }                                
    

    // Use for TKIP MIC
    s_vGetDASA(skb->data+4, &cbHeaderSize, &pDevice->sRxEthHeader);
    
    // filter packet send from myself    
    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 (BSSDBbIsSTAInNodeDB(pMgmt, (PBYTE)(p802_11Header->abyAddr2), &iSANodeIndex)) {
#ifdef PRIVATE_OBJ
                pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = get_jiffies();
#else                
                pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies;
#endif                
                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;
    
        DEVICE_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) {
                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV Fail\n");
                if ( (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
                    (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
                    (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) ||
                    (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
                    (pDevice->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 {
            DEVICE_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((skb->data+4)))
        ) {
        // defragment
        bDeFragRx = WCTLbHandleFragment(pDevice, (PS802_11Header) (skb->data+4), FrameSize, bIsWEP, bExtIV);
        pDevice->s802_11Counter.ReceivedFragmentCount++;
        if (bDeFragRx) {
            // defrag complete
#ifdef PRIVATE_OBJ
            skb = &(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].ref_skb);
#else            
            skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb;
#endif                        
            FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength;

        }
        else {
            return FALSE;
        }
    } 
    

// Management & Control frame Handle    
    if ((IS_TYPE_DATA((skb->data+4))) == FALSE) {
        // Handle Control & Manage Frame
        
        if (IS_TYPE_MGMT((skb->data+4))) {
            PBYTE pbyData1;
            PBYTE pbyData2;            
            
            pRxPacket->p80211Header = (PUWLAN_80211HDR)(skb->data+4);
            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(skb->data+4);
                pbyData2 = WLAN_HDR_A3_DATA_PTR(skb->data+4) + 4;
                for (ii = 0; ii < (FrameSize - 4); ii++) {
                    *pbyData1 = *pbyData2;
                     pbyData1++;
                     pbyData2++;
                }     
            }
            pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate);
            pRxPacket->byRxChannel = (*pbyRxSts) >> 2;
            vMgrRxManagePacket((HANDLE)pDevice, pDevice->pMgmt, pRxPacket);
            // hostap Deamon handle 802.11 management
            if (pDevice->bEnableHostapd) {
	            skb->dev = pDevice->apdev;
#ifdef PRIVATE_OBJ
                ref_skb_add_offset(skb->skb, 4);
                ref_skb_set_dev(pDevice->apdev, skb->skb);
                skb_put(skb->skb, FrameSize);
	            skb->mac.raw = skb->data;
	            *(skb->pkt_type) = PACKET_OTHERHOST;
    	        *(skb->protocol) = htons(ETH_P_802_2);
	            memset(skb->cb, 0, sizeof(skb->cb));
	            netif_rx(skb->skb);	            
#else
	            skb->data += 4;
	            skb->tail += 4;
                skb_put(skb, FrameSize);
	            skb->mac.raw = skb->data;
	            skb->pkt_type = PACKET_OTHERHOST;
    	        skb->protocol = htons(ETH_P_802_2);
	            memset(skb->cb, 0, sizeof(skb->cb));
	            netif_rx(skb);	            
#endif                            
                return TRUE;
	        }    
        } 
        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])) {
                        DEVICE_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])) {
                        DEVICE_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((skb->data+4))) {
            if (BITbIsBitOn(*pbyRsr, RSR_ADDROK)) { 
                //PSbSendPSPOLL((PSDevice)pDevice);
            }    
        }
        else {
            if (pDevice->pMgmt->bInTIMWake == TRUE) {
                pDevice->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);
    }        


    if (pDevice->byLocalID != REV_ID_VT3253_B1) {
        pDevice->uCurrRSSI = *pbyRSSI;
    }    
    pDevice->byCurrSQ = *pbySQ;

    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 + 4 + 24 + 6] << 8) | 
                    skb->data[cbIVOffset + 4 + 24 + 6 + 1];

	    DEVICE_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 + 4), 24);
                memcpy((skb->data + 4 + cbIVOffset), &abyMacHdr[0], 24);
            }    
#ifdef PRIVATE_OBJ
            ref_skb_add_offset(skb->skb, (cbIVOffset + 4));
            ref_skb_set_dev(pDevice->apdev, skb->skb);
            skb_put(skb->skb, FrameSize);
            skb->mac.raw = skb->data;
            *(skb->pkt_type) = PACKET_OTHERHOST;
	        *(skb->protocol) = htons(ETH_P_802_2);
            memset(skb->cb, 0, sizeof(skb->cb));
            netif_rx(skb->skb);
#else                
            skb->data +=  (cbIVOffset + 4);
            skb->tail +=  (cbIVOffset + 4);
            skb_put(skb, FrameSize);
            skb->mac.raw = skb->data;
            skb->pkt_type = PACKET_OTHERHOST;
            skb->protocol = htons(ETH_P_802_2);
            memset(skb->cb, 0, sizeof(skb->cb));
            netif_rx(skb);
#endif                

⌨️ 快捷键说明

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