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

📄 isl_ioctl.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (islpci_get_state(priv) < PRV_STATE_INIT)		return 0;	/* Determine and validate the key index */	idx = (encoding->flags & IW_ENCODE_INDEX) - 1;	if (idx) {		if (idx < 0 || idx > 3)			return -EINVAL;	} else {		ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);		if (ret < 0)			goto out;		idx = r.u;	}	if (encoding->flags & IW_ENCODE_DISABLED)		alg = IW_ENCODE_ALG_NONE;	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {		/* Only set transmit key index here, actual		 * key is set below if needed.		 */		ret = mgt_set_request(priv, DOT11_OID_DEFKEYID, 0, &idx);		set_key = ext->key_len > 0 ? 1 : 0;	}	if (set_key) {		struct obj_key key = { DOT11_PRIV_WEP, 0, "" };		switch (alg) {		case IW_ENCODE_ALG_NONE:			break;		case IW_ENCODE_ALG_WEP:			if (ext->key_len > KEY_SIZE_WEP104) {				ret = -EINVAL;				goto out;			}			if (ext->key_len > KEY_SIZE_WEP40)				key.length = KEY_SIZE_WEP104;			else				key.length = KEY_SIZE_WEP40;			break;		case IW_ENCODE_ALG_TKIP:			if (ext->key_len > KEY_SIZE_TKIP) {				ret = -EINVAL;				goto out;			}			key.type = DOT11_PRIV_TKIP;			key.length = KEY_SIZE_TKIP;			break;		default:			return -EINVAL;		}		if (key.length) {			memset(key.key, 0, sizeof(key.key));			memcpy(key.key, ext->key, ext->key_len);			ret = mgt_set_request(priv, DOT11_OID_DEFKEYX, idx,					    &key);			if (ret < 0)				goto out;		}	}	/* Read the flags */	if (encoding->flags & IW_ENCODE_DISABLED) {		/* Encoding disabled,		 * authen = DOT11_AUTH_OS;		 * invoke = 0;		 * exunencrypt = 0; */	}	if (encoding->flags & IW_ENCODE_OPEN) {		/* Encode but accept non-encoded packets. No auth */		invoke = 1;	}	if (encoding->flags & IW_ENCODE_RESTRICTED) {		/* Refuse non-encoded packets. Auth */		authen = DOT11_AUTH_BOTH;		invoke = 1;		exunencrypt = 1;	}	/* do the change if requested  */	if (encoding->flags & IW_ENCODE_MODE) {		ret = mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0,				      &authen);		ret = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0,				      &invoke);		ret = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,				      &exunencrypt);	}out:	return ret;}static int prism54_get_encodeext(struct net_device *ndev,				 struct iw_request_info *info,				 union iwreq_data *wrqu,				 char *extra){	islpci_private *priv = netdev_priv(ndev);	struct iw_point *encoding = &wrqu->encoding;	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;	int idx, max_key_len;	union oid_res_t r;	int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0, wpa = 0;	int ret = 0;	if (islpci_get_state(priv) < PRV_STATE_INIT)		return 0;	/* first get the flags */	ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);	authen = r.u;	ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);	invoke = r.u;	ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);	exunencrypt = r.u;	if (ret < 0)		goto out;	max_key_len = encoding->length - sizeof(*ext);	if (max_key_len < 0)		return -EINVAL;	idx = (encoding->flags & IW_ENCODE_INDEX) - 1;	if (idx) {		if (idx < 0 || idx > 3)			return -EINVAL;	} else {		ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);		if (ret < 0)			goto out;		idx = r.u;	}	encoding->flags = idx + 1;	memset(ext, 0, sizeof(*ext));	switch (authen) {	case DOT11_AUTH_BOTH:	case DOT11_AUTH_SK:		wrqu->encoding.flags |= IW_ENCODE_RESTRICTED;	case DOT11_AUTH_OS:	default:		wrqu->encoding.flags |= IW_ENCODE_OPEN;		break;	}	down_write(&priv->mib_sem);	wpa = priv->wpa;	up_write(&priv->mib_sem);	if (authen == DOT11_AUTH_OS && !exunencrypt && !invoke && !wpa) {		/* No encryption */		ext->alg = IW_ENCODE_ALG_NONE;		ext->key_len = 0;		wrqu->encoding.flags |= IW_ENCODE_DISABLED;	} else {		struct obj_key *key;		ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, idx, NULL, &r);		if (ret < 0)			goto out;		key = r.ptr;		if (max_key_len < key->length) {			ret = -E2BIG;			goto out;		}		memcpy(ext->key, key->key, key->length);		ext->key_len = key->length;		switch (key->type) {		case DOT11_PRIV_TKIP:			ext->alg = IW_ENCODE_ALG_TKIP;			break;		default:		case DOT11_PRIV_WEP:			ext->alg = IW_ENCODE_ALG_WEP;			break;		}		wrqu->encoding.flags |= IW_ENCODE_ENABLED;	}out:	return ret;}static intprism54_reset(struct net_device *ndev, struct iw_request_info *info,	      __u32 * uwrq, char *extra){	islpci_reset(netdev_priv(ndev), 0);	return 0;}static intprism54_get_oid(struct net_device *ndev, struct iw_request_info *info,		struct iw_point *dwrq, char *extra){	union oid_res_t r;	int rvalue;	enum oid_num_t n = dwrq->flags;	rvalue = mgt_get_request(netdev_priv(ndev), n, 0, NULL, &r);	dwrq->length = mgt_response_to_str(n, &r, extra);	if ((isl_oid[n].flags & OID_FLAG_TYPE) != OID_TYPE_U32)		kfree(r.ptr);	return rvalue;}static intprism54_set_u32(struct net_device *ndev, struct iw_request_info *info,		__u32 * uwrq, char *extra){	u32 oid = uwrq[0], u = uwrq[1];	return mgt_set_request(netdev_priv(ndev), oid, 0, &u);}static intprism54_set_raw(struct net_device *ndev, struct iw_request_info *info,		struct iw_point *dwrq, char *extra){	u32 oid = dwrq->flags;	return mgt_set_request(netdev_priv(ndev), oid, 0, extra);}voidprism54_acl_init(struct islpci_acl *acl){	sema_init(&acl->sem, 1);	INIT_LIST_HEAD(&acl->mac_list);	acl->size = 0;	acl->policy = MAC_POLICY_OPEN;}static voidprism54_clear_mac(struct islpci_acl *acl){	struct list_head *ptr, *next;	struct mac_entry *entry;	if (down_interruptible(&acl->sem))		return;	if (acl->size == 0) {		up(&acl->sem);		return;	}	for (ptr = acl->mac_list.next, next = ptr->next;	     ptr != &acl->mac_list; ptr = next, next = ptr->next) {		entry = list_entry(ptr, struct mac_entry, _list);		list_del(ptr);		kfree(entry);	}	acl->size = 0;	up(&acl->sem);}voidprism54_acl_clean(struct islpci_acl *acl){	prism54_clear_mac(acl);}static intprism54_add_mac(struct net_device *ndev, struct iw_request_info *info,		struct sockaddr *awrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	struct islpci_acl *acl = &priv->acl;	struct mac_entry *entry;	struct sockaddr *addr = (struct sockaddr *) extra;	if (addr->sa_family != ARPHRD_ETHER)		return -EOPNOTSUPP;	entry = kmalloc(sizeof (struct mac_entry), GFP_KERNEL);	if (entry == NULL)		return -ENOMEM;	memcpy(entry->addr, addr->sa_data, ETH_ALEN);	if (down_interruptible(&acl->sem)) {		kfree(entry);		return -ERESTARTSYS;	}	list_add_tail(&entry->_list, &acl->mac_list);	acl->size++;	up(&acl->sem);	return 0;}static intprism54_del_mac(struct net_device *ndev, struct iw_request_info *info,		struct sockaddr *awrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	struct islpci_acl *acl = &priv->acl;	struct mac_entry *entry;	struct sockaddr *addr = (struct sockaddr *) extra;	if (addr->sa_family != ARPHRD_ETHER)		return -EOPNOTSUPP;	if (down_interruptible(&acl->sem))		return -ERESTARTSYS;	list_for_each_entry(entry, &acl->mac_list, _list) {		if (memcmp(entry->addr, addr->sa_data, ETH_ALEN) == 0) {			list_del(&entry->_list);			acl->size--;			kfree(entry);			up(&acl->sem);			return 0;		}	}	up(&acl->sem);	return -EINVAL;}static intprism54_get_mac(struct net_device *ndev, struct iw_request_info *info,		struct iw_point *dwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	struct islpci_acl *acl = &priv->acl;	struct mac_entry *entry;	struct sockaddr *dst = (struct sockaddr *) extra;	dwrq->length = 0;	if (down_interruptible(&acl->sem))		return -ERESTARTSYS;	list_for_each_entry(entry, &acl->mac_list, _list) {		memcpy(dst->sa_data, entry->addr, ETH_ALEN);		dst->sa_family = ARPHRD_ETHER;		dwrq->length++;		dst++;	}	up(&acl->sem);	return 0;}/* Setting policy also clears the MAC acl, even if we don't change the defaut * policy */static intprism54_set_policy(struct net_device *ndev, struct iw_request_info *info,		   __u32 * uwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	struct islpci_acl *acl = &priv->acl;	u32 mlmeautolevel;	prism54_clear_mac(acl);	if ((*uwrq < MAC_POLICY_OPEN) || (*uwrq > MAC_POLICY_REJECT))		return -EINVAL;	down_write(&priv->mib_sem);	acl->policy = *uwrq;	/* the ACL code needs an intermediate mlmeautolevel */	if ((priv->iw_mode == IW_MODE_MASTER) &&	    (acl->policy != MAC_POLICY_OPEN))		mlmeautolevel = DOT11_MLME_INTERMEDIATE;	else		mlmeautolevel = CARD_DEFAULT_MLME_MODE;	if (priv->wpa)		mlmeautolevel = DOT11_MLME_EXTENDED;	mgt_set(priv, DOT11_OID_MLMEAUTOLEVEL, &mlmeautolevel);	/* restart the card with our new policy */	if (mgt_commit(priv)) {		up_write(&priv->mib_sem);		return -EIO;	}	up_write(&priv->mib_sem);	return 0;}static intprism54_get_policy(struct net_device *ndev, struct iw_request_info *info,		   __u32 * uwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	struct islpci_acl *acl = &priv->acl;	*uwrq = acl->policy;	return 0;}/* Return 1 only if client should be accepted. */static intprism54_mac_accept(struct islpci_acl *acl, char *mac){	struct mac_entry *entry;	int res = 0;	if (down_interruptible(&acl->sem))		return -ERESTARTSYS;	if (acl->policy == MAC_POLICY_OPEN) {		up(&acl->sem);		return 1;	}	list_for_each_entry(entry, &acl->mac_list, _list) {		if (memcmp(entry->addr, mac, ETH_ALEN) == 0) {			res = 1;			break;		}	}	res = (acl->policy == MAC_POLICY_ACCEPT) ? !res : res;	up(&acl->sem);	return res;}static intprism54_kick_all(struct net_device *ndev, struct iw_request_info *info,		 struct iw_point *dwrq, char *extra){	struct obj_mlme *mlme;	int rvalue;	mlme = kmalloc(sizeof (struct obj_mlme), GFP_KERNEL);	if (mlme == NULL)		return -ENOMEM;	/* Tell the card to kick every client */	mlme->id = 0;	rvalue =	    mgt_set_request(netdev_priv(ndev), DOT11_OID_DISASSOCIATE, 0, mlme);	kfree(mlme);	return rvalue;}static intprism54_kick_mac(struct net_device *ndev, struct iw_request_info *info,		 struct sockaddr *awrq, char *extra){	struct obj_mlme *mlme;	struct sockaddr *addr = (struct sockaddr *) extra;	int rvalue;	if (addr->sa_family != ARPHRD_ETHER)		return -EOPNOTSUPP;	mlme = kmalloc(sizeof (struct obj_mlme), GFP_KERNEL);	if (mlme == NULL)		return -ENOMEM;	/* Tell the card to only kick the corresponding bastard */	memcpy(mlme->address, addr->sa_data, ETH_ALEN);	mlme->id = -1;	rvalue =	    mgt_set_request(netdev_priv(ndev), DOT11_OID_DISASSOCIATE, 0, mlme);	kfree(mlme);	return rvalue;}/* Translate a TRAP oid into a wireless event. Called in islpci_mgt_receive. */static voidformat_event(islpci_private *priv, char *dest, const char *str,	     const struct obj_mlme *mlme, u16 *length, int error){	DECLARE_MAC_BUF(mac);	int n = snprintf(dest, IW_CUSTOM_MAX,			 "%s %s %s %s (%2.2X)",			 str,			 ((priv->iw_mode == IW_MODE_MASTER) ? "from" : "to"),			 print_mac(mac, mlme->address),			 (error ? (mlme->code ? " : REJECTED " : " : ACCEPTED ")			  : ""), mlme->code);	BUG_ON(n > IW_CUSTOM_MAX);	*length = n;}static voidsend_formatted_event(islpci_private *priv, const char *str,		     const struct obj_mlme *mlme, int error){	union iwreq_data wrqu;	char *memptr;	memptr = kmalloc(IW_CUSTOM_MAX, GFP_KERNEL);	if (!memptr)		return;	wrqu.data.pointer = memptr;	wrqu.data.length = 0;	format_event(priv, memptr, str, mlme, &wrqu.data.length,		     error);	wireless_send_event(priv->ndev, IWEVCUSTOM, &wrqu, memptr);	kfree(memptr);}static voidsend_simple_event(islpci_private *priv, const char *str){

⌨️ 快捷键说明

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