📄 dot11dpelib.c
字号:
/* Join to the same cl-blk and increment the reference count */ netMblkDup(pCurrentMblk, pNewMblk); /* Offset to the fragmentation point */ pNewMblk->mBlkHdr.mData = pCurrentMblk->mBlkHdr.mData + fragLen - pktLen; pNewMblk->mBlkHdr.mLen = pCurrentMblk->mBlkHdr.mLen - (fragLen - pktLen); /* Sever the old packet, and connect up the new */ pNewMblk->mBlkHdr.mNext = pCurrentMblk->mBlkHdr.mNext; pCurrentMblk->mBlkHdr.mNext = NULL; /* Adjust the length of the old mblk to reflect the boundary */ pCurrentMblk->mBlkHdr.mLen = fragLen - pktLen; status = dot11DpeFragmentSend(pDot11, pDstAddr, pSrcAddr, pHeadMblk, currentFrag, min((totalLen - currentLen) + sizeof(DOT11_HEADER) - sizeof(UINT16), pDot11->dpe->fragThreshold), pBss); currentFrag ++; } else { pHeadMblk->mBlkPktHdr.len = totalLen - currentLen; currentLen = totalLen; /* The end of the chain is simple to deal with. Just send the packet */ status = dot11DpeFragmentSend(pDot11, pDstAddr, pSrcAddr, pHeadMblk, currentFrag|DOT11_FRAGMENT_LAST, 0, pBss); break; } } /* Free the Cl-Blk that we incremented refCnt on earlier */ netClBlkFree(pDot11->endObj.pNetPool, pHdrClBlk); } return status; }/***************************************************************************** dot11DpeFragmentSend - Sends a particular fragment out the interface** This function does the real work in the transmit. It takes the M-Blk* chain that has been fragmented if applicable, adds an 802.11 header and a* SNAP header if applicable and sends it to the HDD.** RETURNS: OK** ERRNO: N/A*/LOCAL STATUS dot11DpeFragmentSend ( DOT11_FW * pDot11, /* Pointer to device structure */ UINT8 * pDstAddr, /* Pointer to DA */ UINT8 * pSrcAddr, /* Pointer to SA */ M_BLK_ID pDataMblk, /* Mblk containing payload */ int fragNum, /* Fragment number, bit 15 set if last */ int nextFragLen, /* Length of the next fragment */ DOT11_BSS * pBss /* BSS to send the packet to */ ) { UINT8 * pCluster; /* Cluster with 802.11 Header */ M_BLK_ID pMblk; /* MBlk for 802.11 header */ M_BLK_ID pLastMblk; /* Working MBlk */ DOT11_HEADER * pHeader; /* Dot11 header data structure */ int length; /* Length of the final packet */ UINT16 etherType; /* Ptr to location of ethertype */ DOT11_KSL_ENTRY * pKsl; /* KSL entry for the immediate dest */ UINT32 txRate; /* Rate at which to transmit */ DOT11_ENCRYPT_TYPE encryptType; /* Type of encryption to use */ UINT32 encryptKey; /* key to use */ UINT32 encryptIndex; /* WEP index, 0 for pw keys */ UINT32 iv; /* WEP initialization vector */ UINT8 * pTsc; /* Pointer to packet ctr for TKIP/AES */ STATUS status = OK; DOT11_LOG(DOT11_DEBUG_FLOOD, DOT11_AREA_DPE, ("dot11DpeFragmentSend: Called first Mblk len = %d framelen=%d " "fragment=%04x!\n", pDataMblk->mBlkHdr.mLen , pDataMblk->mBlkPktHdr.len, fragNum, 0,0,0)); if ((fragNum & DOT11_FRAGMENT_MASK) == 0) { /* If this is the first fragment, we need to "remove" the old 802.3 and get a copy of the ethertype. */ etherType = *(UINT16 *)(pDataMblk->mBlkHdr.mData + (2 * DOT11_ADDR_LEN)); /* If this is an 802.1Q tagged packet, strip the tag off, as well */ if (etherType == htons(DOT11_ETHERTYPE_8021Q)) { /* The correct ethertype follows the 802.1Q tag, which is offset two from the end of the EH (the other two bytes were in the ethertype field of the EH */ etherType = *(UINT16 *)(pDataMblk->mBlkHdr.mData + (2 * DOT11_ADDR_LEN) + DOT11_8021Q_TAG_LEN); pDataMblk->mBlkHdr.mData = pDataMblk->mBlkHdr.mData + DOT11_8021Q_TAG_LEN; pDataMblk->mBlkHdr.mLen = pDataMblk->mBlkHdr.mLen - DOT11_8021Q_TAG_LEN; DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_DPE, ("dot11DpeFragmentSend: Called for 802.1Q packet. " "Correct ethertype = %04x\n", ntohs(etherType),0,0,0,0,0)); } /* Advance the "start of data" pointer to ignore the Ethernet header. Adjust the Mblk header to reflect that it is no longer the first mblk in the chain. */ pDataMblk->mBlkHdr.mData = pDataMblk->mBlkHdr.mData + DOT11_ETHER_HEADER_LEN; pDataMblk->mBlkHdr.mLen = pDataMblk->mBlkHdr.mLen - DOT11_ETHER_HEADER_LEN; } else { /* This is just here to prevent "variable possibly used before initialized" warning messages. The compiler's not smart enough to figure out that the logic prevents that case */ etherType = 0; } /* The payload is no longer the first packet in the Mblk chain if we're adding an 802.11 header. */ pDataMblk->mBlkHdr.mFlags &= (~M_PKTHDR); /* Next, create an Mblk containing the 802.11 Header */ if ((pMblk = netTupleGet(pDot11->endObj.pNetPool, DOT11_MTU, M_DONTWAIT, MT_DATA, FALSE)) == NULL) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_DPE, ("dot11DpeFragmentSend: Error getting Mblk\n", 0, 0, 0, 0, 0, 0)); netMblkClChainFree(pDataMblk); return ERROR; } pCluster = (UINT8 *)pMblk->mBlkHdr.mData; /* Clear some space for the 802.11 header so that we don't need to set fields if their values is zero. */ bzero((char*)pCluster, sizeof(DOT11_HEADER)); pHeader = (DOT11_HEADER *)pCluster; /* Set the frame control and address fields appropriately for our network role. See 7.2.2 - Table 2 of IEEE 802.11/2003 for details. */ switch(pDot11->dot11Mode) { case DOT11_MODE_ESS: pHeader->frameCtrl = DOT11_CPU_TO_LE_16(DOT11_TYPE_DATA | DOT11_FCTL_TO_DS); DOT11_ADDR_COPY((char*)pBss->bssid, (char*)pHeader->addr1); DOT11_ADDR_COPY((char*)pSrcAddr, (char*)pHeader->addr2); DOT11_ADDR_COPY((char*)pDstAddr, (char*)pHeader->addr3); break; case DOT11_MODE_IBSS: pHeader->frameCtrl = DOT11_CPU_TO_LE_16(DOT11_TYPE_DATA); DOT11_ADDR_COPY((char*)pDstAddr, (char*)pHeader->addr1); DOT11_ADDR_COPY((char*)pSrcAddr, (char*)pHeader->addr2); DOT11_ADDR_COPY((char*)pBss->bssid, (char*)pHeader->addr3); break; case DOT11_MODE_AP: pHeader->frameCtrl = DOT11_CPU_TO_LE_16(DOT11_TYPE_DATA | DOT11_FCTL_FROM_DS); DOT11_ADDR_COPY((char*)pDstAddr, (char*)pHeader->addr1); DOT11_ADDR_COPY((char*)pBss->bssid, (char*)pHeader->addr2); DOT11_ADDR_COPY((char*)pSrcAddr, (char*)pHeader->addr3); break; default: DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_DPE, ("dot11DpeFragmentSend: Device is in unknown mode\n",0,0,0,0, 0, 0)); netMblkClChainFree(pMblk); return ERROR; break; } /* If this is a fragmented packet, set the more fragment bit and the fragment number field appropriately */ /*If this isn't the only fragment*/ if (fragNum != (DOT11_FRAGMENT_LAST | 0)) { /* Set the "More Fragments" flag if this isn't the last frag */ if ((fragNum & DOT11_FRAGMENT_LAST) == 0) { pHeader->frameCtrl |= DOT11_CPU_TO_LE_16(DOT11_FCTL_MORE_FRAG); } /* Fill in the fragment number field */ pHeader->seqCtrl = DOT11_CPU_TO_LE_16(fragNum & DOT11_FRAGMENT_MASK); } /* Start calculating the length of the new MBlk containing the DOT11 header, SNAP header and IV if applicable */ length = sizeof(DOT11_HEADER); encryptIndex = 0; encryptKey = DOT11_KEYINDEX_NONE; encryptType = DOT11_ENCRYPT_NONE; /* Get the current rate from the KSL entry for the immediate destination, aka 802.11 addr 1. The encryption state for the immediate dest. is also in the KSL record. */ if ((pKsl = pDot11->sme->ksl.lookup(pDot11, pHeader->addr1)) == NULL) { txRate = pBss->bcastRate; } else /* Found KSL record */ { if (pDot11->sme->ksl.lock(pDot11) != OK) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_DPE, ("dot11DpeFragmentSend: Cannot get KSL lock.\n", 0, 0, 0, 0, 0, 0)); txRate = pBss->bcastRate; encryptType = DOT11_ENCRYPT_NONE; /* If we can't get the KSL lock, then we shouldn't use the KSL entry */ pKsl = NULL; } else /* we got the lock OK */ { txRate = pKsl->currentTxRate; encryptType = pKsl->uniEncryptType; encryptKey = pKsl->uniEncryptIndex; encryptIndex = 0; /* Release the KSL protection semaphore */ pDot11->sme->ksl.unlock(pDot11); } } /* Set pKsl to NULL if this is a multicast packet */ if ((DOT11_IS_MCAST(pHeader->addr1)) || (pKsl == NULL)) { pKsl = NULL; pTsc = pBss->tscMultiTx; } else { pTsc = pKsl->tscUniTx; } /* If a key mapping entry wasn't set, then we need to check to see if there is a multicast entry */ if ((pKsl == NULL) || (encryptType == DOT11_ENCRYPT_NONE)) { encryptIndex = pBss->multiKeySlot; encryptKey = pBss->multiEncryptIndex; encryptType = pBss->multiEncryptType; } /* Check for an exclusion policy for 802.1x. If the packet is an EAPOL packet and the 802.1X exclusion policy is set, then don't set the WEP flag */ if ((encryptType != DOT11_ENCRYPT_NONE) && (etherType == DOT1X_ETHERTYPE)) { encryptType = DOT11_ENCRYPT_NONE; } /* Check if we need to run encryption on this packet */ if ((encryptType == DOT11_KEY_TYPE_WEP40) || (encryptType == DOT11_KEY_TYPE_WEP104)) { /* If so, we need to add an IV to the end of the Header cluster, and and ICV to the last mblk in the chain, if possible. If there isn't room then we'll have to allocate a whole new MBLK-cluster chain just for four bytes. C'est la vie.*/ iv = ++ pDot11->dpe->currentIV; /* First add the IV. No need to swap, since it's more or less arbitrary */ *(pCluster + length) = iv & 0x000000ff; length ++; nextFragLen ++; *(pCluster + length) = (iv & 0x0000ff00) >> 8; length ++;nextFragLen ++; *(pCluster + length) = (iv & 0x00ff0000) >> 16; length ++;nextFragLen ++; *(pCluster + length) = encryptIndex << 6; length ++;nextFragLen ++; /* Next, adjust the frame control header to indicate we're using WEP*/ pHeader->frameCtrl |= DOT11_CPU_TO_LE_16(DOT11_FCTL_WEP); } else if (encryptType == DOT11_KEY_TYPE_TKIP) { pHeader->frameCtrl |= DOT11_CPU_TO_LE_16(DOT11_FCTL_WEP); *(pCluster + length) = pTsc[1]; length ++;nextFragLen ++; *(pCluster + length) = (pTsc[1] | 0x20) & 0x7f; length ++;nextFragLen ++; *(pCluster + length) = pTsc[0]; length ++;nextFragLen ++; *(pCluster + length) = DOT11_EXT_IV | (encryptIndex << 6); length ++;nextFragLen ++; *(pCluster + length) = pTsc[5]; length ++;nextFragLen ++; *(pCluster + length) = pTsc[4]; length ++;nextFragLen ++; *(pCluster + length) = pTsc[3]; length ++;nextFragLen ++; *(pCluster + length) = pTsc[2]; length ++;nextFragLen ++; /* increment the packet count */ DOT11_BYTEARRAY_INC(pTsc, DOT11_TSC_LEN); } else if (encryptType == DOT11_KEY_TYPE_AES) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -