intprismhostap.c

来自「vworks 下wlan的实现代码」· C语言 代码 · 共 1,651 行 · 第 1/5 页

C
1,651
字号
* ERRNO: N/A*/LOCAL STATUS intPrismHostApReceive    (    WLAN_DEV * pWlanDev,     /* Pointer to device control structure */    RX_PACKET * pRxPacketIn  /* Pointer to net cluster, in a struct */    )    {    WLAN_RX_FRAME * pRxFrame;/* Intersil frame - first 60 bytes of packet */    WLAN_STA * pSta;         /* Pointer to station record */    RX_PACKET * pRxNext;     /* Used to walk linked list of queued packets */    RX_PACKET * pRxPacket;   /* Used to walk linked list of queued packets */    int numPackets;          /* Counts number of packets processed this call*/    int intLevel;        WLAN_DEBUG(DEBUG_INFO, ("intPrismHostApReceive: Starting\n"));     /* Set the counter that limits how many packets we can process at once to    zero */    numPackets = 0;    /* Setup the "next" packet */    pRxNext = pRxPacketIn;        while (((pRxPacket = pRxNext) != NULL) && (numPackets < 10))        {        numPackets ++;                        WLAN_INT_LOCK;        pWlanDev->pRxHead = pRxPacket->pNext;        pRxNext = pRxPacket->pNext;         if (pWlanDev->pRxTail == pRxPacket)            {            pWlanDev->pRxTail = NULL;            }                WLAN_INT_UNLOCK;                pRxFrame = (WLAN_RX_FRAME *)(pRxPacket->pData);        /* Check if this is a known station.  If not, then make an entry. */        if ((pSta = intPrismHostApStaLookup(pRxFrame->addr2)) == NULL)            {            WLAN_DEBUG(DEBUG_INFO, ("New station " MAC_ADDR_STRING " found\n",                                    MAC_ADDR(pRxFrame->addr2)));            /* Add the station to the list of known stations */            if ((pSta=intPrismHostApStaAdd(pRxFrame->addr2)) == NULL)                {                WLAN_DEBUG(DEBUG_ERROR, ("Unable to add station\n"));                return ERROR;                }            }        else             {            /* This is a known station we're hearing from, so we can restart             its  watchdog */            if ((pSta->assocStatus != TRUE) && (pWlanHostAp->authTime != 0))                {                if(wdStart(pSta->timeoutWd,pWlanHostAp->authTime*sysClkRateGet(),                           (FUNCPTR)intPrismHostApRemoveSta, (int)pSta) == ERROR)                    {                    WLAN_DEBUG(DEBUG_ERROR, ("intPrismReceive : Error start"                                             "ing timeout watchdog!\n"));                    return ERROR;                    }                            }            else if (pWlanHostAp->activeTime != 0)                {                if (wdStart(pSta->timeoutWd, pWlanHostAp->activeTime *                             sysClkRateGet(), (FUNCPTR)intPrismHostApRemoveSta,                             (int)pSta) == ERROR)                    {                    WLAN_DEBUG(DEBUG_ERROR, ("intPrismReceive : Error start"                                             "ing timeout watchdog!\n"));                    return ERROR;                    }                            }            }            /* Rate is in lower byte of the UINT16 field */        pSta->lastTxRate = pRxFrame->rate & 0x00ff;             /* Handle the received packet differently based upon the type of frame */        switch(pRxFrame->frameCtl & WLAN_FTYPE_MASK)            {            case WLAN_FTYPE_DATA:                intPrismHostApReceiveData(pWlanDev, pSta, pRxPacket, pRxFrame);                break;            case WLAN_FTYPE_CTL:                WLAN_DEBUG(DEBUG_INFO, ("intPrismHostApReceive: Control frame "                                        "received: "));                switch(pRxFrame->frameCtl & 0xf0)                    {                    case WLAN_STYPE_CTL_PS_POLL:                        /* When we get a PS-Poll, we know that the sending station                        is awake and wanting one more packet.  Send it to him */                        WLAN_DEBUG(DEBUG_INFO,("PS-Poll\n"));                        if (intPrismHostApPMHandle(pWlanDev, pSta) != OK)                            break;                                            /* Only clear the TIM bit if there's no more data */                        if (pSta->pPMQueue == NULL)                            {                            intPrismHostApTIMSet(pWlanDev, pSta->assocId,                                                  WLAN_HAP_DTIM_CLEAR);                            }                        break;                    case WLAN_STYPE_CTL_RTS:                        WLAN_DEBUG(DEBUG_INFO,("RTS\n"));                        break;                    case WLAN_STYPE_CTL_CTS:                        WLAN_DEBUG(DEBUG_INFO,("CTS\n"));                        break;                    case WLAN_STYPE_CTL_ACK:                        WLAN_DEBUG(DEBUG_INFO,("ACK\n"));                        break;                    case WLAN_STYPE_CTL_CF_END:                        WLAN_DEBUG(DEBUG_INFO,("CF-End\n"));                        break;                    case WLAN_STYPE_CTL_CF_ACK_END:                        WLAN_DEBUG(DEBUG_INFO,("CF-End & CF-Ack \n"));                        break;                    default:                        WLAN_DEBUG(DEBUG_INFO,("Unknown framectl = %04x\n",                                               pRxFrame->frameCtl));                        break;                    }                netClFree (&pWlanDev->netPool, (UCHAR *)pRxPacket);                                break;            case WLAN_FTYPE_MGMT:                intPrismHostApReceiveMgmt(pWlanDev, pSta, pRxPacket, pRxFrame);                netClFree (&pWlanDev->netPool, (UCHAR *)pRxPacket);                break;            default:                WLAN_DEBUG(DEBUG_INFO, ("Error\n"));                break;            }               } /* WHILE (More packets && !tooManyPackets) */    /* Check if we tried to process more packets than we're allowed.  If so,     give other jobs on the netJob queue a chance to run by spawning another     netjob for us to continue */    if (pRxPacket != NULL)        {        netJobAdd(intPrismHostApReceive, (int)pWlanDev, (int)pRxPacket,0,0,0);        }    return OK;    }/***************************************************************************** intPrismHostApReceiveData - Receive handler for data frames** This routine is called when a data frame is received.  This routine will* ensure that the packet is deallocated, even in an error condition, so the* calling function should not try to deallocate pRxFrame.** RETURNS: OK or ERROR** ERRNO: N/A*/LOCAL STATUS intPrismHostApReceiveData    (    WLAN_DEV * pWlanDev,     WLAN_STA * pSta,      RX_PACKET * pRxPacket,     WLAN_RX_FRAME *pRxFrame     )    {    M_BLK_ID  pMBlk;          /* Pointer to MBlk to put data in */    CL_BLK_ID pClBlk;         /* Pointer to ClBlk to put data in */    UINT16 reason;            /* buffer to store disassociation reason */    /* These variables are used when a broadcast comes in from an associated    wireless station, and a separate copy of the packet must be made to send    to the wireless interface as well as pass up the IP stack for routing to     the wired interface */    M_BLK_ID  pMBlkTx;    /* Data frames are a Class 3 frame unless they are sent in IBSS,    thus we only accept frames from known stations.  If the sender is    not authenticated, send a deauth frame.  If the sender if auth but    not assoc, send a disassoc. frame. */    if (pSta->authStatus != TRUE)        {        WLAN_DEBUG(DEBUG_INFO, ("intPrismHostApReceiveData: Data frame "                                "received from un-"                                "authenticated host \n"));        reason = WLAN_HOST_AP_REASON_INVALID;        intPrismManagementFrameSend(pWlanDev, WLAN_STYPE_MGMT_DEAUTH,                                    (char *) &reason,                                     sizeof(UINT16), pSta);          netClFree (&pWlanDev->netPool, (UCHAR *)pRxPacket);        return ERROR;        }            else if (pSta->assocStatus != TRUE)        {        WLAN_DEBUG(DEBUG_INFO, ("intPrismHostApReceiveData: Data frame re"                                "ceived from un-associated host \n"));        reason = WLAN_HOST_AP_REASON_NOT_ASSOC;        intPrismManagementFrameSend(pWlanDev, WLAN_STYPE_MGMT_DISASSOC,                                    (char *) &reason,                                     sizeof(UINT16), pSta);          netClFree (&pWlanDev->netPool, (UCHAR *)pRxPacket);        return ERROR;        }                /* Check for a PM frame */    if ((pRxFrame->frameCtl & WLAN_FCTL_PWRMAN) != 0)        {        WLAN_DEBUG(DEBUG_INFO, ("intPrismHostApReceiveData: frame cont"                                "aining PWR MAN!\n"));         if (!pSta->pmEnabled)            {            pSta->pmEnabled = TRUE;            pWlanHostAp->numPM ++;            }        }    /* Fix for SPR 75641 - NULL-DATA packets without the PWRMAN bit    should turn PWRMAN off */    else if ( (pRxFrame->frameCtl & WLAN_STYPE_MASK) ==               WLAN_STYPE_DATA_NULL)        {        if (pSta->pmEnabled)            {            pSta->pmEnabled = FALSE;            pWlanHostAp->numPM --;            }        }                /* If there's no data, then drop the packet. This usually happens    when a station sends a NULL_DATA frame with the PWRMAN bit set    to signal that it is entering PM mode */    if ( ((pRxFrame->frameCtl & WLAN_STYPE_MASK) ==           WLAN_STYPE_DATA_NULL) ||         (pRxFrame->dataLen == 0))        {        netClFree (&pWlanDev->netPool, (UCHAR *)pRxPacket);        return ERROR;        }    /* So, this is a normal data frame from an authorized source.    Pass it up the MUX stack for forwarding */    if((pClBlk = netClBlkGet (&pWlanDev->netPool, M_DONTWAIT))        == NULL)        {        netClFree (&pWlanDev->netPool, (UCHAR *)pRxPacket);        WLAN_DEBUG(DEBUG_ERROR, ("intPrismHostApReceiveData: Error alloc"                                 " ClBlk\n"));        return ERROR;        }    if((pMBlk = netMblkGet (&pWlanDev->netPool, M_DONTWAIT,                             MT_DATA)) == NULL)        {        netClBlkFree (&pWlanDev->netPool, pClBlk);        netClFree (&pWlanDev->netPool, (UCHAR *)pRxPacket);                        WLAN_DEBUG(DEBUG_ERROR, ("intPrismHostApReceiveData: Error getti"                                 "ng MBlk\n"));        return ERROR;        }                if (netClBlkJoin(pClBlk, (char*)pRxPacket,                      pWlanHostAp->clDescTbl.clSize,                     NULL, 0, 0, 0) == NULL)        {        WLAN_DEBUG(DEBUG_ERROR, ("intPrismHostApReceiveData: Error in "                                 "netClBlkJoin\n"));        return ERROR;        }                if (netMblkClJoin (pMBlk, pClBlk) == NULL)        {        WLAN_DEBUG(DEBUG_ERROR, ("intPrismHostApReceiveData: Error in "                                 "netMblkClJoin\n"));        return ERROR;        }                /* Check if host-decrypt needs to be done on this packet */    if ((pWlanHostAp->hostDecrypt == 1) &&         ((pRxFrame->frameCtl & WLAN_FCTL_WEP) != 0))        {        if ((pRxFrame = (WLAN_RX_FRAME *)intPrismHostApPacketDecrypt(pWlanDev,                                                  (UINT8 *) pRxPacket->pData,                                                  (UINT32 *) &pRxPacket->length,                                                  pSta))             == NULL)            {            WLAN_DEBUG(DEBUG_INFO, ("intPrismHostApReceiveData: Host "                                     "decrypt failed\n"));            netMblkClFree(pMBlk);            return ERROR;            }        }    pMBlk->mBlkHdr.mData = (char *)((char*)pRxFrame + sizeof(WLAN_RX_FRAME) -                                     WLAN_EH_SIZE);    pMBlk->mBlkHdr.mLen = pRxPacket->length - sizeof (WLAN_RX_FRAME)         + WLAN_EH_SIZE;    pMBlk->mBlkHdr.mFlags |= M_PKTHDR;    pMBlk->mBlkPktHdr.len = pRxPacket->length - sizeof (WLAN_RX_FRAME)         + WLAN_EH_SIZE;    END_ERR_ADD (&pWlanDev->endObj, MIB2_IN_UCAST, +1);    /* Check if this packet is destined for a source that's on our    wireless network */    pSta = intPrismHostApStaLookup(pRxFrame->addr3);    if (pSta != NULL)        {        WLAN_DEBUG(DEBUG_INFO,("intPrismHostApReceiveData: Sending packet "                               "to known station\n"));        /* We know about the destination.  Now check if it's on our  

⌨️ 快捷键说明

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