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

📄 if_an.c

📁 访问基于802.1x认证方式的网络
💻 C
📖 第 1 页 / 共 4 页
字号:
	case AN_RID_SSIDLIST:		ssid = (struct an_ltv_ssidlist *)areq;		bcopy((char *)ssid, (char *)&sc->an_ssidlist,			sizeof(struct an_ltv_ssidlist));		break;	case AN_RID_APLIST:		ap = (struct an_ltv_aplist *)areq;		bcopy((char *)ap, (char *)&sc->an_aplist,			sizeof(struct an_ltv_aplist));		break;	case AN_RID_TX_SPEED:		sp = (struct an_ltv_gen *)areq;		sc->an_tx_rate = sp->an_val;		break;	case AN_RID_WEP_TEMP:	case AN_RID_WEP_PERM:		/* Disable the MAC. */      	        /* an_cmd(sc, AN_CMD_DISABLE, 0); */		/* Write the key */		an_write_record(sc, (struct an_ltv_gen *)areq);		/* Turn the MAC back on. */		/* an_cmd(sc, AN_CMD_ENABLE, 0); */		return;		break;	case AN_RID_MONITOR_MODE:		cfg = (struct an_ltv_genconfig *)areq;		bpfdetach(ifp);		if (ng_ether_detach_p != NULL)			(*ng_ether_detach_p) (ifp);		sc->an_monitor = cfg->an_len;		if (sc->an_monitor & AN_MONITOR) {			if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER) {				bpfattach(ifp, DLT_AIRONET_HEADER,					sizeof(struct ether_header));			} else {				bpfattach(ifp, DLT_IEEE802_11,					sizeof(struct ether_header));			}		} else {			bpfattach(ifp, DLT_EN10MB,				  sizeof(struct ether_header));			if (ng_ether_attach_p != NULL)				(*ng_ether_attach_p) (ifp);		}		break;	default:		printf("an%d: unknown RID: %x\n", sc->an_unit, areq->an_type);		return;		break;	}	/* Reinitialize the card. */	if (ifp->if_flags)		an_init(sc);	return;}/* * Derived from Linux driver to enable promiscious mode. */static voidan_promisc(sc, promisc)	struct an_softc		*sc;	int			promisc;{	if (sc->an_was_monitor)		an_reset(sc);	if (sc->an_monitor || sc->an_was_monitor)		an_init(sc);	sc->an_was_monitor = sc->an_monitor;	an_cmd(sc, AN_CMD_SET_MODE, promisc ? 0xffff : 0);	return;}static intan_ioctl(ifp, command, data)	struct ifnet		*ifp;	u_long			command;	caddr_t			data;{	int			s, error = 0;	int			len;	int			i;	struct an_softc		*sc;	struct an_req		areq;	struct ifreq		*ifr;	struct proc		*p = curproc;	struct ieee80211req	*ireq;	u_int8_t		tmpstr[IEEE80211_NWID_LEN*2];	u_int8_t		*tmpptr;	struct an_ltv_genconfig	*config;	struct an_ltv_key	*key;	struct an_ltv_status	*status;	struct an_ltv_ssidlist	*ssids;	s = splimp();	sc = ifp->if_softc;	ifr = (struct ifreq *)data;	ireq = (struct ieee80211req *)data;	config = (struct an_ltv_genconfig *)&areq;	key = (struct an_ltv_key *)&areq;	status = (struct an_ltv_status *)&areq;	ssids = (struct an_ltv_ssidlist *)&areq;	if (sc->an_gone) {		error = ENODEV;		goto out;	}	switch (command) {	case SIOCSIFADDR:	case SIOCGIFADDR:	case SIOCSIFMTU:		error = ether_ioctl(ifp, command, data);		break;	case SIOCSIFFLAGS:		if (ifp->if_flags & IFF_UP) {			if (ifp->if_flags & IFF_RUNNING &&			    ifp->if_flags & IFF_PROMISC &&			    !(sc->an_if_flags & IFF_PROMISC)) {				an_promisc(sc, 1);			} else if (ifp->if_flags & IFF_RUNNING &&			    !(ifp->if_flags & IFF_PROMISC) &&			    sc->an_if_flags & IFF_PROMISC) {				an_promisc(sc, 0);			} else				an_init(sc);		} else {			if (ifp->if_flags & IFF_RUNNING)				an_stop(sc);		}		sc->an_if_flags = ifp->if_flags;		error = 0;		break;	case SIOCSIFMEDIA:	case SIOCGIFMEDIA:		error = ifmedia_ioctl(ifp, ifr, &sc->an_ifmedia, command);		break;	case SIOCADDMULTI:	case SIOCDELMULTI:		/* The Aironet has no multicast filter. */		error = 0;		break;	case SIOCGAIRONET:		error = copyin(ifr->ifr_data, &areq, sizeof(areq));		if (error != 0)			break;#ifdef ANCACHE		if (areq.an_type == AN_RID_ZERO_CACHE) {			sc->an_sigitems = sc->an_nextitem = 0;			break;		} else if (areq.an_type == AN_RID_READ_CACHE) {			char *pt = (char *)&areq.an_val;			bcopy((char *)&sc->an_sigitems, (char *)pt,			    sizeof(int));			pt += sizeof(int);			areq.an_len = sizeof(int) / 2;			bcopy((char *)&sc->an_sigcache, (char *)pt,			    sizeof(struct an_sigcache) * sc->an_sigitems);			areq.an_len += ((sizeof(struct an_sigcache) *			    sc->an_sigitems) / 2) + 1;		} else#endif		if (an_read_record(sc, (struct an_ltv_gen *)&areq)) {			error = EINVAL;			break;		}		error = copyout(&areq, ifr->ifr_data, sizeof(areq));		break;	case SIOCSAIRONET:		if ((error = suser(p)))			goto out;		error = copyin(ifr->ifr_data, &areq, sizeof(areq));		if (error != 0)			break;		an_setdef(sc, &areq);		break;	case SIOCG80211:		areq.an_len = sizeof(areq);		switch (ireq->i_type) {		case IEEE80211_IOC_SSID:			if (ireq->i_val == -1) {				areq.an_type = AN_RID_STATUS;				if (an_read_record(sc,				    (struct an_ltv_gen *)&areq)) {					error = EINVAL;					break;				}				len = status->an_ssidlen;				tmpptr = status->an_ssid;			} else if (ireq->i_val >= 0) {				areq.an_type = AN_RID_SSIDLIST;				if (an_read_record(sc,				    (struct an_ltv_gen *)&areq)) {					error = EINVAL;					break;				}				if (ireq->i_val == 0) {					len = ssids->an_ssid1_len;					tmpptr = ssids->an_ssid1;				} else if (ireq->i_val == 1) {					len = ssids->an_ssid2_len;					tmpptr = ssids->an_ssid3;				} else if (ireq->i_val == 1) {					len = ssids->an_ssid3_len;					tmpptr = ssids->an_ssid3;				} else {					error = EINVAL;					break;				}			} else {				error = EINVAL;				break;			}			if (len > IEEE80211_NWID_LEN) {				error = EINVAL;				break;			}			ireq->i_len = len;			bzero(tmpstr, IEEE80211_NWID_LEN);			bcopy(tmpptr, tmpstr, len);			error = copyout(tmpstr, ireq->i_data,			    IEEE80211_NWID_LEN);			break;		case IEEE80211_IOC_NUMSSIDS:			ireq->i_val = 3;			break;		case IEEE80211_IOC_WEP:			areq.an_type = AN_RID_ACTUALCFG;			if (an_read_record(sc,			    (struct an_ltv_gen *)&areq)) {				error = EINVAL;				break;			}			if (config->an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE) {				if (config->an_authtype &				    AN_AUTHTYPE_ALLOW_UNENCRYPTED)					ireq->i_val = IEEE80211_WEP_MIXED;				else					ireq->i_val = IEEE80211_WEP_ON;			} else {				ireq->i_val = IEEE80211_WEP_OFF;			}			break;		case IEEE80211_IOC_WEPKEY:			/*			 * XXX: I'm not entierly convinced this is			 * correct, but it's what is implemented in			 * ancontrol so it will have to do until we get			 * access to actual Cisco code.			 */			if (ireq->i_val < 0 || ireq->i_val > 7) {				error = EINVAL;				break;			}			len = 0;			if (ireq->i_val < 4) {				areq.an_type = AN_RID_WEP_TEMP;				for (i = 0; i < 5; i++) {					if (an_read_record(sc,					    (struct an_ltv_gen *)&areq)) {						error = EINVAL;						break;					}					if (key->kindex == 0xffff)						break;					if (key->kindex == ireq->i_val)						len = key->klen;					/* Required to get next entry */					areq.an_type = AN_RID_WEP_PERM;				}				if (error != 0)					break;			}			/* We aren't allowed to read the value of the			 * key from the card so we just output zeros			 * like we would if we could read the card, but			 * denied the user access.			 */			bzero(tmpstr, len);			ireq->i_len = len;			error = copyout(tmpstr, ireq->i_data, len);			break;		case IEEE80211_IOC_NUMWEPKEYS:			ireq->i_val = 8;			break;		case IEEE80211_IOC_WEPTXKEY:			/*			 * For some strange reason, you have to read all			 * keys before you can read the txkey.			 */			areq.an_type = AN_RID_WEP_TEMP;			for (i = 0; i < 5; i++) {				if (an_read_record(sc,				    (struct an_ltv_gen *)&areq)) {					error = EINVAL;					break;				}				if (key->kindex == 0xffff)					break;				/* Required to get next entry */				areq.an_type = AN_RID_WEP_PERM;			}			if (error != 0)				break;			areq.an_type = AN_RID_WEP_PERM;			key->kindex = 0xffff;			if (an_read_record(sc,			    (struct an_ltv_gen *)&areq)) {				error = EINVAL;				break;			}			ireq->i_val = key->mac[0];			break;		case IEEE80211_IOC_AUTHMODE:			areq.an_type = AN_RID_ACTUALCFG;			if (an_read_record(sc,			    (struct an_ltv_gen *)&areq)) {				error = EINVAL;				break;			}			if ((config->an_authtype & AN_AUTHTYPE_MASK) ==			    AN_AUTHTYPE_NONE) {			    ireq->i_val = IEEE80211_AUTH_NONE;			} else if ((config->an_authtype & AN_AUTHTYPE_MASK) ==			    AN_AUTHTYPE_OPEN) {			    ireq->i_val = IEEE80211_AUTH_OPEN;			} else if ((config->an_authtype & AN_AUTHTYPE_MASK) ==			    AN_AUTHTYPE_SHAREDKEY) {			    ireq->i_val = IEEE80211_AUTH_SHARED;			} else				error = EINVAL;			break;		case IEEE80211_IOC_STATIONNAME:			areq.an_type = AN_RID_ACTUALCFG;			if (an_read_record(sc,			    (struct an_ltv_gen *)&areq)) {				error = EINVAL;				break;			}			ireq->i_len = sizeof(config->an_nodename);			tmpptr = config->an_nodename;			bzero(tmpstr, IEEE80211_NWID_LEN);			bcopy(tmpptr, tmpstr, ireq->i_len);			error = copyout(tmpstr, ireq->i_data,			    IEEE80211_NWID_LEN);			break;		case IEEE80211_IOC_CHANNEL:			areq.an_type = AN_RID_STATUS;			if (an_read_record(sc,			    (struct an_ltv_gen *)&areq)) {				error = EINVAL;				break;			}			ireq->i_val = status->an_cur_channel;			break;		case IEEE80211_IOC_POWERSAVE:			areq.an_type = AN_RID_ACTUALCFG;			if (an_read_record(sc,			    (struct an_ltv_gen *)&areq)) {				error = EINVAL;				break;			}			if (config->an_psave_mode == AN_PSAVE_NONE) {				ireq->i_val = IEEE80211_POWERSAVE_OFF;			} else if (config->an_psave_mode == AN_PSAVE_CAM) {				ireq->i_val = IEEE80211_POWERSAVE_CAM;			} else if (config->an_psave_mode == AN_PSAVE_PSP) {				ireq->i_val = IEEE80211_POWERSAVE_PSP;			} else if (config->an_psave_mode == AN_PSAVE_PSP_CAM) {				ireq->i_val = IEEE80211_POWERSAVE_PSP_CAM;			} else				error = EINVAL;			break;		case IEEE80211_IOC_POWERSAVESLEEP:			areq.an_type = AN_RID_ACTUALCFG;			if (an_read_record(sc,			    (struct an_ltv_gen *)&areq)) {				error = EINVAL;				break;			}			ireq->i_val = config->an_listen_interval;			break;		}		break;	case SIOCS80211:		if ((error = suser(p)))			goto out;		areq.an_len = sizeof(areq);		/*		 * We need a config structure for everything but the WEP		 * key management and SSIDs so we get it now so avoid		 * duplicating this code every time.		 */		if (ireq->i_type != IEEE80211_IOC_SSID &&		    ireq->i_type != IEEE80211_IOC_WEPKEY &&		    ireq->i_type != IEEE80211_IOC_WEPTXKEY) {			areq.an_type = AN_RID_GENCONFIG;			if (an_read_record(sc,			    (struct an_ltv_gen *)&areq)) {				error = EINVAL;				break;			}		}		switch (ireq->i_type) {		case IEEE80211_IOC_SSID:			areq.an_type = AN_RID_SSIDLIST;			if (an_read_record(sc,			    (struct an_ltv_gen *)&areq)) {				error = EINVAL;				break;			}			if (ireq->i_len > IEEE80211_NWID_LEN) {				error = EINVAL;				break;			}			switch (ireq->i_val) {			case 0:				error = copyin(ireq->i_data,				    ssids->an_ssid1, ireq->i_len);				ssids->an_ssid1_len = ireq->i_len;				break;			case 1:				error = copyin(ireq->i_data,				    ssids->an_ssid2, ireq->i_len);				ssids->an_ssid2_len = ireq->i_len;				break;			case 2:				error = copyin(ireq->i_data,				    ssids->an_ssid3, ireq->i_len);				ssids->an_ssid3_len = ireq->i_len;				break;			default:				error = EINVAL;				break;			}			break;		case IEEE80211_IOC_WEP:			switch (ireq->i_val) {			case IEEE80211_WEP_OFF:				config->an_authtype &=				    ~(AN_AUTHTYPE_PRIVACY_IN_USE |				    AN_AUTHTYPE_ALLOW_UNENCRYPTED);				break;			case IEEE80211_WEP_ON:				config->an_authtype |=				    AN_AUTHTYPE_PRIVACY_IN_USE;				config->an_authtype &=				    ~AN_AUTHTYPE_ALLOW_UNENCRYPTED;				break;			case IEEE80211_WEP_MIXED:				config->an_authtype |=				    AN_AUTHTYPE_PRIVACY_IN_USE |				    AN_AUTHTYPE_ALLOW_UNENCRYPTED;				break;			default:				error = EINVAL;				break;			}			break;		case IEEE80211_IOC_WEPKEY:			if (ireq->i_val < 0 || ireq->i_val > 7 ||			    ireq->i_len > 13) {				error = EINVAL;				break;			}			error = copyin(ireq->i_data, tmpstr, 13);			if (error != 0)				break;			bzero(&areq, sizeof(struct an_ltv_key));			areq.an_len = sizeof(struct an_ltv_key);			key->mac[0] = 1;	/* The others are 0. */			key->kindex = ireq->i_val % 4;			if (ireq->i_val < 4)				areq.an_type = AN_RID_WEP_TEMP;			else				areq.an_type = AN_RID_WEP_PERM;			key->klen = ireq->i_len;			bcopy(tmpstr, key->key, key->klen);			break;		case IEEE80211_IOC_WEPTXKEY:			if (ireq->i_val < 0 || ireq->i_val > 3) {				error = EINVAL;				break;			}			bzero(&areq, sizeof(struct an_ltv_key));			areq.an_len = sizeof(struct an_ltv_key);			areq.an_type = AN_RID_WEP_PERM;			key->kindex = 0xffff;			key->mac[0] = ireq->i_val;			break;		case IEEE80211_IOC_AUTHMODE:			switch (ireq->i_val) {			case IEEE80211_AUTH_NONE:				config->an_authtype = AN_AUTHTYPE_NONE |				    (config->an_authtype & ~AN_AUTHTYPE_MASK);				break;			case IEEE80211_AUTH_OPEN:				config->an_authtype = AN_AUTHTYPE_OPEN |				    (config->an_authtype & ~AN_AUTHTYPE_MASK);				break;			case IEEE80211_AUTH_SHARED:				config->an_authtype = AN_AUTHTYPE_SHAREDKEY |				    (config->an_authtype & ~AN_AUTHTYPE_MASK);				break;			default:				error = EINVAL;			}			break;		case IEEE80211_IOC_STATIONNAME:			if (ireq->i_len > 16) {				error = EINVAL;				break;			}			bzero(config->an_nodename, 16);			error = copyin(ireq->i_data,			    config->an_nodename, ireq->i_len);			break;		case IEEE80211_IOC_CHANNEL:			/*			 * The actual range is 1-14, but if you set it			 * to 0 you get the default so we let that work			 * too.			 */			if (ireq->i_val < 0 || ireq->i_val >14) {				error = EINVAL;				break;			}			config->an_ds_channel = ireq->i_val;			break;		case IEEE80211_IOC_POWERSAVE:			switch (ireq->i_val) {			case IEEE80211_POWERSAVE_OFF:				config->an_psave_mode = AN_PSAVE_NONE;				break;			case IEEE80211_POWERSAVE_CAM:				config->an_psave_mode = AN_PSAVE_CAM;				break;			case IEEE80211_POWERSAVE_PSP:				config->an_psave_mode = AN_PSAVE_PSP;				break;			case IEEE80211_POWERSAVE_PSP_CAM:				config->an_psave_mode = AN_PSAVE_PSP_CAM;				break;			default:				error = EINVAL;				break;			}			break;		case IEEE80211_IOC_POWERSAVESLEEP:			config->an_listen_interval = ireq->i_val;			break;		}		if (!error)			an_setdef(sc, &areq);		break;	default:		error = EINVAL;		break;

⌨️ 快捷键说明

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