ieee80211_node.c revision 148941
1/*- 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * Alternatively, this software may be distributed under the terms of the 18 * GNU General Public License ("GPL") version 2 as published by the Free 19 * Software Foundation. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> 34__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_node.c 148941 2005-08-10 17:42:13Z sam $"); 35 36#include <sys/param.h> 37#include <sys/systm.h> 38#include <sys/mbuf.h> 39#include <sys/malloc.h> 40#include <sys/kernel.h> 41 42#include <sys/socket.h> 43 44#include <net/if.h> 45#include <net/if_media.h> 46#include <net/ethernet.h> 47 48#include <net80211/ieee80211_var.h> 49 50#include <net/bpf.h> 51 52/* 53 * Association id's are managed with a bit vector. 54 */ 55#define IEEE80211_AID_SET(b, w) \ 56 ((w)[IEEE80211_AID(b) / 32] |= (1 << (IEEE80211_AID(b) % 32))) 57#define IEEE80211_AID_CLR(b, w) \ 58 ((w)[IEEE80211_AID(b) / 32] &= ~(1 << (IEEE80211_AID(b) % 32))) 59#define IEEE80211_AID_ISSET(b, w) \ 60 ((w)[IEEE80211_AID(b) / 32] & (1 << (IEEE80211_AID(b) % 32))) 61 62static struct ieee80211_node *node_alloc(struct ieee80211_node_table *); 63static void node_cleanup(struct ieee80211_node *); 64static void node_free(struct ieee80211_node *); 65static u_int8_t node_getrssi(const struct ieee80211_node *); 66 67static void ieee80211_setup_node(struct ieee80211_node_table *, 68 struct ieee80211_node *, const u_int8_t *); 69static void _ieee80211_free_node(struct ieee80211_node *); 70static void ieee80211_free_allnodes(struct ieee80211_node_table *); 71 72static void ieee80211_timeout_scan_candidates(struct ieee80211_node_table *); 73static void ieee80211_timeout_stations(struct ieee80211_node_table *); 74 75static void ieee80211_set_tim(struct ieee80211_node *, int set); 76 77static void ieee80211_node_table_init(struct ieee80211com *ic, 78 struct ieee80211_node_table *nt, const char *name, 79 int inact, int keyixmax, 80 void (*timeout)(struct ieee80211_node_table *)); 81static void ieee80211_node_table_cleanup(struct ieee80211_node_table *nt); 82 83MALLOC_DEFINE(M_80211_NODE, "80211node", "802.11 node state"); 84 85void 86ieee80211_node_attach(struct ieee80211com *ic) 87{ 88 89 ic->ic_node_alloc = node_alloc; 90 ic->ic_node_free = node_free; 91 ic->ic_node_cleanup = node_cleanup; 92 ic->ic_node_getrssi = node_getrssi; 93 94 /* default station inactivity timer setings */ 95 ic->ic_inact_init = IEEE80211_INACT_INIT; 96 ic->ic_inact_auth = IEEE80211_INACT_AUTH; 97 ic->ic_inact_run = IEEE80211_INACT_RUN; 98 ic->ic_inact_probe = IEEE80211_INACT_PROBE; 99 100 /* NB: driver should override */ 101 ic->ic_max_aid = IEEE80211_AID_DEF; 102 ic->ic_set_tim = ieee80211_set_tim; 103} 104 105void 106ieee80211_node_lateattach(struct ieee80211com *ic) 107{ 108 struct ieee80211_rsnparms *rsn; 109 110 if (ic->ic_max_aid > IEEE80211_AID_MAX) 111 ic->ic_max_aid = IEEE80211_AID_MAX; 112 MALLOC(ic->ic_aid_bitmap, u_int32_t *, 113 howmany(ic->ic_max_aid, 32) * sizeof(u_int32_t), 114 M_DEVBUF, M_NOWAIT | M_ZERO); 115 if (ic->ic_aid_bitmap == NULL) { 116 /* XXX no way to recover */ 117 printf("%s: no memory for AID bitmap!\n", __func__); 118 ic->ic_max_aid = 0; 119 } 120 121 /* XXX defer until using hostap/ibss mode */ 122 ic->ic_tim_len = howmany(ic->ic_max_aid, 8) * sizeof(u_int8_t); 123 MALLOC(ic->ic_tim_bitmap, u_int8_t *, ic->ic_tim_len, 124 M_DEVBUF, M_NOWAIT | M_ZERO); 125 if (ic->ic_tim_bitmap == NULL) { 126 /* XXX no way to recover */ 127 printf("%s: no memory for TIM bitmap!\n", __func__); 128 } 129 130 ieee80211_node_table_init(ic, &ic->ic_sta, "station", 131 IEEE80211_INACT_INIT, ic->ic_crypto.cs_max_keyix, 132 ieee80211_timeout_stations); 133 ieee80211_node_table_init(ic, &ic->ic_scan, "scan", 134 IEEE80211_INACT_SCAN, 0, 135 ieee80211_timeout_scan_candidates); 136 137 ieee80211_reset_bss(ic); 138 /* 139 * Setup "global settings" in the bss node so that 140 * each new station automatically inherits them. 141 */ 142 rsn = &ic->ic_bss->ni_rsn; 143 /* WEP, TKIP, and AES-CCM are always supported */ 144 rsn->rsn_ucastcipherset |= 1<<IEEE80211_CIPHER_WEP; 145 rsn->rsn_ucastcipherset |= 1<<IEEE80211_CIPHER_TKIP; 146 rsn->rsn_ucastcipherset |= 1<<IEEE80211_CIPHER_AES_CCM; 147 if (ic->ic_caps & IEEE80211_C_AES) 148 rsn->rsn_ucastcipherset |= 1<<IEEE80211_CIPHER_AES_OCB; 149 if (ic->ic_caps & IEEE80211_C_CKIP) 150 rsn->rsn_ucastcipherset |= 1<<IEEE80211_CIPHER_CKIP; 151 /* 152 * Default unicast cipher to WEP for 802.1x use. If 153 * WPA is enabled the management code will set these 154 * values to reflect. 155 */ 156 rsn->rsn_ucastcipher = IEEE80211_CIPHER_WEP; 157 rsn->rsn_ucastkeylen = 104 / NBBY; 158 /* 159 * WPA says the multicast cipher is the lowest unicast 160 * cipher supported. But we skip WEP which would 161 * otherwise be used based on this criteria. 162 */ 163 rsn->rsn_mcastcipher = IEEE80211_CIPHER_TKIP; 164 rsn->rsn_mcastkeylen = 128 / NBBY; 165 166 /* 167 * We support both WPA-PSK and 802.1x; the one used 168 * is determined by the authentication mode and the 169 * setting of the PSK state. 170 */ 171 rsn->rsn_keymgmtset = WPA_ASE_8021X_UNSPEC | WPA_ASE_8021X_PSK; 172 rsn->rsn_keymgmt = WPA_ASE_8021X_PSK; 173 174 ic->ic_auth = ieee80211_authenticator_get(ic->ic_bss->ni_authmode); 175} 176 177void 178ieee80211_node_detach(struct ieee80211com *ic) 179{ 180 181 if (ic->ic_bss != NULL) { 182 ieee80211_free_node(ic->ic_bss); 183 ic->ic_bss = NULL; 184 } 185 ieee80211_node_table_cleanup(&ic->ic_scan); 186 ieee80211_node_table_cleanup(&ic->ic_sta); 187 if (ic->ic_aid_bitmap != NULL) { 188 FREE(ic->ic_aid_bitmap, M_DEVBUF); 189 ic->ic_aid_bitmap = NULL; 190 } 191 if (ic->ic_tim_bitmap != NULL) { 192 FREE(ic->ic_tim_bitmap, M_DEVBUF); 193 ic->ic_tim_bitmap = NULL; 194 } 195} 196 197/* 198 * Port authorize/unauthorize interfaces for use by an authenticator. 199 */ 200 201void 202ieee80211_node_authorize(struct ieee80211_node *ni) 203{ 204 struct ieee80211com *ic = ni->ni_ic; 205 206 ni->ni_flags |= IEEE80211_NODE_AUTH; 207 ni->ni_inact_reload = ic->ic_inact_run; 208} 209 210void 211ieee80211_node_unauthorize(struct ieee80211_node *ni) 212{ 213 ni->ni_flags &= ~IEEE80211_NODE_AUTH; 214} 215 216/* 217 * Set/change the channel. The rate set is also updated as 218 * to insure a consistent view by drivers. 219 */ 220static __inline void 221ieee80211_set_chan(struct ieee80211com *ic, 222 struct ieee80211_node *ni, struct ieee80211_channel *chan) 223{ 224 ni->ni_chan = chan; 225 ni->ni_rates = ic->ic_sup_rates[ieee80211_chan2mode(ic, chan)]; 226} 227 228/* 229 * AP scanning support. 230 */ 231 232#ifdef IEEE80211_DEBUG 233static void 234dump_chanlist(const u_char chans[]) 235{ 236 const char *sep; 237 int i; 238 239 sep = " "; 240 for (i = 0; i < IEEE80211_CHAN_MAX; i++) 241 if (isset(chans, i)) { 242 printf("%s%u", sep, i); 243 sep = ", "; 244 } 245} 246#endif /* IEEE80211_DEBUG */ 247 248/* 249 * Initialize the channel set to scan based on the 250 * of available channels and the current PHY mode. 251 */ 252static void 253ieee80211_reset_scan(struct ieee80211com *ic) 254{ 255 256 /* XXX ic_des_chan should be handled with ic_chan_active */ 257 if (ic->ic_des_chan != IEEE80211_CHAN_ANYC) { 258 memset(ic->ic_chan_scan, 0, sizeof(ic->ic_chan_scan)); 259 setbit(ic->ic_chan_scan, 260 ieee80211_chan2ieee(ic, ic->ic_des_chan)); 261 } else 262 memcpy(ic->ic_chan_scan, ic->ic_chan_active, 263 sizeof(ic->ic_chan_active)); 264#ifdef IEEE80211_DEBUG 265 if (ieee80211_msg_scan(ic)) { 266 printf("%s: scan set:", __func__); 267 dump_chanlist(ic->ic_chan_scan); 268 printf(" start chan %u\n", 269 ieee80211_chan2ieee(ic, ic->ic_curchan)); 270 } 271#endif /* IEEE80211_DEBUG */ 272} 273 274/* 275 * Begin an active scan. 276 */ 277void 278ieee80211_begin_scan(struct ieee80211com *ic, int reset) 279{ 280 281 ic->ic_scan.nt_scangen++; 282 /* 283 * In all but hostap mode scanning starts off in 284 * an active mode before switching to passive. 285 */ 286 if (ic->ic_opmode != IEEE80211_M_HOSTAP) { 287 ic->ic_flags |= IEEE80211_F_ASCAN; 288 ic->ic_stats.is_scan_active++; 289 } else 290 ic->ic_stats.is_scan_passive++; 291 IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN, 292 "begin %s scan in %s mode, scangen %u\n", 293 (ic->ic_flags & IEEE80211_F_ASCAN) ? "active" : "passive", 294 ieee80211_phymode_name[ic->ic_curmode], ic->ic_scan.nt_scangen); 295 /* 296 * Clear scan state and flush any previously seen AP's. 297 */ 298 ieee80211_reset_scan(ic); 299 if (reset) 300 ieee80211_free_allnodes(&ic->ic_scan); 301 302 ic->ic_flags |= IEEE80211_F_SCAN; 303 304 /* Scan the next channel. */ 305 ieee80211_next_scan(ic); 306} 307 308/* 309 * Switch to the next channel marked for scanning. 310 */ 311int 312ieee80211_next_scan(struct ieee80211com *ic) 313{ 314 struct ieee80211_channel *chan; 315 316 /* 317 * Insure any previous mgt frame timeouts don't fire. 318 * This assumes the driver does the right thing in 319 * flushing anything queued in the driver and below. 320 */ 321 ic->ic_mgt_timer = 0; 322 323 chan = ic->ic_curchan; 324 do { 325 if (++chan > &ic->ic_channels[IEEE80211_CHAN_MAX]) 326 chan = &ic->ic_channels[0]; 327 if (isset(ic->ic_chan_scan, ieee80211_chan2ieee(ic, chan))) { 328 clrbit(ic->ic_chan_scan, ieee80211_chan2ieee(ic, chan)); 329 IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN, 330 "%s: chan %d->%d\n", __func__, 331 ieee80211_chan2ieee(ic, ic->ic_curchan), 332 ieee80211_chan2ieee(ic, chan)); 333 ic->ic_curchan = chan; 334 /* 335 * XXX drivers should do this as needed, 336 * XXX for now maintain compatibility 337 */ 338 ic->ic_bss->ni_rates = 339 ic->ic_sup_rates[ieee80211_chan2mode(ic, chan)]; 340 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 341 return 1; 342 } 343 } while (chan != ic->ic_curchan); 344 ieee80211_end_scan(ic); 345 return 0; 346} 347 348static __inline void 349copy_bss(struct ieee80211_node *nbss, const struct ieee80211_node *obss) 350{ 351 /* propagate useful state */ 352 nbss->ni_authmode = obss->ni_authmode; 353 nbss->ni_txpower = obss->ni_txpower; 354 nbss->ni_vlan = obss->ni_vlan; 355 nbss->ni_rsn = obss->ni_rsn; 356 /* XXX statistics? */ 357} 358 359void 360ieee80211_create_ibss(struct ieee80211com* ic, struct ieee80211_channel *chan) 361{ 362 struct ieee80211_node_table *nt; 363 struct ieee80211_node *ni; 364 365 IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN, 366 "%s: creating ibss\n", __func__); 367 368 /* 369 * Create the station/neighbor table. Note that for adhoc 370 * mode we make the initial inactivity timer longer since 371 * we create nodes only through discovery and they typically 372 * are long-lived associations. 373 */ 374 nt = &ic->ic_sta; 375 IEEE80211_NODE_LOCK(nt); 376 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 377 nt->nt_name = "station"; 378 nt->nt_inact_init = ic->ic_inact_init; 379 } else { 380 nt->nt_name = "neighbor"; 381 nt->nt_inact_init = ic->ic_inact_run; 382 } 383 IEEE80211_NODE_UNLOCK(nt); 384 385 ni = ieee80211_alloc_node(&ic->ic_sta, ic->ic_myaddr); 386 if (ni == NULL) { 387 /* XXX recovery? */ 388 return; 389 } 390 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_myaddr); 391 ni->ni_esslen = ic->ic_des_esslen; 392 memcpy(ni->ni_essid, ic->ic_des_essid, ni->ni_esslen); 393 copy_bss(ni, ic->ic_bss); 394 ni->ni_intval = ic->ic_bintval; 395 if (ic->ic_flags & IEEE80211_F_PRIVACY) 396 ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY; 397 if (ic->ic_phytype == IEEE80211_T_FH) { 398 ni->ni_fhdwell = 200; /* XXX */ 399 ni->ni_fhindex = 1; 400 } 401 if (ic->ic_opmode == IEEE80211_M_IBSS) { 402 ic->ic_flags |= IEEE80211_F_SIBSS; 403 ni->ni_capinfo |= IEEE80211_CAPINFO_IBSS; /* XXX */ 404 if (ic->ic_flags & IEEE80211_F_DESBSSID) 405 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_des_bssid); 406 else 407 ni->ni_bssid[0] |= 0x02; /* local bit for IBSS */ 408 } 409 /* 410 * Fix the channel and related attributes. 411 */ 412 ieee80211_set_chan(ic, ni, chan); 413 ic->ic_curchan = chan; 414 ic->ic_curmode = ieee80211_chan2mode(ic, chan); 415 /* 416 * Do mode-specific rate setup. 417 */ 418 if (ic->ic_curmode == IEEE80211_MODE_11G) { 419 /* 420 * Use a mixed 11b/11g rate set. 421 */ 422 ieee80211_set11gbasicrates(&ni->ni_rates, IEEE80211_MODE_11G); 423 } else if (ic->ic_curmode == IEEE80211_MODE_11B) { 424 /* 425 * Force pure 11b rate set. 426 */ 427 ieee80211_set11gbasicrates(&ni->ni_rates, IEEE80211_MODE_11B); 428 } 429 430 (void) ieee80211_sta_join(ic, ieee80211_ref_node(ni)); 431} 432 433void 434ieee80211_reset_bss(struct ieee80211com *ic) 435{ 436 struct ieee80211_node *ni, *obss; 437 438 ieee80211_node_table_reset(&ic->ic_scan); 439 ieee80211_node_table_reset(&ic->ic_sta); 440 441 ni = ieee80211_alloc_node(&ic->ic_scan, ic->ic_myaddr); 442 KASSERT(ni != NULL, ("unable to setup inital BSS node")); 443 obss = ic->ic_bss; 444 ic->ic_bss = ieee80211_ref_node(ni); 445 if (obss != NULL) { 446 copy_bss(ni, obss); 447 ni->ni_intval = ic->ic_bintval; 448 ieee80211_free_node(obss); 449 } 450} 451 452/* XXX tunable */ 453#define STA_FAILS_MAX 2 /* assoc failures before ignored */ 454 455static int 456ieee80211_match_bss(struct ieee80211com *ic, struct ieee80211_node *ni) 457{ 458 u_int8_t rate; 459 int fail; 460 461 fail = 0; 462 if (isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, ni->ni_chan))) 463 fail |= 0x01; 464 if (ic->ic_des_chan != IEEE80211_CHAN_ANYC && 465 ni->ni_chan != ic->ic_des_chan) 466 fail |= 0x01; 467 if (ic->ic_opmode == IEEE80211_M_IBSS) { 468 if ((ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) == 0) 469 fail |= 0x02; 470 } else { 471 if ((ni->ni_capinfo & IEEE80211_CAPINFO_ESS) == 0) 472 fail |= 0x02; 473 } 474 if (ic->ic_flags & IEEE80211_F_PRIVACY) { 475 if ((ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) == 0) 476 fail |= 0x04; 477 } else { 478 /* XXX does this mean privacy is supported or required? */ 479 if (ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) 480 fail |= 0x04; 481 } 482 rate = ieee80211_fix_rate(ni, IEEE80211_F_DONEGO | IEEE80211_F_DOFRATE); 483 if (rate & IEEE80211_RATE_BASIC) 484 fail |= 0x08; 485 if (ic->ic_des_esslen != 0 && 486 (ni->ni_esslen != ic->ic_des_esslen || 487 memcmp(ni->ni_essid, ic->ic_des_essid, ic->ic_des_esslen) != 0)) 488 fail |= 0x10; 489 if ((ic->ic_flags & IEEE80211_F_DESBSSID) && 490 !IEEE80211_ADDR_EQ(ic->ic_des_bssid, ni->ni_bssid)) 491 fail |= 0x20; 492 if (ni->ni_fails >= STA_FAILS_MAX) 493 fail |= 0x40; 494#ifdef IEEE80211_DEBUG 495 if (ieee80211_msg_scan(ic)) { 496 printf(" %c %s", 497 fail & 0x40 ? '=' : fail & 0x80 ? '^' : fail ? '-' : '+', 498 ether_sprintf(ni->ni_macaddr)); 499 printf(" %s%c", ether_sprintf(ni->ni_bssid), 500 fail & 0x20 ? '!' : ' '); 501 printf(" %3d%c", ieee80211_chan2ieee(ic, ni->ni_chan), 502 fail & 0x01 ? '!' : ' '); 503 printf(" %+4d", ni->ni_rssi); 504 printf(" %2dM%c", (rate & IEEE80211_RATE_VAL) / 2, 505 fail & 0x08 ? '!' : ' '); 506 printf(" %4s%c", 507 (ni->ni_capinfo & IEEE80211_CAPINFO_ESS) ? "ess" : 508 (ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) ? "ibss" : 509 "????", 510 fail & 0x02 ? '!' : ' '); 511 printf(" %3s%c ", 512 (ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) ? 513 "wep" : "no", 514 fail & 0x04 ? '!' : ' '); 515 ieee80211_print_essid(ni->ni_essid, ni->ni_esslen); 516 printf("%s\n", fail & 0x10 ? "!" : ""); 517 } 518#endif 519 return fail; 520} 521 522static __inline u_int8_t 523maxrate(const struct ieee80211_node *ni) 524{ 525 const struct ieee80211_rateset *rs = &ni->ni_rates; 526 /* NB: assumes rate set is sorted (happens on frame receive) */ 527 return rs->rs_rates[rs->rs_nrates-1] & IEEE80211_RATE_VAL; 528} 529 530/* 531 * Compare the capabilities of two nodes and decide which is 532 * more desirable (return >0 if a is considered better). Note 533 * that we assume compatibility/usability has already been checked 534 * so we don't need to (e.g. validate whether privacy is supported). 535 * Used to select the best scan candidate for association in a BSS. 536 */ 537static int 538ieee80211_node_compare(struct ieee80211com *ic, 539 const struct ieee80211_node *a, 540 const struct ieee80211_node *b) 541{ 542 u_int8_t maxa, maxb; 543 u_int8_t rssia, rssib; 544 int weight; 545 546 /* privacy support preferred */ 547 if ((a->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) && 548 (b->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) == 0) 549 return 1; 550 if ((a->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) == 0 && 551 (b->ni_capinfo & IEEE80211_CAPINFO_PRIVACY)) 552 return -1; 553 554 /* compare count of previous failures */ 555 weight = b->ni_fails - a->ni_fails; 556 if (abs(weight) > 1) 557 return weight; 558 559 rssia = ic->ic_node_getrssi(a); 560 rssib = ic->ic_node_getrssi(b); 561 if (abs(rssib - rssia) < 5) { 562 /* best/max rate preferred if signal level close enough XXX */ 563 maxa = maxrate(a); 564 maxb = maxrate(b); 565 if (maxa != maxb) 566 return maxa - maxb; 567 /* XXX use freq for channel preference */ 568 /* for now just prefer 5Ghz band to all other bands */ 569 if (IEEE80211_IS_CHAN_5GHZ(a->ni_chan) && 570 !IEEE80211_IS_CHAN_5GHZ(b->ni_chan)) 571 return 1; 572 if (!IEEE80211_IS_CHAN_5GHZ(a->ni_chan) && 573 IEEE80211_IS_CHAN_5GHZ(b->ni_chan)) 574 return -1; 575 } 576 /* all things being equal, use signal level */ 577 return rssia - rssib; 578} 579 580/* 581 * Mark an ongoing scan stopped. 582 */ 583void 584ieee80211_cancel_scan(struct ieee80211com *ic) 585{ 586 587 IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN, "%s: end %s scan\n", 588 __func__, 589 (ic->ic_flags & IEEE80211_F_ASCAN) ? "active" : "passive"); 590 591 ic->ic_flags &= ~(IEEE80211_F_SCAN | IEEE80211_F_ASCAN); 592} 593 594/* 595 * Complete a scan of potential channels. 596 */ 597void 598ieee80211_end_scan(struct ieee80211com *ic) 599{ 600 struct ieee80211_node_table *nt = &ic->ic_scan; 601 struct ieee80211_node *ni, *selbs; 602 603 ieee80211_cancel_scan(ic); 604 ieee80211_notify_scan_done(ic); 605 606 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 607 u_int8_t maxrssi[IEEE80211_CHAN_MAX]; /* XXX off stack? */ 608 int i, bestchan; 609 u_int8_t rssi; 610 611 /* 612 * The passive scan to look for existing AP's completed, 613 * select a channel to camp on. Identify the channels 614 * that already have one or more AP's and try to locate 615 * an unoccupied one. If that fails, pick a channel that 616 * looks to be quietest. 617 */ 618 memset(maxrssi, 0, sizeof(maxrssi)); 619 IEEE80211_NODE_LOCK(nt); 620 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { 621 rssi = ic->ic_node_getrssi(ni); 622 i = ieee80211_chan2ieee(ic, ni->ni_chan); 623 if (rssi > maxrssi[i]) 624 maxrssi[i] = rssi; 625 } 626 IEEE80211_NODE_UNLOCK(nt); 627 /* XXX select channel more intelligently */ 628 bestchan = -1; 629 for (i = 0; i < IEEE80211_CHAN_MAX; i++) 630 if (isset(ic->ic_chan_active, i)) { 631 /* 632 * If the channel is unoccupied the max rssi 633 * should be zero; just take it. Otherwise 634 * track the channel with the lowest rssi and 635 * use that when all channels appear occupied. 636 */ 637 if (maxrssi[i] == 0) { 638 bestchan = i; 639 break; 640 } 641 if (bestchan == -1 || 642 maxrssi[i] < maxrssi[bestchan]) 643 bestchan = i; 644 } 645 if (bestchan != -1) { 646 ieee80211_create_ibss(ic, &ic->ic_channels[bestchan]); 647 return; 648 } 649 /* no suitable channel, should not happen */ 650 } 651 652 /* 653 * When manually sequencing the state machine; scan just once 654 * regardless of whether we have a candidate or not. The 655 * controlling application is expected to setup state and 656 * initiate an association. 657 */ 658 if (ic->ic_roaming == IEEE80211_ROAMING_MANUAL) 659 return; 660 /* 661 * Automatic sequencing; look for a candidate and 662 * if found join the network. 663 */ 664 /* NB: unlocked read should be ok */ 665 if (TAILQ_FIRST(&nt->nt_node) == NULL) { 666 IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN, 667 "%s: no scan candidate\n", __func__); 668 notfound: 669 if (ic->ic_opmode == IEEE80211_M_IBSS && 670 (ic->ic_flags & IEEE80211_F_IBSSON) && 671 ic->ic_des_esslen != 0) { 672 ieee80211_create_ibss(ic, ic->ic_ibss_chan); 673 return; 674 } 675 /* 676 * Decrement the failure counts so entries will be 677 * reconsidered the next time around. We really want 678 * to do this only for sta's where we've previously 679 had some success. 680 */ 681 IEEE80211_NODE_LOCK(nt); 682 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) 683 if (ni->ni_fails) 684 ni->ni_fails--; 685 IEEE80211_NODE_UNLOCK(nt); 686 /* 687 * Reset the list of channels to scan and start again. 688 */ 689 ieee80211_reset_scan(ic); 690 ic->ic_flags |= IEEE80211_F_SCAN; 691 ieee80211_next_scan(ic); 692 return; 693 } 694 selbs = NULL; 695 IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN, "\t%s\n", 696 "macaddr bssid chan rssi rate flag wep essid"); 697 IEEE80211_NODE_LOCK(nt); 698 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { 699 if (ieee80211_match_bss(ic, ni) == 0) { 700 if (selbs == NULL) 701 selbs = ni; 702 else if (ieee80211_node_compare(ic, ni, selbs) > 0) 703 selbs = ni; 704 } 705 } 706 if (selbs != NULL) /* NB: grab ref while dropping lock */ 707 (void) ieee80211_ref_node(selbs); 708 IEEE80211_NODE_UNLOCK(nt); 709 if (selbs == NULL) 710 goto notfound; 711 if (!ieee80211_sta_join(ic, selbs)) { 712 ieee80211_free_node(selbs); 713 goto notfound; 714 } 715} 716 717/* 718 * Handle 802.11 ad hoc network merge. The 719 * convention, set by the Wireless Ethernet Compatibility Alliance 720 * (WECA), is that an 802.11 station will change its BSSID to match 721 * the "oldest" 802.11 ad hoc network, on the same channel, that 722 * has the station's desired SSID. The "oldest" 802.11 network 723 * sends beacons with the greatest TSF timestamp. 724 * 725 * The caller is assumed to validate TSF's before attempting a merge. 726 * 727 * Return !0 if the BSSID changed, 0 otherwise. 728 */ 729int 730ieee80211_ibss_merge(struct ieee80211_node *ni) 731{ 732 struct ieee80211com *ic = ni->ni_ic; 733 734 if (ni == ic->ic_bss || 735 IEEE80211_ADDR_EQ(ni->ni_bssid, ic->ic_bss->ni_bssid)) { 736 /* unchanged, nothing to do */ 737 return 0; 738 } 739 if (ieee80211_match_bss(ic, ni) != 0) { /* capabilities mismatch */ 740 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 741 "%s: merge failed, capabilities mismatch\n", __func__); 742 ic->ic_stats.is_ibss_capmismatch++; 743 return 0; 744 } 745 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 746 "%s: new bssid %s: %s preamble, %s slot time%s\n", __func__, 747 ether_sprintf(ni->ni_bssid), 748 ic->ic_flags&IEEE80211_F_SHPREAMBLE ? "short" : "long", 749 ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long", 750 ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "" 751 ); 752 return ieee80211_sta_join(ic, ieee80211_ref_node(ni)); 753} 754 755/* 756 * Join the specified IBSS/BSS network. The node is assumed to 757 * be passed in with a held reference. 758 */ 759int 760ieee80211_sta_join(struct ieee80211com *ic, struct ieee80211_node *selbs) 761{ 762 struct ieee80211_node *obss; 763 764 if (ic->ic_opmode == IEEE80211_M_IBSS) { 765 struct ieee80211_node_table *nt; 766 /* 767 * Delete unusable rates; we've already checked 768 * that the negotiated rate set is acceptable. 769 */ 770 ieee80211_fix_rate(selbs, IEEE80211_F_DODEL); 771 /* 772 * Fillin the neighbor table; it will already 773 * exist if we are simply switching mastership. 774 * XXX ic_sta always setup so this is unnecessary? 775 */ 776 nt = &ic->ic_sta; 777 IEEE80211_NODE_LOCK(nt); 778 nt->nt_name = "neighbor"; 779 nt->nt_inact_init = ic->ic_inact_run; 780 IEEE80211_NODE_UNLOCK(nt); 781 } 782 783 /* 784 * Committed to selbs, setup state. 785 */ 786 obss = ic->ic_bss; 787 ic->ic_bss = selbs; /* NB: caller assumed to bump refcnt */ 788 if (obss != NULL) 789 ieee80211_free_node(obss); 790 /* 791 * Set the erp state (mostly the slot time) to deal with 792 * the auto-select case; this should be redundant if the 793 * mode is locked. 794 */ 795 ic->ic_curmode = ieee80211_chan2mode(ic, selbs->ni_chan); 796 ic->ic_curchan = selbs->ni_chan; 797 ieee80211_reset_erp(ic); 798 ieee80211_wme_initparams(ic); 799 800 if (ic->ic_opmode == IEEE80211_M_STA) 801 ieee80211_new_state(ic, IEEE80211_S_AUTH, -1); 802 else 803 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 804 return 1; 805} 806 807/* 808 * Leave the specified IBSS/BSS network. The node is assumed to 809 * be passed in with a held reference. 810 */ 811void 812ieee80211_sta_leave(struct ieee80211com *ic, struct ieee80211_node *ni) 813{ 814 ic->ic_node_cleanup(ni); 815 ieee80211_notify_node_leave(ic, ni); 816} 817 818static struct ieee80211_node * 819node_alloc(struct ieee80211_node_table *nt) 820{ 821 struct ieee80211_node *ni; 822 823 MALLOC(ni, struct ieee80211_node *, sizeof(struct ieee80211_node), 824 M_80211_NODE, M_NOWAIT | M_ZERO); 825 return ni; 826} 827 828/* 829 * Reclaim any resources in a node and reset any critical 830 * state. Typically nodes are free'd immediately after, 831 * but in some cases the storage may be reused so we need 832 * to insure consistent state (should probably fix that). 833 */ 834static void 835node_cleanup(struct ieee80211_node *ni) 836{ 837#define N(a) (sizeof(a)/sizeof(a[0])) 838 struct ieee80211com *ic = ni->ni_ic; 839 int i, qlen; 840 841 /* NB: preserve ni_table */ 842 if (ni->ni_flags & IEEE80211_NODE_PWR_MGT) { 843 ic->ic_ps_sta--; 844 ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT; 845 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 846 "[%s] power save mode off, %u sta's in ps mode\n", 847 ether_sprintf(ni->ni_macaddr), ic->ic_ps_sta); 848 } 849 /* 850 * Clear AREF flag that marks the authorization refcnt bump 851 * has happened. This is probably not needed as the node 852 * should always be removed from the table so not found but 853 * do it just in case. 854 */ 855 ni->ni_flags &= ~IEEE80211_NODE_AREF; 856 857 /* 858 * Drain power save queue and, if needed, clear TIM. 859 */ 860 IEEE80211_NODE_SAVEQ_DRAIN(ni, qlen); 861 if (qlen != 0 && ic->ic_set_tim != NULL) 862 ic->ic_set_tim(ni, 0); 863 864 ni->ni_associd = 0; 865 if (ni->ni_challenge != NULL) { 866 FREE(ni->ni_challenge, M_DEVBUF); 867 ni->ni_challenge = NULL; 868 } 869 /* 870 * Preserve SSID, WPA, and WME ie's so the bss node is 871 * reusable during a re-auth/re-assoc state transition. 872 * If we remove these data they will not be recreated 873 * because they come from a probe-response or beacon frame 874 * which cannot be expected prior to the association-response. 875 * This should not be an issue when operating in other modes 876 * as stations leaving always go through a full state transition 877 * which will rebuild this state. 878 * 879 * XXX does this leave us open to inheriting old state? 880 */ 881 for (i = 0; i < N(ni->ni_rxfrag); i++) 882 if (ni->ni_rxfrag[i] != NULL) { 883 m_freem(ni->ni_rxfrag[i]); 884 ni->ni_rxfrag[i] = NULL; 885 } 886 /* 887 * Must be careful here to remove any key map entry w/o a LOR. 888 */ 889 ieee80211_node_delucastkey(ni); 890#undef N 891} 892 893static void 894node_free(struct ieee80211_node *ni) 895{ 896 struct ieee80211com *ic = ni->ni_ic; 897 898 ic->ic_node_cleanup(ni); 899 if (ni->ni_wpa_ie != NULL) 900 FREE(ni->ni_wpa_ie, M_DEVBUF); 901 if (ni->ni_wme_ie != NULL) 902 FREE(ni->ni_wme_ie, M_DEVBUF); 903 IEEE80211_NODE_SAVEQ_DESTROY(ni); 904 FREE(ni, M_80211_NODE); 905} 906 907static u_int8_t 908node_getrssi(const struct ieee80211_node *ni) 909{ 910 return ni->ni_rssi; 911} 912 913static void 914ieee80211_setup_node(struct ieee80211_node_table *nt, 915 struct ieee80211_node *ni, const u_int8_t *macaddr) 916{ 917 struct ieee80211com *ic = nt->nt_ic; 918 int hash; 919 920 IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE, 921 "%s %p<%s> in %s table\n", __func__, ni, 922 ether_sprintf(macaddr), nt->nt_name); 923 924 IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr); 925 hash = IEEE80211_NODE_HASH(macaddr); 926 ieee80211_node_initref(ni); /* mark referenced */ 927 ni->ni_chan = IEEE80211_CHAN_ANYC; 928 ni->ni_authmode = IEEE80211_AUTH_OPEN; 929 ni->ni_txpower = ic->ic_txpowlimit; /* max power */ 930 ieee80211_crypto_resetkey(ic, &ni->ni_ucastkey, IEEE80211_KEYIX_NONE); 931 ni->ni_inact_reload = nt->nt_inact_init; 932 ni->ni_inact = ni->ni_inact_reload; 933 IEEE80211_NODE_SAVEQ_INIT(ni, "unknown"); 934 935 IEEE80211_NODE_LOCK(nt); 936 TAILQ_INSERT_TAIL(&nt->nt_node, ni, ni_list); 937 LIST_INSERT_HEAD(&nt->nt_hash[hash], ni, ni_hash); 938 ni->ni_table = nt; 939 ni->ni_ic = ic; 940 IEEE80211_NODE_UNLOCK(nt); 941} 942 943struct ieee80211_node * 944ieee80211_alloc_node(struct ieee80211_node_table *nt, const u_int8_t *macaddr) 945{ 946 struct ieee80211com *ic = nt->nt_ic; 947 struct ieee80211_node *ni; 948 949 ni = ic->ic_node_alloc(nt); 950 if (ni != NULL) 951 ieee80211_setup_node(nt, ni, macaddr); 952 else 953 ic->ic_stats.is_rx_nodealloc++; 954 return ni; 955} 956 957/* 958 * Craft a temporary node suitable for sending a management frame 959 * to the specified station. We craft only as much state as we 960 * need to do the work since the node will be immediately reclaimed 961 * once the send completes. 962 */ 963struct ieee80211_node * 964ieee80211_tmp_node(struct ieee80211com *ic, const u_int8_t *macaddr) 965{ 966 struct ieee80211_node *ni; 967 968 ni = ic->ic_node_alloc(&ic->ic_sta); 969 if (ni != NULL) { 970 IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE, 971 "%s %p<%s>\n", __func__, ni, ether_sprintf(macaddr)); 972 973 IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr); 974 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid); 975 ieee80211_node_initref(ni); /* mark referenced */ 976 ni->ni_txpower = ic->ic_bss->ni_txpower; 977 /* NB: required by ieee80211_fix_rate */ 978 ieee80211_set_chan(ic, ni, ic->ic_bss->ni_chan); 979 ieee80211_crypto_resetkey(ic, &ni->ni_ucastkey, 980 IEEE80211_KEYIX_NONE); 981 /* XXX optimize away */ 982 IEEE80211_NODE_SAVEQ_INIT(ni, "unknown"); 983 984 ni->ni_table = NULL; /* NB: pedantic */ 985 ni->ni_ic = ic; 986 } else { 987 /* XXX msg */ 988 ic->ic_stats.is_rx_nodealloc++; 989 } 990 return ni; 991} 992 993struct ieee80211_node * 994ieee80211_dup_bss(struct ieee80211_node_table *nt, const u_int8_t *macaddr) 995{ 996 struct ieee80211com *ic = nt->nt_ic; 997 struct ieee80211_node *ni; 998 999 ni = ic->ic_node_alloc(nt); 1000 if (ni != NULL) { 1001 ieee80211_setup_node(nt, ni, macaddr); 1002 /* 1003 * Inherit from ic_bss. 1004 */ 1005 ni->ni_authmode = ic->ic_bss->ni_authmode; 1006 ni->ni_txpower = ic->ic_bss->ni_txpower; 1007 ni->ni_vlan = ic->ic_bss->ni_vlan; /* XXX?? */ 1008 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid); 1009 ieee80211_set_chan(ic, ni, ic->ic_bss->ni_chan); 1010 ni->ni_rsn = ic->ic_bss->ni_rsn; 1011 } else 1012 ic->ic_stats.is_rx_nodealloc++; 1013 return ni; 1014} 1015 1016static struct ieee80211_node * 1017#ifdef IEEE80211_DEBUG_REFCNT 1018_ieee80211_find_node_debug(struct ieee80211_node_table *nt, 1019 const u_int8_t *macaddr, const char *func, int line) 1020#else 1021_ieee80211_find_node(struct ieee80211_node_table *nt, 1022 const u_int8_t *macaddr) 1023#endif 1024{ 1025 struct ieee80211_node *ni; 1026 int hash; 1027 1028 IEEE80211_NODE_LOCK_ASSERT(nt); 1029 1030 hash = IEEE80211_NODE_HASH(macaddr); 1031 LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) { 1032 if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) { 1033 ieee80211_ref_node(ni); /* mark referenced */ 1034#ifdef IEEE80211_DEBUG_REFCNT 1035 IEEE80211_DPRINTF(nt->nt_ic, IEEE80211_MSG_NODE, 1036 "%s (%s:%u) %p<%s> refcnt %d\n", __func__, 1037 func, line, 1038 ni, ether_sprintf(ni->ni_macaddr), 1039 ieee80211_node_refcnt(ni)); 1040#endif 1041 return ni; 1042 } 1043 } 1044 return NULL; 1045} 1046#ifdef IEEE80211_DEBUG_REFCNT 1047#define _ieee80211_find_node(nt, mac) \ 1048 _ieee80211_find_node_debug(nt, mac, func, line) 1049#endif 1050 1051struct ieee80211_node * 1052#ifdef IEEE80211_DEBUG_REFCNT 1053ieee80211_find_node_debug(struct ieee80211_node_table *nt, 1054 const u_int8_t *macaddr, const char *func, int line) 1055#else 1056ieee80211_find_node(struct ieee80211_node_table *nt, const u_int8_t *macaddr) 1057#endif 1058{ 1059 struct ieee80211_node *ni; 1060 1061 IEEE80211_NODE_LOCK(nt); 1062 ni = _ieee80211_find_node(nt, macaddr); 1063 IEEE80211_NODE_UNLOCK(nt); 1064 return ni; 1065} 1066 1067/* 1068 * Fake up a node; this handles node discovery in adhoc mode. 1069 * Note that for the driver's benefit we we treat this like 1070 * an association so the driver has an opportunity to setup 1071 * it's private state. 1072 */ 1073struct ieee80211_node * 1074ieee80211_fakeup_adhoc_node(struct ieee80211_node_table *nt, 1075 const u_int8_t macaddr[IEEE80211_ADDR_LEN]) 1076{ 1077 struct ieee80211com *ic = nt->nt_ic; 1078 struct ieee80211_node *ni; 1079 1080 ni = ieee80211_dup_bss(nt, macaddr); 1081 if (ni != NULL) { 1082 /* XXX no rate negotiation; just dup */ 1083 ni->ni_rates = ic->ic_bss->ni_rates; 1084 if (ic->ic_newassoc != NULL) 1085 ic->ic_newassoc(ni, 1); 1086 /* XXX not right for 802.1x/WPA */ 1087 ieee80211_node_authorize(ni); 1088 } 1089 return ni; 1090} 1091 1092#ifdef IEEE80211_DEBUG 1093static void 1094dump_probe_beacon(u_int8_t subtype, int isnew, 1095 const u_int8_t mac[IEEE80211_ADDR_LEN], 1096 const struct ieee80211_scanparams *sp) 1097{ 1098 1099 printf("[%s] %s%s on chan %u (bss chan %u) ", 1100 ether_sprintf(mac), isnew ? "new " : "", 1101 ieee80211_mgt_subtype_name[subtype >> IEEE80211_FC0_SUBTYPE_SHIFT], 1102 sp->chan, sp->bchan); 1103 ieee80211_print_essid(sp->ssid + 2, sp->ssid[1]); 1104 printf("\n"); 1105 1106 if (isnew) { 1107 printf("[%s] caps 0x%x bintval %u erp 0x%x", 1108 ether_sprintf(mac), sp->capinfo, sp->bintval, sp->erp); 1109 if (sp->country != NULL) { 1110#ifdef __FreeBSD__ 1111 printf(" country info %*D", 1112 sp->country[1], sp->country+2, " "); 1113#else 1114 int i; 1115 printf(" country info"); 1116 for (i = 0; i < sp->country[1]; i++) 1117 printf(" %02x", sp->country[i+2]); 1118#endif 1119 } 1120 printf("\n"); 1121 } 1122} 1123#endif /* IEEE80211_DEBUG */ 1124 1125static void 1126saveie(u_int8_t **iep, const u_int8_t *ie) 1127{ 1128 1129 if (ie == NULL) 1130 *iep = NULL; 1131 else 1132 ieee80211_saveie(iep, ie); 1133} 1134 1135/* 1136 * Process a beacon or probe response frame. 1137 */ 1138void 1139ieee80211_add_scan(struct ieee80211com *ic, 1140 const struct ieee80211_scanparams *sp, 1141 const struct ieee80211_frame *wh, 1142 int subtype, int rssi, int rstamp) 1143{ 1144#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP) 1145 struct ieee80211_node_table *nt = &ic->ic_scan; 1146 struct ieee80211_node *ni; 1147 int newnode = 0; 1148 1149 ni = ieee80211_find_node(nt, wh->i_addr2); 1150 if (ni == NULL) { 1151 /* 1152 * Create a new entry. 1153 */ 1154 ni = ic->ic_node_alloc(nt); 1155 if (ni == NULL) { 1156 ic->ic_stats.is_rx_nodealloc++; 1157 return; 1158 } 1159 ieee80211_setup_node(nt, ni, wh->i_addr2); 1160 /* 1161 * XXX inherit from ic_bss. 1162 */ 1163 ni->ni_authmode = ic->ic_bss->ni_authmode; 1164 ni->ni_txpower = ic->ic_bss->ni_txpower; 1165 ni->ni_vlan = ic->ic_bss->ni_vlan; /* XXX?? */ 1166 ieee80211_set_chan(ic, ni, ic->ic_curchan); 1167 ni->ni_rsn = ic->ic_bss->ni_rsn; 1168 newnode = 1; 1169 } 1170#ifdef IEEE80211_DEBUG 1171 if (ieee80211_msg_scan(ic) && (ic->ic_flags & IEEE80211_F_SCAN)) 1172 dump_probe_beacon(subtype, newnode, wh->i_addr2, sp); 1173#endif 1174 /* XXX ap beaconing multiple ssid w/ same bssid */ 1175 if (sp->ssid[1] != 0 && 1176 (ISPROBE(subtype) || ni->ni_esslen == 0)) { 1177 ni->ni_esslen = sp->ssid[1]; 1178 memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); 1179 memcpy(ni->ni_essid, sp->ssid + 2, sp->ssid[1]); 1180 } 1181 ni->ni_scangen = ic->ic_scan.nt_scangen; 1182 IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); 1183 ni->ni_rssi = rssi; 1184 ni->ni_rstamp = rstamp; 1185 memcpy(ni->ni_tstamp.data, sp->tstamp, sizeof(ni->ni_tstamp)); 1186 ni->ni_intval = sp->bintval; 1187 ni->ni_capinfo = sp->capinfo; 1188 ni->ni_chan = &ic->ic_channels[sp->chan]; 1189 ni->ni_fhdwell = sp->fhdwell; 1190 ni->ni_fhindex = sp->fhindex; 1191 ni->ni_erp = sp->erp; 1192 if (sp->tim != NULL) { 1193 struct ieee80211_tim_ie *ie = 1194 (struct ieee80211_tim_ie *) sp->tim; 1195 1196 ni->ni_dtim_count = ie->tim_count; 1197 ni->ni_dtim_period = ie->tim_period; 1198 } 1199 /* 1200 * Record the byte offset from the mac header to 1201 * the start of the TIM information element for 1202 * use by hardware and/or to speedup software 1203 * processing of beacon frames. 1204 */ 1205 ni->ni_timoff = sp->timoff; 1206 /* 1207 * Record optional information elements that might be 1208 * used by applications or drivers. 1209 */ 1210 saveie(&ni->ni_wme_ie, sp->wme); 1211 saveie(&ni->ni_wpa_ie, sp->wpa); 1212 1213 /* NB: must be after ni_chan is setup */ 1214 ieee80211_setup_rates(ni, sp->rates, sp->xrates, IEEE80211_F_DOSORT); 1215 1216 if (!newnode) 1217 ieee80211_free_node(ni); 1218#undef ISPROBE 1219} 1220 1221/* 1222 * Do node discovery in adhoc mode on receipt of a beacon 1223 * or probe response frame. Note that for the driver's 1224 * benefit we we treat this like an association so the 1225 * driver has an opportunity to setup it's private state. 1226 */ 1227struct ieee80211_node * 1228ieee80211_add_neighbor(struct ieee80211com *ic, 1229 const struct ieee80211_frame *wh, 1230 const struct ieee80211_scanparams *sp) 1231{ 1232 struct ieee80211_node *ni; 1233 1234 ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);/* XXX alloc_node? */ 1235 if (ni != NULL) { 1236 ni->ni_esslen = sp->ssid[1]; 1237 memcpy(ni->ni_essid, sp->ssid + 2, sp->ssid[1]); 1238 IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); 1239 memcpy(ni->ni_tstamp.data, sp->tstamp, sizeof(ni->ni_tstamp)); 1240 ni->ni_intval = sp->bintval; 1241 ni->ni_capinfo = sp->capinfo; 1242 ni->ni_chan = ic->ic_bss->ni_chan; 1243 ni->ni_fhdwell = sp->fhdwell; 1244 ni->ni_fhindex = sp->fhindex; 1245 ni->ni_erp = sp->erp; 1246 ni->ni_timoff = sp->timoff; 1247 if (sp->wme != NULL) 1248 ieee80211_saveie(&ni->ni_wme_ie, sp->wme); 1249 if (sp->wpa != NULL) 1250 ieee80211_saveie(&ni->ni_wpa_ie, sp->wpa); 1251 1252 /* NB: must be after ni_chan is setup */ 1253 ieee80211_setup_rates(ni, sp->rates, sp->xrates, IEEE80211_F_DOSORT); 1254 1255 if (ic->ic_newassoc != NULL) 1256 ic->ic_newassoc(ni, 1); 1257 /* XXX not right for 802.1x/WPA */ 1258 ieee80211_node_authorize(ni); 1259 } 1260 return ni; 1261} 1262 1263#define IS_CTL(wh) \ 1264 ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) 1265#define IS_PSPOLL(wh) \ 1266 ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PS_POLL) 1267/* 1268 * Locate the node for sender, track state, and then pass the 1269 * (referenced) node up to the 802.11 layer for its use. We 1270 * are required to pass some node so we fall back to ic_bss 1271 * when this frame is from an unknown sender. The 802.11 layer 1272 * knows this means the sender wasn't in the node table and 1273 * acts accordingly. 1274 */ 1275struct ieee80211_node * 1276#ifdef IEEE80211_DEBUG_REFCNT 1277ieee80211_find_rxnode_debug(struct ieee80211com *ic, 1278 const struct ieee80211_frame_min *wh, const char *func, int line) 1279#else 1280ieee80211_find_rxnode(struct ieee80211com *ic, 1281 const struct ieee80211_frame_min *wh) 1282#endif 1283{ 1284 struct ieee80211_node_table *nt; 1285 struct ieee80211_node *ni; 1286 1287 /* XXX may want scanned nodes in the neighbor table for adhoc */ 1288 if (ic->ic_opmode == IEEE80211_M_STA || 1289 ic->ic_opmode == IEEE80211_M_MONITOR || 1290 (ic->ic_flags & IEEE80211_F_SCAN)) 1291 nt = &ic->ic_scan; 1292 else 1293 nt = &ic->ic_sta; 1294 /* XXX check ic_bss first in station mode */ 1295 /* XXX 4-address frames? */ 1296 IEEE80211_NODE_LOCK(nt); 1297 if (IS_CTL(wh) && !IS_PSPOLL(wh) /*&& !IS_RTS(ah)*/) 1298 ni = _ieee80211_find_node(nt, wh->i_addr1); 1299 else 1300 ni = _ieee80211_find_node(nt, wh->i_addr2); 1301 if (ni == NULL) 1302 ni = ieee80211_ref_node(ic->ic_bss); 1303 IEEE80211_NODE_UNLOCK(nt); 1304 1305 return ni; 1306} 1307 1308/* 1309 * Like ieee80211_find_rxnode but use the supplied h/w 1310 * key index as a hint to locate the node in the key 1311 * mapping table. If an entry is present at the key 1312 * index we return it; otherwise do a normal lookup and 1313 * update the mapping table if the station has a unicast 1314 * key assigned to it. 1315 */ 1316struct ieee80211_node * 1317#ifdef IEEE80211_DEBUG_REFCNT 1318ieee80211_find_rxnode_withkey_debug(struct ieee80211com *ic, 1319 const struct ieee80211_frame_min *wh, ieee80211_keyix keyix, 1320 const char *func, int line) 1321#else 1322ieee80211_find_rxnode_withkey(struct ieee80211com *ic, 1323 const struct ieee80211_frame_min *wh, ieee80211_keyix keyix) 1324#endif 1325{ 1326 struct ieee80211_node_table *nt; 1327 struct ieee80211_node *ni; 1328 1329 if (ic->ic_opmode == IEEE80211_M_STA || 1330 ic->ic_opmode == IEEE80211_M_MONITOR || 1331 (ic->ic_flags & IEEE80211_F_SCAN)) 1332 nt = &ic->ic_scan; 1333 else 1334 nt = &ic->ic_sta; 1335 IEEE80211_NODE_LOCK(nt); 1336 if (nt->nt_keyixmap != NULL && keyix < nt->nt_keyixmax) 1337 ni = nt->nt_keyixmap[keyix]; 1338 else 1339 ni = NULL; 1340 if (ni == NULL) { 1341 if (IS_CTL(wh) && !IS_PSPOLL(wh) /*&& !IS_RTS(ah)*/) 1342 ni = _ieee80211_find_node(nt, wh->i_addr1); 1343 else 1344 ni = _ieee80211_find_node(nt, wh->i_addr2); 1345 if (ni == NULL) 1346 ni = ieee80211_ref_node(ic->ic_bss); 1347 if (nt->nt_keyixmap != NULL) { 1348 /* 1349 * If the station has a unicast key cache slot 1350 * assigned update the key->node mapping table. 1351 */ 1352 keyix = ni->ni_ucastkey.wk_rxkeyix; 1353 /* XXX can keyixmap[keyix] != NULL? */ 1354 if (keyix < nt->nt_keyixmax && 1355 nt->nt_keyixmap[keyix] == NULL) { 1356 IEEE80211_DPRINTF(ni->ni_ic, IEEE80211_MSG_NODE, 1357 "%s: add key map entry %p<%s> refcnt %d\n", 1358 __func__, ni, ether_sprintf(ni->ni_macaddr), 1359 ieee80211_node_refcnt(ni)+1); 1360 nt->nt_keyixmap[keyix] = ieee80211_ref_node(ni); 1361 } 1362 } 1363 } else { 1364 ieee80211_ref_node(ni); 1365 } 1366 IEEE80211_NODE_UNLOCK(nt); 1367 1368 return ni; 1369} 1370#undef IS_PSPOLL 1371#undef IS_CTL 1372 1373/* 1374 * Return a reference to the appropriate node for sending 1375 * a data frame. This handles node discovery in adhoc networks. 1376 */ 1377struct ieee80211_node * 1378#ifdef IEEE80211_DEBUG_REFCNT 1379ieee80211_find_txnode_debug(struct ieee80211com *ic, const u_int8_t *macaddr, 1380 const char *func, int line) 1381#else 1382ieee80211_find_txnode(struct ieee80211com *ic, const u_int8_t *macaddr) 1383#endif 1384{ 1385 struct ieee80211_node_table *nt = &ic->ic_sta; 1386 struct ieee80211_node *ni; 1387 1388 /* 1389 * The destination address should be in the node table 1390 * unless this is a multicast/broadcast frame. We can 1391 * also optimize station mode operation, all frames go 1392 * to the bss node. 1393 */ 1394 /* XXX can't hold lock across dup_bss 'cuz of recursive locking */ 1395 IEEE80211_NODE_LOCK(nt); 1396 if (ic->ic_opmode == IEEE80211_M_STA || IEEE80211_IS_MULTICAST(macaddr)) 1397 ni = ieee80211_ref_node(ic->ic_bss); 1398 else 1399 ni = _ieee80211_find_node(nt, macaddr); 1400 IEEE80211_NODE_UNLOCK(nt); 1401 1402 if (ni == NULL) { 1403 if (ic->ic_opmode == IEEE80211_M_IBSS || 1404 ic->ic_opmode == IEEE80211_M_AHDEMO) { 1405 /* 1406 * In adhoc mode cons up a node for the destination. 1407 * Note that we need an additional reference for the 1408 * caller to be consistent with _ieee80211_find_node. 1409 */ 1410 ni = ieee80211_fakeup_adhoc_node(nt, macaddr); 1411 if (ni != NULL) 1412 (void) ieee80211_ref_node(ni); 1413 } else { 1414 IEEE80211_DPRINTF(ic, IEEE80211_MSG_OUTPUT, 1415 "[%s] no node, discard frame (%s)\n", 1416 ether_sprintf(macaddr), __func__); 1417 ic->ic_stats.is_tx_nonode++; 1418 } 1419 } 1420 return ni; 1421} 1422 1423/* 1424 * Like find but search based on the channel too. 1425 */ 1426struct ieee80211_node * 1427#ifdef IEEE80211_DEBUG_REFCNT 1428ieee80211_find_node_with_channel_debug(struct ieee80211_node_table *nt, 1429 const u_int8_t *macaddr, struct ieee80211_channel *chan, 1430 const char *func, int line) 1431#else 1432ieee80211_find_node_with_channel(struct ieee80211_node_table *nt, 1433 const u_int8_t *macaddr, struct ieee80211_channel *chan) 1434#endif 1435{ 1436 struct ieee80211_node *ni; 1437 int hash; 1438 1439 hash = IEEE80211_NODE_HASH(macaddr); 1440 IEEE80211_NODE_LOCK(nt); 1441 LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) { 1442 if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr) && 1443 ni->ni_chan == chan) { 1444 ieee80211_ref_node(ni); /* mark referenced */ 1445 IEEE80211_DPRINTF(nt->nt_ic, IEEE80211_MSG_NODE, 1446#ifdef IEEE80211_DEBUG_REFCNT 1447 "%s (%s:%u) %p<%s> refcnt %d\n", __func__, 1448 func, line, 1449#else 1450 "%s %p<%s> refcnt %d\n", __func__, 1451#endif 1452 ni, ether_sprintf(ni->ni_macaddr), 1453 ieee80211_node_refcnt(ni)); 1454 break; 1455 } 1456 } 1457 IEEE80211_NODE_UNLOCK(nt); 1458 return ni; 1459} 1460 1461/* 1462 * Like find but search based on the ssid too. 1463 */ 1464struct ieee80211_node * 1465#ifdef IEEE80211_DEBUG_REFCNT 1466ieee80211_find_node_with_ssid_debug(struct ieee80211_node_table *nt, 1467 const u_int8_t *macaddr, u_int ssidlen, const u_int8_t *ssid, 1468 const char *func, int line) 1469#else 1470ieee80211_find_node_with_ssid(struct ieee80211_node_table *nt, 1471 const u_int8_t *macaddr, u_int ssidlen, const u_int8_t *ssid) 1472#endif 1473{ 1474#define MATCH_SSID(ni, ssid, ssidlen) \ 1475 (ni->ni_esslen == ssidlen && memcmp(ni->ni_essid, ssid, ssidlen) == 0) 1476 static const u_int8_t zeromac[IEEE80211_ADDR_LEN]; 1477 struct ieee80211com *ic = nt->nt_ic; 1478 struct ieee80211_node *ni; 1479 int hash; 1480 1481 IEEE80211_NODE_LOCK(nt); 1482 /* 1483 * A mac address that is all zero means match only the ssid; 1484 * otherwise we must match both. 1485 */ 1486 if (IEEE80211_ADDR_EQ(macaddr, zeromac)) { 1487 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { 1488 if (MATCH_SSID(ni, ssid, ssidlen)) 1489 break; 1490 } 1491 } else { 1492 hash = IEEE80211_NODE_HASH(macaddr); 1493 LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) { 1494 if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr) && 1495 MATCH_SSID(ni, ssid, ssidlen)) 1496 break; 1497 } 1498 } 1499 if (ni != NULL) { 1500 ieee80211_ref_node(ni); /* mark referenced */ 1501 IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE, 1502#ifdef IEEE80211_DEBUG_REFCNT 1503 "%s (%s:%u) %p<%s> refcnt %d\n", __func__, 1504 func, line, 1505#else 1506 "%s %p<%s> refcnt %d\n", __func__, 1507#endif 1508 ni, ether_sprintf(ni->ni_macaddr), 1509 ieee80211_node_refcnt(ni)); 1510 } 1511 IEEE80211_NODE_UNLOCK(nt); 1512 return ni; 1513#undef MATCH_SSID 1514} 1515 1516static void 1517_ieee80211_free_node(struct ieee80211_node *ni) 1518{ 1519 struct ieee80211com *ic = ni->ni_ic; 1520 struct ieee80211_node_table *nt = ni->ni_table; 1521 1522 IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE, 1523 "%s %p<%s> in %s table\n", __func__, ni, 1524 ether_sprintf(ni->ni_macaddr), 1525 nt != NULL ? nt->nt_name : "<gone>"); 1526 1527 IEEE80211_AID_CLR(ni->ni_associd, ic->ic_aid_bitmap); 1528 if (nt != NULL) { 1529 TAILQ_REMOVE(&nt->nt_node, ni, ni_list); 1530 LIST_REMOVE(ni, ni_hash); 1531 } 1532 ic->ic_node_free(ni); 1533} 1534 1535void 1536#ifdef IEEE80211_DEBUG_REFCNT 1537ieee80211_free_node_debug(struct ieee80211_node *ni, const char *func, int line) 1538#else 1539ieee80211_free_node(struct ieee80211_node *ni) 1540#endif 1541{ 1542 struct ieee80211_node_table *nt = ni->ni_table; 1543 1544#ifdef IEEE80211_DEBUG_REFCNT 1545 IEEE80211_DPRINTF(ni->ni_ic, IEEE80211_MSG_NODE, 1546 "%s (%s:%u) %p<%s> refcnt %d\n", __func__, func, line, ni, 1547 ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)-1); 1548#endif 1549 if (nt != NULL) { 1550 IEEE80211_NODE_LOCK(nt); 1551 if (ieee80211_node_dectestref(ni)) { 1552 /* 1553 * Last reference, reclaim state. 1554 */ 1555 _ieee80211_free_node(ni); 1556 } else if (ieee80211_node_refcnt(ni) == 1 && 1557 nt->nt_keyixmap != NULL) { 1558 ieee80211_keyix keyix; 1559 /* 1560 * Check for a last reference in the key mapping table. 1561 */ 1562 keyix = ni->ni_ucastkey.wk_rxkeyix; 1563 if (keyix < nt->nt_keyixmax && 1564 nt->nt_keyixmap[keyix] == ni) { 1565 IEEE80211_DPRINTF(ni->ni_ic, IEEE80211_MSG_NODE, 1566 "%s: %p<%s> clear key map entry", __func__, 1567 ni, ether_sprintf(ni->ni_macaddr)); 1568 nt->nt_keyixmap[keyix] = NULL; 1569 ieee80211_node_decref(ni); /* XXX needed? */ 1570 _ieee80211_free_node(ni); 1571 } 1572 } 1573 IEEE80211_NODE_UNLOCK(nt); 1574 } else { 1575 if (ieee80211_node_dectestref(ni)) 1576 _ieee80211_free_node(ni); 1577 } 1578} 1579 1580/* 1581 * Reclaim a unicast key and clear any key cache state. 1582 */ 1583int 1584ieee80211_node_delucastkey(struct ieee80211_node *ni) 1585{ 1586 struct ieee80211com *ic = ni->ni_ic; 1587 struct ieee80211_node_table *nt = &ic->ic_sta; 1588 struct ieee80211_node *nikey; 1589 ieee80211_keyix keyix; 1590 int isowned, status; 1591 1592 /* 1593 * NB: We must beware of LOR here; deleting the key 1594 * can cause the crypto layer to block traffic updates 1595 * which can generate a LOR against the node table lock; 1596 * grab it here and stash the key index for our use below. 1597 * 1598 * Must also beware of recursion on the node table lock. 1599 * When called from node_cleanup we may already have 1600 * the node table lock held. Unfortunately there's no 1601 * way to separate out this path so we must do this 1602 * conditionally. 1603 */ 1604 isowned = IEEE80211_NODE_IS_LOCKED(nt); 1605 if (!isowned) 1606 IEEE80211_NODE_LOCK(nt); 1607 keyix = ni->ni_ucastkey.wk_rxkeyix; 1608 status = ieee80211_crypto_delkey(ic, &ni->ni_ucastkey); 1609 if (nt->nt_keyixmap != NULL && keyix < nt->nt_keyixmax) { 1610 nikey = nt->nt_keyixmap[keyix]; 1611 nt->nt_keyixmap[keyix] = NULL;; 1612 } else 1613 nikey = NULL; 1614 if (!isowned) 1615 IEEE80211_NODE_UNLOCK(&ic->ic_sta); 1616 1617 if (nikey != NULL) { 1618 KASSERT(nikey == ni, 1619 ("key map out of sync, ni %p nikey %p", ni, nikey)); 1620 IEEE80211_DPRINTF(ni->ni_ic, IEEE80211_MSG_NODE, 1621 "%s: delete key map entry %p<%s> refcnt %d\n", 1622 __func__, ni, ether_sprintf(ni->ni_macaddr), 1623 ieee80211_node_refcnt(ni)-1); 1624 ieee80211_free_node(ni); 1625 } 1626 return status; 1627} 1628 1629/* 1630 * Reclaim a node. If this is the last reference count then 1631 * do the normal free work. Otherwise remove it from the node 1632 * table and mark it gone by clearing the back-reference. 1633 */ 1634static void 1635node_reclaim(struct ieee80211_node_table *nt, struct ieee80211_node *ni) 1636{ 1637 ieee80211_keyix keyix; 1638 1639 IEEE80211_NODE_LOCK_ASSERT(nt); 1640 1641 IEEE80211_DPRINTF(ni->ni_ic, IEEE80211_MSG_NODE, 1642 "%s: remove %p<%s> from %s table, refcnt %d\n", 1643 __func__, ni, ether_sprintf(ni->ni_macaddr), 1644 nt->nt_name, ieee80211_node_refcnt(ni)-1); 1645 /* 1646 * Clear any entry in the unicast key mapping table. 1647 * We need to do it here so rx lookups don't find it 1648 * in the mapping table even if it's not in the hash 1649 * table. We cannot depend on the mapping table entry 1650 * being cleared because the node may not be free'd. 1651 */ 1652 keyix = ni->ni_ucastkey.wk_rxkeyix; 1653 if (nt->nt_keyixmap != NULL && keyix < nt->nt_keyixmax && 1654 nt->nt_keyixmap[keyix] == ni) { 1655 IEEE80211_DPRINTF(ni->ni_ic, IEEE80211_MSG_NODE, 1656 "%s: %p<%s> clear key map entry\n", 1657 __func__, ni, ether_sprintf(ni->ni_macaddr)); 1658 nt->nt_keyixmap[keyix] = NULL; 1659 ieee80211_node_decref(ni); /* NB: don't need free */ 1660 } 1661 if (!ieee80211_node_dectestref(ni)) { 1662 /* 1663 * Other references are present, just remove the 1664 * node from the table so it cannot be found. When 1665 * the references are dropped storage will be 1666 * reclaimed. 1667 */ 1668 TAILQ_REMOVE(&nt->nt_node, ni, ni_list); 1669 LIST_REMOVE(ni, ni_hash); 1670 ni->ni_table = NULL; /* clear reference */ 1671 } else 1672 _ieee80211_free_node(ni); 1673} 1674 1675static void 1676ieee80211_free_allnodes_locked(struct ieee80211_node_table *nt) 1677{ 1678 struct ieee80211com *ic = nt->nt_ic; 1679 struct ieee80211_node *ni; 1680 1681 IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE, 1682 "%s: free all nodes in %s table\n", __func__, nt->nt_name); 1683 1684 while ((ni = TAILQ_FIRST(&nt->nt_node)) != NULL) { 1685 if (ni->ni_associd != 0) { 1686 if (ic->ic_auth->ia_node_leave != NULL) 1687 ic->ic_auth->ia_node_leave(ic, ni); 1688 IEEE80211_AID_CLR(ni->ni_associd, ic->ic_aid_bitmap); 1689 } 1690 node_reclaim(nt, ni); 1691 } 1692 ieee80211_reset_erp(ic); 1693} 1694 1695static void 1696ieee80211_free_allnodes(struct ieee80211_node_table *nt) 1697{ 1698 1699 IEEE80211_NODE_LOCK(nt); 1700 ieee80211_free_allnodes_locked(nt); 1701 IEEE80211_NODE_UNLOCK(nt); 1702} 1703 1704/* 1705 * Timeout entries in the scan cache. 1706 */ 1707static void 1708ieee80211_timeout_scan_candidates(struct ieee80211_node_table *nt) 1709{ 1710 struct ieee80211com *ic = nt->nt_ic; 1711 struct ieee80211_node *ni, *tni; 1712 1713 IEEE80211_NODE_LOCK(nt); 1714 ni = ic->ic_bss; 1715 /* XXX belongs elsewhere */ 1716 if (ni->ni_rxfrag[0] != NULL && ticks > ni->ni_rxfragstamp + hz) { 1717 m_freem(ni->ni_rxfrag[0]); 1718 ni->ni_rxfrag[0] = NULL; 1719 } 1720 TAILQ_FOREACH_SAFE(ni, &nt->nt_node, ni_list, tni) { 1721 if (ni->ni_inact && --ni->ni_inact == 0) { 1722 IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE, 1723 "[%s] scan candidate purged from cache " 1724 "(refcnt %u)\n", ether_sprintf(ni->ni_macaddr), 1725 ieee80211_node_refcnt(ni)); 1726 node_reclaim(nt, ni); 1727 } 1728 } 1729 IEEE80211_NODE_UNLOCK(nt); 1730 1731 nt->nt_inact_timer = IEEE80211_INACT_WAIT; 1732} 1733 1734/* 1735 * Timeout inactive stations and do related housekeeping. 1736 * Note that we cannot hold the node lock while sending a 1737 * frame as this would lead to a LOR. Instead we use a 1738 * generation number to mark nodes that we've scanned and 1739 * drop the lock and restart a scan if we have to time out 1740 * a node. Since we are single-threaded by virtue of 1741 * controlling the inactivity timer we can be sure this will 1742 * process each node only once. 1743 */ 1744static void 1745ieee80211_timeout_stations(struct ieee80211_node_table *nt) 1746{ 1747 struct ieee80211com *ic = nt->nt_ic; 1748 struct ieee80211_node *ni; 1749 u_int gen; 1750 int isadhoc; 1751 1752 isadhoc = (ic->ic_opmode == IEEE80211_M_IBSS || 1753 ic->ic_opmode == IEEE80211_M_AHDEMO); 1754 IEEE80211_SCAN_LOCK(nt); 1755 gen = nt->nt_scangen++; 1756 IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE, 1757 "%s: %s scangen %u\n", __func__, nt->nt_name, gen); 1758restart: 1759 IEEE80211_NODE_LOCK(nt); 1760 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { 1761 if (ni->ni_scangen == gen) /* previously handled */ 1762 continue; 1763 ni->ni_scangen = gen; 1764 /* 1765 * Ignore entries for which have yet to receive an 1766 * authentication frame. These are transient and 1767 * will be reclaimed when the last reference to them 1768 * goes away (when frame xmits complete). 1769 */ 1770 if (ic->ic_opmode == IEEE80211_M_HOSTAP && 1771 (ni->ni_flags & IEEE80211_NODE_AREF) == 0) 1772 continue; 1773 /* 1774 * Free fragment if not needed anymore 1775 * (last fragment older than 1s). 1776 * XXX doesn't belong here 1777 */ 1778 if (ni->ni_rxfrag[0] != NULL && 1779 ticks > ni->ni_rxfragstamp + hz) { 1780 m_freem(ni->ni_rxfrag[0]); 1781 ni->ni_rxfrag[0] = NULL; 1782 } 1783 /* 1784 * Special case ourself; we may be idle for extended periods 1785 * of time and regardless reclaiming our state is wrong. 1786 */ 1787 if (ni == ic->ic_bss) 1788 continue; 1789 ni->ni_inact--; 1790 if (ni->ni_associd != 0 || isadhoc) { 1791 /* 1792 * Age frames on the power save queue. The 1793 * aging interval is 4 times the listen 1794 * interval specified by the station. This 1795 * number is factored into the age calculations 1796 * when the frame is placed on the queue. We 1797 * store ages as time differences we can check 1798 * and/or adjust only the head of the list. 1799 */ 1800 if (IEEE80211_NODE_SAVEQ_QLEN(ni) != 0) { 1801 struct mbuf *m; 1802 int discard = 0; 1803 1804 IEEE80211_NODE_SAVEQ_LOCK(ni); 1805 while (IF_POLL(&ni->ni_savedq, m) != NULL && 1806 M_AGE_GET(m) < IEEE80211_INACT_WAIT) { 1807IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, "[%s] discard frame, age %u\n", ether_sprintf(ni->ni_macaddr), M_AGE_GET(m));/*XXX*/ 1808 _IEEE80211_NODE_SAVEQ_DEQUEUE_HEAD(ni, m); 1809 m_freem(m); 1810 discard++; 1811 } 1812 if (m != NULL) 1813 M_AGE_SUB(m, IEEE80211_INACT_WAIT); 1814 IEEE80211_NODE_SAVEQ_UNLOCK(ni); 1815 1816 if (discard != 0) { 1817 IEEE80211_DPRINTF(ic, 1818 IEEE80211_MSG_POWER, 1819 "[%s] discard %u frames for age\n", 1820 ether_sprintf(ni->ni_macaddr), 1821 discard); 1822 IEEE80211_NODE_STAT_ADD(ni, 1823 ps_discard, discard); 1824 if (IEEE80211_NODE_SAVEQ_QLEN(ni) == 0) 1825 ic->ic_set_tim(ni, 0); 1826 } 1827 } 1828 /* 1829 * Probe the station before time it out. We 1830 * send a null data frame which may not be 1831 * universally supported by drivers (need it 1832 * for ps-poll support so it should be...). 1833 */ 1834 if (0 < ni->ni_inact && 1835 ni->ni_inact <= ic->ic_inact_probe) { 1836 IEEE80211_NOTE(ic, 1837 IEEE80211_MSG_INACT | IEEE80211_MSG_NODE, 1838 ni, "%s", 1839 "probe station due to inactivity"); 1840 /* 1841 * Grab a reference before unlocking the table 1842 * so the node cannot be reclaimed before we 1843 * send the frame. ieee80211_send_nulldata 1844 * understands we've done this and reclaims the 1845 * ref for us as needed. 1846 */ 1847 ieee80211_ref_node(ni); 1848 IEEE80211_NODE_UNLOCK(nt); 1849 ieee80211_send_nulldata(ni); 1850 /* XXX stat? */ 1851 goto restart; 1852 } 1853 } 1854 if (ni->ni_inact <= 0) { 1855 IEEE80211_NOTE(ic, 1856 IEEE80211_MSG_INACT | IEEE80211_MSG_NODE, ni, 1857 "station timed out due to inactivity " 1858 "(refcnt %u)", ieee80211_node_refcnt(ni)); 1859 /* 1860 * Send a deauthenticate frame and drop the station. 1861 * This is somewhat complicated due to reference counts 1862 * and locking. At this point a station will typically 1863 * have a reference count of 1. ieee80211_node_leave 1864 * will do a "free" of the node which will drop the 1865 * reference count. But in the meantime a reference 1866 * wil be held by the deauth frame. The actual reclaim 1867 * of the node will happen either after the tx is 1868 * completed or by ieee80211_node_leave. 1869 * 1870 * Separately we must drop the node lock before sending 1871 * in case the driver takes a lock, as this will result 1872 * in LOR between the node lock and the driver lock. 1873 */ 1874 IEEE80211_NODE_UNLOCK(nt); 1875 if (ni->ni_associd != 0) { 1876 IEEE80211_SEND_MGMT(ic, ni, 1877 IEEE80211_FC0_SUBTYPE_DEAUTH, 1878 IEEE80211_REASON_AUTH_EXPIRE); 1879 } 1880 ieee80211_node_leave(ic, ni); 1881 ic->ic_stats.is_node_timeout++; 1882 goto restart; 1883 } 1884 } 1885 IEEE80211_NODE_UNLOCK(nt); 1886 1887 IEEE80211_SCAN_UNLOCK(nt); 1888 1889 nt->nt_inact_timer = IEEE80211_INACT_WAIT; 1890} 1891 1892void 1893ieee80211_iterate_nodes(struct ieee80211_node_table *nt, ieee80211_iter_func *f, void *arg) 1894{ 1895 struct ieee80211_node *ni; 1896 u_int gen; 1897 1898 IEEE80211_SCAN_LOCK(nt); 1899 gen = nt->nt_scangen++; 1900restart: 1901 IEEE80211_NODE_LOCK(nt); 1902 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { 1903 if (ni->ni_scangen != gen) { 1904 ni->ni_scangen = gen; 1905 (void) ieee80211_ref_node(ni); 1906 IEEE80211_NODE_UNLOCK(nt); 1907 (*f)(arg, ni); 1908 ieee80211_free_node(ni); 1909 goto restart; 1910 } 1911 } 1912 IEEE80211_NODE_UNLOCK(nt); 1913 1914 IEEE80211_SCAN_UNLOCK(nt); 1915} 1916 1917void 1918ieee80211_dump_node(struct ieee80211_node_table *nt, struct ieee80211_node *ni) 1919{ 1920 printf("0x%p: mac %s refcnt %d\n", ni, 1921 ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)); 1922 printf("\tscangen %u authmode %u flags 0x%x\n", 1923 ni->ni_scangen, ni->ni_authmode, ni->ni_flags); 1924 printf("\tassocid 0x%x txpower %u vlan %u\n", 1925 ni->ni_associd, ni->ni_txpower, ni->ni_vlan); 1926 printf("\ttxseq %u rxseq %u fragno %u rxfragstamp %u\n", 1927 ni->ni_txseqs[0], 1928 ni->ni_rxseqs[0] >> IEEE80211_SEQ_SEQ_SHIFT, 1929 ni->ni_rxseqs[0] & IEEE80211_SEQ_FRAG_MASK, 1930 ni->ni_rxfragstamp); 1931 printf("\trstamp %u rssi %u intval %u capinfo 0x%x\n", 1932 ni->ni_rstamp, ni->ni_rssi, ni->ni_intval, ni->ni_capinfo); 1933 printf("\tbssid %s essid \"%.*s\" channel %u:0x%x\n", 1934 ether_sprintf(ni->ni_bssid), 1935 ni->ni_esslen, ni->ni_essid, 1936 ni->ni_chan->ic_freq, ni->ni_chan->ic_flags); 1937 printf("\tfails %u inact %u txrate %u\n", 1938 ni->ni_fails, ni->ni_inact, ni->ni_txrate); 1939} 1940 1941void 1942ieee80211_dump_nodes(struct ieee80211_node_table *nt) 1943{ 1944 ieee80211_iterate_nodes(nt, 1945 (ieee80211_iter_func *) ieee80211_dump_node, nt); 1946} 1947 1948/* 1949 * Handle a station joining an 11g network. 1950 */ 1951static void 1952ieee80211_node_join_11g(struct ieee80211com *ic, struct ieee80211_node *ni) 1953{ 1954 1955 /* 1956 * Station isn't capable of short slot time. Bump 1957 * the count of long slot time stations and disable 1958 * use of short slot time. Note that the actual switch 1959 * over to long slot time use may not occur until the 1960 * next beacon transmission (per sec. 7.3.1.4 of 11g). 1961 */ 1962 if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) == 0) { 1963 ic->ic_longslotsta++; 1964 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 1965 "[%s] station needs long slot time, count %d\n", 1966 ether_sprintf(ni->ni_macaddr), ic->ic_longslotsta); 1967 /* XXX vap's w/ conflicting needs won't work */ 1968 ieee80211_set_shortslottime(ic, 0); 1969 } 1970 /* 1971 * If the new station is not an ERP station 1972 * then bump the counter and enable protection 1973 * if configured. 1974 */ 1975 if (!ieee80211_iserp_rateset(ic, &ni->ni_rates)) { 1976 ic->ic_nonerpsta++; 1977 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 1978 "[%s] station is !ERP, %d non-ERP stations associated\n", 1979 ether_sprintf(ni->ni_macaddr), ic->ic_nonerpsta); 1980 /* 1981 * If protection is configured, enable it. 1982 */ 1983 if (ic->ic_protmode != IEEE80211_PROT_NONE) { 1984 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 1985 "%s: enable use of protection\n", __func__); 1986 ic->ic_flags |= IEEE80211_F_USEPROT; 1987 } 1988 /* 1989 * If station does not support short preamble 1990 * then we must enable use of Barker preamble. 1991 */ 1992 if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) == 0) { 1993 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 1994 "[%s] station needs long preamble\n", 1995 ether_sprintf(ni->ni_macaddr)); 1996 ic->ic_flags |= IEEE80211_F_USEBARKER; 1997 ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE; 1998 } 1999 } else 2000 ni->ni_flags |= IEEE80211_NODE_ERP; 2001} 2002 2003void 2004ieee80211_node_join(struct ieee80211com *ic, struct ieee80211_node *ni, int resp) 2005{ 2006 int newassoc; 2007 2008 if (ni->ni_associd == 0) { 2009 u_int16_t aid; 2010 2011 /* 2012 * It would be good to search the bitmap 2013 * more efficiently, but this will do for now. 2014 */ 2015 for (aid = 1; aid < ic->ic_max_aid; aid++) { 2016 if (!IEEE80211_AID_ISSET(aid, 2017 ic->ic_aid_bitmap)) 2018 break; 2019 } 2020 if (aid >= ic->ic_max_aid) { 2021 IEEE80211_SEND_MGMT(ic, ni, resp, 2022 IEEE80211_REASON_ASSOC_TOOMANY); 2023 ieee80211_node_leave(ic, ni); 2024 return; 2025 } 2026 ni->ni_associd = aid | 0xc000; 2027 IEEE80211_AID_SET(ni->ni_associd, ic->ic_aid_bitmap); 2028 ic->ic_sta_assoc++; 2029 newassoc = 1; 2030 if (ic->ic_curmode == IEEE80211_MODE_11G || 2031 ic->ic_curmode == IEEE80211_MODE_TURBO_G) 2032 ieee80211_node_join_11g(ic, ni); 2033 } else 2034 newassoc = 0; 2035 2036 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC | IEEE80211_MSG_DEBUG, 2037 "[%s] station %sassociated at aid %d: %s preamble, %s slot time%s%s\n", 2038 ether_sprintf(ni->ni_macaddr), newassoc ? "" : "re", 2039 IEEE80211_NODE_AID(ni), 2040 ic->ic_flags & IEEE80211_F_SHPREAMBLE ? "short" : "long", 2041 ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long", 2042 ic->ic_flags & IEEE80211_F_USEPROT ? ", protection" : "", 2043 ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "" 2044 ); 2045 2046 /* give driver a chance to setup state like ni_txrate */ 2047 if (ic->ic_newassoc != NULL) 2048 ic->ic_newassoc(ni, newassoc); 2049 ni->ni_inact_reload = ic->ic_inact_auth; 2050 ni->ni_inact = ni->ni_inact_reload; 2051 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_SUCCESS); 2052 /* tell the authenticator about new station */ 2053 if (ic->ic_auth->ia_node_join != NULL) 2054 ic->ic_auth->ia_node_join(ic, ni); 2055 ieee80211_notify_node_join(ic, ni, newassoc); 2056} 2057 2058/* 2059 * Handle a station leaving an 11g network. 2060 */ 2061static void 2062ieee80211_node_leave_11g(struct ieee80211com *ic, struct ieee80211_node *ni) 2063{ 2064 2065 KASSERT(IEEE80211_IS_CHAN_ANYG(ni->ni_chan), 2066 ("not in 11g, bss %u:0x%x, curmode %u", ni->ni_chan->ic_freq, 2067 ni->ni_chan->ic_flags, ic->ic_curmode)); 2068 2069 /* 2070 * If a long slot station do the slot time bookkeeping. 2071 */ 2072 if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) == 0) { 2073 KASSERT(ic->ic_longslotsta > 0, 2074 ("bogus long slot station count %d", ic->ic_longslotsta)); 2075 ic->ic_longslotsta--; 2076 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2077 "[%s] long slot time station leaves, count now %d\n", 2078 ether_sprintf(ni->ni_macaddr), ic->ic_longslotsta); 2079 if (ic->ic_longslotsta == 0) { 2080 /* 2081 * Re-enable use of short slot time if supported 2082 * and not operating in IBSS mode (per spec). 2083 */ 2084 if ((ic->ic_caps & IEEE80211_C_SHSLOT) && 2085 ic->ic_opmode != IEEE80211_M_IBSS) { 2086 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2087 "%s: re-enable use of short slot time\n", 2088 __func__); 2089 ieee80211_set_shortslottime(ic, 1); 2090 } 2091 } 2092 } 2093 /* 2094 * If a non-ERP station do the protection-related bookkeeping. 2095 */ 2096 if ((ni->ni_flags & IEEE80211_NODE_ERP) == 0) { 2097 KASSERT(ic->ic_nonerpsta > 0, 2098 ("bogus non-ERP station count %d", ic->ic_nonerpsta)); 2099 ic->ic_nonerpsta--; 2100 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2101 "[%s] non-ERP station leaves, count now %d\n", 2102 ether_sprintf(ni->ni_macaddr), ic->ic_nonerpsta); 2103 if (ic->ic_nonerpsta == 0) { 2104 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2105 "%s: disable use of protection\n", __func__); 2106 ic->ic_flags &= ~IEEE80211_F_USEPROT; 2107 /* XXX verify mode? */ 2108 if (ic->ic_caps & IEEE80211_C_SHPREAMBLE) { 2109 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2110 "%s: re-enable use of short preamble\n", 2111 __func__); 2112 ic->ic_flags |= IEEE80211_F_SHPREAMBLE; 2113 ic->ic_flags &= ~IEEE80211_F_USEBARKER; 2114 } 2115 } 2116 } 2117} 2118 2119/* 2120 * Handle bookkeeping for station deauthentication/disassociation 2121 * when operating as an ap. 2122 */ 2123void 2124ieee80211_node_leave(struct ieee80211com *ic, struct ieee80211_node *ni) 2125{ 2126 struct ieee80211_node_table *nt = ni->ni_table; 2127 2128 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC | IEEE80211_MSG_DEBUG, 2129 "[%s] station with aid %d leaves\n", 2130 ether_sprintf(ni->ni_macaddr), IEEE80211_NODE_AID(ni)); 2131 2132 KASSERT(ic->ic_opmode == IEEE80211_M_HOSTAP || 2133 ic->ic_opmode == IEEE80211_M_IBSS || 2134 ic->ic_opmode == IEEE80211_M_AHDEMO, 2135 ("unexpected operating mode %u", ic->ic_opmode)); 2136 /* 2137 * If node wasn't previously associated all 2138 * we need to do is reclaim the reference. 2139 */ 2140 /* XXX ibss mode bypasses 11g and notification */ 2141 if (ni->ni_associd == 0) 2142 goto done; 2143 /* 2144 * Tell the authenticator the station is leaving. 2145 * Note that we must do this before yanking the 2146 * association id as the authenticator uses the 2147 * associd to locate it's state block. 2148 */ 2149 if (ic->ic_auth->ia_node_leave != NULL) 2150 ic->ic_auth->ia_node_leave(ic, ni); 2151 IEEE80211_AID_CLR(ni->ni_associd, ic->ic_aid_bitmap); 2152 ni->ni_associd = 0; 2153 ic->ic_sta_assoc--; 2154 2155 if (IEEE80211_IS_CHAN_ANYG(ic->ic_bss->ni_chan)) 2156 ieee80211_node_leave_11g(ic, ni); 2157 /* 2158 * Cleanup station state. In particular clear various 2159 * state that might otherwise be reused if the node 2160 * is reused before the reference count goes to zero 2161 * (and memory is reclaimed). 2162 */ 2163 ieee80211_sta_leave(ic, ni); 2164done: 2165 /* 2166 * Remove the node from any table it's recorded in and 2167 * drop the caller's reference. Removal from the table 2168 * is important to insure the node is not reprocessed 2169 * for inactivity. 2170 */ 2171 if (nt != NULL) { 2172 IEEE80211_NODE_LOCK(nt); 2173 node_reclaim(nt, ni); 2174 IEEE80211_NODE_UNLOCK(nt); 2175 } else 2176 ieee80211_free_node(ni); 2177} 2178 2179u_int8_t 2180ieee80211_getrssi(struct ieee80211com *ic) 2181{ 2182#define NZ(x) ((x) == 0 ? 1 : (x)) 2183 struct ieee80211_node_table *nt = &ic->ic_sta; 2184 u_int32_t rssi_samples, rssi_total; 2185 struct ieee80211_node *ni; 2186 2187 rssi_total = 0; 2188 rssi_samples = 0; 2189 switch (ic->ic_opmode) { 2190 case IEEE80211_M_IBSS: /* average of all ibss neighbors */ 2191 /* XXX locking */ 2192 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) 2193 if (ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) { 2194 rssi_samples++; 2195 rssi_total += ic->ic_node_getrssi(ni); 2196 } 2197 break; 2198 case IEEE80211_M_AHDEMO: /* average of all neighbors */ 2199 /* XXX locking */ 2200 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { 2201 rssi_samples++; 2202 rssi_total += ic->ic_node_getrssi(ni); 2203 } 2204 break; 2205 case IEEE80211_M_HOSTAP: /* average of all associated stations */ 2206 /* XXX locking */ 2207 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) 2208 if (IEEE80211_AID(ni->ni_associd) != 0) { 2209 rssi_samples++; 2210 rssi_total += ic->ic_node_getrssi(ni); 2211 } 2212 break; 2213 case IEEE80211_M_MONITOR: /* XXX */ 2214 case IEEE80211_M_STA: /* use stats from associated ap */ 2215 default: 2216 if (ic->ic_bss != NULL) 2217 rssi_total = ic->ic_node_getrssi(ic->ic_bss); 2218 rssi_samples = 1; 2219 break; 2220 } 2221 return rssi_total / NZ(rssi_samples); 2222#undef NZ 2223} 2224 2225/* 2226 * Indicate whether there are frames queued for a station in power-save mode. 2227 */ 2228static void 2229ieee80211_set_tim(struct ieee80211_node *ni, int set) 2230{ 2231 struct ieee80211com *ic = ni->ni_ic; 2232 u_int16_t aid; 2233 2234 KASSERT(ic->ic_opmode == IEEE80211_M_HOSTAP || 2235 ic->ic_opmode == IEEE80211_M_IBSS, 2236 ("operating mode %u", ic->ic_opmode)); 2237 2238 aid = IEEE80211_AID(ni->ni_associd); 2239 KASSERT(aid < ic->ic_max_aid, 2240 ("bogus aid %u, max %u", aid, ic->ic_max_aid)); 2241 2242 IEEE80211_BEACON_LOCK(ic); 2243 if (set != (isset(ic->ic_tim_bitmap, aid) != 0)) { 2244 if (set) { 2245 setbit(ic->ic_tim_bitmap, aid); 2246 ic->ic_ps_pending++; 2247 } else { 2248 clrbit(ic->ic_tim_bitmap, aid); 2249 ic->ic_ps_pending--; 2250 } 2251 ic->ic_flags |= IEEE80211_F_TIMUPDATE; 2252 } 2253 IEEE80211_BEACON_UNLOCK(ic); 2254} 2255 2256/* 2257 * Node table support. 2258 */ 2259 2260static void 2261ieee80211_node_table_init(struct ieee80211com *ic, 2262 struct ieee80211_node_table *nt, 2263 const char *name, int inact, int keyixmax, 2264 void (*timeout)(struct ieee80211_node_table *)) 2265{ 2266 2267 IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE, 2268 "%s %s table, inact %u\n", __func__, name, inact); 2269 2270 nt->nt_ic = ic; 2271 /* XXX need unit */ 2272 IEEE80211_NODE_LOCK_INIT(nt, ic->ic_ifp->if_xname); 2273 IEEE80211_SCAN_LOCK_INIT(nt, ic->ic_ifp->if_xname); 2274 TAILQ_INIT(&nt->nt_node); 2275 nt->nt_name = name; 2276 nt->nt_scangen = 1; 2277 nt->nt_inact_init = inact; 2278 nt->nt_timeout = timeout; 2279 nt->nt_keyixmax = keyixmax; 2280 if (nt->nt_keyixmax > 0) { 2281 MALLOC(nt->nt_keyixmap, struct ieee80211_node **, 2282 keyixmax * sizeof(struct ieee80211_node *), 2283 M_80211_NODE, M_NOWAIT | M_ZERO); 2284 if (nt->nt_keyixmap == NULL) 2285 if_printf(ic->ic_ifp, 2286 "Cannot allocate key index map with %u entries\n", 2287 keyixmax); 2288 } else 2289 nt->nt_keyixmap = NULL; 2290} 2291 2292void 2293ieee80211_node_table_reset(struct ieee80211_node_table *nt) 2294{ 2295 2296 IEEE80211_DPRINTF(nt->nt_ic, IEEE80211_MSG_NODE, 2297 "%s %s table\n", __func__, nt->nt_name); 2298 2299 IEEE80211_NODE_LOCK(nt); 2300 nt->nt_inact_timer = 0; 2301 ieee80211_free_allnodes_locked(nt); 2302 IEEE80211_NODE_UNLOCK(nt); 2303} 2304 2305static void 2306ieee80211_node_table_cleanup(struct ieee80211_node_table *nt) 2307{ 2308 2309 IEEE80211_DPRINTF(nt->nt_ic, IEEE80211_MSG_NODE, 2310 "%s %s table\n", __func__, nt->nt_name); 2311 2312 IEEE80211_NODE_LOCK(nt); 2313 ieee80211_free_allnodes_locked(nt); 2314 if (nt->nt_keyixmap != NULL) { 2315 /* XXX verify all entries are NULL */ 2316 int i; 2317 for (i = 0; i < nt->nt_keyixmax; i++) 2318 if (nt->nt_keyixmap[i] != NULL) 2319 printf("%s: %s[%u] still active\n", __func__, 2320 nt->nt_name, i); 2321 FREE(nt->nt_keyixmap, M_80211_NODE); 2322 nt->nt_keyixmap = NULL; 2323 } 2324 IEEE80211_SCAN_LOCK_DESTROY(nt); 2325 IEEE80211_NODE_LOCK_DESTROY(nt); 2326} 2327