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