⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dot11dpelib.c

📁 PNE 3.3 wlan source code, running at more than vxworks6.x version
💻 C
📖 第 1 页 / 共 5 页
字号:
* chain and put the appropriate 802.11 header into it.  The new chain is linked* in front of the old chain, and the old header is adjusted to offset behind* the ethernet header.  The SNAP header is also created in the first MBlk.** Note that the entire ethernet header must be in one cluster.** RETURNS: OK or ERROR on allocation error** ERRNO: N/A*/LOCAL STATUS dot11DpeEndSend    (    END_OBJ * pEnd,               /* Pointer to END_OBJ */    M_BLK_ID pDataMblk            /* Mblk containing payload */    )    {    DOT11_FW * pDot11 = (DOT11_FW *)pEnd;    DOT11_KSL_ENTRY * pKsl;    STATUS     status = OK;    int        i;    M_BLK_ID   pMblk;    UINT16     destVlan;    UINT16     etherType;    DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_DPE,              ("dot11DpeEndSend: Called for dest " DOT11_MAC_ADDR_STR "\n",               DOT11_MAC_ADDR((UINT8 *)pDataMblk->mBlkHdr.mData)));    /* Ensure a correct MBlk */    if ((pDataMblk == NULL) || (pDataMblk->mBlkHdr.mType == MT_FREE))        {        return ERROR;        }        /* Sanity check. */    if ((pDot11 == NULL) || (pDot11->hdd == NULL))        {        netMblkClChainFree(pDataMblk);        return ERROR;        }        if (pDot11->dot11Mode != DOT11_MODE_AP)        {        /* If this isn't AP mode, we don't need to worry about multiple BSSs */        etherType = *(UINT16 *)(pDataMblk->mBlkHdr.mData + 2 * DOT11_ADDR_LEN);        status = dot11DpeEndSendBss(pDot11, pDataMblk, DOT11_DEFAULT_BSS);        }    else        {        /* Get the VLAN from the VLAN tag, if present */        if ((pDot11->sme->vlanEnabled) &&            (*(UINT16 *)(pDataMblk->mBlkHdr.mData +                          DOT11_ADDR_LEN + DOT11_ADDR_LEN) ==              ntohs(DOT11_ETHERTYPE_8021Q)))            {            destVlan = ntohs(*(UINT16 *)(pDataMblk->mBlkHdr.mData +                                          DOT11_ETHER_HEADER_LEN)) &                                          DOT11_8021Q_VLAN_MASK;            etherType = *(UINT16 *)(pDataMblk->mBlkHdr.mData +                                     DOT11_ETHER_HEADER_LEN + sizeof(UINT16));                        DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_DPE,                      ("dot11DpeEndSend: Called for VLAN %d \n", destVlan,                       0,0,0,0,0));            }        else            {            etherType = *(UINT16 *)(pDataMblk->mBlkHdr.mData + 2 *                                     DOT11_ADDR_LEN);            destVlan = DOT11_NO_VLAN;            }                /* Check if this is a multicast or unicast packet.  The destination         address is at the start of the ethernet header, which is at the start        of the packet */        if (DOT11_IS_MCAST(pDataMblk->mBlkHdr.mData))            {            /* Send packet to each connected BSS */            for (i=0; i<DOT11_BSS_MAX; i++)                {                if (pDot11->sme->bss[i].inUse)                    {                    /* If VLAN support is enabled, verify that the tagged VLAN                    is that of the destination BSS, and forward */                    if ((pDot11->sme->vlanEnabled) &&                         (pDot11->sme->bss[i].vlanId != destVlan) &&                        (etherType != DOT1X_ETHERTYPE))                        {                        DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_DPE,                                  ("dot11DpeEndSend: Dropping bcast packet "                                   "sent to VLAN %d - BSS %d belongs to vlan"                                   " %d \n", destVlan, i,                                    pDot11->sme->bss[i].vlanId,0,0,0));                        continue;                        }                    if ((pMblk = netMblkChainDup(pDot11->endObj.pNetPool,                                                 pDataMblk, 0, M_COPYALL,                                                 M_WAIT)) == NULL)                        {                        DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_DPE,                                  ("dot11DpeEndSend: Out of MBlks sending"                                   " broadcast packet\n",0,0,0,0,0,0));                        status = ERROR;                        break;                        }                    status |= dot11DpeEndSendBss(pDot11, pMblk,                                                 &pDot11->sme->bss[i]);                    }                }                        /* Free the original non-duplicated packet */            netMblkClChainFree(pDataMblk);            }        else            {            pKsl = pDot11->sme->ksl.lookup(pDot11,                                            (UINT8 *)pDataMblk->mBlkHdr.mData);                        /* If there is no KSL entry, then we are not connected to the             destination */            if (pKsl == NULL)                {                /* Drop packet silently */                netMblkClChainFree(pDataMblk);                status = OK;                }            else                {                /* If VLAN support is enabled, verify that the tagged VLAN                is that of the destination BSS, and forward */                if ((pDot11->sme->vlanEnabled) &&                     (pKsl->pBss->vlanId != destVlan) &&                    (etherType != DOT1X_ETHERTYPE))                    {                    DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_DPE,                              ("dot11DpeEndSend: Dropping UCAST packet "                               "sent to VLAN %d - BSS %d belongs to vlan"                               " %d \n", destVlan, pKsl->pBss->bssNum,                                pKsl->pBss->vlanId,    0,0,0));                    DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_DPE,                              ("dot11DpeEndSend: Dropping UCAST to "                                DOT11_MAC_ADDR_STR "\n",                               DOT11_MAC_ADDR(pKsl->macAddr)));                                        netMblkClChainFree(pDataMblk);                    status = OK;                    }                else                    {                    status =  dot11DpeEndSendBss(pDot11, pDataMblk, pKsl->pBss);                    }                }            }        }        return status;    }/***************************************************************************** dot11DpeEndSendBss - END Send routine for a specific BSS** 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 * chain and put the appropriate 802.11 header into it.  The new chain is linked* in front of the old chain, and the old header is adjusted to offset behind* the ethernet header.  The SNAP header is also created in the first MBlk.** Note that the entire ethernet header must be in one cluster.** RETURNS: OK or ERROR on allocation error** ERRNO: N/A*/LOCAL STATUS dot11DpeEndSendBss    (    DOT11_FW * pDot11,            /* Pointer to END_OBJ */    M_BLK_ID pDataMblk,           /* Mblk containing payload */    DOT11_BSS * pBss              /* BSS to send packet to */    )    {    STATUS     status = ERROR;    /* Status of second-level send function */    int        fragLen;           /* Max size of each packet, NOT inc header*/     int        totalLen;          /* Total PAYLOAD data to be sent */    int        currentLen;        /* Cumulative PAYLOAD data sent */    int        currentFrag;       /* Cumulative fragments sent - ZB */    int        pktLen;            /* Used when calc indiv packet details */    M_BLK_ID   pCurrentMblk;      /* Used when a new MBlk needs allocation */    M_BLK_ID   pNewMblk;          /* Used when a new MBlk needs allocation */    M_BLK_ID   pHeadMblk;         /* Used when a new MBlk needs allocation */    CL_BLK_ID  pHdrClBlk;         /* Cl-Blk containing header info */    UINT8 *    pDstAddr;          /* Pointer to DA for all packets */    UINT8 *    pSrcAddr;          /* Pointer to SA for all packets */            if (pBss->linkStatus == DOT11_LINK_DOWN)        {        DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_DPE,                  ("dot11DpeEndSendBss: Not connected\n",0,0,0,0,0,0));                    netMblkClChainFree(pDataMblk);        return ERROR;        }            /* Drop undersized packets */    if (pDataMblk->mBlkHdr.mLen < DOT11_ETHER_HEADER_LEN)        {        DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_DPE,                  ("dot11DpeEndSendBss: MBlk not formed correctly.  EH must "                   "not be split across MBlks!.  Len = %d\n",                    pDataMblk->mBlkHdr.mLen, 0, 0, 0, 0,0));        netMblkClChainFree(pDataMblk);        return ERROR;        }        /* Store the SA and DA so that we can put it in every packet.  Since     we know that it's in the first cluster by the check above, we just     increment the refcnt on the first cluster so that nobody frees it     until we're done with all fragments*/    pDstAddr = (UINT8*)pDataMblk->mBlkHdr.mData;    pSrcAddr = (UINT8*)pDataMblk->mBlkHdr.mData + DOT11_ADDR_LEN;    /* Check if we need to perform fragmentation */    if (((pDataMblk->mBlkPktHdr.len + sizeof(DOT11_HEADER) +           DOT11_SNAP_HEADER_LEN - DOT11_ETHER_HEADER_LEN + DOT11_FCS_SIZE)         <= pDot11->dpe->fragThreshold) || (DOT11_IS_MCAST(pDstAddr)))        {        /* No fragmentation necessary */        status = dot11DpeFragmentSend            ((DOT11_FW*)pDot11,              (UINT8*)pDataMblk->mBlkHdr.mData,             (UINT8*)pDataMblk->mBlkHdr.mData+DOT11_ADDR_LEN,              (M_BLK_ID)pDataMblk,              (int)(0 | DOT11_FRAGMENT_LAST), 0,              pBss);        }    else        {        DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_DPE,                  ("dot11DpeEndSendBss: Fragmenting pkt len %d/%d frag=%d\n",                   pDataMblk->mBlkPktHdr.len,                   pDataMblk->mBlkPktHdr.len + sizeof(DOT11_HEADER) -                    DOT11_ETHER_HEADER_LEN + DOT11_FCS_SIZE,                    pDot11->dpe->fragThreshold,                   0,0,0));                        if (pDot11->dpe->fragThreshold < DOT11_FRAGMENT_MIN_SIZE)            {                    DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_DPE,                      ("dot11DpeEndSendBss: Invalid fragmentation threshold\n",                       0, 0, 0, 0, 0, 0));            netMblkClChainFree(pDataMblk);            return ERROR;            }                pHdrClBlk = pDataMblk->pClBlk;        pHdrClBlk->clRefCnt ++;                    /* We need to create appropriately sized fragments. Choose the maximum        length of fragment based on the fragmentation size.  Since         802.11(2003) 9.4 states that the size must always be even except for         the last packet, accomodate that condition as well */        fragLen = (pDot11->dpe->fragThreshold - sizeof(DOT11_HEADER) -                    DOT11_FCS_SIZE) & (~0x00000001);        totalLen = pDataMblk->mBlkPktHdr.len;        currentLen = 0;        currentFrag = 0;        pNewMblk = pDataMblk;        /* This is the main fragment creating loop.  The original m-blk chain        is examined.  Anytime an M-blk has a fragment boundary in it, the         length is adjusted to compensate, and a new Mblk is created for the         part of the cluster after the boundary with the mData pointer adjusted.        The reference count field in the Cl-Blk is used to keep track of         multiple uses of a cluster.  */        while (totalLen > currentLen)            {            /* For the first fragment, assume that dot11DpeFragmentSend() is            going to add a SNAP header, and account for it */            if (currentLen == 0)                {                pktLen = DOT11_SNAP_HEADER_LEN - DOT11_ETHER_HEADER_LEN;                }            else                {                pktLen = 0;                }             pHeadMblk = pNewMblk;            pCurrentMblk = pHeadMblk;            /* Advance though the current M-Blk chain until we find an M-blk             with a fragment boundary */            while ((pCurrentMblk != NULL) &&                    ((pktLen + pCurrentMblk->mBlkHdr.mLen) <= fragLen))                {                /* Since there's room for the entire mBlk,  add it to the                 chain. */                pktLen += pCurrentMblk->mBlkHdr.mLen;                pCurrentMblk = pCurrentMblk->mBlkHdr.mNext;                }                            /* Getting here means that either we're at a cluster boundary or             we're at the end of the chain.  Either way, fill in the first Mblk             with the appropriate header details */            pHeadMblk->mBlkHdr.mFlags |= M_PKTHDR;            if (pCurrentMblk != NULL)                {                /* This is not the last fragment.  Adjust the last Mblk of this                fragment to reflect the boundary.  */                pHeadMblk->mBlkPktHdr.len = fragLen;                currentLen += fragLen;                /* Allocate a new mBlk for the start of the next packet */                if ((pNewMblk = netMblkGet(pDot11->endObj.pNetPool,                                           M_DONTWAIT, MT_DATA)) == NULL)                    {                    DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_DPE,                              ("dot11DpeEndSendBss:  Error allocting Mblk ln%d\n",                               __LINE__,0, 0, 0, 0,0));                                        netMblkClChainFree(pHeadMblk);                    /* Free the Cl-Blk that we incremented refCnt earlier */                    netClBlkFree(pDot11->endObj.pNetPool, pHdrClBlk);                    return ERROR;                    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -