This source file includes following definitions.
- ieee80211_node_attach
- ieee80211_alloc_node_helper
- ieee80211_node_lateattach
- ieee80211_node_detach
- ieee80211_reset_scan
- ieee80211_begin_scan
- ieee80211_next_scan
- ieee80211_create_ibss
- ieee80211_match_bss
- ieee80211_end_scan
- ieee80211_get_rate
- ieee80211_node_alloc
- ieee80211_node_cleanup
- ieee80211_node_free
- ieee80211_node_copy
- ieee80211_node_getrssi
- ieee80211_setup_node
- ieee80211_alloc_node
- ieee80211_dup_bss
- ieee80211_find_node
- ieee80211_find_txnode
- ieee80211_needs_rxnode
- ieee80211_find_rxnode
- ieee80211_find_node_for_beacon
- ieee80211_free_node
- ieee80211_release_node
- ieee80211_free_allnodes
- ieee80211_clean_nodes
- ieee80211_iterate_nodes
- ieee80211_iserp_sta
- ieee80211_node_join_11g
- ieee80211_node_join
- ieee80211_node_leave_11g
- ieee80211_node_leave
- ieee80211_set_tim
- ieee80211_node_cmp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 #include "bpfilter.h"
33 #include "bridge.h"
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/mbuf.h>
38 #include <sys/malloc.h>
39 #include <sys/kernel.h>
40 #include <sys/socket.h>
41 #include <sys/sockio.h>
42 #include <sys/endian.h>
43 #include <sys/errno.h>
44 #include <sys/proc.h>
45 #include <sys/sysctl.h>
46 #include <sys/tree.h>
47
48 #include <net/if.h>
49 #include <net/if_dl.h>
50 #include <net/if_media.h>
51 #include <net/if_arp.h>
52 #include <net/if_llc.h>
53
54 #if NBPFILTER > 0
55 #include <net/bpf.h>
56 #endif
57
58 #ifdef INET
59 #include <netinet/in.h>
60 #include <netinet/if_ether.h>
61 #endif
62
63 #if NBRIDGE > 0
64 #include <net/if_bridge.h>
65 #endif
66
67 #include <net80211/ieee80211_var.h>
68
69 #include <dev/rndvar.h>
70
71 struct ieee80211_node *ieee80211_node_alloc(struct ieee80211com *);
72 void ieee80211_node_free(struct ieee80211com *, struct ieee80211_node *);
73 void ieee80211_node_copy(struct ieee80211com *, struct ieee80211_node *,
74 const struct ieee80211_node *);
75 u_int8_t ieee80211_node_getrssi(struct ieee80211com *,
76 const struct ieee80211_node *);
77 void ieee80211_setup_node(struct ieee80211com *, struct ieee80211_node *,
78 const u_int8_t *);
79 void ieee80211_free_node(struct ieee80211com *, struct ieee80211_node *);
80 struct ieee80211_node *ieee80211_alloc_node_helper(struct ieee80211com *);
81 void ieee80211_node_cleanup(struct ieee80211com *, struct ieee80211_node *);
82 void ieee80211_node_join_11g(struct ieee80211com *, struct ieee80211_node *);
83 void ieee80211_node_leave_11g(struct ieee80211com *, struct ieee80211_node *);
84 void ieee80211_set_tim(struct ieee80211com *, int, int);
85
86 #define M_80211_NODE M_DEVBUF
87
88 void
89 ieee80211_node_attach(struct ifnet *ifp)
90 {
91 struct ieee80211com *ic = (void *)ifp;
92 int size;
93
94 RB_INIT(&ic->ic_tree);
95 ic->ic_node_alloc = ieee80211_node_alloc;
96 ic->ic_node_free = ieee80211_node_free;
97 ic->ic_node_copy = ieee80211_node_copy;
98 ic->ic_node_getrssi = ieee80211_node_getrssi;
99 ic->ic_scangen = 1;
100 ic->ic_max_nnodes = ieee80211_cache_size;
101
102 if (ic->ic_max_aid == 0)
103 ic->ic_max_aid = IEEE80211_AID_DEF;
104 else if (ic->ic_max_aid > IEEE80211_AID_MAX)
105 ic->ic_max_aid = IEEE80211_AID_MAX;
106 size = howmany(ic->ic_max_aid, 32) * sizeof(u_int32_t);
107 MALLOC(ic->ic_aid_bitmap, u_int32_t *, size, M_DEVBUF, M_NOWAIT);
108 if (ic->ic_aid_bitmap == NULL) {
109
110 printf("%s: no memory for AID bitmap!\n", __func__);
111 ic->ic_max_aid = 0;
112 } else
113 memset(ic->ic_aid_bitmap, 0, size);
114
115 if (ic->ic_caps & (IEEE80211_C_HOSTAP | IEEE80211_C_IBSS)) {
116 ic->ic_tim_len = howmany(ic->ic_max_aid, 8);
117 MALLOC(ic->ic_tim_bitmap, u_int8_t *, ic->ic_tim_len, M_DEVBUF,
118 M_NOWAIT);
119 if (ic->ic_tim_bitmap == NULL) {
120 printf("%s: no memory for TIM bitmap!\n", __func__);
121 ic->ic_tim_len = 0;
122 } else {
123 memset(ic->ic_tim_bitmap, 0, ic->ic_tim_len);
124 ic->ic_set_tim = ieee80211_set_tim;
125 }
126 }
127 }
128
129 struct ieee80211_node *
130 ieee80211_alloc_node_helper(struct ieee80211com *ic)
131 {
132 struct ieee80211_node *ni;
133 if (ic->ic_nnodes >= ic->ic_max_nnodes)
134 ieee80211_clean_nodes(ic);
135 if (ic->ic_nnodes >= ic->ic_max_nnodes)
136 return NULL;
137 ni = (*ic->ic_node_alloc)(ic);
138 if (ni != NULL)
139 ic->ic_nnodes++;
140 return ni;
141 }
142
143 void
144 ieee80211_node_lateattach(struct ifnet *ifp)
145 {
146 struct ieee80211com *ic = (void *)ifp;
147 struct ieee80211_node *ni;
148
149 ni = ieee80211_alloc_node_helper(ic);
150 if (ni == NULL)
151 panic("unable to setup inital BSS node");
152 ni->ni_chan = IEEE80211_CHAN_ANYC;
153 ic->ic_bss = ieee80211_ref_node(ni);
154 ic->ic_txpower = IEEE80211_TXPOWER_MAX;
155 }
156
157 void
158 ieee80211_node_detach(struct ifnet *ifp)
159 {
160 struct ieee80211com *ic = (void *)ifp;
161
162 if (ic->ic_bss != NULL) {
163 (*ic->ic_node_free)(ic, ic->ic_bss);
164 ic->ic_bss = NULL;
165 }
166 ieee80211_free_allnodes(ic);
167 if (ic->ic_aid_bitmap != NULL)
168 FREE(ic->ic_aid_bitmap, M_DEVBUF);
169 if (ic->ic_tim_bitmap != NULL)
170 FREE(ic->ic_tim_bitmap, M_DEVBUF);
171 }
172
173
174
175
176
177
178
179
180
181 void
182 ieee80211_reset_scan(struct ifnet *ifp)
183 {
184 struct ieee80211com *ic = (void *)ifp;
185
186 memcpy(ic->ic_chan_scan, ic->ic_chan_active,
187 sizeof(ic->ic_chan_active));
188
189 if (ic->ic_bss != NULL && ic->ic_bss->ni_chan == IEEE80211_CHAN_ANYC)
190 ic->ic_bss->ni_chan = &ic->ic_channels[IEEE80211_CHAN_MAX];
191 }
192
193
194
195
196 void
197 ieee80211_begin_scan(struct ifnet *ifp)
198 {
199 struct ieee80211com *ic = (void *)ifp;
200
201 if (ic->ic_scan_lock & IEEE80211_SCAN_LOCKED)
202 return;
203 ic->ic_scan_lock |= IEEE80211_SCAN_LOCKED;
204
205
206
207
208
209 if (ic->ic_opmode != IEEE80211_M_HOSTAP) {
210 ic->ic_flags |= IEEE80211_F_ASCAN;
211 ic->ic_stats.is_scan_active++;
212 } else
213 ic->ic_stats.is_scan_passive++;
214 if (ifp->if_flags & IFF_DEBUG)
215 printf("%s: begin %s scan\n", ifp->if_xname,
216 (ic->ic_flags & IEEE80211_F_ASCAN) ?
217 "active" : "passive");
218
219
220
221
222
223
224
225 ieee80211_free_allnodes(ic);
226
227
228
229
230
231 if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) == IFM_AUTO)
232 ic->ic_curmode = IEEE80211_MODE_AUTO;
233 ieee80211_setmode(ic, ic->ic_curmode);
234
235 ic->ic_scan_count = 0;
236
237
238 ieee80211_next_scan(ifp);
239 }
240
241
242
243
244 void
245 ieee80211_next_scan(struct ifnet *ifp)
246 {
247 struct ieee80211com *ic = (void *)ifp;
248 struct ieee80211_channel *chan;
249
250 chan = ic->ic_bss->ni_chan;
251 for (;;) {
252 if (++chan > &ic->ic_channels[IEEE80211_CHAN_MAX])
253 chan = &ic->ic_channels[0];
254 if (isset(ic->ic_chan_scan, ieee80211_chan2ieee(ic, chan))) {
255
256
257
258
259 if ((ic->ic_flags & IEEE80211_F_ASCAN) == 0 ||
260 (chan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0)
261 break;
262 }
263 if (chan == ic->ic_bss->ni_chan) {
264 ieee80211_end_scan(ifp);
265 return;
266 }
267 }
268 clrbit(ic->ic_chan_scan, ieee80211_chan2ieee(ic, chan));
269 IEEE80211_DPRINTF(("%s: chan %d->%d\n", __func__,
270 ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
271 ieee80211_chan2ieee(ic, chan)));
272 ic->ic_bss->ni_chan = chan;
273 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
274 }
275
276 void
277 ieee80211_create_ibss(struct ieee80211com* ic, struct ieee80211_channel *chan)
278 {
279 struct ieee80211_node *ni;
280 struct ifnet *ifp = &ic->ic_if;
281
282 ni = ic->ic_bss;
283 if (ifp->if_flags & IFF_DEBUG)
284 printf("%s: creating ibss\n", ifp->if_xname);
285 ic->ic_flags |= IEEE80211_F_SIBSS;
286 ni->ni_chan = chan;
287 ni->ni_rates = ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)];
288 IEEE80211_ADDR_COPY(ni->ni_macaddr, ic->ic_myaddr);
289 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_myaddr);
290 if (ic->ic_opmode == IEEE80211_M_IBSS) {
291 if ((ic->ic_flags & IEEE80211_F_DESBSSID) != 0)
292 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_des_bssid);
293 else
294 ni->ni_bssid[0] |= 0x02;
295 }
296 ni->ni_esslen = ic->ic_des_esslen;
297 memcpy(ni->ni_essid, ic->ic_des_essid, ni->ni_esslen);
298 ni->ni_rssi = 0;
299 ni->ni_rstamp = 0;
300 memset(ni->ni_tstamp, 0, sizeof(ni->ni_tstamp));
301 ni->ni_intval = ic->ic_lintval;
302 ni->ni_capinfo = IEEE80211_CAPINFO_IBSS;
303 if (ic->ic_flags & IEEE80211_F_WEPON)
304 ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY;
305 if (ic->ic_phytype == IEEE80211_T_FH) {
306 ni->ni_fhdwell = 200;
307 ni->ni_fhindex = 1;
308 }
309 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
310 }
311
312 int
313 ieee80211_match_bss(struct ieee80211com *ic, struct ieee80211_node *ni)
314 {
315 u_int8_t rate;
316 int fail;
317
318 fail = 0;
319 if (isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, ni->ni_chan)))
320 fail |= 0x01;
321 if (ic->ic_des_chan != IEEE80211_CHAN_ANYC &&
322 ni->ni_chan != ic->ic_des_chan)
323 fail |= 0x01;
324 if (ic->ic_opmode == IEEE80211_M_IBSS) {
325 if ((ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) == 0)
326 fail |= 0x02;
327 } else {
328 if ((ni->ni_capinfo & IEEE80211_CAPINFO_ESS) == 0)
329 fail |= 0x02;
330 }
331 if (ic->ic_flags & IEEE80211_F_WEPON) {
332 if ((ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) == 0)
333 fail |= 0x04;
334 } else {
335
336 if (ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY)
337 fail |= 0x04;
338 }
339 rate = ieee80211_fix_rate(ic, ni, IEEE80211_F_DONEGO);
340 if (rate & IEEE80211_RATE_BASIC)
341 fail |= 0x08;
342 if (ic->ic_des_esslen != 0 &&
343 (ni->ni_esslen != ic->ic_des_esslen ||
344 memcmp(ni->ni_essid, ic->ic_des_essid, ic->ic_des_esslen) != 0))
345 fail |= 0x10;
346 if ((ic->ic_flags & IEEE80211_F_DESBSSID) &&
347 !IEEE80211_ADDR_EQ(ic->ic_des_bssid, ni->ni_bssid))
348 fail |= 0x20;
349 #ifdef IEEE80211_DEBUG
350 if (ic->ic_if.if_flags & IFF_DEBUG) {
351 printf(" %c %s", fail ? '-' : '+',
352 ether_sprintf(ni->ni_macaddr));
353 printf(" %s%c", ether_sprintf(ni->ni_bssid),
354 fail & 0x20 ? '!' : ' ');
355 printf(" %3d%c", ieee80211_chan2ieee(ic, ni->ni_chan),
356 fail & 0x01 ? '!' : ' ');
357 printf(" %+4d", ni->ni_rssi);
358 printf(" %2dM%c", (rate & IEEE80211_RATE_VAL) / 2,
359 fail & 0x08 ? '!' : ' ');
360 printf(" %4s%c",
361 (ni->ni_capinfo & IEEE80211_CAPINFO_ESS) ? "ess" :
362 (ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) ? "ibss" :
363 "????",
364 fail & 0x02 ? '!' : ' ');
365 printf(" %3s%c ",
366 (ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) ?
367 "wep" : "no",
368 fail & 0x04 ? '!' : ' ');
369 ieee80211_print_essid(ni->ni_essid, ni->ni_esslen);
370 printf("%s\n", fail & 0x10 ? "!" : "");
371 }
372 #endif
373 return fail;
374 }
375
376
377
378
379 void
380 ieee80211_end_scan(struct ifnet *ifp)
381 {
382 struct ieee80211com *ic = (void *)ifp;
383 struct ieee80211_node *ni, *nextbs, *selbs;
384 int i, fail;
385
386 if (ifp->if_flags & IFF_DEBUG)
387 printf("%s: end %s scan\n", ifp->if_xname,
388 (ic->ic_flags & IEEE80211_F_ASCAN) ?
389 "active" : "passive");
390
391 if (ic->ic_scan_count)
392 ic->ic_flags &= ~IEEE80211_F_ASCAN;
393
394 ni = RB_MIN(ieee80211_tree, &ic->ic_tree);
395
396 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
397
398 u_char occupied[howmany(IEEE80211_CHAN_MAX, NBBY)];
399
400
401
402
403
404
405
406 RB_FOREACH(ni, ieee80211_tree, &ic->ic_tree)
407 setbit(occupied, ieee80211_chan2ieee(ic, ni->ni_chan));
408 for (i = 0; i < IEEE80211_CHAN_MAX; i++)
409 if (isset(ic->ic_chan_active, i) && isclr(occupied, i))
410 break;
411 if (i == IEEE80211_CHAN_MAX) {
412 fail = arc4random() & 3;
413 for (i = 0; i < IEEE80211_CHAN_MAX; i++)
414 if (isset(ic->ic_chan_active, i) && fail-- == 0)
415 break;
416 }
417 ieee80211_create_ibss(ic, &ic->ic_channels[i]);
418 goto wakeup;
419 }
420 if (ni == NULL) {
421 IEEE80211_DPRINTF(("%s: no scan candidate\n", __func__));
422 notfound:
423 if (ic->ic_opmode == IEEE80211_M_IBSS &&
424 (ic->ic_flags & IEEE80211_F_IBSSON) &&
425 ic->ic_des_esslen != 0) {
426 ieee80211_create_ibss(ic, ic->ic_ibss_chan);
427 goto wakeup;
428 }
429
430
431
432
433
434
435
436
437 if (ieee80211_next_mode(ifp) == IEEE80211_MODE_AUTO) {
438 if (ic->ic_scan_lock & IEEE80211_SCAN_REQUEST &&
439 ic->ic_scan_lock & IEEE80211_SCAN_RESUME) {
440 ic->ic_scan_lock = IEEE80211_SCAN_LOCKED;
441
442 wakeup(&ic->ic_scan_lock);
443 } else if (ic->ic_scan_lock & IEEE80211_SCAN_REQUEST)
444 goto wakeup;
445 ic->ic_scan_count++;
446 }
447
448
449
450
451 ieee80211_next_scan(ifp);
452 return;
453 }
454 selbs = NULL;
455
456 for (; ni != NULL; ni = nextbs) {
457 nextbs = RB_NEXT(ieee80211_tree, &ic->ic_tree, ni);
458 if (ni->ni_fails) {
459
460
461
462
463
464 if (ni->ni_fails++ > 2)
465 ieee80211_free_node(ic, ni);
466 continue;
467 }
468 if (ieee80211_match_bss(ic, ni) == 0) {
469 if (selbs == NULL)
470 selbs = ni;
471 else if (ni->ni_rssi > selbs->ni_rssi)
472 selbs = ni;
473 }
474 }
475 if (selbs == NULL)
476 goto notfound;
477 (*ic->ic_node_copy)(ic, ic->ic_bss, selbs);
478
479
480
481
482
483
484 ic->ic_curmode = ieee80211_chan2mode(ic, selbs->ni_chan);
485 ieee80211_reset_erp(ic);
486
487 ieee80211_node_newstate(selbs, IEEE80211_STA_BSS);
488 if (ic->ic_opmode == IEEE80211_M_IBSS) {
489 ieee80211_fix_rate(ic, ic->ic_bss, IEEE80211_F_DOFRATE |
490 IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
491 if (ic->ic_bss->ni_rates.rs_nrates == 0)
492 goto notfound;
493 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
494 } else {
495 ieee80211_new_state(ic, IEEE80211_S_AUTH, -1);
496 }
497
498 wakeup:
499 if (ic->ic_scan_lock & IEEE80211_SCAN_REQUEST) {
500
501 wakeup(&ic->ic_scan_lock);
502 }
503
504 ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED;
505 }
506
507 int
508 ieee80211_get_rate(struct ieee80211com *ic)
509 {
510 u_int8_t (*rates)[IEEE80211_RATE_MAXSIZE];
511 int rate;
512
513 rates = &ic->ic_bss->ni_rates.rs_rates;
514
515 if (ic->ic_fixed_rate != -1)
516 rate = (*rates)[ic->ic_fixed_rate];
517 else if (ic->ic_state == IEEE80211_S_RUN)
518 rate = (*rates)[ic->ic_bss->ni_txrate];
519 else
520 rate = 0;
521
522 return rate & IEEE80211_RATE_VAL;
523 }
524
525 struct ieee80211_node *
526 ieee80211_node_alloc(struct ieee80211com *ic)
527 {
528 struct ieee80211_node *ni;
529 MALLOC(ni, struct ieee80211_node *, sizeof(struct ieee80211_node),
530 M_80211_NODE, M_NOWAIT);
531 if (ni != NULL)
532 memset(ni, 0, sizeof(struct ieee80211_node));
533 return ni;
534 }
535
536 void
537 ieee80211_node_cleanup(struct ieee80211com *ic, struct ieee80211_node *ni)
538 {
539 }
540
541 void
542 ieee80211_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
543 {
544 ieee80211_node_cleanup(ic, ni);
545 FREE(ni, M_80211_NODE);
546 }
547
548 void
549 ieee80211_node_copy(struct ieee80211com *ic,
550 struct ieee80211_node *dst, const struct ieee80211_node *src)
551 {
552 ieee80211_node_cleanup(ic, dst);
553 *dst = *src;
554 }
555
556 u_int8_t
557 ieee80211_node_getrssi(struct ieee80211com *ic,
558 const struct ieee80211_node *ni)
559 {
560 return ni->ni_rssi;
561 }
562
563 void
564 ieee80211_setup_node(struct ieee80211com *ic,
565 struct ieee80211_node *ni, const u_int8_t *macaddr)
566 {
567 int s;
568
569 IEEE80211_DPRINTF(("%s %s\n", __func__,
570 ether_sprintf((u_int8_t *)macaddr)));
571 IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr);
572 ieee80211_node_newstate(ni, IEEE80211_STA_CACHE);
573
574
575
576
577
578
579
580
581
582
583 s = splnet();
584 if (ic->ic_opmode != IEEE80211_M_STA &&
585 RB_EMPTY(&ic->ic_tree))
586 ic->ic_inact_timer = IEEE80211_INACT_WAIT;
587 RB_INSERT(ieee80211_tree, &ic->ic_tree, ni);
588 splx(s);
589 }
590
591 struct ieee80211_node *
592 ieee80211_alloc_node(struct ieee80211com *ic, const u_int8_t *macaddr)
593 {
594 struct ieee80211_node *ni = ieee80211_alloc_node_helper(ic);
595 if (ni != NULL)
596 ieee80211_setup_node(ic, ni, macaddr);
597 else
598 ic->ic_stats.is_rx_nodealloc++;
599 return ni;
600 }
601
602 struct ieee80211_node *
603 ieee80211_dup_bss(struct ieee80211com *ic, const u_int8_t *macaddr)
604 {
605 struct ieee80211_node *ni = ieee80211_alloc_node_helper(ic);
606 if (ni != NULL) {
607 ieee80211_setup_node(ic, ni, macaddr);
608
609
610
611 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid);
612 ni->ni_chan = ic->ic_bss->ni_chan;
613 } else
614 ic->ic_stats.is_rx_nodealloc++;
615 return ni;
616 }
617
618 struct ieee80211_node *
619 ieee80211_find_node(struct ieee80211com *ic, const u_int8_t *macaddr)
620 {
621 struct ieee80211_node ni;
622
623 IEEE80211_ADDR_COPY(ni.ni_macaddr, macaddr);
624 return (RB_FIND(ieee80211_tree, &ic->ic_tree, &ni));
625 }
626
627
628
629
630
631
632
633
634 struct ieee80211_node *
635 ieee80211_find_txnode(struct ieee80211com *ic, const u_int8_t *macaddr)
636 {
637 struct ieee80211_node *ni;
638 int s;
639
640
641
642
643
644
645 if (ic->ic_opmode == IEEE80211_M_STA || IEEE80211_IS_MULTICAST(macaddr))
646 return ieee80211_ref_node(ic->ic_bss);
647
648 s = splnet();
649 ni = ieee80211_find_node(ic, macaddr);
650 splx(s);
651 if (ni == NULL) {
652 if (ic->ic_opmode != IEEE80211_M_IBSS &&
653 ic->ic_opmode != IEEE80211_M_AHDEMO)
654 return NULL;
655
656
657
658
659
660
661
662
663
664
665 if ((ni = ieee80211_dup_bss(ic, macaddr)) == NULL)
666 return NULL;
667
668 ni->ni_rates = ic->ic_bss->ni_rates;
669 if (ic->ic_newassoc)
670 (*ic->ic_newassoc)(ic, ni, 1);
671 }
672 return ieee80211_ref_node(ni);
673 }
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700 static __inline int
701 ieee80211_needs_rxnode(struct ieee80211com *ic,
702 const struct ieee80211_frame *wh, const u_int8_t **bssid)
703 {
704 struct ieee80211_node *bss = ic->ic_bss;
705 int monitor, rc = 0;
706
707 monitor = (ic->ic_opmode == IEEE80211_M_MONITOR);
708
709 *bssid = NULL;
710
711 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
712 case IEEE80211_FC0_TYPE_CTL:
713 if (!monitor)
714 break;
715 return (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
716 IEEE80211_FC0_SUBTYPE_RTS;
717 case IEEE80211_FC0_TYPE_MGT:
718 *bssid = wh->i_addr3;
719 switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
720 case IEEE80211_FC0_SUBTYPE_BEACON:
721 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
722 rc = 1;
723 break;
724 default:
725 if (ic->ic_opmode == IEEE80211_M_STA)
726 break;
727 rc = IEEE80211_ADDR_EQ(*bssid, bss->ni_bssid) ||
728 IEEE80211_ADDR_EQ(*bssid, etherbroadcastaddr);
729 break;
730 }
731 break;
732 case IEEE80211_FC0_TYPE_DATA:
733 switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
734 case IEEE80211_FC1_DIR_NODS:
735 *bssid = wh->i_addr3;
736 if (ic->ic_opmode == IEEE80211_M_IBSS ||
737 ic->ic_opmode == IEEE80211_M_AHDEMO)
738 rc = IEEE80211_ADDR_EQ(*bssid, bss->ni_bssid);
739 break;
740 case IEEE80211_FC1_DIR_TODS:
741 *bssid = wh->i_addr1;
742 if (ic->ic_opmode == IEEE80211_M_HOSTAP)
743 rc = IEEE80211_ADDR_EQ(*bssid, bss->ni_bssid);
744 break;
745 case IEEE80211_FC1_DIR_FROMDS:
746 case IEEE80211_FC1_DIR_DSTODS:
747 *bssid = wh->i_addr2;
748 rc = (ic->ic_opmode == IEEE80211_M_HOSTAP);
749 break;
750 }
751 break;
752 }
753 return monitor || rc;
754 }
755
756
757
758
759
760 struct ieee80211_node *
761 ieee80211_find_rxnode(struct ieee80211com *ic,
762 const struct ieee80211_frame *wh)
763 {
764 static const u_int8_t zero[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
765 struct ieee80211_node *ni;
766 const u_int8_t *bssid;
767 int s;
768
769 if (!ieee80211_needs_rxnode(ic, wh, &bssid))
770 return ieee80211_ref_node(ic->ic_bss);
771
772 s = splnet();
773 ni = ieee80211_find_node(ic, wh->i_addr2);
774 splx(s);
775
776 if (ni != NULL)
777 return ieee80211_ref_node(ni);
778 if (ic->ic_opmode == IEEE80211_M_HOSTAP)
779 return ieee80211_ref_node(ic->ic_bss);
780
781
782
783 if ((ni = ieee80211_dup_bss(ic, wh->i_addr2)) == NULL)
784 return ieee80211_ref_node(ic->ic_bss);
785
786 IEEE80211_ADDR_COPY(ni->ni_bssid, (bssid != NULL) ? bssid : zero);
787
788 ni->ni_rates = ic->ic_bss->ni_rates;
789 if (ic->ic_newassoc)
790 (*ic->ic_newassoc)(ic, ni, 1);
791
792 IEEE80211_DPRINTF(("%s: faked-up node %p for %s\n", __func__, ni,
793 ether_sprintf((u_int8_t *)wh->i_addr2)));
794
795 return ieee80211_ref_node(ni);
796 }
797
798 struct ieee80211_node *
799 ieee80211_find_node_for_beacon(struct ieee80211com *ic,
800 const u_int8_t *macaddr, const struct ieee80211_channel *chan,
801 const char *ssid, u_int8_t rssi)
802 {
803 struct ieee80211_node *ni, *keep = NULL;
804 int s, score = 0;
805
806 if ((ni = ieee80211_find_node(ic, macaddr)) != NULL) {
807 s = splnet();
808
809 if (ni->ni_chan != chan && ni->ni_rssi >= rssi)
810 score++;
811 if (ssid[1] == 0 && ni->ni_esslen != 0)
812 score++;
813 if (score > 0)
814 keep = ni;
815
816 splx(s);
817 }
818
819 return (keep);
820 }
821
822 void
823 ieee80211_free_node(struct ieee80211com *ic, struct ieee80211_node *ni)
824 {
825 if (ni == ic->ic_bss)
826 panic("freeing bss node");
827
828 IEEE80211_DPRINTF(("%s %s\n", __func__, ether_sprintf(ni->ni_macaddr)));
829 IEEE80211_AID_CLR(ni->ni_associd, ic->ic_aid_bitmap);
830 RB_REMOVE(ieee80211_tree, &ic->ic_tree, ni);
831 ic->ic_nnodes--;
832 if (!IF_IS_EMPTY(&ni->ni_savedq)) {
833 IF_PURGE(&ni->ni_savedq);
834 if (ic->ic_set_tim != NULL)
835 (*ic->ic_set_tim)(ic, ni->ni_associd, 0);
836 }
837 if (RB_EMPTY(&ic->ic_tree))
838 ic->ic_inact_timer = 0;
839 (*ic->ic_node_free)(ic, ni);
840
841 }
842
843 void
844 ieee80211_release_node(struct ieee80211com *ic, struct ieee80211_node *ni)
845 {
846 int s;
847
848 IEEE80211_DPRINTF(("%s %s refcnt %d\n", __func__,
849 ether_sprintf(ni->ni_macaddr), ni->ni_refcnt));
850 if (ieee80211_node_decref(ni) == 0 &&
851 ni->ni_state == IEEE80211_STA_COLLECT) {
852 s = splnet();
853 ieee80211_free_node(ic, ni);
854 splx(s);
855 }
856 }
857
858 void
859 ieee80211_free_allnodes(struct ieee80211com *ic)
860 {
861 struct ieee80211_node *ni;
862 int s;
863
864 IEEE80211_DPRINTF(("%s\n", __func__));
865 s = splnet();
866 while ((ni = RB_MIN(ieee80211_tree, &ic->ic_tree)) != NULL)
867 ieee80211_free_node(ic, ni);
868 splx(s);
869
870 if (ic->ic_bss != NULL)
871 ieee80211_node_cleanup(ic, ic->ic_bss);
872 }
873
874
875
876
877 void
878 ieee80211_clean_nodes(struct ieee80211com *ic)
879 {
880 struct ieee80211_node *ni, *next_ni;
881 u_int gen = ic->ic_scangen++;
882 int s;
883
884 s = splnet();
885 for (ni = RB_MIN(ieee80211_tree, &ic->ic_tree);
886 ni != NULL; ni = next_ni) {
887 next_ni = RB_NEXT(ieee80211_tree, &ic->ic_tree, ni);
888 if (ic->ic_nnodes <= ic->ic_max_nnodes)
889 break;
890 if (ni->ni_scangen == gen)
891 continue;
892 ni->ni_scangen = gen;
893 if (ni->ni_refcnt > 0)
894 continue;
895 IEEE80211_DPRINTF(("station %s purged from LRU cache\n",
896 ether_sprintf(ni->ni_macaddr)));
897
898
899
900 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
901 splx(s);
902 IEEE80211_SEND_MGMT(ic, ni,
903 IEEE80211_FC0_SUBTYPE_DEAUTH,
904 IEEE80211_REASON_AUTH_EXPIRE);
905 s = splnet();
906 ieee80211_node_leave(ic, ni);
907 } else
908 ieee80211_free_node(ic, ni);
909 ic->ic_stats.is_node_timeout++;
910 }
911 splx(s);
912 }
913
914 void
915 ieee80211_iterate_nodes(struct ieee80211com *ic, ieee80211_iter_func *f,
916 void *arg)
917 {
918 struct ieee80211_node *ni;
919 int s;
920
921 s = splnet();
922 RB_FOREACH(ni, ieee80211_tree, &ic->ic_tree)
923 (*f)(arg, ni);
924 splx(s);
925 }
926
927
928
929
930 int
931 ieee80211_iserp_sta(const struct ieee80211_node *ni)
932 {
933 #define N(a) (sizeof (a) / sizeof (a)[0])
934 static const u_int8_t rates[] = { 2, 4, 11, 22, 12, 24, 48 };
935 const struct ieee80211_rateset *rs = &ni->ni_rates;
936 int i, j;
937
938
939
940
941
942 for (i = 0; i < N(rates); i++) {
943 for (j = 0; j < rs->rs_nrates; j++) {
944 if ((rs->rs_rates[j] & IEEE80211_RATE_VAL) == rates[i])
945 break;
946 }
947 if (j == rs->rs_nrates)
948 return 0;
949 }
950 return 1;
951 #undef N
952 }
953
954
955
956
957 void
958 ieee80211_node_join_11g(struct ieee80211com *ic, struct ieee80211_node *ni)
959 {
960 if (!(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)) {
961
962
963
964
965
966
967 if (++ic->ic_longslotsta == 1) {
968 if (ic->ic_caps & IEEE80211_C_SHSLOT)
969 ieee80211_set_shortslottime(ic, 0);
970 }
971 IEEE80211_DPRINTF(("[%s] station needs long slot time, "
972 "count %d\n", ether_sprintf(ni->ni_macaddr),
973 ic->ic_longslotsta));
974 }
975
976 if (!ieee80211_iserp_sta(ni)) {
977
978
979
980 ic->ic_nonerpsta++;
981
982 IEEE80211_DPRINTF(("[%s] station is non-ERP, %d non-ERP "
983 "stations associated\n", ether_sprintf(ni->ni_macaddr),
984 ic->ic_nonerpsta));
985
986
987 if (ic->ic_protmode != IEEE80211_PROT_NONE) {
988 IEEE80211_DPRINTF(("%s: enable use of protection\n",
989 __func__));
990 ic->ic_flags |= IEEE80211_F_USEPROT;
991 }
992
993 if (!(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE))
994 ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
995 } else
996 ni->ni_flags |= IEEE80211_NODE_ERP;
997 }
998
999 void
1000 ieee80211_node_join(struct ieee80211com *ic, struct ieee80211_node *ni,
1001 int resp)
1002 {
1003 int newassoc;
1004
1005 if (ni->ni_associd == 0) {
1006 u_int16_t aid;
1007
1008
1009
1010
1011
1012 for (aid = 1; aid < ic->ic_max_aid; aid++) {
1013 if (!IEEE80211_AID_ISSET(aid,
1014 ic->ic_aid_bitmap))
1015 break;
1016 }
1017 if (aid >= ic->ic_max_aid) {
1018 IEEE80211_SEND_MGMT(ic, ni, resp,
1019 IEEE80211_REASON_ASSOC_TOOMANY);
1020 ieee80211_node_leave(ic, ni);
1021 return;
1022 }
1023 ni->ni_associd = aid | 0xc000;
1024 IEEE80211_AID_SET(ni->ni_associd, ic->ic_aid_bitmap);
1025 newassoc = 1;
1026 if (ic->ic_curmode == IEEE80211_MODE_11G)
1027 ieee80211_node_join_11g(ic, ni);
1028 } else
1029 newassoc = 0;
1030
1031 IEEE80211_DPRINTF(("station %s %s associated at aid %d\n",
1032 ether_sprintf(ni->ni_macaddr),
1033 (newassoc ? "newly" : "already"),
1034 ni->ni_associd & ~0xc000));
1035
1036
1037 if (ic->ic_newassoc)
1038 (*ic->ic_newassoc)(ic, ni, newassoc);
1039 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_SUCCESS);
1040 ieee80211_node_newstate(ni, IEEE80211_STA_ASSOC);
1041
1042 #if NBRIDGE > 0
1043
1044
1045
1046
1047 if (ic->ic_if.if_bridge != NULL)
1048 bridge_update(&ic->ic_if,
1049 (struct ether_addr *)ni->ni_macaddr, 0);
1050 #endif
1051 }
1052
1053
1054
1055
1056 void
1057 ieee80211_node_leave_11g(struct ieee80211com *ic, struct ieee80211_node *ni)
1058 {
1059 if (!(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)) {
1060 #ifdef DIAGNOSTIC
1061 if (ic->ic_longslotsta == 0) {
1062 panic("bogus long slot station count %d",
1063 ic->ic_longslotsta);
1064 }
1065 #endif
1066
1067 if (--ic->ic_longslotsta == 0) {
1068
1069
1070
1071
1072
1073
1074 if ((ic->ic_caps & IEEE80211_C_SHSLOT) &&
1075 ic->ic_opmode != IEEE80211_M_IBSS)
1076 ieee80211_set_shortslottime(ic, 1);
1077 }
1078 IEEE80211_DPRINTF(("[%s] long slot time station leaves, "
1079 "count now %d\n", ether_sprintf(ni->ni_macaddr),
1080 ic->ic_longslotsta));
1081 }
1082
1083 if (!(ni->ni_flags & IEEE80211_NODE_ERP)) {
1084 #ifdef DIAGNOSTIC
1085 if (ic->ic_nonerpsta == 0) {
1086 panic("bogus non-ERP station count %d\n",
1087 ic->ic_nonerpsta);
1088 }
1089 #endif
1090
1091 if (--ic->ic_nonerpsta == 0) {
1092
1093
1094
1095
1096 ic->ic_flags &= ~IEEE80211_F_USEPROT;
1097 if (ic->ic_caps & IEEE80211_C_SHPREAMBLE)
1098 ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
1099 }
1100 IEEE80211_DPRINTF(("[%s] non-ERP station leaves, "
1101 "count now %d\n", ether_sprintf(ni->ni_macaddr),
1102 ic->ic_nonerpsta));
1103 }
1104 }
1105
1106
1107
1108
1109
1110 void
1111 ieee80211_node_leave(struct ieee80211com *ic, struct ieee80211_node *ni)
1112 {
1113 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
1114 panic("not in ap mode, mode %u", ic->ic_opmode);
1115
1116
1117
1118
1119 if (ni->ni_associd == 0)
1120 return;
1121 IEEE80211_AID_CLR(ni->ni_associd, ic->ic_aid_bitmap);
1122 ni->ni_associd = 0;
1123
1124 if (ic->ic_curmode == IEEE80211_MODE_11G)
1125 ieee80211_node_leave_11g(ic, ni);
1126
1127 ieee80211_node_newstate(ni, IEEE80211_STA_COLLECT);
1128
1129 #if NBRIDGE > 0
1130
1131
1132
1133
1134 if (ic->ic_if.if_bridge != NULL)
1135 bridge_update(&ic->ic_if,
1136 (struct ether_addr *)ni->ni_macaddr, 1);
1137 #endif
1138 }
1139
1140 void
1141 ieee80211_set_tim(struct ieee80211com *ic, int aid, int set)
1142 {
1143 if (set)
1144 setbit(ic->ic_tim_bitmap, aid & ~0xc000);
1145 else
1146 clrbit(ic->ic_tim_bitmap, aid & ~0xc000);
1147 }
1148
1149
1150
1151
1152 int
1153 ieee80211_node_cmp(const struct ieee80211_node *b1,
1154 const struct ieee80211_node *b2)
1155 {
1156 return (memcmp(b1->ni_macaddr, b2->ni_macaddr, IEEE80211_ADDR_LEN));
1157 }
1158
1159
1160
1161
1162 RB_GENERATE(ieee80211_tree, ieee80211_node, ni_node, ieee80211_node_cmp);