| 1 | /*- |
| 2 | * Copyright (c) 2001 Atsushi Onoe |
| 3 | * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting |
| 4 | * All rights reserved. |
| 5 | * |
| 6 | * Redistribution and use in source and binary forms, with or without |
| 7 | * modification, are permitted provided that the following conditions |
| 8 | * are met: |
| 9 | * 1. Redistributions of source code must retain the above copyright |
| 10 | * notice, this list of conditions and the following disclaimer. |
| 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 12 | * notice, this list of conditions and the following disclaimer in the |
| 13 | * documentation and/or other materials provided with the distribution. |
| 14 | * |
| 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 25 | * |
| 26 | * $FreeBSD$ |
| 27 | */ |
| 28 | #ifndef _NET80211_IEEE80211_NODE_H_ |
| 29 | #define _NET80211_IEEE80211_NODE_H_ |
| 30 | |
| 31 | #include <netproto/802_11/ieee80211_ioctl.h> /* for ieee80211_nodestats */ |
| 32 | #include <netproto/802_11/ieee80211_ht.h> /* for aggregation state */ |
| 33 | |
| 34 | /* |
| 35 | * Each ieee80211com instance has a single timer that fires every |
| 36 | * IEEE80211_INACT_WAIT seconds to handle "inactivity processing". |
| 37 | * This is used to do node inactivity processing when operating |
| 38 | * as an AP, adhoc or mesh mode. For inactivity processing each node |
| 39 | * has a timeout set in it's ni_inact field that is decremented |
| 40 | * on each timeout and the node is reclaimed when the counter goes |
| 41 | * to zero. We use different inactivity timeout values depending |
| 42 | * on whether the node is associated and authorized (either by |
| 43 | * 802.1x or open/shared key authentication) or associated but yet |
| 44 | * to be authorized. The latter timeout is shorter to more aggressively |
| 45 | * reclaim nodes that leave part way through the 802.1x exchange. |
| 46 | */ |
| 47 | #define IEEE80211_INACT_WAIT 15 /* inactivity interval (secs) */ |
| 48 | #define IEEE80211_INACT_INIT (30/IEEE80211_INACT_WAIT) /* initial */ |
| 49 | #define IEEE80211_INACT_AUTH (180/IEEE80211_INACT_WAIT) /* associated but not authorized */ |
| 50 | #define IEEE80211_INACT_RUN (300/IEEE80211_INACT_WAIT) /* authorized */ |
| 51 | #define IEEE80211_INACT_PROBE (30/IEEE80211_INACT_WAIT) /* probe */ |
| 52 | #define IEEE80211_INACT_SCAN (300/IEEE80211_INACT_WAIT) /* scanned */ |
| 53 | |
| 54 | #define IEEE80211_TRANS_WAIT 2 /* mgt frame tx timer (secs) */ |
| 55 | |
| 56 | /* threshold for aging overlapping non-ERP bss */ |
| 57 | #define IEEE80211_NONERP_PRESENT_AGE msecs_to_ticks(60*1000) |
| 58 | |
| 59 | #define IEEE80211_NODE_HASHSIZE 32 /* NB: hash size must be pow2 */ |
| 60 | /* simple hash is enough for variation of macaddr */ |
| 61 | #define IEEE80211_NODE_HASH(ic, addr) \ |
| 62 | (((const uint8_t *)(addr))[IEEE80211_ADDR_LEN - 1] % \ |
| 63 | IEEE80211_NODE_HASHSIZE) |
| 64 | |
| 65 | struct ieee80211_node_table; |
| 66 | struct ieee80211com; |
| 67 | struct ieee80211vap; |
| 68 | |
| 69 | /* |
| 70 | * Information element ``blob''. We use this structure |
| 71 | * to capture management frame payloads that need to be |
| 72 | * retained. Information elements within the payload that |
| 73 | * we need to consult have references recorded. |
| 74 | */ |
| 75 | struct ieee80211_ies { |
| 76 | /* the following are either NULL or point within data */ |
| 77 | uint8_t *wpa_ie; /* captured WPA ie */ |
| 78 | uint8_t *rsn_ie; /* captured RSN ie */ |
| 79 | uint8_t *wme_ie; /* captured WME ie */ |
| 80 | uint8_t *ath_ie; /* captured Atheros ie */ |
| 81 | uint8_t *htcap_ie; /* captured HTCAP ie */ |
| 82 | uint8_t *htinfo_ie; /* captured HTINFO ie */ |
| 83 | uint8_t *tdma_ie; /* captured TDMA ie */ |
| 84 | uint8_t *meshid_ie; /* captured MESH ID ie */ |
| 85 | uint8_t *spare[4]; |
| 86 | /* NB: these must be the last members of this structure */ |
| 87 | uint8_t *data; /* frame data > 802.11 header */ |
| 88 | int len; /* data size in bytes */ |
| 89 | }; |
| 90 | |
| 91 | /* |
| 92 | * 802.11s (Mesh) Peer Link FSM state. |
| 93 | */ |
| 94 | enum ieee80211_mesh_mlstate { |
| 95 | IEEE80211_NODE_MESH_IDLE = 0, |
| 96 | IEEE80211_NODE_MESH_OPENSNT = 1, /* open frame sent */ |
| 97 | IEEE80211_NODE_MESH_OPENRCV = 2, /* open frame received */ |
| 98 | IEEE80211_NODE_MESH_CONFIRMRCV = 3, /* confirm frame received */ |
| 99 | IEEE80211_NODE_MESH_ESTABLISHED = 4, /* link established */ |
| 100 | IEEE80211_NODE_MESH_HOLDING = 5, /* link closing */ |
| 101 | }; |
| 102 | #define IEEE80211_MESH_MLSTATE_BITS \ |
| 103 | "\20\1IDLE\2OPENSNT\2OPENRCV\3CONFIRMRCV\4ESTABLISHED\5HOLDING" |
| 104 | |
| 105 | /* |
| 106 | * Node specific information. Note that drivers are expected |
| 107 | * to derive from this structure to add device-specific per-node |
| 108 | * state. This is done by overriding the ic_node_* methods in |
| 109 | * the ieee80211com structure. |
| 110 | */ |
| 111 | struct ieee80211_node { |
| 112 | struct ieee80211vap *ni_vap; /* associated vap */ |
| 113 | struct ieee80211com *ni_ic; /* copy from vap to save deref*/ |
| 114 | struct ieee80211_node_table *ni_table; /* NB: may be NULL */ |
| 115 | TAILQ_ENTRY(ieee80211_node) ni_list; /* list of all nodes */ |
| 116 | LIST_ENTRY(ieee80211_node) ni_hash; /* hash collision list */ |
| 117 | u_int ni_refcnt; /* count of held references */ |
| 118 | u_int ni_scangen; /* gen# for timeout scan */ |
| 119 | u_int ni_flags; |
| 120 | #define IEEE80211_NODE_AUTH 0x000001 /* authorized for data */ |
| 121 | #define IEEE80211_NODE_QOS 0x000002 /* QoS enabled */ |
| 122 | #define IEEE80211_NODE_ERP 0x000004 /* ERP enabled */ |
| 123 | /* NB: this must have the same value as IEEE80211_FC1_PWR_MGT */ |
| 124 | #define IEEE80211_NODE_PWR_MGT 0x000010 /* power save mode enabled */ |
| 125 | #define IEEE80211_NODE_AREF 0x000020 /* authentication ref held */ |
| 126 | #define IEEE80211_NODE_HT 0x000040 /* HT enabled */ |
| 127 | #define IEEE80211_NODE_HTCOMPAT 0x000080 /* HT setup w/ vendor OUI's */ |
| 128 | #define IEEE80211_NODE_WPS 0x000100 /* WPS association */ |
| 129 | #define IEEE80211_NODE_TSN 0x000200 /* TSN association */ |
| 130 | #define IEEE80211_NODE_AMPDU_RX 0x000400 /* AMPDU rx enabled */ |
| 131 | #define IEEE80211_NODE_AMPDU_TX 0x000800 /* AMPDU tx enabled */ |
| 132 | #define IEEE80211_NODE_MIMO_PS 0x001000 /* MIMO power save enabled */ |
| 133 | #define IEEE80211_NODE_MIMO_RTS 0x002000 /* send RTS in MIMO PS */ |
| 134 | #define IEEE80211_NODE_RIFS 0x004000 /* RIFS enabled */ |
| 135 | #define IEEE80211_NODE_SGI20 0x008000 /* Short GI in HT20 enabled */ |
| 136 | #define IEEE80211_NODE_SGI40 0x010000 /* Short GI in HT40 enabled */ |
| 137 | #define IEEE80211_NODE_ASSOCID 0x020000 /* xmit requires associd */ |
| 138 | #define IEEE80211_NODE_AMSDU_RX 0x040000 /* AMSDU rx enabled */ |
| 139 | #define IEEE80211_NODE_AMSDU_TX 0x080000 /* AMSDU tx enabled */ |
| 140 | uint16_t ni_associd; /* association ID */ |
| 141 | uint16_t ni_vlan; /* vlan tag */ |
| 142 | uint16_t ni_txpower; /* current transmit power */ |
| 143 | uint8_t ni_authmode; /* authentication algorithm */ |
| 144 | uint8_t ni_ath_flags; /* Atheros feature flags */ |
| 145 | /* NB: These must have the same values as IEEE80211_ATHC_* */ |
| 146 | #define IEEE80211_NODE_TURBOP 0x0001 /* Turbo prime enable */ |
| 147 | #define IEEE80211_NODE_COMP 0x0002 /* Compresssion enable */ |
| 148 | #define IEEE80211_NODE_FF 0x0004 /* Fast Frame capable */ |
| 149 | #define IEEE80211_NODE_XR 0x0008 /* Atheros WME enable */ |
| 150 | #define IEEE80211_NODE_AR 0x0010 /* AR capable */ |
| 151 | #define IEEE80211_NODE_BOOST 0x0080 /* Dynamic Turbo boosted */ |
| 152 | uint16_t ni_ath_defkeyix;/* Atheros def key index */ |
| 153 | const struct ieee80211_txparam *ni_txparms; |
| 154 | uint32_t ni_jointime; /* time of join (secs) */ |
| 155 | uint32_t *ni_challenge; /* shared-key challenge */ |
| 156 | struct ieee80211_ies ni_ies; /* captured ie's */ |
| 157 | /* tx seq per-tid */ |
| 158 | ieee80211_seq ni_txseqs[IEEE80211_TID_SIZE]; |
| 159 | /* rx seq previous per-tid*/ |
| 160 | ieee80211_seq ni_rxseqs[IEEE80211_TID_SIZE]; |
| 161 | uint32_t ni_rxfragstamp; /* time stamp of last rx frag */ |
| 162 | struct mbuf *ni_rxfrag[3]; /* rx frag reassembly */ |
| 163 | struct ieee80211_key ni_ucastkey; /* unicast key */ |
| 164 | |
| 165 | /* hardware */ |
| 166 | uint32_t ni_avgrssi; /* recv ssi state */ |
| 167 | int8_t ni_noise; /* noise floor */ |
| 168 | |
| 169 | /* mimo statistics */ |
| 170 | uint32_t ni_mimo_rssi_ctl[IEEE80211_MAX_CHAINS]; |
| 171 | uint32_t ni_mimo_rssi_ext[IEEE80211_MAX_CHAINS]; |
| 172 | uint8_t ni_mimo_noise_ctl[IEEE80211_MAX_CHAINS]; |
| 173 | uint8_t ni_mimo_noise_ext[IEEE80211_MAX_CHAINS]; |
| 174 | uint8_t ni_mimo_chains; |
| 175 | |
| 176 | /* header */ |
| 177 | uint8_t ni_macaddr[IEEE80211_ADDR_LEN]; |
| 178 | uint8_t ni_bssid[IEEE80211_ADDR_LEN]; |
| 179 | |
| 180 | /* beacon, probe response */ |
| 181 | union { |
| 182 | uint8_t data[8]; |
| 183 | u_int64_t tsf; |
| 184 | } ni_tstamp; /* from last rcv'd beacon */ |
| 185 | uint16_t ni_intval; /* beacon interval */ |
| 186 | uint16_t ni_capinfo; /* capabilities */ |
| 187 | uint8_t ni_esslen; |
| 188 | uint8_t ni_essid[IEEE80211_NWID_LEN]; |
| 189 | struct ieee80211_rateset ni_rates; /* negotiated rate set */ |
| 190 | struct ieee80211_channel *ni_chan; |
| 191 | uint16_t ni_fhdwell; /* FH only */ |
| 192 | uint8_t ni_fhindex; /* FH only */ |
| 193 | uint16_t ni_erp; /* ERP from beacon/probe resp */ |
| 194 | uint16_t ni_timoff; /* byte offset to TIM ie */ |
| 195 | uint8_t ni_dtim_period; /* DTIM period */ |
| 196 | uint8_t ni_dtim_count; /* DTIM count for last bcn */ |
| 197 | |
| 198 | /* 11s state */ |
| 199 | uint8_t ni_meshidlen; |
| 200 | uint8_t ni_meshid[IEEE80211_MESHID_LEN]; |
| 201 | enum ieee80211_mesh_mlstate ni_mlstate; /* peering management state */ |
| 202 | uint16_t ni_mllid; /* link local ID */ |
| 203 | uint16_t ni_mlpid; /* link peer ID */ |
| 204 | struct callout ni_mltimer; /* link mesh timer */ |
| 205 | uint8_t ni_mlrcnt; /* link mesh retry counter */ |
| 206 | uint8_t ni_mltval; /* link mesh timer value */ |
| 207 | struct callout ni_mlhtimer; /* link mesh backoff timer */ |
| 208 | uint8_t ni_mlhcnt; /* link mesh holding counter */ |
| 209 | |
| 210 | /* 11n state */ |
| 211 | uint16_t ni_htcap; /* HT capabilities */ |
| 212 | uint8_t ni_htparam; /* HT params */ |
| 213 | uint8_t ni_htctlchan; /* HT control channel */ |
| 214 | uint8_t ni_ht2ndchan; /* HT 2nd channel */ |
| 215 | uint8_t ni_htopmode; /* HT operating mode */ |
| 216 | uint8_t ni_htstbc; /* HT */ |
| 217 | uint8_t ni_chw; /* negotiated channel width */ |
| 218 | struct ieee80211_htrateset ni_htrates; /* negotiated ht rate set */ |
| 219 | struct ieee80211_tx_ampdu ni_tx_ampdu[WME_NUM_TID]; |
| 220 | struct ieee80211_rx_ampdu ni_rx_ampdu[WME_NUM_TID]; |
| 221 | |
| 222 | /* others */ |
| 223 | short ni_inact; /* inactivity mark count */ |
| 224 | short ni_inact_reload;/* inactivity reload value */ |
| 225 | int ni_txrate; /* legacy rate/MCS */ |
| 226 | struct ieee80211_psq ni_psq; /* power save queue */ |
| 227 | struct ieee80211_nodestats ni_stats; /* per-node statistics */ |
| 228 | |
| 229 | struct ieee80211vap *ni_wdsvap; /* associated WDS vap */ |
| 230 | void *ni_rctls; /* private ratectl state */ |
| 231 | uint64_t ni_spare[3]; |
| 232 | }; |
| 233 | MALLOC_DECLARE(M_80211_NODE); |
| 234 | MALLOC_DECLARE(M_80211_NODE_IE); |
| 235 | |
| 236 | #define IEEE80211_NODE_ATH (IEEE80211_NODE_FF | IEEE80211_NODE_TURBOP) |
| 237 | #define IEEE80211_NODE_AMPDU \ |
| 238 | (IEEE80211_NODE_AMPDU_RX | IEEE80211_NODE_AMPDU_TX) |
| 239 | #define IEEE80211_NODE_AMSDU \ |
| 240 | (IEEE80211_NODE_AMSDU_RX | IEEE80211_NODE_AMSDU_TX) |
| 241 | #define IEEE80211_NODE_HT_ALL \ |
| 242 | (IEEE80211_NODE_HT | IEEE80211_NODE_HTCOMPAT | \ |
| 243 | IEEE80211_NODE_AMPDU | IEEE80211_NODE_AMSDU | \ |
| 244 | IEEE80211_NODE_MIMO_PS | IEEE80211_NODE_MIMO_RTS | \ |
| 245 | IEEE80211_NODE_RIFS | IEEE80211_NODE_SGI20 | IEEE80211_NODE_SGI40) |
| 246 | |
| 247 | #define IEEE80211_NODE_BITS \ |
| 248 | "\20\1AUTH\2QOS\3ERP\5PWR_MGT\6AREF\7HT\10HTCOMPAT\11WPS\12TSN" \ |
| 249 | "\13AMPDU_RX\14AMPDU_TX\15MIMO_PS\16MIMO_RTS\17RIFS\20SGI20\21SGI40" \ |
| 250 | "\22ASSOCID" |
| 251 | |
| 252 | #define IEEE80211_NODE_AID(ni) IEEE80211_AID(ni->ni_associd) |
| 253 | |
| 254 | #define IEEE80211_NODE_STAT(ni,stat) (ni->ni_stats.ns_##stat++) |
| 255 | #define IEEE80211_NODE_STAT_ADD(ni,stat,v) (ni->ni_stats.ns_##stat += v) |
| 256 | #define IEEE80211_NODE_STAT_SET(ni,stat,v) (ni->ni_stats.ns_##stat = v) |
| 257 | |
| 258 | /* |
| 259 | * Filtered rssi calculation support. The receive rssi is maintained |
| 260 | * as an average over the last 10 frames received using a low pass filter |
| 261 | * (all frames for now, possibly need to be more selective). Calculations |
| 262 | * are designed such that a good compiler can optimize them. The avg |
| 263 | * rssi state should be initialized to IEEE80211_RSSI_DUMMY_MARKER and |
| 264 | * each sample incorporated with IEEE80211_RSSI_LPF. Use IEEE80211_RSSI_GET |
| 265 | * to extract the current value. |
| 266 | * |
| 267 | * Note that we assume rssi data are in the range [-127..127] and we |
| 268 | * discard values <-20. This is consistent with assumptions throughout |
| 269 | * net80211 that signal strength data are in .5 dBm units relative to |
| 270 | * the current noise floor (linear, not log). |
| 271 | */ |
| 272 | #define IEEE80211_RSSI_LPF_LEN 10 |
| 273 | #define IEEE80211_RSSI_DUMMY_MARKER 127 |
| 274 | /* NB: pow2 to optimize out * and / */ |
| 275 | #define IEEE80211_RSSI_EP_MULTIPLIER (1<<7) |
| 276 | #define IEEE80211_RSSI_IN(x) ((x) * IEEE80211_RSSI_EP_MULTIPLIER) |
| 277 | #define _IEEE80211_RSSI_LPF(x, y, len) \ |
| 278 | (((x) != IEEE80211_RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y)) |
| 279 | #define IEEE80211_RSSI_LPF(x, y) do { \ |
| 280 | if ((y) >= -20) { \ |
| 281 | x = _IEEE80211_RSSI_LPF((x), IEEE80211_RSSI_IN((y)), \ |
| 282 | IEEE80211_RSSI_LPF_LEN); \ |
| 283 | } \ |
| 284 | } while (0) |
| 285 | #define IEEE80211_RSSI_EP_RND(x, mul) \ |
| 286 | ((((x) % (mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) |
| 287 | #define IEEE80211_RSSI_GET(x) \ |
| 288 | IEEE80211_RSSI_EP_RND(x, IEEE80211_RSSI_EP_MULTIPLIER) |
| 289 | |
| 290 | static __inline struct ieee80211_node * |
| 291 | ieee80211_ref_node(struct ieee80211_node *ni) |
| 292 | { |
| 293 | ieee80211_node_incref(ni); |
| 294 | return ni; |
| 295 | } |
| 296 | |
| 297 | static __inline void |
| 298 | ieee80211_unref_node(struct ieee80211_node **ni) |
| 299 | { |
| 300 | ieee80211_node_decref(*ni); |
| 301 | *ni = NULL; /* guard against use */ |
| 302 | } |
| 303 | |
| 304 | void ieee80211_node_attach(struct ieee80211com *); |
| 305 | void ieee80211_node_lateattach(struct ieee80211com *); |
| 306 | void ieee80211_node_detach(struct ieee80211com *); |
| 307 | void ieee80211_node_vattach(struct ieee80211vap *); |
| 308 | void ieee80211_node_latevattach(struct ieee80211vap *); |
| 309 | void ieee80211_node_vdetach(struct ieee80211vap *); |
| 310 | |
| 311 | static __inline int |
| 312 | ieee80211_node_is_authorized(const struct ieee80211_node *ni) |
| 313 | { |
| 314 | return (ni->ni_flags & IEEE80211_NODE_AUTH); |
| 315 | } |
| 316 | |
| 317 | void ieee80211_node_authorize(struct ieee80211_node *); |
| 318 | void ieee80211_node_unauthorize(struct ieee80211_node *); |
| 319 | |
| 320 | void ieee80211_node_setuptxparms(struct ieee80211_node *); |
| 321 | void ieee80211_node_set_chan(struct ieee80211_node *, |
| 322 | struct ieee80211_channel *); |
| 323 | void ieee80211_create_ibss(struct ieee80211vap*, struct ieee80211_channel *); |
| 324 | void ieee80211_reset_bss(struct ieee80211vap *); |
| 325 | void ieee80211_sync_curchan(struct ieee80211com *); |
| 326 | void ieee80211_setupcurchan(struct ieee80211com *, |
| 327 | struct ieee80211_channel *); |
| 328 | void ieee80211_setcurchan(struct ieee80211com *, struct ieee80211_channel *); |
| 329 | void ieee80211_update_chw(struct ieee80211com *); |
| 330 | int ieee80211_ibss_merge(struct ieee80211_node *); |
| 331 | struct ieee80211_scan_entry; |
| 332 | int ieee80211_sta_join(struct ieee80211vap *, struct ieee80211_channel *, |
| 333 | const struct ieee80211_scan_entry *); |
| 334 | void ieee80211_sta_leave(struct ieee80211_node *); |
| 335 | void ieee80211_node_deauth(struct ieee80211_node *, int); |
| 336 | |
| 337 | int ieee80211_ies_init(struct ieee80211_ies *, const uint8_t *, int); |
| 338 | void ieee80211_ies_cleanup(struct ieee80211_ies *); |
| 339 | void ieee80211_ies_expand(struct ieee80211_ies *); |
| 340 | #define ieee80211_ies_setie(_ies, _ie, _off) do { \ |
| 341 | (_ies)._ie = (_ies).data + (_off); \ |
| 342 | } while (0) |
| 343 | |
| 344 | /* |
| 345 | * Table of ieee80211_node instances. Each ieee80211com |
| 346 | * has one that holds association stations (when operating |
| 347 | * as an ap) or neighbors (in ibss mode). |
| 348 | * |
| 349 | * XXX embed this in ieee80211com instead of indirect? |
| 350 | */ |
| 351 | struct ieee80211_node_table { |
| 352 | struct ieee80211com *nt_ic; /* back reference */ |
| 353 | ieee80211_node_lock_t nt_nodelock; /* on node table */ |
| 354 | TAILQ_HEAD(, ieee80211_node) nt_node; /* information of all nodes */ |
| 355 | LIST_HEAD(, ieee80211_node) nt_hash[IEEE80211_NODE_HASHSIZE]; |
| 356 | struct ieee80211_node **nt_keyixmap; /* key ix -> node map */ |
| 357 | int nt_keyixmax; /* keyixmap size */ |
| 358 | const char *nt_name; /* table name for debug msgs */ |
| 359 | ieee80211_scan_lock_t nt_scanlock; /* on nt_scangen */ |
| 360 | u_int nt_scangen; /* gen# for iterators */ |
| 361 | int nt_inact_init; /* initial node inact setting */ |
| 362 | }; |
| 363 | |
| 364 | struct ieee80211_node *ieee80211_alloc_node(struct ieee80211_node_table *, |
| 365 | struct ieee80211vap *, |
| 366 | const uint8_t macaddr[IEEE80211_ADDR_LEN]); |
| 367 | struct ieee80211_node *ieee80211_tmp_node(struct ieee80211vap *, |
| 368 | const uint8_t macaddr[IEEE80211_ADDR_LEN]); |
| 369 | struct ieee80211_node *ieee80211_dup_bss(struct ieee80211vap *, |
| 370 | const uint8_t macaddr[IEEE80211_ADDR_LEN]); |
| 371 | struct ieee80211_node *ieee80211_node_create_wds(struct ieee80211vap *, |
| 372 | const uint8_t bssid[IEEE80211_ADDR_LEN], |
| 373 | struct ieee80211_channel *); |
| 374 | #ifdef IEEE80211_DEBUG_REFCNT |
| 375 | void ieee80211_free_node_debug(struct ieee80211_node *, |
| 376 | const char *func, int line); |
| 377 | struct ieee80211_node *ieee80211_find_node_locked_debug( |
| 378 | struct ieee80211_node_table *, |
| 379 | const uint8_t macaddr[IEEE80211_ADDR_LEN], |
| 380 | const char *func, int line); |
| 381 | struct ieee80211_node *ieee80211_find_node_debug(struct ieee80211_node_table *, |
| 382 | const uint8_t macaddr[IEEE80211_ADDR_LEN], |
| 383 | const char *func, int line); |
| 384 | struct ieee80211_node *ieee80211_find_vap_node_locked_debug( |
| 385 | struct ieee80211_node_table *, |
| 386 | const struct ieee80211vap *vap, |
| 387 | const uint8_t macaddr[IEEE80211_ADDR_LEN], |
| 388 | const char *func, int line); |
| 389 | struct ieee80211_node *ieee80211_find_vap_node_debug( |
| 390 | struct ieee80211_node_table *, |
| 391 | const struct ieee80211vap *vap, |
| 392 | const uint8_t macaddr[IEEE80211_ADDR_LEN], |
| 393 | const char *func, int line); |
| 394 | struct ieee80211_node * ieee80211_find_rxnode_debug(struct ieee80211com *, |
| 395 | const struct ieee80211_frame_min *, |
| 396 | const char *func, int line); |
| 397 | struct ieee80211_node * ieee80211_find_rxnode_withkey_debug( |
| 398 | struct ieee80211com *, |
| 399 | const struct ieee80211_frame_min *, uint16_t keyix, |
| 400 | const char *func, int line); |
| 401 | struct ieee80211_node *ieee80211_find_txnode_debug(struct ieee80211vap *, |
| 402 | const uint8_t *, |
| 403 | const char *func, int line); |
| 404 | #define ieee80211_free_node(ni) \ |
| 405 | ieee80211_free_node_debug(ni, __func__, __LINE__) |
| 406 | #define ieee80211_find_node_locked(nt, mac) \ |
| 407 | ieee80211_find_node_locked_debug(nt, mac, __func__, __LINE__) |
| 408 | #define ieee80211_find_node(nt, mac) \ |
| 409 | ieee80211_find_node_debug(nt, mac, __func__, __LINE__) |
| 410 | #define ieee80211_find_vap_node_locked(nt, vap, mac) \ |
| 411 | ieee80211_find_vap_node_locked_debug(nt, vap, mac, __func__, __LINE__) |
| 412 | #define ieee80211_find_vap_node(nt, vap, mac) \ |
| 413 | ieee80211_find_vap_node_debug(nt, vap, mac, __func__, __LINE__) |
| 414 | #define ieee80211_find_rxnode(ic, wh) \ |
| 415 | ieee80211_find_rxnode_debug(ic, wh, __func__, __LINE__) |
| 416 | #define ieee80211_find_rxnode_withkey(ic, wh, keyix) \ |
| 417 | ieee80211_find_rxnode_withkey_debug(ic, wh, keyix, __func__, __LINE__) |
| 418 | #define ieee80211_find_txnode(vap, mac) \ |
| 419 | ieee80211_find_txnode_debug(vap, mac, __func__, __LINE__) |
| 420 | #else |
| 421 | void ieee80211_free_node(struct ieee80211_node *); |
| 422 | struct ieee80211_node *ieee80211_find_node_locked(struct ieee80211_node_table *, |
| 423 | const uint8_t macaddr[IEEE80211_ADDR_LEN]); |
| 424 | struct ieee80211_node *ieee80211_find_node(struct ieee80211_node_table *, |
| 425 | const uint8_t macaddr[IEEE80211_ADDR_LEN]); |
| 426 | struct ieee80211_node *ieee80211_find_vap_node_locked( |
| 427 | struct ieee80211_node_table *, const struct ieee80211vap *, |
| 428 | const uint8_t macaddr[IEEE80211_ADDR_LEN]); |
| 429 | struct ieee80211_node *ieee80211_find_vap_node( |
| 430 | struct ieee80211_node_table *, const struct ieee80211vap *, |
| 431 | const uint8_t macaddr[IEEE80211_ADDR_LEN]); |
| 432 | struct ieee80211_node * ieee80211_find_rxnode(struct ieee80211com *, |
| 433 | const struct ieee80211_frame_min *); |
| 434 | struct ieee80211_node * ieee80211_find_rxnode_withkey(struct ieee80211com *, |
| 435 | const struct ieee80211_frame_min *, uint16_t keyix); |
| 436 | struct ieee80211_node *ieee80211_find_txnode(struct ieee80211vap *, |
| 437 | const uint8_t macaddr[IEEE80211_ADDR_LEN]); |
| 438 | #endif |
| 439 | int ieee80211_node_delucastkey(struct ieee80211_node *); |
| 440 | void ieee80211_node_timeout(void *arg); |
| 441 | |
| 442 | typedef void ieee80211_iter_func(void *, struct ieee80211_node *); |
| 443 | int ieee80211_iterate_nt(struct ieee80211_node_table *, |
| 444 | struct ieee80211_node **, uint16_t); |
| 445 | void ieee80211_iterate_nodes(struct ieee80211_node_table *, |
| 446 | ieee80211_iter_func *, void *); |
| 447 | |
| 448 | void ieee80211_notify_erp(struct ieee80211com *); |
| 449 | void ieee80211_dump_node(struct ieee80211_node_table *, |
| 450 | struct ieee80211_node *); |
| 451 | void ieee80211_dump_nodes(struct ieee80211_node_table *); |
| 452 | |
| 453 | struct ieee80211_node *ieee80211_fakeup_adhoc_node(struct ieee80211vap *, |
| 454 | const uint8_t macaddr[IEEE80211_ADDR_LEN]); |
| 455 | struct ieee80211_scanparams; |
| 456 | void ieee80211_init_neighbor(struct ieee80211_node *, |
| 457 | const struct ieee80211_frame *, |
| 458 | const struct ieee80211_scanparams *); |
| 459 | struct ieee80211_node *ieee80211_add_neighbor(struct ieee80211vap *, |
| 460 | const struct ieee80211_frame *, |
| 461 | const struct ieee80211_scanparams *); |
| 462 | void ieee80211_node_join(struct ieee80211_node *,int); |
| 463 | void ieee80211_node_leave(struct ieee80211_node *); |
| 464 | int8_t ieee80211_getrssi(struct ieee80211vap *); |
| 465 | void ieee80211_getsignal(struct ieee80211vap *, int8_t *, int8_t *); |
| 466 | #endif /* _NET80211_IEEE80211_NODE_H_ */ |