Ticket #921: madwifi_monitor_invalid_frames_2.patch

File madwifi_monitor_invalid_frames_2.patch, 6.2 kB (added by scottr, 5 years ago)

Improved patch for monitoring frames with errors. Signed-off-by: Scott Raynel <scottraynel@gmail.com>

  • net80211/ieee80211_monitor.c

    old new  
    319319                struct ieee80211_frame *wh = (struct ieee80211_frame *)skb->data; 
    320320                u_int8_t dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 
    321321 
    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 */ 
    330343                        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                } 
    331357 
    332                 next = TAILQ_NEXT(vap, iv_next); 
    333358                if (vap->iv_opmode != IEEE80211_M_MONITOR || 
    334359                    vap->iv_state != IEEE80211_S_RUN) 
    335360                        continue; 
  • net80211/ieee80211_var.h

    old new  
    321321 
    322322        int iv_monitor_nods_only;               /* in monitor mode only nods traffic */ 
    323323        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 */ 
    324326 
    325327        int (*iv_newstate)(struct ieee80211vap *, enum ieee80211_state, int); 
    326328        u_int8_t iv_myaddr[IEEE80211_ADDR_LEN]; 
  • net80211/ieee80211_linux.c

    old new  
    565565        } 
    566566        return ret; 
    567567} 
     568static int 
     569IEEE80211_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; 
    568575 
     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 
     591static int 
     592IEEE80211_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 
    569614#define CTL_AUTO        -2      /* cannot be CTL_ANY or CTL_NONE */ 
    570615 
    571616static const ctl_table ieee80211_sysctl_template[] = { 
     
    591636          .mode         = 0644, 
    592637          .proc_handler = ieee80211_sysctl_monitor_txf_len 
    593638        }, 
     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        }, 
    594649        /* NB: must be last entry before NULL */ 
    595650        { .ctl_name     = CTL_AUTO, 
    596651          .procname     = "%parent", 
  • ath/if_ath.c

    old new  
    55615561                                sc->sc_stats.ast_rx_phyerr++; 
    55625562                                phyerr = ds->ds_rxstat.rs_phyerr & 0x1f; 
    55635563                                sc->sc_stats.ast_rx_phy[phyerr]++; 
    5564                                 goto rx_next; 
    55655564                        } 
    55665565                        if (ds->ds_rxstat.rs_status & HAL_RXERR_DECRYPT) { 
    55675566                                /* 
     
    56025601                                } 
    56035602                        } 
    56045603                        /* 
    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. 
    56085606                         */ 
    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; 
    56135608                } 
    56145609rx_accept: 
    56155610                /* 
     
    56345629                skb->protocol = ETH_P_CONTROL;          /* XXX */ 
    56355630 
    56365631                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 
    56425635                         */ 
     5636#if 0 
    56435637                        if (len < IEEE80211_ACK_LEN) { 
    56445638                                DPRINTF(sc, ATH_DEBUG_RECV, 
    56455639                                        "%s: runt packet %d\n", __func__, len); 
     
    56485642                                skb = NULL; 
    56495643                                goto rx_next; 
    56505644                        } 
     5645#endif 
    56515646                        ath_rx_capture(dev, ds, skb); 
    56525647                        if (sc->sc_ic.ic_opmode == IEEE80211_M_MONITOR) { 
    56535648                                /* no other VAPs need the packet */ 
     
    56575652                        } 
    56585653                } 
    56595654 
     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                 
    56605665                /* remove the CRC */ 
    56615666                skb_trim(skb, skb->len - IEEE80211_CRC_LEN); 
    56625667