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

📄 if_wi.c

📁 一个学习SNMP项目:tmoerlan.
💻 C
📖 第 1 页 / 共 5 页
字号:
/*		char wrongaddr2[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};*/		if (!bcmp(tx_frame->wi_dst_addr, wrongaddr1, 6))/* ||			!bcmp(tx_frame->wi_dst_addr, wrongaddr2, 6))*/			/* wrong dest address, forget this frame */			;		else {			msglen = tx_frame->wi_dat_len;			msglen += WI_SNAPHDR_LEN;			/* if we're using WEP, 64 bits is added to packet */			if (sc->wi_use_wep)				msglen += 8;			if (sc->arpcom.ac_if.if_flags & IFF_DEBUG) {				device_printf(sc->dev, "wi_dat_len=%d\n", tx_frame->wi_dat_len);				device_printf(sc->dev, "status=%d, ", tx_frame->wi_status);				device_printf(sc->dev, "thus len=%ld\n", msglen);			}			int cache_slot;			cache_slot = wi_findCacheEntry(sc, tx_frame->wi_dst_addr);			if (cache_slot > -1) {				struct wi_sigextcache *p;				p = &sc->wi_sigextcache[cache_slot];				/* printf("cach_slot %d\n", cache_slot); */				p->sndpkts++;				p->sndbytes += msglen;				p->tempsndbytes += msglen;				if (sc->wi_ptype == WI_PORTTYPE_BSS)					p->remove_ctr = sc->wi_timeout_time;/*				device_printf(sc->dev, "bw_timer: storing cache in slot %d\n", cache_slot);*/			}		}	}#endif	if (wi_seek(sc, id, off, WI_BAP0))		return(EIO);	ptr = (u_int16_t *)buf;	for (i = 0; i < (len / 2); i++)		CSR_WRITE_2(sc, WI_DATA0, ptr[i]);#ifdef WI_HERMES_AUTOINC_WAR	CSR_WRITE_2(sc, WI_DATA0, 0x1234);	CSR_WRITE_2(sc, WI_DATA0, 0x5678);	if (wi_seek(sc, id, off + len, WI_BAP0))		return(EIO);	if (CSR_READ_2(sc, WI_DATA0) != 0x1234 ||	    CSR_READ_2(sc, WI_DATA0) != 0x5678) {		if (--retries >= 0)			goto again;		device_printf(sc->dev, "wi_write_data device timeout\n");		return (EIO);	}#endif	return(0);}/* * Allocate a region of memory inside the NIC and zero * it out. */static intwi_alloc_nicmem(sc, len, id)	struct wi_softc		*sc;	int			len;	int			*id;{	int			i;	if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len, 0, 0)) {		device_printf(sc->dev,		    "failed to allocate %d bytes on NIC\n", len);		return(ENOMEM);	}	for (i = 0; i < WI_TIMEOUT; i++) {		if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)			break;		DELAY(WI_DELAY);	}	if (i == WI_TIMEOUT) {		device_printf(sc->dev, "time out allocating memory on card\n");		return(ETIMEDOUT);	}	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);	*id = CSR_READ_2(sc, WI_ALLOC_FID);	if (wi_seek(sc, *id, 0, WI_BAP0)) {		device_printf(sc->dev, "seek failed while allocating memory on card\n");		return(EIO);	}	for (i = 0; i < len / 2; i++)		CSR_WRITE_2(sc, WI_DATA0, 0);	return(0);}static voidwi_setmulti(sc)	struct wi_softc		*sc;{	struct ifnet		*ifp;	int			i = 0;	struct ifmultiaddr	*ifma;	struct wi_ltv_mcast	mcast;	ifp = &sc->arpcom.ac_if;	bzero((char *)&mcast, sizeof(mcast));	mcast.wi_type = WI_RID_MCAST_LIST;	mcast.wi_len = (3 * 16) + 1;	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {		wi_write_record(sc, (struct wi_ltv_gen *)&mcast);		return;	}#if __FreeBSD_version < 500000	LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {#else	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {#endif		if (ifma->ifma_addr->sa_family != AF_LINK)			continue;		if (i < 16) {			bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),			    (char *)&mcast.wi_mcast[i], ETHER_ADDR_LEN);			i++;		} else {			bzero((char *)&mcast, sizeof(mcast));			break;		}	}	mcast.wi_len = (i * 3) + 1;	wi_write_record(sc, (struct wi_ltv_gen *)&mcast);	return;}static voidwi_setdef(sc, wreq)	struct wi_softc		*sc;	struct wi_req		*wreq;{	struct sockaddr_dl	*sdl;	struct ifaddr		*ifa;	struct ifnet		*ifp;	ifp = &sc->arpcom.ac_if;	switch(wreq->wi_type) {	case WI_RID_MAC_NODE:		ifa = ifaddr_byindex(ifp->if_index);		sdl = (struct sockaddr_dl *)ifa->ifa_addr;		bcopy((char *)&wreq->wi_val, (char *)&sc->arpcom.ac_enaddr,		   ETHER_ADDR_LEN);		bcopy((char *)&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN);		break;	case WI_RID_PORTTYPE:		sc->wi_ptype = le16toh(wreq->wi_val[0]);		break;	case WI_RID_TX_RATE:		sc->wi_tx_rate = le16toh(wreq->wi_val[0]);		break;	case WI_RID_MAX_DATALEN:		sc->wi_max_data_len = le16toh(wreq->wi_val[0]);		break;	case WI_RID_RTS_THRESH:		sc->wi_rts_thresh = le16toh(wreq->wi_val[0]);		break;	case WI_RID_SYSTEM_SCALE:		sc->wi_ap_density = le16toh(wreq->wi_val[0]);		break;	case WI_RID_CREATE_IBSS:		sc->wi_create_ibss = le16toh(wreq->wi_val[0]);		break;	case WI_RID_OWN_CHNL:		sc->wi_channel = le16toh(wreq->wi_val[0]);		break;	case WI_RID_NODENAME:		bzero(sc->wi_node_name, sizeof(sc->wi_node_name));		bcopy((char *)&wreq->wi_val[1], sc->wi_node_name, 30);		break;	case WI_RID_DESIRED_SSID:		bzero(sc->wi_net_name, sizeof(sc->wi_net_name));		bcopy((char *)&wreq->wi_val[1], sc->wi_net_name, 30);		break;	case WI_RID_OWN_SSID:		bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));		bcopy((char *)&wreq->wi_val[1], sc->wi_ibss_name, 30);		break;	case WI_RID_PM_ENABLED:		sc->wi_pm_enabled = le16toh(wreq->wi_val[0]);		break;	case WI_RID_MICROWAVE_OVEN:		sc->wi_mor_enabled = le16toh(wreq->wi_val[0]);		break;	case WI_RID_MAX_SLEEP:		sc->wi_max_sleep = le16toh(wreq->wi_val[0]);		break;	case WI_RID_CNFAUTHMODE:		sc->wi_authtype = le16toh(wreq->wi_val[0]);		break;	case WI_RID_ROAMING_MODE:		sc->wi_roaming = le16toh(wreq->wi_val[0]);		break;	case WI_RID_ENCRYPTION:		sc->wi_use_wep = le16toh(wreq->wi_val[0]);		break;	case WI_RID_TX_CRYPT_KEY:		sc->wi_tx_key = le16toh(wreq->wi_val[0]);		break;	case WI_RID_DEFLT_CRYPT_KEYS:		bcopy((char *)wreq, (char *)&sc->wi_keys,		    sizeof(struct wi_ltv_keys));		break;	default:		break;	}	/* Reinitialize WaveLAN. */	wi_init(sc);	return;}static intwi_ioctl(ifp, command, data)	struct ifnet		*ifp;	u_long			command;	caddr_t			data;{	int			error = 0;	int			len;	int			s;	uint16_t		mif;	uint16_t		val;	u_int8_t		tmpkey[14];	char			tmpssid[IEEE80211_NWID_LEN];	struct wi_softc		*sc;	struct wi_req		wreq;	struct ifreq		*ifr;	struct ieee80211req	*ireq;#if __FreeBSD_version >= 500000	struct thread		*td = curthread;#else	struct proc		*td = curproc;		/* Little white lie */#endif	sc = ifp->if_softc;	WI_LOCK(sc, s);	ifr = (struct ifreq *)data;	ireq = (struct ieee80211req *)data;	if (sc->wi_gone) {		error = ENODEV;		goto out;	}	switch(command) {	case SIOCSIFFLAGS:		/*		 * Can't do promisc and hostap at the same time.  If all that's		 * changing is the promisc flag, try to short-circuit a call to		 * wi_init() by just setting PROMISC in the hardware.		 */		if (ifp->if_flags & IFF_UP) {			if (sc->wi_ptype != WI_PORTTYPE_HOSTAP &&			    ifp->if_flags & IFF_RUNNING) {				if (ifp->if_flags & IFF_PROMISC &&				    !(sc->wi_if_flags & IFF_PROMISC)) {					WI_SETVAL(WI_RID_PROMISC, 1);				} else if (!(ifp->if_flags & IFF_PROMISC) &&				    sc->wi_if_flags & IFF_PROMISC) {					WI_SETVAL(WI_RID_PROMISC, 0);				} else {					wi_init(sc);				}			} else {				wi_init(sc);			}		} else {			if (ifp->if_flags & IFF_RUNNING) {				wi_stop(sc);			}		}		sc->wi_if_flags = ifp->if_flags;		error = 0;		break;	case SIOCSIFMEDIA:	case SIOCGIFMEDIA:		error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);		break;	case SIOCADDMULTI:	case SIOCDELMULTI:		wi_setmulti(sc);		error = 0;		break;	case SIOCGWAVELAN:		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));		if (error)			break;		if (wreq.wi_len > WI_MAX_DATALEN) {			error = EINVAL;			break;		}		/* Don't show WEP keys to non-root users. */		if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS && suser(td))			break;		if (wreq.wi_type == WI_RID_IFACE_STATS) {			bcopy((char *)&sc->wi_stats, (char *)&wreq.wi_val,			    sizeof(sc->wi_stats));			wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1;		} else if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS) {			bcopy((char *)&sc->wi_keys, (char *)&wreq,			    sizeof(struct wi_ltv_keys));		}#ifdef WICACHE		else if (wreq.wi_type == WI_RID_ZERO_CACHE) {			device_printf(sc->dev, "ioctl ZERO-ing CACHE!!!\n");			sc->wi_sigitems = sc->wi_nextitem = 0;		} else if (wreq.wi_type == WI_RID_READ_CACHE) {			char *pt = (char *)&wreq.wi_val;			/* we make sure we don't exceed the WI_MAX_DATALEN limit			   if we have more than can be transfered, simply skip those			   also, we return this number of items, not the real, bigger one			   so older programs can still work with this driver */			int tocopy, maxtransfer;			tocopy = sc->wi_sigitems;                        maxtransfer = (WI_MAX_DATALEN << 1) * sizeof(struct wi_sigcache);                        if (tocopy > maxtransfer)                                tocopy = maxtransfer;			bcopy((char *)&tocopy,			    (char *)pt, sizeof(int));			pt += (sizeof (int));			wreq.wi_len = sizeof(int) / 2;			bcopy((char *)&sc->wi_sigcache, (char *)pt,			    sizeof(struct wi_sigcache) * tocopy);			wreq.wi_len += ((sizeof(struct wi_sigcache) *			    tocopy) / 2) + 1;		} else if (wreq.wi_type == WI_RID_ZERO_EXTCACHE) {			sc->wi_sigitems = sc->wi_nextitem = 0;			/* set whole cache buffer to zero */			bzero(sc->wi_sigextcache, MAXWICACHE * sizeof(struct wi_sigextcache));		} else if (wreq.wi_type == WI_RID_READ_EXTCACHE) { 	      		char *pt = (char *)&wreq.wi_val;			int offset, tocopy;			bcopy(pt, (char *) &offset, sizeof(int));			/* offset now contains the first entry the user wants to have			   we give all entries from [offset, offset+MAXCACHE_TRANSFER-1]			   or less, if the end is reached.		  	*/			/* but the first integer we return is always total number of items! */			bcopy((char *)&sc->wi_sigitems,				(char *)pt, sizeof(int));			pt += (sizeof (int));			wreq.wi_len = sizeof(int) / 2;			tocopy = MAXCACHE_TRANSFER;			if (sc->wi_sigitems - offset < tocopy)				tocopy = sc->wi_sigitems - offset;			if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)				device_printf(sc->dev, "READ_EXTCACHE returning %d items: %d till %d\n",					tocopy, offset, offset+tocopy-1);			if (tocopy > 0) {				bcopy((char *)&sc->wi_sigextcache[offset], (char *)pt,					sizeof(struct wi_sigextcache) * tocopy);							wreq.wi_len += ((sizeof(struct wi_sigextcache) * tocopy) / 2) + 1;			}		} else if (wreq.wi_type == WI_RID_READ_EWMACONSTBW) {			int ewmaconst = (int) (1000 * sc->wi_ewmaconst_bw); 			bcopy((char *)&ewmaconst, (char *)&wreq.wi_val, sizeof(int));			wreq.wi_len = sizeof(int) / 2;	/* in words... */ 		} else if (wreq.wi_type == WI_RID_READ_EWMACONSTSNQ) {                        int ewmaconst = (int) (1000 * sc->wi_ewmaconst_snq);			bcopy((char *)&ewmaconst, (char *)&wreq.wi_val, sizeof(int));			wreq.wi_len = sizeof(int) / 2;  /* in words... */                } else if (wreq.wi_type == WI_RID_READ_TIMEOUT_TIME) {                        wreq.wi_val[0] = sc->wi_timeout_time;                        wreq.wi_len = 2;  /* why should this be 2 (check other word-returns)? we're only returning 1 word! */		}#endif		else if (wreq.wi_type == WI_RID_PROCFRAME) {			wreq.wi_len = 2;			wreq.wi_val[0] = sc->wi_procframe;		} else if (wreq.wi_type == WI_RID_PRISM2) {			wreq.wi_len = 2;			wreq.wi_val[0] = sc->sc_firmware_type != WI_LUCENT;		} else if (wreq.wi_type == WI_RID_SCAN_RES && 		    sc->sc_firmware_type == WI_LUCENT) {			memcpy((char *)wreq.wi_val, (char *)sc->wi_scanbuf,			    sc->wi_scanbuf_len * 2);			wreq.wi_len = sc->wi_scanbuf_len;		} else if (wreq.wi_type == WI_RID_MIF) {			mif = wreq.wi_val[0];			error = wi_cmd(sc, WI_CMD_READMIF, mif, 0, 0);			val = CSR_READ_2(sc, WI_RESP0);			wreq.wi_len = 2;			wreq.wi_val[0] = val;		} else {			if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) {				error = EINVAL;				break;			}		}		error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));		break;	case SIOCSWAVELAN:		if ((error = suser(td)))			goto out;		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));		if (error)			break;		if (wreq.wi_len > WI_MAX_DATALEN) {			error = EINVAL;			break;		}		if (wreq.wi_type == WI_RID_IFACE_STATS) {			error = EINVAL;			break;		} else if (wreq.wi_type == WI_RID_MGMT_XMIT) {			error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val,			    wreq.wi_len);		} else if (wreq.wi_type == WI_RID_PROCFRAME) {			sc->wi_procframe = wreq.wi_val[0];		/*		 * if we're getting a scan request from a wavelan card		 * (non-prism2), send out a cmd_inquire to the card to scan		 * results for the scan will be received through the info		 * interrupt handler. otherwise the scan request can be		 * directly han

⌨️ 快捷键说明

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