📄 dot11smeibsslib.c
字号:
length = pMblk->mBlkHdr.mLen; /* Only pass if we're doing a scan, or if this is a member of our BSS */ if (!((pIbss->state == DOT11_IBSS_STATE_SEARCHING) || ((pIbss->state == DOT11_IBSS_STATE_CONNECTED) && (bcmp((char *)DOT11_DEFAULT_BSS->bssid, (char *)pHeader->addr3, DOT11_ADDR_LEN) == 0)) || ((pIbss->state == DOT11_IBSS_STATE_SYNC) && (bcmp((char *)DOT11_DEFAULT_BSS->bssid, (char *)pHeader->addr3, DOT11_ADDR_LEN) == 0)))) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11SmeIbssBeaconReceive: Not for our BSSID\n", 0,0,0,0,0,0)); netMblkClChainFree(pMblk); return ERROR; } /* Ensure that the packet has at least a Timestamp field, a Beacon Rate field, a Capabilities field and an SSID (can be NULL, ie length of 0)*/ if (length < (sizeof(DOT11_HEADER)+sizeof(DOT11_TIMESTAMP) + sizeof(DOT11_BEACON_RATE) + sizeof(DOT11_CAPABILITIES) + DOT11_IE_HEADER_SIZE)) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11SmeIbssBeaconScanReceive: Invalid packet!\n", 0,0,0,0,0,0)); netMblkClChainFree(pMblk); return ERROR; } /* Grab the mutex for the KSL */ if (pDot11->sme->ksl.lock(pDot11) != OK) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_SME, ("dot11SmeIbssProbeReqReceive: Cannot get KSL lock\n", 0,0,0,0,0,0)); netMblkClChainFree(pMblk); return ERROR; } /* Determine if this is the first time we've gotten this beacon/probe. This allows us to only copy the parameters over once */ if (pDot11->sme->ksl.lookup(pDot11, pHeader->addr2) == NULL) { newKsl = TRUE; } else { newKsl = FALSE; } /* See if there is a KSL entry, or create one if not */ if ((pKsl = dot11SmeIbssKslUpdate(pDot11, pHeader)) == NULL) { /* Error message would have been handled at upper layer */ netMblkClChainFree(pMblk); pDot11->sme->ksl.unlock(pDot11); return ERROR; } /* Update the KSL entry with any information in the detected beacon or probe response. Process the fixed fields first, then the IEs*/ /* If this is a beacon, grab their TSF as well as our own for later comparisons. Probe responses have timestamps too, but this is of no use to use since it's the beacons we need to sync to.*/ bcopy((char *)(pCluster + sizeof(DOT11_HEADER)), (char *)&pKsl->type.ibss.lastBeaconTsf, sizeof(DOT11_TIMESTAMP)); pDot11->hdd->tsfGet(pDot11, &pKsl->type.ibss.ourTsf); if (newKsl || (!pKsl->type.ibss.ratesUpdated)) { /* Start at the beacon interval, which is after the 802.11 header and the timestamp */ pBug = pCluster + sizeof(DOT11_HEADER) + sizeof(DOT11_TIMESTAMP); /* Check out the beacon interval. If it is not the same as the one that we are using, then an adjustment is necessary if we are connected. */ pKsl->type.ibss.beaconInterval = DOT11_LE_TO_CPU_16(*(UINT16 *)pBug); pBug += sizeof(DOT11_BEACON_RATE); /* Get the capabilities field in case we need it later */ pKsl->capabilities = DOT11_LE_TO_CPU_16(*(UINT16 *)pBug); pBug += sizeof(DOT11_CAPABILITIES); /* Get the SSID */ pSsid = (DOT11_IE_SSID *)pBug; bcopy(pSsid->ssid, pKsl->ssid, min(DOT11_SSID_LEN, pSsid->length)); pKsl->ssid[min(DOT11_SSID_LEN,pSsid->length)] = 0x00; pBug += pSsid->length + DOT11_IE_HEADER_SIZE; pKsl->type.ibss.channel = 0; pKsl->type.ibss.ssi = ssi; /* Parse through the rest of the IEs, ignoring any not present */ /* Continue processing IEs until done. If a particular IE is not present, then the information will not be entered */ pIe = (DOT11_IE_GENERIC *)pBug; while ((int)pIe < (int)(pCluster + length)) { switch(pIe->elementId) { case DOT11_ELEMID_SUPP_RATES: /* This is an element that appears before a TIM - fill in timIeOffset in case this is an active probe. */ pKsl->suppRates.length = pIe->length; bcopy((char *)&pIe->data[0], (char *)&pKsl->suppRates.rates[0], pIe->length); pKsl->type.ibss.ratesUpdated = TRUE; break; case DOT11_ELEMID_FH_PARAM: DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11SmeEssBeaconScanReceive: FH Param IE\n", 0,0,0,0,0,0)); break; case DOT11_ELEMID_DS_PARAM: DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11SmeEssBeaconScanReceive: DS Param IE\n", 0,0,0,0,0,0)); /* The DS Info IE contains the channel to be used. */ pKsl->type.ibss.channel = pIe->data[0]; break; case DOT11_ELEMID_CF_PARAM: DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11SmeEssBeaconScanReceive: CF Param IE\n", 0,0,0,0,0,0)); break; case DOT11_ELEMID_IBSS: DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11SmeEssBeaconScanReceive: IBSS IE\n", 0,0,0,0,0,0)); pKsl->type.ibss.atimWindow = DOT11_LE_TO_CPU_16(*(UINT16*)(&pIe->data[0])); break; case DOT11_ELEMID_COUNTRY: DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11SmeEssBeaconScanReceive: Country IE\n", 0,0,0,0,0,0)); break; case DOT11_ELEMID_ERP: DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11SmeEssBeaconScanReceive: ERP IE\n", 0,0,0,0,0,0)); break; case DOT11_ELEMID_EXT_RATES: bcopy((char *)&pIe->data[0], (char *)&pKsl->suppRates.rates[pKsl->suppRates.length], pIe->length); pKsl->suppRates.length += pIe->length; break; default: DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11SmeEssBeaconScanReceive: Unknown IE %d\n", pIe->elementId,0,0,0,0,0)); break; } /* Point pIe to the next IE */ pIe = (DOT11_IE_GENERIC *)(((UINT8 *)pIe) + DOT11_IE_HEADER_SIZE + pIe->length); } /* Fix for stations that don't include the DS_PARAM IE */ if (pKsl->type.ibss.channel == 0) { pKsl->type.ibss.channel = pDot11->hdd->curChannel; } /* Calculate the actual rates, which is the intersection of the remote station's supported rates, our supported rates and the allowed rates as set by the user */ if (dot11SmeActualRateCalc(pDot11, &pDot11->sme->suppRates, &pKsl->suppRates, &DOT11_DEFAULT_BSS->allowedRates, &pKsl->actualRates) != OK) { bcopy((char *)&pDot11->sme->suppRates, (char *)&pKsl->actualRates, pDot11->sme->suppRates.length); } } /* if (newKsl) */ /* Check if we are trying to syncronize. If so, this should become the beacon we sync to */ if ((pIbss->state == DOT11_IBSS_STATE_SYNC) && (!pIbss->syncBeacon)) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11SmeIbssBeaconReceives: SYNC!\n", 0,0,0,0,0,0)); pIbss->pKslIbss = pKsl; pIbss->syncBeacon = TRUE; dot11SmeIbssLinkEventNotify(pDot11, DOT11_IBSS_EV_SYNC_IBSS); } /* Release the mutex for the KSL */ if (pDot11->sme->ksl.unlock(pDot11) != OK) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_SME, ("dot11SmeIbssBeaconReceive: Unable to free KSL lock\n", 0,0,0,0,0,0)); dot11SmeIbssLinkEventNotify(pDot11, DOT11_IBSS_EV_RESET); netMblkClChainFree(pMblk); return ERROR; } netMblkClChainFree(pMblk); return OK; }/***************************************************************************** dot11SmeIbssProbeReqReceive - Handles an incoming Probe Request** This routine handles the reception of a probe request from another station.* Once we have determined that they are trying to find the IBSS that we are* connected to, we send out a probe request of our own in order to grab the * rates** RETURNS: OK or ERROR** ERRNO: N/A*/LOCAL STATUS dot11SmeIbssProbeReqReceive ( DOT11_FW * pDot11, /* Ptr to DOT11 framework root obj */ M_BLK_ID pMblk, /* ClBlk with received packet */ UINT32 rate, /* Rate pkt was received at */ UINT8 ssi /* SSI of received packet */ ) { DOT11_IBSS_OBJ * pIbss; /* Ptr to IBSS data */ UINT8 * pCluster; /* Cluster containing rx pkt */ DOT11_HEADER * pHeader; /* 802.11 header */ DOT11_IE_SSID * pSsid; /* Ptr to ssid IE in probe req */ DOT11_KSL_ENTRY * pKsl; /* KSL entry for source station */ DOT11_IE_GENERIC * pIe; /* Generic IE for parsing */ UINT32 curLen; /* Used for searching for EXT RATE */ UINT32 length; DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11SmeIbssProbeReqReceive: Started\n", 0,0,0,0,0,0)); /* Double check the length to ensure we at least have an 802.11 header and the start of an SSID IE */ if (pMblk->mBlkHdr.mLen < sizeof(DOT11_HEADER) + DOT11_IE_HEADER_SIZE) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_SME, ("dot11SmeIbssProbeReqReceive: Packet too small. " "Discarding.\n", 0,0,0,0,0,0)); netMblkClChainFree(pMblk); return ERROR; } pIbss = &pDot11->sme->type.ibss; pCluster = (UINT8 *)pMblk->mBlkHdr.mData; pHeader = (DOT11_HEADER *)pCluster; pSsid = (DOT11_IE_SSID *)(pCluster + sizeof(DOT11_HEADER)); length = pMblk->mBlkHdr.mLen; /* We only care about the probe request if the destination and bssid are broadcast and the SSID is any or ours (must compare length as well as content) */ if (!((bcmp((char *)dot11BcastMAC, (char *)pHeader->addr1, DOT11_ADDR_LEN) == 0) && ( (pSsid->length == 0) || ((strlen(pDot11->desiredSsid) == pSsid->length) && (bcmp(pSsid->ssid, pDot11->desiredSsid, min(DOT11_SSID_LEN, pSsid->length)) == 0))) )) { DOT11_LOG(DOT11_DEBUG_FLOOD, DOT11_AREA_SME, ("dot11SmeIbssProbeReqReceive: Probe Req for different " "SSID\n", (int)pSsid->ssid, 0, 0, 0, 0, 0)); netMblkClChainFree(pMblk); return OK; } /* The only station in an IBSS that should be responding to a probe request is the last station to transmit a beacon (all stations contend for the TBTT) */ /* Send out a probe response */ if (dot11SmeIbssProbeRespSend(pDot11, pHeader->addr2) == ERROR) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_SME, ("dot11SmeIbssProbeReqReceive: Failed send probe resp\n", 0,0,0,0,0,0)); /* There's nothing we can do */ } /* See if there is a KSL entry, or create one if not */ if ((pKsl = dot11SmeIbssKslUpdate(pDot11, pHeader)) == NULL) { /* Error message would have been handled at upper layer */ netMblkClChainFree(pMblk); return ERROR; } /* Grab the KSL lock */ if (pDot11->sme->ksl.lock(pDot11) == ERROR) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_SME, ("dot11SmeIbssProbeReqReceive: Cannot get KSL lock\n", 0,1,2,3,4,5)); dot11SmeIbssLinkEventNotify(pDot11, DOT11_IBSS_EV_RESET); netMblkClChainFree(pMblk); return ERROR; } pKsl->suppRates.length = 0; /* Grab the rate control data from the received packet, if any */ if (length > sizeof(DOT11_HEADER) + pSsid->length + DOT11_IE_HEADER_SIZE) { pIe = (DOT11_IE_GENERIC *)(pCluster + sizeof(DOT11_HEADER) + pSsid->length + DOT11_IE_HEADER_SIZE); /* Check if the next IE after the SSID is the supported rates IE. It should be, but better safe than segfaulted */ if (pIe->elementId == DOT11_ELEMID_SUPP_RATES) { bcopy((char *)&pIe->data[0], (char *)&pKsl->suppRates.rates[0], min(DOT11_RATE_MAX, pIe->length)); pKsl->suppRates.length = min(DOT11_RATE_MAX, pIe->length); pKsl->type.ibss.ratesUpdated = TRUE; } /* See if there are any additional IEs, and go through them looking for the extended rates IE. It usually follows the supported rates IE in a probe request, but won't in an 802.11d aware station. */ curLen = sizeof(DOT11_HEADER) + pSsid->length + DOT11_IE_HEADER_SIZE + pIe->length + DOT11_IE_HEADER_SIZE; while (curLen <= length) { pIe = (DOT11_IE_GENERIC *)(pCluster + curLen); if (pIe->elementId == DOT11_ELEMID_EXT_RATES) { /* If this is the extended rates ie, add them to the end of our rate list and break out */ bcopy((char *)&pIe->data[0], (char *)&pKsl->suppRates.rates[pKsl->suppRates.length], pIe->length);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -