📄 dot11dpelib.c
字号:
pHeader->frameCtrl |= DOT11_CPU_TO_LE_16(DOT11_FCTL_WEP); *(pCluster + length) = pTsc[0]; length ++;nextFragLen ++; *(pCluster + length) = pTsc[1]; length ++;nextFragLen ++; *(pCluster + length) = 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); } /* Only add the SNAP header if this is the first ( or only) packet in a fragment chain, and there isn't a SNAP header already. */ if (((fragNum & DOT11_FRAGMENT_MASK) == 0) && (ntohs(etherType) > DOT11_ETHERMTU)) { *(UINT16 *)(pCluster + length) = DOT11_CPU_TO_LE_16(0xaaaa); *(UINT16 *)(pCluster + length + 2) = DOT11_CPU_TO_LE_16(0x0003); *(UINT16 *)(pCluster + length + 4) = DOT11_CPU_TO_LE_16(0x0000); *(UINT16 *)(pCluster + length + 6) = etherType; length += DOT11_SNAP_HEADER_LEN; } /* Fill in the size, data location and link this Mblk to the payload */ pMblk->mBlkHdr.mData = (char *)pCluster; pMblk->mBlkHdr.mLen = length; pMblk->mBlkHdr.mNext = pDataMblk; pMblk->mBlkHdr.mFlags |= M_PKTHDR; pMblk->mBlkPktHdr.len = length + pDataMblk->mBlkHdr.mLen; /* Check if 802.1X is enabled. If so, we need to check that this is a valid egress packet */ if (pKsl != NULL) { /* Drop the packet if the 802.1x port is not open */ if ((pKsl->dot1xControlled) && (!pKsl->dot1xAllowed) && (etherType != DOT1X_ETHERTYPE)) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_DPE, ("dot11DpeFragmentSend: 802.1X dropped packet\n", 0,0,0,0,0,0)); pDot11->stats.txDot1xDropped ++; netMblkClChainFree(pMblk); return ERROR; } } /* If encryption is enabled, we need to add the ICV or MIC at this point */ if (encryptType != DOT11_ENCRYPT_NONE) { /* Now, find the last Mblk in the chain to add fake room for the ICV */ for (pLastMblk = pDataMblk; pLastMblk->mBlkHdr.mNext != NULL; pLastMblk = pLastMblk->mBlkHdr.mNext) { } if ((encryptType == DOT11_KEY_TYPE_WEP40) || (encryptType == DOT11_KEY_TYPE_WEP104)) { pLastMblk->mBlkHdr.mLen += DOT11_WEP_ICV_SIZE; /* Regardless of where the ICV is stored, we need to increase the total frame length so that it is actually transmitted */ pMblk->mBlkPktHdr.len += DOT11_WEP_ICV_SIZE; nextFragLen += DOT11_WEP_ICV_SIZE; } else if (encryptType == DOT11_KEY_TYPE_TKIP) { pLastMblk->mBlkHdr.mLen += DOT11_WEP_ICV_SIZE + DOT11_MIC_LEN; pMblk->mBlkPktHdr.len += DOT11_WEP_ICV_SIZE + DOT11_MIC_LEN; nextFragLen += DOT11_WEP_ICV_SIZE + DOT11_MIC_LEN; } else if (encryptType == DOT11_KEY_TYPE_AES) { pLastMblk->mBlkHdr.mLen += DOT11_MIC_LEN; pMblk->mBlkPktHdr.len += DOT11_MIC_LEN; nextFragLen += DOT11_MIC_LEN; } } /* Hide the next fragment length at the end of the first cluster. ar521xTxDescSetup() needs to know this to correctly set the duration in the frame */ *(UINT32 *)(pMblk->mBlkHdr.mData + pMblk->mBlkHdr.mLen + sizeof(UINT32)) = nextFragLen; /* Grab the transmission semaphore. Do this before examining the link status, since the device could be in the process of flushing the TX queue. We don't want to add to the queue while it's being flushed */ if (semTake(pDot11->dpe->transmitSem, DOT11_TX_SEM_WAIT) != OK) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_DPE, ("dot11DpeFragmentSend: Unable to get TX Sem!\n", 0, 0, 0, 0, 0,0)); netMblkClChainFree(pMblk); return ERROR; } /* Figure out if the link is up. If so, send the packet. If not, queue it up for transmission. Each packet will also have an expiration timer to prevent all of the MBlks from being used up on the TX queue */ if (pBss->linkStatus == DOT11_LINK_SLEEP) { pMblk->mBlkHdr.mNextPkt = NULL; /* Store the rate and txIndex past the end of the Mblk. Since our cluster pool is large enough for a max size 802.11 packet, there is guaranteed to be room since we just put the header in this block */ *(UINT32 *)(pMblk->mBlkHdr.mData + pMblk->mBlkHdr.mLen) = txRate; *((UINT32 *)(pMblk->mBlkHdr.mData + pMblk->mBlkHdr.mLen) + 1) = encryptKey; /* Special case - no other packets queued */ if (pDot11->dpe->transmitQueueHead == NULL) { pDot11->dpe->transmitQueueHead = pMblk; pDot11->dpe->transmitQueueTail = pMblk; } else /* Insert onto tail */ { pDot11->dpe->transmitQueueTail->mBlkHdr.mNextPkt = pMblk; pDot11->dpe->transmitQueueTail = pMblk; } } else { /* Check if there are any queued packets. If so, flush them before continuing. This is necessary in case packets were added after the queue was flushed but before the link status was changed.*/ if (pDot11->dpe->transmitQueueHead != NULL) { pDot11->dpe->transmitQueueFlush(pDot11); } /* Send the packet to the HDD, who will perform whatever card-specific operations are necessary to transmit the packet in the correct state */ if (pDot11->hdd->rawPacketSend != NULL) { status = pDot11->hdd->rawPacketSend(pDot11, pMblk, txRate, encryptKey); } else { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_DPE, ("dot11DpeFragmentSend: No hdd.rawSend() implemented\n", 0, 0, 0, 0, 0, 0)); semGive(pDot11->dpe->transmitSem); netMblkClChainFree(pMblk); return ERROR; } } /* Release the transmit sem */ semGive(pDot11->dpe->transmitSem); return status; }/***************************************************************************** dot11DpeTransmitQueueFlush - Flushes the transmit queue** This function is called by the SME when the link status changes to connected.* When called, it tries to send all packets that were queued since the link * was put to sleep.** RETURNS: OK** ERRNO: N/A*/LOCAL STATUS dot11DpeTransmitQueueFlush ( DOT11_FW * pDot11 /* Pointer to device structure */ ) { M_BLK_ID pMblk; M_BLK_ID pNextMblk; /* Grab the transmission semaphore. Do this before examining the link status, since the device could be in the process of flushing the TX queue. We don't want to add to the queue while it's being flushed */ if (semTake(pDot11->dpe->transmitSem, DOT11_TX_SEM_WAIT) != OK) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_DPE, ("dot11DpeTransmitQueueFlush: Unable to get TX Sem!\n", 0, 0, 0, 0, 0,0)); return ERROR; } pNextMblk = pDot11->dpe->transmitQueueHead; while ((pMblk = pNextMblk) != NULL) { pNextMblk = pMblk->mBlkHdr.mNextPkt; /* Send the packet to the HDD, who will perform whatever card-specific operations are necessary to transmit the packet in the correct state. Retrieve the txRate and the encryptionIndex from above. */ if (pDot11->hdd->rawPacketSend != NULL) { pDot11->hdd->rawPacketSend(pDot11, pMblk, *(UINT32 *)(pMblk->mBlkHdr.mData + pMblk->mBlkHdr.mLen), *((UINT32 *)(pMblk->mBlkHdr.mData + pMblk->mBlkHdr.mLen) + 1)); } else { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_DPE, ("dot11DpeTransmitQueueFlush: No hdd.rawSend() implemented\n", 0, 0, 0, 0, 0, 0)); netMblkClChainFree(pMblk); } } pDot11->dpe->transmitQueueHead = NULL; pDot11->dpe->transmitQueueTail = NULL; /* Release the transmit sem */ semGive(pDot11->dpe->transmitSem); return OK; }/***************************************************************************** dot11DpeFragThresholdSet - Set the fragmentation threshold** This fucntion sets the fragmentation threshold. This value is used by* tbe** RETURNS: Pointer to new END_OBJ (aka DOT11_FW) or NULL on error** ERRNO: N/A*/LOCAL STATUS dot11DpeFragThresholdSet ( DOT11_FW * pDot11, /* Pointer to device structure */ UINT32 fragThresh ) { if ((pDot11 == NULL) || (pDot11->dpe == NULL)) { return ERROR; } if (fragThresh > DOT11_MAX_PACKET) { fragThresh = 2304; } taskLock(); pDot11->dpe->fragThreshold = fragThresh; taskUnlock(); return OK; }/***************************************************************************** dot11DpeFragThresholdGet - **** RETURNS: Pointer to new END_OBJ (aka DOT11_FW) or NULL on error** ERRNO: N/A*/LOCAL STATUS dot11DpeFragThresholdGet ( DOT11_FW * pDot11, /* Pointer to device structure */ UINT32 * pFragThresh ) { if ((pDot11 == NULL) || (pDot11->dpe == NULL) || (pFragThresh == NULL)) { return ERROR; } *pFragThresh = pDot11->dpe->fragThreshold; return OK; }/****************************************************************************** dot11DpeEndPollSend - Sends a packet in polled mode*** RETURNS: OK or ERROR** ERRNO: N/A*/LOCAL STATUS dot11DpeEndPollSend ( END_OBJ* pEnd, /* Pointer to device handle */ M_BLK_ID pMblk /* Buffer containing data to write */ ) { return ERROR; }/****************************************************************************** dot11DpeEndPollRcv - Sends a packet in polled mode*** RETURNS: OK or ERROR** ERRNO: N/A*/LOCAL STATUS dot11DpeEndPollRcv ( END_OBJ* pEnd, /* Pointer to device handle */ M_BLK_ID pMblk /* Buffer containing data to write */ ) { return ERROR; }/*************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -