1 /*- 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002-2009 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$"); 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/endian.h> 37 #include <sys/kernel.h> 38 39 #include <sys/socket.h> 40 41 #include <net/ethernet.h> 42 #include <net/if.h> 43 #include <net/if_var.h> 44 #include <net/if_llc.h> 45 #include <net/if_media.h> 46 #if defined(__DragonFly__) 47 #include <net/vlan/if_vlan_var.h> 48 #else 49 #include <net/if_vlan_var.h> 50 #endif 51 52 #include <netproto/802_11/ieee80211_var.h> 53 #include <netproto/802_11/ieee80211_input.h> 54 #ifdef IEEE80211_SUPPORT_MESH 55 #include <netproto/802_11/ieee80211_mesh.h> 56 #endif 57 58 #include <net/bpf.h> 59 60 #ifdef INET 61 #include <netinet/in.h> 62 #include <net/ethernet.h> 63 #endif 64 65 static void 66 ieee80211_process_mimo(struct ieee80211_node *ni, struct ieee80211_rx_stats *rx) 67 { 68 int i; 69 70 /* Verify the required MIMO bits are set */ 71 if ((rx->r_flags & (IEEE80211_R_C_CHAIN | IEEE80211_R_C_NF | IEEE80211_R_C_RSSI)) != 72 (IEEE80211_R_C_CHAIN | IEEE80211_R_C_NF | IEEE80211_R_C_RSSI)) 73 return; 74 75 /* XXX This assumes the MIMO radios have both ctl and ext chains */ 76 for (i = 0; i < MIN(rx->c_chain, IEEE80211_MAX_CHAINS); i++) { 77 IEEE80211_RSSI_LPF(ni->ni_mimo_rssi_ctl[i], rx->c_rssi_ctl[i]); 78 IEEE80211_RSSI_LPF(ni->ni_mimo_rssi_ext[i], rx->c_rssi_ext[i]); 79 } 80 81 /* XXX This also assumes the MIMO radios have both ctl and ext chains */ 82 for(i = 0; i < MIN(rx->c_chain, IEEE80211_MAX_CHAINS); i++) { 83 ni->ni_mimo_noise_ctl[i] = rx->c_nf_ctl[i]; 84 ni->ni_mimo_noise_ext[i] = rx->c_nf_ext[i]; 85 } 86 ni->ni_mimo_chains = rx->c_chain; 87 } 88 89 int 90 ieee80211_input_mimo(struct ieee80211_node *ni, struct mbuf *m, 91 struct ieee80211_rx_stats *rx) 92 { 93 struct ieee80211_rx_stats rxs; 94 95 if (rx) { 96 memcpy(&rxs, rx, sizeof(*rx)); 97 } else { 98 /* try to read from mbuf */ 99 bzero(&rxs, sizeof(rxs)); 100 ieee80211_get_rx_params(m, &rxs); 101 } 102 103 /* XXX should assert IEEE80211_R_NF and IEEE80211_R_RSSI are set */ 104 ieee80211_process_mimo(ni, &rxs); 105 106 //return ieee80211_input(ni, m, rx->rssi, rx->nf); 107 return ni->ni_vap->iv_input(ni, m, &rxs, rxs.rssi, rxs.nf); 108 } 109 110 int 111 ieee80211_input_all(struct ieee80211com *ic, struct mbuf *m, int rssi, int nf) 112 { 113 struct ieee80211_rx_stats rx; 114 115 rx.r_flags = IEEE80211_R_NF | IEEE80211_R_RSSI; 116 rx.nf = nf; 117 rx.rssi = rssi; 118 return ieee80211_input_mimo_all(ic, m, &rx); 119 } 120 121 int 122 ieee80211_input_mimo_all(struct ieee80211com *ic, struct mbuf *m, 123 struct ieee80211_rx_stats *rx) 124 { 125 struct ieee80211_rx_stats rxs; 126 struct ieee80211vap *vap; 127 int type = -1; 128 129 m->m_flags |= M_BCAST; /* NB: mark for bpf tap'ing */ 130 131 if (rx) { 132 memcpy(&rxs, rx, sizeof(*rx)); 133 } else { 134 /* try to read from mbuf */ 135 bzero(&rxs, sizeof(rxs)); 136 ieee80211_get_rx_params(m, &rxs); 137 } 138 139 /* XXX locking */ 140 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { 141 struct ieee80211_node *ni; 142 struct mbuf *mcopy; 143 144 /* NB: could check for IFF_UP but this is cheaper */ 145 if (vap->iv_state == IEEE80211_S_INIT) 146 continue; 147 /* 148 * WDS vap's only receive directed traffic from the 149 * station at the ``far end''. That traffic should 150 * be passed through the AP vap the station is associated 151 * to--so don't spam them with mcast frames. 152 */ 153 if (vap->iv_opmode == IEEE80211_M_WDS) 154 continue; 155 if (TAILQ_NEXT(vap, iv_next) != NULL) { 156 /* 157 * Packet contents are changed by ieee80211_decap 158 * so do a deep copy of the packet. 159 */ 160 mcopy = m_dup(m, M_NOWAIT); 161 if (mcopy == NULL) { 162 /* XXX stat+msg */ 163 continue; 164 } 165 } else { 166 mcopy = m; 167 m = NULL; 168 } 169 ni = ieee80211_ref_node(vap->iv_bss); 170 type = ieee80211_input_mimo(ni, mcopy, &rxs); 171 ieee80211_free_node(ni); 172 } 173 if (m != NULL) /* no vaps, reclaim mbuf */ 174 m_freem(m); 175 return type; 176 } 177 178 /* 179 * This function reassembles fragments. 180 * 181 * XXX should handle 3 concurrent reassemblies per-spec. 182 */ 183 struct mbuf * 184 ieee80211_defrag(struct ieee80211_node *ni, struct mbuf *m, int hdrspace) 185 { 186 struct ieee80211vap *vap = ni->ni_vap; 187 struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); 188 struct ieee80211_frame *lwh; 189 uint16_t rxseq; 190 uint8_t fragno; 191 uint8_t more_frag = wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG; 192 struct mbuf *mfrag; 193 194 KASSERT(!IEEE80211_IS_MULTICAST(wh->i_addr1), ("multicast fragm?")); 195 196 rxseq = le16toh(*(uint16_t *)wh->i_seq); 197 fragno = rxseq & IEEE80211_SEQ_FRAG_MASK; 198 199 /* Quick way out, if there's nothing to defragment */ 200 if (!more_frag && fragno == 0 && ni->ni_rxfrag[0] == NULL) 201 return m; 202 203 /* 204 * Remove frag to insure it doesn't get reaped by timer. 205 */ 206 if (ni->ni_table == NULL) { 207 /* 208 * Should never happen. If the node is orphaned (not in 209 * the table) then input packets should not reach here. 210 * Otherwise, a concurrent request that yanks the table 211 * should be blocked by other interlocking and/or by first 212 * shutting the driver down. Regardless, be defensive 213 * here and just bail 214 */ 215 /* XXX need msg+stat */ 216 m_freem(m); 217 return NULL; 218 } 219 IEEE80211_NODE_LOCK(ni->ni_table); 220 mfrag = ni->ni_rxfrag[0]; 221 ni->ni_rxfrag[0] = NULL; 222 IEEE80211_NODE_UNLOCK(ni->ni_table); 223 224 /* 225 * Validate new fragment is in order and 226 * related to the previous ones. 227 */ 228 if (mfrag != NULL) { 229 uint16_t last_rxseq; 230 231 lwh = mtod(mfrag, struct ieee80211_frame *); 232 last_rxseq = le16toh(*(uint16_t *)lwh->i_seq); 233 /* NB: check seq # and frag together */ 234 if (rxseq != last_rxseq+1 || 235 !IEEE80211_ADDR_EQ(wh->i_addr1, lwh->i_addr1) || 236 !IEEE80211_ADDR_EQ(wh->i_addr2, lwh->i_addr2)) { 237 /* 238 * Unrelated fragment or no space for it, 239 * clear current fragments. 240 */ 241 m_freem(mfrag); 242 mfrag = NULL; 243 } 244 } 245 246 if (mfrag == NULL) { 247 if (fragno != 0) { /* !first fragment, discard */ 248 vap->iv_stats.is_rx_defrag++; 249 IEEE80211_NODE_STAT(ni, rx_defrag); 250 m_freem(m); 251 return NULL; 252 } 253 mfrag = m; 254 } else { /* concatenate */ 255 m_adj(m, hdrspace); /* strip header */ 256 #if defined(__DragonFly__) 257 m_cat(mfrag, m); 258 /* NB: m_cat doesn't update the packet header */ 259 mfrag->m_pkthdr.len += m->m_pkthdr.len; 260 #else 261 m_catpkt(mfrag, m); 262 #endif 263 /* track last seqnum and fragno */ 264 lwh = mtod(mfrag, struct ieee80211_frame *); 265 *(uint16_t *) lwh->i_seq = *(uint16_t *) wh->i_seq; 266 } 267 if (more_frag) { /* more to come, save */ 268 ni->ni_rxfragstamp = ticks; 269 ni->ni_rxfrag[0] = mfrag; 270 mfrag = NULL; 271 } 272 return mfrag; 273 } 274 275 void 276 ieee80211_deliver_data(struct ieee80211vap *vap, 277 struct ieee80211_node *ni, struct mbuf *m) 278 { 279 struct ether_header *eh = mtod(m, struct ether_header *); 280 struct ifnet *ifp = vap->iv_ifp; 281 282 /* clear driver/net80211 flags before passing up */ 283 m->m_flags &= ~(M_MCAST | M_BCAST); 284 #if defined(__DragonFly__) 285 #else 286 m_clrprotoflags(m); 287 #endif 288 289 /* NB: see hostap_deliver_data, this path doesn't handle hostap */ 290 KASSERT(vap->iv_opmode != IEEE80211_M_HOSTAP, ("gack, hostap")); 291 /* 292 * Do accounting. 293 */ 294 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); 295 IEEE80211_NODE_STAT(ni, rx_data); 296 IEEE80211_NODE_STAT_ADD(ni, rx_bytes, m->m_pkthdr.len); 297 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 298 m->m_flags |= M_MCAST; /* XXX M_BCAST? */ 299 IEEE80211_NODE_STAT(ni, rx_mcast); 300 } else 301 IEEE80211_NODE_STAT(ni, rx_ucast); 302 m->m_pkthdr.rcvif = ifp; 303 304 if (ni->ni_vlan != 0) { 305 /* attach vlan tag */ 306 #if defined(__DragonFly__) 307 m->m_pkthdr.ether_vlantag = ni->ni_vlan; 308 #else 309 m->m_pkthdr.ether_vtag = ni->ni_vlan; 310 #endif 311 m->m_flags |= M_VLANTAG; 312 } 313 #if defined(__DragonFly__) 314 ifp->if_input(ifp, m, NULL, -1); 315 #else 316 ifp->if_input(ifp, m); 317 #endif 318 } 319 320 struct mbuf * 321 ieee80211_decap(struct ieee80211vap *vap, struct mbuf *m, int hdrlen) 322 { 323 struct ieee80211_qosframe_addr4 wh; 324 struct ether_header *eh; 325 struct llc *llc; 326 327 KASSERT(hdrlen <= sizeof(wh), 328 ("hdrlen %d > max %zd", hdrlen, sizeof(wh))); 329 330 if (m->m_len < hdrlen + sizeof(*llc) && 331 (m = m_pullup(m, hdrlen + sizeof(*llc))) == NULL) { 332 vap->iv_stats.is_rx_tooshort++; 333 /* XXX msg */ 334 return NULL; 335 } 336 memcpy(&wh, mtod(m, caddr_t), hdrlen); 337 llc = (struct llc *)(mtod(m, caddr_t) + hdrlen); 338 if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP && 339 llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 && 340 llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0 && 341 /* NB: preserve AppleTalk frames that have a native SNAP hdr */ 342 !(llc->llc_snap.ether_type == htons(ETHERTYPE_AARP) || 343 llc->llc_snap.ether_type == htons(ETHERTYPE_IPX))) { 344 m_adj(m, hdrlen + sizeof(struct llc) - sizeof(*eh)); 345 llc = NULL; 346 } else { 347 m_adj(m, hdrlen - sizeof(*eh)); 348 } 349 eh = mtod(m, struct ether_header *); 350 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) { 351 case IEEE80211_FC1_DIR_NODS: 352 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); 353 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); 354 break; 355 case IEEE80211_FC1_DIR_TODS: 356 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3); 357 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); 358 break; 359 case IEEE80211_FC1_DIR_FROMDS: 360 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); 361 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3); 362 break; 363 case IEEE80211_FC1_DIR_DSTODS: 364 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3); 365 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr4); 366 break; 367 } 368 #ifndef __NO_STRICT_ALIGNMENT 369 if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), uint32_t)) { 370 m = ieee80211_realign(vap, m, sizeof(*eh)); 371 if (m == NULL) 372 return NULL; 373 } 374 #endif /* !__NO_STRICT_ALIGNMENT */ 375 if (llc != NULL) { 376 eh = mtod(m, struct ether_header *); 377 eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh)); 378 } 379 return m; 380 } 381 382 /* 383 * Decap a frame encapsulated in a fast-frame/A-MSDU. 384 */ 385 struct mbuf * 386 ieee80211_decap1(struct mbuf *m, int *framelen) 387 { 388 #define FF_LLC_SIZE (sizeof(struct ether_header) + sizeof(struct llc)) 389 struct ether_header *eh; 390 struct llc *llc; 391 392 /* 393 * The frame has an 802.3 header followed by an 802.2 394 * LLC header. The encapsulated frame length is in the 395 * first header type field; save that and overwrite it 396 * with the true type field found in the second. Then 397 * copy the 802.3 header up to where it belongs and 398 * adjust the mbuf contents to remove the void. 399 */ 400 if (m->m_len < FF_LLC_SIZE && (m = m_pullup(m, FF_LLC_SIZE)) == NULL) 401 return NULL; 402 eh = mtod(m, struct ether_header *); /* 802.3 header is first */ 403 llc = (struct llc *)&eh[1]; /* 802.2 header follows */ 404 *framelen = ntohs(eh->ether_type) /* encap'd frame size */ 405 + sizeof(struct ether_header) - sizeof(struct llc); 406 eh->ether_type = llc->llc_un.type_snap.ether_type; 407 bcopy(eh, mtod(m, uint8_t *) + sizeof(struct llc), 408 sizeof(struct ether_header)); 409 m_adj(m, sizeof(struct llc)); 410 return m; 411 #undef FF_LLC_SIZE 412 } 413 414 /* 415 * Install received rate set information in the node's state block. 416 */ 417 int 418 ieee80211_setup_rates(struct ieee80211_node *ni, 419 const uint8_t *rates, const uint8_t *xrates, int flags) 420 { 421 struct ieee80211vap *vap = ni->ni_vap; 422 struct ieee80211_rateset *rs = &ni->ni_rates; 423 424 memset(rs, 0, sizeof(*rs)); 425 rs->rs_nrates = rates[1]; 426 memcpy(rs->rs_rates, rates + 2, rs->rs_nrates); 427 if (xrates != NULL) { 428 uint8_t nxrates; 429 /* 430 * Tack on 11g extended supported rate element. 431 */ 432 nxrates = xrates[1]; 433 if (rs->rs_nrates + nxrates > IEEE80211_RATE_MAXSIZE) { 434 nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates; 435 IEEE80211_NOTE(vap, IEEE80211_MSG_XRATE, ni, 436 "extended rate set too large; only using " 437 "%u of %u rates", nxrates, xrates[1]); 438 vap->iv_stats.is_rx_rstoobig++; 439 } 440 memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates); 441 rs->rs_nrates += nxrates; 442 } 443 return ieee80211_fix_rate(ni, rs, flags); 444 } 445 446 /* 447 * Send a management frame error response to the specified 448 * station. If ni is associated with the station then use 449 * it; otherwise allocate a temporary node suitable for 450 * transmitting the frame and then free the reference so 451 * it will go away as soon as the frame has been transmitted. 452 */ 453 void 454 ieee80211_send_error(struct ieee80211_node *ni, 455 const uint8_t mac[IEEE80211_ADDR_LEN], int subtype, int arg) 456 { 457 struct ieee80211vap *vap = ni->ni_vap; 458 int istmp; 459 460 if (ni == vap->iv_bss) { 461 if (vap->iv_state != IEEE80211_S_RUN) { 462 /* 463 * XXX hack until we get rid of this routine. 464 * We can be called prior to the vap reaching 465 * run state under certain conditions in which 466 * case iv_bss->ni_chan will not be setup. 467 * Check for this explicitly and and just ignore 468 * the request. 469 */ 470 return; 471 } 472 ni = ieee80211_tmp_node(vap, mac); 473 if (ni == NULL) { 474 /* XXX msg */ 475 return; 476 } 477 istmp = 1; 478 } else 479 istmp = 0; 480 IEEE80211_SEND_MGMT(ni, subtype, arg); 481 if (istmp) 482 ieee80211_free_node(ni); 483 } 484 485 int 486 ieee80211_alloc_challenge(struct ieee80211_node *ni) 487 { 488 if (ni->ni_challenge == NULL) 489 #if defined(__DragonFly__) 490 ni->ni_challenge = (uint32_t *) kmalloc(IEEE80211_CHALLENGE_LEN, 491 M_80211_NODE, M_INTWAIT); 492 #else 493 ni->ni_challenge = (uint32_t *) 494 IEEE80211_MALLOC(IEEE80211_CHALLENGE_LEN, 495 M_80211_NODE, IEEE80211_M_NOWAIT); 496 #endif 497 if (ni->ni_challenge == NULL) { 498 IEEE80211_NOTE(ni->ni_vap, 499 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, ni, 500 "%s", "shared key challenge alloc failed"); 501 /* XXX statistic */ 502 } 503 return (ni->ni_challenge != NULL); 504 } 505 506 /* 507 * Parse a Beacon or ProbeResponse frame and return the 508 * useful information in an ieee80211_scanparams structure. 509 * Status is set to 0 if no problems were found; otherwise 510 * a bitmask of IEEE80211_BPARSE_* items is returned that 511 * describes the problems detected. 512 */ 513 int 514 ieee80211_parse_beacon(struct ieee80211_node *ni, struct mbuf *m, 515 struct ieee80211_channel *rxchan, struct ieee80211_scanparams *scan) 516 { 517 struct ieee80211vap *vap = ni->ni_vap; 518 struct ieee80211com *ic = ni->ni_ic; 519 struct ieee80211_frame *wh; 520 uint8_t *frm, *efrm; 521 522 wh = mtod(m, struct ieee80211_frame *); 523 frm = (uint8_t *)&wh[1]; 524 efrm = mtod(m, uint8_t *) + m->m_len; 525 scan->status = 0; 526 /* 527 * beacon/probe response frame format 528 * [8] time stamp 529 * [2] beacon interval 530 * [2] capability information 531 * [tlv] ssid 532 * [tlv] supported rates 533 * [tlv] country information 534 * [tlv] channel switch announcement (CSA) 535 * [tlv] parameter set (FH/DS) 536 * [tlv] erp information 537 * [tlv] extended supported rates 538 * [tlv] WME 539 * [tlv] WPA or RSN 540 * [tlv] HT capabilities 541 * [tlv] HT information 542 * [tlv] Atheros capabilities 543 * [tlv] Mesh ID 544 * [tlv] Mesh Configuration 545 */ 546 IEEE80211_VERIFY_LENGTH(efrm - frm, 12, 547 return (scan->status = IEEE80211_BPARSE_BADIELEN)); 548 memset(scan, 0, sizeof(*scan)); 549 scan->tstamp = frm; frm += 8; 550 scan->bintval = le16toh(*(uint16_t *)frm); frm += 2; 551 scan->capinfo = le16toh(*(uint16_t *)frm); frm += 2; 552 scan->bchan = ieee80211_chan2ieee(ic, rxchan); 553 scan->chan = scan->bchan; 554 scan->ies = frm; 555 scan->ies_len = efrm - frm; 556 557 while (efrm - frm > 1) { 558 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, 559 return (scan->status = IEEE80211_BPARSE_BADIELEN)); 560 switch (*frm) { 561 case IEEE80211_ELEMID_SSID: 562 scan->ssid = frm; 563 break; 564 case IEEE80211_ELEMID_RATES: 565 scan->rates = frm; 566 break; 567 case IEEE80211_ELEMID_COUNTRY: 568 scan->country = frm; 569 break; 570 case IEEE80211_ELEMID_CSA: 571 scan->csa = frm; 572 break; 573 case IEEE80211_ELEMID_QUIET: 574 scan->quiet = frm; 575 break; 576 case IEEE80211_ELEMID_FHPARMS: 577 if (ic->ic_phytype == IEEE80211_T_FH) { 578 scan->fhdwell = le16dec(&frm[2]); 579 scan->chan = IEEE80211_FH_CHAN(frm[4], frm[5]); 580 scan->fhindex = frm[6]; 581 } 582 break; 583 case IEEE80211_ELEMID_DSPARMS: 584 /* 585 * XXX hack this since depending on phytype 586 * is problematic for multi-mode devices. 587 */ 588 if (ic->ic_phytype != IEEE80211_T_FH) 589 scan->chan = frm[2]; 590 break; 591 case IEEE80211_ELEMID_TIM: 592 /* XXX ATIM? */ 593 scan->tim = frm; 594 scan->timoff = frm - mtod(m, uint8_t *); 595 break; 596 case IEEE80211_ELEMID_IBSSPARMS: 597 case IEEE80211_ELEMID_CFPARMS: 598 case IEEE80211_ELEMID_PWRCNSTR: 599 case IEEE80211_ELEMID_BSSLOAD: 600 case IEEE80211_ELEMID_APCHANREP: 601 /* NB: avoid debugging complaints */ 602 break; 603 case IEEE80211_ELEMID_XRATES: 604 scan->xrates = frm; 605 break; 606 case IEEE80211_ELEMID_ERP: 607 if (frm[1] != 1) { 608 IEEE80211_DISCARD_IE(vap, 609 IEEE80211_MSG_ELEMID, wh, "ERP", 610 "bad len %u", frm[1]); 611 vap->iv_stats.is_rx_elem_toobig++; 612 break; 613 } 614 scan->erp = frm[2] | 0x100; 615 break; 616 case IEEE80211_ELEMID_HTCAP: 617 scan->htcap = frm; 618 break; 619 case IEEE80211_ELEMID_RSN: 620 scan->rsn = frm; 621 break; 622 case IEEE80211_ELEMID_HTINFO: 623 scan->htinfo = frm; 624 break; 625 #ifdef IEEE80211_SUPPORT_MESH 626 case IEEE80211_ELEMID_MESHID: 627 scan->meshid = frm; 628 break; 629 case IEEE80211_ELEMID_MESHCONF: 630 scan->meshconf = frm; 631 break; 632 #endif 633 /* Extended capabilities; nothing handles it for now */ 634 case IEEE80211_ELEMID_EXTCAP: 635 break; 636 case IEEE80211_ELEMID_VENDOR: 637 if (iswpaoui(frm)) 638 scan->wpa = frm; 639 else if (iswmeparam(frm) || iswmeinfo(frm)) 640 scan->wme = frm; 641 #ifdef IEEE80211_SUPPORT_SUPERG 642 else if (isatherosoui(frm)) 643 scan->ath = frm; 644 #endif 645 #ifdef IEEE80211_SUPPORT_TDMA 646 else if (istdmaoui(frm)) 647 scan->tdma = frm; 648 #endif 649 else if (vap->iv_flags_ht & IEEE80211_FHT_HTCOMPAT) { 650 /* 651 * Accept pre-draft HT ie's if the 652 * standard ones have not been seen. 653 */ 654 if (ishtcapoui(frm)) { 655 if (scan->htcap == NULL) 656 scan->htcap = frm; 657 } else if (ishtinfooui(frm)) { 658 if (scan->htinfo == NULL) 659 scan->htcap = frm; 660 } 661 } 662 break; 663 default: 664 IEEE80211_DISCARD_IE(vap, IEEE80211_MSG_ELEMID, 665 wh, "unhandled", 666 "id %u, len %u", *frm, frm[1]); 667 vap->iv_stats.is_rx_elem_unknown++; 668 break; 669 } 670 frm += frm[1] + 2; 671 } 672 IEEE80211_VERIFY_ELEMENT(scan->rates, IEEE80211_RATE_MAXSIZE, 673 scan->status |= IEEE80211_BPARSE_RATES_INVALID); 674 if (scan->rates != NULL && scan->xrates != NULL) { 675 /* 676 * NB: don't process XRATES if RATES is missing. This 677 * avoids a potential null ptr deref and should be ok 678 * as the return code will already note RATES is missing 679 * (so callers shouldn't otherwise process the frame). 680 */ 681 IEEE80211_VERIFY_ELEMENT(scan->xrates, 682 IEEE80211_RATE_MAXSIZE - scan->rates[1], 683 scan->status |= IEEE80211_BPARSE_XRATES_INVALID); 684 } 685 IEEE80211_VERIFY_ELEMENT(scan->ssid, IEEE80211_NWID_LEN, 686 scan->status |= IEEE80211_BPARSE_SSID_INVALID); 687 if (scan->chan != scan->bchan && ic->ic_phytype != IEEE80211_T_FH) { 688 /* 689 * Frame was received on a channel different from the 690 * one indicated in the DS params element id; 691 * silently discard it. 692 * 693 * NB: this can happen due to signal leakage. 694 * But we should take it for FH phy because 695 * the rssi value should be correct even for 696 * different hop pattern in FH. 697 */ 698 IEEE80211_DISCARD(vap, 699 IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT, 700 wh, NULL, "for off-channel %u (bchan=%u)", 701 scan->chan, scan->bchan); 702 vap->iv_stats.is_rx_chanmismatch++; 703 scan->status |= IEEE80211_BPARSE_OFFCHAN; 704 } 705 if (!(IEEE80211_BINTVAL_MIN <= scan->bintval && 706 scan->bintval <= IEEE80211_BINTVAL_MAX)) { 707 IEEE80211_DISCARD(vap, 708 IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT, 709 wh, NULL, "bogus beacon interval (%d TU)", 710 (int) scan->bintval); 711 vap->iv_stats.is_rx_badbintval++; 712 scan->status |= IEEE80211_BPARSE_BINTVAL_INVALID; 713 } 714 if (scan->country != NULL) { 715 /* 716 * Validate we have at least enough data to extract 717 * the country code. Not sure if we should return an 718 * error instead of discarding the IE; consider this 719 * being lenient as we don't depend on the data for 720 * correct operation. 721 */ 722 IEEE80211_VERIFY_LENGTH(scan->country[1], 3 * sizeof(uint8_t), 723 scan->country = NULL); 724 } 725 if (scan->csa != NULL) { 726 /* 727 * Validate Channel Switch Announcement; this must 728 * be the correct length or we toss the frame. 729 */ 730 IEEE80211_VERIFY_LENGTH(scan->csa[1], 3 * sizeof(uint8_t), 731 scan->status |= IEEE80211_BPARSE_CSA_INVALID); 732 } 733 /* 734 * Process HT ie's. This is complicated by our 735 * accepting both the standard ie's and the pre-draft 736 * vendor OUI ie's that some vendors still use/require. 737 */ 738 if (scan->htcap != NULL) { 739 IEEE80211_VERIFY_LENGTH(scan->htcap[1], 740 scan->htcap[0] == IEEE80211_ELEMID_VENDOR ? 741 4 + sizeof(struct ieee80211_ie_htcap)-2 : 742 sizeof(struct ieee80211_ie_htcap)-2, 743 scan->htcap = NULL); 744 } 745 if (scan->htinfo != NULL) { 746 IEEE80211_VERIFY_LENGTH(scan->htinfo[1], 747 scan->htinfo[0] == IEEE80211_ELEMID_VENDOR ? 748 4 + sizeof(struct ieee80211_ie_htinfo)-2 : 749 sizeof(struct ieee80211_ie_htinfo)-2, 750 scan->htinfo = NULL); 751 } 752 return scan->status; 753 } 754 755 /* 756 * Parse an Action frame. Return 0 on success, non-zero on failure. 757 */ 758 int 759 ieee80211_parse_action(struct ieee80211_node *ni, struct mbuf *m) 760 { 761 struct ieee80211vap *vap = ni->ni_vap; 762 const struct ieee80211_action *ia; 763 struct ieee80211_frame *wh; 764 uint8_t *frm, *efrm; 765 766 /* 767 * action frame format: 768 * [1] category 769 * [1] action 770 * [tlv] parameters 771 */ 772 wh = mtod(m, struct ieee80211_frame *); 773 frm = (u_int8_t *)&wh[1]; 774 efrm = mtod(m, u_int8_t *) + m->m_len; 775 IEEE80211_VERIFY_LENGTH(efrm - frm, 776 sizeof(struct ieee80211_action), return EINVAL); 777 ia = (const struct ieee80211_action *) frm; 778 779 vap->iv_stats.is_rx_action++; 780 IEEE80211_NODE_STAT(ni, rx_action); 781 782 /* verify frame payloads but defer processing */ 783 switch (ia->ia_category) { 784 case IEEE80211_ACTION_CAT_BA: 785 switch (ia->ia_action) { 786 case IEEE80211_ACTION_BA_ADDBA_REQUEST: 787 IEEE80211_VERIFY_LENGTH(efrm - frm, 788 sizeof(struct ieee80211_action_ba_addbarequest), 789 return EINVAL); 790 break; 791 case IEEE80211_ACTION_BA_ADDBA_RESPONSE: 792 IEEE80211_VERIFY_LENGTH(efrm - frm, 793 sizeof(struct ieee80211_action_ba_addbaresponse), 794 return EINVAL); 795 break; 796 case IEEE80211_ACTION_BA_DELBA: 797 IEEE80211_VERIFY_LENGTH(efrm - frm, 798 sizeof(struct ieee80211_action_ba_delba), 799 return EINVAL); 800 break; 801 } 802 break; 803 case IEEE80211_ACTION_CAT_HT: 804 switch (ia->ia_action) { 805 case IEEE80211_ACTION_HT_TXCHWIDTH: 806 IEEE80211_VERIFY_LENGTH(efrm - frm, 807 sizeof(struct ieee80211_action_ht_txchwidth), 808 return EINVAL); 809 break; 810 case IEEE80211_ACTION_HT_MIMOPWRSAVE: 811 IEEE80211_VERIFY_LENGTH(efrm - frm, 812 sizeof(struct ieee80211_action_ht_mimopowersave), 813 return EINVAL); 814 break; 815 } 816 break; 817 #ifdef IEEE80211_SUPPORT_MESH 818 case IEEE80211_ACTION_CAT_MESH: 819 switch (ia->ia_action) { 820 case IEEE80211_ACTION_MESH_LMETRIC: 821 /* 822 * XXX: verification is true only if we are using 823 * Airtime link metric (default) 824 */ 825 IEEE80211_VERIFY_LENGTH(efrm - frm, 826 sizeof(struct ieee80211_meshlmetric_ie), 827 return EINVAL); 828 break; 829 case IEEE80211_ACTION_MESH_HWMP: 830 /* verify something */ 831 break; 832 case IEEE80211_ACTION_MESH_GANN: 833 IEEE80211_VERIFY_LENGTH(efrm - frm, 834 sizeof(struct ieee80211_meshgann_ie), 835 return EINVAL); 836 break; 837 case IEEE80211_ACTION_MESH_CC: 838 case IEEE80211_ACTION_MESH_MCCA_SREQ: 839 case IEEE80211_ACTION_MESH_MCCA_SREP: 840 case IEEE80211_ACTION_MESH_MCCA_AREQ: 841 case IEEE80211_ACTION_MESH_MCCA_ADVER: 842 case IEEE80211_ACTION_MESH_MCCA_TRDOWN: 843 case IEEE80211_ACTION_MESH_TBTT_REQ: 844 case IEEE80211_ACTION_MESH_TBTT_RES: 845 /* reject these early on, not implemented */ 846 IEEE80211_DISCARD(vap, 847 IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT, 848 wh, NULL, "not implemented yet, act=0x%02X", 849 ia->ia_action); 850 return EINVAL; 851 } 852 break; 853 case IEEE80211_ACTION_CAT_SELF_PROT: 854 /* If TA or RA group address discard silently */ 855 if (IEEE80211_IS_MULTICAST(wh->i_addr1) || 856 IEEE80211_IS_MULTICAST(wh->i_addr2)) 857 return EINVAL; 858 /* 859 * XXX: Should we verify complete length now or it is 860 * to varying in sizes? 861 */ 862 switch (ia->ia_action) { 863 case IEEE80211_ACTION_MESHPEERING_CONFIRM: 864 case IEEE80211_ACTION_MESHPEERING_CLOSE: 865 /* is not a peering candidate (yet) */ 866 if (ni == vap->iv_bss) 867 return EINVAL; 868 break; 869 } 870 break; 871 #endif 872 } 873 return 0; 874 } 875 876 #ifdef IEEE80211_DEBUG 877 /* 878 * Debugging support. 879 */ 880 void 881 ieee80211_ssid_mismatch(struct ieee80211vap *vap, const char *tag, 882 uint8_t mac[IEEE80211_ADDR_LEN], uint8_t *ssid) 883 { 884 kprintf("[%s] discard %s frame, ssid mismatch: ", 885 ether_sprintf(mac), tag); 886 ieee80211_print_essid(ssid + 2, ssid[1]); 887 kprintf("\n"); 888 } 889 890 /* 891 * Return the bssid of a frame. 892 */ 893 static const uint8_t * 894 ieee80211_getbssid(const struct ieee80211vap *vap, 895 const struct ieee80211_frame *wh) 896 { 897 if (vap->iv_opmode == IEEE80211_M_STA) 898 return wh->i_addr2; 899 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) != IEEE80211_FC1_DIR_NODS) 900 return wh->i_addr1; 901 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PS_POLL) 902 return wh->i_addr1; 903 return wh->i_addr3; 904 } 905 906 #include <machine/stdarg.h> 907 908 void 909 ieee80211_note(const struct ieee80211vap *vap, const char *fmt, ...) 910 { 911 char buf[128]; /* XXX */ 912 #if defined(__DragonFly__) 913 osdep_va_list ap; 914 915 osdep_va_start(ap, fmt); 916 kvsnprintf(buf, sizeof(buf), fmt, ap); 917 osdep_va_end(ap); 918 #else 919 va_list ap; 920 921 va_start(ap, fmt); 922 vsnprintf(buf, sizeof(buf), fmt, ap); 923 va_end(ap); 924 #endif 925 926 if_printf(vap->iv_ifp, "%s", buf); /* NB: no \n */ 927 } 928 929 void 930 ieee80211_note_frame(const struct ieee80211vap *vap, 931 const struct ieee80211_frame *wh, 932 const char *fmt, ...) 933 { 934 char buf[128]; /* XXX */ 935 #if defined(__DragonFly__) 936 osdep_va_list ap; 937 938 osdep_va_start(ap, fmt); 939 kvsnprintf(buf, sizeof(buf), fmt, ap); 940 osdep_va_end(ap); 941 #else 942 va_list ap; 943 944 va_start(ap, fmt); 945 vsnprintf(buf, sizeof(buf), fmt, ap); 946 va_end(ap); 947 #endif 948 if_printf(vap->iv_ifp, "[%s] %s\n", 949 ether_sprintf(ieee80211_getbssid(vap, wh)), buf); 950 } 951 952 void 953 ieee80211_note_mac(const struct ieee80211vap *vap, 954 const uint8_t mac[IEEE80211_ADDR_LEN], 955 const char *fmt, ...) 956 { 957 char buf[128]; /* XXX */ 958 #if defined(__DragonFly__) 959 osdep_va_list ap; 960 961 osdep_va_start(ap, fmt); 962 kvsnprintf(buf, sizeof(buf), fmt, ap); 963 osdep_va_end(ap); 964 #else 965 va_list ap; 966 967 va_start(ap, fmt); 968 vsnprintf(buf, sizeof(buf), fmt, ap); 969 va_end(ap); 970 #endif 971 if_printf(vap->iv_ifp, "[%s] %s\n", ether_sprintf(mac), buf); 972 } 973 974 void 975 ieee80211_discard_frame(const struct ieee80211vap *vap, 976 const struct ieee80211_frame *wh, 977 const char *type, const char *fmt, ...) 978 { 979 #if defined(__DragonFly__) 980 osdep_va_list ap; 981 982 if_printf(vap->iv_ifp, "[%s] discard ", 983 ether_sprintf(ieee80211_getbssid(vap, wh))); 984 kprintf("%s frame, ", type != NULL ? type : 985 ieee80211_mgt_subtype_name(wh->i_fc[0])); 986 osdep_va_start(ap, fmt); 987 kvprintf(fmt, ap); 988 osdep_va_end(ap); 989 #else 990 va_list ap; 991 992 if_printf(vap->iv_ifp, "[%s] discard ", 993 ether_sprintf(ieee80211_getbssid(vap, wh))); 994 printf("%s frame, ", type != NULL ? type : 995 ieee80211_mgt_subtype_name(wh->i_fc[0])); 996 va_start(ap, fmt); 997 vprintf(fmt, ap); 998 va_end(ap); 999 #endif 1000 kprintf("\n"); 1001 } 1002 1003 void 1004 ieee80211_discard_ie(const struct ieee80211vap *vap, 1005 const struct ieee80211_frame *wh, 1006 const char *type, const char *fmt, ...) 1007 { 1008 osdep_va_list ap; 1009 1010 #if defined(__DragonFly__) 1011 if_printf(vap->iv_ifp, "[%s] discard ", 1012 ether_sprintf(ieee80211_getbssid(vap, wh))); 1013 if (type != NULL) 1014 kprintf("%s information element, ", type); 1015 else 1016 kprintf("information element, "); 1017 osdep_va_start(ap, fmt); 1018 kvprintf(fmt, ap); 1019 osdep_va_end(ap); 1020 kprintf("\n"); 1021 #else 1022 if_printf(vap->iv_ifp, "[%s] discard ", 1023 ether_sprintf(ieee80211_getbssid(vap, wh))); 1024 if (type != NULL) 1025 printf("%s information element, ", type); 1026 else 1027 printf("information element, "); 1028 va_start(ap, fmt); 1029 vprintf(fmt, ap); 1030 va_end(ap); 1031 printf("\n"); 1032 #endif 1033 } 1034 1035 void 1036 ieee80211_discard_mac(const struct ieee80211vap *vap, 1037 const uint8_t mac[IEEE80211_ADDR_LEN], 1038 const char *type, const char *fmt, ...) 1039 { 1040 #if defined(__DragonFly__) 1041 osdep_va_list ap; 1042 1043 if_printf(vap->iv_ifp, "[%s] discard ", ether_sprintf(mac)); 1044 if (type != NULL) 1045 kprintf("%s frame, ", type); 1046 else 1047 kprintf("frame, "); 1048 osdep_va_start(ap, fmt); 1049 kvprintf(fmt, ap); 1050 osdep_va_end(ap); 1051 #else 1052 va_list ap; 1053 1054 if_printf(vap->iv_ifp, "[%s] discard ", ether_sprintf(mac)); 1055 if (type != NULL) 1056 printf("%s frame, ", type); 1057 else 1058 printf("frame, "); 1059 va_start(ap, fmt); 1060 vprintf(fmt, ap); 1061 va_end(ap); 1062 #endif 1063 kprintf("\n"); 1064 } 1065 #endif /* IEEE80211_DEBUG */ 1066