1 /*-
2 * Copyright (c) 2001 Atsushi Onoe
3 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * Alternatively, this software may be distributed under the terms of the
18 * GNU General Public License ("GPL") version 2 as published by the Free
19 * Software Foundation.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD: releng/6.0/sys/net80211/ieee80211_proto.c 149772 2005-09-03 22:40:02Z sam $");
35
36 /*
37 * IEEE 802.11 protocol support.
38 */
39
40 #include "opt_inet.h"
41
42 #include <sys/param.h>
43 #include <sys/kernel.h>
44 #include <sys/systm.h>
45
46 #include <sys/socket.h>
47
48 #include <net/if.h>
49 #include <net/if_media.h>
50 #include <net/ethernet.h> /* XXX for ether_sprintf */
51
52 #include <net80211/ieee80211_var.h>
53
54 /* XXX tunables */
55 #define AGGRESSIVE_MODE_SWITCH_HYSTERESIS 3 /* pkts / 100ms */
56 #define HIGH_PRI_SWITCH_THRESH 10 /* pkts / 100ms */
57
58 #define IEEE80211_RATE2MBS(r) (((r) & IEEE80211_RATE_VAL) / 2)
59
60 const char *ieee80211_mgt_subtype_name[] = {
61 "assoc_req", "assoc_resp", "reassoc_req", "reassoc_resp",
62 "probe_req", "probe_resp", "reserved#6", "reserved#7",
63 "beacon", "atim", "disassoc", "auth",
64 "deauth", "reserved#13", "reserved#14", "reserved#15"
65 };
66 const char *ieee80211_ctl_subtype_name[] = {
67 "reserved#0", "reserved#1", "reserved#2", "reserved#3",
68 "reserved#3", "reserved#5", "reserved#6", "reserved#7",
69 "reserved#8", "reserved#9", "ps_poll", "rts",
70 "cts", "ack", "cf_end", "cf_end_ack"
71 };
72 const char *ieee80211_state_name[IEEE80211_S_MAX] = {
73 "INIT", /* IEEE80211_S_INIT */
74 "SCAN", /* IEEE80211_S_SCAN */
75 "AUTH", /* IEEE80211_S_AUTH */
76 "ASSOC", /* IEEE80211_S_ASSOC */
77 "RUN" /* IEEE80211_S_RUN */
78 };
79 const char *ieee80211_wme_acnames[] = {
80 "WME_AC_BE",
81 "WME_AC_BK",
82 "WME_AC_VI",
83 "WME_AC_VO",
84 "WME_UPSD",
85 };
86
87 static int ieee80211_newstate(struct ieee80211com *, enum ieee80211_state, int);
88
89 void
90 ieee80211_proto_attach(struct ieee80211com *ic)
91 {
92 struct ifnet *ifp = ic->ic_ifp;
93
94 /* XXX room for crypto */
95 ifp->if_hdrlen = sizeof(struct ieee80211_qosframe_addr4);
96
97 ic->ic_rtsthreshold = IEEE80211_RTS_DEFAULT;
98 ic->ic_fragthreshold = IEEE80211_FRAG_DEFAULT;
99 ic->ic_fixed_rate = IEEE80211_FIXED_RATE_NONE;
100 ic->ic_protmode = IEEE80211_PROT_CTSONLY;
101 ic->ic_roaming = IEEE80211_ROAMING_AUTO;
102
103 ic->ic_wme.wme_hipri_switch_hysteresis =
104 AGGRESSIVE_MODE_SWITCH_HYSTERESIS;
105
106 mtx_init(&ic->ic_mgtq.ifq_mtx, ifp->if_xname, "mgmt send q", MTX_DEF);
107
108 /* protocol state change handler */
109 ic->ic_newstate = ieee80211_newstate;
110
111 /* initialize management frame handlers */
112 ic->ic_recv_mgmt = ieee80211_recv_mgmt;
113 ic->ic_send_mgmt = ieee80211_send_mgmt;
114 }
115
116 void
117 ieee80211_proto_detach(struct ieee80211com *ic)
118 {
119
120 /*
121 * This should not be needed as we detach when reseting
122 * the state but be conservative here since the
123 * authenticator may do things like spawn kernel threads.
124 */
125 if (ic->ic_auth->ia_detach)
126 ic->ic_auth->ia_detach(ic);
127
128 IF_DRAIN(&ic->ic_mgtq);
129 mtx_destroy(&ic->ic_mgtq.ifq_mtx);
130
131 /*
132 * Detach any ACL'ator.
133 */
134 if (ic->ic_acl != NULL)
135 ic->ic_acl->iac_detach(ic);
136 }
137
138 /*
139 * Simple-minded authenticator module support.
140 */
141
142 #define IEEE80211_AUTH_MAX (IEEE80211_AUTH_WPA+1)
143 /* XXX well-known names */
144 static const char *auth_modnames[IEEE80211_AUTH_MAX] = {
145 "wlan_internal", /* IEEE80211_AUTH_NONE */
146 "wlan_internal", /* IEEE80211_AUTH_OPEN */
147 "wlan_internal", /* IEEE80211_AUTH_SHARED */
148 "wlan_xauth", /* IEEE80211_AUTH_8021X */
149 "wlan_internal", /* IEEE80211_AUTH_AUTO */
150 "wlan_xauth", /* IEEE80211_AUTH_WPA */
151 };
152 static const struct ieee80211_authenticator *authenticators[IEEE80211_AUTH_MAX];
153
154 static const struct ieee80211_authenticator auth_internal = {
155 .ia_name = "wlan_internal",
156 .ia_attach = NULL,
157 .ia_detach = NULL,
158 .ia_node_join = NULL,
159 .ia_node_leave = NULL,
160 };
161
162 /*
163 * Setup internal authenticators once; they are never unregistered.
164 */
165 static void
166 ieee80211_auth_setup(void)
167 {
168 ieee80211_authenticator_register(IEEE80211_AUTH_OPEN, &auth_internal);
169 ieee80211_authenticator_register(IEEE80211_AUTH_SHARED, &auth_internal);
170 ieee80211_authenticator_register(IEEE80211_AUTH_AUTO, &auth_internal);
171 }
172 SYSINIT(wlan_auth, SI_SUB_DRIVERS, SI_ORDER_FIRST, ieee80211_auth_setup, NULL);
173
174 const struct ieee80211_authenticator *
175 ieee80211_authenticator_get(int auth)
176 {
177 if (auth >= IEEE80211_AUTH_MAX)
178 return NULL;
179 if (authenticators[auth] == NULL)
180 ieee80211_load_module(auth_modnames[auth]);
181 return authenticators[auth];
182 }
183
184 void
185 ieee80211_authenticator_register(int type,
186 const struct ieee80211_authenticator *auth)
187 {
188 if (type >= IEEE80211_AUTH_MAX)
189 return;
190 authenticators[type] = auth;
191 }
192
193 void
194 ieee80211_authenticator_unregister(int type)
195 {
196
197 if (type >= IEEE80211_AUTH_MAX)
198 return;
199 authenticators[type] = NULL;
200 }
201
202 /*
203 * Very simple-minded ACL module support.
204 */
205 /* XXX just one for now */
206 static const struct ieee80211_aclator *acl = NULL;
207
208 void
209 ieee80211_aclator_register(const struct ieee80211_aclator *iac)
210 {
211 printf("wlan: %s acl policy registered\n", iac->iac_name);
212 acl = iac;
213 }
214
215 void
216 ieee80211_aclator_unregister(const struct ieee80211_aclator *iac)
217 {
218 if (acl == iac)
219 acl = NULL;
220 printf("wlan: %s acl policy unregistered\n", iac->iac_name);
221 }
222
223 const struct ieee80211_aclator *
224 ieee80211_aclator_get(const char *name)
225 {
226 if (acl == NULL)
227 ieee80211_load_module("wlan_acl");
228 return acl != NULL && strcmp(acl->iac_name, name) == 0 ? acl : NULL;
229 }
230
231 void
232 ieee80211_print_essid(const u_int8_t *essid, int len)
233 {
234 const u_int8_t *p;
235 int i;
236
237 if (len > IEEE80211_NWID_LEN)
238 len = IEEE80211_NWID_LEN;
239 /* determine printable or not */
240 for (i = 0, p = essid; i < len; i++, p++) {
241 if (*p < ' ' || *p > 0x7e)
242 break;
243 }
244 if (i == len) {
245 printf("\"");
246 for (i = 0, p = essid; i < len; i++, p++)
247 printf("%c", *p);
248 printf("\"");
249 } else {
250 printf("0x");
251 for (i = 0, p = essid; i < len; i++, p++)
252 printf("%02x", *p);
253 }
254 }
255
256 void
257 ieee80211_dump_pkt(const u_int8_t *buf, int len, int rate, int rssi)
258 {
259 const struct ieee80211_frame *wh;
260 int i;
261
262 wh = (const struct ieee80211_frame *)buf;
263 switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
264 case IEEE80211_FC1_DIR_NODS:
265 printf("NODS %s", ether_sprintf(wh->i_addr2));
266 printf("->%s", ether_sprintf(wh->i_addr1));
267 printf("(%s)", ether_sprintf(wh->i_addr3));
268 break;
269 case IEEE80211_FC1_DIR_TODS:
270 printf("TODS %s", ether_sprintf(wh->i_addr2));
271 printf("->%s", ether_sprintf(wh->i_addr3));
272 printf("(%s)", ether_sprintf(wh->i_addr1));
273 break;
274 case IEEE80211_FC1_DIR_FROMDS:
275 printf("FRDS %s", ether_sprintf(wh->i_addr3));
276 printf("->%s", ether_sprintf(wh->i_addr1));
277 printf("(%s)", ether_sprintf(wh->i_addr2));
278 break;
279 case IEEE80211_FC1_DIR_DSTODS:
280 printf("DSDS %s", ether_sprintf((const u_int8_t *)&wh[1]));
281 printf("->%s", ether_sprintf(wh->i_addr3));
282 printf("(%s", ether_sprintf(wh->i_addr2));
283 printf("->%s)", ether_sprintf(wh->i_addr1));
284 break;
285 }
286 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
287 case IEEE80211_FC0_TYPE_DATA:
288 printf(" data");
289 break;
290 case IEEE80211_FC0_TYPE_MGT:
291 printf(" %s", ieee80211_mgt_subtype_name[
292 (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK)
293 >> IEEE80211_FC0_SUBTYPE_SHIFT]);
294 break;
295 default:
296 printf(" type#%d", wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK);
297 break;
298 }
299 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
300 int i;
301 printf(" WEP [IV");
302 for (i = 0; i < IEEE80211_WEP_IVLEN; i++)
303 printf(" %.02x", buf[sizeof(*wh)+i]);
304 printf(" KID %u]", buf[sizeof(*wh)+i] >> 6);
305 }
306 if (rate >= 0)
307 printf(" %dM", rate / 2);
308 if (rssi >= 0)
309 printf(" +%d", rssi);
310 printf("\n");
311 if (len > 0) {
312 for (i = 0; i < len; i++) {
313 if ((i & 1) == 0)
314 printf(" ");
315 printf("%02x", buf[i]);
316 }
317 printf("\n");
318 }
319 }
320
321 int
322 ieee80211_fix_rate(struct ieee80211_node *ni, int flags)
323 {
324 #define RV(v) ((v) & IEEE80211_RATE_VAL)
325 struct ieee80211com *ic = ni->ni_ic;
326 int i, j, ignore, error;
327 int okrate, badrate, fixedrate;
328 struct ieee80211_rateset *srs, *nrs;
329 u_int8_t r;
330
331 /*
332 * If the fixed rate check was requested but no
333 * fixed has been defined then just remove it.
334 */
335 if ((flags & IEEE80211_F_DOFRATE) &&
336 ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE)
337 flags &= ~IEEE80211_F_DOFRATE;
338 error = 0;
339 okrate = badrate = fixedrate = 0;
340 srs = &ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)];
341 nrs = &ni->ni_rates;
342 for (i = 0; i < nrs->rs_nrates; ) {
343 ignore = 0;
344 if (flags & IEEE80211_F_DOSORT) {
345 /*
346 * Sort rates.
347 */
348 for (j = i + 1; j < nrs->rs_nrates; j++) {
349 if (RV(nrs->rs_rates[i]) > RV(nrs->rs_rates[j])) {
350 r = nrs->rs_rates[i];
351 nrs->rs_rates[i] = nrs->rs_rates[j];
352 nrs->rs_rates[j] = r;
353 }
354 }
355 }
356 r = nrs->rs_rates[i] & IEEE80211_RATE_VAL;
357 badrate = r;
358 if (flags & IEEE80211_F_DOFRATE) {
359 /*
360 * Check any fixed rate is included.
361 */
362 if (r == RV(srs->rs_rates[ic->ic_fixed_rate]))
363 fixedrate = r;
364 }
365 if (flags & IEEE80211_F_DONEGO) {
366 /*
367 * Check against supported rates.
368 */
369 for (j = 0; j < srs->rs_nrates; j++) {
370 if (r == RV(srs->rs_rates[j])) {
371 /*
372 * Overwrite with the supported rate
373 * value so any basic rate bit is set.
374 * This insures that response we send
375 * to stations have the necessary basic
376 * rate bit set.
377 */
378 nrs->rs_rates[i] = srs->rs_rates[j];
379 break;
380 }
381 }
382 if (j == srs->rs_nrates) {
383 /*
384 * A rate in the node's rate set is not
385 * supported. If this is a basic rate and we
386 * are operating as an AP then this is an error.
387 * Otherwise we just discard/ignore the rate.
388 * Note that this is important for 11b stations
389 * when they want to associate with an 11g AP.
390 */
391 if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
392 (nrs->rs_rates[i] & IEEE80211_RATE_BASIC))
393 error++;
394 ignore++;
395 }
396 }
397 if (flags & IEEE80211_F_DODEL) {
398 /*
399 * Delete unacceptable rates.
400 */
401 if (ignore) {
402 nrs->rs_nrates--;
403 for (j = i; j < nrs->rs_nrates; j++)
404 nrs->rs_rates[j] = nrs->rs_rates[j + 1];
405 nrs->rs_rates[j] = 0;
406 continue;
407 }
408 }
409 if (!ignore)
410 okrate = nrs->rs_rates[i];
411 i++;
412 }
413 if (okrate == 0 || error != 0 ||
414 ((flags & IEEE80211_F_DOFRATE) && fixedrate == 0))
415 return badrate | IEEE80211_RATE_BASIC;
416 else
417 return RV(okrate);
418 #undef RV
419 }
420
421 /*
422 * Reset 11g-related state.
423 */
424 void
425 ieee80211_reset_erp(struct ieee80211com *ic)
426 {
427 ic->ic_flags &= ~IEEE80211_F_USEPROT;
428 ic->ic_nonerpsta = 0;
429 ic->ic_longslotsta = 0;
430 /*
431 * Short slot time is enabled only when operating in 11g
432 * and not in an IBSS. We must also honor whether or not
433 * the driver is capable of doing it.
434 */
435 ieee80211_set_shortslottime(ic,
436 ic->ic_curmode == IEEE80211_MODE_11A ||
437 (ic->ic_curmode == IEEE80211_MODE_11G &&
438 ic->ic_opmode == IEEE80211_M_HOSTAP &&
439 (ic->ic_caps & IEEE80211_C_SHSLOT)));
440 /*
441 * Set short preamble and ERP barker-preamble flags.
442 */
443 if (ic->ic_curmode == IEEE80211_MODE_11A ||
444 (ic->ic_caps & IEEE80211_C_SHPREAMBLE)) {
445 ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
446 ic->ic_flags &= ~IEEE80211_F_USEBARKER;
447 } else {
448 ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
449 ic->ic_flags |= IEEE80211_F_USEBARKER;
450 }
451 }
452
453 /*
454 * Set the short slot time state and notify the driver.
455 */
456 void
457 ieee80211_set_shortslottime(struct ieee80211com *ic, int onoff)
458 {
459 if (onoff)
460 ic->ic_flags |= IEEE80211_F_SHSLOT;
461 else
462 ic->ic_flags &= ~IEEE80211_F_SHSLOT;
463 /* notify driver */
464 if (ic->ic_updateslot != NULL)
465 ic->ic_updateslot(ic->ic_ifp);
466 }
467
468 /*
469 * Check if the specified rate set supports ERP.
470 * NB: the rate set is assumed to be sorted.
471 */
472 int
473 ieee80211_iserp_rateset(struct ieee80211com *ic, struct ieee80211_rateset *rs)
474 {
475 #define N(a) (sizeof(a) / sizeof(a[0]))
476 static const int rates[] = { 2, 4, 11, 22, 12, 24, 48 };
477 int i, j;
478
479 if (rs->rs_nrates < N(rates))
480 return 0;
481 for (i = 0; i < N(rates); i++) {
482 for (j = 0; j < rs->rs_nrates; j++) {
483 int r = rs->rs_rates[j] & IEEE80211_RATE_VAL;
484 if (rates[i] == r)
485 goto next;
486 if (r > rates[i])
487 return 0;
488 }
489 return 0;
490 next:
491 ;
492 }
493 return 1;
494 #undef N
495 }
496
497 /*
498 * Mark the basic rates for the 11g rate table based on the
499 * operating mode. For real 11g we mark all the 11b rates
500 * and 6, 12, and 24 OFDM. For 11b compatibility we mark only
501 * 11b rates. There's also a pseudo 11a-mode used to mark only
502 * the basic OFDM rates.
503 */
504 void
505 ieee80211_set11gbasicrates(struct ieee80211_rateset *rs, enum ieee80211_phymode mode)
506 {
507 static const struct ieee80211_rateset basic[] = {
508 { 0 }, /* IEEE80211_MODE_AUTO */
509 { 3, { 12, 24, 48 } }, /* IEEE80211_MODE_11A */
510 { 2, { 2, 4 } }, /* IEEE80211_MODE_11B */
511 { 4, { 2, 4, 11, 22 } }, /* IEEE80211_MODE_11G (mixed b/g) */
512 { 0 }, /* IEEE80211_MODE_FH */
513 /* IEEE80211_MODE_PUREG (not yet) */
514 { 7, { 2, 4, 11, 22, 12, 24, 48 } },
515 };
516 int i, j;
517
518 for (i = 0; i < rs->rs_nrates; i++) {
519 rs->rs_rates[i] &= IEEE80211_RATE_VAL;
520 for (j = 0; j < basic[mode].rs_nrates; j++)
521 if (basic[mode].rs_rates[j] == rs->rs_rates[i]) {
522 rs->rs_rates[i] |= IEEE80211_RATE_BASIC;
523 break;
524 }
525 }
526 }
527
528 /*
529 * WME protocol support. The following parameters come from the spec.
530 */
531 typedef struct phyParamType {
532 u_int8_t aifsn;
533 u_int8_t logcwmin;
534 u_int8_t logcwmax;
535 u_int16_t txopLimit;
536 u_int8_t acm;
537 } paramType;
538
539 static const struct phyParamType phyParamForAC_BE[IEEE80211_MODE_MAX] = {
540 { 3, 4, 6 }, /* IEEE80211_MODE_AUTO */
541 { 3, 4, 6 }, /* IEEE80211_MODE_11A */
542 { 3, 5, 7 }, /* IEEE80211_MODE_11B */
543 { 3, 4, 6 }, /* IEEE80211_MODE_11G */
544 { 3, 5, 7 }, /* IEEE80211_MODE_FH */
545 { 2, 3, 5 }, /* IEEE80211_MODE_TURBO_A */
546 { 2, 3, 5 }, /* IEEE80211_MODE_TURBO_G */
547 };
548 static const struct phyParamType phyParamForAC_BK[IEEE80211_MODE_MAX] = {
549 { 7, 4, 10 }, /* IEEE80211_MODE_AUTO */
550 { 7, 4, 10 }, /* IEEE80211_MODE_11A */
551 { 7, 5, 10 }, /* IEEE80211_MODE_11B */
552 { 7, 4, 10 }, /* IEEE80211_MODE_11G */
553 { 7, 5, 10 }, /* IEEE80211_MODE_FH */
554 { 7, 3, 10 }, /* IEEE80211_MODE_TURBO_A */
555 { 7, 3, 10 }, /* IEEE80211_MODE_TURBO_G */
556 };
557 static const struct phyParamType phyParamForAC_VI[IEEE80211_MODE_MAX] = {
558 { 1, 3, 4, 94 }, /* IEEE80211_MODE_AUTO */
559 { 1, 3, 4, 94 }, /* IEEE80211_MODE_11A */
560 { 1, 4, 5, 188 }, /* IEEE80211_MODE_11B */
561 { 1, 3, 4, 94 }, /* IEEE80211_MODE_11G */
562 { 1, 4, 5, 188 }, /* IEEE80211_MODE_FH */
563 { 1, 2, 3, 94 }, /* IEEE80211_MODE_TURBO_A */
564 { 1, 2, 3, 94 }, /* IEEE80211_MODE_TURBO_G */
565 };
566 static const struct phyParamType phyParamForAC_VO[IEEE80211_MODE_MAX] = {
567 { 1, 2, 3, 47 }, /* IEEE80211_MODE_AUTO */
568 { 1, 2, 3, 47 }, /* IEEE80211_MODE_11A */
569 { 1, 3, 4, 102 }, /* IEEE80211_MODE_11B */
570 { 1, 2, 3, 47 }, /* IEEE80211_MODE_11G */
571 { 1, 3, 4, 102 }, /* IEEE80211_MODE_FH */
572 { 1, 2, 2, 47 }, /* IEEE80211_MODE_TURBO_A */
573 { 1, 2, 2, 47 }, /* IEEE80211_MODE_TURBO_G */
574 };
575
576 static const struct phyParamType bssPhyParamForAC_BE[IEEE80211_MODE_MAX] = {
577 { 3, 4, 10 }, /* IEEE80211_MODE_AUTO */
578 { 3, 4, 10 }, /* IEEE80211_MODE_11A */
579 { 3, 5, 10 }, /* IEEE80211_MODE_11B */
580 { 3, 4, 10 }, /* IEEE80211_MODE_11G */
581 { 3, 5, 10 }, /* IEEE80211_MODE_FH */
582 { 2, 3, 10 }, /* IEEE80211_MODE_TURBO_A */
583 { 2, 3, 10 }, /* IEEE80211_MODE_TURBO_G */
584 };
585 static const struct phyParamType bssPhyParamForAC_VI[IEEE80211_MODE_MAX] = {
586 { 2, 3, 4, 94 }, /* IEEE80211_MODE_AUTO */
587 { 2, 3, 4, 94 }, /* IEEE80211_MODE_11A */
588 { 2, 4, 5, 188 }, /* IEEE80211_MODE_11B */
589 { 2, 3, 4, 94 }, /* IEEE80211_MODE_11G */
590 { 2, 4, 5, 188 }, /* IEEE80211_MODE_FH */
591 { 2, 2, 3, 94 }, /* IEEE80211_MODE_TURBO_A */
592 { 2, 2, 3, 94 }, /* IEEE80211_MODE_TURBO_G */
593 };
594 static const struct phyParamType bssPhyParamForAC_VO[IEEE80211_MODE_MAX] = {
595 { 2, 2, 3, 47 }, /* IEEE80211_MODE_AUTO */
596 { 2, 2, 3, 47 }, /* IEEE80211_MODE_11A */
597 { 2, 3, 4, 102 }, /* IEEE80211_MODE_11B */
598 { 2, 2, 3, 47 }, /* IEEE80211_MODE_11G */
599 { 2, 3, 4, 102 }, /* IEEE80211_MODE_FH */
600 { 1, 2, 2, 47 }, /* IEEE80211_MODE_TURBO_A */
601 { 1, 2, 2, 47 }, /* IEEE80211_MODE_TURBO_G */
602 };
603
604 void
605 ieee80211_wme_initparams(struct ieee80211com *ic)
606 {
607 struct ieee80211_wme_state *wme = &ic->ic_wme;
608 const paramType *pPhyParam, *pBssPhyParam;
609 struct wmeParams *wmep;
610 int i;
611
612 if ((ic->ic_caps & IEEE80211_C_WME) == 0)
613 return;
614
615 for (i = 0; i < WME_NUM_AC; i++) {
616 switch (i) {
617 case WME_AC_BK:
618 pPhyParam = &phyParamForAC_BK[ic->ic_curmode];
619 pBssPhyParam = &phyParamForAC_BK[ic->ic_curmode];
620 break;
621 case WME_AC_VI:
622 pPhyParam = &phyParamForAC_VI[ic->ic_curmode];
623 pBssPhyParam = &bssPhyParamForAC_VI[ic->ic_curmode];
624 break;
625 case WME_AC_VO:
626 pPhyParam = &phyParamForAC_VO[ic->ic_curmode];
627 pBssPhyParam = &bssPhyParamForAC_VO[ic->ic_curmode];
628 break;
629 case WME_AC_BE:
630 default:
631 pPhyParam = &phyParamForAC_BE[ic->ic_curmode];
632 pBssPhyParam = &bssPhyParamForAC_BE[ic->ic_curmode];
633 break;
634 }
635
636 wmep = &wme->wme_wmeChanParams.cap_wmeParams[i];
637 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
638 wmep->wmep_acm = pPhyParam->acm;
639 wmep->wmep_aifsn = pPhyParam->aifsn;
640 wmep->wmep_logcwmin = pPhyParam->logcwmin;
641 wmep->wmep_logcwmax = pPhyParam->logcwmax;
642 wmep->wmep_txopLimit = pPhyParam->txopLimit;
643 } else {
644 wmep->wmep_acm = pBssPhyParam->acm;
645 wmep->wmep_aifsn = pBssPhyParam->aifsn;
646 wmep->wmep_logcwmin = pBssPhyParam->logcwmin;
647 wmep->wmep_logcwmax = pBssPhyParam->logcwmax;
648 wmep->wmep_txopLimit = pBssPhyParam->txopLimit;
649
650 }
651 IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME,
652 "%s: %s chan [acm %u aifsn %u log2(cwmin) %u "
653 "log2(cwmax) %u txpoLimit %u]\n", __func__
654 , ieee80211_wme_acnames[i]
655 , wmep->wmep_acm
656 , wmep->wmep_aifsn
657 , wmep->wmep_logcwmin
658 , wmep->wmep_logcwmax
659 , wmep->wmep_txopLimit
660 );
661
662 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[i];
663 wmep->wmep_acm = pBssPhyParam->acm;
664 wmep->wmep_aifsn = pBssPhyParam->aifsn;
665 wmep->wmep_logcwmin = pBssPhyParam->logcwmin;
666 wmep->wmep_logcwmax = pBssPhyParam->logcwmax;
667 wmep->wmep_txopLimit = pBssPhyParam->txopLimit;
668 IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME,
669 "%s: %s bss [acm %u aifsn %u log2(cwmin) %u "
670 "log2(cwmax) %u txpoLimit %u]\n", __func__
671 , ieee80211_wme_acnames[i]
672 , wmep->wmep_acm
673 , wmep->wmep_aifsn
674 , wmep->wmep_logcwmin
675 , wmep->wmep_logcwmax
676 , wmep->wmep_txopLimit
677 );
678 }
679 /* NB: check ic_bss to avoid NULL deref on initial attach */
680 if (ic->ic_bss != NULL) {
681 /*
682 * Calculate agressive mode switching threshold based
683 * on beacon interval. This doesn't need locking since
684 * we're only called before entering the RUN state at
685 * which point we start sending beacon frames.
686 */
687 wme->wme_hipri_switch_thresh =
688 (HIGH_PRI_SWITCH_THRESH * ic->ic_bss->ni_intval) / 100;
689 ieee80211_wme_updateparams(ic);
690 }
691 }
692
693 /*
694 * Update WME parameters for ourself and the BSS.
695 */
696 void
697 ieee80211_wme_updateparams_locked(struct ieee80211com *ic)
698 {
699 static const paramType phyParam[IEEE80211_MODE_MAX] = {
700 { 2, 4, 10, 64 }, /* IEEE80211_MODE_AUTO */
701 { 2, 4, 10, 64 }, /* IEEE80211_MODE_11A */
702 { 2, 5, 10, 64 }, /* IEEE80211_MODE_11B */
703 { 2, 4, 10, 64 }, /* IEEE80211_MODE_11G */
704 { 2, 5, 10, 64 }, /* IEEE80211_MODE_FH */
705 { 1, 3, 10, 64 }, /* IEEE80211_MODE_TURBO_A */
706 { 1, 3, 10, 64 }, /* IEEE80211_MODE_TURBO_G */
707 };
708 struct ieee80211_wme_state *wme = &ic->ic_wme;
709 const struct wmeParams *wmep;
710 struct wmeParams *chanp, *bssp;
711 int i;
712
713 /* set up the channel access parameters for the physical device */
714 for (i = 0; i < WME_NUM_AC; i++) {
715 chanp = &wme->wme_chanParams.cap_wmeParams[i];
716 wmep = &wme->wme_wmeChanParams.cap_wmeParams[i];
717 chanp->wmep_aifsn = wmep->wmep_aifsn;
718 chanp->wmep_logcwmin = wmep->wmep_logcwmin;
719 chanp->wmep_logcwmax = wmep->wmep_logcwmax;
720 chanp->wmep_txopLimit = wmep->wmep_txopLimit;
721
722 chanp = &wme->wme_bssChanParams.cap_wmeParams[i];
723 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[i];
724 chanp->wmep_aifsn = wmep->wmep_aifsn;
725 chanp->wmep_logcwmin = wmep->wmep_logcwmin;
726 chanp->wmep_logcwmax = wmep->wmep_logcwmax;
727 chanp->wmep_txopLimit = wmep->wmep_txopLimit;
728 }
729
730 /*
731 * This implements agressive mode as found in certain
732 * vendors' AP's. When there is significant high
733 * priority (VI/VO) traffic in the BSS throttle back BE
734 * traffic by using conservative parameters. Otherwise
735 * BE uses agressive params to optimize performance of
736 * legacy/non-QoS traffic.
737 */
738 if ((ic->ic_opmode == IEEE80211_M_HOSTAP &&
739 (wme->wme_flags & WME_F_AGGRMODE) == 0) ||
740 (ic->ic_opmode != IEEE80211_M_HOSTAP &&
741 (ic->ic_bss->ni_flags & IEEE80211_NODE_QOS) == 0) ||
742 (ic->ic_flags & IEEE80211_F_WME) == 0) {
743 chanp = &wme->wme_chanParams.cap_wmeParams[WME_AC_BE];
744 bssp = &wme->wme_bssChanParams.cap_wmeParams[WME_AC_BE];
745
746 chanp->wmep_aifsn = bssp->wmep_aifsn =
747 phyParam[ic->ic_curmode].aifsn;
748 chanp->wmep_logcwmin = bssp->wmep_logcwmin =
749 phyParam[ic->ic_curmode].logcwmin;
750 chanp->wmep_logcwmax = bssp->wmep_logcwmax =
751 phyParam[ic->ic_curmode].logcwmax;
752 chanp->wmep_txopLimit = bssp->wmep_txopLimit =
753 (ic->ic_caps & IEEE80211_C_BURST) ?
754 phyParam[ic->ic_curmode].txopLimit : 0;
755 IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME,
756 "%s: %s [acm %u aifsn %u log2(cwmin) %u "
757 "log2(cwmax) %u txpoLimit %u]\n", __func__
758 , ieee80211_wme_acnames[WME_AC_BE]
759 , chanp->wmep_acm
760 , chanp->wmep_aifsn
761 , chanp->wmep_logcwmin
762 , chanp->wmep_logcwmax
763 , chanp->wmep_txopLimit
764 );
765 }
766
767 if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
768 ic->ic_sta_assoc < 2 && (wme->wme_flags & WME_F_AGGRMODE) == 0) {
769 static const u_int8_t logCwMin[IEEE80211_MODE_MAX] = {
770 3, /* IEEE80211_MODE_AUTO */
771 3, /* IEEE80211_MODE_11A */
772 4, /* IEEE80211_MODE_11B */
773 3, /* IEEE80211_MODE_11G */
774 4, /* IEEE80211_MODE_FH */
775 3, /* IEEE80211_MODE_TURBO_A */
776 3, /* IEEE80211_MODE_TURBO_G */
777 };
778 chanp = &wme->wme_chanParams.cap_wmeParams[WME_AC_BE];
779 bssp = &wme->wme_bssChanParams.cap_wmeParams[WME_AC_BE];
780
781 chanp->wmep_logcwmin = bssp->wmep_logcwmin =
782 logCwMin[ic->ic_curmode];
783 IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME,
784 "%s: %s log2(cwmin) %u\n", __func__
785 , ieee80211_wme_acnames[WME_AC_BE]
786 , chanp->wmep_logcwmin
787 );
788 }
789 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { /* XXX ibss? */
790 /*
791 * Arrange for a beacon update and bump the parameter
792 * set number so associated stations load the new values.
793 */
794 wme->wme_bssChanParams.cap_info =
795 (wme->wme_bssChanParams.cap_info+1) & WME_QOSINFO_COUNT;
796 ic->ic_flags |= IEEE80211_F_WMEUPDATE;
797 }
798
799 wme->wme_update(ic);
800
801 IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME,
802 "%s: WME params updated, cap_info 0x%x\n", __func__,
803 ic->ic_opmode == IEEE80211_M_STA ?
804 wme->wme_wmeChanParams.cap_info :
805 wme->wme_bssChanParams.cap_info);
806 }
807
808 void
809 ieee80211_wme_updateparams(struct ieee80211com *ic)
810 {
811
812 if (ic->ic_caps & IEEE80211_C_WME) {
813 IEEE80211_BEACON_LOCK(ic);
814 ieee80211_wme_updateparams_locked(ic);
815 IEEE80211_BEACON_UNLOCK(ic);
816 }
817 }
818
819 static void
820 sta_disassoc(void *arg, struct ieee80211_node *ni)
821 {
822 struct ieee80211com *ic = arg;
823
824 if (ni->ni_associd != 0) {
825 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DISASSOC,
826 IEEE80211_REASON_ASSOC_LEAVE);
827 ieee80211_node_leave(ic, ni);
828 }
829 }
830
831 static void
832 sta_deauth(void *arg, struct ieee80211_node *ni)
833 {
834 struct ieee80211com *ic = arg;
835
836 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
837 IEEE80211_REASON_ASSOC_LEAVE);
838 }
839
840 static int
841 ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
842 {
843 struct ifnet *ifp = ic->ic_ifp;
844 struct ieee80211_node *ni;
845 enum ieee80211_state ostate;
846
847 ostate = ic->ic_state;
848 IEEE80211_DPRINTF(ic, IEEE80211_MSG_STATE, "%s: %s -> %s\n", __func__,
849 ieee80211_state_name[ostate], ieee80211_state_name[nstate]);
850 ic->ic_state = nstate; /* state transition */
851 ni = ic->ic_bss; /* NB: no reference held */
852 switch (nstate) {
853 case IEEE80211_S_INIT:
854 switch (ostate) {
855 case IEEE80211_S_INIT:
856 break;
857 case IEEE80211_S_RUN:
858 switch (ic->ic_opmode) {
859 case IEEE80211_M_STA:
860 IEEE80211_SEND_MGMT(ic, ni,
861 IEEE80211_FC0_SUBTYPE_DISASSOC,
862 IEEE80211_REASON_ASSOC_LEAVE);
863 ieee80211_sta_leave(ic, ni);
864 break;
865 case IEEE80211_M_HOSTAP:
866 ieee80211_iterate_nodes(&ic->ic_sta,
867 sta_disassoc, ic);
868 break;
869 default:
870 break;
871 }
872 goto reset;
873 case IEEE80211_S_ASSOC:
874 switch (ic->ic_opmode) {
875 case IEEE80211_M_STA:
876 IEEE80211_SEND_MGMT(ic, ni,
877 IEEE80211_FC0_SUBTYPE_DEAUTH,
878 IEEE80211_REASON_AUTH_LEAVE);
879 break;
880 case IEEE80211_M_HOSTAP:
881 ieee80211_iterate_nodes(&ic->ic_sta,
882 sta_deauth, ic);
883 break;
884 default:
885 break;
886 }
887 goto reset;
888 case IEEE80211_S_SCAN:
889 ieee80211_cancel_scan(ic);
890 goto reset;
891 case IEEE80211_S_AUTH:
892 reset:
893 ic->ic_mgt_timer = 0;
894 IF_DRAIN(&ic->ic_mgtq);
895 ieee80211_reset_bss(ic);
896 break;
897 }
898 if (ic->ic_auth->ia_detach != NULL)
899 ic->ic_auth->ia_detach(ic);
900 break;
901 case IEEE80211_S_SCAN:
902 switch (ostate) {
903 case IEEE80211_S_INIT:
904 if ((ic->ic_opmode == IEEE80211_M_HOSTAP ||
905 ic->ic_opmode == IEEE80211_M_IBSS ||
906 ic->ic_opmode == IEEE80211_M_AHDEMO) &&
907 ic->ic_des_chan != IEEE80211_CHAN_ANYC) {
908 /*
909 * AP operation and we already have a channel;
910 * bypass the scan and startup immediately.
911 */
912 ieee80211_create_ibss(ic, ic->ic_des_chan);
913 } else {
914 ieee80211_begin_scan(ic, arg);
915 }
916 break;
917 case IEEE80211_S_SCAN:
918 /*
919 * Scan next. If doing an active scan and the
920 * channel is not marked passive-only then send
921 * a probe request. Otherwise just listen for
922 * beacons on the channel.
923 */
924 if ((ic->ic_flags & IEEE80211_F_ASCAN) &&
925 (ic->ic_curchan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0) {
926 ieee80211_send_probereq(ni,
927 ic->ic_myaddr, ifp->if_broadcastaddr,
928 ifp->if_broadcastaddr,
929 ic->ic_des_essid, ic->ic_des_esslen,
930 ic->ic_opt_ie, ic->ic_opt_ie_len);
931 }
932 break;
933 case IEEE80211_S_RUN:
934 /* beacon miss */
935 IEEE80211_DPRINTF(ic, IEEE80211_MSG_STATE,
936 "no recent beacons from %s; rescanning\n",
937 ether_sprintf(ic->ic_bss->ni_bssid));
938 ieee80211_sta_leave(ic, ni);
939 ic->ic_flags &= ~IEEE80211_F_SIBSS; /* XXX */
940 /* FALLTHRU */
941 case IEEE80211_S_AUTH:
942 case IEEE80211_S_ASSOC:
943 /* timeout restart scan */
944 ni = ieee80211_find_node(&ic->ic_scan,
945 ic->ic_bss->ni_macaddr);
946 if (ni != NULL) {
947 ni->ni_fails++;
948 ieee80211_unref_node(&ni);
949 }
950 if (ic->ic_roaming == IEEE80211_ROAMING_AUTO)
951 ieee80211_begin_scan(ic, arg);
952 break;
953 }
954 break;
955 case IEEE80211_S_AUTH:
956 switch (ostate) {
957 case IEEE80211_S_INIT:
958 case IEEE80211_S_SCAN:
959 IEEE80211_SEND_MGMT(ic, ni,
960 IEEE80211_FC0_SUBTYPE_AUTH, 1);
961 break;
962 case IEEE80211_S_AUTH:
963 case IEEE80211_S_ASSOC:
964 switch (arg) {
965 case IEEE80211_FC0_SUBTYPE_AUTH:
966 /* ??? */
967 IEEE80211_SEND_MGMT(ic, ni,
968 IEEE80211_FC0_SUBTYPE_AUTH, 2);
969 break;
970 case IEEE80211_FC0_SUBTYPE_DEAUTH:
971 /* ignore and retry scan on timeout */
972 break;
973 }
974 break;
975 case IEEE80211_S_RUN:
976 switch (arg) {
977 case IEEE80211_FC0_SUBTYPE_AUTH:
978 IEEE80211_SEND_MGMT(ic, ni,
979 IEEE80211_FC0_SUBTYPE_AUTH, 2);
980 ic->ic_state = ostate; /* stay RUN */
981 break;
982 case IEEE80211_FC0_SUBTYPE_DEAUTH:
983 ieee80211_sta_leave(ic, ni);
984 if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
985 /* try to reauth */
986 IEEE80211_SEND_MGMT(ic, ni,
987 IEEE80211_FC0_SUBTYPE_AUTH, 1);
988 }
989 break;
990 }
991 break;
992 }
993 break;
994 case IEEE80211_S_ASSOC:
995 switch (ostate) {
996 case IEEE80211_S_INIT:
997 case IEEE80211_S_SCAN:
998 case IEEE80211_S_ASSOC:
999 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
1000 "%s: invalid transition\n", __func__);
1001 break;
1002 case IEEE80211_S_AUTH:
1003 IEEE80211_SEND_MGMT(ic, ni,
1004 IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0);
1005 break;
1006 case IEEE80211_S_RUN:
1007 ieee80211_sta_leave(ic, ni);
1008 if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
1009 IEEE80211_SEND_MGMT(ic, ni,
1010 IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 1);
1011 }
1012 break;
1013 }
1014 break;
1015 case IEEE80211_S_RUN:
1016 if (ic->ic_flags & IEEE80211_F_WPA) {
1017 /* XXX validate prerequisites */
1018 }
1019 switch (ostate) {
1020 case IEEE80211_S_INIT:
1021 if (ic->ic_opmode == IEEE80211_M_MONITOR)
1022 break;
1023 /* fall thru... */
1024 case IEEE80211_S_AUTH:
1025 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
1026 "%s: invalid transition\n", __func__);
1027 /* fall thru... */
1028 case IEEE80211_S_RUN:
1029 break;
1030 case IEEE80211_S_SCAN: /* adhoc/hostap mode */
1031 case IEEE80211_S_ASSOC: /* infra mode */
1032 KASSERT(ni->ni_txrate < ni->ni_rates.rs_nrates,
1033 ("%s: bogus xmit rate %u setup\n", __func__,
1034 ni->ni_txrate));
1035 #ifdef IEEE80211_DEBUG
1036 if (ieee80211_msg_debug(ic)) {
1037 if (ic->ic_opmode == IEEE80211_M_STA)
1038 if_printf(ifp, "associated ");
1039 else
1040 if_printf(ifp, "synchronized ");
1041 printf("with %s ssid ",
1042 ether_sprintf(ni->ni_bssid));
1043 ieee80211_print_essid(ic->ic_bss->ni_essid,
1044 ni->ni_esslen);
1045 printf(" channel %d start %uMb\n",
1046 ieee80211_chan2ieee(ic, ic->ic_curchan),
1047 IEEE80211_RATE2MBS(ni->ni_rates.rs_rates[ni->ni_txrate]));
1048 }
1049 #endif
1050 ic->ic_mgt_timer = 0;
1051 if (ic->ic_opmode == IEEE80211_M_STA)
1052 ieee80211_notify_node_join(ic, ni,
1053 arg == IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
1054 if_start(ifp); /* XXX not authorized yet */
1055 break;
1056 }
1057 /*
1058 * Start/stop the authenticator when operating as an
1059 * AP. We delay until here to allow configuration to
1060 * happen out of order.
1061 */
1062 if (ic->ic_opmode == IEEE80211_M_HOSTAP && /* XXX IBSS/AHDEMO */
1063 ic->ic_auth->ia_attach != NULL) {
1064 /* XXX check failure */
1065 ic->ic_auth->ia_attach(ic);
1066 } else if (ic->ic_auth->ia_detach != NULL) {
1067 ic->ic_auth->ia_detach(ic);
1068 }
1069 /*
1070 * When 802.1x is not in use mark the port authorized
1071 * at this point so traffic can flow.
1072 */
1073 if (ni->ni_authmode != IEEE80211_AUTH_8021X)
1074 ieee80211_node_authorize(ni);
1075 /*
1076 * Enable inactivity processing.
1077 * XXX
1078 */
1079 ic->ic_scan.nt_inact_timer = IEEE80211_INACT_WAIT;
1080 ic->ic_sta.nt_inact_timer = IEEE80211_INACT_WAIT;
1081 break;
1082 }
1083 return 0;
1084 }
Cache object: 976916564426fb19aae8649c9116516e
|