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

📄 ieee80211_node.c

📁 Linux下wifi实现
💻 C
📖 第 1 页 / 共 5 页
字号:
			IEEE80211_NODE_UNLOCK(nt);			(*f)(arg, ni);			ieee80211_free_node(ni);			goto restart;		}	}	IEEE80211_NODE_UNLOCK(nt);	IEEE80211_SCAN_UNLOCK_IRQ(nt);}EXPORT_SYMBOL(ieee80211_iterate_nodes);voidieee80211_dump_node(struct ieee80211_node_table *nt, struct ieee80211_node *ni){	int i;	printf("0x%p: mac %s refcnt %d\n", ni,		ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni));	printf("\tscangen %u authmode %u flags 0x%x\n",		ni->ni_scangen, ni->ni_authmode, ni->ni_flags);	printf("\tassocid 0x%x txpower %u vlan %u\n",		ni->ni_associd, ni->ni_txpower, ni->ni_vlan);	printf ("rxfragstamp %u\n", ni->ni_rxfragstamp);	for (i = 0; i < 17; i++) {		printf("\t%d: txseq %u rxseq %u fragno %u\n", i, 		       ni->ni_txseqs[i],		       ni->ni_rxseqs[i] >> IEEE80211_SEQ_SEQ_SHIFT,		       ni->ni_rxseqs[i] & IEEE80211_SEQ_FRAG_MASK);	}	printf("\trstamp %u rssi %u intval %u capinfo 0x%x\n",		ni->ni_rstamp, ni->ni_rssi, ni->ni_intval, ni->ni_capinfo);	printf("\tbssid %s essid \"%.*s\" channel %u:0x%x\n",		ether_sprintf(ni->ni_bssid),		ni->ni_esslen, ni->ni_essid,		ni->ni_chan != IEEE80211_CHAN_ANYC ?			ni->ni_chan->ic_freq : IEEE80211_CHAN_ANY,		ni->ni_chan != IEEE80211_CHAN_ANYC ? ni->ni_chan->ic_flags : 0);	printf("\tinact %u txrate %u\n",		ni->ni_inact, ni->ni_txrate);}voidieee80211_dump_nodes(struct ieee80211_node_table *nt){	ieee80211_iterate_nodes(nt,		(ieee80211_iter_func *) ieee80211_dump_node, nt);}/* * Handle a station joining an 11g network. */static voidieee80211_node_join_11g(struct ieee80211_node *ni){	struct ieee80211com *ic = ni->ni_ic;	struct ieee80211vap *vap = ni->ni_vap;	IEEE80211_LOCK_ASSERT(ic);	KASSERT(IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan),	     ("not in 11g, bss %u:0x%x, curmode %u", ic->ic_bsschan->ic_freq,	      ic->ic_bsschan->ic_flags, ic->ic_curmode));	/*	 * Station isn't capable of short slot time.  Bump	 * the count of long slot time stations and disable	 * use of short slot time.  Note that the actual switch	 * over to long slot time use may not occur until the	 * next beacon transmission (per sec. 7.3.1.4 of 11g).	 */	if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) == 0) {		ic->ic_longslotsta++;		IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,			"station needs long slot time, count %d",			ic->ic_longslotsta);		/* XXX vap's w/ conflicting needs won't work */		if (!IEEE80211_IS_CHAN_108G(ic->ic_bsschan)) {			/*			 * Don't force slot time when switched to turbo			 * mode as non-ERP stations won't be present; this			 * need only be done when on the normal G channel.			 */			ieee80211_set_shortslottime(ic, 0);		}	}	/*	 * If the new station is not an ERP station	 * then bump the counter and enable protection	 * if configured.	 */	if (!ieee80211_iserp_rateset(ic, &ni->ni_rates)) {		ic->ic_nonerpsta++;		IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,			"station is !ERP, %d non-ERP stations associated",			ic->ic_nonerpsta);		/*		 * If protection is configured, enable it.		 */		if (ic->ic_protmode != IEEE80211_PROT_NONE) {			IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,				"%s: enable use of protection\n", __func__);			ic->ic_flags |= IEEE80211_F_USEPROT;		}		/*		 * If station does not support short preamble		 * then we must enable use of Barker preamble.		 */		if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) == 0) {			IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,				"%s", "station needs long preamble");			ic->ic_flags |= IEEE80211_F_USEBARKER;			ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;		}		/* Update ERP element if this is first non ERP station */		if (ic->ic_nonerpsta == 1)			ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE;	} else		ni->ni_flags |= IEEE80211_NODE_ERP;}voidieee80211_node_join(struct ieee80211_node *ni, int resp){	struct ieee80211com *ic = ni->ni_ic;	struct ieee80211vap *vap = ni->ni_vap;	int newassoc;	if (ni->ni_associd == 0) {		u_int16_t aid;		KASSERT(vap->iv_aid_bitmap != NULL, ("no aid bitmap"));		/*		 * It would be good to search the bitmap		 * more efficiently, but this will do for now.		 */		for (aid = 1; aid < vap->iv_max_aid; aid++)			if (!IEEE80211_AID_ISSET(vap, aid))				break;		if (aid >= vap->iv_max_aid) {			IEEE80211_SEND_MGMT(ni, resp,				IEEE80211_REASON_ASSOC_TOOMANY);			ieee80211_node_leave(ni);			return;		}		ni->ni_associd = aid | 0xc000;		IEEE80211_LOCK_IRQ(ic);		IEEE80211_AID_SET(vap, ni->ni_associd);		vap->iv_sta_assoc++;		ic->ic_sta_assoc++;#ifdef ATH_SUPERG_XR		if (ni->ni_vap->iv_flags & IEEE80211_F_XR)			ic->ic_xr_sta_assoc++;#endif		if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_ATHC_TURBOP))			ic->ic_dt_sta_assoc++;		if (IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))			ieee80211_node_join_11g(ni);		IEEE80211_UNLOCK_IRQ(ic);		newassoc = 1;	} else		newassoc = 0;	IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_DEBUG, ni,		"station %sassociated at aid %d: %s preamble, %s slot time"		"%s%s%s%s%s%s%s",		newassoc ? "" : "re",		IEEE80211_NODE_AID(ni),		ic->ic_flags & IEEE80211_F_SHPREAMBLE ? "short" : "long",		ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long",		ic->ic_flags & IEEE80211_F_USEPROT ? ", protection" : "",		ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "",		IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_TURBOP) ?			", turbo" : "",		IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_COMP) ?			", compression" : "",		IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_FF) ?			", fast-frames" : "",		IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_XR) ? ", XR" : "",		IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_AR) ? ", AR" : ""	);	/* give driver a chance to setup state like ni_txrate */	if (ic->ic_newassoc != NULL)		ic->ic_newassoc(ni, newassoc);	ni->ni_inact_reload = vap->iv_inact_auth;	ni->ni_inact = ni->ni_inact_reload;	IEEE80211_SEND_MGMT(ni, resp, IEEE80211_STATUS_SUCCESS);	/* tell the authenticator about new station */	if (vap->iv_auth->ia_node_join != NULL)		vap->iv_auth->ia_node_join(ni);	ieee80211_notify_node_join(ni, newassoc);}/* * Handle a station leaving an 11g network. */static voidieee80211_node_leave_11g(struct ieee80211_node *ni){	struct ieee80211com *ic = ni->ni_ic;	struct ieee80211vap *vap = ni->ni_vap;	IEEE80211_LOCK_ASSERT(ic);	KASSERT(IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan),		("not in 11g, bss %u:0x%x, curmode %u",		ic->ic_bsschan->ic_freq, ic->ic_bsschan->ic_flags,		ic->ic_curmode));	/*	 * If a long slot station do the slot time bookkeeping.	 */	if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) == 0) {		/* this can be 0 on mode changes from B -> G */		if (ic->ic_longslotsta > 0)			ic->ic_longslotsta--;		IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,			"long slot time station leaves, count now %d",			ic->ic_longslotsta);		if (ic->ic_longslotsta == 0) {			/*			 * Re-enable use of short slot time if supported			 * and not operating in IBSS mode (per spec).			 */			if ((ic->ic_caps & IEEE80211_C_SHSLOT) &&			    vap->iv_opmode != IEEE80211_M_IBSS) {				IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,					"%s: re-enable use of short slot time\n",					__func__);				ieee80211_set_shortslottime(ic, 1);			}		}	}	/*	 * If a non-ERP station do the protection-related bookkeeping.	 */	if ((ni->ni_flags & IEEE80211_NODE_ERP) == 0) {		/* this can be 0 on mode changes from B -> G */		if (ic->ic_nonerpsta > 0)			ic->ic_nonerpsta--;		IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,			"non-ERP station leaves, count now %d", ic->ic_nonerpsta);		if (ic->ic_nonerpsta == 0) {			IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,				"%s: disable use of protection\n", __func__);			ic->ic_flags &= ~IEEE80211_F_USEPROT;			/* XXX verify mode? */			if (ic->ic_caps & IEEE80211_C_SHPREAMBLE) {				IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,					"%s: re-enable use of short preamble\n",					__func__);				ic->ic_flags |= IEEE80211_F_SHPREAMBLE;				ic->ic_flags &= ~IEEE80211_F_USEBARKER;			}			ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE;		}	}}/* * Handle bookkeeping for a station/neighbor leaving * the bss when operating in ap or adhoc modes. */voidieee80211_node_leave(struct ieee80211_node *ni){	struct ieee80211com *ic = ni->ni_ic;	struct ieee80211vap *vap = ni->ni_vap;	struct ieee80211_node_table *nt = ni->ni_table;	IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_DEBUG, ni,		"station with aid %d leaves (refcnt %u)",		IEEE80211_NODE_AID(ni), ieee80211_node_refcnt(ni));	/*	 * If node wasn't previously associated all	 * we need to do is reclaim the reference.	 */	/* XXX ibss mode bypasses 11g and notification */	if (ni->ni_associd == 0)		goto done;	/*	 * Tell the authenticator the station is leaving.	 * Note that we must do this before yanking the	 * association id as the authenticator uses the	 * associd to locate it's state block.	 */	if (vap->iv_auth->ia_node_leave != NULL)		vap->iv_auth->ia_node_leave(ni);	IEEE80211_LOCK_IRQ(ic);	if (vap->iv_aid_bitmap != NULL)		IEEE80211_AID_CLR(vap, ni->ni_associd);	ni->ni_associd = 0;	vap->iv_sta_assoc--;	ic->ic_sta_assoc--;#ifdef ATH_SUPERG_XR	if (ni->ni_vap->iv_flags & IEEE80211_F_XR)		ic->ic_xr_sta_assoc--;#endif	if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_ATHC_TURBOP))		ic->ic_dt_sta_assoc--;	if (IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))		ieee80211_node_leave_11g(ni);	IEEE80211_UNLOCK_IRQ(ic);	/*	 * Cleanup station state.  In particular clear various	 * state that might otherwise be reused if the node	 * is reused before the reference count goes to zero	 * (and memory is reclaimed).	 */	ieee80211_sta_leave(ni);done:	/*	 * Remove the node from any table it's recorded in and	 * drop the caller's reference.  Removal from the table	 * is important to ensure the node is not reprocessed	 * for inactivity.	 */	if (nt != NULL) {		IEEE80211_NODE_LOCK_IRQ(nt);		node_reclaim(nt, ni);		IEEE80211_NODE_UNLOCK_IRQ(nt);		ieee80211_remove_wds_addr(nt,ni->ni_macaddr);		ieee80211_del_wds_node(nt,ni);	} else		ieee80211_free_node(ni);}EXPORT_SYMBOL(ieee80211_node_leave);u_int8_tieee80211_getrssi(struct ieee80211com *ic){#define	NZ(x)	((x) == 0 ? 1 : (x))	struct ieee80211_node_table *nt = &ic->ic_sta;	struct ieee80211vap *vap;	u_int32_t rssi_samples, rssi_total;	struct ieee80211_node *ni;	rssi_total = 0;	rssi_samples = 0;	switch (ic->ic_opmode) {	case IEEE80211_M_IBSS:		/* average of all ibss neighbors */		/* XXX locking */		TAILQ_FOREACH(ni, &nt->nt_node, ni_list)			if (ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) {				rssi_samples++;				rssi_total += ic->ic_node_getrssi(ni);			}		break;	case IEEE80211_M_AHDEMO:	/* average of all neighbors */		/* XXX locking */		TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {			if (memcmp(ni->ni_vap->iv_myaddr, ni->ni_macaddr, 						IEEE80211_ADDR_LEN)!=0) {				rssi_samples++;				rssi_total += ic->ic_node_getrssi(ni);			}		}		break;	case IEEE80211_M_HOSTAP:	/* average of all associated stations */		/* XXX locking */		TAILQ_FOREACH(ni, &nt->nt_node, ni_list)			if (IEEE80211_AID(ni->ni_associd) != 0) {				rssi_samples++;				rssi_total += ic->ic_node_getrssi(ni);			}		break;	case IEEE80211_M_MONITOR:	/* XXX */	case IEEE80211_M_STA:		/* use stats from associated ap */	default:		TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)			if (vap->iv_bss != NULL) {				rssi_samples++;				rssi_total += ic->ic_node_getrssi(vap->iv_bss);			}		break;	}	return rssi_total / NZ(rssi_samples);#undef NZ}EXPORT_SYMBOL(ieee80211_getrssi);voidieee80211_node_reset(struct ieee80211_node *ni, struct ieee80211vap *vap){	if (ni != NULL) {		struct ieee80211_node_table *nt = ni->ni_table;		if (!nt)			nt = &vap->iv_ic->ic_sta;		IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_bss->ni_bssid);		ni->ni_prev_vap = ni->ni_vap;		ni->ni_vap = vap;		ni->ni_ic = vap->iv_ic;		/* 		 * if node not found in the node table		 * add it to the node table .		 */		if(nt && ieee80211_find_node(nt, ni->ni_macaddr) != ni) {			int hash = IEEE80211_NODE_HASH(ni->ni_macaddr);			IEEE80211_NODE_LOCK_IRQ(nt);			TAILQ_INSERT_TAIL(&nt->nt_node, ni, ni_list);			LIST_INSERT_HEAD(&nt->nt_hash[hash], ni, ni_hash);			ni->ni_table = nt;			IEEE80211_NODE_UNLOCK_IRQ(nt);		}	}}

⌨️ 快捷键说明

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