⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ieee80211_wx.c

📁 Source for the 802.11 (wireless) network stack for Linux
💻 C
📖 第 1 页 / 共 2 页
字号:
			       "load module ieee80211_crypt_wep\n", dev->name);			return -EOPNOTSUPP;		}		*crypt = new_crypt;	}	/* If a new key was provided, set it up */	if (erq->length > 0) {		len = erq->length <= 5 ? 5 : 13;		memcpy(sec.keys[key], keybuf, erq->length);		if (len > erq->length)			memset(sec.keys[key] + erq->length, 0,			       len - erq->length);		IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",				   key, escape_essid(sec.keys[key], len),				   erq->length, len);		sec.key_sizes[key] = len;		if (*crypt)			(*crypt)->ops->set_key(sec.keys[key], len, NULL,					       (*crypt)->priv);		sec.flags |= (1 << key);		/* This ensures a key will be activated if no key is		 * explicitely set */		if (key == sec.active_key)			sec.flags |= SEC_ACTIVE_KEY;	} else {		if (host_crypto) {			len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,						     NULL, (*crypt)->priv);			if (len == 0) {				/* Set a default key of all 0 */				IEEE80211_DEBUG_WX("Setting key %d to all "						   "zero.\n", key);				memset(sec.keys[key], 0, 13);				(*crypt)->ops->set_key(sec.keys[key], 13, NULL,						       (*crypt)->priv);				sec.key_sizes[key] = 13;				sec.flags |= (1 << key);			}		}		/* No key data - just set the default TX key index */		if (key_provided) {			IEEE80211_DEBUG_WX("Setting key %d to default Tx "					   "key.\n", key);			ieee->tx_keyidx = key;			sec.active_key = key;			sec.flags |= SEC_ACTIVE_KEY;		}	}	if (erq->flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED)) {		ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);		sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN :		    WLAN_AUTH_SHARED_KEY;		sec.flags |= SEC_AUTH_MODE;		IEEE80211_DEBUG_WX("Auth: %s\n",				   sec.auth_mode == WLAN_AUTH_OPEN ?				   "OPEN" : "SHARED KEY");	}	/* For now we just support WEP, so only set that security level...	 * TODO: When WPA is added this is one place that needs to change */	sec.flags |= SEC_LEVEL;	sec.level = SEC_LEVEL_1;	/* 40 and 104 bit WEP */	sec.encode_alg[key] = SEC_ALG_WEP;      done:	if (ieee->set_security)		ieee->set_security(dev, &sec);	/* Do not reset port if card is in Managed mode since resetting will	 * generate new IEEE 802.11 authentication which may end up in looping	 * with IEEE 802.1X.  If your hardware requires a reset after WEP	 * configuration (for example... Prism2), implement the reset_port in	 * the callbacks structures used to initialize the 802.11 stack. */	if (ieee->reset_on_keychange &&	    ieee->iw_mode != IW_MODE_INFRA &&	    ieee->reset_port && ieee->reset_port(dev)) {		printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);		return -EINVAL;	}	return 0;}int ieee80211_wx_get_encode(struct ieee80211_device *ieee,			    struct iw_request_info *info,			    union iwreq_data *wrqu, char *keybuf){	struct iw_point *erq = &(wrqu->encoding);	int len, key;	struct ieee80211_crypt_data *crypt;	struct ieee80211_security *sec = &ieee->sec;	IEEE80211_DEBUG_WX("GET_ENCODE\n");	key = erq->flags & IW_ENCODE_INDEX;	if (key) {		if (key > WEP_KEYS)			return -EINVAL;		key--;	} else		key = ieee->tx_keyidx;	crypt = ieee->crypt[key];	erq->flags = key + 1;	if (!sec->enabled) {		erq->length = 0;		erq->flags |= IW_ENCODE_DISABLED;		return 0;	}	len = sec->key_sizes[key];	memcpy(keybuf, sec->keys[key], len);	erq->length = (len >= 0 ? len : 0);	erq->flags |= IW_ENCODE_ENABLED;	if (ieee->open_wep)		erq->flags |= IW_ENCODE_OPEN;	else		erq->flags |= IW_ENCODE_RESTRICTED;	return 0;}#if WIRELESS_EXT >= 18int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,			       struct iw_request_info *info,			       union iwreq_data *wrqu, char *extra){	struct net_device *dev = ieee->dev;	struct iw_point *encoding = &wrqu->encoding;	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;	int i, idx, ret = 0;	int group_key = 0;	const char *alg, *module;	struct ieee80211_crypto_ops *ops;	struct ieee80211_crypt_data **crypt;	struct ieee80211_security sec = {		.flags = 0,	};	idx = encoding->flags & IW_ENCODE_INDEX;	if (idx) {		if (idx < 1 || idx > WEP_KEYS)			return -EINVAL;		idx--;	} else		idx = ieee->tx_keyidx;	if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {		crypt = &ieee->crypt[idx];		group_key = 1;	} else {		if (idx != 0)			return -EINVAL;		if (ieee->iw_mode == IW_MODE_INFRA)			crypt = &ieee->crypt[idx];		else			return -EINVAL;	}	sec.flags |= SEC_ENABLED | SEC_ENCRYPT;	if ((encoding->flags & IW_ENCODE_DISABLED) ||	    ext->alg == IW_ENCODE_ALG_NONE) {		if (*crypt)			ieee80211_crypt_delayed_deinit(ieee, crypt);		for (i = 0; i < WEP_KEYS; i++)			if (ieee->crypt[i] != NULL)				break;		if (i == WEP_KEYS) {			sec.enabled = 0;			sec.encrypt = 0;			sec.level = SEC_LEVEL_0;			sec.flags |= SEC_LEVEL;		}		goto done;	}	sec.enabled = 1;	sec.encrypt = 1;	if (group_key ? !ieee->host_mc_decrypt :	    !(ieee->host_encrypt || ieee->host_decrypt ||	      ieee->host_encrypt_msdu))		goto skip_host_crypt;	switch (ext->alg) {	case IW_ENCODE_ALG_WEP:		alg = "WEP";		module = "ieee80211_crypt_wep";		break;	case IW_ENCODE_ALG_TKIP:		alg = "TKIP";		module = "ieee80211_crypt_tkip";		break;	case IW_ENCODE_ALG_CCMP:		alg = "CCMP";		module = "ieee80211_crypt_ccmp";		break;	default:		IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",				   dev->name, ext->alg);		ret = -EINVAL;		goto done;	}	ops = ieee80211_get_crypto_ops(alg);	if (ops == NULL) {		request_module(module);		ops = ieee80211_get_crypto_ops(alg);	}	if (ops == NULL) {		IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",				   dev->name, ext->alg);		ret = -EINVAL;		goto done;	}	if (*crypt == NULL || (*crypt)->ops != ops) {		struct ieee80211_crypt_data *new_crypt;		ieee80211_crypt_delayed_deinit(ieee, crypt);		new_crypt = (struct ieee80211_crypt_data *)		    kmalloc(sizeof(*new_crypt), GFP_KERNEL);		if (new_crypt == NULL) {			ret = -ENOMEM;			goto done;		}		memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));		new_crypt->ops = ops;		if (new_crypt->ops && try_module_get(new_crypt->ops->owner))			new_crypt->priv = new_crypt->ops->init(idx);		if (new_crypt->priv == NULL) {			kfree(new_crypt);			ret = -EINVAL;			goto done;		}		*crypt = new_crypt;	}	if (ext->key_len > 0 && (*crypt)->ops->set_key &&	    (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,				   (*crypt)->priv) < 0) {		IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);		ret = -EINVAL;		goto done;	}      skip_host_crypt:	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {		ieee->tx_keyidx = idx;		sec.active_key = idx;		sec.flags |= SEC_ACTIVE_KEY;	}	if (ext->alg != IW_ENCODE_ALG_NONE) {		memcpy(sec.keys[idx], ext->key, ext->key_len);		sec.key_sizes[idx] = ext->key_len;		sec.flags |= (1 << idx);		if (ext->alg == IW_ENCODE_ALG_WEP) {			sec.encode_alg[idx] = SEC_ALG_WEP;			sec.flags |= SEC_LEVEL;			sec.level = SEC_LEVEL_1;		} else if (ext->alg == IW_ENCODE_ALG_TKIP) {			sec.encode_alg[idx] = SEC_ALG_TKIP;			sec.flags |= SEC_LEVEL;			sec.level = SEC_LEVEL_2;		} else if (ext->alg == IW_ENCODE_ALG_CCMP) {			sec.encode_alg[idx] = SEC_ALG_CCMP;			sec.flags |= SEC_LEVEL;			sec.level = SEC_LEVEL_3;		}		/* Don't set sec level for group keys. */		if (group_key)			sec.flags &= ~SEC_LEVEL;	}      done:	if (ieee->set_security)		ieee->set_security(ieee->dev, &sec);	/*	 * Do not reset port if card is in Managed mode since resetting will	 * generate new IEEE 802.11 authentication which may end up in looping	 * with IEEE 802.1X. If your hardware requires a reset after WEP	 * configuration (for example... Prism2), implement the reset_port in	 * the callbacks structures used to initialize the 802.11 stack.	 */	if (ieee->reset_on_keychange &&	    ieee->iw_mode != IW_MODE_INFRA &&	    ieee->reset_port && ieee->reset_port(dev)) {		IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);		return -EINVAL;	}	return ret;}int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,			       struct iw_request_info *info,			       union iwreq_data *wrqu, char *extra){	struct iw_point *encoding = &wrqu->encoding;	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;	struct ieee80211_security *sec = &ieee->sec;	int idx, max_key_len;	max_key_len = encoding->length - sizeof(*ext);	if (max_key_len < 0)		return -EINVAL;	idx = encoding->flags & IW_ENCODE_INDEX;	if (idx) {		if (idx < 1 || idx > WEP_KEYS)			return -EINVAL;		idx--;	} else		idx = ieee->tx_keyidx;	if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)		if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)			return -EINVAL;	encoding->flags = idx + 1;	memset(ext, 0, sizeof(*ext));	if (!sec->enabled) {		ext->alg = IW_ENCODE_ALG_NONE;		ext->key_len = 0;		encoding->flags |= IW_ENCODE_DISABLED;	} else {		if (sec->encode_alg[idx] == SEC_ALG_WEP)			ext->alg = IW_ENCODE_ALG_WEP;		else if (sec->encode_alg[idx] == SEC_ALG_TKIP)			ext->alg = IW_ENCODE_ALG_TKIP;		else if (sec->encode_alg[idx] == SEC_ALG_CCMP)			ext->alg = IW_ENCODE_ALG_CCMP;		else			return -EINVAL;		ext->key_len = sec->key_sizes[idx];		memcpy(ext->key, sec->keys[idx], ext->key_len);		encoding->flags |= IW_ENCODE_ENABLED;		if (ext->key_len &&		    (ext->alg == IW_ENCODE_ALG_TKIP ||		     ext->alg == IW_ENCODE_ALG_CCMP))			ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;	}	return 0;}EXPORT_SYMBOL(ieee80211_wx_set_encodeext);EXPORT_SYMBOL(ieee80211_wx_get_encodeext);#endifEXPORT_SYMBOL(ieee80211_wx_get_scan);EXPORT_SYMBOL(ieee80211_wx_set_encode);EXPORT_SYMBOL(ieee80211_wx_get_encode);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -