📄 rtmp_data.c
字号:
// Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst// In Cisco CCX 2.0 Leap Authentication// WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey// Instead of the SharedKey, SharedKey Length may be Zero.VOID STAFindCipherAlgorithm( IN PRTMP_ADAPTER pAd, IN TX_BLK *pTxBlk){ NDIS_802_11_ENCRYPTION_STATUS Cipher; // To indicate cipher used for this packet UCHAR CipherAlg = CIPHER_NONE; // cipher alogrithm UCHAR KeyIdx = 0xff; PUCHAR pSrcBufVA; PCIPHER_KEY pKey = NULL; pSrcBufVA = GET_OS_PKT_DATAPTR(pTxBlk->pPacket); { // Select Cipher if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))) Cipher = pAd->StaCfg.GroupCipher; // Cipher for Multicast or Broadcast else Cipher = pAd->StaCfg.PairCipher; // Cipher for Unicast if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket)) { ASSERT(pAd->SharedKey[BSS0][0].CipherAlg <= CIPHER_CKIP128); // 4-way handshaking frame must be clear if (!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame)) && (pAd->SharedKey[BSS0][0].CipherAlg) && (pAd->SharedKey[BSS0][0].KeyLen)) { CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg; KeyIdx = 0; } } else if (Cipher == Ndis802_11Encryption1Enabled) { KeyIdx = pAd->StaCfg.DefaultKeyId; } else if ((Cipher == Ndis802_11Encryption2Enabled) || (Cipher == Ndis802_11Encryption3Enabled)) { if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))) // multicast KeyIdx = pAd->StaCfg.DefaultKeyId; else if (pAd->SharedKey[BSS0][0].KeyLen) KeyIdx = 0; else KeyIdx = pAd->StaCfg.DefaultKeyId; } if (KeyIdx == 0xff) CipherAlg = CIPHER_NONE; else if ((Cipher == Ndis802_11EncryptionDisabled) || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0)) CipherAlg = CIPHER_NONE;#ifdef WPA_SUPPLICANT_SUPPORT else if ( pAd->StaCfg.WpaSupplicantUP && (Cipher == Ndis802_11Encryption1Enabled) && (pAd->StaCfg.IEEE8021X == TRUE) && (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) CipherAlg = CIPHER_NONE;#endif // WPA_SUPPLICANT_SUPPORT // else { //Header_802_11.FC.Wep = 1; CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg; pKey = &pAd->SharedKey[BSS0][KeyIdx]; } } pTxBlk->CipherAlg = CipherAlg; pTxBlk->pKey = pKey;}VOID STABuildCommon802_11Header( IN PRTMP_ADAPTER pAd, IN TX_BLK *pTxBlk){ HEADER_802_11 *pHeader_802_11;#ifdef QOS_DLS_SUPPORT BOOLEAN bDLSFrame = FALSE; INT DlsEntryIndex = 0;#endif // QOS_DLS_SUPPORT // // // MAKE A COMMON 802.11 HEADER // // normal wlan header size : 24 octets pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11); pHeader_802_11 = (HEADER_802_11 *) &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]; NdisZeroMemory(pHeader_802_11, sizeof(HEADER_802_11)); pHeader_802_11->FC.FrDs = 0; pHeader_802_11->FC.Type = BTYPE_DATA; pHeader_802_11->FC.SubType = ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA : SUBTYPE_DATA);#ifdef QOS_DLS_SUPPORT if (INFRA_ON(pAd)) { // Check if the frame can be sent through DLS direct link interface // If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability) DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader); if (DlsEntryIndex >= 0) bDLSFrame = TRUE; else bDLSFrame = FALSE; }#endif // QOS_DLS_SUPPORT // if (pTxBlk->pMacEntry) { if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS)) { pHeader_802_11->Sequence = pTxBlk->pMacEntry->NonQosDataSeq; pTxBlk->pMacEntry->NonQosDataSeq = (pTxBlk->pMacEntry->NonQosDataSeq+1) & MAXSEQ; } else { { pHeader_802_11->Sequence = pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority]; pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] = (pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ; } } } else { pHeader_802_11->Sequence = pAd->Sequence; pAd->Sequence = (pAd->Sequence+1) & MAXSEQ; // next sequence } pHeader_802_11->Frag = 0; pHeader_802_11->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData); { if (INFRA_ON(pAd)) {#ifdef QOS_DLS_SUPPORT if (bDLSFrame) { COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader); COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress); COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid); pHeader_802_11->FC.ToDs = 0; } else#endif // QOS_DLS_SUPPORT // { COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid); COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress); COPY_MAC_ADDR(pHeader_802_11->Addr3, pTxBlk->pSrcBufHeader); pHeader_802_11->FC.ToDs = 1; } } else if (ADHOC_ON(pAd)) { COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader); COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress); COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid); pHeader_802_11->FC.ToDs = 0; } } if (pTxBlk->CipherAlg != CIPHER_NONE) pHeader_802_11->FC.Wep = 1; // ----------------------------------------------------------------- // STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later. // ----------------------------------------------------------------- if (pAd->CommonCfg.bAPSDForcePowerSave) pHeader_802_11->FC.PwrMgmt = PWR_SAVE; else pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE); }#ifdef DOT11_N_SUPPORTVOID STABuildCache802_11Header( IN RTMP_ADAPTER *pAd, IN TX_BLK *pTxBlk, IN UCHAR *pHeader){ MAC_TABLE_ENTRY *pMacEntry; PHEADER_802_11 pHeader80211; pHeader80211 = (PHEADER_802_11)pHeader; pMacEntry = pTxBlk->pMacEntry; // // Update the cached 802.11 HEADER // // normal wlan header size : 24 octets pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11); // More Bit pHeader80211->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData); // Sequence pHeader80211->Sequence = pMacEntry->TxSeq[pTxBlk->UserPriority]; pMacEntry->TxSeq[pTxBlk->UserPriority] = (pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ; { // Check if the frame can be sent through DLS direct link interface // If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)#ifdef QOS_DLS_SUPPORT BOOLEAN bDLSFrame = FALSE; INT DlsEntryIndex = 0; DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader); if (DlsEntryIndex >= 0) bDLSFrame = TRUE; else bDLSFrame = FALSE;#endif // QOS_DLS_SUPPORT // // The addr3 of normal packet send from DS is Dest Mac address.#ifdef QOS_DLS_SUPPORT if (bDLSFrame) { COPY_MAC_ADDR(pHeader80211->Addr1, pTxBlk->pSrcBufHeader); COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid); pHeader80211->FC.ToDs = 0; } else#endif // QOS_DLS_SUPPORT // if (ADHOC_ON(pAd)) COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid); else COPY_MAC_ADDR(pHeader80211->Addr3, pTxBlk->pSrcBufHeader); } // ----------------------------------------------------------------- // STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later. // ----------------------------------------------------------------- if (pAd->CommonCfg.bAPSDForcePowerSave) pHeader80211->FC.PwrMgmt = PWR_SAVE; else pHeader80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE); }#endif // DOT11_N_SUPPORT //static inline PUCHAR STA_Build_ARalink_Frame_Header( IN RTMP_ADAPTER *pAd, IN TX_BLK *pTxBlk){ PUCHAR pHeaderBufPtr; HEADER_802_11 *pHeader_802_11; PNDIS_PACKET pNextPacket; UINT32 nextBufLen; PQUEUE_ENTRY pQEntry; STAFindCipherAlgorithm(pAd, pTxBlk); STABuildCommon802_11Header(pAd, pTxBlk); pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]; pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr; // steal "order" bit to mark "aggregation" pHeader_802_11->FC.Order = 1; // skip common header pHeaderBufPtr += pTxBlk->MpduHeaderLen; if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) { // // build QOS Control bytes // *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F); *(pHeaderBufPtr+1) = 0; pHeaderBufPtr +=2; pTxBlk->MpduHeaderLen += 2; } // padding at front of LLC header. LLC header should at 4-bytes aligment. pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr; pHeaderBufPtr = (PUCHAR)ROUND_UP(pHeaderBufPtr, 4); pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen); // For RA Aggregation, // put the 2nd MSDU length(extra 2-byte field) after QOS_CONTROL in little endian format pQEntry = pTxBlk->TxPacketList.Head; pNextPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); nextBufLen = GET_OS_PKT_LEN(pNextPacket); if (RTMP_GET_PACKET_VLAN(pNextPacket)) nextBufLen -= LENGTH_802_1Q; *pHeaderBufPtr = (UCHAR)nextBufLen & 0xff; *(pHeaderBufPtr+1) = (UCHAR)(nextBufLen >> 8); pHeaderBufPtr += 2; pTxBlk->MpduHeaderLen += 2; return pHeaderBufPtr; }#ifdef DOT11_N_SUPPORTstatic inline PUCHAR STA_Build_AMSDU_Frame_Header( IN RTMP_ADAPTER *pAd, IN TX_BLK *pTxBlk){ PUCHAR pHeaderBufPtr;//, pSaveBufPtr; HEADER_802_11 *pHeader_802_11; STAFindCipherAlgorithm(pAd, pTxBlk); STABuildCommon802_11Header(pAd, pTxBlk); pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]; pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr; // skip common header pHeaderBufPtr += pTxBlk->MpduHeaderLen; // // build QOS Control bytes // *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F); // // A-MSDU packet // *pHeaderBufPtr |= 0x80; *(pHeaderBufPtr+1) = 0; pHeaderBufPtr +=2; pTxBlk->MpduHeaderLen += 2; //pSaveBufPtr = pHeaderBufPtr; // // padding at front of LLC header // LLC header should locate at 4-octets aligment // // @@@ MpduHeaderLen excluding padding @@@ // pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr; pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4); pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen); return pHeaderBufPtr;}VOID STA_AMPDU_Frame_Tx( IN PRTMP_ADAPTER pAd, IN TX_BLK *pTxBlk){ HEADER_802_11 *pHeader_802_11; PUCHAR pHeaderBufPtr; USHORT FreeNumber; MAC_TABLE_ENTRY *pMacEntry; BOOLEAN bVLANPkt; PQUEUE_ENTRY pQEntry; ASSERT(pTxBlk); while(pTxBlk->TxPacketList.Head) { pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList); pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); if ( RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) { RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); continue; } bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE); pMacEntry = pTxBlk->pMacEntry; if (pMacEntry->isCached) { // NOTE: Please make sure the size of pMacEntry->CachedBuf[] is smaller than pTxBlk->HeaderBuf[]!!!! NdisMoveMemory((PUCHAR)&pTxBlk->HeaderBuf[TXINFO_SIZE], (PUCHAR)&pMacEntry->CachedBuf[0], TXWI_SIZE + sizeof(HEADER_802_11)); pHeaderBufPtr = (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]); STABuildCache802_11Header(pAd, pTxBlk, pHeaderBufPtr); } else { STAFindCipherAlgorithm(pAd, pTxBlk); STABuildCommon802_11Header(pAd, pTxBlk); pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]; } pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr; // skip common header pHeaderBufPtr += pTxBlk->MpduHeaderLen; // // build QOS Control bytes // *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F); *(pHeaderBufPtr+1) = 0; pHeaderBufPtr +=2; pTxBlk->MpduHeaderLen += 2; // // build HTC+ // HTC control filed following QoS field // if ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_RDG_CAPABLE)) { if (pMacEntry->isCached == FALSE) { // mark HTC bit pHeader_802_11->FC.Order = 1; NdisZeroMemory(pHeaderBufPtr, 4); *(pHeaderBufPtr+3) |= 0x80; } pHeaderBufPtr += 4; pTxBlk->MpduHeaderLen += 4; } //pTxBlk->MpduHeaderLen = pHeaderBufPtr - pTxBlk->HeaderBuf - TXWI_SIZE - TXINFO_SIZE; ASSERT(pTxBlk->MpduHeaderLen >= 24); // skip 802.3 header pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3; pTxBlk->SrcBufLen -= LENGTH_802_3; // skip vlan tag if (bVLANPkt) { pTxBlk->pSrcBufData += LENGTH_802_1Q; pTxBlk->SrcBufLen -= LENGTH_802_1Q; } // // padding at front of LLC header // LLC header should locate at 4-octets aligment // // @@@ MpduHeaderLen excluding padding @@@ // pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr; pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4); pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen); { // // Insert LLC-SNAP encapsulation - 8 octets // EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap); if (pTxBlk->pExtraLlcSnapEncap) { NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6); pHeaderBufPtr += 6; // get 2 octets (TypeofLen) NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2); pHeaderBufPtr += 2; pTxBlk->MpduHeaderLen += LENGTH_802_1_H; } } if (pMacEntry->isCached) { RTMPWriteTxWI_Cache(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk); } else { RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk); NdisZeroMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), sizeof(pMacEntry->CachedBuf)); NdisMoveMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), (pHeaderBufPtr - (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE])));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -