[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]

FreeBSD/Linux Kernel Cross Reference
sys/net80211/ieee80211_node.c

Version: -  FREEBSD  -  FREEBSD7  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  OPENSOLARIS  -  minix-3-1-1  -  TRUSTEDBSD-SEBSD  -  FREEBSD-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  excerpts  -  bigexcerpts 

  1 /*-
  2  * Copyright (c) 2001 Atsushi Onoe
  3  * Copyright (c) 2002-2008 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  *
 15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 25  */
 26 
 27 #include <sys/cdefs.h>
 28 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_node.c,v 1.111 2008/10/26 21:59:07 sam Exp $");
 29 
 30 #include "opt_wlan.h"
 31 
 32 #include <sys/param.h>
 33 #include <sys/systm.h> 
 34 #include <sys/mbuf.h>   
 35 #include <sys/malloc.h>
 36 #include <sys/kernel.h>
 37 
 38 #include <sys/socket.h>
 39  
 40 #include <net/if.h>
 41 #include <net/if_media.h>
 42 #include <net/ethernet.h>
 43 
 44 #include <net80211/ieee80211_var.h>
 45 #include <net80211/ieee80211_input.h>
 46 #include <net80211/ieee80211_wds.h>
 47 
 48 #include <net/bpf.h>
 49 
 50 /*
 51  * Association id's are managed with a bit vector.
 52  */
 53 #define IEEE80211_AID_SET(_vap, b) \
 54         ((_vap)->iv_aid_bitmap[IEEE80211_AID(b) / 32] |= \
 55                 (1 << (IEEE80211_AID(b) % 32)))
 56 #define IEEE80211_AID_CLR(_vap, b) \
 57         ((_vap)->iv_aid_bitmap[IEEE80211_AID(b) / 32] &= \
 58                 ~(1 << (IEEE80211_AID(b) % 32)))
 59 #define IEEE80211_AID_ISSET(_vap, b) \
 60         ((_vap)->iv_aid_bitmap[IEEE80211_AID(b) / 32] & (1 << (IEEE80211_AID(b) % 32)))
 61 
 62 #ifdef IEEE80211_DEBUG_REFCNT
 63 #define REFCNT_LOC "%s (%s:%u) %p<%s> refcnt %d\n", __func__, func, line
 64 #else
 65 #define REFCNT_LOC "%s %p<%s> refcnt %d\n", __func__
 66 #endif
 67 
 68 static int ieee80211_sta_join1(struct ieee80211_node *);
 69 
 70 static struct ieee80211_node *node_alloc(struct ieee80211vap *,
 71         const uint8_t [IEEE80211_ADDR_LEN]);
 72 static void node_cleanup(struct ieee80211_node *);
 73 static void node_free(struct ieee80211_node *);
 74 static void node_age(struct ieee80211_node *);
 75 static int8_t node_getrssi(const struct ieee80211_node *);
 76 static void node_getsignal(const struct ieee80211_node *, int8_t *, int8_t *);
 77 static void node_getmimoinfo(const struct ieee80211_node *,
 78         struct ieee80211_mimo_info *);
 79 
 80 static void _ieee80211_free_node(struct ieee80211_node *);
 81 
 82 static void ieee80211_node_table_init(struct ieee80211com *ic,
 83         struct ieee80211_node_table *nt, const char *name,
 84         int inact, int keymaxix);
 85 static void ieee80211_node_table_reset(struct ieee80211_node_table *,
 86         struct ieee80211vap *);
 87 static void ieee80211_node_reclaim(struct ieee80211_node *);
 88 static void ieee80211_node_table_cleanup(struct ieee80211_node_table *nt);
 89 static void ieee80211_erp_timeout(struct ieee80211com *);
 90 
 91 MALLOC_DEFINE(M_80211_NODE, "80211node", "802.11 node state");
 92 MALLOC_DEFINE(M_80211_NODE_IE, "80211nodeie", "802.11 node ie");
 93 
 94 void
 95 ieee80211_node_attach(struct ieee80211com *ic)
 96 {
 97         ieee80211_node_table_init(ic, &ic->ic_sta, "station",
 98                 IEEE80211_INACT_INIT, ic->ic_max_keyix);
 99         callout_init(&ic->ic_inact, CALLOUT_MPSAFE);
100         callout_reset(&ic->ic_inact, IEEE80211_INACT_WAIT*hz,
101                 ieee80211_node_timeout, ic);
102 
103         ic->ic_node_alloc = node_alloc;
104         ic->ic_node_free = node_free;
105         ic->ic_node_cleanup = node_cleanup;
106         ic->ic_node_age = node_age;
107         ic->ic_node_drain = node_age;           /* NB: same as age */
108         ic->ic_node_getrssi = node_getrssi;
109         ic->ic_node_getsignal = node_getsignal;
110         ic->ic_node_getmimoinfo = node_getmimoinfo;
111 
112         /*
113          * Set flags to be propagated to all vap's;
114          * these define default behaviour/configuration.
115          */
116         ic->ic_flags_ext |= IEEE80211_FEXT_INACT; /* inactivity processing */
117 }
118 
119 void
120 ieee80211_node_detach(struct ieee80211com *ic)
121 {
122 
123         callout_drain(&ic->ic_inact);
124         ieee80211_node_table_cleanup(&ic->ic_sta);
125 }
126 
127 void
128 ieee80211_node_vattach(struct ieee80211vap *vap)
129 {
130         /* NB: driver can override */
131         vap->iv_max_aid = IEEE80211_AID_DEF;
132 
133         /* default station inactivity timer setings */
134         vap->iv_inact_init = IEEE80211_INACT_INIT;
135         vap->iv_inact_auth = IEEE80211_INACT_AUTH;
136         vap->iv_inact_run = IEEE80211_INACT_RUN;
137         vap->iv_inact_probe = IEEE80211_INACT_PROBE;
138 
139         IEEE80211_DPRINTF(vap, IEEE80211_MSG_INACT,
140             "%s: init %u auth %u run %u probe %u\n", __func__,
141             vap->iv_inact_init, vap->iv_inact_auth,
142             vap->iv_inact_run, vap->iv_inact_probe);
143 }
144 
145 void
146 ieee80211_node_latevattach(struct ieee80211vap *vap)
147 {
148         if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
149                 /* XXX should we allow max aid to be zero? */
150                 if (vap->iv_max_aid < IEEE80211_AID_MIN) {
151                         vap->iv_max_aid = IEEE80211_AID_MIN;
152                         if_printf(vap->iv_ifp,
153                             "WARNING: max aid too small, changed to %d\n",
154                             vap->iv_max_aid);
155                 }
156                 MALLOC(vap->iv_aid_bitmap, uint32_t *,
157                         howmany(vap->iv_max_aid, 32) * sizeof(uint32_t),
158                         M_80211_NODE, M_NOWAIT | M_ZERO);
159                 if (vap->iv_aid_bitmap == NULL) {
160                         /* XXX no way to recover */
161                         printf("%s: no memory for AID bitmap, max aid %d!\n",
162                             __func__, vap->iv_max_aid);
163                         vap->iv_max_aid = 0;
164                 }
165         }
166 
167         ieee80211_reset_bss(vap);
168 
169         vap->iv_auth = ieee80211_authenticator_get(vap->iv_bss->ni_authmode);
170 }
171 
172 void
173 ieee80211_node_vdetach(struct ieee80211vap *vap)
174 {
175         struct ieee80211com *ic = vap->iv_ic;
176 
177         ieee80211_node_table_reset(&ic->ic_sta, vap);
178         if (vap->iv_bss != NULL) {
179                 ieee80211_free_node(vap->iv_bss);
180                 vap->iv_bss = NULL;
181         }
182         if (vap->iv_aid_bitmap != NULL) {
183                 FREE(vap->iv_aid_bitmap, M_80211_NODE);
184                 vap->iv_aid_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 ieee80211vap *vap = ni->ni_vap;
196 
197         ni->ni_flags |= IEEE80211_NODE_AUTH;
198         ni->ni_inact_reload = vap->iv_inact_run;
199         ni->ni_inact = ni->ni_inact_reload;
200 
201         IEEE80211_NOTE(vap, IEEE80211_MSG_INACT, ni,
202             "%s: inact_reload %u", __func__, ni->ni_inact_reload);
203 }
204 
205 void
206 ieee80211_node_unauthorize(struct ieee80211_node *ni)
207 {
208         struct ieee80211vap *vap = ni->ni_vap;
209 
210         ni->ni_flags &= ~IEEE80211_NODE_AUTH;
211         ni->ni_inact_reload = vap->iv_inact_auth;
212         if (ni->ni_inact > ni->ni_inact_reload)
213                 ni->ni_inact = ni->ni_inact_reload;
214 
215         IEEE80211_NOTE(vap, IEEE80211_MSG_INACT, ni,
216             "%s: inact_reload %u inact %u", __func__,
217             ni->ni_inact_reload, ni->ni_inact);
218 }
219 
220 /*
221  * Fix tx parameters for a node according to ``association state''.
222  */
223 static void
224 node_setuptxparms(struct ieee80211_node *ni)
225 {
226         struct ieee80211vap *vap = ni->ni_vap;
227 
228         if (ni->ni_flags & IEEE80211_NODE_HT) {
229                 if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan))
230                         ni->ni_txparms = &vap->iv_txparms[IEEE80211_MODE_11NA];
231                 else
232                         ni->ni_txparms = &vap->iv_txparms[IEEE80211_MODE_11NG];
233         } else {                                /* legacy rate handling */
234                 if (IEEE80211_IS_CHAN_A(ni->ni_chan))
235                         ni->ni_txparms = &vap->iv_txparms[IEEE80211_MODE_11A];
236                 else if (ni->ni_flags & IEEE80211_NODE_ERP)
237                         ni->ni_txparms = &vap->iv_txparms[IEEE80211_MODE_11G];
238                 else
239                         ni->ni_txparms = &vap->iv_txparms[IEEE80211_MODE_11B];
240         }
241 }
242 
243 /*
244  * Set/change the channel.  The rate set is also updated as
245  * to insure a consistent view by drivers.
246  * XXX should be private but hostap needs it to deal with CSA
247  */
248 void
249 ieee80211_node_set_chan(struct ieee80211_node *ni,
250         struct ieee80211_channel *chan)
251 {
252         struct ieee80211com *ic = ni->ni_ic;
253         struct ieee80211vap *vap = ni->ni_vap;
254         enum ieee80211_phymode mode;
255 
256         KASSERT(chan != IEEE80211_CHAN_ANYC, ("no channel"));
257 
258         ni->ni_chan = chan;
259         mode = ieee80211_chan2mode(chan);
260         if (IEEE80211_IS_CHAN_HT(chan)) {
261                 /*
262                  * XXX Gotta be careful here; the rate set returned by
263                  * ieee80211_get_suprates is actually any HT rate
264                  * set so blindly copying it will be bad.  We must
265                  * install the legacy rate est in ni_rates and the
266                  * HT rate set in ni_htrates.
267                  */
268                 ni->ni_htrates = *ieee80211_get_suphtrates(ic, chan);
269                 /*
270                  * Setup bss tx parameters based on operating mode.  We
271                  * use legacy rates when operating in a mixed HT+non-HT bss
272                  * and non-ERP rates in 11g for mixed ERP+non-ERP bss.
273                  */
274                 if (mode == IEEE80211_MODE_11NA &&
275                     (vap->iv_flags_ext & IEEE80211_FEXT_PUREN) == 0)
276                         mode = IEEE80211_MODE_11A;
277                 else if (mode == IEEE80211_MODE_11NG &&
278                     (vap->iv_flags_ext & IEEE80211_FEXT_PUREN) == 0)
279                         mode = IEEE80211_MODE_11G;
280                 if (mode == IEEE80211_MODE_11G &&
281                     (vap->iv_flags & IEEE80211_F_PUREG) == 0)
282                         mode = IEEE80211_MODE_11B;
283         }
284         ni->ni_txparms = &vap->iv_txparms[mode];
285         ni->ni_rates = *ieee80211_get_suprates(ic, chan);
286 }
287 
288 static __inline void
289 copy_bss(struct ieee80211_node *nbss, const struct ieee80211_node *obss)
290 {
291         /* propagate useful state */
292         nbss->ni_authmode = obss->ni_authmode;
293         nbss->ni_txpower = obss->ni_txpower;
294         nbss->ni_vlan = obss->ni_vlan;
295         /* XXX statistics? */
296         /* XXX legacy WDS bssid? */
297 }
298 
299 void
300 ieee80211_create_ibss(struct ieee80211vap* vap, struct ieee80211_channel *chan)
301 {
302         struct ieee80211com *ic = vap->iv_ic;
303         struct ieee80211_node *ni;
304 
305         IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
306                 "%s: creating ibss on channel %u\n", __func__,
307                 ieee80211_chan2ieee(ic, chan));
308 
309         ni = ieee80211_alloc_node(&ic->ic_sta, vap, vap->iv_myaddr);
310         if (ni == NULL) {
311                 /* XXX recovery? */
312                 return;
313         }
314         IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_myaddr);
315         ni->ni_esslen = vap->iv_des_ssid[0].len;
316         memcpy(ni->ni_essid, vap->iv_des_ssid[0].ssid, ni->ni_esslen);
317         if (vap->iv_bss != NULL)
318                 copy_bss(ni, vap->iv_bss);
319         ni->ni_intval = ic->ic_bintval;
320         if (vap->iv_flags & IEEE80211_F_PRIVACY)
321                 ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY;
322         if (ic->ic_phytype == IEEE80211_T_FH) {
323                 ni->ni_fhdwell = 200;   /* XXX */
324                 ni->ni_fhindex = 1;
325         }
326         if (vap->iv_opmode == IEEE80211_M_IBSS) {
327                 vap->iv_flags |= IEEE80211_F_SIBSS;
328                 ni->ni_capinfo |= IEEE80211_CAPINFO_IBSS;       /* XXX */
329                 if (vap->iv_flags & IEEE80211_F_DESBSSID)
330                         IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_des_bssid);
331                 else {
332                         get_random_bytes(ni->ni_bssid, IEEE80211_ADDR_LEN);
333                         /* clear group bit, add local bit */
334                         ni->ni_bssid[0] = (ni->ni_bssid[0] &~ 0x01) | 0x02;
335                 }
336         } else if (vap->iv_opmode == IEEE80211_M_AHDEMO) {
337                 if (vap->iv_flags & IEEE80211_F_DESBSSID)
338                         IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_des_bssid);
339                 else
340                         memset(ni->ni_bssid, 0, IEEE80211_ADDR_LEN);
341         }
342         /* 
343          * Fix the channel and related attributes.
344          */
345         /* clear DFS CAC state on previous channel */
346         if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
347             ic->ic_bsschan->ic_freq != chan->ic_freq &&
348             IEEE80211_IS_CHAN_CACDONE(ic->ic_bsschan))
349                 ieee80211_dfs_cac_clear(ic, ic->ic_bsschan);
350         ic->ic_bsschan = chan;
351         ieee80211_node_set_chan(ni, chan);
352         ic->ic_curmode = ieee80211_chan2mode(chan);
353         /*
354          * Do mode-specific setup.
355          */
356         if (IEEE80211_IS_CHAN_FULL(chan)) {
357                 if (IEEE80211_IS_CHAN_ANYG(chan)) {
358                         /*
359                          * Use a mixed 11b/11g basic rate set.
360                          */
361                         ieee80211_setbasicrates(&ni->ni_rates,
362                             IEEE80211_MODE_11G);
363                         if (vap->iv_flags & IEEE80211_F_PUREG) {
364                                 /*
365                                  * Also mark OFDM rates basic so 11b
366                                  * stations do not join (WiFi compliance).
367                                  */
368                                 ieee80211_addbasicrates(&ni->ni_rates,
369                                     IEEE80211_MODE_11A);
370                         }
371                 } else if (IEEE80211_IS_CHAN_B(chan)) {
372                         /*
373                          * Force pure 11b rate set.
374                          */
375                         ieee80211_setbasicrates(&ni->ni_rates,
376                                 IEEE80211_MODE_11B);
377                 }
378         }
379 
380         (void) ieee80211_sta_join1(ieee80211_ref_node(ni));
381 }
382 
383 /*
384  * Reset bss state on transition to the INIT state.
385  * Clear any stations from the table (they have been
386  * deauth'd) and reset the bss node (clears key, rate
387  * etc. state).
388  */
389 void
390 ieee80211_reset_bss(struct ieee80211vap *vap)
391 {
392         struct ieee80211com *ic = vap->iv_ic;
393         struct ieee80211_node *ni, *obss;
394 
395         ieee80211_node_table_reset(&ic->ic_sta, vap);
396         /* XXX multi-bss: wrong */
397         ieee80211_reset_erp(ic);
398 
399         ni = ieee80211_alloc_node(&ic->ic_sta, vap, vap->iv_myaddr);
400         KASSERT(ni != NULL, ("unable to setup inital BSS node"));
401         obss = vap->iv_bss;
402         vap->iv_bss = ieee80211_ref_node(ni);
403         if (obss != NULL) {
404                 copy_bss(ni, obss);
405                 ni->ni_intval = ic->ic_bintval;
406                 ieee80211_free_node(obss);
407         } else
408                 IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_myaddr);
409 }
410 
411 static int
412 match_ssid(const struct ieee80211_node *ni,
413         int nssid, const struct ieee80211_scan_ssid ssids[])
414 {
415         int i;
416 
417         for (i = 0; i < nssid; i++) {
418                 if (ni->ni_esslen == ssids[i].len &&
419                      memcmp(ni->ni_essid, ssids[i].ssid, ni->ni_esslen) == 0)
420                         return 1;
421         }
422         return 0;
423 }
424 
425 /*
426  * Test a node for suitability/compatibility.
427  */
428 static int
429 check_bss(struct ieee80211vap *vap, struct ieee80211_node *ni)
430 {
431         struct ieee80211com *ic = ni->ni_ic;
432         uint8_t rate;
433 
434         if (isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, ni->ni_chan)))
435                 return 0;
436         if (vap->iv_opmode == IEEE80211_M_IBSS) {
437                 if ((ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) == 0)
438                         return 0;
439         } else {
440                 if ((ni->ni_capinfo & IEEE80211_CAPINFO_ESS) == 0)
441                         return 0;
442         }
443         if (vap->iv_flags & IEEE80211_F_PRIVACY) {
444                 if ((ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) == 0)
445                         return 0;
446         } else {
447                 /* XXX does this mean privacy is supported or required? */
448                 if (ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY)
449                         return 0;
450         }
451         rate = ieee80211_fix_rate(ni, &ni->ni_rates,
452             IEEE80211_F_JOIN | IEEE80211_F_DONEGO | IEEE80211_F_DOFRATE);
453         if (rate & IEEE80211_RATE_BASIC)
454                 return 0;
455         if (vap->iv_des_nssid != 0 &&
456             !match_ssid(ni, vap->iv_des_nssid, vap->iv_des_ssid))
457                 return 0;
458         if ((vap->iv_flags & IEEE80211_F_DESBSSID) &&
459             !IEEE80211_ADDR_EQ(vap->iv_des_bssid, ni->ni_bssid))
460                 return 0;
461         return 1;
462 }
463 
464 #ifdef IEEE80211_DEBUG
465 /*
466  * Display node suitability/compatibility.
467  */
468 static void
469 check_bss_debug(struct ieee80211vap *vap, struct ieee80211_node *ni)
470 {
471         struct ieee80211com *ic = ni->ni_ic;
472         uint8_t rate;
473         int fail;
474 
475         fail = 0;
476         if (isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, ni->ni_chan)))
477                 fail |= 0x01;
478         if (vap->iv_opmode == IEEE80211_M_IBSS) {
479                 if ((ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) == 0)
480                         fail |= 0x02;
481         } else {
482                 if ((ni->ni_capinfo & IEEE80211_CAPINFO_ESS) == 0)
483                         fail |= 0x02;
484         }
485         if (vap->iv_flags & IEEE80211_F_PRIVACY) {
486                 if ((ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) == 0)
487                         fail |= 0x04;
488         } else {
489                 /* XXX does this mean privacy is supported or required? */
490                 if (ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY)
491                         fail |= 0x04;
492         }
493         rate = ieee80211_fix_rate(ni, &ni->ni_rates,
494              IEEE80211_F_JOIN | IEEE80211_F_DONEGO | IEEE80211_F_DOFRATE);
495         if (rate & IEEE80211_RATE_BASIC)
496                 fail |= 0x08;
497         if (vap->iv_des_nssid != 0 &&
498             !match_ssid(ni, vap->iv_des_nssid, vap->iv_des_ssid))
499                 fail |= 0x10;
500         if ((vap->iv_flags & IEEE80211_F_DESBSSID) &&
501             !IEEE80211_ADDR_EQ(vap->iv_des_bssid, ni->ni_bssid))
502                 fail |= 0x20;
503 
504         printf(" %c %s", fail ? '-' : '+', ether_sprintf(ni->ni_macaddr));
505         printf(" %s%c", ether_sprintf(ni->ni_bssid), fail & 0x20 ? '!' : ' ');
506         printf(" %3d%c",
507             ieee80211_chan2ieee(ic, ni->ni_chan), fail & 0x01 ? '!' : ' ');
508         printf(" %2dM%c", (rate & IEEE80211_RATE_VAL) / 2,
509             fail & 0x08 ? '!' : ' ');
510         printf(" %4s%c",
511             (ni->ni_capinfo & IEEE80211_CAPINFO_ESS) ? "ess" :
512             (ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) ? "ibss" :
513             "????",
514             fail & 0x02 ? '!' : ' ');
515         printf(" %3s%c ",
516             (ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) ?  "wep" : "no",
517             fail & 0x04 ? '!' : ' ');
518         ieee80211_print_essid(ni->ni_essid, ni->ni_esslen);
519         printf("%s\n", fail & 0x10 ? "!" : "");
520 }
521 #endif /* IEEE80211_DEBUG */
522  
523 /*
524  * Handle 802.11 ad hoc network merge.  The
525  * convention, set by the Wireless Ethernet Compatibility Alliance
526  * (WECA), is that an 802.11 station will change its BSSID to match
527  * the "oldest" 802.11 ad hoc network, on the same channel, that
528  * has the station's desired SSID.  The "oldest" 802.11 network
529  * sends beacons with the greatest TSF timestamp.
530  *
531  * The caller is assumed to validate TSF's before attempting a merge.
532  *
533  * Return !0 if the BSSID changed, 0 otherwise.
534  */
535 int
536 ieee80211_ibss_merge(struct ieee80211_node *ni)
537 {
538         struct ieee80211vap *vap = ni->ni_vap;
539 #ifdef IEEE80211_DEBUG
540         struct ieee80211com *ic = ni->ni_ic;
541 #endif
542 
543         if (ni == vap->iv_bss ||
544             IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid)) {
545                 /* unchanged, nothing to do */
546                 return 0;
547         }
548         if (!check_bss(vap, ni)) {
549                 /* capabilities mismatch */
550                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,
551                     "%s: merge failed, capabilities mismatch\n", __func__);
552 #ifdef IEEE80211_DEBUG
553                 if (ieee80211_msg_assoc(vap))
554                         check_bss_debug(vap, ni);
555 #endif
556                 vap->iv_stats.is_ibss_capmismatch++;
557                 return 0;
558         }
559         IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,
560                 "%s: new bssid %s: %s preamble, %s slot time%s\n", __func__,
561                 ether_sprintf(ni->ni_bssid),
562                 ic->ic_flags&IEEE80211_F_SHPREAMBLE ? "short" : "long",
563                 ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long",
564                 ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : ""
565         );
566         return ieee80211_sta_join1(ieee80211_ref_node(ni));
567 }
568 
569 /*
570  * Calculate HT channel promotion flags for all vaps.
571  * This assumes ni_chan have been setup for each vap.
572  */
573 static int
574 gethtadjustflags(struct ieee80211com *ic)
575 {
576         struct ieee80211vap *vap;
577         int flags;
578 
579         flags = 0;
580         /* XXX locking */
581         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
582                 if (vap->iv_state < IEEE80211_S_RUN)
583                         continue;
584                 switch (vap->iv_opmode) {
585                 case IEEE80211_M_WDS:
586                 case IEEE80211_M_STA:
587                 case IEEE80211_M_AHDEMO:
588                 case IEEE80211_M_HOSTAP:
589                 case IEEE80211_M_IBSS:
590                         flags |= ieee80211_htchanflags(vap->iv_bss->ni_chan);
591                         break;
592                 default:
593                         break;
594                 }
595         }
596         return flags;
597 }
598 
599 /*
600  * Check if the current channel needs to change based on whether
601  * any vap's are using HT20/HT40.  This is used to sync the state
602  * of ic_curchan after a channel width change on a running vap.
603  */
604 void
605 ieee80211_sync_curchan(struct ieee80211com *ic)
606 {
607         struct ieee80211_channel *c;
608 
609         c = ieee80211_ht_adjust_channel(ic, ic->ic_curchan, gethtadjustflags(ic));
610         if (c != ic->ic_curchan) {
611                 ic->ic_curchan = c;
612                 ic->ic_curmode = ieee80211_chan2mode(ic->ic_curchan);
613                 ic->ic_set_channel(ic);
614         }
615 }
616 
617 /*
618  * Change the current channel.  The request channel may be
619  * promoted if other vap's are operating with HT20/HT40.
620  */
621 void
622 ieee80211_setcurchan(struct ieee80211com *ic, struct ieee80211_channel *c)
623 {
624         if (ic->ic_htcaps & IEEE80211_HTC_HT) {
625                 int flags = gethtadjustflags(ic);
626                 /*
627                  * Check for channel promotion required to support the
628                  * set of running vap's.  This assumes we are called
629                  * after ni_chan is setup for each vap.
630                  */
631                 /* NB: this assumes IEEE80211_FEXT_USEHT40 > IEEE80211_FEXT_HT */
632                 if (flags > ieee80211_htchanflags(c))
633                         c = ieee80211_ht_adjust_channel(ic, c, flags);
634         }
635         ic->ic_bsschan = ic->ic_curchan = c;
636         ic->ic_curmode = ieee80211_chan2mode(ic->ic_curchan);
637         ic->ic_set_channel(ic);
638 }
639 
640 /*
641  * Join the specified IBSS/BSS network.  The node is assumed to
642  * be passed in with a held reference.
643  */
644 static int
645 ieee80211_sta_join1(struct ieee80211_node *selbs)
646 {
647         struct ieee80211vap *vap = selbs->ni_vap;
648         struct ieee80211com *ic = selbs->ni_ic;
649         struct ieee80211_node *obss;
650         int canreassoc;
651 
652         /*
653          * Committed to selbs, setup state.
654          */
655         obss = vap->iv_bss;
656         /*
657          * Check if old+new node have the same address in which
658          * case we can reassociate when operating in sta mode.
659          */
660         canreassoc = (obss != NULL &&
661                 vap->iv_state == IEEE80211_S_RUN &&
662                 IEEE80211_ADDR_EQ(obss->ni_macaddr, selbs->ni_macaddr));
663         vap->iv_bss = selbs;            /* NB: caller assumed to bump refcnt */
664         if (obss != NULL) {
665                 copy_bss(selbs, obss);
666                 ieee80211_node_reclaim(obss);
667                 obss = NULL;            /* NB: guard against later use */
668         }
669 
670         /*
671          * Delete unusable rates; we've already checked
672          * that the negotiated rate set is acceptable.
673          */
674         ieee80211_fix_rate(vap->iv_bss, &vap->iv_bss->ni_rates,
675                 IEEE80211_F_DODEL | IEEE80211_F_JOIN);
676 
677         ieee80211_setcurchan(ic, selbs->ni_chan);
678         /*
679          * Set the erp state (mostly the slot time) to deal with
680          * the auto-select case; this should be redundant if the
681          * mode is locked.
682          */ 
683         ieee80211_reset_erp(ic);
684         ieee80211_wme_initparams(vap);
685 
686         if (vap->iv_opmode == IEEE80211_M_STA) {
687                 if (canreassoc) {
688                         /* Reassociate */
689                         ieee80211_new_state(vap, IEEE80211_S_ASSOC, 1);
690                 } else {
691                         /*
692                          * Act as if we received a DEAUTH frame in case we
693                          * are invoked from the RUN state.  This will cause
694                          * us to try to re-authenticate if we are operating
695                          * as a station.
696                          */
697                         ieee80211_new_state(vap, IEEE80211_S_AUTH,
698                                 IEEE80211_FC0_SUBTYPE_DEAUTH);
699                 }
700         } else
701                 ieee80211_new_state(vap, IEEE80211_S_RUN, -1);
702         return 1;
703 }
704 
705 int
706 ieee80211_sta_join(struct ieee80211vap *vap, struct ieee80211_channel *chan,
707         const struct ieee80211_scan_entry *se)
708 {
709         struct ieee80211com *ic = vap->iv_ic;
710         struct ieee80211_node *ni;
711 
712         ni = ieee80211_alloc_node(&ic->ic_sta, vap, se->se_macaddr);
713         if (ni == NULL) {
714                 /* XXX msg */
715                 return 0;
716         }
717         /*
718          * Expand scan state into node's format.
719          * XXX may not need all this stuff
720          */
721         IEEE80211_ADDR_COPY(ni->ni_bssid, se->se_bssid);
722         ni->ni_esslen = se->se_ssid[1];
723         memcpy(ni->ni_essid, se->se_ssid+2, ni->ni_esslen);
724         ni->ni_rstamp = se->se_rstamp;
725         ni->ni_tstamp.tsf = se->se_tstamp.tsf;
726         ni->ni_intval = se->se_intval;
727         ni->ni_capinfo = se->se_capinfo;
728         ni->ni_chan = chan;
729         ni->ni_timoff = se->se_timoff;
730         ni->ni_fhdwell = se->se_fhdwell;
731         ni->ni_fhindex = se->se_fhindex;
732         ni->ni_erp = se->se_erp;
733         IEEE80211_RSSI_LPF(ni->ni_avgrssi, se->se_rssi);
734         ni->ni_noise = se->se_noise;
735 
736         if (ieee80211_ies_init(&ni->ni_ies, se->se_ies.data, se->se_ies.len)) {
737                 ieee80211_ies_expand(&ni->ni_ies);
738                 if (ni->ni_ies.ath_ie != NULL)
739                         ieee80211_parse_ath(ni, ni->ni_ies.ath_ie);
740                 if (ni->ni_ies.htcap_ie != NULL)
741                         ieee80211_parse_htcap(ni, ni->ni_ies.htcap_ie);
742                 if (ni->ni_ies.htinfo_ie != NULL)
743                         ieee80211_parse_htinfo(ni, ni->ni_ies.htinfo_ie);
744         }
745 
746         vap->iv_dtim_period = se->se_dtimperiod;
747         vap->iv_dtim_count = 0;
748 
749         /* NB: must be after ni_chan is setup */
750         ieee80211_setup_rates(ni, se->se_rates, se->se_xrates,
751                 IEEE80211_F_DOSORT);
752         if (ieee80211_iserp_rateset(&ni->ni_rates))
753                 ni->ni_flags |= IEEE80211_NODE_ERP;
754         node_setuptxparms(ni);
755 
756         return ieee80211_sta_join1(ieee80211_ref_node(ni));
757 }
758 
759 /*
760  * Leave the specified IBSS/BSS network.  The node is assumed to
761  * be passed in with a held reference.
762  */
763 void
764 ieee80211_sta_leave(struct ieee80211_node *ni)
765 {
766         struct ieee80211com *ic = ni->ni_ic;
767 
768         ic->ic_node_cleanup(ni);
769         ieee80211_notify_node_leave(ni);
770 }
771 
772 /*
773  * Send a deauthenticate frame and drop the station.
774  */
775 void
776 ieee80211_node_deauth(struct ieee80211_node *ni, int reason)
777 {
778         /* NB: bump the refcnt to be sure temporay nodes are not reclaimed */
779         ieee80211_ref_node(ni);
780         if (ni->ni_associd != 0)
781                 IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_DEAUTH, reason);
782         ieee80211_node_leave(ni);
783         ieee80211_free_node(ni);
784 }
785 
786 static struct ieee80211_node *
787 node_alloc(struct ieee80211vap *vap, const uint8_t macaddr[IEEE80211_ADDR_LEN])
788 {
789         struct ieee80211_node *ni;
790 
791         MALLOC(ni, struct ieee80211_node *, sizeof(struct ieee80211_node),
792                 M_80211_NODE, M_NOWAIT | M_ZERO);
793         return ni;
794 }
795 
796 /*
797  * Initialize an ie blob with the specified data.  If previous
798  * data exists re-use the data block.  As a side effect we clear
799  * all references to specific ie's; the caller is required to
800  * recalculate them.
801  */
802 int
803 ieee80211_ies_init(struct ieee80211_ies *ies, const uint8_t *data, int len)
804 {
805         /* NB: assumes data+len are the last fields */
806         memset(ies, 0, offsetof(struct ieee80211_ies, data));
807         if (ies->data != NULL && ies->len != len) {
808                 /* data size changed */
809                 FREE(ies->data, M_80211_NODE_IE);
810                 ies->data = NULL;
811         }
812         if (ies->data == NULL) {
813                 MALLOC(ies->data, uint8_t *, len, M_80211_NODE_IE, M_NOWAIT);
814                 if (ies->data == NULL) {
815                         ies->len = 0;
816                         /* NB: pointers have already been zero'd above */
817                         return 0;
818                 }
819         }
820         memcpy(ies->data, data, len);
821         ies->len = len;
822         return 1;
823 }
824 
825 /*
826  * Reclaim storage for an ie blob.
827  */
828 void
829 ieee80211_ies_cleanup(struct ieee80211_ies *ies)
830 {
831         if (ies->data != NULL)
832                 FREE(ies->data, M_80211_NODE_IE);
833 }
834 
835 /*
836  * Expand an ie blob data contents and to fillin individual
837  * ie pointers.  The data blob is assumed to be well-formed;
838  * we don't do any validity checking of ie lengths.
839  */
840 void
841 ieee80211_ies_expand(struct ieee80211_ies *ies)
842 {
843         uint8_t *ie;
844         int ielen;
845 
846         ie = ies->data;
847         ielen = ies->len;
848         while (ielen > 0) {
849                 switch (ie[0]) {
850                 case IEEE80211_ELEMID_VENDOR:
851                         if (iswpaoui(ie))
852                                 ies->wpa_ie = ie;
853                         else if (iswmeoui(ie))
854                                 ies->wme_ie = ie;
855                         else if (isatherosoui(ie))
856                                 ies->ath_ie = ie;
857                         break;
858                 case IEEE80211_ELEMID_RSN:
859                         ies->rsn_ie = ie;
860                         break;
861                 case IEEE80211_ELEMID_HTCAP:
862                         ies->htcap_ie = ie;
863                         break;
864                 }
865                 ielen -= 2 + ie[1];
866                 ie += 2 + ie[1];
867         }
868 }
869 
870 /*
871  * Reclaim any resources in a node and reset any critical
872  * state.  Typically nodes are free'd immediately after,
873  * but in some cases the storage may be reused so we need
874  * to insure consistent state (should probably fix that).
875  */
876 static void
877 node_cleanup(struct ieee80211_node *ni)
878 {
879 #define N(a)    (sizeof(a)/sizeof(a[0]))
880         struct ieee80211vap *vap = ni->ni_vap;
881         int i;
882 
883         /* NB: preserve ni_table */
884         if (ni->ni_flags & IEEE80211_NODE_PWR_MGT) {
885                 if (vap->iv_opmode != IEEE80211_M_STA)
886                         vap->iv_ps_sta--;
887                 ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT;
888                 IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
889                     "power save mode off, %u sta's in ps mode", vap->iv_ps_sta);
890         }
891         /*
892          * Cleanup any HT-related state.
893          */
894         if (ni->ni_flags & IEEE80211_NODE_HT)
895                 ieee80211_ht_node_cleanup(ni);
896         /*
897          * Clear AREF flag that marks the authorization refcnt bump
898          * has happened.  This is probably not needed as the node
899          * should always be removed from the table so not found but
900          * do it just in case.
901          */
902         ni->ni_flags &= ~IEEE80211_NODE_AREF;
903