📄 dot11ksllib.c
字号:
/* dot11KslLib.c - Implements the Known Station List library *//* * Copyright (c) 2004-2006 Wind River Systems, Inc. * * The right to copy, distribute, modify or otherwise make use * of this software may be licensed only pursuant to the terms * of an applicable Wind River license agreement. *//* Modification History--------------------02v,15mar06,rb Fix for SPR 118966 - ACL and WPA/RSN do not work together02u,16jan06,rb Added diagnostic code to show number of packets on PM queue02t,12dec05,rb Fix to SPR 115230 - Shared keys getting deleted as though they were unicast03a,28feb06,rb Merge from 2.1.2 bugfix branch02z,02feb06,rb Implement mSSID feature02y,18nov05,rb Fix to SPR 115230 - Shared keys erroneously deleted when KSL entry pruned02x,28sep05,rb Update header comments and copyright02w,28sep05,rb Fix APIGEN Errors02v,23sep05,rb Fix to B0174 - Station does not leave RSN/WPA cleanly02u,23sep05,rb Fix for B0171 - AP keyslot corruption02t,01sep05,rb Improved show routine with 802.11d info02s,14jul05,rb Implemented KSL memory pool to reduce memory fragmentation02r,29jun05,rb Ensure that timers are deleted when removing KSL entries02q,14jun05,rb Changes to implement global four-way timer02p,01jun05,rb Fix for bug B0464: Handoff takes 3 min02o,20may05,rb Backed out changes requiring WEP stas to assoc with WEP APs02n,18may05,rb Fix for bug B0367 - TSN Sta cannot connect to WEP AP02m,27apr05,rb Updated external routines with KERNEL tags02l,22apr05,rb Changed to new authCallback.02k,14apr05,rb Fix for bug B0210: Station can join AP even if groupPol not in02j,29mar05,rb Demoted debug level02i,09mar05,rb Fix for bug B0056: dot11KslShow() should take the instance number not the cookie02h,03mar05,rb Changes for RSNLib codereview02g,04feb05,rb Added B/G compatibility mode02f,28jan05,rb Stop disassociating stations that aren't assoc on kslCleanup02e,19jan05,rb Expanded show routine to display 802.1X stats02d,12jan05,rb Added authCallback notification to kslPrune()02c,20dec04,rb Improved TSN Handling02b,04nov04,rb Enforce security policies while making SSID decision02a,25aug04,rb Wind River Wireless Ethernet Driver 2.0 FCS*//*DESCRIPTIONThe Known Station List is a list that keeps track of all stations known tothis entity. Any STA that has sent a packet that has been received by this instance is recorded here. The KSL is also used to perform scans, since theresponses to the scan will be heard by the receive routine.SEE ALSOWind Net 802.11 Station 2.0 High Level Design DocumentINCLUDE FILES: drv/wlan/dot11Lib.h*/#include <vxWorks.h>#include <endLib.h>#include <stdio.h>#include <muxLib.h>#include <tickLib.h>#include <etherMultiLib.h>#include "drv/wlan/dot11Lib.h"#include "drv/wlan/dot11TimerLib.h"/* Forward declarations */STATUS dot11KslShow(int unitNum);LOCAL STATUS dot11KslPrint(DOT11_FW * pDot11, DOT11_KSL_ENTRY * pKsl);LOCAL STATUS dot11KslFree( DOT11_FW * pDot11);LOCAL DOT11_KSL_ENTRY * dot11KslEntryAlloc(DOT11_FW * pDot11);LOCAL DOT11_KSL_ENTRY * dot11KslEntryForceFree(DOT11_FW * pDot11);LOCAL STATUS dot11KslEntryFree(DOT11_FW * pDot11, DOT11_KSL_ENTRY * pKsl);LOCAL STATUS dot11KslLock(DOT11_FW * pDot11);LOCAL STATUS dot11KslUnlock(DOT11_FW * pDot11);LOCAL DOT11_KSL_ENTRY * dot11KslLookup(DOT11_FW * pDot11, UINT8 * macAddr);LOCAL DOT11_KSL_ENTRY * dot11KslSSIDLookup(DOT11_FW * pDot11, char * ssid, int dot11Mode);LOCAL DOT11_KSL_ENTRY * dot11KslAdd(DOT11_FW * pDot11,UINT8 * macAddr);LOCAL STATUS dot11KslDelete(DOT11_FW * pDot11, DOT11_KSL_ENTRY * pKsl);LOCAL STATUS dot11KslFlush(DOT11_FW * pDot11);LOCAL DOT11_KSL_ENTRY * dot11KslRxUpdate(DOT11_FW * pDot11, UINT8 * macAddr, int rate, int SSI);LOCAL DOT11_KSL_ENTRY * dot11KslTxUpdate(DOT11_FW * pDot11, UINT8 * macAddr, BOOL success, UINT32 nRetries, UINT32 ackSSI);LOCAL STATUS dot11KslCleanup(DOT11_FW * pDot11);LOCAL STATUS dot11KslLastAttemptReset(DOT11_FW * pDot11);LOCAL INT32 dot11KslPmQCount(DOT11_FW * pDot11, DOT11_KSL_ENTRY * pKsl);/***************************************************************************** dot11KslInit - Initialize the Known Stations List** Initializes the KSL. It should be called from the specific SME * initialization utility - dot11SmeEssInit() or some such.* ** RETURNS: OK or ERROR** ERRNO: N/A** \NOMANUAL**/STATUS dot11KslInit ( DOT11_FW * pDot11 /* Pointer to device structure */ ) { int i; DOT11_KSL_ENTRY * pKslPool; if ((pDot11->sme->ksl.lockSem = semMCreate(SEM_Q_FIFO)) == NULL) { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_INIT, ("dot11KslInit: Error initializing lock semaphore\n", 0,0,0,0,0,0)); return ERROR; } if ((pDot11->sme->ksl.poolSem = semMCreate(SEM_Q_FIFO)) == NULL) { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_INIT, ("dot11KslInit: Error initializing pool semaphore\n", 0,0,0,0,0,0)); semDelete(pDot11->sme->ksl.lockSem); return ERROR; } for (i=0; i<DOT11_KSL_MAX_HASH; i++) { pDot11->sme->ksl.list[i] = NULL; } pDot11->sme->ksl.free = dot11KslFree; pDot11->sme->ksl.show = dot11KslShow; pDot11->sme->ksl.lock = dot11KslLock; pDot11->sme->ksl.unlock = dot11KslUnlock; pDot11->sme->ksl.lookup = dot11KslLookup; pDot11->sme->ksl.flush = dot11KslFlush; pDot11->sme->ksl.ssidLookup = dot11KslSSIDLookup; pDot11->sme->ksl.rxUpdate = dot11KslRxUpdate; pDot11->sme->ksl.txUpdate = dot11KslTxUpdate; pDot11->sme->ksl.add = dot11KslAdd; pDot11->sme->ksl.delete = dot11KslDelete; pDot11->sme->ksl.lastAttemptReset = dot11KslLastAttemptReset; /* Allocate and clear the KSL pool */ if ((pKslPool = (DOT11_KSL_ENTRY *)calloc(sizeof(DOT11_KSL_ENTRY), DOT11_KSL_POOL_SIZE)) == NULL) { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_INIT, ("dot11KslInit: could not allocate %d bytes for KSL pool of" " %d entries\n", sizeof(DOT11_KSL_ENTRY) * DOT11_KSL_POOL_SIZE, DOT11_KSL_POOL_SIZE,0,0,0,0)); semDelete(pDot11->sme->ksl.poolSem); semDelete(pDot11->sme->ksl.lockSem); return ERROR; } /* Point the head of the free pool to the first entry in the pool */ pDot11->sme->ksl.pPool = &pKslPool[0]; pDot11->sme->ksl.pFreeEntry = &pKslPool[0]; pDot11->sme->ksl.poolUsed = 0; pDot11->sme->ksl.poolMaxUsed = 0; /* Link all of the entries in the pool together */ for (i=0; i<DOT11_KSL_POOL_SIZE; i++) { pKslPool[i].pNext = &pKslPool[i + 1]; } pKslPool[DOT11_KSL_POOL_SIZE-1].pNext = NULL; /* Start the cleanup timer */ pDot11->sme->ksl.cleanupTimer = dot11TimerAdd(DOT11_KSL_CLEANUP_TIME, (FUNCPTR)dot11KslCleanup, (int)pDot11, 0); return OK; }/***************************************************************************** dot11KslFree - Frees all memory associated with the KSL** ** RETURNS: OK or ERROR** ERRNO: N/A*/LOCAL STATUS dot11KslFree ( DOT11_FW * pDot11 /* Pointer to device structure */ ) { if (pDot11 == NULL) { return ERROR; } (void) dot11TimerDel(pDot11->sme->ksl.cleanupTimer); dot11KslFlush(pDot11); if (semDelete(pDot11->sme->ksl.lockSem) != OK) { return ERROR; } /* Free up the entire KSL pool */ free(pDot11->sme->ksl.pPool); return OK; }/***************************************************************************** dot11KslEntryAlloc - Allocates a KSL entry from the free pool ** This routine allocates a KSL entry from the free pool. If none are * available in the free pool, it will examine the KSL table and choose the * oldest entry in that table for deletion, and then return that entry.** RETURNS: Pointer to KSL_ENTRY or NULL on error** ERRNO: N/A*/LOCAL DOT11_KSL_ENTRY * dot11KslEntryAlloc ( DOT11_FW * pDot11 /* Pointer to device structure */ ) { DOT11_KSL_ENTRY * pKsl; if (semTake(pDot11->sme->ksl.poolSem, DOT11_KSL_ALLOC_TIME) != OK) { return NULL; } /* Check if there are any entries in the pool. If so, then the task is easy - pul one of the entries out of the pool and return it */ if (pDot11->sme->ksl.pFreeEntry != NULL) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11KslEntryAlloc: allocating from pool!\n",0,0,0,0,0,0)); pKsl = pDot11->sme->ksl.pFreeEntry; pDot11->sme->ksl.pFreeEntry = pKsl->pNext; } else { if ((pKsl = dot11KslEntryForceFree(pDot11)) == NULL) { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_SME, ("dot11KslEntryAlloc: cannot get free entry!!\n", 0,0,0,0,0,0)); return NULL; } } if ((++pDot11->sme->ksl.poolUsed) > pDot11->sme->ksl.poolMaxUsed) { pDot11->sme->ksl.poolMaxUsed = pDot11->sme->ksl.poolUsed; } semGive(pDot11->sme->ksl.poolSem); return pKsl; }/***************************************************************************** dot11KslEntryForceFree - Finds a KSL entry to be deallocated** This routine returns the address of a free KSL entry for use by * dot11KslEntryAlloc(). It is called when there are no free entries, and one* needs to be forceably cleared. The algorithm used to free up an entry is as* follows* 1. Go through KSL looking for useless or old entries. Build list of * eight candidates.* 2. If there are no candidates, choose the oldest entry in the KSL* 3. Otherwise, choose the oldest candidate** RETURNS: OK or ERROR** ERRNO: N/A*/LOCAL DOT11_KSL_ENTRY * dot11KslEntryForceFree ( DOT11_FW * pDot11 /* Pointer to device structure */ ) { DOT11_KSL_ENTRY * candidates[8]; /* List of candidates for deletion */ int numCandidates = 0; /* Number of candidates found */ int i; DOT11_KSL_ENTRY * pKsl; int hash; DOT11_KSL_ENTRY * pOldestKsl; DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_SME, ("dot11KslEntryAlloc: cannot get free entry!!\n", 0,0,0,0,0,0)); for (i=0; i<8; i++) { candidates[i] = NULL; } /* Go through the KSL until we have enough candidates or we hit the end of the list */ for (hash = 0; hash < DOT11_KSL_MAX_HASH; hash ++) { /* Start at the head of the hash bin */ pKsl = pDot11->sme->ksl.list[hash]; while (pKsl != NULL) { if ((tickGet() - pKsl->timestamp) > DOT11_KSL_MAX_AGE) { candidates[numCandidates++] = pKsl; } else if ((pKsl->pBss->secPol != 0) && (pKsl->secPol == 0)) { candidates[numCandidates++] = pKsl; } else if ((pKsl->pBss->secPol == 0) && (pKsl->secPol != 0)) { candidates[numCandidates++] = pKsl; } else if ((pDot11->dot11Mode == DOT11_MODE_ESS) || (pDot11->dot11Mode == DOT11_MODE_IBSS)) { if ((strlen(pDot11->desiredSsid) != 0) && (strlen(pKsl->ssid) != 0) && (bcmp(pDot11->desiredSsid, pKsl->ssid, min(strlen(pDot11->desiredSsid), strlen(pKsl->ssid))) != 0)) { candidates[numCandidates++] = pKsl; } } else if (pDot11->dot11Mode == DOT11_MODE_AP) { if ((!pKsl->type.sta.associated) && ((tickGet() - pKsl->timestamp) > DOT11_DEFAULT_AUTH_TIMEOUT)) { candidates[numCandidates++] = pKsl; } } pKsl = pKsl->pNext; } } /* Check if we found any obvious choices */ if (numCandidates > 0) { /* Start by assuming the first entry is the oldest */ pOldestKsl = candidates[0]; for (i=1; i<numCandidates; i++) { if (pOldestKsl->timestamp > candidates[i]->timestamp) { pOldestKsl=candidates[i]; } } } else { pOldestKsl = NULL; /* Find the absolute oldest entry in the KSL */ for (hash = 0; hash < DOT11_KSL_MAX_HASH; hash ++) { /* Start at the head of the hash bin */ pKsl = pDot11->sme->ksl.list[hash]; while (pKsl != NULL) { if (pOldestKsl == NULL) { pOldestKsl = pKsl; } else if (pOldestKsl->timestamp > pKsl->timestamp) { pOldestKsl = pKsl; } pKsl = pKsl->pNext; } } } return pOldestKsl; }/***************************************************************************** dot11KslEntryFree - Returns a KSL entry to the free pool** This routine returns a KSL entry to the free pool. ** RETURNS: OK or ERROR** ERRNO: N/A*/LOCAL STATUS dot11KslEntryFree ( DOT11_FW * pDot11, /* Pointer to device structure */ DOT11_KSL_ENTRY * pKsl /* KSL entry to delete */ ) { DOT11_KSL_ENTRY * pSearch; int hash; if (semTake(pDot11->sme->ksl.poolSem, DOT11_KSL_ALLOC_TIME) != OK) { return ERROR; } hash = DOT11_KSL_HASH(pKsl->macAddr); /* First, delink the KSL entry from the hash list */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -