📄 rtmp_data.c
字号:
pRxD->DataByteCnt -= 16; //8 bytes MIC, 8 bytes IV/EIV (CCMP Header)
}
else
{
printk("ERROR : RTMPSoftDecryptAES Failed\n");
break; // give up this frame
}
}
else
{
break; // give up this frame
}
}
pDA = pHeader->Addr1;
pSA = pHeader->Addr3;
pData += LENGTH_802_11;
DataSize = (USHORT)pRxD->DataByteCnt - LENGTH_802_11;
// remove the 2 extra QOS CNTL bytes
if(pHeader->FC.SubType & 0x08)
{
bQoS = TRUE;
pData += 2;
DataSize -= 2;
Offset += 2;
}
// remove the 2 extra AGGREGATION bytes
Msdu2Size = 0;
if(pHeader->FC.Order)
{
Msdu2Size = *pData + (*(pData+1) << 8);
if((Msdu2Size <= 1536) && (Msdu2Size < DataSize))
{
pData += 2;
DataSize -= 2;
} else
Msdu2Size = 0;
}
CONVERT_TO_802_3(Header802_3, pDA, pSA, pData, DataSize, pRemovedLLCSNAP);
REPORT_ETHERNET_FRAME_TO_LLC_WITH_NON_COPY(pAd, Header802_3, pData, DataSize, net_dev);
pRxD->BufPhyAddr = pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocPa;
break;//end process this packet
#endif
}//else
} // end - Broadcast/Multicast frame
// DUPLICATE FRAME CHECK:
// Check retry bit. If this bit is on, search the cache with SA & sequence
// as index, if matched, discard this frame, otherwise, update cache
// This check only apply to unicast data & management frames
if ((pRxD->U2M) &&
(pHeader->FC.Retry) &&
(RTMPSearchTupleCache(pAd, pHeader) == TRUE))
{
DBGPRINT(RT_DEBUG_INFO,"RxDone- drop DUPLICATE frame(len=%d)\n",pRxD->DataByteCnt);
pAd->WlanCounters.FrameDuplicateCount++;
break; // give up this frame
}
else // Update Tuple Cache
RTMPUpdateTupleCache(pAd, pHeader);
pAd->Counters8023.GoodReceives++;
#ifdef RALINK_ATE
if(pAd->ate.Mode != ATE_APSTART)
{
break;
}
#endif
//
// CASE I. receive a DATA frame
//
if (pHeader->FC.Type == BTYPE_DATA)
{
#ifndef APCLI_SUPPORT
if (pHeader->FC.ToDs == 0)
break; // give up this frame
#endif
pAd->RalinkCounters.OneSecRxOkCnt++;
pEntry = PACInquiry(pAd, pHeader->Addr2, &Privacy, &WpaState);
if(pEntry)
{
apidx = pEntry->ApIdx;
net_dev = pAd->PortCfg.MBSSID[apidx].MSSIDDev;
DBGPRINT(RT_DEBUG_INFO, "Rcv packet to IF(ra%d)\n", apidx);
}
if ((pEntry) && (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_APSD_CAPABLE)))
{
UCHAR OldUP;
OldUP = (*(pData+LENGTH_802_11) & 0x07);
if (pHeader->FC.PwrMgmt && (OldPwrMgmt == PWR_SAVE))
{
RTMPHandleUAPSDTriggerFrame(pAd, pEntry, OldUP);
}
}
// Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame
if (pHeader->FC.SubType & 0x04) // bit 2 : no DATA
break; // give up this frame
// check if Class2 or 3 error
if ((pHeader->FC.FrDs == 0) && (CheckClass2Class3Error(pAd, pHeader, pEntry)))
break; // give up this frame
if(pAd->PortCfg.MBSSID[apidx].BANClass3Data == TRUE)
break; // give up this frame
if ((pEntry) && (pAd->PortCfg.bEnableHSCounter))
{
pEntry->HSCounter.TotalRxByteCount += pRxD->DataByteCnt;
pEntry->HSCounter.LastDataPacketTime = jiffies;
}
// pData : Pointer skip the first 24 bytes, 802.11 HEADER
if ((pHeader->FC.FrDs == 1) && (pHeader->FC.ToDs == 1))
{
pData += LENGTH_802_11_WITH_ADDR4;
DataSize = (USHORT)pRxD->DataByteCnt - LENGTH_802_11_WITH_ADDR4;
}
else
{
pData += LENGTH_802_11;
DataSize = (USHORT)pRxD->DataByteCnt - LENGTH_802_11;
}
bQoS = FALSE;
// remove the 2 extra QOS CNTL bytes
if (pHeader->FC.SubType & 0x08)
{
bQoS = TRUE;
pData += 2;
DataSize -= 2;
Offset += 2;
}
// remove the 2 extra AGGREGATION bytes
Msdu2Size = 0;
if (pHeader->FC.Order)
{
Msdu2Size = *pData + (*(pData+1) << 8);
if ((Msdu2Size <= 1536) && (Msdu2Size < DataSize))
{
pData += 2;
DataSize -= 2;
}
else
Msdu2Size = 0;
}
#ifdef APCLI_SUPPORT
// handle APCLI
bApCliPacket = FALSE;
if ((pHeader->FC.FrDs == 1) && (pHeader->FC.ToDs == 0))
{
for (i = 0; i < MAX_APCLI_ENTRY; i++)
{
//BSSID match the ApCliBssid ?(from a valid AP)
if ((pAd->ApCliTab.ApCliEntry[i].Valid == TRUE)
&& (pAd->ApCliTab.ApCliEntry[i].Enable == TRUE)
&& (MAC_ADDR_EQUAL(&pAd->ApCliTab.ApCliEntry[i].ApCliBssid, &pHeader->Addr2)))
{
net_dev = pAd->ApCliTab.ApCliEntry[i].dev;
bApCliPacket = TRUE;
ApCliIdx = i;
DBGPRINT(RT_DEBUG_INFO, "APCLI packet from (apcli%d)!!!\n", ApCliIdx);
break;
}
}
if (i == MAX_APCLI_ENTRY)
{
DBGPRINT(RT_DEBUG_INFO, "APCLI packet, but not our APCLI group, give it up!!!\n");
break; // give up this frame
}
}
#endif
//
// handle WDS
//
bWdsPacket = FALSE;
#ifdef WDS_SUPPORT
if ((pHeader->FC.FrDs == 1) && (pHeader->FC.ToDs == 1))
{
// Lazy/Bridge/Repeater mode will auto learning, match with FrDs=1 and ToDs=1
if (pAd->WdsTab.Mode >= WDS_LAZY_MODE)
{
// Lookup entry, if exist, then update the Rcv beacon time and return
for (i = 0; i < MAX_WDS_ENTRY; i++)
{
if ((pAd->WdsTab.WdsEntry[i].Valid == TRUE) && (MAC_ADDR_EQUAL(&pAd->WdsTab.WdsEntry[i].WdsAddr, &pHeader->Addr2)))
{
// Update wds received beacon time for age out usage
pAd->WdsTab.WdsEntry[i].WdsRcvBeaconTime = jiffies;
break;
}
}
// Look for empty entry, and add to our WdsTable
if (i == MAX_WDS_ENTRY)
{
for (i = 0; i < MAX_WDS_ENTRY; i++)
{
if (pAd->WdsTab.WdsEntry[i].Valid == FALSE)
{
COPY_MAC_ADDR(&pAd->WdsTab.WdsEntry[i].WdsAddr, &pHeader->Addr2);
pAd->WdsTab.WdsEntry[i].WdsRcvBeaconTime = jiffies;
pAd->WdsTab.WdsEntry[i].CurrTxRate = RATE_11;
if(pAd->PortCfg.PhyMode == PHY_11B)
pAd->WdsTab.WdsEntry[i].MaxSupportedRate = RATE_11;
else
pAd->WdsTab.WdsEntry[i].MaxSupportedRate = RATE_54;
pAd->WdsTab.WdsEntry[i].Valid = TRUE;
DBGPRINT(RT_DEBUG_TRACE, "Lazy WDS mode, AP(%02x:%02x:%02x:%02x:%02x:%02x) has 4-addr packet and add to entry(%d) in our WDSTable \n",
pHeader->Addr2[0], pHeader->Addr2[1], pHeader->Addr2[2],
pHeader->Addr2[3], pHeader->Addr2[4], pHeader->Addr2[5], i);
break;
}
}
if (i == MAX_WDS_ENTRY)
{
DBGPRINT(RT_DEBUG_WARN, "WDS Table is full!\n");
}
}
}
if (pAd->WdsTab.Mode != WDS_DISABLE_MODE)
{
for (i = 0; i < MAX_WDS_ENTRY; i++)
{
if ((pAd->WdsTab.WdsEntry[i].Valid == TRUE) && (MAC_ADDR_EQUAL(&pAd->WdsTab.WdsEntry[i].WdsAddr, &pHeader->Addr2)))
{
net_dev = pAd->WdsTab.WdsEntry[i].dev;
bWdsPacket = TRUE;
DBGPRINT(RT_DEBUG_INFO, "WDS packet from (%d)!!!\n", i);
break;
}
}
if (i == MAX_WDS_ENTRY)
{
DBGPRINT(RT_DEBUG_WARN, "WDS packet, but not our WDS group, give it up!!!\n");
break;
}
}
}
#else
if ((pHeader->FC.FrDs == 1) && (pHeader->FC.ToDs == 1))
{
break;
}
#endif /* !WDS_SUPPORT */
#ifdef APCLI_SUPPORT
if (bApCliPacket)
{
Privacy = Ndis802_11PrivFilterAcceptAll; // no 802.1x PAC for APCLI frame
WpaState = pAd->ApCliTab.ApCliEntry[ApCliIdx].WpaState;
pDA = pHeader->Addr1;
pSA = pHeader->Addr3;
}
else
#endif
// WDS packet's DA & SA is not the same
if (bWdsPacket)
{
Privacy = Ndis802_11PrivFilterAcceptAll; // no 802.1x PAC for WDS frame
pDA = pHeader->Addr3;
pSA = (PUCHAR)pHeader + sizeof(HEADER_802_11);
}
else
{
pDA = pHeader->Addr3;
pSA = pHeader->Addr2;
}
// Determine the destination of 802.1x frame (WPA state machine or upper layer TCPIP)
// drop all non-802.1x DATA frame before this client's Port-Access-Control is secured
if (Privacy != Ndis802_11PrivFilterAcceptAll)
{
//needs to handle fragmented EAP packets specially
if (pHeader->Frag == 0) // Frag. Number is 0 : First frag or only one pkt
{
// One & The only fragment
if (pHeader->FC.MoreFrag == FALSE)
{
if (!RTMPCheckWPAframe(pAd, (PUCHAR)pHeader, pRxD->DataByteCnt, Offset))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -