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

📄 p80211wext.c

📁 对于无线网卡采用prism芯片的linux的开源驱动.
💻 C
📖 第 1 页 / 共 3 页
字号:
        int err = 0;                                      DBFENTER;	       if (!wlan_wext_write) {                err = (-EOPNOTSUPP);                 goto exit;            }        msg.msgcode = DIDmsg_dot11req_mibset;        switch (rrq->value) {          case 1 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel1; break;          case 2 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel2; break;          case 3 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel3; break;          case 4 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel4; break;          case 5 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel5; break;          case 6 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel6; break;          case 7 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel7; break;          case 8 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8; break;          default: mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8; break;	}        memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));        result = p80211req_dorequest(wlandev, (UINT8*)&msg);        if (result) {                err = -EFAULT;                goto exit;        } exit:        DBFEXIT;        return err;}static int p80211wext_giwtxpow(netdevice_t *dev,			       struct iw_request_info *info,			       struct iw_param *rrq, char *extra){	wlandevice_t *wlandev = (wlandevice_t*)dev->priv;	p80211item_uint32_t             mibitem;	p80211msg_dot11req_mibset_t     msg;	int result;	int err = 0;	DBFENTER;	msg.msgcode = DIDmsg_dot11req_mibget;	mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));	result = p80211req_dorequest(wlandev, (UINT8*)&msg);	if (result) {		err = -EFAULT;		goto exit;	}	memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));	// XXX handle OFF by setting disabled = 1;	rrq->flags = 0; // IW_TXPOW_DBM;	rrq->disabled = 0;	rrq->fixed = 0;	rrq->value = mibitem.data; exit:	DBFEXIT;	return err;}#endif /* WIRELESS_EXT > 9 */static int p80211wext_siwspy(netdevice_t *dev,			     struct iw_request_info *info,			     struct iw_point *srq, char *extra){	wlandevice_t *wlandev = (wlandevice_t*)dev->priv;        struct sockaddr address[IW_MAX_SPY];        int number = srq->length;        int i;	DBFENTER;	/* Copy the data from the input buffer */	memcpy(address, extra, sizeof(struct sockaddr)*number);         wlandev->spy_number = 0;        if (number > 0) {                /* extract the addresses */                for (i = 0; i < number; i++) {                        memcpy(wlandev->spy_address[i], address[i].sa_data, ETH_ALEN);		}                /* reset stats */                memset(wlandev->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY);                /* set number of addresses */                wlandev->spy_number = number;        }	DBFEXIT;	return 0;}/* jkriegl: from orinoco, modified */static int p80211wext_giwspy(netdevice_t *dev,			     struct iw_request_info *info,			     struct iw_point *srq, char *extra){	wlandevice_t *wlandev = (wlandevice_t*)dev->priv;        struct sockaddr address[IW_MAX_SPY];        struct iw_quality spy_stat[IW_MAX_SPY];        int number;        int i;	DBFENTER;        number = wlandev->spy_number;        if (number > 0) {                /* populate address and spy struct's */                for (i = 0; i < number; i++) {                        memcpy(address[i].sa_data, wlandev->spy_address[i], ETH_ALEN);                        address[i].sa_family = AF_UNIX;                	memcpy(&spy_stat[i], &wlandev->spy_stat[i], sizeof(struct iw_quality));                }		/* reset update flag */                for (i=0; i < number; i++)                        wlandev->spy_stat[i].updated = 0;        }        /* push stuff to user space */        srq->length = number;	memcpy(extra, address, sizeof(struct sockaddr)*number); 	memcpy(extra+sizeof(struct sockaddr)*number, spy_stat, sizeof(struct iw_quality)*number); 	DBFEXIT;	return 0;}int prism2_result2err (int prism2_result){	int err = 0;	switch (prism2_result) {		case P80211ENUM_resultcode_invalid_parameters:			err = -EINVAL;			break;		case P80211ENUM_resultcode_implementation_failure:			err = -EIO;			break;		case P80211ENUM_resultcode_not_supported:			err = -EOPNOTSUPP;			break;		default:			err = 0;			break;	}	return err;}#if WIRELESS_EXT > 13static int p80211wext_siwscan(netdevice_t *dev,			     struct iw_request_info *info,			     struct iw_point *srq, char *extra){	wlandevice_t *wlandev = (wlandevice_t*)dev->priv;	p80211msg_dot11req_scan_t	msg;		int result;	int err = 0;	int i = 0;	DBFENTER;	if (wlandev->macmode == WLAN_MACMODE_ESS_AP) {		WLAN_LOG_ERROR("Can't scan in AP mode\n");		err = (-EOPNOTSUPP);		goto exit;	}	memset(&msg, 0x00, sizeof(p80211msg_dot11req_scan_t));	msg.msgcode = DIDmsg_dot11req_scan;	msg.bsstype.data = P80211ENUM_bsstype_any;	memset(&(msg.bssid.data), 0xFF, sizeof (p80211item_pstr6_t));	msg.bssid.data.len = 6;	msg.scantype.data = P80211ENUM_scantype_active;	msg.probedelay.data = 0;	for (i = 0; i < 14; i++)		msg.channellist.data.data[i] = i;	msg.channellist.data.len = 14;	msg.maxchanneltime.data = 250;	msg.minchanneltime.data = 200;	result = p80211req_dorequest(wlandev, (UINT8*)&msg);	if (result)		err = prism2_result2err (msg.resultcode.data); exit:	DBFEXIT;	return err;}/* Helper to translate scan into Wireless Extensions scan results. * Inspired by the prism54 code, which was in turn inspired by the * airo driver code. */static char *wext_translate_bss(char *current_ev, char *end_buf, p80211msg_dot11req_scan_results_t *bss){	struct iw_event iwe;	/* Temporary buffer */	/* The first entry must be the MAC address */	memcpy(iwe.u.ap_addr.sa_data, bss->bssid.data.data, WLAN_BSSID_LEN);	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;	iwe.cmd = SIOCGIWAP;	current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);	/* The following entries will be displayed in the same order we give them */	/* The ESSID. */	if (bss->ssid.data.len > 0) {		char essid[IW_ESSID_MAX_SIZE + 1];		int size;		size = wlan_min(IW_ESSID_MAX_SIZE, bss->ssid.data.len);		memset(&essid, 0, sizeof (essid));		memcpy(&essid, bss->ssid.data.data, size);		WLAN_LOG_DEBUG(1, " essid size = %d\n", size);		iwe.u.data.length = size;		iwe.u.data.flags = 1;		iwe.cmd = SIOCGIWESSID;		current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, &essid[0]);		WLAN_LOG_DEBUG(1, " essid size OK.\n");	}	switch (bss->bsstype.data) {		case P80211ENUM_bsstype_infrastructure:			iwe.u.mode = IW_MODE_MASTER;			break;		case P80211ENUM_bsstype_independent:			iwe.u.mode = IW_MODE_ADHOC;			break;		default:			iwe.u.mode = 0;				break;	}	iwe.cmd = SIOCGIWMODE;	if (iwe.u.mode)		current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);	/* Encryption capability */	if (bss->privacy.data == P80211ENUM_truth_true)		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;	else		iwe.u.data.flags = IW_ENCODE_DISABLED;	iwe.u.data.length = 0;	iwe.cmd = SIOCGIWENCODE;	current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL);	/* Add frequency. (short) bss->channel is the frequency in MHz */	iwe.u.freq.m = bss->dschannel.data;	iwe.u.freq.e = 0;	iwe.cmd = SIOCGIWFREQ;	current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);	/* Add quality statistics */	iwe.u.qual.level = bss->signal.data;	iwe.u.qual.noise = bss->noise.data;	/* do a simple SNR for quality */	iwe.u.qual.qual = bss->signal.data - bss->noise.data;	iwe.cmd = IWEVQUAL;	current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);	return current_ev;}static int p80211wext_giwscan(netdevice_t *dev,			     struct iw_request_info *info,			     struct iw_point *srq, char *extra){	wlandevice_t *wlandev = (wlandevice_t*)dev->priv;	p80211msg_dot11req_scan_results_t	msg;	int result = 0;	int err = 0;	int i = 0;	int scan_good = 0;	char *current_ev = extra;	DBFENTER;	/* Since wireless tools doesn't really have a way of passing how	 * many scan results results there were back here, keep grabbing them	 * until we fail.	 */	do {		memset(&msg, 0, sizeof(msg));		msg.msgcode = DIDmsg_dot11req_scan_results;		msg.bssindex.data = i;		result = p80211req_dorequest(wlandev, (UINT8*)&msg);		if ((result != 0) || 		    (msg.resultcode.data != P80211ENUM_resultcode_success)) {			break;		}		  		current_ev = wext_translate_bss(current_ev, extra + IW_SCAN_MAX_DATA, &msg);		scan_good = 1;		i++;	} while (i < IW_MAX_AP);	srq->length = (current_ev - extra);	srq->flags = 0;	/* todo */	if (result && !scan_good)		err = prism2_result2err (msg.resultcode.data);	DBFEXIT;	return err;}#endif/*typedef int (*iw_handler)(netdevice_t *dev, struct iw_request_info *info,                          union iwreq_data *wrqu, char *extra);*/#if WIRELESS_EXT > 12static iw_handler p80211wext_handlers[] =  {	(iw_handler) p80211wext_siwcommit,		/* SIOCSIWCOMMIT */	(iw_handler) p80211wext_giwname,		/* SIOCGIWNAME */	(iw_handler) NULL,				/* SIOCSIWNWID */	(iw_handler) NULL,				/* SIOCGIWNWID */	(iw_handler) p80211wext_siwfreq,  		/* SIOCSIWFREQ */	(iw_handler) p80211wext_giwfreq,  		/* SIOCGIWFREQ */	(iw_handler) p80211wext_siwmode,       		/* SIOCSIWMODE */	(iw_handler) p80211wext_giwmode,       		/* SIOCGIWMODE */	(iw_handler) NULL,                 		/* SIOCSIWSENS */	(iw_handler) NULL,                		/* SIOCGIWSENS */	(iw_handler) NULL, /* not used */     		/* SIOCSIWRANGE */	(iw_handler) p80211wext_giwrange,      		/* SIOCGIWRANGE */	(iw_handler) NULL, /* not used */     		/* SIOCSIWPRIV */	(iw_handler) NULL, /* kernel code */   		/* SIOCGIWPRIV */	(iw_handler) NULL, /* not used */     		/* SIOCSIWSTATS */	(iw_handler) NULL, /* kernel code */   		/* SIOCGIWSTATS */	(iw_handler) p80211wext_siwspy,			/* SIOCSIWSPY */	(iw_handler) p80211wext_giwspy,			/* SIOCGIWSPY */	(iw_handler) NULL,				/* -- hole -- */	(iw_handler) NULL,				/* -- hole -- */	(iw_handler) NULL,              		/* SIOCSIWAP */	(iw_handler) p80211wext_giwap,         		/* SIOCGIWAP */	(iw_handler) NULL,				/* -- hole -- */	(iw_handler) NULL,                  		/* SIOCGIWAPLIST */#if WIRELESS_EXT > 13	(iw_handler) p80211wext_siwscan,			/* SIOCSIWSCAN */	(iw_handler) p80211wext_giwscan,			/* SIOCGIWSCAN */#else /* WIRELESS_EXT > 13 */	(iw_handler) NULL,	/* null */		/* SIOCSIWSCAN */	(iw_handler) NULL,	/* null */		/* SIOCGIWSCAN */#endif /* WIRELESS_EXT > 13 */	(iw_handler) p80211wext_siwessid,  		/* SIOCSIWESSID */	(iw_handler) p80211wext_giwessid,      		/* SIOCGIWESSID */	(iw_handler) NULL,                 		/* SIOCSIWNICKN */	(iw_handler) p80211wext_giwessid,      		/* SIOCGIWNICKN */	(iw_handler) NULL,				/* -- hole -- */	(iw_handler) NULL,				/* -- hole -- */	(iw_handler) NULL,                		/* SIOCSIWRATE */	(iw_handler) p80211wext_giwrate,      		/* SIOCGIWRATE */	(iw_handler) p80211wext_siwrts,  		/* SIOCSIWRTS */	(iw_handler) p80211wext_giwrts,        		/* SIOCGIWRTS */	(iw_handler) p80211wext_siwfrag,      		/* SIOCSIWFRAG */	(iw_handler) p80211wext_giwfrag,   		/* SIOCGIWFRAG */	(iw_handler) p80211wext_siwtxpow,           	/* SIOCSIWTXPOW */	(iw_handler) p80211wext_giwtxpow,  		/* SIOCGIWTXPOW */	(iw_handler) p80211wext_siwretry,     		/* SIOCSIWRETRY */	(iw_handler) p80211wext_giwretry,  		/* SIOCGIWRETRY */	(iw_handler) p80211wext_siwencode,     		/* SIOCSIWENCODE */	(iw_handler) p80211wext_giwencode,  		/* SIOCGIWENCODE */	(iw_handler) NULL,                 		/* SIOCSIWPOWER */	(iw_handler) NULL,                  		/* SIOCGIWPOWER */};struct iw_handler_def p80211wext_handler_def = {	.num_standard = sizeof(p80211wext_handlers) / sizeof(iw_handler),	.num_private = 0,	.num_private_args = 0,        .standard = p80211wext_handlers,	.private = NULL,	.private_args = NULL,#if WIRELESS_EXT > 16	.get_wireless_stats = p80211wext_get_wireless_stats#endif};#endif/* wireless extensions' ioctls */ int p80211wext_support_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd){	wlandevice_t *wlandev = (wlandevice_t*)dev->priv;#if WIRELESS_EXT < 13	struct iwreq *iwr = (struct iwreq*)ifr;#endif	p80211item_uint32_t             mibitem;	int err = 0;	DBFENTER;	mibitem.status = P80211ENUM_msgitem_status_data_ok;		if ( wlandev->msdstate != WLAN_MSD_RUNNING ) {		err = -ENODEV;		goto exit;	}	WLAN_LOG_DEBUG(1, "Received wireless extension ioctl #%d.\n", cmd);	switch (cmd) {#if WIRELESS_EXT < 13	case SIOCSIWNAME:  /* unused  */		err = (-EOPNOTSUPP);		break;	case SIOCGIWNAME: /* get name == wireless protocol */                err = p80211wext_giwname(dev, NULL, (char *) &iwr->u, NULL);		break;		case SIOCSIWNWID:	case SIOCGIWNWID:		err = (-EOPNOTSUPP);		break;	case SIOCSIWFREQ: /* set channel */                err = p80211wext_siwfreq(dev, NULL, &(iwr->u.freq), NULL);		break;	case SIOCGIWFREQ: /* get channel */                err = p80211wext_giwfreq(dev, NULL, &(iwr->u.freq), NULL);		break;	case SIOCSIWRANGE:	case SIOCSIWPRIV:		case SIOCSIWAP: /* set access point MAC addresses (BSSID) */			err = (-EOPNOTSUPP);		break;	case SIOCGIWAP:	/* get access point MAC addresses (BSSID) */                err = p80211wext_giwap(dev, NULL, &(iwr->u.ap_addr), NULL);		break;#if WIRELESS_EXT > 8	case SIOCSIWMODE: /* set operation mode */	case SIOCSIWESSID: /* set SSID (network name) */	case SIOCSIWRATE: /* set default bit rate (bps) */			err = (-EOPNOTSUPP);		break;			case SIOCGIWMODE: /* get operation mode */		err = p80211wext_giwmode(dev, NULL, &iwr->u.mode, NULL);		break;	case SIOCGIWNICKN: /* get node name/nickname */	case SIOCGIWESSID: /* get SSID */		if(iwr->u.essid.pointer) {                        char ssid[IW_ESSID_MAX_SIZE+1];			memset(ssid, 0, sizeof(ssid));			err = p80211wext_giwessid(dev, NULL, &iwr->u.essid, ssid);			if(copy_to_user(iwr->u.essid.pointer, ssid, sizeof(ssid)))				err = (-EFAULT);		}		break;	case SIOCGIWRATE:                err = p80211wext_giwrate(dev, NULL, &iwr->u.bitrate, NULL);		break;	case SIOCGIWRTS:			err = p80211wext_giwrts(dev, NULL, &iwr->u.rts, NULL);			break;	case SIOCGIWFRAG:		err = p80211wext_giwfrag(dev, NULL, &iwr->u.rts, NULL);			break;	case SIOCGIWENCODE:		if (!capable(CAP_NET_ADMIN))			err = -EPERM;		else if (iwr->u.encoding.pointer) {			char keybuf[MAX_KEYLEN];			err = p80211wext_giwencode(dev, NULL,						     &iwr->u.encoding, keybuf);			if (copy_to_user(iwr->u.encoding.pointer, keybuf,					 iwr->u.encoding.length))				err = -EFAULT;		}		break;	case SIOCGIWAPLIST:		case SIOCSIWRTS:	case SIOCSIWFRAG:		case SIOCSIWSENS:	case SIOCGIWSENS:	case SIOCSIWNICKN: /* set node name/nickname */		case SIOCSIWENCODE: /* set encoding token & mode */		case SIOCSIWSPY:	case SIOCGIWSPY:	case SIOCSIWPOWER:		case SIOCGIWPOWER:	case SIOCGIWPRIV:		err = (-EOPNOTSUPP);		break;	case SIOCGIWRANGE:		if(iwr->u.data.pointer != NULL) {                        struct iw_range range;                        err = p80211wext_giwrange(dev, NULL, &iwr->u.data,						  (char *) &range);			/* Push that up to the caller */			if (copy_to_user(iwr->u.data.pointer, &range, sizeof(range)))				err = -EFAULT;		}		break;#endif /* WIRELESS_EXT > 8 */#if WIRELESS_EXT > 9	case SIOCSIWTXPOW:		err = (-EOPNOTSUPP);		break;		case SIOCGIWTXPOW:			err = p80211wext_giwtxpow(dev, NULL, &iwr->u.txpower, NULL);		break;#endif /* WIRELESS_EXT > 9 */		#if WIRELESS_EXT > 10	case SIOCSIWRETRY:			err = (-EOPNOTSUPP);		break;	case SIOCGIWRETRY:			err = p80211wext_giwretry(dev, NULL, &iwr->u.retry, NULL);		break;#endif /* WIRELESS_EXT > 10 */		#endif /* WIRELESS_EXT <= 12 */	default:		err = (-EOPNOTSUPP);		break;	} exit:	DBFEXIT;	return (err);}int p80211wext_event_associated(wlandevice_t *wlandev, int assoc){        union iwreq_data data;        DBFENTER;#if WIRELESS_EXT > 13        /* Send the association state first */        data.ap_addr.sa_family = ARPHRD_ETHER;        if (assoc) {                memcpy(data.ap_addr.sa_data, wlandev->bssid, WLAN_ADDR_LEN);        } else {                memset(data.ap_addr.sa_data, 0, WLAN_ADDR_LEN);        }               if (wlan_wext_write)                wireless_send_event(wlandev->netdev, SIOCGIWAP, &data, NULL);        if (!assoc) goto done;        // XXX send association data, like IEs, etc etc.#endif done:        DBFEXIT;        return 0;}#endif /* compatibility to wireless extensions */

⌨️ 快捷键说明

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