Example #1
0
File: iwctl.c Project: 7799/linux
int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
		union iwreq_data *wrqu, char *extra)
{
	struct vnt_private *pDevice = netdev_priv(dev);
	struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
	struct iw_point *wrq = &wrqu->encoding;
	struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
	struct viawget_wpa_param *param = NULL;
// original member
	wpa_alg alg_name;
	u8 addr[6];
	int key_idx;
	int set_tx = 0;
	u8 seq[IW_ENCODE_SEQ_MAX_SIZE];
	u8 key[64];
	size_t seq_len = 0;
	size_t key_len = 0;
	u8 *buf;
	u8 key_array[64];
	int ret = 0;

	PRINT_K("SIOCSIWENCODEEXT......\n");

	if (pMgmt == NULL)
		return -EFAULT;

	if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
		return -ENODEV;

	buf = kzalloc(sizeof(struct viawget_wpa_param), GFP_KERNEL);
	if (buf == NULL)
		return -ENOMEM;

	param = (struct viawget_wpa_param *)buf;

// recover alg_name
	switch (ext->alg) {
	case IW_ENCODE_ALG_NONE:
		alg_name = WPA_ALG_NONE;
		break;
	case IW_ENCODE_ALG_WEP:
		alg_name = WPA_ALG_WEP;
		break;
	case IW_ENCODE_ALG_TKIP:
		alg_name = WPA_ALG_TKIP;
		break;
	case IW_ENCODE_ALG_CCMP:
		alg_name = WPA_ALG_CCMP;
		break;
	default:
		PRINT_K("Unknown alg = %d\n", ext->alg);
		ret = -ENOMEM;
		goto error;
	}
// recover addr
	memcpy(addr, ext->addr.sa_data, ETH_ALEN);
// recover key_idx
	key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1;
// recover set_tx
	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
		set_tx = 1;
// recover seq,seq_len
	if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
		seq_len = IW_ENCODE_SEQ_MAX_SIZE;
		memcpy(seq, ext->rx_seq, seq_len);
	}
// recover key,key_len
	if (ext->key_len) {
		key_len = ext->key_len;
		memcpy(key, &ext->key[0], key_len);
	}
	memset(key_array, 0, 64);
	if (key_len > 0) {
		memcpy(key_array, key, key_len);
		if (key_len == 32) {
			// notice ! the oder
			memcpy(&key_array[16], &key[24], 8);
			memcpy(&key_array[24], &key[16], 8);
		}
	}

/**************Translate iw_encode_ext to viawget_wpa_param****************/
	memcpy(param->addr, addr, ETH_ALEN);
	param->u.wpa_key.alg_name = (int)alg_name;
	param->u.wpa_key.set_tx = set_tx;
	param->u.wpa_key.key_index = key_idx;
	param->u.wpa_key.key_len = key_len;
	param->u.wpa_key.key = (u8 *)key_array;
	param->u.wpa_key.seq = (u8 *)seq;
	param->u.wpa_key.seq_len = seq_len;

/****set if current action is Network Manager count?? */
/****this method is so foolish,but there is no other way??? */
	if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
		if (param->u.wpa_key.key_index == 0) {
			pDevice->bwextstep0 = true;
		}
		if ((pDevice->bwextstep0 == true) && (param->u.wpa_key.key_index == 1)) {
			pDevice->bwextstep0 = false;
			pDevice->bwextstep1 = true;
		}
		if ((pDevice->bwextstep1 == true) && (param->u.wpa_key.key_index == 2)) {
			pDevice->bwextstep1 = false;
			pDevice->bwextstep2 = true;
		}
		if ((pDevice->bwextstep2 == true) && (param->u.wpa_key.key_index == 3)) {
			pDevice->bwextstep2 = false;
			pDevice->bwextstep3 = true;
		}
	}
	if (pDevice->bwextstep3 == true) {
		PRINT_K("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
		pDevice->bwextstep0 = false;
		pDevice->bwextstep1 = false;
		pDevice->bwextstep2 = false;
		pDevice->bwextstep3 = false;
		pDevice->bWPASuppWextEnabled = true;
		memset(pMgmt->abyDesireBSSID, 0xFF, 6);
		KeyvInitTable(pDevice, &pDevice->sKey);
	}
/*******/
	spin_lock_irq(&pDevice->lock);
	ret = wpa_set_keys(pDevice, param);
	spin_unlock_irq(&pDevice->lock);

error:
	kfree(buf);
	return ret;
}
int wpa_ioctl(PSDevice pDevice, struct iw_point *p)
{
	struct viawget_wpa_param *param;
	int ret = 0;
	int wpa_ioctl = 0;

	if (p->length < sizeof(struct viawget_wpa_param) ||
	    p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer)
		return -EINVAL;

	param = kmalloc((int)p->length, (int)GFP_KERNEL);
	if (param == NULL)
		return -ENOMEM;

	if (copy_from_user(param, p->pointer, p->length)) {
		ret = -EFAULT;
		goto out;
	}

	switch (param->cmd) {
	case VIAWGET_SET_WPA:
        ret = wpa_set_wpa(pDevice, param);
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_WPA \n");
		break;

	case VIAWGET_SET_KEY:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY \n");
	    spin_lock_irq(&pDevice->lock);
        ret = wpa_set_keys(pDevice, param, false);
        spin_unlock_irq(&pDevice->lock);
		break;

	case VIAWGET_SET_SCAN:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_SCAN \n");
        ret = wpa_set_scan(pDevice, param);
		break;

	case VIAWGET_GET_SCAN:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SCAN\n");
        ret = wpa_get_scan(pDevice, param);
		wpa_ioctl = 1;
		break;

	case VIAWGET_GET_SSID:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SSID \n");
        ret = wpa_get_ssid(pDevice, param);
		wpa_ioctl = 1;
		break;

	case VIAWGET_GET_BSSID:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_BSSID \n");
        ret = wpa_get_bssid(pDevice, param);
		wpa_ioctl = 1;
		break;

	case VIAWGET_SET_ASSOCIATE:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_ASSOCIATE \n");
        ret = wpa_set_associate(pDevice, param);
		break;

	case VIAWGET_SET_DISASSOCIATE:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DISASSOCIATE \n");
        ret = wpa_set_disassociate(pDevice, param);
		break;

	case VIAWGET_SET_DROP_UNENCRYPT:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT \n");
		break;

    case VIAWGET_SET_DEAUTHENTICATE:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DEAUTHENTICATE \n");
		break;

	default:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n",
		       param->cmd);
		return -EOPNOTSUPP;
		break;
	}

	if ((ret == 0) && wpa_ioctl) {
		if (copy_to_user(p->pointer, param, p->length)) {
			ret = -EFAULT;
			goto out;
		}
	}

