1 /*- 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002, 2003 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$"); 35 36 /* 37 * IEEE 802.11 protocol support. 38 */ 39 40 #include "opt_inet.h" 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/mbuf.h> 45 #include <sys/malloc.h> 46 #include <sys/kernel.h> 47 #include <sys/socket.h> 48 #include <sys/sockio.h> 49 #include <sys/endian.h> 50 #include <sys/errno.h> 51 #include <sys/bus.h> 52 #include <sys/proc.h> 53 #include <sys/sysctl.h> 54 55 #include <machine/atomic.h> 56 57 #include <net/if.h> 58 #include <net/if_dl.h> 59 #include <net/if_media.h> 60 #include <net/if_arp.h> 61 #include <net/ethernet.h> 62 #include <net/if_llc.h> 63 64 #include <net80211/ieee80211_var.h> 65 66 #include <net/bpf.h> 67 68 #ifdef INET 69 #include <netinet/in.h> 70 #include <netinet/if_ether.h> 71 #endif 72 73 #define IEEE80211_RATE2MBS(r) (((r) & IEEE80211_RATE_VAL) / 2) 74 75 const char *ieee80211_mgt_subtype_name[] = { 76 "assoc_req", "assoc_resp", "reassoc_req", "reassoc_resp", 77 "probe_req", "probe_resp", "reserved#6", "reserved#7", 78 "beacon", "atim", "disassoc", "auth", 79 "deauth", "reserved#13", "reserved#14", "reserved#15" 80 }; 81 const char *ieee80211_state_name[IEEE80211_S_MAX] = { 82 "INIT", /* IEEE80211_S_INIT */ 83 "SCAN", /* IEEE80211_S_SCAN */ 84 "AUTH", /* IEEE80211_S_AUTH */ 85 "ASSOC", /* IEEE80211_S_ASSOC */ 86 "RUN" /* IEEE80211_S_RUN */ 87 }; 88 89 static int ieee80211_newstate(struct ieee80211com *, enum ieee80211_state, int); 90 91 void 92 ieee80211_proto_attach(struct ifnet *ifp) 93 { 94 struct ieee80211com *ic = (void *)ifp; 95 96 ifp->if_hdrlen = sizeof(struct ieee80211_frame); 97 98 #ifdef notdef 99 ic->ic_rtsthreshold = IEEE80211_RTS_DEFAULT; 100 #else 101 ic->ic_rtsthreshold = IEEE80211_RTS_MAX; 102 #endif 103 ic->ic_fragthreshold = 2346; /* XXX not used yet */ 104 ic->ic_fixed_rate = -1; /* no fixed rate */ 105 106 mtx_init(&ic->ic_mgtq.ifq_mtx, ifp->if_name, "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 ifnet *ifp) 118 { 119 struct ieee80211com *ic = (void *)ifp; 120 121 IF_DRAIN(&ic->ic_mgtq); 122 mtx_destroy(&ic->ic_mgtq.ifq_mtx); 123 } 124 125 void 126 ieee80211_print_essid(u_int8_t *essid, int len) 127 { 128 int i; 129 u_int8_t *p; 130 131 if (len > IEEE80211_NWID_LEN) 132 len = IEEE80211_NWID_LEN; 133 /* determine printable or not */ 134 for (i = 0, p = essid; i < len; i++, p++) { 135 if (*p < ' ' || *p > 0x7e) 136 break; 137 } 138 if (i == len) { 139 printf("\""); 140 for (i = 0, p = essid; i < len; i++, p++) 141 printf("%c", *p); 142 printf("\""); 143 } else { 144 printf("0x"); 145 for (i = 0, p = essid; i < len; i++, p++) 146 printf("%02x", *p); 147 } 148 } 149 150 void 151 ieee80211_dump_pkt(u_int8_t *buf, int len, int rate, int rssi) 152 { 153 struct ieee80211_frame *wh; 154 int i; 155 156 wh = (struct ieee80211_frame *)buf; 157 switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) { 158 case IEEE80211_FC1_DIR_NODS: 159 printf("NODS %s", ether_sprintf(wh->i_addr2)); 160 printf("->%s", ether_sprintf(wh->i_addr1)); 161 printf("(%s)", ether_sprintf(wh->i_addr3)); 162 break; 163 case IEEE80211_FC1_DIR_TODS: 164 printf("TODS %s", ether_sprintf(wh->i_addr2)); 165 printf("->%s", ether_sprintf(wh->i_addr3)); 166 printf("(%s)", ether_sprintf(wh->i_addr1)); 167 break; 168 case IEEE80211_FC1_DIR_FROMDS: 169 printf("FRDS %s", ether_sprintf(wh->i_addr3)); 170 printf("->%s", ether_sprintf(wh->i_addr1)); 171 printf("(%s)", ether_sprintf(wh->i_addr2)); 172 break; 173 case IEEE80211_FC1_DIR_DSTODS: 174 printf("DSDS %s", ether_sprintf((u_int8_t *)&wh[1])); 175 printf("->%s", ether_sprintf(wh->i_addr3)); 176 printf("(%s", ether_sprintf(wh->i_addr2)); 177 printf("->%s)", ether_sprintf(wh->i_addr1)); 178 break; 179 } 180 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) { 181 case IEEE80211_FC0_TYPE_DATA: 182 printf(" data"); 183 break; 184 case IEEE80211_FC0_TYPE_MGT: 185 printf(" %s", ieee80211_mgt_subtype_name[ 186 (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) 187 >> IEEE80211_FC0_SUBTYPE_SHIFT]); 188 break; 189 default: 190 printf(" type#%d", wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK); 191 break; 192 } 193 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 194 printf(" WEP"); 195 if (rate >= 0) 196 printf(" %dM", rate / 2); 197 if (rssi >= 0) 198 printf(" +%d", rssi); 199 printf("\n"); 200 if (len > 0) { 201 for (i = 0; i < len; i++) { 202 if ((i & 1) == 0) 203 printf(" "); 204 printf("%02x", buf[i]); 205 } 206 printf("\n"); 207 } 208 } 209 210 int 211 ieee80211_fix_rate(struct ieee80211com *ic, struct ieee80211_node *ni, int flags) 212 { 213 #define RV(v) ((v) & IEEE80211_RATE_VAL) 214 int i, j, ignore, error; 215 int okrate, badrate; 216 struct ieee80211_rateset *srs, *nrs; 217 u_int8_t r; 218 219 error = 0; 220 okrate = badrate = 0; 221 srs = &ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)]; 222 nrs = &ni->ni_rates; 223 for (i = 0; i < ni->ni_rates.rs_nrates; ) { 224 ignore = 0; 225 if (flags & IEEE80211_F_DOSORT) { 226 /* 227 * Sort rates. 228 */ 229 for (j = i + 1; j < nrs->rs_nrates; j++) { 230 if (RV(nrs->rs_rates[i]) > RV(nrs->rs_rates[j])) { 231 r = nrs->rs_rates[i]; 232 nrs->rs_rates[i] = nrs->rs_rates[j]; 233 nrs->rs_rates[j] = r; 234 } 235 } 236 } 237 r = nrs->rs_rates[i] & IEEE80211_RATE_VAL; 238 badrate = r; 239 if (flags & IEEE80211_F_DOFRATE) { 240 /* 241 * Apply fixed rate constraint. Note that we do 242 * not apply the constraint to basic rates as 243 * otherwise we may not be able to associate if 244 * the rate set we submit to the AP is invalid 245 * (e.g. fix rate at 36Mb/s which is not a basic 246 * rate for 11a operation). 247 */ 248 if ((nrs->rs_rates[i] & IEEE80211_RATE_BASIC) == 0 && 249 ic->ic_fixed_rate >= 0 && 250 r != RV(srs->rs_rates[ic->ic_fixed_rate])) 251 ignore++; 252 } 253 if (flags & IEEE80211_F_DONEGO) { 254 /* 255 * Check against supported rates. 256 */ 257 for (j = 0; j < srs->rs_nrates; j++) { 258 if (r == RV(srs->rs_rates[j])) 259 break; 260 } 261 if (j == srs->rs_nrates) { 262 if (nrs->rs_rates[i] & IEEE80211_RATE_BASIC) 263 error++; 264 ignore++; 265 } 266 } 267 if (flags & IEEE80211_F_DODEL) { 268 /* 269 * Delete unacceptable rates. 270 */ 271 if (ignore) { 272 nrs->rs_nrates--; 273 for (j = i; j < nrs->rs_nrates; j++) 274 nrs->rs_rates[j] = nrs->rs_rates[j + 1]; 275 nrs->rs_rates[j] = 0; 276 continue; 277 } 278 } 279 if (!ignore) 280 okrate = nrs->rs_rates[i]; 281 i++; 282 } 283 if (okrate == 0 || error != 0) 284 return badrate | IEEE80211_RATE_BASIC; 285 else 286 return RV(okrate); 287 #undef RV 288 } 289 290 static int 291 ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int mgt) 292 { 293 struct ifnet *ifp = &ic->ic_if; 294 struct ieee80211_node *ni; 295 enum ieee80211_state ostate; 296 297 ostate = ic->ic_state; 298 IEEE80211_DPRINTF(("%s: %s -> %s\n", __func__, 299 ieee80211_state_name[ostate], ieee80211_state_name[nstate])); 300 ic->ic_state = nstate; /* state transition */ 301 ni = ic->ic_bss; /* NB: no reference held */ 302 switch (nstate) { 303 case IEEE80211_S_INIT: 304 switch (ostate) { 305 case IEEE80211_S_INIT: 306 break; 307 case IEEE80211_S_RUN: 308 switch (ic->ic_opmode) { 309 case IEEE80211_M_STA: 310 IEEE80211_SEND_MGMT(ic, ni, 311 IEEE80211_FC0_SUBTYPE_DISASSOC, 312 IEEE80211_REASON_ASSOC_LEAVE); 313 break; 314 case IEEE80211_M_HOSTAP: 315 mtx_lock(&ic->ic_nodelock); 316 TAILQ_FOREACH(ni, &ic->ic_node, ni_list) { 317 if (ni->ni_associd == 0) 318 continue; 319 IEEE80211_SEND_MGMT(ic, ni, 320 IEEE80211_FC0_SUBTYPE_DISASSOC, 321 IEEE80211_REASON_ASSOC_LEAVE); 322 } 323 mtx_unlock(&ic->ic_nodelock); 324 break; 325 default: 326 break; 327 } 328 /* FALLTHRU */ 329 case IEEE80211_S_ASSOC: 330 switch (ic->ic_opmode) { 331 case IEEE80211_M_STA: 332 IEEE80211_SEND_MGMT(ic, ni, 333 IEEE80211_FC0_SUBTYPE_DEAUTH, 334 IEEE80211_REASON_AUTH_LEAVE); 335 break; 336 case IEEE80211_M_HOSTAP: 337 mtx_lock(&ic->ic_nodelock); 338 TAILQ_FOREACH(ni, &ic->ic_node, ni_list) { 339 IEEE80211_SEND_MGMT(ic, ni, 340 IEEE80211_FC0_SUBTYPE_DEAUTH, 341 IEEE80211_REASON_AUTH_LEAVE); 342 } 343 mtx_unlock(&ic->ic_nodelock); 344 break; 345 default: 346 break; 347 } 348 /* FALLTHRU */ 349 case IEEE80211_S_AUTH: 350 case IEEE80211_S_SCAN: 351 ic->ic_mgt_timer = 0; 352 IF_DRAIN(&ic->ic_mgtq); 353 if (ic->ic_wep_ctx != NULL) { 354 free(ic->ic_wep_ctx, M_DEVBUF); 355 ic->ic_wep_ctx = NULL; 356 } 357 ieee80211_free_allnodes(ic); 358 break; 359 } 360 break; 361 case IEEE80211_S_SCAN: 362 ic->ic_flags &= ~IEEE80211_F_SIBSS; 363 /* initialize bss for probe request */ 364 IEEE80211_ADDR_COPY(ni->ni_macaddr, ifp->if_broadcastaddr); 365 IEEE80211_ADDR_COPY(ni->ni_bssid, ifp->if_broadcastaddr); 366 ni->ni_rates = ic->ic_sup_rates[ 367 ieee80211_chan2mode(ic, ni->ni_chan)]; 368 ni->ni_associd = 0; 369 ni->ni_rstamp = 0; 370 switch (ostate) { 371 case IEEE80211_S_INIT: 372 if (ic->ic_opmode == IEEE80211_M_HOSTAP && 373 ic->ic_des_chan != IEEE80211_CHAN_ANYC) { 374 /* 375 * AP operation and we already have a channel; 376 * bypass the scan and startup immediately. 377 */ 378 ieee80211_create_ibss(ic, ic->ic_des_chan); 379 } else { 380 ieee80211_begin_scan(ifp); 381 } 382 break; 383 case IEEE80211_S_SCAN: 384 /* scan next */ 385 if (ic->ic_flags & IEEE80211_F_ASCAN) { 386 IEEE80211_SEND_MGMT(ic, ni, 387 IEEE80211_FC0_SUBTYPE_PROBE_REQ, 0); 388 } 389 break; 390 case IEEE80211_S_RUN: 391 /* beacon miss */ 392 if (ifp->if_flags & IFF_DEBUG) { 393 /* XXX bssid clobbered above */ 394 if_printf(ifp, "no recent beacons from %s;" 395 " rescanning\n", 396 ether_sprintf(ic->ic_bss->ni_bssid)); 397 } 398 ieee80211_free_allnodes(ic); 399 /* FALLTHRU */ 400 case IEEE80211_S_AUTH: 401 case IEEE80211_S_ASSOC: 402 /* timeout restart scan */ 403 ni = ieee80211_find_node(ic, ic->ic_bss->ni_macaddr); 404 if (ni != NULL) { 405 ni->ni_fails++; 406 ieee80211_unref_node(&ni); 407 } 408 ieee80211_begin_scan(ifp); 409 break; 410 } 411 break; 412 case IEEE80211_S_AUTH: 413 switch (ostate) { 414 case IEEE80211_S_INIT: 415 IEEE80211_DPRINTF(("%s: invalid transition\n", 416 __func__)); 417 break; 418 case IEEE80211_S_SCAN: 419 IEEE80211_SEND_MGMT(ic, ni, 420 IEEE80211_FC0_SUBTYPE_AUTH, 1); 421 break; 422 case IEEE80211_S_AUTH: 423 case IEEE80211_S_ASSOC: 424 switch (mgt) { 425 case IEEE80211_FC0_SUBTYPE_AUTH: 426 /* ??? */ 427 IEEE80211_SEND_MGMT(ic, ni, 428 IEEE80211_FC0_SUBTYPE_AUTH, 2); 429 break; 430 case IEEE80211_FC0_SUBTYPE_DEAUTH: 431 /* ignore and retry scan on timeout */ 432 break; 433 } 434 break; 435 case IEEE80211_S_RUN: 436 switch (mgt) { 437 case IEEE80211_FC0_SUBTYPE_AUTH: 438 IEEE80211_SEND_MGMT(ic, ni, 439 IEEE80211_FC0_SUBTYPE_AUTH, 2); 440 ic->ic_state = ostate; /* stay RUN */ 441 break; 442 case IEEE80211_FC0_SUBTYPE_DEAUTH: 443 /* try to reauth */ 444 IEEE80211_SEND_MGMT(ic, ni, 445 IEEE80211_FC0_SUBTYPE_AUTH, 1); 446 break; 447 } 448 break; 449 } 450 break; 451 case IEEE80211_S_ASSOC: 452 switch (ostate) { 453 case IEEE80211_S_INIT: 454 case IEEE80211_S_SCAN: 455 case IEEE80211_S_ASSOC: 456 IEEE80211_DPRINTF(("%s: invalid transition\n", 457 __func__)); 458 break; 459 case IEEE80211_S_AUTH: 460 IEEE80211_SEND_MGMT(ic, ni, 461 IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0); 462 break; 463 case IEEE80211_S_RUN: 464 IEEE80211_SEND_MGMT(ic, ni, 465 IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 1); 466 break; 467 } 468 break; 469 case IEEE80211_S_RUN: 470 switch (ostate) { 471 case IEEE80211_S_INIT: 472 case IEEE80211_S_AUTH: 473 case IEEE80211_S_RUN: 474 IEEE80211_DPRINTF(("%s: invalid transition\n", 475 __func__)); 476 break; 477 case IEEE80211_S_SCAN: /* adhoc/hostap mode */ 478 case IEEE80211_S_ASSOC: /* infra mode */ 479 KASSERT(ni->ni_txrate < ni->ni_rates.rs_nrates, 480 ("%s: bogus xmit rate %u setup\n", __func__, 481 ni->ni_txrate)); 482 if (ifp->if_flags & IFF_DEBUG) { 483 if_printf(ifp, " "); 484 if (ic->ic_opmode == IEEE80211_M_STA) 485 printf("associated "); 486 else 487 printf("synchronized "); 488 printf("with %s ssid ", 489 ether_sprintf(ni->ni_bssid)); 490 ieee80211_print_essid(ic->ic_bss->ni_essid, 491 ni->ni_esslen); 492 printf(" channel %d start %uMb\n", 493 ieee80211_chan2ieee(ic, ni->ni_chan), 494 IEEE80211_RATE2MBS(ni->ni_rates.rs_rates[ni->ni_txrate])); 495 } 496 ic->ic_mgt_timer = 0; 497 (*ifp->if_start)(ifp); 498 break; 499 } 500 break; 501 } 502 return 0; 503 } 504