Ticket #921: madwifi_monitor_invalid_frames_2.patch
| File madwifi_monitor_invalid_frames_2.patch, 6.2 kB (added by scottr, 5 years ago) |
|---|
-
net80211/ieee80211_monitor.c
old new 319 319 struct ieee80211_frame *wh = (struct ieee80211_frame *)skb->data; 320 320 u_int8_t dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 321 321 322 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { 323 if (IEEE80211_ADDR_EQ(wh->i_addr1, dev->broadcast)) 324 pkttype = PACKET_BROADCAST; 325 else 326 pkttype = PACKET_MULTICAST; 327 } else if (tx) 328 pkttype = PACKET_OUTGOING; 329 else 322 next = TAILQ_NEXT(vap, iv_next); 323 /* If we have rx'd an error frame... */ 324 if (!tx && ds->ds_rxstat.rs_status != 0) { 325 326 /* Discard PHY errors if necessary */ 327 if (ds->ds_rxstat.rs_status & HAL_RXERR_PHY) { 328 if (vap->iv_monitor_phy_errors == 0) continue; 329 } 330 331 /* Discard CRC errors if necessary */ 332 if (ds->ds_rxstat.rs_status & HAL_RXERR_CRC) { 333 if (vap->iv_monitor_crc_errors == 0) continue; 334 } 335 336 /* Accept PHY, CRC and decrypt errors. Discard the rest. */ 337 if (ds->ds_rxstat.rs_status &~ 338 (HAL_RXERR_DECRYPT | HAL_RXERR_MIC | 339 HAL_RXERR_PHY | HAL_RXERR_CRC )) 340 continue; 341 342 /* We can't use addr1 to determine direction at this point */ 330 343 pkttype = PACKET_HOST; 344 } else { 345 /* 346 * The frame passed it's CRC, so we can rely 347 * on the contents of the frame to set pkttype. 348 */ 349 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { 350 if (IEEE80211_ADDR_EQ(wh->i_addr1, dev->broadcast)) 351 pkttype = PACKET_BROADCAST; 352 else 353 pkttype = PACKET_MULTICAST; 354 } else 355 pkttype = (tx) ? PACKET_OUTGOING : PACKET_HOST; 356 } 331 357 332 next = TAILQ_NEXT(vap, iv_next);333 358 if (vap->iv_opmode != IEEE80211_M_MONITOR || 334 359 vap->iv_state != IEEE80211_S_RUN) 335 360 continue; -
net80211/ieee80211_var.h
old new 321 321 322 322 int iv_monitor_nods_only; /* in monitor mode only nods traffic */ 323 323 int iv_monitor_txf_len; /* in monitor mode, truncate tx packets */ 324 int iv_monitor_phy_errors; /* in monitor mode, accept phy errors */ 325 int iv_monitor_crc_errors; /* in monitor mode, accept crc errors */ 324 326 325 327 int (*iv_newstate)(struct ieee80211vap *, enum ieee80211_state, int); 326 328 u_int8_t iv_myaddr[IEEE80211_ADDR_LEN]; -
net80211/ieee80211_linux.c
old new 565 565 } 566 566 return ret; 567 567 } 568 static int 569 IEEE80211_SYSCTL_DECL(ieee80211_sysctl_monitor_phy_errors, ctl, write, filp, buffer, 570 lenp, ppos) 571 { 572 struct ieee80211vap *vap = ctl->extra1; 573 u_int val; 574 int ret; 568 575 576 ctl->data = &val; 577 ctl->maxlen = sizeof(val); 578 if (write) { 579 ret = IEEE80211_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, 580 lenp, ppos); 581 if (ret == 0) 582 vap->iv_monitor_phy_errors = val; 583 } else { 584 val = vap->iv_monitor_phy_errors; 585 ret = IEEE80211_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, 586 lenp, ppos); 587 } 588 return ret; 589 } 590 591 static int 592 IEEE80211_SYSCTL_DECL(ieee80211_sysctl_monitor_crc_errors, ctl, write, filp, buffer, 593 lenp, ppos) 594 { 595 struct ieee80211vap *vap = ctl->extra1; 596 u_int val; 597 int ret; 598 599 ctl->data = &val; 600 ctl->maxlen = sizeof(val); 601 if (write) { 602 ret = IEEE80211_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, 603 lenp, ppos); 604 if (ret == 0) 605 vap->iv_monitor_crc_errors = val; 606 } else { 607 val = vap->iv_monitor_crc_errors; 608 ret = IEEE80211_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, 609 lenp, ppos); 610 } 611 return ret; 612 } 613 569 614 #define CTL_AUTO -2 /* cannot be CTL_ANY or CTL_NONE */ 570 615 571 616 static const ctl_table ieee80211_sysctl_template[] = { … … 591 636 .mode = 0644, 592 637 .proc_handler = ieee80211_sysctl_monitor_txf_len 593 638 }, 639 { .ctl_name = CTL_AUTO, 640 .procname = "monitor_phy_errors", 641 .mode = 0644, 642 .proc_handler = ieee80211_sysctl_monitor_phy_errors 643 }, 644 { .ctl_name = CTL_AUTO, 645 .procname = "monitor_crc_errors", 646 .mode = 0644, 647 .proc_handler = ieee80211_sysctl_monitor_crc_errors 648 }, 594 649 /* NB: must be last entry before NULL */ 595 650 { .ctl_name = CTL_AUTO, 596 651 .procname = "%parent", -
ath/if_ath.c
old new 5561 5561 sc->sc_stats.ast_rx_phyerr++; 5562 5562 phyerr = ds->ds_rxstat.rs_phyerr & 0x1f; 5563 5563 sc->sc_stats.ast_rx_phy[phyerr]++; 5564 goto rx_next;5565 5564 } 5566 5565 if (ds->ds_rxstat.rs_status & HAL_RXERR_DECRYPT) { 5567 5566 /* … … 5602 5601 } 5603 5602 } 5604 5603 /* 5605 * Reject error frames, we normally don't want 5606 * to see them in monitor mode (in monitor mode 5607 * allow through packets that have crypto problems). 5604 * Reject error frames if we have no vaps that 5605 * are operating in monitor mode. 5608 5606 */ 5609 if ((ds->ds_rxstat.rs_status &~ 5610 (HAL_RXERR_DECRYPT|HAL_RXERR_MIC)) || 5611 sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR) 5612 goto rx_next; 5607 if(sc->sc_nmonvaps == 0) goto rx_next; 5613 5608 } 5614 5609 rx_accept: 5615 5610 /* … … 5634 5629 skb->protocol = ETH_P_CONTROL; /* XXX */ 5635 5630 5636 5631 if (sc->sc_nmonvaps > 0) { 5637 /* 5638 * Some VAP is in monitor mode. Discard 5639 * anything shorter than an ack or cts, clean 5640 * the skbuff, fabricate the Prism header 5641 * existing tools expect, and dispatch. 5632 /* 5633 * Some vap is in monitor mode, so send to 5634 * ath_rx_capture for monitor encapsulation 5642 5635 */ 5636 #if 0 5643 5637 if (len < IEEE80211_ACK_LEN) { 5644 5638 DPRINTF(sc, ATH_DEBUG_RECV, 5645 5639 "%s: runt packet %d\n", __func__, len); … … 5648 5642 skb = NULL; 5649 5643 goto rx_next; 5650 5644 } 5645 #endif 5651 5646 ath_rx_capture(dev, ds, skb); 5652 5647 if (sc->sc_ic.ic_opmode == IEEE80211_M_MONITOR) { 5653 5648 /* no other VAPs need the packet */ … … 5657 5652 } 5658 5653 } 5659 5654 5655 /* 5656 * Finished monitor mode handling, now reject 5657 * error frames before passing to other vaps 5658 */ 5659 if (ds->ds_rxstat.rs_status != 0) { 5660 dev_kfree_skb(skb); 5661 skb = NULL; 5662 goto rx_next; 5663 } 5664 5660 5665 /* remove the CRC */ 5661 5666 skb_trim(skb, skb->len - IEEE80211_CRC_LEN); 5662 5667
