compat.c

来自「和我之前上载的intel 802.11协议源码是配套的」· C语言 代码 · 共 599 行 · 第 1/2 页

C
599
字号
	if (param->u.crypt.idx != 0)		group_key = 1;	sec.flags |= SEC_ENABLED | SEC_ENCRYPT;	if (strcmp(param->u.crypt.alg, "none") == 0) {		if (crypt) {			sec.enabled = 0;			sec.encrypt = 0;			sec.level = SEC_LEVEL_0;			sec.flags |= SEC_LEVEL;			ieee80211_crypt_delayed_deinit(ieee, crypt);		}		goto done;	}	sec.enabled = 1;	sec.encrypt = 1;	/* IPW HW cannot build TKIP MIC, host decryption still needed. */	if (strcmp(param->u.crypt.alg, "TKIP") == 0) {		if (group_key)			ieee->host_mc_decrypt = 1;		else			ieee->host_encrypt_msdu = 1;	}	/*if (!(ieee->host_encrypt || ieee->host_encrypt_msdu ||	   ieee->host_decrypt))	   goto skip_host_crypt; */	if (group_key ? !ieee->host_mc_decrypt :	    !(ieee->host_encrypt || ieee->host_decrypt ||	      ieee->host_encrypt_msdu))		goto skip_host_crypt;	ops = ieee80211_get_crypto_ops(param->u.crypt.alg);	if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {		request_module("ieee80211_crypt_wep");		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);	} else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {		request_module("ieee80211_crypt_tkip");		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);	} else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {		request_module("ieee80211_crypt_ccmp");		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);	}	if (ops == NULL) {		IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",			       dev->name, param->u.crypt.alg);		param->u.crypt.err = IPW_CRYPT_ERR_UNKNOWN_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(param->u.crypt.idx);		if (new_crypt->priv == NULL) {			kfree(new_crypt);			param->u.crypt.err = IPW_CRYPT_ERR_CRYPT_INIT_FAILED;			ret = -EINVAL;			goto done;		}		*crypt = new_crypt;	}	if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&	    (*crypt)->ops->set_key(param->u.crypt.key,				   param->u.crypt.key_len, param->u.crypt.seq,				   (*crypt)->priv) < 0) {		IPW_DEBUG_INFO("%s: key setting failed\n", dev->name);		param->u.crypt.err = IPW_CRYPT_ERR_KEY_SET_FAILED;		ret = -EINVAL;		goto done;	}      skip_host_crypt:	if (param->u.crypt.set_tx) {		ieee->tx_keyidx = param->u.crypt.idx;		sec.active_key = param->u.crypt.idx;		sec.flags |= SEC_ACTIVE_KEY;	} else		sec.flags &= ~SEC_ACTIVE_KEY;	if (param->u.crypt.alg != NULL) {		memcpy(sec.keys[param->u.crypt.idx],		       param->u.crypt.key, param->u.crypt.key_len);		sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;		sec.flags |= (1 << param->u.crypt.idx);		if (strcmp(param->u.crypt.alg, "WEP") == 0) {			sec.flags |= SEC_LEVEL;			sec.level = SEC_LEVEL_1;		} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {			sec.flags |= SEC_LEVEL;			sec.level = SEC_LEVEL_2;		} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {			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)) {		IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);		param->u.crypt.err = IPW_CRYPT_ERR_CARD_CONF_FAILED;		return -EINVAL;	}	return ret;}static int ipw_wpa_supplicant(struct net_device *dev, struct iw_point *p){	struct ipw_param *param;	struct ipw_priv *priv = ieee80211_priv(dev);	int ret = 0;	IPW_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);	if (p->length < sizeof(struct ipw_param) || !p->pointer)		return -EINVAL;	param = (struct ipw_param *)kmalloc(p->length, GFP_KERNEL);	if (param == NULL)		return -ENOMEM;	if (copy_from_user(param, p->pointer, p->length)) {		kfree(param);		return -EFAULT;	}	mutex_lock(&priv->mutex);	switch (param->cmd) {	case IPW_CMD_SET_WPA_PARAM:		ret = ipw_wpa_set_param(dev, param->u.wpa_param.name,					param->u.wpa_param.value);		break;	case IPW_CMD_SET_WPA_IE:		ret = ipw_wpa_set_wpa_ie(dev, param, p->length);		break;	case IPW_CMD_SET_ENCRYPTION:		ret = ipw_wpa_set_encryption(dev, param, p->length);		break;	case IPW_CMD_MLME:		ret = ipw_wpa_mlme(dev, param->u.mlme.command,				   param->u.mlme.reason_code);		break;	default:		IPW_ERROR("%s: Unknown WPA supplicant request: %d\n",			  dev->name, param->cmd);		ret = -EOPNOTSUPP;	}	mutex_unlock(&priv->mutex);	if (ret == 0 && copy_to_user(p->pointer, param, p->length))		ret = -EFAULT;	kfree(param);	return ret;}static int ipw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd){	struct iwreq *wrq = (struct iwreq *)rq;	int ret = -1;	switch (cmd) {	case IPW_IOCTL_WPA_SUPPLICANT:		ret = ipw_wpa_supplicant(dev, &wrq->u.data);		return ret;	default:		return -EOPNOTSUPP;	}	return -EOPNOTSUPP;}#endif/* GEO code borrowed from ieee80211_geo.c */static int ipw_is_valid_channel(struct ieee80211_device *ieee, u8 channel){	int i;	/* Driver needs to initialize the geography map before using	 * these helper functions */	BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);	if (ieee->freq_band & IEEE80211_24GHZ_BAND)		for (i = 0; i < ieee->geo.bg_channels; i++)			/* NOTE: If G mode is currently supported but			 * this is a B only channel, we don't see it			 * as valid. */			if ((ieee->geo.bg[i].channel == channel) &&			    (!(ieee->mode & IEEE_G) ||			     !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))				return IEEE80211_24GHZ_BAND;	if (ieee->freq_band & IEEE80211_52GHZ_BAND)		for (i = 0; i < ieee->geo.a_channels; i++)			if (ieee->geo.a[i].channel == channel)				return IEEE80211_52GHZ_BAND;	return 0;}static int ipw_channel_to_index(struct ieee80211_device *ieee, u8 channel){	int i;	/* Driver needs to initialize the geography map before using	 * these helper functions */	BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);	if (ieee->freq_band & IEEE80211_24GHZ_BAND)		for (i = 0; i < ieee->geo.bg_channels; i++)			if (ieee->geo.bg[i].channel == channel)				return i;	if (ieee->freq_band & IEEE80211_52GHZ_BAND)		for (i = 0; i < ieee->geo.a_channels; i++)			if (ieee->geo.a[i].channel == channel)				return i;	return -1;}static u8 ipw_freq_to_channel(struct ieee80211_device *ieee, u32 freq){	int i;	/* Driver needs to initialize the geography map before using	 * these helper functions */	BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);	freq /= 100000;	if (ieee->freq_band & IEEE80211_24GHZ_BAND)		for (i = 0; i < ieee->geo.bg_channels; i++)			if (ieee->geo.bg[i].freq == freq)				return ieee->geo.bg[i].channel;	if (ieee->freq_band & IEEE80211_52GHZ_BAND)		for (i = 0; i < ieee->geo.a_channels; i++)			if (ieee->geo.a[i].freq == freq)				return ieee->geo.a[i].channel;	return 0;}static int ipw_set_geo(struct ieee80211_device *ieee,		       const struct ieee80211_geo *geo){	memcpy(ieee->geo.name, geo->name, 3);	ieee->geo.name[3] = '\0';	ieee->geo.bg_channels = geo->bg_channels;	ieee->geo.a_channels = geo->a_channels;	memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *	       sizeof(struct ieee80211_channel));	memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *	       sizeof(struct ieee80211_channel));	return 0;}static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *ieee){	return &ieee->geo;}

⌨️ 快捷键说明

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