📄 dot11dpelib.c
字号:
pDot11->stats.rxExcludeUnencrypted ++; netMblkClChainFree(pMblk); return OK; } } /* If the packet used WEP, check that the IV bits are non-zero */ if (((DOT11_LE_TO_CPU_16(pHeader->frameCtrl)) & DOT11_FCTL_WEP) != 0) { if ((*(pCluster + sizeof(DOT11_HEADER) + 3) & 0x1f) != 0) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_SME, ("dot11DpeEndReceive: Station " DOT11_MAC_ADDR_STR " send packet with WEP pad bits set\n", DOT11_MAC_ADDR(pHeader->addr2))); netMblkClChainFree(pMblk); return ERROR; } } /* Fix for SPR 102025 - IPv6 Incompatabilities. In ESS mode, we need to filter out our own broadcast packets that are getting sent back from the AP since they confuse the IPv6 stack. Thus, we drop packets that are to the broadcast address from our own address. */ if ((pDot11->dot11Mode == DOT11_MODE_ESS) && (DOT11_IS_MCAST(pHeader->addr1)) && (bcmp((char *)pHeader->addr3, (char *)pDot11->macAddr, DOT11_ADDR_LEN) == 0)) { DOT11_LOG(DOT11_DEBUG_FLOOD, DOT11_AREA_DPE, ("dot11DpeEndReceive: Dropping our own bcast packet.\n", 0, 0, 0, 0, 0, 0)); pDot11->sme->ksl.unlock(pDot11); netMblkClChainFree(pMblk); return OK; } /* Check if this is a fragmented packet in need of reassembly. If this is a fragmented packet, either the "More fragments" bit will be set, indicating this is not the last packet, or the fragment number will be greate than zero. If a packet did not have the More frag bit and had a fragnum of zero, then it is not fragmented and not our concern. */ if ((((DOT11_LE_TO_CPU_16(pHeader->frameCtrl)) & DOT11_FCTL_MORE_FRAG) != 0) || ((DOT11_LE_TO_CPU_16(pHeader->seqCtrl)&DOT11_SEQCTL_FRAGNUM) > 0)) { if ((pHeadMblk = dot11DpeReassemble(pDot11, pMblk, pKsl)) == NULL) { pDot11->sme->ksl.unlock(pDot11); DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_DPE, ("dot11DpeEndReceive: Queued packet\n",0,0,0,0,0,0)); /* This wasn't the last fragment in a chain. No packet was generated, so just leave things be. Pakcet is either on the reassembly queue or deallocated. In either case, we're done with it. */ return OK; } DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_DPE, ("dot11DpeEndReceive: New formed packet len = %d\n", pHeadMblk->mBlkPktHdr.len,0,0,0,0,0)); /* Adjust pCluster and pHeader to point to the start of the reassembled packet rather than the fragment that triggered the reassembly */ pCluster = (UINT8*)pHeadMblk->mBlkHdr.mData; pHeader = (DOT11_HEADER *)pCluster; } else { pHeadMblk = pMblk; pHeadMblk->mBlkPktHdr.len = pMblk->mBlkHdr.mLen; } /* Having gotten this far, we know that pHeadMblk points to the head of a reassembled (or only) packet chain. Since the dot11 header and any encryption byproducts were stripped from all M-Blks except the first, we need to reassemble the ethernet header based on the info in the first packet */ pDataOffset = sizeof(DOT11_HEADER); if (((DOT11_LE_TO_CPU_16(pHeader->frameCtrl)) & DOT11_FCTL_WEP) != 0) { /* If hardware encryption is enabled, then the card was nice enough to decrypt it for us. We don't even have to do the checksum, since the HDD should have discarded packets with a bad checksum. */ /* Look at the third byte of the IV - if the EXT IV bit is set, then this is either an AES or TKIP packet, and we need to get rid of the extended IV header and the MIC fields */ if ((*(pCluster + sizeof(DOT11_HEADER) + 3) & DOT11_EXT_IV) != 0) { pDataOffset += DOT11_WEP_IV_SIZE + DOT11_WEP_EXT_IV_SIZE; pHeadMblk->mBlkHdr.mLen -= DOT11_WEP_IV_SIZE + DOT11_MIC_LEN + DOT11_WEP_EXT_IV_SIZE; pHeadMblk->mBlkPktHdr.len -= DOT11_WEP_IV_SIZE + DOT11_MIC_LEN + DOT11_WEP_EXT_IV_SIZE; /* If this is a TKIP packet, then we also need to account for the ICV at the end of the packet. In order to check if this is a TKIP packet, we need to determine if it's unicast or multicast, and check the appropriate key. */ if (((!(DOT11_IS_MCAST(pHeader->addr1))) && (pKsl->uniEncryptType == DOT11_KEY_TYPE_TKIP)) || ((DOT11_IS_MCAST(pHeader->addr1)) && (pKsl->pBss->multiEncryptType == DOT11_KEY_TYPE_TKIP))) { pHeadMblk->mBlkHdr.mLen -= DOT11_WEP_ICV_SIZE; pHeadMblk->mBlkPktHdr.len -= DOT11_WEP_ICV_SIZE; } } else { pDataOffset += DOT11_WEP_IV_SIZE; pHeadMblk->mBlkHdr.mLen -= DOT11_WEP_ICV_SIZE + DOT11_WEP_IV_SIZE; pHeadMblk->mBlkPktHdr.len -= DOT11_WEP_ICV_SIZE+DOT11_WEP_IV_SIZE; } } pLlcHeader = (DOT11_LLC_HEADER *)(pCluster + pDataOffset); stripLlc = (((ntohs(pLlcHeader->orgCode) == DOT11_LLC_RFC1024) || (ntohs(pLlcHeader->orgCode) == DOT11_LLC_8021H)) && !((ntohs(pLlcHeader->protocol) == 0x809B) || (ntohs(pLlcHeader->protocol) == 0x80F3))); pDataOffset += (stripLlc ? DOT11_SNAP_HEADER_LEN : 0); pDataOffset -= sizeof(UINT16); /* Adjust the length for the missing 802.11 Header and SNAP Header */ pHeadMblk->mBlkHdr.mLen -= sizeof(DOT11_HEADER) + (stripLlc ? DOT11_SNAP_HEADER_LEN : 0); pHeadMblk->mBlkPktHdr.len -= sizeof(DOT11_HEADER) + (stripLlc ? DOT11_SNAP_HEADER_LEN : 0); /* If the LLC header has not been removed, the length of packet must be filled in at the front of the packet */ if (!stripLlc) { *((UINT16*)(pCluster + pDataOffset)) = htons(pHeadMblk->mBlkPktHdr.len); } /* If required, add in the egress VLAN tag. 802.1X packets are an exception */ if ((pDot11->sme->vlanEnabled) && (pKsl->pBss->vlanId != DOT11_NO_VLAN) && (*(UINT16 *)(pHeadMblk->mBlkHdr.mData + pDataOffset) != (DOT1X_ETHERTYPE))) { pDataOffset -= DOT11_8021Q_TAG_LEN; pHeadMblk->mBlkHdr.mLen += DOT11_8021Q_TAG_LEN; pHeadMblk->mBlkPktHdr.len += DOT11_8021Q_TAG_LEN; *(UINT16 *)(pCluster + pDataOffset) = htons(DOT11_ETHERTYPE_8021Q); *((UINT16 *)(pCluster + pDataOffset + 2)) = htons(pKsl->pBss->vlanId); } /* Now that we've calculated the offsets, including WEP, write them to the Mblk, leaving room for the first twelve bytes of the ethernet header (the ethertype field will be used direct from the SNAP header). */ pHeadMblk->mBlkHdr.mData += pDataOffset - (2 * DOT11_ADDR_LEN); /* Copy the DA and SA over from the dot11 header, overwriting the non- relevent portions of the SNAP header. The ethernet packet starts 14 bytes before the pDataOffset. The ethertype remains untouched, as accounted for by pDataOffset. */ switch(pDot11->dot11Mode) { case DOT11_MODE_ESS: /* Find the source and copy it over */ DOT11_ADDR_COPY((char*)pHeader->addr3, (char*)(pCluster + pDataOffset - (1 * DOT11_ADDR_LEN))); /* Find the destination and copy it over */ DOT11_ADDR_COPY((char*)pHeader->addr1, (char*)(pCluster + pDataOffset - (2 * DOT11_ADDR_LEN))); break; case DOT11_MODE_IBSS: /* Find the source and copy it over */ DOT11_ADDR_COPY((char*)pHeader->addr2, (char*)(pCluster + pDataOffset - (1 * DOT11_ADDR_LEN))); /* Find the destination and copy it over */ DOT11_ADDR_COPY((char*)pHeader->addr1, (char*)(pCluster + pDataOffset - (2 * DOT11_ADDR_LEN))); break; case DOT11_MODE_AP: /* Find the destination and copy it over. Note that this is an overlapping copy, since the DA field of the etherheader extends four bytes into the addr3 field. Do a two stage copy on MIPS, since there is a known bug (SPR 89530) in MIPS where bcopy does not perform overlapping copies correctly. We can use pCluster offset 0 as a temporary buffer since this just gets discarded anyways. */ /* Find the source and copy it over */ DOT11_ADDR_COPY((char*)pHeader->addr3, (char*)pCluster); DOT11_ADDR_COPY((char*)pHeader->addr2, (char*)(pCluster + pDataOffset - (1 * DOT11_ADDR_LEN))); DOT11_ADDR_COPY((char*)pCluster, (char*)(pCluster + pDataOffset - (2 * DOT11_ADDR_LEN))) break; default: DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_DPE, ("dot11DpeEndReceive: Device is in unknown mode\n", 0, 0, 0, 0, 0, 0)); pDot11->sme->ksl.unlock(pDot11); netMblkClChainFree(pHeadMblk); return ERROR; break; } pHeadMblk->mBlkHdr.mLen += DOT11_ETHER_HEADER_LEN; pHeadMblk->mBlkHdr.mFlags |= M_PKTHDR; pHeadMblk->mBlkPktHdr.len += DOT11_ETHER_HEADER_LEN; DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_DPE, ("dot11DpeEndReceive: called ethertype=%04x len=%d!\n", ntohs(*(UINT16 *)(pHeadMblk->mBlkHdr.mData + DOT11_ADDR_LEN*2)), pHeadMblk->mBlkPktHdr.len,0,0,0,0)); /* Check if this is an EAPOL-Key message. If so, and if an advanced security policy is in place, then pass the packet to the RSN module instead of the MUX */ if ((pKsl->pBss->secPol != DOT11_SECPOL_NONE) && (stripLlc) && (*(UINT16 *)(pHeadMblk->mBlkHdr.mData + DOT11_ADDR_LEN*2) == (DOT1X_ETHERTYPE))) { if (((DOT11_EAPOL_KEY_PKT *)(pHeadMblk->mBlkHdr.mData + DOT11_ETHER_HEADER_LEN))->eapolType == DOT11_EAPOL_TYPE_KEY) { /* This routine will consume the packet regardless of return status */ pDot11->sme->ksl.unlock(pDot11); if (pDot11->sme->rsn.eapolPktReceive != NULL) { pDot11->sme->rsn.eapolPktReceive(pDot11, pHeadMblk); } else { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_DPE, ("dot11DpeEndReceive: RSN Module not present for " "EAPOL-Key\n",0,0,0,0,0,0)); netMblkClChainFree(pHeadMblk); } return OK; } } /* If this is an AP, then check the destination address to see if it is an associated station. If so, then quickly route it back to the send routine. */ if (pDot11->dot11Mode == DOT11_MODE_AP) { if (((pBridgeKsl = pDot11->sme->ksl.lookup(pDot11, (UINT8 *)pHeadMblk->mBlkHdr.mData)) != NULL) && (pBridgeKsl->type.sta.associated)) { /* Check that the destination station is on the same VLAN as the source, if appropriate */ if ((!pDot11->sme->vlanEnabled) || (pBridgeKsl->pBss->vlanId == pKsl->pBss->vlanId)) { DOT11_LOG(DOT11_DEBUG_FLOOD, DOT11_AREA_DPE, ("dot11DpeEndReceive: Quick bridge to destination " DOT11_MAC_ADDR_STR "\n", DOT11_MAC_ADDR(pBridgeKsl->macAddr))); pDot11->sme->ksl.unlock(pDot11); return pDot11->dpe->endSend((END_OBJ *)pDot11, pHeadMblk); } } } if (pKsl->dot1xControlled) { /* Check if we are in 802.1X mode. If so, we need to check with the 802.1X state machine to see if this is a valid ingress packet */ if ((pKsl->dot1xAllowed) || ((stripLlc) && (*(UINT16 *)(pHeadMblk->mBlkHdr.mData + DOT11_ADDR_LEN*2) == (DOT1X_ETHERTYPE)))) { pDot11->sme->ksl.unlock(pDot11); END_RCV_RTN_CALL(&pDot11->endObj, pHeadMblk); } else { pDot11->sme->ksl.unlock(pDot11); DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_DPE, ("dot11DpeEndReceive: 802.1X rejected ingress packet\n", 0,0,0,0,0,0)); pDot11->stats.rxDot1xDropped ++; netMblkClChainFree(pHeadMblk); } } else { pDot11->sme->ksl.unlock(pDot11); /* Pass the packet up to the vxWorks network stack */ END_RCV_RTN_CALL(&pDot11->endObj, pHeadMblk); } /* Note : the KSL lock was released and the packet consumed in all branches of the IF statement above */ return OK; }/***************************************************************************** dot11DpeEndSend - END Send routine for WLS Framework** This is the END Send routine that is called when END wishes to send a packet* out the interface. This function will create a new Mblk/cl-blk/cluster
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -