📄 wext.c
字号:
* @param vwrq A pointer to iw_param structure * @param extra A pointer to extra data buf * @return 0 --success, otherwise fail */static int wlan_get_encode(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, u8 * extra){ wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; lbs_deb_enter(LBS_DEB_WEXT); lbs_deb_wext("flags 0x%x, index %d, length %d, wep_tx_keyidx %d\n", dwrq->flags, index, dwrq->length, adapter->wep_tx_keyidx); dwrq->flags = 0; /* Authentication method */ switch (adapter->secinfo.auth_mode) { case IW_AUTH_ALG_OPEN_SYSTEM: dwrq->flags = IW_ENCODE_OPEN; break; case IW_AUTH_ALG_SHARED_KEY: case IW_AUTH_ALG_LEAP: dwrq->flags = IW_ENCODE_RESTRICTED; break; default: dwrq->flags = IW_ENCODE_DISABLED | IW_ENCODE_OPEN; break; } if ( adapter->secinfo.wep_enabled || adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) { dwrq->flags &= ~IW_ENCODE_DISABLED; } else { dwrq->flags |= IW_ENCODE_DISABLED; } memset(extra, 0, 16); mutex_lock(&adapter->lock); /* Default to returning current transmit key */ if (index < 0) index = adapter->wep_tx_keyidx; if ((adapter->wep_keys[index].len) && adapter->secinfo.wep_enabled) { memcpy(extra, adapter->wep_keys[index].key, adapter->wep_keys[index].len); dwrq->length = adapter->wep_keys[index].len; dwrq->flags |= (index + 1); /* Return WEP enabled */ dwrq->flags &= ~IW_ENCODE_DISABLED; } else if ((adapter->secinfo.WPAenabled) || (adapter->secinfo.WPA2enabled)) { /* return WPA enabled */ dwrq->flags &= ~IW_ENCODE_DISABLED; } else { dwrq->flags |= IW_ENCODE_DISABLED; } mutex_unlock(&adapter->lock); dwrq->flags |= IW_ENCODE_NOKEY; lbs_deb_wext("key: %02x:%02x:%02x:%02x:%02x:%02x, keylen %d\n", extra[0], extra[1], extra[2], extra[3], extra[4], extra[5], dwrq->length); lbs_deb_wext("return flags 0x%x\n", dwrq->flags); lbs_deb_leave(LBS_DEB_WEXT); return 0;}/** * @brief Set Encryption key (internal) * * @param priv A pointer to private card structure * @param key_material A pointer to key material * @param key_length length of key material * @param index key index to set * @param set_tx_key Force set TX key (1 = yes, 0 = no) * @return 0 --success, otherwise fail */static int wlan_set_wep_key(struct assoc_request *assoc_req, const char *key_material, u16 key_length, u16 index, int set_tx_key){ int ret = 0; struct enc_key *pkey; lbs_deb_enter(LBS_DEB_WEXT); /* Paranoid validation of key index */ if (index > 3) { ret = -EINVAL; goto out; } /* validate max key length */ if (key_length > KEY_LEN_WEP_104) { ret = -EINVAL; goto out; } pkey = &assoc_req->wep_keys[index]; if (key_length > 0) { memset(pkey, 0, sizeof(struct enc_key)); pkey->type = KEY_TYPE_ID_WEP; /* Standardize the key length */ pkey->len = (key_length > KEY_LEN_WEP_40) ? KEY_LEN_WEP_104 : KEY_LEN_WEP_40; memcpy(pkey->key, key_material, key_length); } if (set_tx_key) { /* Ensure the chosen key is valid */ if (!pkey->len) { lbs_deb_wext("key not set, so cannot enable it\n"); ret = -EINVAL; goto out; } assoc_req->wep_tx_keyidx = index; } assoc_req->secinfo.wep_enabled = 1;out: lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret;}static int validate_key_index(u16 def_index, u16 raw_index, u16 *out_index, u16 *is_default){ if (!out_index || !is_default) return -EINVAL; /* Verify index if present, otherwise use default TX key index */ if (raw_index > 0) { if (raw_index > 4) return -EINVAL; *out_index = raw_index - 1; } else { *out_index = def_index; *is_default = 1; } return 0;}static void disable_wep(struct assoc_request *assoc_req){ int i; lbs_deb_enter(LBS_DEB_WEXT); /* Set Open System auth mode */ assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; /* Clear WEP keys and mark WEP as disabled */ assoc_req->secinfo.wep_enabled = 0; for (i = 0; i < 4; i++) assoc_req->wep_keys[i].len = 0; set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); lbs_deb_leave(LBS_DEB_WEXT);}static void disable_wpa(struct assoc_request *assoc_req){ lbs_deb_enter(LBS_DEB_WEXT); memset(&assoc_req->wpa_mcast_key, 0, sizeof (struct enc_key)); assoc_req->wpa_mcast_key.flags = KEY_INFO_WPA_MCAST; set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags); memset(&assoc_req->wpa_unicast_key, 0, sizeof (struct enc_key)); assoc_req->wpa_unicast_key.flags = KEY_INFO_WPA_UNICAST; set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); assoc_req->secinfo.WPAenabled = 0; assoc_req->secinfo.WPA2enabled = 0; set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); lbs_deb_leave(LBS_DEB_WEXT);}/** * @brief Set Encryption key * * @param dev A pointer to net_device structure * @param info A pointer to iw_request_info structure * @param vwrq A pointer to iw_param structure * @param extra A pointer to extra data buf * @return 0 --success, otherwise fail */static int wlan_set_encode(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra){ int ret = 0; wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; struct assoc_request * assoc_req; u16 is_default = 0, index = 0, set_tx_key = 0; lbs_deb_enter(LBS_DEB_WEXT); mutex_lock(&adapter->lock); assoc_req = wlan_get_association_request(adapter); if (!assoc_req) { ret = -ENOMEM; goto out; } if (dwrq->flags & IW_ENCODE_DISABLED) { disable_wep (assoc_req); disable_wpa (assoc_req); goto out; } ret = validate_key_index(assoc_req->wep_tx_keyidx, (dwrq->flags & IW_ENCODE_INDEX), &index, &is_default); if (ret) { ret = -EINVAL; goto out; } /* If WEP isn't enabled, or if there is no key data but a valid * index, set the TX key. */ if (!assoc_req->secinfo.wep_enabled || (dwrq->length == 0 && !is_default)) set_tx_key = 1; ret = wlan_set_wep_key(assoc_req, extra, dwrq->length, index, set_tx_key); if (ret) goto out; if (dwrq->length) set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); if (set_tx_key) set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags); if (dwrq->flags & IW_ENCODE_RESTRICTED) { assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; } else if (dwrq->flags & IW_ENCODE_OPEN) { assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; }out: if (ret == 0) { set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); wlan_postpone_association_work(priv); } else { wlan_cancel_association_work(priv); } mutex_unlock(&adapter->lock); lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret;}/** * @brief Get Extended Encryption key (WPA/802.1x and WEP) * * @param dev A pointer to net_device structure * @param info A pointer to iw_request_info structure * @param vwrq A pointer to iw_param structure * @param extra A pointer to extra data buf * @return 0 on success, otherwise failure */static int wlan_get_encodeext(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra){ int ret = -EINVAL; wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; int index, max_key_len; lbs_deb_enter(LBS_DEB_WEXT); max_key_len = dwrq->length - sizeof(*ext); if (max_key_len < 0) goto out; index = dwrq->flags & IW_ENCODE_INDEX; if (index) { if (index < 1 || index > 4) goto out; index--; } else { index = adapter->wep_tx_keyidx; } if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY && ext->alg != IW_ENCODE_ALG_WEP) { if (index != 0 || adapter->mode != IW_MODE_INFRA) goto out; } dwrq->flags = index + 1; memset(ext, 0, sizeof(*ext)); if ( !adapter->secinfo.wep_enabled && !adapter->secinfo.WPAenabled && !adapter->secinfo.WPA2enabled) { ext->alg = IW_ENCODE_ALG_NONE; ext->key_len = 0; dwrq->flags |= IW_ENCODE_DISABLED; } else { u8 *key = NULL; if ( adapter->secinfo.wep_enabled && !adapter->secinfo.WPAenabled && !adapter->secinfo.WPA2enabled) { /* WEP */ ext->alg = IW_ENCODE_ALG_WEP; ext->key_len = adapter->wep_keys[index].len; key = &adapter->wep_keys[index].key[0]; } else if ( !adapter->secinfo.wep_enabled && (adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled)) { /* WPA */ struct enc_key * pkey = NULL; if ( adapter->wpa_mcast_key.len && (adapter->wpa_mcast_key.flags & KEY_INFO_WPA_ENABLED)) pkey = &adapter->wpa_mcast_key; else if ( adapter->wpa_unicast_key.len && (adapter->wpa_unicast_key.flags & KEY_INFO_WPA_ENABLED)) pkey = &adapter->wpa_unicast_key; if (pkey) { if (pkey->type == KEY_TYPE_ID_AES) { ext->alg = IW_ENCODE_ALG_CCMP; } else { ext->alg = IW_ENCODE_ALG_TKIP; } ext->key_len = pkey->len; key = &pkey->key[0]; } else { ext->alg = IW_ENCODE_ALG_TKIP; ext->key_len = 0; } } else { goto out; } if (ext->key_len > max_key_len) { ret = -E2BIG; goto out; } if (ext->key_len) memcpy(ext->key, key, ext->key_len); else dwrq->flags |= IW_ENCODE_NOKEY; dwrq->flags |= IW_ENCODE_ENABLED; } ret = 0;out: lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret;}/** * @brief Set Encryption key Extended (WPA/802.1x and WEP) * * @param dev A pointer to net_device structure * @param info A pointer to iw_request_info structure * @param vwrq A pointer to iw_param structure * @param extra A pointer to extra data buf * @return 0 --success, otherwise fail */static int wlan_set_encodeext(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra){ int ret = 0; wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; int alg = ext->alg; struct assoc_request * assoc_req; lbs_deb_enter(LBS_DEB_WEXT); mutex_lock(&adapter->lock); assoc_req = wlan_get_association_request(adapter); if (!assoc_req) { ret = -ENOMEM; goto out; } if ((alg == IW_ENCODE_ALG_NONE) || (dwrq->flags & IW_ENCODE_DISABLED)) { disable_wep (assoc_req); disable_wpa (assoc_req); } else if (alg == IW_ENCODE_ALG_WEP) { u16 is_default = 0, index, set_tx_key = 0; ret = validate_key_index(assoc_req->wep_tx_keyidx, (dwrq->flags & IW_ENCODE_INDEX), &index, &is_default); if (ret) goto out; /* If WEP isn't enabled, or if there is no key data but a valid * index, or if the set-TX-key flag was passed, set the TX key. */ if ( !assoc_req->secinfo.wep_enabled || (dwrq->length == 0 && !is_default) || (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) set_tx_key = 1; /* Copy key to driver */ ret = wlan_set_wep_key (assoc_req, ext->key, ext->key_len, index, set_tx_key); if (ret) goto out; if (dwrq->flags & IW_ENCODE_RESTRICTED) { assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; } else if (dwrq->flags & IW_ENCODE_OPEN) { assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; } /* Mark the various WEP bits as modified */ set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); if (dwrq->length) set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); if (set_tx_key) set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags); } else if ((alg == IW_ENCODE_ALG_TKIP) || (alg == IW_ENCODE_ALG_CCMP)) { struct enc_key * pkey; /* validate key length */ if (((alg == IW_ENCODE_ALG_TKIP) && (ext->key_len != KEY_LEN_WPA_TKIP)) || ((alg == IW_ENCODE_ALG_CCMP) && (ext->key_len != KEY_LEN_WPA_AES))) { lbs_deb_wext("invalid size %d for key of alg " "type %d\n", ext->key_len, alg); ret = -EINVAL; goto out; } if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { pkey = &assoc_req->wpa_mcast_key; set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags); } else { pkey = &assoc_req->wpa_unicast_key; set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); } memset(pkey, 0, sizeof (struct enc_key)); memcpy(pkey->key, ext->key, ext->key_len); pkey->len = ext->key_len; if (pkey->len) pkey->flags |= KEY_INFO_WPA_ENABLED; /* Do this after zeroing key structure */ if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { pkey->flags |= KEY_INFO_WPA_MCAST; } else { pkey->flags |= KEY_INFO_WPA_UNICAST; } if (alg == IW_ENCODE_ALG_TKIP) { pkey->type = KEY_TYPE_ID_TKIP; } else if (alg == IW_ENCODE_ALG_CCMP) { pkey->type = KEY_TYPE_ID_AES; } /* If WPA isn't enabled yet, do that now */ if ( assoc_req->secinfo.WPAenabled == 0 && assoc_req->secinfo.WPA2enabled == 0) { assoc_req->secinfo.WPAenabled = 1; assoc_req->secinfo.WPA2enabled = 1; set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); } disable_wep (assoc_req); }out: if (ret == 0) { wlan_postpone_association_work(priv); } else { wlan_cancel_association_work(priv); } mutex_unlock(&adapter->lock); lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); return ret;}static int wlan_set_genie(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra){ wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; int ret = 0; struct assoc_request * assoc_req; lbs_deb_enter(LBS_DEB_WEXT); mutex_lock(&adapter->lock); assoc_req = wlan_get_association_request(adapter); if (!assoc_req) { ret = -ENOMEM; goto out; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -