1 /*- 2 * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include <sys/cdefs.h> 27 #ifdef __FreeBSD__ 28 __FBSDID("$FreeBSD$"); 29 #endif 30 31 /* 32 * IEEE 802.11 WDS mode support. 33 */ 34 #include "opt_inet.h" 35 #include "opt_wlan.h" 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/mbuf.h> 40 #include <sys/malloc.h> 41 #include <sys/kernel.h> 42 43 #include <sys/socket.h> 44 #include <sys/sockio.h> 45 #include <sys/endian.h> 46 #include <sys/errno.h> 47 #include <sys/proc.h> 48 #include <sys/sysctl.h> 49 50 #include <net/if.h> 51 #include <net/if_media.h> 52 #include <net/if_llc.h> 53 #include <net/ethernet.h> 54 55 #include <net/bpf.h> 56 57 #include <net80211/ieee80211_var.h> 58 #include <net80211/ieee80211_wds.h> 59 #include <net80211/ieee80211_input.h> 60 61 static void wds_vattach(struct ieee80211vap *); 62 static int wds_newstate(struct ieee80211vap *, enum ieee80211_state, int); 63 static int wds_input(struct ieee80211_node *ni, struct mbuf *m, 64 int rssi, int noise, uint32_t rstamp); 65 static void wds_recv_mgmt(struct ieee80211_node *, struct mbuf *, 66 int subtype, int rssi, int noise, u_int32_t rstamp); 67 68 void 69 ieee80211_wds_attach(struct ieee80211com *ic) 70 { 71 ic->ic_vattach[IEEE80211_M_WDS] = wds_vattach; 72 } 73 74 void 75 ieee80211_wds_detach(struct ieee80211com *ic) 76 { 77 } 78 79 static void 80 wds_vdetach(struct ieee80211vap *vap) 81 { 82 if (vap->iv_bss != NULL) { 83 /* XXX locking? */ 84 if (vap->iv_bss->ni_wdsvap == vap) 85 vap->iv_bss->ni_wdsvap = NULL; 86 } 87 } 88 89 static void 90 wds_vattach(struct ieee80211vap *vap) 91 { 92 vap->iv_newstate = wds_newstate; 93 vap->iv_input = wds_input; 94 vap->iv_recv_mgmt = wds_recv_mgmt; 95 vap->iv_opdetach = wds_vdetach; 96 } 97 98 static int 99 ieee80211_create_wds(struct ieee80211vap *vap, struct ieee80211_channel *chan) 100 { 101 struct ieee80211com *ic = vap->iv_ic; 102 struct ieee80211_node_table *nt = &ic->ic_sta; 103 struct ieee80211_node *ni, *obss; 104 105 IEEE80211_DPRINTF(vap, IEEE80211_MSG_WDS, 106 "%s: creating link to %s on channel %u\n", __func__, 107 ether_sprintf(vap->iv_des_bssid), ieee80211_chan2ieee(ic, chan)); 108 109 /* NB: vap create must specify the bssid for the link */ 110 KASSERT(vap->iv_flags & IEEE80211_F_DESBSSID, ("no bssid")); 111 /* NB: we should only be called on RUN transition */ 112 KASSERT(vap->iv_state == IEEE80211_S_RUN, ("!RUN state")); 113 114 if ((vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY) == 0) { 115 /* 116 * Dynamic/non-legacy WDS. Reference the associated 117 * station specified by the desired bssid setup at vap 118 * create. Point ni_wdsvap at the WDS vap so 4-address 119 * frames received through the associated AP vap will 120 * be dispatched upward (e.g. to a bridge) as though 121 * they arrived on the WDS vap. 122 */ 123 IEEE80211_NODE_LOCK(nt); 124 obss = NULL; 125 ni = ieee80211_find_node_locked(&ic->ic_sta, vap->iv_des_bssid); 126 if (ni == NULL) { 127 /* 128 * Node went away before we could hookup. This 129 * should be ok; no traffic will flow and a leave 130 * event will be dispatched that should cause 131 * the vap to be destroyed. 132 */ 133 IEEE80211_DPRINTF(vap, IEEE80211_MSG_WDS, 134 "%s: station %s went away\n", 135 __func__, ether_sprintf(vap->iv_des_bssid)); 136 /* XXX stat? */ 137 } else if (ni->ni_wdsvap != NULL) { 138 /* 139 * Node already setup with a WDS vap; we cannot 140 * allow multiple references so disallow. If 141 * ni_wdsvap points at us that's ok; we should 142 * do nothing anyway. 143 */ 144 /* XXX printf instead? */ 145 IEEE80211_DPRINTF(vap, IEEE80211_MSG_WDS, 146 "%s: station %s in use with %s\n", 147 __func__, ether_sprintf(vap->iv_des_bssid), 148 ni->ni_wdsvap->iv_ifp->if_xname); 149 /* XXX stat? */ 150 } else { 151 /* 152 * Committed to new node, setup state. 153 */ 154 obss = vap->iv_bss; 155 vap->iv_bss = ni; 156 ni->ni_wdsvap = vap; 157 } 158 IEEE80211_NODE_UNLOCK(nt); 159 if (obss != NULL) { 160 /* NB: deferred to avoid recursive lock */ 161 ieee80211_free_node(obss); 162 } 163 } else { 164 /* 165 * Legacy WDS vap setup. 166 */ 167 /* 168 * The far end does not associate so we just create 169 * create a new node and install it as the vap's 170 * bss node. We must simulate an association and 171 * authorize the port for traffic to flow. 172 * XXX check if node already in sta table? 173 */ 174 ni = ieee80211_node_create_wds(vap, vap->iv_des_bssid, chan); 175 if (ni != NULL) { 176 obss = vap->iv_bss; 177 vap->iv_bss = ieee80211_ref_node(ni); 178 ni->ni_flags |= IEEE80211_NODE_AREF; 179 if (obss != NULL) 180 ieee80211_free_node(obss); 181 /* give driver a chance to setup state like ni_txrate */ 182 if (ic->ic_newassoc != NULL) 183 ic->ic_newassoc(ni, 1); 184 /* tell the authenticator about new station */ 185 if (vap->iv_auth->ia_node_join != NULL) 186 vap->iv_auth->ia_node_join(ni); 187 if (ni->ni_authmode != IEEE80211_AUTH_8021X) 188 ieee80211_node_authorize(ni); 189 190 ieee80211_notify_node_join(ni, 1 /*newassoc*/); 191 /* XXX inject l2uf frame */ 192 } 193 } 194 195 /* 196 * Flush pending frames now that were setup. 197 */ 198 if (ni != NULL && IEEE80211_NODE_WDSQ_QLEN(ni) != 0) { 199 int8_t rssi, noise; 200 201 IEEE80211_NOTE(vap, IEEE80211_MSG_WDS, ni, 202 "flush wds queue, %u packets queued", 203 IEEE80211_NODE_WDSQ_QLEN(ni)); 204 ic->ic_node_getsignal(ni, &rssi, &noise); 205 for (;;) { 206 struct mbuf *m; 207 208 IEEE80211_NODE_WDSQ_LOCK(ni); 209 _IEEE80211_NODE_WDSQ_DEQUEUE_HEAD(ni, m); 210 IEEE80211_NODE_WDSQ_UNLOCK(ni); 211 if (m == NULL) 212 break; 213 /* XXX cheat and re-use last rstamp */ 214 ieee80211_input(ni, m, rssi, noise, ni->ni_rstamp); 215 } 216 } 217 return (ni == NULL ? ENOENT : 0); 218 } 219 220 /* 221 * Propagate multicast frames of an ap vap to all DWDS links. 222 * The caller is assumed to have verified this frame is multicast. 223 */ 224 void 225 ieee80211_dwds_mcast(struct ieee80211vap *vap0, struct mbuf *m) 226 { 227 struct ieee80211com *ic = vap0->iv_ic; 228 struct ifnet *parent = ic->ic_ifp; 229 const struct ether_header *eh = mtod(m, const struct ether_header *); 230 struct ieee80211_node *ni; 231 struct ieee80211vap *vap; 232 struct ifnet *ifp; 233 struct mbuf *mcopy; 234 int err; 235 236 KASSERT(ETHER_IS_MULTICAST(eh->ether_dhost), 237 ("%s not mcast", ether_sprintf(eh->ether_dhost))); 238 239 /* XXX locking */ 240 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { 241 /* only DWDS vaps are interesting */ 242 if (vap->iv_opmode != IEEE80211_M_WDS || 243 (vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY)) 244 continue; 245 /* if it came in this interface, don't send it back out */ 246 ifp = vap->iv_ifp; 247 if (ifp == m->m_pkthdr.rcvif) 248 continue; 249 /* 250 * Duplicate the frame and send it. We don't need 251 * to classify or lookup the tx node; this was already 252 * done by the caller so we can just re-use the info. 253 */ 254 mcopy = m_copypacket(m, M_DONTWAIT); 255 if (mcopy == NULL) { 256 ifp->if_oerrors++; 257 /* XXX stat + msg */ 258 continue; 259 } 260 ni = ieee80211_find_txnode(vap, eh->ether_dhost); 261 if (ni == NULL) { 262 /* NB: ieee80211_find_txnode does stat+msg */ 263 ifp->if_oerrors++; 264 m_freem(mcopy); 265 continue; 266 } 267 if (ieee80211_classify(ni, mcopy)) { 268 IEEE80211_DISCARD_MAC(vap, 269 IEEE80211_MSG_OUTPUT | IEEE80211_MSG_WDS, 270 eh->ether_dhost, NULL, 271 "%s", "classification failure"); 272 vap->iv_stats.is_tx_classify++; 273 ifp->if_oerrors++; 274 m_freem(mcopy); 275 ieee80211_free_node(ni); 276 continue; 277 } 278 mcopy->m_flags |= M_MCAST | M_WDS; 279 mcopy->m_pkthdr.rcvif = (void *) ni; 280 281 IFQ_HANDOFF(parent, mcopy, err); 282 if (err) { 283 /* NB: IFQ_HANDOFF reclaims mbuf */ 284 ifp->if_oerrors++; 285 ieee80211_free_node(ni); 286 } else 287 ifp->if_opackets++; 288 } 289 } 290 291 /* 292 * Handle DWDS discovery on receipt of a 4-address frame in 293 * ap mode. Queue the frame and post an event for someone 294 * to plumb the necessary WDS vap for this station. Frames 295 * received prior to the vap set running will then be reprocessed 296 * as if they were just received. 297 */ 298 void 299 ieee80211_dwds_discover(struct ieee80211_node *ni, struct mbuf *m) 300 { 301 struct ieee80211vap *vap = ni->ni_vap; 302 struct ieee80211com *ic = ni->ni_ic; 303 int qlen, age; 304 305 IEEE80211_NODE_WDSQ_LOCK(ni); 306 if (!_IF_QFULL(&ni->ni_wdsq)) { 307 /* 308 * Tag the frame with it's expiry time and insert 309 * it in the queue. The aging interval is 4 times 310 * the listen interval specified by the station. 311 * Frames that sit around too long are reclaimed 312 * using this information. 313 */ 314 /* XXX handle overflow? */ 315 /* XXX per/vap beacon interval? */ 316 /* NB: TU -> secs */ 317 age = ((ni->ni_intval * ic->ic_lintval) << 2) / 1024; 318 _IEEE80211_NODE_WDSQ_ENQUEUE(ni, m, qlen, age); 319 IEEE80211_NODE_WDSQ_UNLOCK(ni); 320 321 IEEE80211_NOTE(vap, IEEE80211_MSG_WDS, ni, 322 "save frame, %u now queued", qlen); 323 } else { 324 vap->iv_stats.is_dwds_qdrop++; 325 _IF_DROP(&ni->ni_wdsq); 326 IEEE80211_NODE_WDSQ_UNLOCK(ni); 327 328 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT | IEEE80211_MSG_WDS, 329 mtod(m, struct ieee80211_frame *), "wds data", 330 "pending q overflow, drops %d (len %d)", 331 ni->ni_wdsq.ifq_drops, ni->ni_wdsq.ifq_len); 332 333 #ifdef IEEE80211_DEBUG 334 if (ieee80211_msg_dumppkts(vap)) 335 ieee80211_dump_pkt(ic, mtod(m, caddr_t), 336 m->m_len, -1, -1); 337 #endif 338 /* XXX tail drop? */ 339 m_freem(m); 340 } 341 ieee80211_notify_wds_discover(ni); 342 } 343 344 /* 345 * Age frames on the WDS pending queue. The aging interval is 346 * 4 times the listen interval specified by the station. This 347 * number is factored into the age calculations when the frame 348 * is placed on the queue. We store ages as time differences 349 * so we can check and/or adjust only the head of the list. 350 * If a frame's age exceeds the threshold then discard it. 351 * The number of frames discarded is returned to the caller. 352 */ 353 int 354 ieee80211_node_wdsq_age(struct ieee80211_node *ni) 355 { 356 #ifdef IEEE80211_DEBUG 357 struct ieee80211vap *vap = ni->ni_vap; 358 #endif 359 struct mbuf *m; 360 int discard = 0; 361 362 IEEE80211_NODE_WDSQ_LOCK(ni); 363 while (_IF_POLL(&ni->ni_wdsq, m) != NULL && 364 M_AGE_GET(m) < IEEE80211_INACT_WAIT) { 365 IEEE80211_NOTE(vap, IEEE80211_MSG_WDS, ni, 366 "discard frame, age %u", M_AGE_GET(m)); 367 368 /* XXX could be optimized */ 369 _IEEE80211_NODE_WDSQ_DEQUEUE_HEAD(ni, m); 370 m_freem(m); 371 discard++; 372 } 373 if (m != NULL) 374 M_AGE_SUB(m, IEEE80211_INACT_WAIT); 375 IEEE80211_NODE_WDSQ_UNLOCK(ni); 376 377 IEEE80211_NOTE(vap, IEEE80211_MSG_WDS, ni, 378 "discard %u frames for age", discard); 379 #if 0 380 IEEE80211_NODE_STAT_ADD(ni, wds_discard, discard); 381 #endif 382 return discard; 383 } 384 385 /* 386 * IEEE80211_M_WDS vap state machine handler. 387 */ 388 static int 389 wds_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 390 { 391 struct ieee80211com *ic = vap->iv_ic; 392 struct ieee80211_node *ni; 393 enum ieee80211_state ostate; 394 int error; 395 396 IEEE80211_LOCK_ASSERT(ic); 397 398 ostate = vap->iv_state; 399 IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s\n", __func__, 400 ieee80211_state_name[ostate], ieee80211_state_name[nstate]); 401 vap->iv_state = nstate; /* state transition */ 402 callout_stop(&vap->iv_mgtsend); /* XXX callout_drain */ 403 if (ostate != IEEE80211_S_SCAN) 404 ieee80211_cancel_scan(vap); /* background scan */ 405 ni = vap->iv_bss; /* NB: no reference held */ 406 error = 0; 407 switch (nstate) { 408 case IEEE80211_S_INIT: 409 switch (ostate) { 410 case IEEE80211_S_SCAN: 411 ieee80211_cancel_scan(vap); 412 break; 413 default: 414 break; 415 } 416 if (ostate != IEEE80211_S_INIT) { 417 /* NB: optimize INIT -> INIT case */ 418 ieee80211_reset_bss(vap); 419 } 420 break; 421 case IEEE80211_S_SCAN: 422 switch (ostate) { 423 case IEEE80211_S_INIT: 424 ieee80211_check_scan_current(vap); 425 break; 426 default: 427 break; 428 } 429 break; 430 case IEEE80211_S_RUN: 431 if (ostate == IEEE80211_S_INIT) { 432 /* 433 * Already have a channel; bypass the scan 434 * and startup immediately. 435 */ 436 error = ieee80211_create_wds(vap, ic->ic_curchan); 437 } 438 break; 439 default: 440 break; 441 } 442 return error; 443 } 444 445 /* 446 * Process a received frame. The node associated with the sender 447 * should be supplied. If nothing was found in the node table then 448 * the caller is assumed to supply a reference to iv_bss instead. 449 * The RSSI and a timestamp are also supplied. The RSSI data is used 450 * during AP scanning to select a AP to associate with; it can have 451 * any units so long as values have consistent units and higher values 452 * mean ``better signal''. The receive timestamp is currently not used 453 * by the 802.11 layer. 454 */ 455 static int 456 wds_input(struct ieee80211_node *ni, struct mbuf *m, 457 int rssi, int noise, uint32_t rstamp) 458 { 459 #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) 460 #define HAS_SEQ(type) ((type & 0x4) == 0) 461 struct ieee80211vap *vap = ni->ni_vap; 462 struct ieee80211com *ic = ni->ni_ic; 463 struct ifnet *ifp = vap->iv_ifp; 464 struct ieee80211_frame *wh; 465 struct ieee80211_key *key; 466 struct ether_header *eh; 467 int hdrspace, need_tap; 468 uint8_t dir, type, subtype, qos; 469 uint16_t rxseq; 470 471 if (m->m_flags & M_AMPDU) { 472 /* 473 * Fastpath for A-MPDU reorder q resubmission. Frames 474 * w/ M_AMPDU marked have already passed through here 475 * but were received out of order and been held on the 476 * reorder queue. When resubmitted they are marked 477 * with the M_AMPDU flag and we can bypass most of the 478 * normal processing. 479 */ 480 wh = mtod(m, struct ieee80211_frame *); 481 type = IEEE80211_FC0_TYPE_DATA; 482 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 483 subtype = IEEE80211_FC0_SUBTYPE_QOS; 484 hdrspace = ieee80211_hdrspace(ic, wh); /* XXX optimize? */ 485 goto resubmit_ampdu; 486 } 487 488 KASSERT(ni != NULL, ("null node")); 489 490 need_tap = 1; /* mbuf need to be tapped. */ 491 type = -1; /* undefined */ 492 493 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) { 494 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, 495 ni->ni_macaddr, NULL, 496 "too short (1): len %u", m->m_pkthdr.len); 497 vap->iv_stats.is_rx_tooshort++; 498 goto out; 499 } 500 /* 501 * Bit of a cheat here, we use a pointer for a 3-address 502 * frame format but don't reference fields past outside 503 * ieee80211_frame_min w/o first validating the data is 504 * present. 505 */ 506 wh = mtod(m, struct ieee80211_frame *); 507 508 if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != 509 IEEE80211_FC0_VERSION_0) { 510 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, 511 ni->ni_macaddr, NULL, "wrong version %x", wh->i_fc[0]); 512 vap->iv_stats.is_rx_badversion++; 513 goto err; 514 } 515 516 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 517 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 518 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 519 520 /* NB: WDS vap's do not scan */ 521 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_addr4)) { 522 IEEE80211_DISCARD_MAC(vap, 523 IEEE80211_MSG_ANY, ni->ni_macaddr, NULL, 524 "too short (3): len %u", m->m_pkthdr.len); 525 vap->iv_stats.is_rx_tooshort++; 526 goto out; 527 } 528 /* NB: the TA is implicitly verified by finding the wds peer node */ 529 if (!IEEE80211_ADDR_EQ(wh->i_addr1, vap->iv_myaddr) && 530 !IEEE80211_ADDR_EQ(wh->i_addr1, ifp->if_broadcastaddr)) { 531 /* not interested in */ 532 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, 533 wh->i_addr1, NULL, "%s", "not to bss"); 534 vap->iv_stats.is_rx_wrongbss++; 535 goto out; 536 } 537 IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); 538 ni->ni_noise = noise; 539 ni->ni_rstamp = rstamp; 540 if (HAS_SEQ(type)) { 541 uint8_t tid = ieee80211_gettid(wh); 542 if (IEEE80211_QOS_HAS_SEQ(wh) && 543 TID_TO_WME_AC(tid) >= WME_AC_VI) 544 ic->ic_wme.wme_hipri_traffic++; 545 rxseq = le16toh(*(uint16_t *)wh->i_seq); 546 if ((ni->ni_flags & IEEE80211_NODE_HT) == 0 && 547 (wh->i_fc[1] & IEEE80211_FC1_RETRY) && 548 SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) { 549 /* duplicate, discard */ 550 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, 551 wh->i_addr1, "duplicate", 552 "seqno <%u,%u> fragno <%u,%u> tid %u", 553 rxseq >> IEEE80211_SEQ_SEQ_SHIFT, 554 ni->ni_rxseqs[tid] >> IEEE80211_SEQ_SEQ_SHIFT, 555 rxseq & IEEE80211_SEQ_FRAG_MASK, 556 ni->ni_rxseqs[tid] & IEEE80211_SEQ_FRAG_MASK, 557 tid); 558 vap->iv_stats.is_rx_dup++; 559 IEEE80211_NODE_STAT(ni, rx_dup); 560 goto out; 561 } 562 ni->ni_rxseqs[tid] = rxseq; 563 } 564 switch (type) { 565 case IEEE80211_FC0_TYPE_DATA: 566 hdrspace = ieee80211_hdrspace(ic, wh); 567 if (m->m_len < hdrspace && 568 (m = m_pullup(m, hdrspace)) == NULL) { 569 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, 570 ni->ni_macaddr, NULL, 571 "data too short: expecting %u", hdrspace); 572 vap->iv_stats.is_rx_tooshort++; 573 goto out; /* XXX */ 574 } 575 if (dir != IEEE80211_FC1_DIR_DSTODS) { 576 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 577 wh, "data", "incorrect dir 0x%x", dir); 578 vap->iv_stats.is_rx_wrongdir++; 579 goto out; 580 } 581 /* 582 * Only legacy WDS traffic should take this path. 583 */ 584 if ((vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY) == 0) { 585 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 586 wh, "data", "%s", "not legacy wds"); 587 vap->iv_stats.is_rx_wrongdir++;/*XXX*/ 588 goto out; 589 } 590 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) 591 ni->ni_inact = ni->ni_inact_reload; 592 /* 593 * Handle A-MPDU re-ordering. The station must be 594 * associated and negotiated HT. The frame must be 595 * a QoS frame (not QoS null data) and not previously 596 * processed for A-MPDU re-ordering. If the frame is 597 * to be processed directly then ieee80211_ampdu_reorder 598 * will return 0; otherwise it has consumed the mbuf 599 * and we should do nothing more with it. 600 */ 601 if ((ni->ni_flags & IEEE80211_NODE_HT) && 602 subtype == IEEE80211_FC0_SUBTYPE_QOS && 603 ieee80211_ampdu_reorder(ni, m) != 0) { 604 m = NULL; 605 goto out; 606 } 607 resubmit_ampdu: 608 609 /* 610 * Handle privacy requirements. Note that we 611 * must not be preempted from here until after 612 * we (potentially) call ieee80211_crypto_demic; 613 * otherwise we may violate assumptions in the 614 * crypto cipher modules used to do delayed update 615 * of replay sequence numbers. 616 */ 617 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 618 if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { 619 /* 620 * Discard encrypted frames when privacy is off. 621 */ 622 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 623 wh, "WEP", "%s", "PRIVACY off"); 624 vap->iv_stats.is_rx_noprivacy++; 625 IEEE80211_NODE_STAT(ni, rx_noprivacy); 626 goto out; 627 } 628 key = ieee80211_crypto_decap(ni, m, hdrspace); 629 if (key == NULL) { 630 /* NB: stats+msgs handled in crypto_decap */ 631 IEEE80211_NODE_STAT(ni, rx_wepfail); 632 goto out; 633 } 634 wh = mtod(m, struct ieee80211_frame *); 635 wh->i_fc[1] &= ~IEEE80211_FC1_WEP; 636 } else { 637 /* XXX M_WEP and IEEE80211_F_PRIVACY */ 638 key = NULL; 639 } 640 641 /* 642 * Save QoS bits for use below--before we strip the header. 643 */ 644 if (subtype == IEEE80211_FC0_SUBTYPE_QOS) { 645 qos = (dir == IEEE80211_FC1_DIR_DSTODS) ? 646 ((struct ieee80211_qosframe_addr4 *)wh)->i_qos[0] : 647 ((struct ieee80211_qosframe *)wh)->i_qos[0]; 648 } else 649 qos = 0; 650 651 /* 652 * Next up, any fragmentation. 653 */ 654 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 655 m = ieee80211_defrag(ni, m, hdrspace); 656 if (m == NULL) { 657 /* Fragment dropped or frame not complete yet */ 658 goto out; 659 } 660 } 661 wh = NULL; /* no longer valid, catch any uses */ 662 663 /* 664 * Next strip any MSDU crypto bits. 665 */ 666 if (key != NULL && !ieee80211_crypto_demic(vap, key, m, 0)) { 667 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, 668 ni->ni_macaddr, "data", "%s", "demic error"); 669 vap->iv_stats.is_rx_demicfail++; 670 IEEE80211_NODE_STAT(ni, rx_demicfail); 671 goto out; 672 } 673 674 /* copy to listener after decrypt */ 675 if (bpf_peers_present(vap->iv_rawbpf)) 676 bpf_mtap(vap->iv_rawbpf, m); 677 need_tap = 0; 678 679 /* 680 * Finally, strip the 802.11 header. 681 */ 682 m = ieee80211_decap(vap, m, hdrspace); 683 if (m == NULL) { 684 /* XXX mask bit to check for both */ 685 /* don't count Null data frames as errors */ 686 if (subtype == IEEE80211_FC0_SUBTYPE_NODATA || 687 subtype == IEEE80211_FC0_SUBTYPE_QOS_NULL) 688 goto out; 689 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, 690 ni->ni_macaddr, "data", "%s", "decap error"); 691 vap->iv_stats.is_rx_decap++; 692 IEEE80211_NODE_STAT(ni, rx_decap); 693 goto err; 694 } 695 eh = mtod(m, struct ether_header *); 696 if (!ieee80211_node_is_authorized(ni)) { 697 /* 698 * Deny any non-PAE frames received prior to 699 * authorization. For open/shared-key 700 * authentication the port is mark authorized 701 * after authentication completes. For 802.1x 702 * the port is not marked authorized by the 703 * authenticator until the handshake has completed. 704 */ 705 if (eh->ether_type != htons(ETHERTYPE_PAE)) { 706 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, 707 eh->ether_shost, "data", 708 "unauthorized port: ether type 0x%x len %u", 709 eh->ether_type, m->m_pkthdr.len); 710 vap->iv_stats.is_rx_unauth++; 711 IEEE80211_NODE_STAT(ni, rx_unauth); 712 goto err; 713 } 714 } else { 715 /* 716 * When denying unencrypted frames, discard 717 * any non-PAE frames received without encryption. 718 */ 719 if ((vap->iv_flags & IEEE80211_F_DROPUNENC) && 720 (key == NULL && (m->m_flags & M_WEP) == 0) && 721 eh->ether_type != htons(ETHERTYPE_PAE)) { 722 /* 723 * Drop unencrypted frames. 724 */ 725 vap->iv_stats.is_rx_unencrypted++; 726 IEEE80211_NODE_STAT(ni, rx_unencrypted); 727 goto out; 728 } 729 } 730 /* XXX require HT? */ 731 if (qos & IEEE80211_QOS_AMSDU) { 732 m = ieee80211_decap_amsdu(ni, m); 733 if (m == NULL) 734 return IEEE80211_FC0_TYPE_DATA; 735 } else if ((ni->ni_ath_flags & IEEE80211_NODE_FF) && 736 #define FF_LLC_SIZE (sizeof(struct ether_header) + sizeof(struct llc)) 737 m->m_pkthdr.len >= 3*FF_LLC_SIZE) { 738 struct llc *llc; 739 740 /* 741 * Check for fast-frame tunnel encapsulation. 742 */ 743 if (m->m_len < FF_LLC_SIZE && 744 (m = m_pullup(m, FF_LLC_SIZE)) == NULL) { 745 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, 746 ni->ni_macaddr, "fast-frame", 747 "%s", "m_pullup(llc) failed"); 748 vap->iv_stats.is_rx_tooshort++; 749 return IEEE80211_FC0_TYPE_DATA; 750 } 751 llc = (struct llc *)(mtod(m, uint8_t *) + 752 sizeof(struct ether_header)); 753 if (llc->llc_snap.ether_type == htons(ATH_FF_ETH_TYPE)) { 754 m_adj(m, FF_LLC_SIZE); 755 m = ieee80211_decap_fastframe(ni, m); 756 if (m == NULL) 757 return IEEE80211_FC0_TYPE_DATA; 758 } 759 } 760 #undef FF_LLC_SIZE 761 ieee80211_deliver_data(vap, ni, m); 762 return IEEE80211_FC0_TYPE_DATA; 763 764 case IEEE80211_FC0_TYPE_MGT: 765 vap->iv_stats.is_rx_mgmt++; 766 IEEE80211_NODE_STAT(ni, rx_mgmt); 767 if (dir != IEEE80211_FC1_DIR_NODS) { 768 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 769 wh, "data", "incorrect dir 0x%x", dir); 770 vap->iv_stats.is_rx_wrongdir++; 771 goto err; 772 } 773 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { 774 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, 775 ni->ni_macaddr, "mgt", "too short: len %u", 776 m->m_pkthdr.len); 777 vap->iv_stats.is_rx_tooshort++; 778 goto out; 779 } 780 #ifdef IEEE80211_DEBUG 781 if (ieee80211_msg_debug(vap) || ieee80211_msg_dumppkts(vap)) { 782 if_printf(ifp, "received %s from %s rssi %d\n", 783 ieee80211_mgt_subtype_name[subtype >> 784 IEEE80211_FC0_SUBTYPE_SHIFT], 785 ether_sprintf(wh->i_addr2), rssi); 786 } 787 #endif 788 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 789 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 790 wh, NULL, "%s", "WEP set but not permitted"); 791 vap->iv_stats.is_rx_mgtdiscard++; /* XXX */ 792 goto out; 793 } 794 if (bpf_peers_present(vap->iv_rawbpf)) 795 bpf_mtap(vap->iv_rawbpf, m); 796 vap->iv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp); 797 m_freem(m); 798 return IEEE80211_FC0_TYPE_MGT; 799 800 case IEEE80211_FC0_TYPE_CTL: 801 vap->iv_stats.is_rx_ctl++; 802 IEEE80211_NODE_STAT(ni, rx_ctrl); 803 goto out; 804 default: 805 IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, 806 wh, "bad", "frame type 0x%x", type); 807 /* should not come here */ 808 break; 809 } 810 err: 811 ifp->if_ierrors++; 812 out: 813 if (m != NULL) { 814 if (bpf_peers_present(vap->iv_rawbpf) && need_tap) 815 bpf_mtap(vap->iv_rawbpf, m); 816 m_freem(m); 817 } 818 return type; 819 #undef SEQ_LEQ 820 } 821 822 static void 823 wds_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, 824 int subtype, int rssi, int noise, u_int32_t rstamp) 825 { 826 struct ieee80211vap *vap = ni->ni_vap; 827 struct ieee80211com *ic = ni->ni_ic; 828 struct ieee80211_frame *wh; 829 u_int8_t *frm, *efrm; 830 831 wh = mtod(m0, struct ieee80211_frame *); 832 frm = (u_int8_t *)&wh[1]; 833 efrm = mtod(m0, u_int8_t *) + m0->m_len; 834 switch (subtype) { 835 case IEEE80211_FC0_SUBTYPE_DEAUTH: 836 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 837 case IEEE80211_FC0_SUBTYPE_BEACON: 838 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 839 case IEEE80211_FC0_SUBTYPE_AUTH: 840 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 841 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: 842 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 843 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: 844 case IEEE80211_FC0_SUBTYPE_DISASSOC: 845 vap->iv_stats.is_rx_mgtdiscard++; 846 break; 847 case IEEE80211_FC0_SUBTYPE_ACTION: 848 if (vap->iv_state != IEEE80211_S_RUN || 849 IEEE80211_IS_MULTICAST(wh->i_addr1)) { 850 vap->iv_stats.is_rx_mgtdiscard++; 851 break; 852 } 853 ni->ni_inact = ni->ni_inact_reload; 854 if (ieee80211_parse_action(ni, m0) == 0) 855 ic->ic_recv_action(ni, frm, efrm); 856 break; 857 default: 858 IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, 859 wh, "mgt", "subtype 0x%x not handled", subtype); 860 vap->iv_stats.is_rx_badsubtype++; 861 break; 862 } 863 } 864