out:
	kfree(param);

	return ret;
}
int iwctl_siwencodeext(struct net_device *dev,
             struct iw_request_info *info,
             struct iw_point *wrq,
             char *extra)
{
    PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
    PSMgmtObject	pMgmt = &(pDevice->sMgmtObj);
	struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
    struct viawget_wpa_param *param=NULL;
    wpa_alg alg_name;
    u8  addr[6];
    int key_idx, set_tx=0;
    u8  seq[IW_ENCODE_SEQ_MAX_SIZE];
    u8 key[64];
    size_t seq_len=0,key_len=0;
    u8 *buf;
    size_t blen;
    u8 key_array[64];
    int ret=0;

PRINT_K("SIOCSIWENCODEEXT...... \n");

blen = sizeof(*param);
buf = kmalloc((int)blen, (int)GFP_KERNEL);
if (buf == NULL)
    return -ENOMEM;
memset(buf, 0, blen);
param = (struct viawget_wpa_param *) buf;

switch (ext->alg) {
    case IW_ENCODE_ALG_NONE:
                  alg_name = WPA_ALG_NONE;
		break;
    case IW_ENCODE_ALG_WEP:
                  alg_name = WPA_ALG_WEP;
		break;
    case IW_ENCODE_ALG_TKIP:
                  alg_name = WPA_ALG_TKIP;
		break;
    case IW_ENCODE_ALG_CCMP:
                  alg_name = WPA_ALG_CCMP;
		break;
    default:
		PRINT_K("Unknown alg = %d\n",ext->alg);
		ret= -ENOMEM;
		goto error;
		}
 memcpy(addr, ext->addr.sa_data, ETH_ALEN);
  key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1;
if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
   set_tx = 1;
	if(ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
   seq_len=IW_ENCODE_SEQ_MAX_SIZE;
   memcpy(seq, ext->rx_seq, seq_len);
		}
if(ext->key_len) {
  key_len=ext->key_len;
  memcpy(key, &ext->key[0], key_len);
	}

memset(key_array, 0, 64);
if ( key_len > 0) {
     memcpy(key_array, key, key_len);
    if (key_len == 32) {
          
	  memcpy(&key_array[16], &key[24], 8);
	  memcpy(&key_array[24], &key[16], 8);
	}
	}

memcpy(param->addr, addr, ETH_ALEN);
param->u.wpa_key.alg_name = (int)alg_name;
param->u.wpa_key.set_tx = set_tx;
param->u.wpa_key.key_index = key_idx;
param->u.wpa_key.key_len = key_len;
param->u.wpa_key.key = (u8 *)key_array;
param->u.wpa_key.seq = (u8 *)seq;
param->u.wpa_key.seq_len = seq_len;

if(param->u.wpa_key.alg_name == WPA_ALG_NONE) {
   if(param->u.wpa_key.key_index ==0) {
     pDevice->bwextstep0 = TRUE;
    }
   if((pDevice->bwextstep0 = TRUE)&&(param->u.wpa_key.key_index ==1)) {
     pDevice->bwextstep0 = FALSE;
     pDevice->bwextstep1 = TRUE;
    }
   if((pDevice->bwextstep1 = TRUE)&&(param->u.wpa_key.key_index ==2)) {
     pDevice->bwextstep1 = FALSE;
     pDevice->bwextstep2 = TRUE;
	}
   if((pDevice->bwextstep2 = TRUE)&&(param->u.wpa_key.key_index ==3)) {
     pDevice->bwextstep2 = FALSE;
     pDevice->bwextstep3 = TRUE;
        }
		 }
if(pDevice->bwextstep3 == TRUE) {
    PRINT_K("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
     pDevice->bwextstep0 = FALSE;
     pDevice->bwextstep1 = FALSE;
     pDevice->bwextstep2 = FALSE;
     pDevice->bwextstep3 = FALSE;
     pDevice->bWPASuppWextEnabled = TRUE;
     memset(pMgmt->abyDesireBSSID, 0xFF,6);
     KeyvInitTable(pDevice,&pDevice->sKey);
		 }

		spin_lock_irq(&pDevice->lock);
 ret = wpa_set_keys(pDevice, param, TRUE);
		spin_unlock_irq(&pDevice->lock);

error:
kfree(param);
	return ret;
}