Changeset 1720

Show
Ignore:
Timestamp:
09/20/06 06:58:19 (2 years ago)
Author:
kelmo
Message:

The attached patch fixes several issues with monitor mode:

  • Record the correct rate for transmitted packets (both prism and
    radiotap encapsulations were referencing the rx rate even for tx
    frames, which was wrong).
  • Record the antenna for tranmitted packets instead of just using 0
  • Record the TSF for tranmitted packets when using radiotap
  • Don't expose kernel memory to userspace in ieee80211_input_monitor

ieee80211_input_monitor was taking a u_int32_t containing the TSF for
the frame, but was copying 8 bytes of memory into the monitoring
header from it's address. This patch changes ieee80211_input_monitor
to take a u_int64_t and touches the appropriate parts in ath/if_ath.c

Signed-off-by: Scott Raynel <scottraynel@gmail.com>

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ath/if_ath.c

    r1719 r1720  
    51965196 
    51975197/* 
     5198 * Extend 15-bit time stamp from rx descriptor to 
     5199 * a full 64-bit TSF using the current h/w TSF. 
     5200 */ 
     5201static __inline u_int64_t 
     5202ath_extend_tsf(struct ath_hal *ah, u_int32_t rstamp) 
     5203{ 
     5204        u_int64_t tsf; 
     5205 
     5206        tsf = ath_hal_gettsf64(ah); 
     5207        if ((tsf & 0x7fff) < rstamp) 
     5208                tsf -= 0x8000; 
     5209        return ((tsf &~ 0x7fff) | rstamp); 
     5210} 
     5211 
     5212/* 
    51985213 * Add a prism2 header to a received frame and 
    51995214 * dispatch it to capture tools like kismet. 
     
    52055220        struct ieee80211com *ic = &sc->sc_ic; 
    52065221        struct ieee80211_frame *wh; 
    5207         u_int32_t tsf; 
     5222        u_int64_t tsf; 
    52085223 
    52095224        /* Pass up tsf clock in mactime 
    52105225         * Rx descriptor has the low 15 bits of the tsf at 
    52115226         * the time the frame was received.  Use the current 
    5212          * tsf to extend this to 32 bits. 
    5213          */ 
    5214         tsf = ath_hal_gettsf32(sc->sc_ah); 
    5215         if ((tsf & 0x7fff) < ds->ds_rxstat.rs_tstamp) 
    5216                 tsf -= 0x8000; 
    5217         tsf = ds->ds_rxstat.rs_tstamp | (tsf &~ 0x7fff); 
     5227         * tsf to extend this to 64 bits. 
     5228         */ 
     5229        tsf = ath_extend_tsf(sc->sc_ah, ds->ds_rxstat.rs_tstamp); 
    52185230 
    52195231        KASSERT(ic->ic_flags & IEEE80211_F_DATAPAD, 
     
    52465258        int extra = A_MAX(sizeof(struct ath_tx_radiotap_header),  
    52475259                          A_MAX(sizeof(wlan_ng_prism2_header), ATHDESC_HEADER_SIZE)); 
     5260        u_int64_t tsf; 
     5261 
     5262        /* Pass up tsf clock in mactime 
     5263         * tx descriptor has the low 15 bits of the tsf at 
     5264         * the time the frame was received.  Use the current 
     5265         * tsf to extend this to 64 bits. 
     5266         */ 
     5267        tsf = ath_extend_tsf(sc->sc_ah, ds->ds_txstat.ts_tstamp); 
     5268 
    52485269        /*                                                                       
    52495270         * release the owner of this skb since we're basically                   
     
    52795300                goto done; 
    52805301        } 
    5281         ieee80211_input_monitor(ic, skb, ds, 1, 0, sc); 
     5302        ieee80211_input_monitor(ic, skb, ds, 1, tsf, sc); 
    52825303 done: 
    52835304        dev_kfree_skb(skb); 
    5284 } 
    5285  
    5286 /* 
    5287  * Extend 15-bit time stamp from rx descriptor to 
    5288  * a full 64-bit TSF using the current h/w TSF. 
    5289  */ 
    5290 static __inline u_int64_t 
    5291 ath_extend_tsf(struct ath_hal *ah, u_int32_t rstamp) 
    5292 { 
    5293         u_int64_t tsf; 
    5294  
    5295         tsf = ath_hal_gettsf64(ah); 
    5296         if ((tsf & 0x7fff) < rstamp) 
    5297                 tsf -= 0x8000; 
    5298         return ((tsf &~ 0x7fff) | rstamp); 
    52995305} 
    53005306 
  • trunk/net80211/ieee80211_monitor.c

    r1713 r1720  
    207207void 
    208208ieee80211_input_monitor(struct ieee80211com *ic, struct sk_buff *skb, 
    209         struct ath_desc *ds, int tx, u_int32_t mactime, struct ath_softc *sc)  
     209        struct ath_desc *ds, int tx, u_int64_t mactime, struct ath_softc *sc)  
    210210{ 
    211211        struct ieee80211vap *vap, *next; 
     
    268268                        ph->hosttime.len = 4; 
    269269                        ph->hosttime.data = jiffies; 
     270                         
    270271                        /* Pass up tsf clock in mactime */ 
     272                        /* NB: the prism mactime field is 32bit, so we lose TSF precision here */ 
    271273                        ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime; 
    272274                        ph->mactime.status = 0; 
     
    309311                        ph->rate.status = 0; 
    310312                        ph->rate.len = 4; 
    311                         ph->rate.data = sc->sc_hwmap[ds->ds_rxstat.rs_rate].ieeerate; 
     313                        if (tx) 
     314                                ph->rate.data = sc->sc_hwmap[ds->ds_txstat.ts_rate].ieeerate; 
     315                        else 
     316                                ph->rate.data = sc->sc_hwmap[ds->ds_rxstat.rs_rate].ieeerate; 
    312317                        break; 
    313318                } 
     
    328333                                th->wt_ihdr.it_len = cpu_to_le16(sizeof(struct ath_tx_radiotap_header)); 
    329334                                th->wt_ihdr.it_present = cpu_to_le32(ATH_TX_RADIOTAP_PRESENT); 
     335 
     336                                /* radiotap's TSF field is the full 64 bits, so we don't lose 
     337                                 * any TSF precision when using radiotap */ 
     338                                memcpy(&th->wt_tsft, &mactime, IEEE80211_TSF_LEN); 
     339                                th->wt_tsft = cpu_to_le64(th->wt_tsft); 
     340                         
    330341                                th->wt_flags = 0; 
    331                                 th->wt_rate = sc->sc_hwmap[ds->ds_rxstat.rs_rate].ieeerate; 
     342                                th->wt_rate = sc->sc_hwmap[ds->ds_txstat.ts_rate].ieeerate; 
    332343                                th->wt_txpower = 0; 
    333                                 th->wt_antenna = 0
     344                                th->wt_antenna = ds->ds_txstat.ts_antenna
    334345                        } else { 
    335346                                struct ath_rx_radiotap_header *th; 
  • trunk/net80211/ieee80211_monitor.h

    r1710 r1720  
    136136 
    137137#define ATH_TX_RADIOTAP_PRESENT (               \ 
     138        (1 << IEEE80211_RADIOTAP_TSFT)          | \ 
    138139        (1 << IEEE80211_RADIOTAP_FLAGS)         | \ 
    139140        (1 << IEEE80211_RADIOTAP_RATE)          | \ 
     
    144145struct ath_tx_radiotap_header { 
    145146        struct ieee80211_radiotap_header wt_ihdr; 
    146         u_int8_t wt_flags;                      /* XXX for padding */ 
     147        u_int64_t wt_tsft; 
     148        u_int8_t wt_flags;       
    147149        u_int8_t wt_rate; 
    148150        u_int8_t wt_txpower; 
     
    155157 */ 
    156158void ieee80211_input_monitor(struct ieee80211com *, struct sk_buff *, 
    157         struct ath_desc *, int, u_int32_t, struct ath_softc *); 
     159        struct ath_desc *, int, u_int64_t, struct ath_softc *); 
    158160 
    159161