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

📄 ieee80211_node.c

📁 Linux下wifi实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	return ni->ni_rssi;}/* * Create an entry in the specified node table.  The node * is setup with the mac address, an initial reference count, * and some basic parameters obtained from global state. * This interface is not intended for general use, it is * used by the routines below to create entries with a * specific purpose. */struct ieee80211_node *ieee80211_alloc_node(struct ieee80211_node_table *nt,	struct ieee80211vap *vap, const u_int8_t *macaddr){	struct ieee80211com *ic = nt->nt_ic;	struct ieee80211_node *ni;	int hash;	int i;	ni = ic->ic_node_alloc(nt, vap);	if (ni == NULL) {		/* XXX msg */		vap->iv_stats.is_rx_nodealloc++;		return NULL;	}	IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,		"%s: %p<%s> in %s table, refcnt %d\n", __func__, ni,		ether_sprintf(macaddr), nt->nt_name,		ieee80211_node_refcnt(ni)+1);	IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr);	hash = IEEE80211_NODE_HASH(macaddr);	ieee80211_node_initref(ni);		/* mark referenced */	ni->ni_chan = IEEE80211_CHAN_ANYC;	ni->ni_authmode = IEEE80211_AUTH_OPEN;	ni->ni_txpower = ic->ic_txpowlimit;	/* max power */	ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey, IEEE80211_KEYIX_NONE);	ni->ni_inact_reload = nt->nt_inact_init;	ni->ni_inact = ni->ni_inact_reload;	ni->ni_ath_defkeyindex = IEEE80211_INVAL_DEFKEY;	ni->ni_rxkeyoff = 0;	IEEE80211_NODE_SAVEQ_INIT(ni, "unknown");	IEEE80211_NODE_LOCK_IRQ(nt);	ni->ni_vap = vap;	ni->ni_ic = ic;	ni->ni_table = nt;	TAILQ_INSERT_TAIL(&nt->nt_node, ni, ni_list);	LIST_INSERT_HEAD(&nt->nt_hash[hash], ni, ni_hash);#define	N(a)	(sizeof(a)/sizeof(a[0]))	for (i = 0; i < N(ni->ni_rxfrag); i++)		ni->ni_rxfrag[i] = NULL;#undef N	ni->ni_challenge = NULL;	IEEE80211_NODE_UNLOCK_IRQ(nt);	WME_UAPSD_NODE_TRIGSEQINIT(ni);	return ni;}EXPORT_SYMBOL(ieee80211_alloc_node);/* Add wds address to the node table */intieee80211_add_wds_addr(struct ieee80211_node_table *nt,	struct ieee80211_node *ni, const u_int8_t *macaddr, u_int8_t wds_static){	int hash;	struct ieee80211_wds_addr *wds;	MALLOC(wds, struct ieee80211_wds_addr *, sizeof(struct ieee80211_wds_addr),	       M_80211_WDS, M_NOWAIT | M_ZERO);	if (wds == NULL) {		/* XXX msg */		return 1;	}	if (wds_static)		wds->wds_agingcount = WDS_AGING_STATIC;	else		wds->wds_agingcount = WDS_AGING_COUNT;	hash = IEEE80211_NODE_HASH(macaddr);	IEEE80211_ADDR_COPY(wds->wds_macaddr, macaddr);	ieee80211_ref_node(ni);		/* Reference node */	wds->wds_ni = ni;	IEEE80211_NODE_LOCK_IRQ(nt);	LIST_INSERT_HEAD(&nt->nt_wds_hash[hash], wds, wds_hash);	IEEE80211_NODE_UNLOCK_IRQ(nt);	return 0;}EXPORT_SYMBOL(ieee80211_add_wds_addr);/* remove wds address from the wds hash table */voidieee80211_remove_wds_addr(struct ieee80211_node_table *nt, const u_int8_t *macaddr){	int hash;	struct ieee80211_wds_addr *wds;	hash = IEEE80211_NODE_HASH(macaddr);	IEEE80211_NODE_LOCK_IRQ(nt);	LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) {		if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) {			if (ieee80211_node_dectestref(wds->wds_ni)) {				_ieee80211_free_node(wds->wds_ni);				LIST_REMOVE(wds, wds_hash);				FREE(wds, M_80211_WDS);				break;			}		}	}	IEEE80211_NODE_UNLOCK_IRQ(nt);}EXPORT_SYMBOL(ieee80211_remove_wds_addr);/* Remove node references from wds table */voidieee80211_del_wds_node(struct ieee80211_node_table *nt, struct ieee80211_node *ni){	int hash;	struct ieee80211_wds_addr *wds;	IEEE80211_NODE_LOCK_IRQ(nt);	for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) {		LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) {			if (wds->wds_ni == ni) {				if (ieee80211_node_dectestref(ni)) {					_ieee80211_free_node(ni);					LIST_REMOVE(wds, wds_hash);					FREE(wds, M_80211_WDS);				}			}		}	}	IEEE80211_NODE_UNLOCK_IRQ(nt);}EXPORT_SYMBOL(ieee80211_del_wds_node);static void ieee80211_node_wds_ageout(unsigned long data){	struct ieee80211_node_table *nt = (struct ieee80211_node_table *)data;	int hash;	struct ieee80211_wds_addr *wds;	IEEE80211_NODE_LOCK_IRQ(nt);	for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) {		LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) {			if (wds->wds_agingcount != WDS_AGING_STATIC) {				if (!wds->wds_agingcount) {					if (ieee80211_node_dectestref(wds->wds_ni)) {						_ieee80211_free_node(wds->wds_ni);  						LIST_REMOVE(wds, wds_hash);						FREE(wds, M_80211_WDS);					}				} else					wds->wds_agingcount--;			}		}	}	IEEE80211_NODE_UNLOCK_IRQ(nt);	mod_timer(&nt->nt_wds_aging_timer, jiffies + HZ * WDS_AGING_TIMER_VAL);}/* * Craft a temporary node suitable for sending a management frame * to the specified station.  We craft only as much state as we * need to do the work since the node will be immediately reclaimed * once the send completes. */struct ieee80211_node *ieee80211_tmp_node(struct ieee80211vap *vap, const u_int8_t *macaddr){	struct ieee80211com *ic = vap->iv_ic;	struct ieee80211_node *ni;	int i;	ni = ic->ic_node_alloc(&ic->ic_sta,vap);	if (ni != NULL) {		IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, 		"%s: %p<%s> refcnt %d\n", __func__, ni, ether_sprintf(macaddr), 		ieee80211_node_refcnt(ni)+1);		IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr);		IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_bss->ni_bssid);		ieee80211_node_initref(ni);		/* mark referenced */		ni->ni_txpower = vap->iv_bss->ni_txpower;		ni->ni_vap = vap;		/* NB: required by ieee80211_fix_rate */		ieee80211_node_set_chan(ic, ni);		ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey,			IEEE80211_KEYIX_NONE);		/* XXX optimize away */		IEEE80211_NODE_SAVEQ_INIT(ni, "unknown");		ni->ni_table = NULL;		/* NB: pedantic */		ni->ni_ic = ic;#define	N(a)	(sizeof(a)/sizeof(a[0]))		for (i = 0; i < N(ni->ni_rxfrag); i++)			ni->ni_rxfrag[i] = NULL;#undef N		ni->ni_challenge = NULL;	} else {		/* XXX msg */		vap->iv_stats.is_rx_nodealloc++;	}	return ni;}/* * Add the specified station to the station table. */struct ieee80211_node *ieee80211_dup_bss(struct ieee80211vap *vap, const u_int8_t *macaddr){	struct ieee80211com *ic = vap->iv_ic;	struct ieee80211_node *ni;	int i;	ni = ieee80211_alloc_node(&ic->ic_sta, vap, macaddr);	if (ni != NULL) {		/*		 * Inherit from iv_bss.		 */		ni->ni_authmode = vap->iv_bss->ni_authmode;		ni->ni_txpower = vap->iv_bss->ni_txpower;		ni->ni_vlan = vap->iv_bss->ni_vlan;	/* XXX?? */		IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_bss->ni_bssid);		ieee80211_node_set_chan(ic, ni);		ni->ni_rsn = vap->iv_bss->ni_rsn;#define	N(a)	(sizeof(a)/sizeof(a[0]))		for (i = 0; i < N(ni->ni_rxfrag); i++)			ni->ni_rxfrag[i] = NULL;#undef N	}	return ni;}static struct ieee80211_node *_ieee80211_find_wds_node(struct ieee80211_node_table *nt, const u_int8_t *macaddr){	struct ieee80211_node *ni;	struct ieee80211_wds_addr *wds;	int hash;	IEEE80211_NODE_LOCK_ASSERT(nt);	hash = IEEE80211_NODE_HASH(macaddr);	LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) {		if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) {			ni = wds->wds_ni;			if (wds->wds_agingcount != WDS_AGING_STATIC)				wds->wds_agingcount = WDS_AGING_COUNT; /* reset the aging count */			ieee80211_ref_node(ni);			return ni;		}	}	return NULL;}static struct ieee80211_node *#ifdef IEEE80211_DEBUG_REFCNT_ieee80211_find_node_debug(struct ieee80211_node_table *nt,	const u_int8_t *macaddr, const char *func, int line)#else_ieee80211_find_node(struct ieee80211_node_table *nt, const u_int8_t *macaddr)#endif{	struct ieee80211_node *ni;	int hash;	struct ieee80211_wds_addr *wds;	IEEE80211_NODE_LOCK_ASSERT(nt);	hash = IEEE80211_NODE_HASH(macaddr);	LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) {		if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) {			ieee80211_ref_node(ni);	/* mark referenced */#ifdef IEEE80211_DEBUG_REFCNT			IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE,				"%s (%s:%u) %p<%s> refcnt %d\n", __func__,				func, line,				ni, ether_sprintf(ni->ni_macaddr),				ieee80211_node_refcnt(ni));#endif			return ni;		}	}		/* Now, we look for the desired mac address in the 4 address	   nodes. */	LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) {		if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) {			ni = wds->wds_ni;			ieee80211_ref_node(ni);			return ni;		}	}	return NULL;}#ifdef IEEE80211_DEBUG_REFCNT#define	_ieee80211_find_node(nt, mac) \	_ieee80211_find_node_debug(nt, mac, func, line)#endifstruct ieee80211_node *ieee80211_find_wds_node(struct ieee80211_node_table *nt, const u_int8_t *macaddr){	struct ieee80211_node *ni;	IEEE80211_NODE_LOCK_IRQ(nt);	ni = _ieee80211_find_wds_node(nt, macaddr);	IEEE80211_NODE_UNLOCK_IRQ(nt);	return ni;}EXPORT_SYMBOL(ieee80211_find_wds_node);struct ieee80211_node *#ifdef IEEE80211_DEBUG_REFCNTieee80211_find_node_debug(struct ieee80211_node_table *nt,	const u_int8_t *macaddr, const char *func, int line)#elseieee80211_find_node(struct ieee80211_node_table *nt, const u_int8_t *macaddr)#endif{	struct ieee80211_node *ni;	IEEE80211_NODE_LOCK_IRQ(nt);	ni = _ieee80211_find_node(nt, macaddr);	IEEE80211_NODE_UNLOCK_IRQ(nt);	return ni;}#ifdef IEEE80211_DEBUG_REFCNTEXPORT_SYMBOL(ieee80211_find_node_debug);#elseEXPORT_SYMBOL(ieee80211_find_node);#endif/* * Fake up a node; this handles node discovery in adhoc mode. * Note that for the driver's benefit we we treat this like * an association so the driver has an opportunity to setup * it's private state. * * Caller must ieee80211_ref_node() */struct ieee80211_node *ieee80211_fakeup_adhoc_node(struct ieee80211vap *vap,	const u_int8_t macaddr[IEEE80211_ADDR_LEN]){	struct ieee80211_node *ni;	ni = ieee80211_dup_bss(vap, macaddr);	if (ni != NULL) {		/* XXX no rate negotiation; just dup */		ni->ni_rates = vap->iv_bss->ni_rates;		if (vap->iv_ic->ic_newassoc != NULL)			vap->iv_ic->ic_newassoc(ni, 1);		/* XXX not right for 802.1x/WPA */		ieee80211_node_authorize(ni);		IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, 		"%s: %p<%s> refcnt %d\n", __func__, ni, ether_sprintf(macaddr), 		ieee80211_node_refcnt(ni));	}	return ni;}/* * Do node discovery in adhoc mode on receipt of a beacon * or probe response frame.  Note that for the driver's * benefit we treat this like an association so the * driver has an opportunity to setup it's private state. */struct ieee80211_node *ieee80211_add_neighbor(struct ieee80211vap *vap,	const struct ieee80211_frame *wh,	const struct ieee80211_scanparams *sp){	struct ieee80211com *ic = vap->iv_ic;	struct ieee80211_node *ni;	ni = ieee80211_dup_bss(vap, wh->i_addr2);	/* XXX alloc_node? */	/* TODO: not really putting itself in a table */	if (ni != NULL) {		ni->ni_esslen = sp->ssid[1];		memcpy(ni->ni_essid, sp->ssid + 2, sp->ssid[1]);		IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);		memcpy(ni->ni_tstamp.data, sp->tstamp, sizeof(ni->ni_tstamp));		ni->ni_intval = sp->bintval;		ni->ni_capinfo = sp->capinfo;		ni->ni_chan = ic->ic_curchan;		ni->ni_fhdwell = sp->fhdwell;		ni->ni_fhindex = sp->fhindex;		ni->ni_erp = sp->erp;		ni->ni_timoff = sp->timoff;		if (sp->wme != NULL)			ieee80211_saveie(&ni->ni_wme_ie, sp->wme);		if (sp->wpa != NULL)			ieee80211_saveie(&ni->ni_wpa_ie, sp->wpa);		if (sp->rsn != NULL)			ieee80211_saveie(&ni->ni_rsn_ie, sp->rsn);		if (sp->ath != NULL)			ieee80211_saveath(ni, sp->ath);		/* NB: must be after ni_chan is setup */		ieee80211_setup_rates(ni, sp->rates, sp->xrates, IEEE80211_F_DOSORT);		if (ic->ic_newassoc != NULL)			ic->ic_newassoc(ni, 1);		/* XXX not right for 802.1x/WPA */		ieee80211_node_authorize(ni);		if (vap->iv_opmode == IEEE80211_M_AHDEMO) {			/*			 * Blindly propagate capabilities based on the			 * local configuration.  In particular this permits

⌨️ 快捷键说明

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