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; }