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 + -
显示快捷键?