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