📄 dpc.c
字号:
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 + -