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

📄 isl_ioctl.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	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){	const u8 *a = mlme->address;	int n = snprintf(dest, IW_CUSTOM_MAX,			 "%s %s %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X %s (%2.2X)",			 str,			 ((priv->iw_mode == IW_MODE_MASTER) ? "from" : "to"),			 a[0], a[1], a[2], a[3], a[4], a[5],			 (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){	union iwreq_data wrqu;	char *memptr;	int n = strlen(str);	memptr = kmalloc(IW_CUSTOM_MAX, GFP_KERNEL);	if (!memptr)		return;	BUG_ON(n > IW_CUSTOM_MAX);	wrqu.data.pointer = memptr;	wrqu.data.length = n;	strcpy(memptr, str);	wireless_send_event(priv->ndev, IWEVCUSTOM, &wrqu, memptr);	kfree(memptr);}static voidlink_changed(struct net_device *ndev, u32 bitrate){	islpci_private *priv = netdev_priv(ndev);	if (bitrate) {		if (priv->iw_mode == IW_MODE_INFRA) {			union iwreq_data uwrq;			prism54_get_wap(ndev, NULL, (struct sockaddr *) &uwrq,					NULL);			wireless_send_event(ndev, SIOCGIWAP, &uwrq, NULL);		} else			send_simple_event(netdev_priv(ndev),					  "Link established");	} else		send_simple_event(netdev_priv(ndev), "Link lost");}/* Beacon/ProbeResp payload header */struct ieee80211_beacon_phdr {	u8 timestamp[8];	u16 beacon_int;	u16 capab_info;} __attribute__ ((packed));#define WLAN_EID_GENERIC 0xddstatic u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 };#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"static voidprism54_wpa_ie_add(islpci_private *priv, u8 *bssid,		   u8 *wpa_ie, size_t wpa_ie_len){	struct list_head *ptr;	struct islpci_bss_wpa_ie *bss = NULL;	if (wpa_ie_len > MAX_WPA_IE_LEN)		wpa_ie_len = MAX_WPA_IE_LEN;	if (down_interruptible(&priv->wpa_sem))		return;	/* try to use existing entry */	list_for_each(ptr, &priv->bss_wpa_list) {		bss = list_entry(ptr, struct islpci_bss_wpa_ie, list);		if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) {			list_move(&bss->list, &priv->bss_wpa_list);			break;		}		bss = NULL;	}	if (bss == NULL) {		/* add a new BSS entry; if max number of entries is already		 * reached, replace the least recently updated */		if (priv->num_bss_wpa >= MAX_BSS_WPA_IE_COUNT) {			bss = list_entry(priv->bss_wpa_list.prev,					 struct islpci_bss_wpa_ie, list);			list_del(&bss->list);		} else {			bss = kmalloc(sizeof (*bss), GFP_ATOMIC);			if (bss != NULL) {				priv->num_bss_wpa++;				memset(bss, 0, sizeof (*bss));			}		}		if (bss != NULL) {			memcpy(bss->bssid, bssid, ETH_ALEN);			list_add(&bss->list, &priv->bss_wpa_list);		}	}	if (bss != NULL) {		memcpy(bss->wpa_ie, wpa_ie, wpa_ie_len);		bss->wpa_ie_len = wpa_ie_len;		bss->last_update = jiffies;	} else {		printk(KERN_DEBUG "Failed to add BSS WPA entry for " MACSTR		       "\n", MAC2STR(bssid));	}	/* expire old entries from WPA list */	while (priv->num_bss_wpa > 0) {		bss = list_entry(priv->bss_wpa_list.prev,				 struct islpci_bss_wpa_ie, list);		if (!time_after(jiffies, bss->last_update + 60 * HZ))			break;		list_del(&bss->list);		priv->num_bss_wpa--;		kfree(bss);	}	up(&priv->wpa_sem);}static size_tprism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie){	struct list_head *ptr;	struct islpci_bss_wpa_ie *bss = NULL;	size_t len = 0;	if (down_interruptible(&priv->wpa_sem))		return 0;	list_for_each(ptr, &priv->bss_wpa_list) {		bss = list_entry(ptr, struct islpci_bss_wpa_ie, list);		if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0)			break;		bss = NULL;	}	if (bss) {		len = bss->wpa_ie_len;		memcpy(wpa_ie, bss->wpa_ie, len);	}	up(&priv->wpa_sem);	return len;}voidprism54_wpa_ie_init(islpci_private *priv){	INIT_LIST_HEAD(&priv->bss_wpa_list);	sema_init(&priv->wpa_sem, 1);}voidprism54_wpa_ie_clean(islpci_private *priv){	struct list_head *ptr, *n;	list_for_each_safe(ptr, n, &priv->bss_wpa_list) {		struct islpci_bss_wpa_ie *bss;		bss = list_entry(ptr, struct islpci_bss_wpa_ie, list);		kfree(bss);	}}static voidprism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr,			 u8 *payload, size_t len){	struct ieee80211_beacon_phdr *hdr;	u8 *pos, *end;	if (!priv->wpa)		return;	hdr = (struct ieee80211_beacon_phdr *) payload;	pos = (u8 *) (hdr + 1);	end = payload + len;	while (pos < end) {		if (pos + 2 + pos[1] > end) {			printk(KERN_DEBUG "Parsing Beacon/ProbeResp failed "			       "for " MACSTR "\n", MAC2STR(addr));			return;		}		if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 &&		    memcmp(pos + 2, wpa_oid, 4) == 0) {			prism54_wpa_ie_add(priv, addr, pos, pos[1] + 2);			return;		}		pos += 2 + pos[1];	}}static voidhandle_request(islpci_private *priv, struct obj_mlme *mlme, enum oid_num_t oid){	if (((mlme->state == DOT11_STATE_AUTHING) ||	     (mlme->state == DOT11_STATE_ASSOCING))	    && mgt_mlme_answer(priv)) {		/* Someone is requesting auth and we must respond. Just send back		 * the trap with error code set accordingly.		 */		mlme->code = prism54_mac_accept(&priv->acl,						mlme->address) ? 0 : 1;		mgt_set_request(priv, oid, 0, mlme);	}}static intprism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,			    char *data){	struct obj_mlme *mlme = (struct obj_mlme *) data;	struct obj_mlmeex *mlmeex = (struct obj_mlmeex *) data;	struct obj_mlmeex *confirm;	u8 wpa_ie[MAX_WPA_IE_LEN];	int wpa_ie_len;	size_t len = 0; /* u16, better? */	u8 *payload = NULL, *pos = NULL;	int ret;	/* I think all trapable objects are listed here.	 * Some oids have a EX version. The difference is that they are emitted	 * in DOT11_MLME_EXTENDED mode (set with DOT11_OID_MLMEAUTOLEVEL)	 * with more info.	 * The few events already defined by the wireless tools are not really	 * suited. We use the more flexible custom event facility.	 */	if (oid >= DOT11_OID_BEACON) {		len = mlmeex->size;		payload = pos = mlmeex->data;	}	/* I fear prism54_process_bss_data won't work with big endian data */	if ((oid == DOT11_OID_BEACON) || (oid == DOT11_OID_PROBE))		prism54_process_bss_data(priv, oid, mlmeex->address,					 payload, len);	mgt_le_to_cpu(isl_oid[oid].flags & OID_FLAG_TYPE, (void *) mlme);	switch (oid) {	case GEN_OID_LINKSTATE:		link_changed(priv->ndev, (u32) *data);		break;	case DOT11_OID_MICFAILURE:		send_simple_event(priv, "Mic failure");		break;	case DOT11_OID_DEAUTHENTICATE:		send_formatted_event(priv, "DeAuthenticate request", mlme, 0);		break;	case DOT11_OID_AUTHENTICATE:		handle_request(priv, mlme, oid);		send_formatted_event(priv, "Authenticate request", mlme, 1);		break;	case DOT11_OID_DISASSOCIATE:		send_formatted_event(priv, "Disassociate request", mlme, 0);		break;	case DOT11_OID_ASSOCIATE:		handle_request(priv, mlme, oid);		send_formatted_event(priv, "Associate request", mlme, 1);		break;	case DOT11_OID_REASSOCIATE:		handle_request(priv, mlme, oid);		send_formatted_event(priv, "ReAssociate request", mlme, 1);		break;	case DOT11_OID_BEACON:		send_formatted_event(priv,				     "Received a beacon from an unkown AP",				     mlme, 0);		break;	case DOT11_OID_PROBE:		/* we received a probe from a client. */		send_formatted_event(priv, "Received a probe from client", mlme,				     0);		break;		/* Note : "mlme" is actually a "struct obj_mlmeex *" here, but this		 * is backward compatible layout-wise with "struct obj_mlme".		 */	case DOT11_OID_DEAUTHENTICATEEX:		send_formatted_event(priv, "DeAuthenticate request", mlme, 0);		break;	case DOT11_OID_AUTHENTICATEEX:		handle_request(priv, mlme, oid);		send_formatted_event(priv, "Authenticate request (ex)", mlme, 1);		if (priv->iw_mode != IW_MODE_MASTER 				&& mlmeex->state != DOT11_STATE_AUTHING)			break;		confirm = kmalloc(sizeof(struct obj_mlmeex) + 6, GFP_ATOMIC);		if (!confirm) 			break;		memcpy(&confirm->address, mlmeex->address, ETH_ALEN);		printk(KERN_DEBUG "Authenticate from: address:\t%02x:%02x:%02x:%02x:%02x:%02x\n", 				mlmeex->address[0],				mlmeex->address[1],				mlmeex->address[2],				mlmeex->address[3],				mlmeex->address[4],				mlmeex->address[5]				);		confirm->id = -1; /* or mlmeex->id ? */		confirm->state = 0; /* not used */		confirm->code = 0;		confirm->size = 6;		confirm->data[0] = 0x00;		confirm->data[1] = 0x00;		confirm->data[2] = 0x02;		confirm->data[3] = 0x00;		confirm->data[4] = 0x00;		confirm->data[5] = 0x00;		ret = mgt_set_varlen(priv, DOT11_OID_ASSOCIATEEX, confirm, 6);		kfree(confirm);		if (ret)			return ret;		break;	case DOT11_OID_DISASSOCIATEEX:		send_formatted_event(priv, "Disassociate request (ex)", mlme, 0);		break;	case DOT11_OID_ASSOCIATEEX:		handle_request(priv, mlme, oid);		send_formatted_event(priv, "Associate request (ex)", mlme, 1);		if (priv->iw_mode != IW_MODE_MASTER 				&& mlmeex->state != DOT11_STATE_AUTHING)			break;				confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);		if (!confirm)			break;		memcpy(&confirm->address, mlmeex->address, ETH_ALEN);		confirm->id = ((struct obj_mlmeex *)mlme)->id;		confirm->state = 0; /* not used */		confirm->code = 0;		wpa_ie_len = prism54_wpa_ie_get(priv, mlmeex->address, wpa_ie);		if (!wpa_ie_len) {			printk(KERN_DEBUG "No WPA IE found from "					"address:\t%02x:%02x:%02x:%02x:%02x:%02x\n", 				mlmeex->address[0],				mlmeex->address[1],				mlmeex->address[2],				mlmeex->address[3],				mlmeex->address[4],				mlmeex->address[5]				);			kfree(confirm);			break;		}		confirm->size = wpa_ie_len;		memcpy(&confirm->data, wpa_ie, wpa_ie_len);		mgt_set_varlen(priv, oid, confirm, wpa_ie_len);		kfree(confirm);				break;	case DOT11_OID_REASSOCIATEEX:		handle_request(priv, mlme, oid);		send_formatted_event(priv, "Reassociate request (ex)", mlme, 1);		if (priv->iw_mode != IW_MODE_MASTER 				&& mlmeex->state != DOT11_STATE_ASSOCING)			break;		confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);		if (!confirm)			break;		memcpy(&confirm->address, mlmeex->address, ETH_ALEN);		confirm->id = mlmeex->id;		confirm->state = 0; /* not used */		confirm->code = 0;		wpa_ie_len = prism54_wpa_ie_get(priv, mlmeex->address, wpa_ie);		if (!wpa_ie_len) {			printk(KERN_DEBUG "No WPA IE found from "					"address:\t%02x:%02x:%02x:%02x:%02x:%02x\n", 				mlmeex->address[0],				mlmeex->address[1],				mlmeex->address[2],				mlmeex->address[3],				mlmeex->address[4],				mlmeex->address[5]				);			kfree(confirm);			break;		}		confirm->size = wpa_ie_len; 		memcpy(&confirm->data, wpa_ie, wpa_ie_len);		mgt_set_varlen(priv, oid, confirm, wpa_ie_len);		kfree(confirm);				break;	default:		return -EINVAL;	}	return 0;}/* * Process a device trap.  This is called via schedule_work(), outside of * interrupt context, no locks held. */voidprism54_process_trap(void *data){	struct islpci_mgmtframe *frame = data;	struct net_device *ndev = frame->ndev;	enum oid_num_t n = mgt_oidtonum(frame->header->oid);	if (n != OID_NUM_LAST)		prism54_process_trap_helper(netdev_priv(ndev), n, frame->data);	islpci_mgt_release(frame);}intprism54_set_mac_address(struct net_device *ndev, void *addr){	islpci_private *priv = netdev_priv(ndev);	int ret;	if (ndev->addr_len != 6)		return -EINVAL;	ret = mgt_set_request(priv, GEN_OID_MACADDRESS, 0,			      &((struct sockaddr *) addr)->sa_data);	if (!ret)		memcpy(priv->ndev->dev_addr,		       &((struct sockaddr *) addr)->sa_data, 6);	return ret;}

⌨️ 快捷键说明

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