/* * Description: * get each stations encryption key * * Parameters: * In: * pDevice - * param - * Out: * * Return Value: * */ static int hostap_get_encryption(struct vnt_private *pDevice, struct viawget_hostapd_param *param, int param_len) { struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; int ret = 0; int ii; s32 iNodeIndex = 0; param->u.crypt.err = 0; if (is_broadcast_ether_addr(param->sta_addr)) { iNodeIndex = 0; } else { if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &iNodeIndex) == false) { param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); return -EINVAL; } } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: %d\n", iNodeIndex); memset(param->u.crypt.seq, 0, 8); for (ii = 0 ; ii < 8 ; ii++) { param->u.crypt.seq[ii] = (BYTE)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8); } return ret; }
/* * Description: * get each stations encryption key * * Parameters: * In: * pDevice - * param - * Out: * * Return Value: * */ static int hostap_get_encryption(PSDevice pDevice, struct viawget_hostapd_param *param, int param_len) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int ret = 0; int ii; int iNodeIndex =0; param->u.crypt.err = 0; if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { iNodeIndex = 0; } else { if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &iNodeIndex) == FALSE) { param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); return -EINVAL; } } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: %d\n", iNodeIndex); memset(param->u.crypt.seq, 0, 8); for (ii = 0 ; ii < 8 ; ii++) { param->u.crypt.seq[ii] = (BYTE)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8); } return ret; }
/* * Description: * remove station function supported for hostap daemon * * Parameters: * In: * pDevice - * param - * Out: * * Return Value: * */ static int hostap_remove_sta(struct vnt_private *pDevice, struct viawget_hostapd_param *param) { unsigned int uNodeIndex; if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) { BSSvRemoveOneNode(pDevice, uNodeIndex); } else { return -ENOENT; } return 0; }
/* * Description: * remove station function supported for hostap deamon * * Parameters: * In: * pDevice - * param - * Out: * * Return Value: * */ static int hostap_remove_sta(PSDevice pDevice, struct viawget_hostapd_param *param) { UINT uNodeIndex; if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) { BSSvRemoveOneNode(pDevice, uNodeIndex); } else { return -ENOENT; } return 0; }
/* * Description: * add a station from hostap daemon * * Parameters: * In: * pDevice - * param - * Out: * * Return Value: * */ static int hostap_add_sta(PSDevice pDevice, struct viawget_hostapd_param *param) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); unsigned int uNodeIndex; if (!BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) { BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex); } memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, param->sta_addr, WLAN_ADDR_LEN); pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC; pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = param->u.add_sta.capability; // TODO listenInterval // pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = 1; pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = FALSE; pMgmt->sNodeDBTable[uNodeIndex].bySuppRate = param->u.add_sta.tx_supp_rates; // set max tx rate pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; // set max basic rate pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate = RATE_2M; // Todo: check sta preamble, if ap can't support, set status code pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(pMgmt->sNodeDBTable[uNodeIndex].wCapInfo); pMgmt->sNodeDBTable[uNodeIndex].wAID = (WORD)param->u.add_sta.aid; pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Add STA AID= %d \n", pMgmt->sNodeDBTable[uNodeIndex].wAID); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n", param->sta_addr[0], param->sta_addr[1], param->sta_addr[2], param->sta_addr[3], param->sta_addr[4], param->sta_addr[5] ) ; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Max Support rate = %d \n", pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); return 0; }
/* * Description: * set station flag * * Parameters: * In: * pDevice - * param - * Out: * * Return Value: * */ static int hostap_set_flags_sta(struct vnt_private *pDevice, struct viawget_hostapd_param *param) { struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; unsigned int uNodeIndex; if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) { pMgmt->sNodeDBTable[uNodeIndex].dwFlags |= param->u.set_flags_sta.flags_or; pMgmt->sNodeDBTable[uNodeIndex].dwFlags &= param->u.set_flags_sta.flags_and; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x\n", (unsigned int) pMgmt->sNodeDBTable[uNodeIndex].dwFlags); } else { return -ENOENT; } return 0; }
static int hostap_get_info_sta(struct vnt_private *pDevice, struct viawget_hostapd_param *param) { struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; unsigned int uNodeIndex; if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) { param->u.get_info_sta.inactive_sec = (jiffies - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ; //param->u.get_info_sta.txexc = pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts; } else { return -ENOENT; } return 0; }
static int hostap_get_info_sta(PSDevice pDevice, struct viawget_hostapd_param *param) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); unsigned int uNodeIndex; if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) { param->u.get_info_sta.inactive_sec = (jiffies - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ; //param->u.get_info_sta.txexc = pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts; } else { return -ENOENT; } return 0; }
/* * Description: * set station flag * * Parameters: * In: * pDevice - * param - * Out: * * Return Value: * */ static int hostap_set_flags_sta(PSDevice pDevice, struct viawget_hostapd_param *param) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); UINT uNodeIndex; if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) { pMgmt->sNodeDBTable[uNodeIndex].dwFlags |= param->u.set_flags_sta.flags_or; pMgmt->sNodeDBTable[uNodeIndex].dwFlags &= param->u.set_flags_sta.flags_and; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x \n", (UINT)pMgmt->sNodeDBTable[uNodeIndex].dwFlags); } else { return -ENOENT; } return 0; }
int RXbBulkInProcessData(struct vnt_private *pDevice, struct vnt_rcb *pRCB, unsigned long BytesToIndicate) { struct net_device_stats *pStats = &pDevice->stats; struct sk_buff *skb; struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; struct vnt_rx_mgmt *pRxPacket = &pMgmt->sRxPacket; struct ieee80211_hdr *p802_11Header; u8 *pbyRsr, *pbyNewRsr, *pbyRSSI, *pbyFrame; u64 *pqwTSFTime; u32 bDeFragRx = false; u32 cbHeaderOffset, cbIVOffset; u32 FrameSize; u16 wEtherType = 0; s32 iSANodeIndex = -1; int ii; u8 *pbyRxSts, *pbyRxRate, *pbySQ, *pby3SQ; u32 cbHeaderSize; PSKeyItem pKey = NULL; u16 wRxTSC15_0 = 0; u32 dwRxTSC47_16 = 0; /* signed long ldBm = 0; */ int bIsWEP = false; int bExtIV = false; u32 dwWbkStatus; struct vnt_rcb *pRCBIndicate = pRCB; u8 *pbyDAddress; u16 *pwPLCP_Length; u8 abyVaildRate[MAX_RATE] = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108}; u16 wPLCPwithPadding; struct ieee80211_hdr *pMACHeader; int bRxeapol_key = false; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- RXbBulkInProcessData---\n"); skb = pRCB->skb; /* [31:16]RcvByteCount ( not include 4-byte Status ) */ dwWbkStatus = *((u32 *)(skb->data)); FrameSize = dwWbkStatus >> 16; FrameSize += 4; if (BytesToIndicate != FrameSize) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"------- WRONG Length 1\n"); pStats->rx_frame_errors++; return false; } if ((BytesToIndicate > 2372) || (BytesToIndicate <= 40)) { // Frame Size error drop this packet. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 2\n"); pStats->rx_frame_errors++; return false; } pbyDAddress = (u8 *)(skb->data); pbyRxSts = pbyDAddress+4; pbyRxRate = pbyDAddress+5; //real Frame Size = USBFrameSize -4WbkStatus - 4RxStatus - 8TSF - 4RSR - 4SQ3 - ?Padding //if SQ3 the range is 24~27, if no SQ3 the range is 20~23 //real Frame size in PLCPLength field. pwPLCP_Length = (u16 *) (pbyDAddress + 6); //Fix hardware bug => PLCP_Length error if ( ((BytesToIndicate - (*pwPLCP_Length)) > 27) || ((BytesToIndicate - (*pwPLCP_Length)) < 24) || (BytesToIndicate < (*pwPLCP_Length)) ) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong PLCP Length %x\n", (int) *pwPLCP_Length); pStats->rx_frame_errors++; return false; } for ( ii=RATE_1M;ii<MAX_RATE;ii++) { if ( *pbyRxRate == abyVaildRate[ii] ) { break; } } if ( ii==MAX_RATE ) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong RxRate %x\n",(int) *pbyRxRate); return false; } wPLCPwithPadding = ( (*pwPLCP_Length / 4) + ( (*pwPLCP_Length % 4) ? 1:0 ) ) *4; pqwTSFTime = (u64 *)(pbyDAddress + 8 + wPLCPwithPadding); if(pDevice->byBBType == BB_TYPE_11G) { pby3SQ = pbyDAddress + 8 + wPLCPwithPadding + 12; pbySQ = pby3SQ; } else { pbySQ = pbyDAddress + 8 + wPLCPwithPadding + 8; pby3SQ = pbySQ; } pbyNewRsr = pbyDAddress + 8 + wPLCPwithPadding + 9; pbyRSSI = pbyDAddress + 8 + wPLCPwithPadding + 10; pbyRsr = pbyDAddress + 8 + wPLCPwithPadding + 11; FrameSize = *pwPLCP_Length; pbyFrame = pbyDAddress + 8; pMACHeader = (struct ieee80211_hdr *) pbyFrame; //mike add: to judge if current AP is activated? if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) || (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) { if (pMgmt->sNodeDBTable[0].bActive) { if (ether_addr_equal(pMgmt->abyCurrBSSID, pMACHeader->addr2)) { if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) pMgmt->sNodeDBTable[0].uInActiveCount = 0; } } } if (!is_multicast_ether_addr(pMACHeader->addr1)) { if (WCTLbIsDuplicate(&(pDevice->sDupRxCache), (struct ieee80211_hdr *) pbyFrame)) { return false; } if (!ether_addr_equal(pDevice->abyCurrentNetAddr, pMACHeader->addr1)) { return false; } } // Use for TKIP MIC s_vGetDASA(pbyFrame, &cbHeaderSize, &pDevice->sRxEthHeader); if (ether_addr_equal((u8 *)pDevice->sRxEthHeader.h_source, pDevice->abyCurrentNetAddr)) return false; if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) { p802_11Header = (struct ieee80211_hdr *) (pbyFrame); // get SA NodeIndex if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(p802_11Header->addr2), &iSANodeIndex)) { pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies; pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0; } } } if (IS_FC_WEP(pbyFrame)) { bool bRxDecryOK = false; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"rx WEP pkt\n"); bIsWEP = true; bRxDecryOK = s_bHandleRxEncryption(pDevice, pbyFrame, FrameSize, pbyRsr, pbyNewRsr, &pKey, &bExtIV, &wRxTSC15_0, &dwRxTSC47_16); if (bRxDecryOK) { if ((*pbyNewRsr & NEWRSR_DECRYPTOK) == 0) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV Fail\n"); if ( (pMgmt->eAuthenMode == WMAC_AUTH_WPA) || (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) || (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { } return false; } } else { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WEP Func Fail\n"); return false; } if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) FrameSize -= 8; // Message Integrity Code else FrameSize -= 4; // 4 is ICV } // // RX OK // /* remove the FCS/CRC length */ FrameSize -= ETH_FCS_LEN; if ( !(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) && // unicast address (IS_FRAGMENT_PKT((pbyFrame))) ) { // defragment bDeFragRx = WCTLbHandleFragment(pDevice, (struct ieee80211_hdr *) (pbyFrame), FrameSize, bIsWEP, bExtIV); if (bDeFragRx) { // defrag complete // TODO skb, pbyFrame skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb; FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength; pbyFrame = skb->data + 8; } else { return false; } } // // Management & Control frame Handle // if ((IS_TYPE_DATA((pbyFrame))) == false) { // Handle Control & Manage Frame if (IS_TYPE_MGMT((pbyFrame))) { u8 * pbyData1; u8 * pbyData2; pRxPacket = &(pRCB->sMngPacket); pRxPacket->p80211Header = (PUWLAN_80211HDR)(pbyFrame); pRxPacket->cbMPDULen = FrameSize; pRxPacket->uRSSI = *pbyRSSI; pRxPacket->bySQ = *pbySQ; pRxPacket->qwLocalTSF = cpu_to_le64(*pqwTSFTime); if (bIsWEP) { // strip IV pbyData1 = WLAN_HDR_A3_DATA_PTR(pbyFrame); pbyData2 = WLAN_HDR_A3_DATA_PTR(pbyFrame) + 4; for (ii = 0; ii < (FrameSize - 4); ii++) { *pbyData1 = *pbyData2; pbyData1++; pbyData2++; } } pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate); if ( *pbyRxSts == 0 ) { //Discard beacon packet which channel is 0 if ( (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_BEACON) || (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_PROBERESP) ) { return false; } } pRxPacket->byRxChannel = (*pbyRxSts) >> 2; // // Insert the RCB in the Recv Mng list // EnqueueRCB(pDevice->FirstRecvMngList, pDevice->LastRecvMngList, pRCBIndicate); pDevice->NumRecvMngList++; if ( bDeFragRx == false) { pRCB->Ref++; } if (pDevice->bIsRxMngWorkItemQueued == false) { pDevice->bIsRxMngWorkItemQueued = true; schedule_work(&pDevice->rx_mng_work_item); } } else { // Control Frame };
/* * Description: * set each stations encryption key * * Parameters: * In: * pDevice - * param - * Out: * * Return Value: * */ static int hostap_set_encryption(struct vnt_private *pDevice, struct viawget_hostapd_param *param, int param_len) { struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; u32 dwKeyIndex = 0; u8 abyKey[MAX_KEY_LEN]; u8 abySeq[MAX_KEY_LEN]; NDIS_802_11_KEY_RSC KeyRSC; u8 byKeyDecMode = KEY_CTL_WEP; int ret = 0; s32 iNodeIndex = -1; int ii; int bKeyTableFull = false; u16 wKeyCtl = 0; param->u.crypt.err = 0; if (param->u.crypt.alg > WPA_ALG_CCMP) return -EINVAL; if ((param->u.crypt.idx > 3) || (param->u.crypt.key_len > MAX_KEY_LEN)) { param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_KEY_SET_FAILED\n"); return -EINVAL; } if (is_broadcast_ether_addr(param->sta_addr)) { if (param->u.crypt.idx >= MAX_GROUP_KEY) return -EINVAL; iNodeIndex = 0; } else { if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &iNodeIndex) == false) { param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); return -EINVAL; } } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: sta_index %d \n", iNodeIndex); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d \n", param->u.crypt.alg); if (param->u.crypt.alg == WPA_ALG_NONE) { if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly == true) { if (KeybRemoveKey( pDevice, &(pDevice->sKey), param->sta_addr, pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex ) == false) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail \n"); } pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; } pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = 0; pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = 0; pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = 0; pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = 0; pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0; pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0; pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = 0; memset(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], 0, MAX_KEY_LEN ); return ret; } memcpy(abyKey, param->u.crypt.key, param->u.crypt.key_len); // copy to node key tbl pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = param->u.crypt.idx; pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = param->u.crypt.key_len; memcpy(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], param->u.crypt.key, param->u.crypt.key_len ); dwKeyIndex = (DWORD)(param->u.crypt.idx); if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) { pDevice->byKeyIndex = (BYTE)dwKeyIndex; pDevice->bTransmitKey = true; dwKeyIndex |= (1 << 31); } if (param->u.crypt.alg == WPA_ALG_WEP) { if ((pDevice->bEnable8021x == false) || (iNodeIndex == 0)) { KeybSetDefaultKey( pDevice, &(pDevice->sKey), dwKeyIndex & ~(BIT30 | USE_KEYRSC), param->u.crypt.key_len, NULL, abyKey, KEY_CTL_WEP ); } else { // 8021x enable, individual key dwKeyIndex |= (1 << 30); // set pairwise key if (KeybSetKey(pDevice, &(pDevice->sKey), ¶m->sta_addr[0], dwKeyIndex & ~(USE_KEYRSC), param->u.crypt.key_len, &KeyRSC, (PBYTE)abyKey, KEY_CTL_WEP ) == true) { pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; } else { // Key Table Full pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; bKeyTableFull = true; } } pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; pDevice->bEncryptionEnable = true; pMgmt->byCSSPK = KEY_CTL_WEP; pMgmt->byCSSGK = KEY_CTL_WEP; pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = KEY_CTL_WEP; pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex; return ret; } if (param->u.crypt.seq) { memcpy(&abySeq, param->u.crypt.seq, 8); for (ii = 0 ; ii < 8 ; ii++) KeyRSC |= (unsigned long)abySeq[ii] << (ii * 8); dwKeyIndex |= 1 << 29; pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = KeyRSC; } if (param->u.crypt.alg == WPA_ALG_TKIP) { if (param->u.crypt.key_len != MAX_KEY_LEN) return -EINVAL; pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; byKeyDecMode = KEY_CTL_TKIP; pMgmt->byCSSPK = KEY_CTL_TKIP; pMgmt->byCSSGK = KEY_CTL_TKIP; } if (param->u.crypt.alg == WPA_ALG_CCMP) { if ((param->u.crypt.key_len != AES_KEY_LEN) || (pDevice->byLocalID <= REV_ID_VT3253_A1)) return -EINVAL; pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; byKeyDecMode = KEY_CTL_CCMP; pMgmt->byCSSPK = KEY_CTL_CCMP; pMgmt->byCSSGK = KEY_CTL_CCMP; } if (iNodeIndex == 0) { KeybSetDefaultKey( pDevice, &(pDevice->sKey), dwKeyIndex, param->u.crypt.key_len, &KeyRSC, abyKey, byKeyDecMode ); pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; } else { dwKeyIndex |= (1 << 30); // set pairwise key if (KeybSetKey(pDevice, &(pDevice->sKey), ¶m->sta_addr[0], dwKeyIndex, param->u.crypt.key_len, &KeyRSC, (PBYTE)abyKey, byKeyDecMode ) == true) { pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; } else { // Key Table Full pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; bKeyTableFull = true; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Key Table Full\n"); } } if (bKeyTableFull == true) { wKeyCtl &= 0x7F00; // clear all key control filed wKeyCtl |= (byKeyDecMode << 4); wKeyCtl |= (byKeyDecMode); wKeyCtl |= 0x0044; // use group key for all address wKeyCtl |= 0x4000; // disable KeyTable[MAX_KEY_TABLE-1] on-fly to genernate rx int // Todo.. xxxxxx //MACvSetDefaultKeyCtl(pDevice->PortOffset, wKeyCtl, MAX_KEY_TABLE-1, pDevice->byLocalID); } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set key sta_index= %d \n", iNodeIndex); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " tx_index=%d len=%d \n", param->u.crypt.idx, param->u.crypt.key_len ); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n", pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[1], pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[2], pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[3], pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[4] ); // set wep key pDevice->bEncryptionEnable = true; pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = byKeyDecMode; pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex; pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0; pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0; return ret; }