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

📄 isl_ioctl.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	union oid_res_t r;	int rvalue = 0;	vwrq->disabled = 0;	/* It cannot be disabled */	if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {		/* we are asked for the life time */		rvalue =		    mgt_get_request(priv, DOT11_OID_MAXTXLIFETIME, 0, NULL, &r);		vwrq->value = r.u * 1024;		vwrq->flags = IW_RETRY_LIFETIME;	} else if ((vwrq->flags & IW_RETRY_MAX)) {		/* we are asked for the long retry limit */		rvalue |=		    mgt_get_request(priv, DOT11_OID_LONGRETRIES, 0, NULL, &r);		vwrq->value = r.u;		vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;	} else {		/* default. get the  short retry limit */		rvalue |=		    mgt_get_request(priv, DOT11_OID_SHORTRETRIES, 0, NULL, &r);		vwrq->value = r.u;		vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MIN;	}	return rvalue;}static intprism54_set_encode(struct net_device *ndev, struct iw_request_info *info,		   struct iw_point *dwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	int rvalue = 0, force = 0;	int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;	union oid_res_t r;	/* with the new API, it's impossible to get a NULL pointer.	 * New version of iwconfig set the IW_ENCODE_NOKEY flag	 * when no key is given, but older versions don't. */	if (dwrq->length > 0) {		/* we have a key to set */		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;		int current_index;		struct obj_key key = { DOT11_PRIV_WEP, 0, "" };		/* get the current key index */		rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);		current_index = r.u;		/* Verify that the key is not marked as invalid */		if (!(dwrq->flags & IW_ENCODE_NOKEY)) {			key.length = dwrq->length > sizeof (key.key) ?			    sizeof (key.key) : dwrq->length;			memcpy(key.key, extra, key.length);			if (key.length == 32)				/* we want WPA-PSK */				key.type = DOT11_PRIV_TKIP;			if ((index < 0) || (index > 3))				/* no index provided use the current one */				index = current_index;			/* now send the key to the card  */			rvalue |=			    mgt_set_request(priv, DOT11_OID_DEFKEYX, index,					    &key);		}		/*		 * If a valid key is set, encryption should be enabled 		 * (user may turn it off later).		 * This is also how "iwconfig ethX key on" works		 */		if ((index == current_index) && (key.length > 0))			force = 1;	} else {		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;		if ((index >= 0) && (index <= 3)) {			/* we want to set the key index */			rvalue |=			    mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,					    &index);		} else {			if (!dwrq->flags & IW_ENCODE_MODE) {				/* we cannot do anything. Complain. */				return -EINVAL;			}		}	}	/* now read the flags */	if (dwrq->flags & IW_ENCODE_DISABLED) {		/* Encoding disabled, 		 * authen = DOT11_AUTH_OS;		 * invoke = 0;		 * exunencrypt = 0; */	}	if (dwrq->flags & IW_ENCODE_OPEN)		/* Encode but accept non-encoded packets. No auth */		invoke = 1;	if ((dwrq->flags & IW_ENCODE_RESTRICTED) || force) {		/* Refuse non-encoded packets. Auth */		authen = DOT11_AUTH_BOTH;		invoke = 1;		exunencrypt = 1;	}	/* do the change if requested  */	if ((dwrq->flags & IW_ENCODE_MODE) || force) {		rvalue |=		    mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);		rvalue |=		    mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke);		rvalue |=		    mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,				    &exunencrypt);	}	return rvalue;}static intprism54_get_encode(struct net_device *ndev, struct iw_request_info *info,		   struct iw_point *dwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	struct obj_key *key;	u32 devindex, index = (dwrq->flags & IW_ENCODE_INDEX) - 1;	u32 authen = 0, invoke = 0, exunencrypt = 0;	int rvalue;	union oid_res_t r;	/* first get the flags */	rvalue = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);	authen = r.u;	rvalue |= mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);	invoke = r.u;	rvalue |= mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);	exunencrypt = r.u;	if (invoke && (authen == DOT11_AUTH_BOTH) && exunencrypt)		dwrq->flags = IW_ENCODE_RESTRICTED;	else if ((authen == DOT11_AUTH_OS) && !exunencrypt) {		if (invoke)			dwrq->flags = IW_ENCODE_OPEN;		else			dwrq->flags = IW_ENCODE_DISABLED;	} else		/* The card should not work in this state */		dwrq->flags = 0;	/* get the current device key index */	rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);	devindex = r.u;	/* Now get the key, return it */	if ((index < 0) || (index > 3))		/* no index provided, use the current one */		index = devindex;	rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);	key = r.ptr;	dwrq->length = key->length;	memcpy(extra, key->key, dwrq->length);	kfree(key);	/* return the used key index */	dwrq->flags |= devindex + 1;	return rvalue;}static intprism54_get_txpower(struct net_device *ndev, struct iw_request_info *info,		    struct iw_param *vwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	union oid_res_t r;	int rvalue;	rvalue = mgt_get_request(priv, OID_INL_OUTPUTPOWER, 0, NULL, &r);	/* intersil firmware operates in 0.25 dBm (1/4 dBm) */	vwrq->value = (s32) r.u / 4;	vwrq->fixed = 1;	/* radio is not turned of	 * btw: how is possible to turn off only the radio 	 */	vwrq->disabled = 0;	return rvalue;}static intprism54_set_txpower(struct net_device *ndev, struct iw_request_info *info,		    struct iw_param *vwrq, char *extra){	islpci_private *priv = netdev_priv(ndev);	s32 u = vwrq->value;	/* intersil firmware operates in 0.25 dBm (1/4) */	u *= 4;	if (vwrq->disabled) {		/* don't know how to disable radio */		printk(KERN_DEBUG		       "%s: %s() disabling radio is not yet supported.\n",		       priv->ndev->name, __FUNCTION__);		return -ENOTSUPP;	} else if (vwrq->fixed)		/* currently only fixed value is supported */		return mgt_set_request(priv, OID_INL_OUTPUTPOWER, 0, &u);	else {		printk(KERN_DEBUG		       "%s: %s() auto power will be implemented later.\n",		       priv->ndev->name, __FUNCTION__);		return -ENOTSUPP;	}}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((islpci_private *) ndev->priv, 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((islpci_private *) ndev->priv, 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((islpci_private *) ndev->priv, 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 list_head *ptr;	struct sockaddr *addr = (struct sockaddr *) extra;	if (addr->sa_family != ARPHRD_ETHER)		return -EOPNOTSUPP;	if (down_interruptible(&acl->sem))		return -ERESTARTSYS;	for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) {		entry = list_entry(ptr, struct mac_entry, _list);		if (memcmp(entry->addr, addr->sa_data, ETH_ALEN) == 0) {			list_del(ptr);			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 list_head *ptr;	struct sockaddr *dst = (struct sockaddr *) extra;	dwrq->length = 0;	if (down_interruptible(&acl->sem))		return -ERESTARTSYS;	for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) {		entry = list_entry(ptr, struct mac_entry, _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 list_head *ptr;	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;	}	for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) {		entry = list_entry(ptr, struct mac_entry, _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);

⌨️ 快捷键说明

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