Line data Source code
1 : /* $OpenBSD: ieee80211_node.h,v 1.77 2018/08/13 15:19:52 stsp Exp $ */
2 : /* $NetBSD: ieee80211_node.h,v 1.9 2004/04/30 22:57:32 dyoung Exp $ */
3 :
4 : /*-
5 : * Copyright (c) 2001 Atsushi Onoe
6 : * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
7 : * All rights reserved.
8 : *
9 : * Redistribution and use in source and binary forms, with or without
10 : * modification, are permitted provided that the following conditions
11 : * are met:
12 : * 1. Redistributions of source code must retain the above copyright
13 : * notice, this list of conditions and the following disclaimer.
14 : * 2. Redistributions in binary form must reproduce the above copyright
15 : * notice, this list of conditions and the following disclaimer in the
16 : * documentation and/or other materials provided with the distribution.
17 : * 3. The name of the author may not be used to endorse or promote products
18 : * derived from this software without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 : *
31 : * $FreeBSD: src/sys/net80211/ieee80211_node.h,v 1.10 2004/04/05 22:10:26 sam Exp $
32 : */
33 : #ifndef _NET80211_IEEE80211_NODE_H_
34 : #define _NET80211_IEEE80211_NODE_H_
35 :
36 : #include <sys/tree.h>
37 :
38 : #define IEEE80211_PSCAN_WAIT 5 /* passive scan wait */
39 : #define IEEE80211_TRANS_WAIT 5 /* transition wait */
40 : #define IEEE80211_INACT_WAIT 5 /* inactivity timer interval */
41 : #define IEEE80211_INACT_MAX (300/IEEE80211_INACT_WAIT)
42 : #define IEEE80211_CACHE_SIZE 100
43 : #define IEEE80211_CACHE_WAIT 30
44 :
45 : struct ieee80211_rateset {
46 : u_int8_t rs_nrates;
47 : u_int8_t rs_rates[IEEE80211_RATE_MAXSIZE];
48 : };
49 :
50 : extern const struct ieee80211_rateset ieee80211_std_rateset_11a;
51 : extern const struct ieee80211_rateset ieee80211_std_rateset_11b;
52 : extern const struct ieee80211_rateset ieee80211_std_rateset_11g;
53 :
54 : enum ieee80211_node_state {
55 : IEEE80211_STA_CACHE, /* cached node */
56 : IEEE80211_STA_BSS, /* ic->ic_bss, the network we joined */
57 : IEEE80211_STA_AUTH, /* successfully authenticated */
58 : IEEE80211_STA_ASSOC, /* successfully associated */
59 : IEEE80211_STA_COLLECT /* This node remains in the cache while
60 : * the driver sends a de-auth message;
61 : * afterward it should be freed to make room
62 : * for a new node.
63 : */
64 : };
65 :
66 : #define ieee80211_node_newstate(__ni, __state) \
67 : do { \
68 : (__ni)->ni_state = (__state); \
69 : } while (0)
70 :
71 : enum ieee80211_node_psstate {
72 : IEEE80211_PS_AWAKE,
73 : IEEE80211_PS_DOZE
74 : };
75 :
76 : #define IEEE80211_PS_MAX_QUEUE 50 /* maximum saved packets */
77 :
78 : /* Authenticator state machine: 4-Way Handshake (see 8.5.6.1.1) */
79 : enum {
80 : RSNA_INITIALIZE,
81 : RSNA_AUTHENTICATION,
82 : RSNA_AUTHENTICATION_2,
83 : RSNA_INITPMK,
84 : RSNA_INITPSK,
85 : RSNA_PTKSTART,
86 : RSNA_PTKCALCNEGOTIATING,
87 : RSNA_PTKCALCNEGOTIATING_2,
88 : RSNA_PTKINITNEGOTIATING,
89 : RSNA_PTKINITDONE,
90 : RSNA_DISCONNECT,
91 : RSNA_DISCONNECTED
92 : };
93 :
94 : /* Authenticator state machine: Group Key Handshake (see 8.5.6.1.2) */
95 : enum {
96 : RSNA_IDLE,
97 : RSNA_REKEYNEGOTIATING,
98 : RSNA_REKEYESTABLISHED,
99 : RSNA_KEYERROR
100 : };
101 :
102 : /* Supplicant state machine: 4-Way Handshake (not documented in standard) */
103 : enum {
104 : RSNA_SUPP_INITIALIZE, /* not expecting any messages */
105 : RSNA_SUPP_PTKSTART, /* awaiting handshake message 1 */
106 : RSNA_SUPP_PTKNEGOTIATING, /* got message 1 and derived PTK */
107 : RNSA_SUPP_PTKDONE /* got message 3 and authenticated AP */
108 : };
109 :
110 : struct ieee80211_rxinfo {
111 : u_int32_t rxi_flags;
112 : u_int32_t rxi_tstamp;
113 : int rxi_rssi;
114 : };
115 : #define IEEE80211_RXI_HWDEC 0x00000001
116 : #define IEEE80211_RXI_AMPDU_DONE 0x00000002
117 :
118 : /* Block Acknowledgement Record */
119 : struct ieee80211_tx_ba {
120 : struct ieee80211_node *ba_ni; /* backpointer for callbacks */
121 : struct timeout ba_to;
122 : int ba_timeout_val;
123 : int ba_state;
124 : #define IEEE80211_BA_INIT 0
125 : #define IEEE80211_BA_REQUESTED 1
126 : #define IEEE80211_BA_AGREED 2
127 :
128 : /* ADDBA parameter set field for this BA agreement. */
129 : u_int16_t ba_params;
130 :
131 : /* These values are IEEE802.11 frame sequence numbers (0x0-0xfff) */
132 : u_int16_t ba_winstart;
133 : u_int16_t ba_winend;
134 :
135 : /* Number of A-MPDU subframes in reorder buffer. */
136 : u_int16_t ba_winsize;
137 : #define IEEE80211_BA_MAX_WINSZ 64 /* corresponds to maximum ADDBA BUFSZ */
138 :
139 : u_int8_t ba_token;
140 : };
141 :
142 : struct ieee80211_rx_ba {
143 : struct ieee80211_node *ba_ni; /* backpointer for callbacks */
144 : struct {
145 : struct mbuf *m;
146 : struct ieee80211_rxinfo rxi;
147 : } *ba_buf;
148 : struct timeout ba_to;
149 : int ba_timeout_val;
150 : int ba_state;
151 : u_int16_t ba_params;
152 : u_int16_t ba_winstart;
153 : u_int16_t ba_winend;
154 : u_int16_t ba_winsize;
155 : u_int16_t ba_head;
156 : struct timeout ba_gap_to;
157 : #define IEEE80211_BA_GAP_TIMEOUT 300 /* msec */
158 : /* Counter for consecutive frames which missed the BA window. */
159 : int ba_winmiss;
160 : /* Sequence number of previous frame which missed the BA window. */
161 : uint16_t ba_missedsn;
162 : /* Window moves forward after this many frames have missed it. */
163 : #define IEEE80211_BA_MAX_WINMISS 8
164 :
165 : uint8_t ba_token;
166 : };
167 :
168 : /*
169 : * Node specific information. Note that drivers are expected
170 : * to derive from this structure to add device-specific per-node
171 : * state. This is done by overriding the ic_node_* methods in
172 : * the ieee80211com structure.
173 : */
174 : struct ieee80211_node {
175 : RBT_ENTRY(ieee80211_node) ni_node;
176 :
177 : struct ieee80211com *ni_ic; /* back-pointer */
178 :
179 : u_int ni_refcnt;
180 : u_int ni_scangen; /* gen# for timeout scan */
181 :
182 : /* hardware */
183 : u_int32_t ni_rstamp; /* recv timestamp */
184 : u_int8_t ni_rssi; /* recv ssi */
185 :
186 : /* header */
187 : u_int8_t ni_macaddr[IEEE80211_ADDR_LEN];
188 : u_int8_t ni_bssid[IEEE80211_ADDR_LEN];
189 :
190 : /* beacon, probe response */
191 : u_int8_t ni_tstamp[8]; /* from last rcv'd beacon */
192 : u_int16_t ni_intval; /* beacon interval */
193 : u_int16_t ni_capinfo; /* capabilities */
194 : u_int8_t ni_esslen;
195 : u_int8_t ni_essid[IEEE80211_NWID_LEN];
196 : struct ieee80211_rateset ni_rates; /* negotiated rate set */
197 : u_int8_t *ni_country; /* country information XXX */
198 : struct ieee80211_channel *ni_chan;
199 : u_int8_t ni_erp; /* 11g only */
200 :
201 : /* DTIM and contention free period (CFP) */
202 : u_int8_t ni_dtimcount;
203 : u_int8_t ni_dtimperiod;
204 : #ifdef notyet
205 : u_int8_t ni_cfpperiod; /* # of DTIMs between CFPs */
206 : u_int16_t ni_cfpduremain; /* remaining cfp duration */
207 : u_int16_t ni_cfpmaxduration;/* max CFP duration in TU */
208 : u_int16_t ni_nextdtim; /* time to next DTIM */
209 : u_int16_t ni_timoffset;
210 : #endif
211 :
212 : /* power saving mode */
213 : u_int8_t ni_pwrsave;
214 : struct mbuf_queue ni_savedq; /* packets queued for pspoll */
215 :
216 : /* RSN */
217 : struct timeout ni_eapol_to;
218 : u_int ni_rsn_state;
219 : u_int ni_rsn_supp_state;
220 : u_int ni_rsn_gstate;
221 : u_int ni_rsn_retries;
222 : u_int ni_supported_rsnprotos;
223 : u_int ni_rsnprotos;
224 : u_int ni_supported_rsnakms;
225 : u_int ni_rsnakms;
226 : u_int ni_rsnciphers;
227 : enum ieee80211_cipher ni_rsngroupcipher;
228 : enum ieee80211_cipher ni_rsngroupmgmtcipher;
229 : u_int16_t ni_rsncaps;
230 : enum ieee80211_cipher ni_rsncipher;
231 : u_int8_t ni_nonce[EAPOL_KEY_NONCE_LEN];
232 : u_int8_t ni_pmk[IEEE80211_PMK_LEN];
233 : u_int8_t ni_pmkid[IEEE80211_PMKID_LEN];
234 : u_int64_t ni_replaycnt;
235 : u_int8_t ni_replaycnt_ok;
236 : u_int64_t ni_reqreplaycnt;
237 : u_int8_t ni_reqreplaycnt_ok;
238 : u_int8_t *ni_rsnie;
239 : struct ieee80211_key ni_pairwise_key;
240 : struct ieee80211_ptk ni_ptk;
241 : u_int8_t ni_key_count;
242 : int ni_port_valid;
243 :
244 : /* SA Query */
245 : u_int16_t ni_sa_query_trid;
246 : struct timeout ni_sa_query_to;
247 : int ni_sa_query_count;
248 :
249 : /* HT capabilities */
250 : uint16_t ni_htcaps;
251 : uint8_t ni_ampdu_param;
252 : uint8_t ni_rxmcs[howmany(80,NBBY)];
253 : uint16_t ni_max_rxrate; /* in Mb/s, 0 <= rate <= 1023 */
254 : uint8_t ni_tx_mcs_set;
255 : uint16_t ni_htxcaps;
256 : uint32_t ni_txbfcaps;
257 : uint8_t ni_aselcaps;
258 :
259 : /* HT operation */
260 : uint8_t ni_primary_chan; /* XXX corresponds to ni_chan */
261 : uint8_t ni_htop0;
262 : uint16_t ni_htop1;
263 : uint16_t ni_htop2;
264 : uint8_t ni_basic_mcs[howmany(128,NBBY)];
265 :
266 : /* Block Ack records */
267 : struct ieee80211_tx_ba ni_tx_ba[IEEE80211_NUM_TID];
268 : struct ieee80211_rx_ba ni_rx_ba[IEEE80211_NUM_TID];
269 :
270 : int ni_txmcs; /* current MCS used for TX */
271 :
272 : /* others */
273 : u_int16_t ni_associd; /* assoc response */
274 : u_int16_t ni_txseq; /* seq to be transmitted */
275 : u_int16_t ni_rxseq; /* seq previous received */
276 : u_int16_t ni_qos_txseqs[IEEE80211_NUM_TID];
277 : u_int16_t ni_qos_rxseqs[IEEE80211_NUM_TID];
278 : int ni_fails; /* failure count to associate */
279 : int ni_inact; /* inactivity mark count */
280 : int ni_txrate; /* index to ni_rates[] */
281 : int ni_state;
282 :
283 : u_int16_t ni_flags; /* special-purpose state */
284 : #define IEEE80211_NODE_ERP 0x0001
285 : #define IEEE80211_NODE_QOS 0x0002
286 : #define IEEE80211_NODE_REKEY 0x0004 /* GTK rekeying in progress */
287 : #define IEEE80211_NODE_RXPROT 0x0008 /* RX protection ON */
288 : #define IEEE80211_NODE_TXPROT 0x0010 /* TX protection ON */
289 : #define IEEE80211_NODE_TXRXPROT \
290 : (IEEE80211_NODE_TXPROT | IEEE80211_NODE_RXPROT)
291 : #define IEEE80211_NODE_RXMGMTPROT 0x0020 /* RX MMPDU protection ON */
292 : #define IEEE80211_NODE_TXMGMTPROT 0x0040 /* TX MMPDU protection ON */
293 : #define IEEE80211_NODE_MFP 0x0080 /* MFP negotiated */
294 : #define IEEE80211_NODE_PMK 0x0100 /* ni_pmk set */
295 : #define IEEE80211_NODE_PMKID 0x0200 /* ni_pmkid set */
296 : #define IEEE80211_NODE_HT 0x0400 /* HT negotiated */
297 : #define IEEE80211_NODE_SA_QUERY 0x0800 /* SA Query in progress */
298 : #define IEEE80211_NODE_SA_QUERY_FAILED 0x1000 /* last SA Query failed */
299 : #define IEEE80211_NODE_RSN_NEW_PTK 0x2000 /* expecting a new PTK */
300 :
301 : /* If not NULL, this function gets called when ni_refcnt hits zero. */
302 : void (*ni_unref_cb)(struct ieee80211com *,
303 : struct ieee80211_node *);
304 : void * ni_unref_arg;
305 : size_t ni_unref_arg_size;
306 : };
307 :
308 : RBT_HEAD(ieee80211_tree, ieee80211_node);
309 :
310 : struct ieee80211_ess_rbt {
311 : RBT_ENTRY(ieee80211_ess_rbt) ess_rbt;
312 : u_int8_t esslen;
313 : u_int8_t essid[IEEE80211_NWID_LEN];
314 : struct ieee80211_node *ni2;
315 : struct ieee80211_node *ni5;
316 : struct ieee80211_node *ni;
317 : };
318 :
319 : RBT_HEAD(ieee80211_ess_tree, ieee80211_ess_rbt);
320 :
321 : static inline void
322 0 : ieee80211_node_incref(struct ieee80211_node *ni)
323 : {
324 : int s;
325 :
326 0 : s = splnet();
327 0 : ni->ni_refcnt++;
328 0 : splx(s);
329 0 : }
330 :
331 : static inline u_int
332 0 : ieee80211_node_decref(struct ieee80211_node *ni)
333 : {
334 : u_int refcnt;
335 : int s;
336 :
337 0 : s = splnet();
338 0 : refcnt = --ni->ni_refcnt;
339 0 : splx(s);
340 0 : return refcnt;
341 : }
342 :
343 : static inline struct ieee80211_node *
344 0 : ieee80211_ref_node(struct ieee80211_node *ni)
345 : {
346 0 : ieee80211_node_incref(ni);
347 0 : return ni;
348 : }
349 :
350 : static inline void
351 0 : ieee80211_unref_node(struct ieee80211_node **ni)
352 : {
353 0 : ieee80211_node_decref(*ni);
354 0 : *ni = NULL; /* guard against use */
355 0 : }
356 :
357 : /*
358 : * Check if the peer supports HT.
359 : * Require at least one of the mandatory MCS.
360 : * MCS 0-7 are mandatory but some APs have particular MCS disabled.
361 : */
362 : static inline int
363 0 : ieee80211_node_supports_ht(struct ieee80211_node *ni)
364 : {
365 0 : return (ni->ni_rxmcs[0] & 0xff);
366 : }
367 :
368 : struct ieee80211com;
369 :
370 : typedef void ieee80211_iter_func(void *, struct ieee80211_node *);
371 :
372 : void ieee80211_node_attach(struct ifnet *);
373 : void ieee80211_node_lateattach(struct ifnet *);
374 : void ieee80211_node_detach(struct ifnet *);
375 :
376 : void ieee80211_begin_scan(struct ifnet *);
377 : void ieee80211_next_scan(struct ifnet *);
378 : void ieee80211_end_scan(struct ifnet *);
379 : void ieee80211_reset_scan(struct ifnet *);
380 : struct ieee80211_node *ieee80211_alloc_node(struct ieee80211com *,
381 : const u_int8_t *);
382 : struct ieee80211_node *ieee80211_dup_bss(struct ieee80211com *,
383 : const u_int8_t *);
384 : struct ieee80211_node *ieee80211_find_node(struct ieee80211com *,
385 : const u_int8_t *);
386 : struct ieee80211_node *ieee80211_find_rxnode(struct ieee80211com *,
387 : const struct ieee80211_frame *);
388 : struct ieee80211_node *ieee80211_find_txnode(struct ieee80211com *,
389 : const u_int8_t *);
390 : struct ieee80211_node *
391 : ieee80211_find_node_for_beacon(struct ieee80211com *,
392 : const u_int8_t *, const struct ieee80211_channel *,
393 : const char *, u_int8_t);
394 : void ieee80211_release_node(struct ieee80211com *,
395 : struct ieee80211_node *);
396 : void ieee80211_free_allnodes(struct ieee80211com *, int);
397 : void ieee80211_iterate_nodes(struct ieee80211com *,
398 : ieee80211_iter_func *, void *);
399 : void ieee80211_clean_cached(struct ieee80211com *);
400 : void ieee80211_clean_nodes(struct ieee80211com *, int);
401 : void ieee80211_setup_htcaps(struct ieee80211_node *, const uint8_t *,
402 : uint8_t);
403 : void ieee80211_clear_htcaps(struct ieee80211_node *);
404 : int ieee80211_setup_htop(struct ieee80211_node *, const uint8_t *,
405 : uint8_t, int);
406 : int ieee80211_setup_rates(struct ieee80211com *,
407 : struct ieee80211_node *, const u_int8_t *, const u_int8_t *, int);
408 : int ieee80211_iserp_sta(const struct ieee80211_node *);
409 : void ieee80211_count_longslotsta(void *, struct ieee80211_node *);
410 : void ieee80211_count_nonerpsta(void *, struct ieee80211_node *);
411 : void ieee80211_count_pssta(void *, struct ieee80211_node *);
412 : void ieee80211_count_rekeysta(void *, struct ieee80211_node *);
413 : void ieee80211_node_join(struct ieee80211com *,
414 : struct ieee80211_node *, int);
415 : void ieee80211_node_leave(struct ieee80211com *,
416 : struct ieee80211_node *);
417 : int ieee80211_match_bss(struct ieee80211com *,
418 : struct ieee80211_node *);
419 : struct ieee80211_node *ieee80211_node_choose_bss(struct ieee80211com *, int,
420 : struct ieee80211_node **);
421 : void ieee80211_node_join_bss(struct ieee80211com *, struct ieee80211_node *);
422 : void ieee80211_create_ibss(struct ieee80211com* ,
423 : struct ieee80211_channel *);
424 : void ieee80211_notify_dtim(struct ieee80211com *);
425 : void ieee80211_set_tim(struct ieee80211com *, int, int);
426 :
427 : int ieee80211_node_cmp(const struct ieee80211_node *,
428 : const struct ieee80211_node *);
429 : int ieee80211_ess_cmp(const struct ieee80211_ess_rbt *,
430 : const struct ieee80211_ess_rbt *);
431 0 : RBT_PROTOTYPE(ieee80211_tree, ieee80211_node, ni_node, ieee80211_node_cmp);
432 : RBT_PROTOTYPE(ieee80211_ess_tree, ieee80211_ess_rbt, ess_rbt, ieee80211_ess_cmp);
433 :
434 : #endif /* _NET80211_IEEE80211_NODE_H_ */
|