示例#1
0
/*
 * Handle bookkeeping for station deauthentication/disassociation
 * when operating as an ap.
 */
void
ieee80211_node_leave(struct ieee80211com *ic, struct ieee80211_node *ni)
{
	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
		panic("not in ap mode, mode %u", ic->ic_opmode);
	/*
	 * If node wasn't previously associated all
	 * we need to do is reclaim the reference.
	 */
	if (ni->ni_associd == 0)
		return;
	IEEE80211_AID_CLR(ni->ni_associd, ic->ic_aid_bitmap);
	ni->ni_associd = 0;

	if (ic->ic_curmode == IEEE80211_MODE_11G)
		ieee80211_node_leave_11g(ic, ni);

	ieee80211_node_newstate(ni, IEEE80211_STA_COLLECT);

#if NBRIDGE > 0
	/*
	 * If the parent interface belongs to a bridge, delete
	 * any dynamically learned address for this node.
	 */
	if (ic->ic_if.if_bridge != NULL)
		bridge_update(&ic->ic_if,
		    (struct ether_addr *)ni->ni_macaddr, 1);
#endif
}
示例#2
0
/*
 * Handle bookkeeping for station deauthentication/disassociation
 * when operating as an ap.
 */
void
ieee80211_node_leave(struct ieee80211com *ic, struct ieee80211_node *ni)
{
	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
		panic("not in ap mode, mode %u", ic->ic_opmode);
	/*
	 * If node wasn't previously associated all we need to do is
	 * reclaim the reference.
	 */
	if (ni->ni_associd == 0) {
		ieee80211_node_newstate(ni, IEEE80211_STA_COLLECT);
		return;
	}

	if (ni->ni_pwrsave == IEEE80211_PS_DOZE) {
		ic->ic_pssta--;
		ni->ni_pwrsave = IEEE80211_PS_AWAKE;
	}

	if (!IF_IS_EMPTY(&ni->ni_savedq)) {
		IF_PURGE(&ni->ni_savedq);
		if (ic->ic_set_tim != NULL)
			(*ic->ic_set_tim)(ic, ni->ni_associd, 0);
	}

	if (ic->ic_flags & IEEE80211_F_RSNON)
		ieee80211_node_leave_rsn(ic, ni);

	if (ic->ic_curmode == IEEE80211_MODE_11G)
		ieee80211_node_leave_11g(ic, ni);

#ifndef IEEE80211_NO_HT
	if (ni->ni_flags & IEEE80211_NODE_HT)
		ieee80211_node_leave_ht(ic, ni);
#endif

	if (ic->ic_node_leave != NULL)
		(*ic->ic_node_leave)(ic, ni);

	IEEE80211_AID_CLR(ni->ni_associd, ic->ic_aid_bitmap);
	ni->ni_associd = 0;
	ieee80211_node_newstate(ni, IEEE80211_STA_COLLECT);

#if NBRIDGE > 0
	/*
	 * If the parent interface is a bridgeport, delete
	 * any dynamically learned address for this node.
	 */
	if (ic->ic_if.if_bridgeport != NULL)
		bridge_update(&ic->ic_if,
		    (struct ether_addr *)ni->ni_macaddr, 1);
#endif
}
示例#3
0
void
ieee80211_node_join(struct ieee80211com *ic, struct ieee80211_node *ni,
    int resp)
{
	int newassoc;

	if (ni->ni_associd == 0) {
		u_int16_t aid;

		/*
		 * It would be clever to search the bitmap
		 * more efficiently, but this will do for now.
		 */
		for (aid = 1; aid < ic->ic_max_aid; aid++) {
			if (!IEEE80211_AID_ISSET(aid,
			    ic->ic_aid_bitmap))
				break;
		}
		if (aid >= ic->ic_max_aid) {
			IEEE80211_SEND_MGMT(ic, ni, resp,
			    IEEE80211_REASON_ASSOC_TOOMANY);
			ieee80211_node_leave(ic, ni);
			return;
		}
		ni->ni_associd = aid | 0xc000;
		IEEE80211_AID_SET(ni->ni_associd, ic->ic_aid_bitmap);
		newassoc = 1;
		if (ic->ic_curmode == IEEE80211_MODE_11G)
			ieee80211_node_join_11g(ic, ni);
	} else
		newassoc = 0;

	IEEE80211_DPRINTF(("station %s %s associated at aid %d\n",
	    ether_sprintf(ni->ni_macaddr),
	    (newassoc ? "newly" : "already"),
	    ni->ni_associd & ~0xc000));

	/* give driver a chance to setup state like ni_txrate */
	if (ic->ic_newassoc)
		(*ic->ic_newassoc)(ic, ni, newassoc);
	IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_SUCCESS);
	ieee80211_node_newstate(ni, IEEE80211_STA_ASSOC);

#if NBRIDGE > 0
	/*
	 * If the parent interface belongs to a bridge, learn
	 * the node's address dynamically on this interface.
	 */
	if (ic->ic_if.if_bridge != NULL)
		bridge_update(&ic->ic_if,
		    (struct ether_addr *)ni->ni_macaddr, 0);
#endif
}