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