/* * Remove the key (no locking, for internal use). */ static int _ieee80211_crypto_delkey(struct ieee80211vap *vap, struct ieee80211_key *key) { KASSERT(key->wk_cipher != NULL, ("No cipher!")); IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, "%s: %s keyix %u flags 0x%x rsc %ju tsc %ju len %u\n", __func__, key->wk_cipher->ic_name, key->wk_keyix, key->wk_flags, key->wk_keyrsc[IEEE80211_NONQOS_TID], key->wk_keytsc, key->wk_keylen); if (key->wk_flags & IEEE80211_KEY_DEVKEY) { /* * Remove hardware entry. */ /* XXX key cache */ if (!dev_key_delete(vap, key)) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, "%s: driver did not delete key index %u\n", __func__, key->wk_keyix); vap->iv_stats.is_crypto_delkey++; /* XXX recovery? */ } } cipher_detach(key); memset(key, 0, sizeof(*key)); ieee80211_crypto_resetkey(vap, key, IEEE80211_KEYIX_NONE); return 1; }
/* * Setup crypto support for a vap. */ void ieee80211_crypto_vattach(struct ieee80211vap *vap) { int i; /* NB: we assume everything is pre-zero'd */ vap->iv_max_keyix = IEEE80211_WEP_NKID; vap->iv_def_txkey = IEEE80211_KEYIX_NONE; for (i = 0; i < IEEE80211_WEP_NKID; i++) ieee80211_crypto_resetkey(vap, &vap->iv_nw_keys[i], IEEE80211_KEYIX_NONE); /* * Initialize the driver key support routines to noop entries. * This is useful especially for the cipher test modules. */ vap->iv_key_alloc = null_key_alloc; vap->iv_key_set = null_key_set; vap->iv_key_delete = null_key_delete; vap->iv_key_update_begin = null_key_update; vap->iv_key_update_end = null_key_update; }
/* * Setup crypto support. */ void ieee80211_crypto_attach(struct ieee80211com *ic) { struct ieee80211_crypto_state *cs = &ic->ic_crypto; int i; /* NB: we assume everything is pre-zero'd */ cs->cs_def_txkey = IEEE80211_KEYIX_NONE; ciphers[IEEE80211_CIPHER_NONE] = &ieee80211_cipher_none; for (i = 0; i < IEEE80211_WEP_NKID; i++) ieee80211_crypto_resetkey(ic, &cs->cs_nw_keys[i], i); /* * Initialize the driver key support routines to noop entries. * This is useful especially for the cipher test modules. */ cs->cs_key_alloc = null_key_alloc; cs->cs_key_set = null_key_set; cs->cs_key_delete = null_key_delete; cs->cs_key_update_begin = null_key_update; cs->cs_key_update_end = null_key_update; }
/* * 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, and the temporary node will NOT be put * into node table. */ 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; /* * if vap is being deleted, do not allow new allocations. */ if (ieee80211_vap_deleted_is_set(vap)) { return NULL; } ni = ic->ic_node_alloc(&ic->ic_sta, vap, TRUE /* temp node */); if (ni == NULL) { vap->iv_stats.is_rx_nodealloc++; return NULL; } #ifdef IEEE80211_DEBUG_NODELEAK do { rwlock_state_t lock_state; OS_RWLOCK_WRITE_LOCK(&ic->ic_nodelock,&lock_state); TAILQ_INSERT_TAIL(&ic->ic_nodes, ni, ni_alloc_list); OS_RWLOCK_WRITE_UNLOCK(&ic->ic_nodelock,&lock_state); } while(0); #endif ni->ni_flags |= IEEE80211_NODE_TEMP; /* useful for debugging */ ieee80211_ref_node(ni); /* mark referenced */ IEEE80211_VAP_LOCK(vap); vap->iv_node_count++; IEEE80211_VAP_UNLOCK(vap); ni->ni_bss_node = ieee80211_ref_bss_node(vap); ni->ni_vap = vap; ni->ni_ic = ic; ni->ni_table = NULL; /* copy some default variables from parent */ IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr); ni->ni_intval = ic->ic_intval; /* default beacon interval */ /* set default rate and channel */ ieee80211_node_set_chan(ni); ni->ni_txpower = ic->ic_txpowlimit; /* max power */ /* init our unicast / receive key state */ ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey, IEEE80211_KEYIX_NONE); ieee80211_crypto_resetkey(vap, &ni->ni_persta.nips_hwkey, IEEE80211_KEYIX_NONE); for (i = 0; i < IEEE80211_WEP_NKID; i++) { ieee80211_crypto_resetkey(vap, &ni->ni_persta.nips_swkey[i], IEEE80211_KEYIX_NONE); } ni->ni_ath_defkeyindex = IEEE80211_INVAL_DEFKEY; /* IBSS-only: mark as unassociated by default. */ ni->ni_assoc_state = IEEE80211_NODE_ADHOC_STATE_UNAUTH_UNASSOC; /* 11n */ ni->ni_chwidth = ic->ic_cwm_get_width(ic); IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_bss->ni_bssid); return ni; }