📄 dot11ksllib.c
字号:
dot11KslLock(pDot11); /* There are three cases to consider when delinking from the hash list. The first is that this is the first (most likely only) entry in the hash list. In the second case, there are no entries in the appropriate bucket - this item was probably already deleted. In the third case, there are multiple entries in the hash bucket and this isn't the first one. It is not a fatal error if the KSL entry is now found in the hash list - some routines may remove the entry from the list before calling this routine. */ if ((pSearch = pDot11->sme->ksl.list[hash]) == pKsl) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11KslEntryFree: Hash bucket %d contains this entry. " "Pruning.\n", hash,0,0,0,0,0)); pDot11->sme->ksl.list[hash] = pKsl->pNext; } else if (pSearch == NULL) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11KslEntryFree: Hash bucket %d is EMPTY\n", DOT11_KSL_HASH(pKsl->macAddr),0,0,0,0,0)); } else { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11KslEntryFree: Hash bucket %d contains multiple " "entries\n",hash,0,0,0,0,0)); /* Spin through the bucket looking for the entry BEFORE the desired entry, so that we can prune the desired entry out. This algorithm works because the IF statements above guaranteed that (pSearch != NULL) and (pSearch != pKsl) */ while ((pSearch->pNext != NULL) && (pSearch->pNext != pKsl)) { pSearch = pSearch->pNext; } /* Trap the case where we reached the end of the list without a match */ if (pSearch->pNext == NULL) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11KslEntryFree: Hash bucket %d does not contain " "the desired entry\n", hash,0,0,0,0,0)); } else { /* Prune the match out */ pSearch->pNext = pKsl->pNext; } } dot11KslUnlock(pDot11); /* Check if there are any timers registered to this entry */ if (pKsl->eapolMsgTimer != 0) { dot11TimerDel(pKsl->eapolMsgTimer); pKsl->eapolMsgTimer = 0; } if (pKsl->fourWayGlobalTimer != 0) { dot11TimerDel(pKsl->fourWayGlobalTimer); pKsl->fourWayGlobalTimer = 0; } /* Check if this is a station that is currently associated or the current AP. If so, then send notifications before deleting the entry */ if (((pKsl->dot11Mode == DOT11_MODE_ESS) && (pKsl->type.sta.associated)) || ((pKsl->dot11Mode == DOT11_MODE_AP) && (bcmp((char *)pKsl->macAddr, (char *)pKsl->pBss->bssid, DOT11_ADDR_LEN) == 0))) { /* Let the association callback know that we're pruning this station */ (void) pDot11->sme->assocCallback(pDot11, pKsl, DOT1X_CALLBACK_DISASSOC); if (pKsl->type.sta.associated) { pDot11->sme->disassocSend(pDot11, pKsl->macAddr, DOT11_REASON_NO_LONGER_VALID, pKsl->pBss); } if (pKsl->type.sta.authenticated) { pDot11->sme->deauthSend(pDot11, pKsl->macAddr, DOT11_REASON_NO_LONGER_VALID, pKsl->pBss); } } /* Remove any existing unicast keys */ if ((pKsl->uniDecryptIndex != pKsl->uniEncryptIndex) && (pKsl->uniDecryptIndex != DOT11_KEYINDEX_NONE) && (pKsl->uniDecryptIndex >= DOT11_MAX_DEFAULT_KEY)) { if (pDot11->hdd->hwEncryptionKeyDel(pDot11, pKsl->uniDecryptIndex) != OK) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_SME, ("dot11KslEntryFree: Unable to free key " "%d\n", pKsl->uniEncryptIndex, 0,0,0,0,0)); } pKsl->uniDecryptIndex = DOT11_KEYINDEX_NONE; } if ((pKsl->uniEncryptIndex != DOT11_KEYINDEX_NONE) && (pKsl->uniEncryptIndex >= DOT11_MAX_DEFAULT_KEY)) { if (pDot11->hdd->hwEncryptionKeyDel(pDot11, pKsl->uniEncryptIndex) != OK) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_SME, ("dot11KslEntryFree: Unable to free key " "%d\n", pKsl->uniEncryptIndex, 0,0,0,0,0)); } pKsl->uniEncryptIndex = DOT11_KEYINDEX_NONE; pKsl->uniDecryptIndex = DOT11_KEYINDEX_NONE; pKsl->uniEncryptType = DOT11_KEY_TYPE_NONE; } pKsl->fourWayState = DOT11_FOURWAY_INIT; /* Then, link it back into the pool */ pKsl->pNext = pDot11->sme->ksl.pFreeEntry; pDot11->sme->ksl.pFreeEntry = pKsl; pDot11->sme->ksl.poolUsed--; semGive(pDot11->sme->ksl.poolSem); return OK; } /***************************************************************************** dot11KslLock - Takes the mutex on the KSL** This routine takes the mutex semaphore on the KSL. While the calling* function has the semaphore, no one else can use the KSL. This call should* always be paired with an dot11KslUnlock() call.** RETURNS: OK or ERROR** ERRNO: N/A*/LOCAL STATUS dot11KslLock ( DOT11_FW * pDot11 /* Pointer to device structure */ ) { STATUS status; DOT11_LOG(DOT11_DEBUG_FLOOD, DOT11_AREA_SME, ("dot11KslLock: LOCK\n", 0,0,0,0,0,0)); status = semTake(pDot11->sme->ksl.lockSem, sysClkRateGet() / 15); if (status != OK) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_SME, ("dot11KslLock: Unable to get lock (semid=%x), current " "tid=%x\n",(int)pDot11->sme->ksl.lockSem,taskIdSelf(), 0,0,0,0)); } return status; }/***************************************************************************** dot11KslUnlock - Releases the KSL mutex** This semaphore releases control of the KSL mutex, allowing other tasks to * read and write to it.** RETURNS: OK or ERROR** ERRNO: N/A*/LOCAL STATUS dot11KslUnlock ( DOT11_FW * pDot11 /* Pointer to device structure */ ) { DOT11_LOG(DOT11_DEBUG_FLOOD, DOT11_AREA_SME, ("dot11KslUnlock: UNLOCK\n", 0,0,0,0,0,0)); return semGive(pDot11->sme->ksl.lockSem); }/***************************************************************************** dot11KslFlush - Erases all entries in the KSL** This routine is typically called on deinitialization to ensure there is* no memory allocated in the KSL, or on initialization to ensure there is* a fresh, empty list to work from.** RETURNS: OK or ERROR** ERRNO: N/A*/LOCAL STATUS dot11KslFlush ( DOT11_FW * pDot11 /* Pointer to device structure */ ) { int i; DOT11_KSL_ENTRY * pKsl; DOT11_KSL_ENTRY * pLastKsl; if (dot11KslLock(pDot11) != OK) { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_SME, ("dot11KslFlush: Cannot get lock\n", 0,0,0,0,0,0)); return ERROR; } /* Go through each hash bucket */ for (i=0; i<DOT11_KSL_MAX_HASH; i++) { /* Delete all entries in the hash bucket, except for ACL or WEPKM entries, which need to be persistent */ pKsl = pDot11->sme->ksl.list[i]; pLastKsl = pKsl; while (pKsl != NULL) { if ((pKsl->accessControlled) || (pKsl->wepKeyMapping)) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11KslFlush: Preserving " DOT11_MAC_ADDR_STR "\n", DOT11_MAC_ADDR(pKsl->macAddr))); /* Preserve encryption keys for WEP key mapping */ if (!pKsl->wepKeyMapping) { /* Remove any existing unicast keys */ if ((pKsl->uniDecryptIndex != pKsl->uniEncryptIndex) && (pKsl->uniDecryptIndex != DOT11_KEYINDEX_NONE) && (pKsl->uniDecryptIndex >= DOT11_MAX_DEFAULT_KEY)) { if (pDot11->hdd->hwEncryptionKeyDel(pDot11, pKsl->uniDecryptIndex) != OK) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_SME, ("dot11KslFlush: Unable to free key " "%d\n", pKsl->uniEncryptIndex, 0,0,0,0,0)); } pKsl->uniDecryptIndex = DOT11_KEYINDEX_NONE; } if ((pKsl->uniEncryptIndex != DOT11_KEYINDEX_NONE) && (pKsl->uniEncryptIndex >= DOT11_MAX_DEFAULT_KEY)) { if (pDot11->hdd->hwEncryptionKeyDel(pDot11, pKsl->uniEncryptIndex) != OK) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_SME, ("dot11KslFlush: Unable to free key " "%d\n", pKsl->uniEncryptIndex, 0,0,0,0,0)); } pKsl->uniEncryptIndex = DOT11_KEYINDEX_NONE; pKsl->uniDecryptIndex = DOT11_KEYINDEX_NONE; pKsl->uniEncryptType = DOT11_KEY_TYPE_NONE; } } /* Check if there are any timers registered to this entry */ if (pKsl->eapolMsgTimer != 0) { dot11TimerDel(pKsl->eapolMsgTimer); pKsl->eapolMsgTimer = 0; } if (pKsl->fourWayGlobalTimer != 0) { dot11TimerDel(pKsl->fourWayGlobalTimer); pKsl->fourWayGlobalTimer = 0; } /* Check if this is a station that is currently associated or the current AP. If so, then send notifications */ if (((pKsl->dot11Mode == DOT11_MODE_ESS) && (pKsl->type.sta.associated)) || ((pKsl->dot11Mode == DOT11_MODE_AP) && (bcmp((char *)pKsl->macAddr, (char *)pKsl->pBss->bssid, DOT11_ADDR_LEN) == 0))) { /* Let the association callback know that we're pruning this station */ (void) pDot11->sme->assocCallback(pDot11, pKsl, DOT1X_CALLBACK_DISASSOC); if (pKsl->type.sta.associated) { pDot11->sme->disassocSend(pDot11, pKsl->macAddr, DOT11_REASON_NO_LONGER_VALID, pKsl->pBss); } if (pKsl->type.sta.authenticated) { pDot11->sme->deauthSend(pDot11, pKsl->macAddr, DOT11_REASON_NO_LONGER_VALID, pKsl->pBss); } pKsl->type.sta.authenticated = FALSE; pKsl->type.sta.associated = FALSE; } pKsl = pKsl->pNext; } else { if (pKsl == pDot11->sme->ksl.list[i]) { pDot11->sme->ksl.list[i] = pKsl->pNext; dot11KslEntryFree(pDot11, pKsl); pKsl = pDot11->sme->ksl.list[i]; pLastKsl = pKsl; } else { pLastKsl->pNext = pKsl->pNext; dot11KslEntryFree(pDot11, pKsl); pKsl = pLastKsl->pNext; } } } } if (dot11KslUnlock(pDot11) != OK) { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_SME, ("dot11KslFlush: Cannot free lock\n", 0,0,0,0,0,0)); return ERROR; } return OK; }/***************************************************************************** dot11KslLookup - Find an existing entry in the KSL** This routine finds an entry in the KSL. Entries are uniquely specified by* the operating mode in which they were found and is currently used.** RETURNS: Pointer to KSL entry, or NULL if not found** ERRNO: N/A*/LOCAL DOT11_KSL_ENTRY * dot11KslLookup ( DOT11_FW * pDot11, /* Pointer to device structure */ UINT8 * macAddr /* MAC address of station to look for */ ) { int hash; DOT11_KSL_ENTRY * pKsl; /* Prevent the KSL from changing while we're looking for an entry */ if (dot11KslLock(pDot11) != OK) { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_INIT, ("dot11KslFlush: Cannot get lock\n", 0,0,0,0,0,0)); return NULL; } hash = DOT11_KSL_HASH(macAddr); pKsl = pDot11->sme->ksl.list[hash]; /* Now look for the right thing . . . */ while ((pKsl != NULL) && ((bcmp((char*)macAddr, (char*)pKsl->macAddr, DOT11_ADDR_LEN) != 0))) { pKsl = pKsl->pNext; } if (pKsl == NULL) { DOT11_LOG(DOT11_DEBUG_FLOOD, DOT11_AREA_SME, ("dot11KslLookup: Entry " DOT11_MAC_ADDR_STR " not" " found\n", DOT11_MAC_ADDR(macAddr))); } if (dot11KslUnlock(pDot11) != OK) { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_INIT, ("dot11KslFlush: Cannot free lock\n", 0,0,0,0,0,0)); /* No point in returning NULL, since we may already have a valid KSL entry */ } return pKsl; }/***************************************************************************** dot11KslAdd - Creates a new record in the KSL** This routine assumes that the user has run dot11KslLookup and the the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -