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

📄 an.c

📁 访问基于802.1x认证方式的网络
💻 C
📖 第 1 页 / 共 3 页
字号:
	CSR_WRITE_2(sc, AN_PARAM0, val);	CSR_WRITE_2(sc, AN_PARAM1, 0);	CSR_WRITE_2(sc, AN_PARAM2, 0);	DELAY(10);	CSR_WRITE_2(sc, AN_COMMAND, cmd);	DELAY(10);	for (i = AN_TIMEOUT; i--; DELAY(10)) {		if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_CMD)			break;		else {			if (CSR_READ_2(sc, AN_COMMAND) == cmd) {				DELAY(10);				CSR_WRITE_2(sc, AN_COMMAND, cmd);			}		}	}	stat = CSR_READ_2(sc, AN_STATUS);	/* clear stuck command busy if needed */	if (CSR_READ_2(sc, AN_COMMAND) & AN_CMD_BUSY) {		CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CLR_STUCK_BUSY);	}	/* Ack the command */	CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CMD);	if (i <= 0)		return(ETIMEDOUT);	if (stat & AN_STAT_CMD_RESULT)		return(EIO);	return(0);}/* * This reset sequence may look a little strange, but this is the * most reliable method I've found to really kick the NIC in the * head and force it to reboot correctly. */voidan_reset(sc)	struct an_softc		*sc;{	if (sc->an_gone)		return;/*printf("ena ");*/	an_cmd(sc, AN_CMD_ENABLE, 0);/* printf("rst ");*/	an_cmd(sc, AN_CMD_FW_RESTART, 0);/*printf("nop ");*/	an_cmd(sc, AN_CMD_NOOP2, 0);	if (an_cmd(sc, AN_CMD_FORCE_SYNCLOSS, 0) == ETIMEDOUT)		printf("%s: reset failed\n", sc->sc_dev.dv_xname);	an_cmd(sc, AN_CMD_DISABLE, 0);}/* * Read an LTV record from the NIC. */intan_read_record(sc, ltv)	struct an_softc		*sc;	struct an_ltv_gen	*ltv;{	u_int16_t	*ptr, len;	int		i;	u_int16_t	ltv_data_length;	if (ltv->an_len < 4 || ltv->an_type == 0)		return(EINVAL);	/* Tell the NIC to enter record read mode. */	if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) {		printf("%s: RID 0x%04x access failed\n",		    sc->sc_dev.dv_xname, ltv->an_type);		return(EIO);	}	/* Seek to the record. */	if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) {		printf("%s: RID 0x%04x seek to record failed\n",		    sc->sc_dev.dv_xname, ltv->an_type);		return(EIO);	}	/*	 * Read the length to make sure it	 * matches what we expect (this verifies that we have enough	 * room to hold all of the returned data).	 */	len = CSR_READ_2(sc, AN_DATA1);	/*	 * Work out record's data length, which is struct length - type word	 * as we have just read the length.	 */	ltv_data_length = ltv->an_len - sizeof(u_int16_t);	if (len > ltv_data_length) {		printf("%s: RID 0x%04x record length mismatch -- expected %d, "		    "got %d\n", sc->sc_dev.dv_xname, ltv->an_type,		    ltv_data_length, len);		return(ENOSPC);	}	/* Now read the data. */	ptr = ltv->an_val;	for (i = 0; i < (len - 1) >> 1; i++)		ptr[i] = CSR_READ_2(sc, AN_DATA1);#if BYTE_ORDER == BIG_ENDIAN	switch (ltv->an_type) {	case AN_RID_GENCONFIG:		an_swap16(&ltv->an_val[4], 7); /* an_macaddr, an_rates */		an_swap16(&ltv->an_val[63], 8);  /* an_nodename */		break;	case AN_RID_SSIDLIST:		an_swap16(&ltv->an_val[1], 16); /* an_ssid1 */		an_swap16(&ltv->an_val[18], 16); /* an_ssid2 */		an_swap16(&ltv->an_val[35], 16); /* an_ssid3 */		break;	case AN_RID_APLIST:		an_swap16(ltv->an_val, 12);		break;	case AN_RID_DRVNAME:		an_swap16(ltv->an_val, 8);		break;	case AN_RID_CAPABILITIES:		an_swap16(ltv->an_val, 2);	/* an_oui */		an_swap16(&ltv->an_val[3], 34); /* an_manufname .. an_aironetaddr */		an_swap16(&ltv->an_val[39], 8); /* an_callid .. an_tx_diversity */		break;	case AN_RID_STATUS:		an_swap16(&ltv->an_val[0], 3);	/* an_macaddr */		an_swap16(&ltv->an_val[7], 36);	/* an_ssid .. an_prev_bssid3 */		an_swap16(&ltv->an_val[0x74/2], 2);	/* an_ap_ip_addr */		break;	case AN_RID_WEP_VOLATILE:	case AN_RID_WEP_PERMANENT:		an_swap16(&ltv->an_val[1], 3);	/* an_mac_addr */		an_swap16(&ltv->an_val[5], 6);		break;	case AN_RID_32BITS_CUM:		for (i = 0x60; i--; ) {			u_int16_t t = ltv->an_val[i * 2] ^ ltv->an_val[i * 2 + 1];			ltv->an_val[i * 2] ^= t;			ltv->an_val[i * 2 + 1] ^= t;		}		break;	}#endif	return(0);}/* * Same as read, except we inject data instead of reading it. */intan_write_record(sc, ltv)	struct an_softc		*sc;	struct an_ltv_gen	*ltv;{	u_int16_t	*ptr;	int		i;	if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type))		return(EIO);	if (an_seek(sc, ltv->an_type, 0, AN_BAP1))		return(EIO);#if BYTE_ORDER == BIG_ENDIAN	switch (ltv->an_type) {	case AN_RID_GENCONFIG:		an_swap16(&ltv->an_val[4], 7); /* an_macaddr, an_rates */		an_swap16(&ltv->an_val[63], 8);  /* an_nodename */		break;	case AN_RID_SSIDLIST:		an_swap16(&ltv->an_val[1], 16); /* an_ssid1 */		an_swap16(&ltv->an_val[18], 16); /* an_ssid2 */		an_swap16(&ltv->an_val[35], 16); /* an_ssid3 */		break;	case AN_RID_APLIST:		an_swap16(ltv->an_val, 12);		break;	case AN_RID_DRVNAME:		an_swap16(ltv->an_val, 8);		break;	case AN_RID_CAPABILITIES:		an_swap16(ltv->an_val, 2);	/* an_oui */		an_swap16(&ltv->an_val[3], 34); /* an_manufname .. an_aironetaddr */		an_swap16(&ltv->an_val[39], 8); /* an_callid .. an_tx_diversity */		break;	case AN_RID_STATUS:		an_swap16(&ltv->an_val[0], 3);	/* an_macaddr */		an_swap16(&ltv->an_val[7], 36);	/* an_ssid .. an_prev_bssid3 */		an_swap16(&ltv->an_val[0x74/2], 2);	/* an_ap_ip_addr */		break;	case AN_RID_WEP_VOLATILE:	case AN_RID_WEP_PERMANENT:		an_swap16(&ltv->an_val[1], 3);	/* an_mac_addr */		an_swap16(&ltv->an_val[5], 6);		break;	}#endif	CSR_WRITE_2(sc, AN_DATA1, ltv->an_len);	ptr = ltv->an_val;	for (i = 0; i < (ltv->an_len - 1) >> 1; i++)		CSR_WRITE_2(sc, AN_DATA1, ptr[i]);	if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_WRITE, ltv->an_type))		return(EIO);	return(0);}intan_seek(sc, id, off, chan)	struct an_softc		*sc;	int			id, off, chan;{	int			i;	int			selreg, offreg;	switch (chan) {	case AN_BAP0:		selreg = AN_SEL0;		offreg = AN_OFF0;		break;	case AN_BAP1:		selreg = AN_SEL1;		offreg = AN_OFF1;		break;	default:		printf("%s: invalid data path: %x\n",		    sc->sc_dev.dv_xname, chan);		return (EIO);	}	CSR_WRITE_2(sc, selreg, id);	CSR_WRITE_2(sc, offreg, off);	for (i = AN_TIMEOUT; i--; DELAY(10)) {		if (!(CSR_READ_2(sc, offreg) & (AN_OFF_BUSY|AN_OFF_ERR)))			break;	}	if (i <= 0)		return(ETIMEDOUT);	return (0);}intan_read_data(sc, id, off, buf, len)	struct an_softc		*sc;	int			id, off;	caddr_t			buf;	int			len;{	if (off != -1 && an_seek(sc, id, off, AN_BAP1))		return(EIO);	bus_space_read_raw_multi_2(sc->an_btag, sc->an_bhandle,	    AN_DATA1, buf, len & ~1);	if (len & 1)	        ((u_int8_t *)buf)[len - 1] = CSR_READ_1(sc, AN_DATA1);	return (0);}intan_write_data(sc, id, off, buf, len)	struct an_softc		*sc;	int			id, off;	caddr_t			buf;	int			len;{	if (off != -1 && an_seek(sc, id, off, AN_BAP0))		return(EIO);	bus_space_write_raw_multi_2(sc->an_btag, sc->an_bhandle,	    AN_DATA0, buf, len & ~1);	if (len & 1)	        CSR_WRITE_1(sc, AN_DATA0, ((u_int8_t *)buf)[len - 1]);	return (0);}/* * Allocate a region of memory inside the NIC and zero * it out. */intan_alloc_nicmem(sc, len, id)	struct an_softc		*sc;	int			len;	int			*id;{	int			i;	if (an_cmd(sc, AN_CMD_ALLOC_MEM, len)) {		printf("%s: failed to allocate %d bytes on NIC\n",		    sc->sc_dev.dv_xname, len);		return(ENOMEM);	}	for (i = AN_TIMEOUT; i--; DELAY(10)) {		if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_ALLOC)			break;	}	if (i <= 0)		return(ETIMEDOUT);	CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_ALLOC);	*id = CSR_READ_2(sc, AN_ALLOC_FID);	if (an_seek(sc, *id, 0, AN_BAP0))		return(EIO);	bus_space_set_multi_2(sc->an_btag, sc->an_bhandle,	    AN_DATA0, 0, len / 2);	CSR_WRITE_1(sc, AN_DATA0, 0);	return(0);}voidan_setdef(sc, areq)	struct an_softc		*sc;	struct an_req		*areq;{	struct sockaddr_dl	*sdl;	struct ifaddr		*ifa;	struct ifnet		*ifp;	struct an_ltv_genconfig	*cfg;	struct an_ltv_ssidlist	*ssid;	struct an_ltv_aplist	*ap;	struct an_ltv_gen	*sp;	extern struct ifaddr	**ifnet_addrs;	ifp = &sc->arpcom.ac_if;	switch (areq->an_type) {	case AN_RID_GENCONFIG:		cfg = (struct an_ltv_genconfig *)areq;		ifa = ifnet_addrs[ifp->if_index];		sdl = (struct sockaddr_dl *)ifa->ifa_addr;		bcopy((char *)&cfg->an_macaddr, (char *)&sc->arpcom.ac_enaddr,		    ETHER_ADDR_LEN);		bcopy((char *)&cfg->an_macaddr, LLADDR(sdl), ETHER_ADDR_LEN);		bcopy((char *)cfg, (char *)&sc->an_config,			sizeof(struct an_ltv_genconfig));		break;	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[0];		break;	case AN_RID_WEP_VOLATILE:		/* Disable the MAC */		an_cmd(sc, AN_CMD_DISABLE, 0);		/* Just write the key, we dont' want to save it */		an_write_record(sc, (struct an_ltv_gen *)areq);		/* Turn the MAC back on */		an_cmd(sc, AN_CMD_ENABLE, 0);		break;	case AN_RID_WEP_PERMANENT:		/* Disable the MAC */	  //		an_cmd(sc, AN_CMD_DISABLE, 0);		/* Just write the key, the card will save it in this mode */		an_write_record(sc, (struct an_ltv_gen *)areq);		/* Turn the MAC back on */		//		an_cmd(sc, AN_CMD_ENABLE, 0);		return;		break;	default:		printf("%s: unknown RID: %x\n",		    sc->sc_dev.dv_xname, areq->an_type);		return;	}	/* Reinitialize the card. */	if (ifp->if_flags & IFF_UP)                		an_init(sc);}/* * We can't change the NIC configuration while the MAC is enabled, * so in order to turn on RX monitor mode, we have to turn the MAC * off first. */voidan_promisc(sc, promisc)	struct an_softc		*sc;	int			promisc;{	struct an_ltv_genconfig genconf;	/* Disable the MAC. */	an_cmd(sc, AN_CMD_DISABLE, 0);	/* Set RX mode. */	if (promisc &&	    !(sc->an_config.an_rxmode & AN_RXMODE_LAN_MONITOR_CURBSS) ) {		sc->an_rxmode = sc->an_config.an_rxmode;		sc->an_config.an_rxmode |=		    AN_RXMODE_LAN_MONITOR_CURBSS;	} else {		sc->an_config.an_rxmode = sc->an_rxmode;	}	/* Transfer the configuration to the NIC */	genconf = sc->an_config;	genconf.an_len = sizeof(struct an_ltv_genconfig);	genconf.an_type = AN_RID_GENCONFIG;	if (an_write_record(sc, (struct an_ltv_gen *)&genconf)) {		printf("%s: failed to set configuration\n",		    sc->sc_dev.dv_xname);		return;	}	/* Turn the MAC back on. */	an_cmd(sc, AN_CMD_ENABLE, 0);}intan_ioctl(ifp, command, data)	struct ifnet		*ifp;	u_long			command;	caddr_t			data;{	int			s, error = 0;	struct an_softc		*sc;	struct an_req		areq;	struct ifreq		*ifr;	struct proc		*p = curproc;	struct ifaddr		*ifa = (struct ifaddr *)data;	s = splimp();	sc = ifp->if_softc;	ifr = (struct ifreq *)data;	if (sc->an_gone) {		splx(s);		return(ENODEV);	}	if ((error = ether_ioctl(ifp, &sc->arpcom, command, data)) > 0) {		splx(s);		return error;	}	switch(command) {	case SIOCSIFADDR:		ifp->if_flags |= IFF_UP;		switch (ifa->ifa_addr->sa_family) {#ifdef INET		case AF_INET:			an_init(sc);			arp_ifinit(&sc->arpcom, ifa);			break;#endif		default:			an_init(sc);			break;		}		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);				an_reset(sc);			}			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)			break;#ifdef ANCACHE		if (areq.an_type == AN_RID_ZERO_CACHE) {			error = suser(p->p_ucred, &p->p_acflag);			if (error)				break;			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);

⌨️ 快捷键说明

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