xref: /titanic_51/usr/src/uts/common/io/net80211/net80211_node.c (revision f34a71784df3fbc5d1227a7b6201fd318ad1667e)
1 /*
2  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Copyright (c) 2001 Atsushi Onoe
8  * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * Alternatively, this software may be distributed under the terms of the
23  * GNU General Public License ("GPL") version 2 as published by the Free
24  * Software Foundation.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 /*
39  * Node management routines
40  */
41 
42 #include "net80211_impl.h"
43 
44 static ieee80211_node_t *ieee80211_node_alloc(ieee80211com_t *);
45 static void ieee80211_node_cleanup(ieee80211_node_t *);
46 static void ieee80211_node_free(ieee80211_node_t *);
47 static uint8_t ieee80211_node_getrssi(const ieee80211_node_t *);
48 static void ieee80211_setup_node(ieee80211com_t *, ieee80211_node_table_t *,
49     ieee80211_node_t *, const uint8_t *);
50 static void ieee80211_node_reclaim(ieee80211_node_table_t *,
51     ieee80211_node_t *);
52 static void ieee80211_free_node_locked(ieee80211_node_t *);
53 static void ieee80211_free_allnodes(ieee80211_node_table_t *);
54 static void ieee80211_node_leave(ieee80211com_t *, ieee80211_node_t *);
55 static void ieee80211_timeout_scan_candidates(ieee80211_node_table_t *);
56 static void ieee80211_timeout_stations(ieee80211_node_table_t *);
57 static void ieee80211_node_table_init(ieee80211com_t *,
58     ieee80211_node_table_t *, const char *, int, int,
59     void (*timeout)(ieee80211_node_table_t *));
60 static void ieee80211_node_table_cleanup(ieee80211_node_table_t *);
61 
62 /*
63  * association failures before ignored
64  * The failure may be caused by the response frame is lost for
65  * environmental reason. So Try associate more than once before
66  * ignore the node
67  */
68 #define	IEEE80211_STA_FAILS_MAX	2
69 
70 /*
71  * Initialize node database management callbacks for the interface.
72  * This function is called by ieee80211_attach(). These callback
73  * functions may be overridden in special circumstances, as long as
74  * as this is done after calling ieee80211_attach() and prior to any
75  * other call which may allocate a node
76  */
77 void
78 ieee80211_node_attach(ieee80211com_t *ic)
79 {
80 	struct ieee80211_impl *im = ic->ic_private;
81 
82 	ic->ic_node_alloc = ieee80211_node_alloc;
83 	ic->ic_node_free = ieee80211_node_free;
84 	ic->ic_node_cleanup = ieee80211_node_cleanup;
85 	ic->ic_node_getrssi = ieee80211_node_getrssi;
86 
87 	/* default station inactivity timer setings */
88 	im->im_inact_init = IEEE80211_INACT_INIT;
89 	im->im_inact_assoc = IEEE80211_INACT_ASSOC;
90 	im->im_inact_run = IEEE80211_INACT_RUN;
91 	im->im_inact_probe = IEEE80211_INACT_PROBE;
92 }
93 
94 /*
95  * Initialize node databases and the ic_bss node element.
96  */
97 void
98 ieee80211_node_lateattach(ieee80211com_t *ic)
99 {
100 	/*
101 	 * Calculate ic_tim_bitmap size in bytes
102 	 * IEEE80211_AID_MAX defines maximum bits in ic_tim_bitmap
103 	 */
104 	ic->ic_tim_len = howmany(IEEE80211_AID_MAX, 8) * sizeof (uint8_t);
105 
106 	ieee80211_node_table_init(ic, &ic->ic_sta, "station",
107 	    IEEE80211_INACT_INIT, IEEE80211_WEP_NKID,
108 	    ieee80211_timeout_stations);
109 	ieee80211_node_table_init(ic, &ic->ic_scan, "scan",
110 	    IEEE80211_INACT_SCAN, 0, ieee80211_timeout_scan_candidates);
111 
112 	ieee80211_reset_bss(ic);
113 }
114 
115 /*
116  * Destroy all node databases and is usually called during device detach
117  */
118 void
119 ieee80211_node_detach(ieee80211com_t *ic)
120 {
121 	/* Node Detach */
122 	if (ic->ic_bss != NULL) {
123 		ieee80211_free_node(ic->ic_bss);
124 		ic->ic_bss = NULL;
125 	}
126 	ieee80211_node_table_cleanup(&ic->ic_scan);
127 	ieee80211_node_table_cleanup(&ic->ic_sta);
128 }
129 
130 /*
131  * Increase a node's reference count
132  *
133  * Return pointer to the node
134  */
135 ieee80211_node_t *
136 ieee80211_ref_node(ieee80211_node_t *in)
137 {
138 	ieee80211_node_incref(in);
139 	return (in);
140 }
141 
142 /*
143  * Dexrease a node's reference count
144  */
145 void
146 ieee80211_unref_node(ieee80211_node_t **in)
147 {
148 	ieee80211_node_decref(*in);
149 	*in = NULL;			/* guard against use */
150 }
151 
152 /*
153  * Mark ports authorized for data traffic. This function is usually
154  * used by 802.1x authenticator.
155  */
156 void
157 ieee80211_node_authorize(ieee80211_node_t *in)
158 {
159 	ieee80211_impl_t *im = in->in_ic->ic_private;
160 
161 	in->in_flags |= IEEE80211_NODE_AUTH;
162 	in->in_inact_reload = im->im_inact_run;
163 	in->in_inact = in->in_inact_reload;
164 }
165 
166 /*
167  * Mark ports unauthorized for data traffic. This function is usually
168  * used by 802.1x authenticator.
169  */
170 void
171 ieee80211_node_unauthorize(ieee80211_node_t *in)
172 {
173 	in->in_flags &= ~IEEE80211_NODE_AUTH;
174 }
175 
176 /*
177  * Set/change the channel.  The rate set is also updated as
178  * to insure a consistent view by drivers.
179  */
180 static void
181 ieee80211_node_setchan(ieee80211com_t *ic, ieee80211_node_t *in,
182     struct ieee80211_channel *chan)
183 {
184 	if (chan == IEEE80211_CHAN_ANYC)
185 		chan = ic->ic_curchan;
186 	in->in_chan = chan;
187 	in->in_rates = ic->ic_sup_rates[ieee80211_chan2mode(ic, chan)];
188 }
189 
190 /*
191  * Initialize the channel set to scan based on the available channels
192  * and the current PHY mode.
193  */
194 static void
195 ieee80211_reset_scan(ieee80211com_t *ic)
196 {
197 	ieee80211_impl_t	*im = ic->ic_private;
198 
199 	if (ic->ic_des_chan != IEEE80211_CHAN_ANYC) {
200 		(void) memset(im->im_chan_scan, 0, sizeof (im->im_chan_scan));
201 		ieee80211_setbit(im->im_chan_scan,
202 		    ieee80211_chan2ieee(ic, ic->ic_des_chan));
203 	} else {
204 		bcopy(ic->ic_chan_active, im->im_chan_scan,
205 		    sizeof (ic->ic_chan_active));
206 	}
207 	ieee80211_dbg(IEEE80211_MSG_SCAN, "ieee80211_reset_scan(): "
208 	    "start chan %u\n", ieee80211_chan2ieee(ic, ic->ic_curchan));
209 }
210 
211 /*
212  * Begin an active scan. Initialize the node cache. The scan
213  * begins on the next radio channel by calling ieee80211_next_scan().
214  * The actual scanning is not automated. The driver itself
215  * only handles setting the radio frequency and stepping through
216  * the channels.
217  */
218 void
219 ieee80211_begin_scan(ieee80211com_t *ic, boolean_t reset)
220 {
221 	IEEE80211_LOCK(ic);
222 
223 	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
224 		ic->ic_flags |= IEEE80211_F_ASCAN;
225 	ieee80211_dbg(IEEE80211_MSG_SCAN,
226 	    "begin %s scan in %s mode on channel %u\n",
227 	    (ic->ic_flags & IEEE80211_F_ASCAN) ?  "active" : "passive",
228 	    ieee80211_phymode_name[ic->ic_curmode],
229 	    ieee80211_chan2ieee(ic, ic->ic_curchan));
230 
231 	/*
232 	 * Clear scan state and flush any previously seen AP's.
233 	 */
234 	ieee80211_reset_scan(ic);
235 	if (reset)
236 		ieee80211_free_allnodes(&ic->ic_scan);
237 
238 	ic->ic_flags |= IEEE80211_F_SCAN;
239 	IEEE80211_UNLOCK(ic);
240 
241 	/* Scan the next channel. */
242 	ieee80211_next_scan(ic);
243 }
244 
245 /*
246  * Switch to the next channel marked for scanning.
247  * A driver is expected to first call ieee80211_begin_scan(),
248  * to initialize the node cache, then set the radio channel
249  * on the device. And then after a certain time has elapsed,
250  * call ieee80211_next_scan() to move to the next channel.
251  * Typically, a timeout routine is used to automate this process.
252  */
253 void
254 ieee80211_next_scan(ieee80211com_t *ic)
255 {
256 	ieee80211_impl_t *im = ic->ic_private;
257 	struct ieee80211_channel *chan;
258 
259 	IEEE80211_LOCK(ic);
260 	/*
261 	 * Insure any previous mgt frame timeouts don't fire.
262 	 * This assumes the driver does the right thing in
263 	 * flushing anything queued in the driver and below.
264 	 */
265 	im->im_mgt_timer = 0;
266 
267 	chan = ic->ic_curchan;
268 	do {
269 		if (++chan > &ic->ic_sup_channels[IEEE80211_CHAN_MAX])
270 			chan = &ic->ic_sup_channels[0];
271 		if (ieee80211_isset(im->im_chan_scan,
272 		    ieee80211_chan2ieee(ic, chan))) {
273 			ieee80211_clrbit(im->im_chan_scan,
274 			    ieee80211_chan2ieee(ic, chan));
275 			ieee80211_dbg(IEEE80211_MSG_SCAN,
276 			    "ieee80211_next_scan: chan %d->%d\n",
277 			    ieee80211_chan2ieee(ic, ic->ic_curchan),
278 			    ieee80211_chan2ieee(ic, chan));
279 			ic->ic_curchan = chan;
280 			/*
281 			 * drivers should do this as needed,
282 			 * for now maintain compatibility
283 			 */
284 			ic->ic_bss->in_rates =
285 			    ic->ic_sup_rates[ieee80211_chan2mode(ic, chan)];
286 			IEEE80211_UNLOCK(ic);
287 			ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
288 			return;
289 		}
290 	} while (chan != ic->ic_curchan);
291 	IEEE80211_UNLOCK(ic);
292 	ieee80211_end_scan(ic);
293 }
294 
295 /*
296  * Copy useful state from node obss into nbss.
297  */
298 static void
299 ieee80211_copy_bss(ieee80211_node_t *nbss, const ieee80211_node_t *obss)
300 {
301 	/* propagate useful state */
302 	nbss->in_authmode = obss->in_authmode;
303 	nbss->in_txpower = obss->in_txpower;
304 	nbss->in_vlan = obss->in_vlan;
305 }
306 
307 /*
308  * Setup the net80211 specific portion of an interface's softc, ic,
309  * for use in IBSS mode
310  */
311 void
312 ieee80211_create_ibss(ieee80211com_t *ic, struct ieee80211_channel *chan)
313 {
314 	ieee80211_impl_t *im = ic->ic_private;
315 	ieee80211_node_table_t *nt;
316 	ieee80211_node_t *in;
317 
318 	IEEE80211_LOCK_ASSERT(ic);
319 	ieee80211_dbg(IEEE80211_MSG_SCAN, "ieee80211_create_ibss: "
320 	    "creating ibss\n");
321 
322 	/*
323 	 * Create the station/neighbor table.  Note that for adhoc
324 	 * mode we make the initial inactivity timer longer since
325 	 * we create nodes only through discovery and they typically
326 	 * are long-lived associations.
327 	 */
328 	nt = &ic->ic_sta;
329 	IEEE80211_NODE_LOCK(nt);
330 	nt->nt_name = "neighbor";
331 	nt->nt_inact_init = im->im_inact_run;
332 	IEEE80211_NODE_UNLOCK(nt);
333 
334 	in = ieee80211_alloc_node(ic, &ic->ic_sta, ic->ic_macaddr);
335 	if (in == NULL) {
336 		ieee80211_err("ieee80211_create_ibss(): alloc node failed\n");
337 		return;
338 	}
339 	IEEE80211_ADDR_COPY(in->in_bssid, ic->ic_macaddr);
340 	in->in_esslen = ic->ic_des_esslen;
341 	(void) memcpy(in->in_essid, ic->ic_des_essid, in->in_esslen);
342 	ieee80211_copy_bss(in, ic->ic_bss);
343 	in->in_intval = ic->ic_bintval;
344 	if (ic->ic_flags & IEEE80211_F_PRIVACY)
345 		in->in_capinfo |= IEEE80211_CAPINFO_PRIVACY;
346 	if (ic->ic_phytype == IEEE80211_T_FH) {
347 		in->in_fhdwell = 200;
348 		in->in_fhindex = 1;
349 	}
350 	switch (ic->ic_opmode) {
351 	case IEEE80211_M_IBSS:
352 		ic->ic_flags |= IEEE80211_F_SIBSS;
353 		in->in_capinfo |= IEEE80211_CAPINFO_IBSS;
354 		if (ic->ic_flags & IEEE80211_F_DESBSSID)
355 			IEEE80211_ADDR_COPY(in->in_bssid, ic->ic_des_bssid);
356 		else
357 			in->in_bssid[0] |= 0x02;	/* local bit for IBSS */
358 		break;
359 	case IEEE80211_M_AHDEMO:
360 		if (ic->ic_flags & IEEE80211_F_DESBSSID)
361 			IEEE80211_ADDR_COPY(in->in_bssid, ic->ic_des_bssid);
362 		else
363 			(void) memset(in->in_bssid, 0, IEEE80211_ADDR_LEN);
364 		break;
365 	default:
366 		ieee80211_err("ieee80211_create_ibss(): "
367 		    "wrong opmode %u to creat IBSS, abort\n",
368 		    ic->ic_opmode);
369 		ieee80211_free_node(in);
370 		return;
371 	}
372 
373 	/*
374 	 * Fix the channel and related attributes.
375 	 */
376 	ieee80211_node_setchan(ic, in, chan);
377 	ic->ic_curchan = chan;
378 	ic->ic_curmode = ieee80211_chan2mode(ic, chan);
379 	/*
380 	 * Do mode-specific rate setup.
381 	 */
382 	ieee80211_setbasicrates(&in->in_rates, ic->ic_curmode);
383 	IEEE80211_UNLOCK(ic);
384 	ieee80211_sta_join(ic, ieee80211_ref_node(in));
385 	IEEE80211_LOCK(ic);
386 }
387 
388 void
389 ieee80211_reset_bss(ieee80211com_t *ic)
390 {
391 	ieee80211_node_t *in;
392 	ieee80211_node_t *obss;
393 
394 	ieee80211_node_table_reset(&ic->ic_sta);
395 	ieee80211_reset_erp(ic);
396 
397 	in = ieee80211_alloc_node(ic, &ic->ic_scan, ic->ic_macaddr);
398 	ASSERT(in != NULL);
399 	obss = ic->ic_bss;
400 	ic->ic_bss = ieee80211_ref_node(in);
401 	if (obss != NULL) {
402 		ieee80211_copy_bss(in, obss);
403 		in->in_intval = ic->ic_bintval;
404 		ieee80211_free_node(obss);
405 	}
406 }
407 
408 static int
409 ieee80211_match_bss(ieee80211com_t *ic, ieee80211_node_t *in)
410 {
411 	uint8_t rate;
412 	int fail;
413 
414 	fail = 0;
415 	if (ieee80211_isclr(ic->ic_chan_active,
416 	    ieee80211_chan2ieee(ic, in->in_chan))) {
417 		fail |= IEEE80211_BADCHAN;
418 	}
419 	if (ic->ic_des_chan != IEEE80211_CHAN_ANYC &&
420 	    in->in_chan != ic->ic_des_chan) {
421 		fail |= IEEE80211_BADCHAN;
422 	}
423 	if (ic->ic_opmode == IEEE80211_M_IBSS) {
424 		if (!(in->in_capinfo & IEEE80211_CAPINFO_IBSS))
425 			fail |= IEEE80211_BADOPMODE;
426 	} else {
427 		if (!(in->in_capinfo & IEEE80211_CAPINFO_ESS))
428 			fail |= IEEE80211_BADOPMODE;
429 	}
430 	if (ic->ic_flags & IEEE80211_F_PRIVACY) {
431 		if (!(in->in_capinfo & IEEE80211_CAPINFO_PRIVACY))
432 			fail |= IEEE80211_BADPRIVACY;
433 	} else {
434 		if (in->in_capinfo & IEEE80211_CAPINFO_PRIVACY)
435 			fail |= IEEE80211_BADPRIVACY;
436 	}
437 	rate = ieee80211_fix_rate(in, IEEE80211_F_DONEGO | IEEE80211_F_DOFRATE);
438 	if (rate & IEEE80211_RATE_BASIC)
439 		fail |= IEEE80211_BADRATE;
440 	if (ic->ic_des_esslen != 0 &&
441 	    (in->in_esslen != ic->ic_des_esslen ||
442 	    memcmp(in->in_essid, ic->ic_des_essid, ic->ic_des_esslen) != 0)) {
443 		fail |= IEEE80211_BADESSID;
444 	}
445 	if ((ic->ic_flags & IEEE80211_F_DESBSSID) &&
446 	    !IEEE80211_ADDR_EQ(ic->ic_des_bssid, in->in_bssid)) {
447 		fail |= IEEE80211_BADBSSID;
448 	}
449 	if (in->in_fails >= IEEE80211_STA_FAILS_MAX)
450 		fail |= IEEE80211_NODEFAIL;
451 
452 	return (fail);
453 }
454 
455 #define	IEEE80211_MAXRATE(_rs) \
456 	((_rs).ir_rates[(_rs).ir_nrates - 1] & IEEE80211_RATE_VAL)
457 
458 /*
459  * Compare the capabilities of node a with node b and decide which is
460  * more desirable (return b if b is considered better than a).  Note
461  * that we assume compatibility/usability has already been checked
462  * so we don't need to (e.g. validate whether privacy is supported).
463  * Used to select the best scan candidate for association in a BSS.
464  *
465  * Return desired node
466  */
467 static ieee80211_node_t *
468 ieee80211_node_compare(ieee80211com_t *ic, ieee80211_node_t *a,
469     ieee80211_node_t *b)
470 {
471 	uint8_t maxa;
472 	uint8_t maxb;
473 	uint8_t rssia;
474 	uint8_t rssib;
475 
476 	/* privacy support preferred */
477 	if ((a->in_capinfo & IEEE80211_CAPINFO_PRIVACY) &&
478 	    !(b->in_capinfo & IEEE80211_CAPINFO_PRIVACY)) {
479 		return (a);
480 	}
481 	if (!(a->in_capinfo & IEEE80211_CAPINFO_PRIVACY) &&
482 	    (b->in_capinfo & IEEE80211_CAPINFO_PRIVACY)) {
483 		return (b);
484 	}
485 
486 	/* compare count of previous failures */
487 	if (b->in_fails != a->in_fails)
488 		return ((a->in_fails > b->in_fails) ? b : a);
489 
490 	rssia = ic->ic_node_getrssi(a);
491 	rssib = ic->ic_node_getrssi(b);
492 	if (ABS(rssib - rssia) < IEEE80211_RSSI_CMP_THRESHOLD) {
493 		/* best/max rate preferred if signal level close enough */
494 		maxa = IEEE80211_MAXRATE(a->in_rates);
495 		maxb = IEEE80211_MAXRATE(b->in_rates);
496 		if (maxa != maxb)
497 			return ((maxb > maxa) ? b : a);
498 		/* for now just prefer 5Ghz band to all other bands */
499 		if (IEEE80211_IS_CHAN_5GHZ(a->in_chan) &&
500 		    !IEEE80211_IS_CHAN_5GHZ(b->in_chan)) {
501 			return (a);
502 		}
503 		if (!IEEE80211_IS_CHAN_5GHZ(a->in_chan) &&
504 		    IEEE80211_IS_CHAN_5GHZ(b->in_chan)) {
505 			return (b);
506 		}
507 	}
508 	/* all things being equal, compare signal level */
509 	return ((rssib > rssia) ? b : a);
510 }
511 
512 /*
513  * Mark an ongoing scan stopped.
514  */
515 void
516 ieee80211_cancel_scan(ieee80211com_t *ic)
517 {
518 	IEEE80211_LOCK(ic);
519 	ieee80211_dbg(IEEE80211_MSG_SCAN, "ieee80211_cancel_scan()"
520 	    "end %s scan\n",
521 	    (ic->ic_flags & IEEE80211_F_ASCAN) ?  "active" : "passive");
522 	ic->ic_flags &= ~(IEEE80211_F_SCAN | IEEE80211_F_ASCAN);
523 	cv_broadcast(&((ieee80211_impl_t *)ic->ic_private)->im_scan_cv);
524 	IEEE80211_UNLOCK(ic);
525 }
526 
527 /*
528  * Complete a scan of potential channels. It is called by
529  * ieee80211_next_scan() when the state machine has performed
530  * a full cycle of scaning on all available radio channels.
531  * ieee80211_end_scan() will inspect the node cache for suitable
532  * APs found during scaning, and associate with one, should
533  * the parameters of the node match those of the configuration
534  * requested from userland.
535  */
536 void
537 ieee80211_end_scan(ieee80211com_t *ic)
538 {
539 	ieee80211_node_table_t *nt = &ic->ic_scan;
540 	ieee80211_node_t *in;
541 	ieee80211_node_t *selbs;
542 
543 	ieee80211_cancel_scan(ic);
544 	/* notify SCAN done */
545 	ieee80211_notify(ic, EVENT_SCAN_RESULTS);
546 	IEEE80211_LOCK(ic);
547 
548 	/*
549 	 * Automatic sequencing; look for a candidate and
550 	 * if found join the network.
551 	 */
552 	/* NB: unlocked read should be ok */
553 	in = list_head(&nt->nt_node);
554 	if (in == NULL && (ic->ic_flags & IEEE80211_F_WPA) == 0) {
555 		ieee80211_dbg(IEEE80211_MSG_SCAN, "ieee80211_end_scan: "
556 		    "no scan candidate\n");
557 	notfound:
558 		if (ic->ic_opmode == IEEE80211_M_IBSS &&
559 		    (ic->ic_flags & IEEE80211_F_IBSSON) &&
560 		    ic->ic_des_esslen != 0) {
561 			ieee80211_create_ibss(ic, ic->ic_ibss_chan);
562 			IEEE80211_UNLOCK(ic);
563 			return;
564 		}
565 
566 		/*
567 		 * Reset the list of channels to scan and start again.
568 		 */
569 		ieee80211_reset_scan(ic);
570 		ic->ic_flags |= IEEE80211_F_SCAN | IEEE80211_F_ASCAN;
571 		IEEE80211_UNLOCK(ic);
572 
573 		ieee80211_next_scan(ic);
574 		return;
575 	}
576 
577 	if (ic->ic_flags & IEEE80211_F_SCANONLY ||
578 	    ic->ic_flags & IEEE80211_F_WPA) {	/* scan only */
579 		ic->ic_flags &= ~IEEE80211_F_SCANONLY;
580 		IEEE80211_UNLOCK(ic);
581 		ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
582 		return;
583 	}
584 
585 	selbs = NULL;
586 	IEEE80211_NODE_LOCK(nt);
587 	while (in != NULL) {
588 		if (in->in_fails >= IEEE80211_STA_FAILS_MAX) {
589 			ieee80211_node_t *tmpin = in;
590 
591 			/*
592 			 * The configuration of the access points may change
593 			 * during my scan.  So delete the entry for the AP
594 			 * and retry to associate if there is another beacon.
595 			 */
596 			in = list_next(&nt->nt_node, tmpin);
597 			ieee80211_node_reclaim(nt, tmpin);
598 			continue;
599 		}
600 		/*
601 		 * It's possible at some special moments, the in_chan will
602 		 * be none. Need to skip the null node.
603 		 */
604 		if (in->in_chan == IEEE80211_CHAN_ANYC) {
605 			in = list_next(&nt->nt_node, in);
606 			continue;
607 		}
608 		if (ieee80211_match_bss(ic, in) == 0) {
609 			if (selbs == NULL)
610 				selbs = in;
611 			else
612 				selbs = ieee80211_node_compare(ic, selbs, in);
613 		}
614 		in = list_next(&nt->nt_node, in);
615 	}
616 	if (selbs != NULL)	/* grab ref while dropping lock */
617 		(void) ieee80211_ref_node(selbs);
618 	IEEE80211_NODE_UNLOCK(nt);
619 	if (selbs == NULL)
620 		goto notfound;
621 	IEEE80211_UNLOCK(ic);
622 	ieee80211_sta_join(ic, selbs);
623 }
624 
625 
626 /*
627  * Handle 802.11 ad hoc network merge.  The convention, set by the
628  * Wireless Ethernet Compatibility Alliance (WECA), is that an 802.11
629  * station will change its BSSID to match the "oldest" 802.11 ad hoc
630  * network, on the same channel, that has the station's desired SSID.
631  * The "oldest" 802.11 network sends beacons with the greatest TSF
632  * timestamp.
633  * The caller is assumed to validate TSF's before attempting a merge.
634  *
635  * Return B_TRUE if the BSSID changed, B_FALSE otherwise.
636  */
637 boolean_t
638 ieee80211_ibss_merge(ieee80211_node_t *in)
639 {
640 	ieee80211com_t *ic = in->in_ic;
641 
642 	if (in == ic->ic_bss ||
643 	    IEEE80211_ADDR_EQ(in->in_bssid, ic->ic_bss->in_bssid)) {
644 		/* unchanged, nothing to do */
645 		return (B_FALSE);
646 	}
647 	if (ieee80211_match_bss(ic, in) != 0) {	/* capabilities mismatch */
648 		ieee80211_dbg(IEEE80211_MSG_ASSOC, "ieee80211_ibss_merge: "
649 		    " merge failed, capabilities mismatch\n");
650 		return (B_FALSE);
651 	}
652 	ieee80211_dbg(IEEE80211_MSG_ASSOC, "ieee80211_ibss_merge: "
653 	    "new bssid %s: %s preamble, %s slot time%s\n",
654 	    ieee80211_macaddr_sprintf(in->in_bssid),
655 	    (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? "short" : "long",
656 	    (ic->ic_flags & IEEE80211_F_SHSLOT) ? "short" : "long",
657 	    (ic->ic_flags&IEEE80211_F_USEPROT) ? ", protection" : "");
658 	ieee80211_sta_join(ic, ieee80211_ref_node(in));
659 	return (B_TRUE);
660 }
661 
662 /*
663  * Join the specified IBSS/BSS network.  The node is assumed to
664  * be passed in with a held reference.
665  */
666 void
667 ieee80211_sta_join(ieee80211com_t *ic, ieee80211_node_t *selbs)
668 {
669 	ieee80211_impl_t *im = ic->ic_private;
670 	ieee80211_node_t *obss;
671 
672 	IEEE80211_LOCK(ic);
673 	if (ic->ic_opmode == IEEE80211_M_IBSS) {
674 		ieee80211_node_table_t *nt;
675 
676 		/*
677 		 * Delete unusable rates; we've already checked
678 		 * that the negotiated rate set is acceptable.
679 		 */
680 		(void) ieee80211_fix_rate(selbs, IEEE80211_F_DODEL);
681 		/*
682 		 * Fillin the neighbor table
683 		 */
684 		nt = &ic->ic_sta;
685 		IEEE80211_NODE_LOCK(nt);
686 		nt->nt_name = "neighbor";
687 		nt->nt_inact_init = im->im_inact_run;
688 		IEEE80211_NODE_UNLOCK(nt);
689 	}
690 
691 	/*
692 	 * Committed to selbs, setup state.
693 	 */
694 	obss = ic->ic_bss;
695 	ic->ic_bss = selbs;	/* caller assumed to bump refcnt */
696 	if (obss != NULL) {
697 		ieee80211_copy_bss(selbs, obss);
698 		ieee80211_free_node(obss);
699 	}
700 	ic->ic_curmode = ieee80211_chan2mode(ic, selbs->in_chan);
701 	ic->ic_curchan = selbs->in_chan;
702 	ic->ic_phytype = selbs->in_phytype;
703 	/*
704 	 * Set the erp state (mostly the slot time) to deal with
705 	 * the auto-select case; this should be redundant if the
706 	 * mode is locked.
707 	 */
708 	ieee80211_reset_erp(ic);
709 
710 	IEEE80211_UNLOCK(ic);
711 	if (ic->ic_opmode == IEEE80211_M_STA)
712 		ieee80211_new_state(ic, IEEE80211_S_AUTH, -1);
713 	else
714 		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
715 }
716 
717 /*
718  * Leave the specified IBSS/BSS network.  The node is assumed to
719  * be passed in with a held reference.
720  */
721 void
722 ieee80211_sta_leave(ieee80211com_t *ic, ieee80211_node_t *in)
723 {
724 	IEEE80211_LOCK(ic);
725 	ic->ic_node_cleanup(in);
726 	ieee80211_notify_node_leave(ic, in);
727 	IEEE80211_UNLOCK(ic);
728 }
729 
730 /*
731  * Allocate a node. This is the default callback function for
732  * ic_node_alloc. This function may be overridden by the driver
733  * to allocate device specific node structure.
734  */
735 /* ARGSUSED */
736 static ieee80211_node_t *
737 ieee80211_node_alloc(ieee80211com_t *ic)
738 {
739 	return (kmem_zalloc(sizeof (ieee80211_node_t), KM_SLEEP));
740 }
741 
742 /*
743  * Cleanup a node, free any memory associated with the node.
744  * This is the default callback function for ic_node_cleanup
745  * and may be overridden by the driver.
746  */
747 static void
748 ieee80211_node_cleanup(ieee80211_node_t *in)
749 {
750 	in->in_associd = 0;
751 	in->in_rssi = 0;
752 	in->in_rstamp = 0;
753 	if (in->in_challenge != NULL) {
754 		kmem_free(in->in_challenge, IEEE80211_CHALLENGE_LEN);
755 		in->in_challenge = NULL;
756 	}
757 	if (in->in_rxfrag != NULL) {
758 		freemsg(in->in_rxfrag);
759 		in->in_rxfrag = NULL;
760 	}
761 }
762 
763 /*
764  * Free a node. This is the default callback function for ic_node_free
765  * and may be overridden by the driver to free memory used by device
766  * specific node structure
767  */
768 static void
769 ieee80211_node_free(ieee80211_node_t *in)
770 {
771 	ieee80211com_t *ic = in->in_ic;
772 
773 	ic->ic_node_cleanup(in);
774 	if (in->in_wpa_ie != NULL)
775 		ieee80211_free(in->in_wpa_ie);
776 	kmem_free(in, sizeof (ieee80211_node_t));
777 }
778 
779 /*
780  * Get a node current RSSI value. This is the default callback function
781  * for ic_node_getrssi and may be overridden by the driver to provide
782  * device specific RSSI calculation algorithm.
783  */
784 static uint8_t
785 ieee80211_node_getrssi(const ieee80211_node_t *in)
786 {
787 	return (in->in_rssi);
788 }
789 
790 /* Free fragment if not needed anymore */
791 static void
792 node_cleanfrag(ieee80211_node_t *in)
793 {
794 	clock_t ticks;
795 
796 	ticks = ddi_get_lbolt();
797 	if (in->in_rxfrag != NULL && ticks > (in->in_rxfragstamp + hz)) {
798 		freemsg(in->in_rxfrag);
799 		in->in_rxfrag = NULL;
800 	}
801 }
802 
803 /*
804  * Setup a node. Initialize the node with specified macaddr. Associate
805  * with the interface softc, ic, and add it to the specified node
806  * database.
807  */
808 static void
809 ieee80211_setup_node(ieee80211com_t *ic, ieee80211_node_table_t *nt,
810     ieee80211_node_t *in, const uint8_t *macaddr)
811 {
812 	int32_t hash;
813 
814 	ieee80211_dbg(IEEE80211_MSG_NODE, "ieee80211_setup_node(): "
815 	    "%p<%s> in %s table\n", in,
816 	    ieee80211_macaddr_sprintf(macaddr),
817 	    (nt != NULL) ? nt->nt_name : "NULL");
818 
819 	in->in_ic = ic;
820 	IEEE80211_ADDR_COPY(in->in_macaddr, macaddr);
821 	hash = ieee80211_node_hash(macaddr);
822 	ieee80211_node_initref(in);		/* mark referenced */
823 	in->in_authmode = IEEE80211_AUTH_OPEN;
824 	in->in_txpower = ic->ic_txpowlimit;	/* max power */
825 	in->in_chan = IEEE80211_CHAN_ANYC;
826 	in->in_inact_reload = IEEE80211_INACT_INIT;
827 	in->in_inact = in->in_inact_reload;
828 	ieee80211_crypto_resetkey(ic, &in->in_ucastkey, IEEE80211_KEYIX_NONE);
829 
830 	if (nt != NULL) {
831 		IEEE80211_NODE_LOCK(nt);
832 		list_insert_tail(&nt->nt_node, in);
833 		list_insert_tail(&nt->nt_hash[hash], in);
834 		in->in_table = nt;
835 		in->in_inact_reload = nt->nt_inact_init;
836 		IEEE80211_NODE_UNLOCK(nt);
837 	}
838 }
839 
840 /*
841  * Allocates and initialize a node with specified MAC address.
842  * Associate the node with the interface ic. If the allocation
843  * is successful, the node structure is initialized by
844  * ieee80211_setup_node(); otherwise, NULL is returned
845  */
846 ieee80211_node_t *
847 ieee80211_alloc_node(ieee80211com_t *ic, ieee80211_node_table_t *nt,
848     const uint8_t *macaddr)
849 {
850 	ieee80211_node_t *in;
851 
852 	in = ic->ic_node_alloc(ic);
853 	if (in != NULL)
854 		ieee80211_setup_node(ic, nt, in, macaddr);
855 	return (in);
856 }
857 
858 /*
859  * Craft a temporary node suitable for sending a management frame
860  * to the specified station.  We craft only as much state as we
861  * need to do the work since the node will be immediately reclaimed
862  * once the send completes.
863  */
864 ieee80211_node_t *
865 ieee80211_tmp_node(ieee80211com_t *ic, const uint8_t *macaddr)
866 {
867 	ieee80211_node_t *in;
868 
869 	in = ic->ic_node_alloc(ic);
870 	if (in != NULL) {
871 		ieee80211_dbg(IEEE80211_MSG_NODE, "ieee80211_tmp_node: "
872 		    "%p<%s>\n", in, ieee80211_macaddr_sprintf(macaddr));
873 
874 		IEEE80211_ADDR_COPY(in->in_macaddr, macaddr);
875 		IEEE80211_ADDR_COPY(in->in_bssid, ic->ic_bss->in_bssid);
876 		ieee80211_node_initref(in);		/* mark referenced */
877 		in->in_txpower = ic->ic_bss->in_txpower;
878 		/* NB: required by ieee80211_fix_rate */
879 		ieee80211_node_setchan(ic, in, ic->ic_bss->in_chan);
880 		ieee80211_crypto_resetkey(ic, &in->in_ucastkey,
881 		    IEEE80211_KEYIX_NONE);
882 
883 		in->in_table = NULL;		/* NB: pedantic */
884 		in->in_ic = ic;
885 	}
886 
887 	return (in);
888 }
889 
890 /*
891  * ieee80211_dup_bss() is similar to ieee80211_alloc_node(),
892  * but is instead used to create a node database entry for
893  * the specified BSSID. If the allocation is successful, the
894  * node is initialized,  otherwise, NULL is returned.
895  */
896 ieee80211_node_t *
897 ieee80211_dup_bss(ieee80211_node_table_t *nt, const uint8_t *macaddr)
898 {
899 	ieee80211com_t *ic = nt->nt_ic;
900 	ieee80211_node_t *in;
901 
902 	in = ieee80211_alloc_node(ic, nt, macaddr);
903 	if (in != NULL) {
904 		/*
905 		 * Inherit from ic_bss.
906 		 */
907 		ieee80211_copy_bss(in, ic->ic_bss);
908 		IEEE80211_ADDR_COPY(in->in_bssid, ic->ic_bss->in_bssid);
909 		ieee80211_node_setchan(ic, in, ic->ic_bss->in_chan);
910 	}
911 
912 	return (in);
913 }
914 
915 /*
916  * Iterate through the node table, searching for a node entry which
917  * matches macaddr. If the entry is found, its reference count is
918  * incremented, and a pointer to the node is returned; otherwise,
919  * NULL will be returned.
920  * The node table lock is acquired by the caller.
921  */
922 static ieee80211_node_t *
923 ieee80211_find_node_locked(ieee80211_node_table_t *nt, const uint8_t *macaddr)
924 {
925 	ieee80211_node_t *in;
926 	int hash;
927 
928 	ASSERT(IEEE80211_NODE_IS_LOCKED(nt));
929 
930 	hash = ieee80211_node_hash(macaddr);
931 	in = list_head(&nt->nt_hash[hash]);
932 	while (in != NULL) {
933 		if (IEEE80211_ADDR_EQ(in->in_macaddr, macaddr))
934 			return (ieee80211_ref_node(in)); /* mark referenced */
935 		in = list_next(&nt->nt_hash[hash], in);
936 	}
937 	return (NULL);
938 }
939 
940 /*
941  * Iterate through the node table, searching for a node entry
942  * which match specified mac address.
943  * Return NULL if no matching node found.
944  */
945 ieee80211_node_t *
946 ieee80211_find_node(ieee80211_node_table_t *nt, const uint8_t *macaddr)
947 {
948 	ieee80211_node_t *in;
949 
950 	IEEE80211_NODE_LOCK(nt);
951 	in = ieee80211_find_node_locked(nt, macaddr);
952 	IEEE80211_NODE_UNLOCK(nt);
953 	return (in);
954 }
955 
956 /*
957  * Like find but search based on the ssid too.
958  */
959 ieee80211_node_t *
960 ieee80211_find_node_with_ssid(ieee80211_node_table_t *nt,
961 	const uint8_t *macaddr, uint32_t ssidlen, const uint8_t *ssid)
962 {
963 	ieee80211_node_t *in;
964 	int hash;
965 
966 	IEEE80211_NODE_LOCK(nt);
967 
968 	hash = ieee80211_node_hash(macaddr);
969 	in = list_head(&nt->nt_hash[hash]);
970 	while (in != NULL) {
971 		if (IEEE80211_ADDR_EQ(in->in_macaddr, macaddr) &&
972 		    in->in_esslen == ssidlen &&
973 		    memcmp(in->in_essid, ssid, ssidlen) == 0)
974 			break;
975 		in = list_next(&nt->nt_hash[hash], in);
976 	}
977 	if (in != NULL) {
978 		(void) ieee80211_ref_node(in); /* mark referenced */
979 	}
980 	IEEE80211_NODE_UNLOCK(nt);
981 
982 	return (in);
983 }
984 
985 /*
986  * Fake up a node; this handles node discovery in adhoc mode.
987  * Note that for the driver's benefit we treat this like an
988  * association so the driver has an opportunity to setup it's
989  * private state.
990  */
991 ieee80211_node_t *
992 ieee80211_fakeup_adhoc_node(ieee80211_node_table_t *nt, const uint8_t *macaddr)
993 {
994 	ieee80211com_t *ic = nt->nt_ic;
995 	ieee80211_node_t *in;
996 
997 	ieee80211_dbg(IEEE80211_MSG_NODE, "ieee80211_fakeup_adhoc_node: "
998 	    "mac<%s>\n", ieee80211_macaddr_sprintf(macaddr));
999 	in = ieee80211_dup_bss(nt, macaddr);
1000 	if (in != NULL) {
1001 		/* no rate negotiation; just dup */
1002 		in->in_rates = ic->ic_bss->in_rates;
1003 		if (ic->ic_node_newassoc != NULL)
1004 			ic->ic_node_newassoc(in, 1);
1005 		ieee80211_node_authorize(in);
1006 	}
1007 	return (in);
1008 }
1009 
1010 static void
1011 ieee80211_saveie(uint8_t **iep, const uint8_t *ie)
1012 {
1013 	uint_t ielen = ie[1]+2;
1014 	/*
1015 	 * Record information element for later use.
1016 	 */
1017 	if (*iep == NULL || (*iep)[1] != ie[1]) {
1018 		if (*iep != NULL)
1019 			ieee80211_free(*iep);
1020 		*iep = ieee80211_malloc(ielen);
1021 	}
1022 	if (*iep != NULL)
1023 		(void) memcpy(*iep, ie, ielen);
1024 }
1025 
1026 static void
1027 saveie(uint8_t **iep, const uint8_t *ie)
1028 {
1029 	if (ie == NULL) {
1030 		if (*iep != NULL)
1031 			ieee80211_free(*iep);
1032 		*iep = NULL;
1033 	}
1034 	else
1035 		ieee80211_saveie(iep, ie);
1036 }
1037 
1038 /*
1039  * Process a beacon or probe response frame.
1040  */
1041 void
1042 ieee80211_add_scan(ieee80211com_t *ic, const struct ieee80211_scanparams *sp,
1043     const struct ieee80211_frame *wh, int subtype, int rssi, int rstamp)
1044 {
1045 	ieee80211_node_table_t *nt = &ic->ic_scan;
1046 	ieee80211_node_t *in;
1047 	boolean_t newnode = B_FALSE;
1048 
1049 	in = ieee80211_find_node(nt, wh->i_addr3);
1050 	if (in == NULL) {
1051 		/*
1052 		 * Create a new entry.
1053 		 */
1054 		in = ieee80211_alloc_node(ic, nt, wh->i_addr3);
1055 		if (in == NULL) {
1056 			ieee80211_dbg(IEEE80211_MSG_ANY, "ieee80211_add_scan: "
1057 			    "alloc node failed\n");
1058 			return;
1059 		}
1060 		/*
1061 		 * inherit from ic_bss.
1062 		 */
1063 		ieee80211_copy_bss(in, ic->ic_bss);
1064 		ieee80211_node_setchan(ic, in, ic->ic_curchan);
1065 		newnode = B_TRUE;
1066 	}
1067 
1068 	/* ap beaconing multiple ssid w/ same bssid */
1069 
1070 	/*
1071 	 * sp->ssid[0] - element ID
1072 	 * sp->ssid[1] - length
1073 	 * sp->ssid[2]... - ssid
1074 	 */
1075 	if (sp->ssid[1] != 0 &&
1076 	    subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP ||
1077 	    in->in_esslen == 0) {
1078 		in->in_esslen = sp->ssid[1];
1079 		bzero(in->in_essid, sizeof (in->in_essid));
1080 		bcopy(sp->ssid + 2, in->in_essid, sp->ssid[1]);
1081 	}
1082 	IEEE80211_ADDR_COPY(in->in_bssid, wh->i_addr3);
1083 	in->in_rssi = (uint8_t)rssi;
1084 	in->in_rstamp = rstamp;
1085 	bcopy(sp->tstamp, in->in_tstamp.data, sizeof (in->in_tstamp));
1086 	in->in_intval = sp->bintval;
1087 	in->in_capinfo = sp->capinfo;
1088 	in->in_chan = &ic->ic_sup_channels[sp->chan];
1089 	in->in_phytype = sp->phytype;
1090 	in->in_fhdwell = sp->fhdwell;
1091 	in->in_fhindex = sp->fhindex;
1092 	in->in_erp = sp->erp;
1093 	if (sp->tim != NULL) {
1094 		struct ieee80211_tim_ie *ie;
1095 
1096 		ie = (struct ieee80211_tim_ie *)sp->tim;
1097 		in->in_dtim_count = ie->tim_count;
1098 		in->in_dtim_period = ie->tim_period;
1099 	}
1100 	/*
1101 	 * Record the byte offset from the mac header to
1102 	 * the start of the TIM information element for
1103 	 * use by hardware and/or to speedup software
1104 	 * processing of beacon frames.
1105 	 */
1106 	in->in_tim_off = sp->timoff;
1107 	/*
1108 	 * Record optional information elements that might be
1109 	 * used by applications or drivers.
1110 	 */
1111 	saveie(&in->in_wpa_ie, sp->wpa);
1112 
1113 	/* NB: must be after in_chan is setup */
1114 	(void) ieee80211_setup_rates(in, sp->rates, sp->xrates,
1115 	    IEEE80211_F_DOSORT);
1116 
1117 	if (!newnode)
1118 		ieee80211_free_node(in);
1119 }
1120 
1121 /*
1122  * Initialize/update an ad-hoc node with contents from a received
1123  * beacon frame.
1124  */
1125 void
1126 ieee80211_init_neighbor(ieee80211_node_t *in, const struct ieee80211_frame *wh,
1127     const struct ieee80211_scanparams *sp)
1128 {
1129 	in->in_esslen = sp->ssid[1];
1130 	(void) memcpy(in->in_essid, sp->ssid + 2, sp->ssid[1]);
1131 	IEEE80211_ADDR_COPY(in->in_bssid, wh->i_addr3);
1132 	(void) memcpy(in->in_tstamp.data, sp->tstamp, sizeof (in->in_tstamp));
1133 	in->in_intval = sp->bintval;
1134 	in->in_capinfo = sp->capinfo;
1135 	in->in_chan = in->in_ic->ic_curchan;
1136 	in->in_fhdwell = sp->fhdwell;
1137 	in->in_fhindex = sp->fhindex;
1138 	in->in_erp = sp->erp;
1139 	in->in_tim_off = sp->timoff;
1140 
1141 	/* NB: must be after in_chan is setup */
1142 	(void) ieee80211_setup_rates(in, sp->rates, sp->xrates,
1143 	    IEEE80211_F_DOSORT);
1144 }
1145 
1146 /*
1147  * Do node discovery in adhoc mode on receipt of a beacon
1148  * or probe response frame.  Note that for the driver's
1149  * benefit we we treat this like an association so the
1150  * driver has an opportuinty to setup it's private state.
1151  */
1152 ieee80211_node_t *
1153 ieee80211_add_neighbor(ieee80211com_t *ic, const struct ieee80211_frame *wh,
1154     const struct ieee80211_scanparams *sp)
1155 {
1156 	ieee80211_node_t *in;
1157 
1158 	in = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
1159 	if (in != NULL) {
1160 		ieee80211_init_neighbor(in, wh, sp);
1161 		if (ic->ic_node_newassoc != NULL)
1162 			ic->ic_node_newassoc(in, 1);
1163 	}
1164 	return (in);
1165 }
1166 
1167 #define	IEEE80211_IS_CTL(wh) \
1168 	((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
1169 
1170 /*
1171  * Locate the node for sender, track state, and then pass the
1172  * (referenced) node up to the 802.11 layer for its use.  We
1173  * are required to pass some node so we fall back to ic_bss
1174  * when this frame is from an unknown sender.  The 802.11 layer
1175  * knows this means the sender wasn't in the node table and
1176  * acts accordingly.
1177  */
1178 ieee80211_node_t *
1179 ieee80211_find_rxnode(ieee80211com_t *ic, const struct ieee80211_frame *wh)
1180 {
1181 	ieee80211_node_table_t *nt;
1182 	ieee80211_node_t *in;
1183 
1184 	/* may want scanned nodes in the neighbor table for adhoc */
1185 	if (ic->ic_opmode == IEEE80211_M_STA ||
1186 	    (ic->ic_flags & IEEE80211_F_SCAN)) {
1187 		nt = &ic->ic_scan;
1188 	} else {
1189 		nt = &ic->ic_sta;
1190 	}
1191 
1192 	IEEE80211_NODE_LOCK(nt);
1193 	if (IEEE80211_IS_CTL(wh))
1194 		in = ieee80211_find_node_locked(nt, wh->i_addr1);
1195 	else
1196 		in = ieee80211_find_node_locked(nt, wh->i_addr2);
1197 	IEEE80211_NODE_UNLOCK(nt);
1198 
1199 	if (in == NULL)
1200 		in = ieee80211_ref_node(ic->ic_bss);
1201 
1202 	return (in);
1203 }
1204 
1205 /*
1206  * Return a reference to the appropriate node for sending
1207  * a data frame.  This handles node discovery in adhoc networks.
1208  */
1209 ieee80211_node_t *
1210 ieee80211_find_txnode(ieee80211com_t *ic, const uint8_t *daddr)
1211 {
1212 	ieee80211_node_table_t *nt = &ic->ic_sta;
1213 	ieee80211_node_t *in;
1214 
1215 	/*
1216 	 * The destination address should be in the node table
1217 	 * unless this is a multicast/broadcast frame.  We can
1218 	 * also optimize station mode operation, all frames go
1219 	 * to the bss node.
1220 	 */
1221 	IEEE80211_NODE_LOCK(nt);
1222 	if (ic->ic_opmode == IEEE80211_M_STA || IEEE80211_IS_MULTICAST(daddr))
1223 		in = ieee80211_ref_node(ic->ic_bss);
1224 	else
1225 		in = ieee80211_find_node_locked(nt, daddr);
1226 	IEEE80211_NODE_UNLOCK(nt);
1227 
1228 	if (in == NULL) {
1229 		if (ic->ic_opmode == IEEE80211_M_IBSS) {
1230 			/*
1231 			 * In adhoc mode cons up a node for the destination.
1232 			 * Note that we need an additional reference for the
1233 			 * caller to be consistent with
1234 			 * ieee80211_find_node_locked
1235 			 * can't hold lock across ieee80211_dup_bss 'cuz of
1236 			 * recursive locking
1237 			 */
1238 			in = ieee80211_fakeup_adhoc_node(nt, daddr);
1239 			if (in != NULL)
1240 				(void) ieee80211_ref_node(in);
1241 		} else {
1242 			ieee80211_dbg(IEEE80211_MSG_OUTPUT,
1243 			    "ieee80211_find_txnode: "
1244 			    "[%s] no node, discard frame\n",
1245 			    ieee80211_macaddr_sprintf(daddr));
1246 		}
1247 	}
1248 	return (in);
1249 }
1250 
1251 /*
1252  * Remove a node from the node database entries and free memory
1253  * associated with the node. The node table lock is acquired by
1254  * the caller.
1255  */
1256 static void
1257 ieee80211_free_node_locked(ieee80211_node_t *in)
1258 {
1259 	ieee80211com_t *ic = in->in_ic;
1260 	ieee80211_node_table_t *nt = in->in_table;
1261 	int32_t hash;
1262 
1263 	if (nt != NULL) {
1264 		hash = ieee80211_node_hash(in->in_macaddr);
1265 		list_remove(&nt->nt_hash[hash], in);
1266 		list_remove(&nt->nt_node, in);
1267 	}
1268 	ic->ic_node_free(in);
1269 }
1270 
1271 /*
1272  * Remove a node from the node database entries and free any
1273  * memory associated with the node.
1274  * This method can be overridden in ieee80211_attach()
1275  */
1276 void
1277 ieee80211_free_node(ieee80211_node_t *in)
1278 {
1279 	ieee80211_node_table_t *nt = in->in_table;
1280 
1281 	if (nt != NULL)
1282 		IEEE80211_NODE_LOCK(nt);
1283 	if (ieee80211_node_decref_nv(in) == 0)
1284 		ieee80211_free_node_locked(in);
1285 	if (nt != NULL)
1286 		IEEE80211_NODE_UNLOCK(nt);
1287 }
1288 
1289 /*
1290  * Reclaim a node.  If this is the last reference count then
1291  * do the normal free work.  Otherwise remove it from the node
1292  * table and mark it gone by clearing the back-reference.
1293  */
1294 static void
1295 ieee80211_node_reclaim(ieee80211_node_table_t *nt, ieee80211_node_t *in)
1296 {
1297 	int32_t hash;
1298 
1299 	IEEE80211_NODE_LOCK_ASSERT(nt);
1300 	ieee80211_dbg(IEEE80211_MSG_NODE, "node_reclaim: "
1301 	    " remove %p<%s> from %s table, refcnt %d\n",
1302 	    in, ieee80211_macaddr_sprintf(in->in_macaddr), nt->nt_name,
1303 	    ieee80211_node_refcnt(in));
1304 
1305 	if (ieee80211_node_decref_nv(in) != 0) {
1306 		/*
1307 		 * Clear any entry in the unicast key mapping table.
1308 		 * We need to do it here so rx lookups don't find it
1309 		 * in the mapping table even if it's not in the hash
1310 		 * table.  We cannot depend on the mapping table entry
1311 		 * being cleared because the node may not be free'd.
1312 		 */
1313 		hash = ieee80211_node_hash(in->in_macaddr);
1314 		list_remove(&nt->nt_hash[hash], in);
1315 		list_remove(&nt->nt_node, in);
1316 		in->in_table = NULL;
1317 	} else {
1318 		ieee80211_free_node_locked(in);
1319 	}
1320 }
1321 
1322 /*
1323  * Iterate through the node list and reclaim all node in the node table.
1324  * The node table lock is acquired by the caller
1325  */
1326 static void
1327 ieee80211_free_allnodes_locked(ieee80211_node_table_t *nt)
1328 {
1329 	ieee80211_node_t *in;
1330 
1331 	ieee80211_dbg(IEEE80211_MSG_NODE, "ieee80211_free_allnodes_locked(): "
1332 	    "free all nodes in %s table\n", nt->nt_name);
1333 
1334 	in = list_head(&nt->nt_node);
1335 	while (in != NULL) {
1336 		ieee80211_node_reclaim(nt, in);
1337 		in = list_head(&nt->nt_node);
1338 	}
1339 	ieee80211_reset_erp(nt->nt_ic);
1340 }
1341 
1342 /*
1343  * Iterate through the node list, calling ieee80211_node_reclaim() for
1344  * all nodes associated with the interface.
1345  */
1346 static void
1347 ieee80211_free_allnodes(ieee80211_node_table_t *nt)
1348 {
1349 	IEEE80211_NODE_LOCK(nt);
1350 	ieee80211_free_allnodes_locked(nt);
1351 	IEEE80211_NODE_UNLOCK(nt);
1352 }
1353 
1354 /*
1355  * Timeout entries in the scan cache. This is the timeout callback
1356  * function of node table ic_scan which is called when the inactivity
1357  * timer expires.
1358  */
1359 static void
1360 ieee80211_timeout_scan_candidates(ieee80211_node_table_t *nt)
1361 {
1362 	ieee80211com_t *ic = nt->nt_ic;
1363 	ieee80211_node_t *in;
1364 
1365 	IEEE80211_NODE_LOCK(nt);
1366 	in = ic->ic_bss;
1367 	node_cleanfrag(in);	/* Free fragment if not needed */
1368 	nt->nt_inact_timer = IEEE80211_INACT_WAIT;
1369 	IEEE80211_NODE_UNLOCK(nt);
1370 }
1371 
1372 /*
1373  * Timeout inactive stations and do related housekeeping.
1374  * Note that we cannot hold the node lock while sending a
1375  * frame as this would lead to a LOR.  Instead we use a
1376  * generation number to mark nodes that we've scanned and
1377  * drop the lock and restart a scan if we have to time out
1378  * a node.  Since we are single-threaded by virtue of
1379  * controlling the inactivity timer we can be sure this will
1380  * process each node only once.
1381  */
1382 static void
1383 ieee80211_timeout_stations(ieee80211_node_table_t *nt)
1384 {
1385 	ieee80211com_t *ic = nt->nt_ic;
1386 	ieee80211_impl_t *im = ic->ic_private;
1387 	ieee80211_node_t *in = NULL;
1388 	uint32_t gen;
1389 	boolean_t isadhoc;
1390 
1391 	IEEE80211_LOCK_ASSERT(ic);
1392 	isadhoc = (ic->ic_opmode == IEEE80211_M_IBSS ||
1393 	    ic->ic_opmode == IEEE80211_M_AHDEMO);
1394 	IEEE80211_SCAN_LOCK(nt);
1395 	gen = ++nt->nt_scangen;
1396 restart:
1397 	IEEE80211_NODE_LOCK(nt);
1398 	for (in = list_head(&nt->nt_node); in != NULL;
1399 	    in = list_next(&nt->nt_node, in)) {
1400 		if (in->in_scangen == gen)	/* previously handled */
1401 			continue;
1402 		in->in_scangen = gen;
1403 		node_cleanfrag(in);	/* free fragment if not needed */
1404 
1405 		/*
1406 		 * Special case ourself; we may be idle for extended periods
1407 		 * of time and regardless reclaiming our state is wrong.
1408 		 */
1409 		if (in == ic->ic_bss)
1410 			continue;
1411 		in->in_inact--;
1412 		if (in->in_associd != 0 || isadhoc) {
1413 			/*
1414 			 * Probe the station before time it out.  We
1415 			 * send a null data frame which may not be
1416 			 * uinversally supported by drivers (need it
1417 			 * for ps-poll support so it should be...).
1418 			 */
1419 			if (0 < in->in_inact &&
1420 			    in->in_inact <= im->im_inact_probe) {
1421 				ieee80211_dbg(IEEE80211_MSG_NODE, "net80211: "
1422 				    "probe station due to inactivity\n");
1423 				IEEE80211_NODE_UNLOCK(nt);
1424 				IEEE80211_UNLOCK(ic);
1425 				(void) ieee80211_send_nulldata(in);
1426 				IEEE80211_LOCK(ic);
1427 				goto restart;
1428 			}
1429 		}
1430 		if (in->in_inact <= 0) {
1431 			ieee80211_dbg(IEEE80211_MSG_NODE, "net80211: "
1432 			    "station timed out due to inact (refcnt %u)\n",
1433 			    ieee80211_node_refcnt(in));
1434 			/*
1435 			 * Send a deauthenticate frame and drop the station.
1436 			 * This is somewhat complicated due to reference counts
1437 			 * and locking.  At this point a station will typically
1438 			 * have a reference count of 1.  ieee80211_node_leave
1439 			 * will do a "free" of the node which will drop the
1440 			 * reference count.  But in the meantime a reference
1441 			 * wil be held by the deauth frame.  The actual reclaim
1442 			 * of the node will happen either after the tx is
1443 			 * completed or by ieee80211_node_leave.
1444 			 *
1445 			 * Separately we must drop the node lock before sending
1446 			 * in case the driver takes a lock, as this will result
1447 			 * in  LOR between the node lock and the driver lock.
1448 			 */
1449 			IEEE80211_NODE_UNLOCK(nt);
1450 			if (in->in_associd != 0) {
1451 				IEEE80211_UNLOCK(ic);
1452 				IEEE80211_SEND_MGMT(ic, in,
1453 				    IEEE80211_FC0_SUBTYPE_DEAUTH,
1454 				    IEEE80211_REASON_AUTH_EXPIRE);
1455 				IEEE80211_LOCK(ic);
1456 			}
1457 			ieee80211_node_leave(ic, in);
1458 			goto restart;
1459 		}
1460 	}
1461 	IEEE80211_NODE_UNLOCK(nt);
1462 
1463 	IEEE80211_SCAN_UNLOCK(nt);
1464 
1465 	nt->nt_inact_timer = IEEE80211_INACT_WAIT;
1466 }
1467 
1468 /*
1469  * Call the user-defined call back function for all nodes in
1470  * the node cache. The callback is invoked with the user-supplied
1471  * value and a pointer to the current node.
1472  */
1473 void
1474 ieee80211_iterate_nodes(ieee80211_node_table_t *nt, ieee80211_iter_func *f,
1475     void *arg)
1476 {
1477 	ieee80211_node_t *in;
1478 
1479 	IEEE80211_NODE_LOCK(nt);
1480 	in = list_head(&nt->nt_node);
1481 	while (in != NULL) {
1482 		if (in->in_chan == IEEE80211_CHAN_ANYC) {
1483 			in = list_next(&nt->nt_node, in);
1484 			continue;
1485 		}
1486 		(void) ieee80211_ref_node(in);
1487 		IEEE80211_NODE_UNLOCK(nt);
1488 		(*f)(arg, in);
1489 		ieee80211_free_node(in);
1490 		IEEE80211_NODE_LOCK(nt);
1491 		in = list_next(&nt->nt_node, in);
1492 	}
1493 	IEEE80211_NODE_UNLOCK(nt);
1494 }
1495 
1496 /*
1497  * Handle bookkeeping for station deauthentication/disassociation
1498  * when operating as an ap.
1499  */
1500 static void
1501 ieee80211_node_leave(ieee80211com_t *ic, ieee80211_node_t *in)
1502 {
1503 	ieee80211_node_table_t *nt = in->in_table;
1504 
1505 	ASSERT(ic->ic_opmode == IEEE80211_M_IBSS);
1506 
1507 	/*
1508 	 * Remove the node from any table it's recorded in and
1509 	 * drop the caller's reference.  Removal from the table
1510 	 * is important to insure the node is not reprocessed
1511 	 * for inactivity.
1512 	 */
1513 	if (nt != NULL) {
1514 		IEEE80211_NODE_LOCK(nt);
1515 		ieee80211_node_reclaim(nt, in);
1516 		IEEE80211_NODE_UNLOCK(nt);
1517 	} else {
1518 		ieee80211_free_node(in);
1519 	}
1520 }
1521 
1522 /*
1523  * Initialize a node table with specified name, inactivity timer value
1524  * and callback inactivity timeout function. Associate the node table
1525  * with interface softc, ic.
1526  */
1527 static void
1528 ieee80211_node_table_init(ieee80211com_t *ic, ieee80211_node_table_t *nt,
1529     const char *name, int inact, int keyixmax,
1530     void (*timeout)(ieee80211_node_table_t *))
1531 {
1532 	int i;
1533 
1534 	ieee80211_dbg(IEEE80211_MSG_NODE, "ieee80211_node_table_init():"
1535 	    "%s table, inact %d\n", name, inact);
1536 
1537 	nt->nt_ic = ic;
1538 	nt->nt_name = name;
1539 	nt->nt_inact_timer = 0;
1540 	nt->nt_inact_init = inact;
1541 	nt->nt_timeout = timeout;
1542 	nt->nt_keyixmax = keyixmax;
1543 	nt->nt_scangen = 1;
1544 	mutex_init(&nt->nt_scanlock, NULL, MUTEX_DRIVER, NULL);
1545 	mutex_init(&nt->nt_nodelock, NULL, MUTEX_DRIVER, NULL);
1546 
1547 	list_create(&nt->nt_node, sizeof (ieee80211_node_t),
1548 	    offsetof(ieee80211_node_t, in_node));
1549 	for (i = 0; i < IEEE80211_NODE_HASHSIZE; i++) {
1550 		list_create(&nt->nt_hash[i], sizeof (ieee80211_node_t),
1551 		    offsetof(ieee80211_node_t, in_hash));
1552 	}
1553 }
1554 
1555 /*
1556  * Reset a node table. Clean its inactivity timer and call
1557  * ieee80211_free_allnodes_locked() to free all nodes in the
1558  * node table.
1559  */
1560 void
1561 ieee80211_node_table_reset(ieee80211_node_table_t *nt)
1562 {
1563 	ieee80211_dbg(IEEE80211_MSG_NODE, "ieee80211_node_table_reset(): "
1564 	    "%s table\n", nt->nt_name);
1565 
1566 	IEEE80211_NODE_LOCK(nt);
1567 	nt->nt_inact_timer = 0;
1568 	ieee80211_free_allnodes_locked(nt);
1569 	IEEE80211_NODE_UNLOCK(nt);
1570 }
1571 
1572 /*
1573  * Destroy a node table. Free all nodes in the node table.
1574  * This function is usually called by node detach function.
1575  */
1576 static void
1577 ieee80211_node_table_cleanup(ieee80211_node_table_t *nt)
1578 {
1579 	ieee80211_dbg(IEEE80211_MSG_NODE, "ieee80211_node_table_cleanup(): "
1580 	    "%s table\n", nt->nt_name);
1581 
1582 	IEEE80211_NODE_LOCK(nt);
1583 	ieee80211_free_allnodes_locked(nt);
1584 	IEEE80211_NODE_UNLOCK(nt);
1585 	mutex_destroy(&nt->nt_nodelock);
1586 	mutex_destroy(&nt->nt_scanlock);
1587 }
1588