/* * 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 }
/* * 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 }
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 }