📄 wpactl.c
字号:
/* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * * This software is copyrighted by and is the sole property of * VIA Networking Technologies, Inc. This software may only be used * in accordance with the corresponding license agreement. Any unauthorized * use, duplication, transmission, distribution, or disclosure of this * software is expressly forbidden. * * This software is provided by VIA Networking Technologies, Inc. "as is" * and any express or implied warranties, including, but not limited to, the * implied warranties of merchantability and fitness for a particular purpose * are disclaimed. In no event shall VIA Networking Technologies, Inc. * be liable for any direct, indirect, incidental, special, exemplary, or * consequential damages. * * * File: wpactl.c * * Purpose: handle wpa supplicant ioctl input/out functions * * Author: Lyndon Chen * * Date: July 28, 2006 * * Functions: * * Revision History: * */ #if !defined(__WPACTL_H__)#include "wpactl.h"#endif#if !defined(__KEY_H__)#include "key.h"#endif#if !defined(__MAC_H__)#include "mac.h"#endif#if !defined(__DEVICE_H__)#include "device.h"#endif#if !defined(__WMGR_H__)#include "wmgr.h"#endif#if !defined(__IOCMD_H__)#include "iocmd.h"#endif#if !defined(__IOWPA_H__)#include "iowpa.h"#endif#if !defined(__CONTROL_H__)#include "control.h"#endif#if !defined(__RNDIS_H__)#include "rndis.h"#endif/*--------------------- Static Definitions -------------------------*/#define VIAWGET_WPA_MAX_BUF_SIZE 1024static const int frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484 };/*--------------------- Static Classes ----------------------------*//*--------------------- Static Variables --------------------------*///static int msglevel =MSG_LEVEL_DEBUG;static int msglevel =MSG_LEVEL_INFO;/*--------------------- Static Functions --------------------------*//*--------------------- Export Variables --------------------------*//* * Description: * register netdev for wpa supplicant deamon * * Parameters: * In: * pDevice - * enable - * Out: * * Return Value: * */ static int wpa_init_wpadev(PSDevice pDevice){ struct net_device *dev = pDevice->dev; int ret;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) pDevice->wpadev = alloc_etherdev(0);//James//20080516#else pDevice->wpadev = (struct net_device *)kmalloc(sizeof(struct net_device), GFP_KERNEL);#endif if (pDevice->wpadev == NULL) return -ENOMEM;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) memset(pDevice->wpadev, 0, sizeof(struct net_device));//James //20080516//Deleted#endif pDevice->wpadev->priv = pDevice; memcpy(pDevice->wpadev->dev_addr, dev->dev_addr, ETH_ALEN); pDevice->wpadev->type = ARPHRD_IEEE80211; pDevice->wpadev->base_addr = dev->base_addr; pDevice->wpadev->irq = dev->irq; pDevice->wpadev->mem_start = dev->mem_start; pDevice->wpadev->mem_end = dev->mem_end; sprintf(pDevice->wpadev->name, "%swpa", dev->name); ret = register_netdevice(pDevice->wpadev); if (ret) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdevice(WPA) failed!\n", dev->name); return -1; } if (pDevice->skb == NULL) { pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); if (pDevice->skb == NULL) return -ENOMEM; } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdevice %s for WPA management\n", dev->name, pDevice->wpadev->name); return 0;}/* * Description: * unregister net_device (wpadev) * * Parameters: * In: * pDevice - * Out: * * Return Value: * */static int wpa_release_wpadev(PSDevice pDevice){ //netif_stop_queue(pDevice->wpadev);//James if (pDevice->skb) { dev_kfree_skb(pDevice->skb); pDevice->skb = NULL; } if (pDevice->wpadev) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "reg_state1:%d\n",pDevice->wpadev->reg_state); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "padded:%x\n",pDevice->wpadev->padded); mdelay(5);//James unregister_netdevice(pDevice->wpadev);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) rtnl_unlock();//James#endif DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "reg_state2:%d\n",pDevice->wpadev->reg_state); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n", pDevice->dev->name, pDevice->wpadev->name); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "reg_state3:%d\n",pDevice->wpadev->reg_state);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) free_netdev(pDevice->wpadev);//James#else DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "kfree\n"); kfree(pDevice->wpadev);//James#endif DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "reg_state5:%d\n",pDevice->wpadev->reg_state); if(pDevice->wpadev != NULL)//James pDevice->wpadev = NULL; } return 0;}/* * Description: * Set enable/disable dev for wpa supplicant deamon * * Parameters: * In: * pDevice - * val - * Out: * * Return Value: * */int wpa_set_wpadev(PSDevice pDevice, int val){ if (val < 0 || val > 1) return -EINVAL; if (pDevice->bWPADevEnable == val) return 0; pDevice->bWPADevEnable = val; if (val) return wpa_init_wpadev(pDevice); else return wpa_release_wpadev(pDevice);} /* * Description: * Set WPA algorithm & keys * * Parameters: * In: * pDevice - * param - * Out: * * Return Value: * */ int wpa_set_keys(PSDevice pDevice, struct viawget_wpa_param *param, BOOL fcpfkernel){ PSMgmtObject pMgmt = &(pDevice->sMgmtObj); DWORD dwKeyIndex = 0; BYTE abyKey[MAX_KEY_LEN]; BYTE abySeq[MAX_KEY_LEN]; QWORD KeyRSC; // NDIS_802_11_KEY_RSC KeyRSC; BYTE byKeyDecMode = KEY_CTL_WEP; int ret = 0; int uu, ii; if (param->u.wpa_key.alg_name > WPA_ALG_CCMP) return -EINVAL; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n", param->u.wpa_key.alg_name); if (param->u.wpa_key.alg_name == WPA_ALG_NONE) { pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; pDevice->bEncryptionEnable = FALSE; pDevice->byKeyIndex = 0; pDevice->bTransmitKey = FALSE; for (uu=0; uu<MAX_KEY_TABLE; uu++) { MACvDisableKeyEntry(pDevice, uu); } return ret; } spin_unlock_irq(&pDevice->lock); if(param->u.wpa_key.key && fcpfkernel) { memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len); } else { if (param->u.wpa_key.key && copy_from_user(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len)) { spin_lock_irq(&pDevice->lock); return -EINVAL; } } spin_lock_irq(&pDevice->lock); dwKeyIndex = (DWORD)(param->u.wpa_key.key_index); if (param->u.wpa_key.alg_name == WPA_ALG_WEP) { if (dwKeyIndex > 3) { return -EINVAL; } else { if (param->u.wpa_key.set_tx) { pDevice->byKeyIndex = (BYTE)dwKeyIndex; pDevice->bTransmitKey = TRUE; dwKeyIndex |= (1 << 31); } KeybSetDefaultKey( pDevice, &(pDevice->sKey), dwKeyIndex & ~(BIT30 | USE_KEYRSC), param->u.wpa_key.key_len, NULL, abyKey, KEY_CTL_WEP ); } pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; pDevice->bEncryptionEnable = TRUE; return ret; } spin_unlock_irq(&pDevice->lock); if(param->u.wpa_key.seq && fcpfkernel) { memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len); } else { if (param->u.wpa_key.seq && copy_from_user(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len)) { spin_lock_irq(&pDevice->lock); return -EINVAL; } } spin_lock_irq(&pDevice->lock); if (param->u.wpa_key.seq_len > 0) { for (ii = 0 ; ii < param->u.wpa_key.seq_len ; ii++) { if (ii < 4) LODWORD(KeyRSC) |= (abySeq[ii] << (ii * 8)); else HIDWORD(KeyRSC) |= (abySeq[ii] << ((ii-4) * 8)); //KeyRSC |= (abySeq[ii] << (ii * 8)); } dwKeyIndex |= 1 << 29; } if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return dwKeyIndex > 3\n"); return -EINVAL; } if (param->u.wpa_key.alg_name == WPA_ALG_TKIP) { pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; } if (param->u.wpa_key.alg_name == WPA_ALG_CCMP) { pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; } if (param->u.wpa_key.set_tx) dwKeyIndex |= (1 << 31); if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) byKeyDecMode = KEY_CTL_CCMP; else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) byKeyDecMode = KEY_CTL_TKIP; else byKeyDecMode = KEY_CTL_WEP; // Fix HCT test that set 256 bits KEY and Ndis802_11Encryption3Enabled if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { if (param->u.wpa_key.key_len == MAX_KEY_LEN) byKeyDecMode = KEY_CTL_TKIP; else if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN) byKeyDecMode = KEY_CTL_WEP; else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN) byKeyDecMode = KEY_CTL_WEP; } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN) byKeyDecMode = KEY_CTL_WEP; else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN) byKeyDecMode = KEY_CTL_WEP; } // Check TKIP key length if ((byKeyDecMode == KEY_CTL_TKIP) && (param->u.wpa_key.key_len != MAX_KEY_LEN)) { // TKIP Key must be 256 bits //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - TKIP Key must be 256 bits\n")); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return- TKIP Key must be 256 bits!\n"); return -EINVAL; } // Check AES key length if ((byKeyDecMode == KEY_CTL_CCMP) && (param->u.wpa_key.key_len != AES_KEY_LEN)) { // AES Key must be 128 bits DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return - AES Key must be 128 bits\n"); return -EINVAL; } if (IS_BROADCAST_ADDRESS(¶m->addr[0]) || (param->addr == NULL)) { // If IS_BROADCAST_ADDRESS, set the key as every key entry's group key. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n"); if ((KeybSetAllGroupKey(pDevice, &(pDevice->sKey), dwKeyIndex, param->u.wpa_key.key_len, (PQWORD) &(KeyRSC), (PBYTE)abyKey, byKeyDecMode ) == TRUE) && (KeybSetDefaultKey(pDevice, &(pDevice->sKey), dwKeyIndex, param->u.wpa_key.key_len, (PQWORD) &(KeyRSC), (PBYTE)abyKey, byKeyDecMode ) == TRUE) ) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n"); } else { //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -KeybSetDefaultKey Fail.0\n")); return -EINVAL; } } else { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n"); // BSSID not 0xffffffffffff // Pairwise Key can't be WEP if (byKeyDecMode == KEY_CTL_WEP) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n"); return -EINVAL; } dwKeyIndex |= (1 << 30); // set pairwise key if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) { //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - WMAC_CONFIG_IBSS_STA\n")); return -EINVAL; } if (KeybSetKey(pDevice, &(pDevice->sKey), ¶m->addr[0], dwKeyIndex, param->u.wpa_key.key_len, (PQWORD) &(KeyRSC), (PBYTE)abyKey, byKeyDecMode ) == TRUE) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n"); } else { // Key Table Full if (IS_ETH_ADDRESS_EQUAL(¶m->addr[0], pDevice->abyBSSID)) { //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n")); return -EINVAL; } else { // Save Key and configure just before associate/reassociate to BSSID // we do not implement now return -EINVAL; } } } // BSSID not 0xffffffffffff if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) { pDevice->byKeyIndex = (BYTE)param->u.wpa_key.key_index; pDevice->bTransmitKey = TRUE; } pDevice->bEncryptionEnable = TRUE;/* DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n", pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][0], pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][1], pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][2], pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][3], pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][4] );*/ return ret; } /* * Description: * enable wpa auth & mode * * Parameters: * In: * pDevice - * param - * Out: * * Return Value: * */ static int wpa_set_wpa(PSDevice pDevice, struct viawget_wpa_param *param){ PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int ret = 0; pMgmt->eAuthenMode = WMAC_AUTH_OPEN; pMgmt->bShareKeyAlgorithm = FALSE; return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -