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