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

📄 wi_hostap.c

📁 一个学习SNMP项目:tmoerlan.
💻 C
📖 第 1 页 / 共 3 页
字号:
		wihap_sta_delete(sta);}/*!	\fn static void wihap_disassoc_req(struct wi_softc *sc, struct wi_frame *rxfrm, caddr_t pkt, int len)	\brief This functions handles incoming disassocation requests	\param sc Pointer to the wi_softc structure of the specific interface	\param rxfrm Pointer to a wi_frame structure containing information about received frame	\param pkt Address of the packet	\param len Length of the packet	Just resets the assoc flag. Station resources are freed up when a deauth request is sent or after inactivity timeout.	A call to saveDisassocTime has been added.*//* wihap_disassoc_req() * *	Handle disassociation requests.  Just reset the assoc flag. *	We'll free up the station resources when we get a deauth *	request or when it times out. */static voidwihap_disassoc_req(struct wi_softc *sc, struct wi_frame *rxfrm,    caddr_t pkt, int len){	struct wihap_info	*whi = &sc->wi_hostap_info;	struct wihap_sta_info	*sta;	u_int16_t		reason;	if (len < 2)		return;	reason = take_hword(&pkt, &len);	sta = wihap_sta_find(whi, rxfrm->wi_addr2);	if (sta == NULL) {		if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)			printf("wihap_disassoc_req: unknown station: %6D\n",			    rxfrm->wi_addr2, ":");	}	else if (!(sta->flags & WI_SIFLAGS_AUTHEN)) {		/*		 * If station is not authenticated, send deauthentication		 * frame.		 */		wihap_sta_deauth(sc, rxfrm->wi_addr2,		    IEEE80211_REASON_NOT_AUTHED);		return;	}	else {		sta->flags &= ~WI_SIFLAGS_ASSOC;#ifdef WICACHE		saveDisassocTime(sc, sta->addr);#endif	}}/* wihap_debug_frame_type() * * Print out frame type.  Used in early debugging. */static __inline voidwihap_debug_frame_type(struct wi_frame *rxfrm){	printf("wihap_mgmt_input: len=%d ", le16toh(rxfrm->wi_dat_len));	if ((rxfrm->wi_frame_ctl & htole16(WI_FCTL_FTYPE)) ==	    htole16(WI_FTYPE_MGMT)) {		printf("MGMT: ");		switch (le16toh(rxfrm->wi_frame_ctl) & WI_FCTL_STYPE) {		case WI_STYPE_MGMT_ASREQ:			printf("assoc req: \n");			break;		case WI_STYPE_MGMT_ASRESP:			printf("assoc resp: \n");			break;		case WI_STYPE_MGMT_REASREQ:			printf("reassoc req: \n");			break;		case WI_STYPE_MGMT_REASRESP:			printf("reassoc resp: \n");			break;		case WI_STYPE_MGMT_PROBEREQ:			printf("probe req: \n");			break;		case WI_STYPE_MGMT_PROBERESP:			printf("probe resp: \n");			break;		case WI_STYPE_MGMT_BEACON:			printf("beacon: \n");			break;		case WI_STYPE_MGMT_ATIM:			printf("ann traf ind \n");			break;		case WI_STYPE_MGMT_DISAS:			printf("disassociation: \n");			break;		case WI_STYPE_MGMT_AUTH:			printf("auth: \n");			break;		case WI_STYPE_MGMT_DEAUTH:			printf("deauth: \n");			break;		default:			printf("unknown (stype=0x%x)\n",			    le16toh(rxfrm->wi_frame_ctl) & WI_FCTL_STYPE);		}	}	else {		printf("ftype=0x%x (ctl=0x%x)\n",		    le16toh(rxfrm->wi_frame_ctl) & WI_FCTL_FTYPE,		    le16toh(rxfrm->wi_frame_ctl));	}}/* wihap_mgmt_input: * *	Called for each management frame received in host ap mode. *	wihap_mgmt_input() is expected to free the mbuf. */voidwihap_mgmt_input(struct wi_softc *sc, struct wi_frame *rxfrm, struct mbuf *m){	caddr_t	pkt;	int	s, len;	if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)		wihap_debug_frame_type(rxfrm);	pkt = mtod(m, caddr_t) + WI_802_11_OFFSET_RAW;	len = m->m_len - WI_802_11_OFFSET_RAW;	if ((rxfrm->wi_frame_ctl & htole16(WI_FCTL_FTYPE)) ==	    htole16(WI_FTYPE_MGMT)) {		/* any of the following will mess w/ the station list */		s = splnet();		switch (le16toh(rxfrm->wi_frame_ctl) & WI_FCTL_STYPE) {		case WI_STYPE_MGMT_ASREQ:			wihap_assoc_req(sc, rxfrm, pkt, len);			break;		case WI_STYPE_MGMT_ASRESP:			break;		case WI_STYPE_MGMT_REASREQ:			wihap_assoc_req(sc, rxfrm, pkt, len);			break;		case WI_STYPE_MGMT_REASRESP:			break;		case WI_STYPE_MGMT_PROBEREQ:			break;		case WI_STYPE_MGMT_PROBERESP:			break;		case WI_STYPE_MGMT_BEACON:			break;		case WI_STYPE_MGMT_ATIM:			break;		case WI_STYPE_MGMT_DISAS:			wihap_disassoc_req(sc, rxfrm, pkt, len);			break;		case WI_STYPE_MGMT_AUTH:			wihap_auth_req(sc, rxfrm, pkt, len);			break;		case WI_STYPE_MGMT_DEAUTH:			wihap_deauth_req(sc, rxfrm, pkt, len);			break;		}		splx(s);	}	m_freem(m);}/* wihap_sta_is_assoc() * *	Determine if a station is assoc'ed.  Update its activity *	counter as a side-effect. */static intwihap_sta_is_assoc(struct wihap_info *whi, u_int8_t addr[]){	struct wihap_sta_info *sta;	int retval, s;	s = splnet();	retval = 0;	sta = wihap_sta_find(whi, addr);	if (sta != NULL && (sta->flags & WI_SIFLAGS_ASSOC)) {		/* Keep it active. */		untimeout(wihap_sta_timeout, sta, sta->tmo);		sta->tmo = timeout(wihap_sta_timeout, sta,		    hz * whi->inactivity_time);		retval = 1;	}	splx(s);	return (retval);}/* wihap_check_tx() * *	Determine if a station is assoc'ed, get its tx rate, and update *	its activity. */intwihap_check_tx(struct wihap_info *whi, u_int8_t addr[], u_int8_t *txrate){	struct wihap_sta_info *sta;	static u_int8_t txratetable[] = { 10, 20, 55, 110 };	int s;	if (addr[0] & 0x01) {		*txrate = 0; /* XXX: multicast rate? */		return(1);	}	s = splnet();	sta = wihap_sta_find(whi, addr);	if (sta != NULL && (sta->flags & WI_SIFLAGS_ASSOC)) {		/* Keep it active. */		untimeout(wihap_sta_timeout, sta, sta->tmo);		sta->tmo = timeout(wihap_sta_timeout, sta,		    hz * whi->inactivity_time);		*txrate = txratetable[ sta->tx_curr_rate ];		splx(s);		return(1);	}	splx(s);	return(0);}/* * wihap_data_input() * *	Handle all data input on interface when in Host AP mode. *	Some packets are destined for this machine, others are *	repeated to other stations. * *	If wihap_data_input() returns a non-zero, it has processed *	the packet and will free the mbuf. */intwihap_data_input(struct wi_softc *sc, struct wi_frame *rxfrm, struct mbuf *m){	struct ifnet		*ifp = &sc->arpcom.ac_if;	struct wihap_info	*whi = &sc->wi_hostap_info;	struct wihap_sta_info	*sta;	int			mcast, s;	/* TODS flag must be set. */	if (!(rxfrm->wi_frame_ctl & htole16(WI_FCTL_TODS))) {		if (ifp->if_flags & IFF_DEBUG)			printf("wihap_data_input: no TODS src=%6D\n",			    rxfrm->wi_addr2, ":");		m_freem(m);		return(1);	}	/* Check BSSID. (Is this necessary?) */	if (!addr_cmp(rxfrm->wi_addr1, sc->arpcom.ac_enaddr)) {		if (ifp->if_flags & IFF_DEBUG)			printf("wihap_data_input: incorrect bss: %6D\n",				rxfrm->wi_addr1, ":");		m_freem(m);		return (1);	}	s = splnet();	/* Find source station. */	sta = wihap_sta_find(whi, rxfrm->wi_addr2);	/* Source station must be associated. */	if (sta == NULL || !(sta->flags & WI_SIFLAGS_ASSOC)) {		if (ifp->if_flags & IFF_DEBUG)			printf("wihap_data_input: dropping unassoc src %6D\n",			    rxfrm->wi_addr2, ":"); 		wihap_sta_disassoc(sc, rxfrm->wi_addr2, 		    IEEE80211_REASON_ASSOC_LEAVE);		splx(s);		m_freem(m);		return(1);	}	untimeout(wihap_sta_timeout, sta, sta->tmo);	sta->tmo = timeout(wihap_sta_timeout, sta,	    hz * whi->inactivity_time);	sta->sig_info = le16toh(rxfrm->wi_q_info);	splx(s);	/* Repeat this packet to BSS? */	mcast = (rxfrm->wi_addr3[0] & 0x01) != 0;	if (mcast || wihap_sta_is_assoc(whi, rxfrm->wi_addr3)) {		/* If it's multicast, make a copy.		 */		if (mcast) {			m = m_copym(m, 0, M_COPYALL, M_DONTWAIT);			if (m == NULL)				return(0);			m->m_flags |= M_MCAST; /* XXX */		}		/* Queue up for repeating.		 */		IF_HANDOFF(&ifp->if_snd, m, ifp);		return (!mcast);	}	return(0);}/*!	\fn int wihap_ioctl(struct wi_softc *sc, u_long command, caddr_t data)	\brief This function handles HostAP specific ioctl calls.	\param sc Pointer to the wi_softc structure of the specific interface	\param command The ioctl request type	\param data Address of ioctl data (to be read or written to)	\note Function is called from wi_ioctl() in if_wi.c	Handles SIOCHOSTAP_<FOO> calls. Added two calls:\n	SIOCHOSTAP_DISASSOC to disassociate a station (send disassociation frame, clear association flag)	SIOCHOSTAP_DEL to disassociate, deauthenticate a station and free it's resources (memory structures).	In both cases saveDisassocTime is called (thus the cache timeout is started).*//* wihap_ioctl() * *	Handle Host AP specific ioctls.  Called from wi_ioctl(). */intwihap_ioctl(struct wi_softc *sc, u_long command, caddr_t data){	struct ifreq		*ifr = (struct ifreq *) data;	struct wihap_info	*whi = &sc->wi_hostap_info;	struct wihap_sta_info	*sta;	struct hostap_getall	reqall;	struct hostap_sta	reqsta;	struct hostap_sta	stabuf;	int			s, error = 0, n, flag;#if __FreeBSD_version >= 500000	struct thread		*td = curthread;#else	struct proc		*td = curproc;		/* Little white lie */#endif	if (!(sc->arpcom.ac_if.if_flags & IFF_RUNNING))		return ENODEV;	switch (command) {	case SIOCHOSTAP_DISASSOC:	case SIOCHOSTAP_DEL:		if ((error = suser(td)))			break;		if ((error = copyin(ifr->ifr_data, &reqsta, sizeof(reqsta))))			break;		s = splnet();		sta = wihap_sta_find(whi, reqsta.addr);		if (sta == NULL)			error = ENOENT;		else {			/* Disassociate station. */			if (sta->flags & WI_SIFLAGS_ASSOC)				wihap_sta_disassoc(sc, sta->addr,				    IEEE80211_REASON_ASSOC_LEAVE);			sta->flags &= ~WI_SIFLAGS_ASSOC;#ifdef WICACHE			if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)				device_printf(sc->dev, "SIOCHOSTAP_DISASSOC/DEL: saving disassoc time\n");			saveDisassocTime(sc, reqsta.addr);#endif			if (command == SIOCHOSTAP_DISASSOC) {				goto end_DISASSOC_case;			} 			/* Deauth station. */			if (sta->flags & WI_SIFLAGS_AUTHEN)				wihap_sta_deauth(sc, sta->addr,				    IEEE80211_REASON_AUTH_LEAVE);			wihap_sta_delete(sta);		}	end_DISASSOC_case:		splx(s);		break;	case SIOCHOSTAP_GET:		if ((error = copyin(ifr->ifr_data, &reqsta, sizeof(reqsta))))			break;		s = splnet();		sta = wihap_sta_find(whi, reqsta.addr);		if (sta == NULL) {			error = ENOENT;			splx(s);		} else {			reqsta.flags = sta->flags;			reqsta.asid = sta->asid;			reqsta.capinfo = sta->capinfo;			reqsta.sig_info = sta->sig_info;			reqsta.rates = sta->rates;			splx(s);			error = copyout(&reqsta, ifr->ifr_data,			    sizeof(reqsta));		}		break;	case SIOCHOSTAP_ADD:		if ((error = suser(td)))			break;		if ((error = copyin(ifr->ifr_data, &reqsta, sizeof(reqsta))))			break;		s = splnet();		sta = wihap_sta_find(whi, reqsta.addr);		if (sta != NULL) {			error = EEXIST;			splx(s);			break;		}		if (whi->n_stations >= WIHAP_MAX_STATIONS) {			error = ENOSPC;			splx(s);			break;		}		sta = wihap_sta_alloc(sc, reqsta.addr);		sta->flags = reqsta.flags;		sta->tmo = timeout(wihap_sta_timeout, sta,		    hz * whi->inactivity_time);		splx(s);		break;	case SIOCHOSTAP_SFLAGS:		if ((error = suser(td)))			break;		if ((error = copyin(ifr->ifr_data, &flag, sizeof(int))))			break;		whi->apflags = (whi->apflags & WIHAPFL_CANTCHANGE) |		    (flag & ~WIHAPFL_CANTCHANGE);		break;	case SIOCHOSTAP_GFLAGS:		flag = (int) whi->apflags;		error = copyout(&flag, ifr->ifr_data, sizeof(int));		break;	case SIOCHOSTAP_GETALL:		if ((error = copyin(ifr->ifr_data, &reqall, sizeof(reqall))))			break;		reqall.nstations = whi->n_stations;		n = 0;		s = splnet();		sta = LIST_FIRST(&whi->sta_list);		while (sta && reqall.size >= n+sizeof(struct hostap_sta)) {			bcopy(sta->addr, stabuf.addr, ETHER_ADDR_LEN);			stabuf.asid = sta->asid;			stabuf.flags = sta->flags;			stabuf.capinfo = sta->capinfo;			stabuf.sig_info = sta->sig_info;			stabuf.rates = sta->rates;			error = copyout(&stabuf, (caddr_t) reqall.addr + n,			    sizeof(struct hostap_sta));			if (error)				break;			sta = LIST_NEXT(sta, list);			n += sizeof(struct hostap_sta);		}		splx(s);		if (!error)			error = copyout(&reqall, ifr->ifr_data,			    sizeof(reqall));		break;	default:		printf("wihap_ioctl: i shouldn't get other ioctls!\n");		error = EINVAL;	}	return(error);}

⌨️ 快捷键说明

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