From 2f1ad18b34dfc1fccb48307f231b0ed2cbf268fa Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Thu, 1 Apr 2004 00:38:45 +0000 Subject: [PATCH] radiotap updates: o force little-endian byte order for header o pad header to 32-bit boundary to guard against applications that assume packet data alignment --- sys/dev/ath/if_ath.c | 17 +++++++++++------ sys/dev/ath/if_athvar.h | 2 ++ sys/dev/wi/if_wi.c | 17 +++++++++++------ sys/dev/wi/if_wivar.h | 2 ++ 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 3597c52fef8..9d6b311a662 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -339,15 +339,20 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) &sc->sc_drvbpf); /* * Initialize constant fields. + * XXX make header lengths a multiple of 32-bits so subsequent + * headers are properly aligned; this is a kludge to keep + * certain applications happy. * * NB: the channel is setup each time we transition to the * RUN state to avoid filling it in for each frame. */ - sc->sc_tx_th.wt_ihdr.it_len = sizeof(sc->sc_tx_th); - sc->sc_tx_th.wt_ihdr.it_present = ATH_TX_RADIOTAP_PRESENT; + sc->sc_tx_th_len = roundup(sizeof(sc->sc_tx_th), sizeof(u_int32_t)); + sc->sc_tx_th.wt_ihdr.it_len = htole16(sc->sc_tx_th_len); + sc->sc_tx_th.wt_ihdr.it_present = htole32(ATH_TX_RADIOTAP_PRESENT); - sc->sc_rx_th.wr_ihdr.it_len = sizeof(sc->sc_rx_th); - sc->sc_rx_th.wr_ihdr.it_present = ATH_RX_RADIOTAP_PRESENT; + sc->sc_rx_th_len = roundup(sizeof(sc->sc_rx_th), sizeof(u_int32_t)); + sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len); + sc->sc_rx_th.wr_ihdr.it_present = htole32(ATH_RX_RADIOTAP_PRESENT); return 0; bad: @@ -1726,7 +1731,7 @@ ath_rx_proc(void *arg, int npending) /* XXX TSF */ bpf_mtap2(sc->sc_drvbpf, - &sc->sc_rx_th, sizeof(sc->sc_rx_th), m); + &sc->sc_rx_th, sc->sc_rx_th_len, m); } m_adj(m, -IEEE80211_CRC_LEN); @@ -2070,7 +2075,7 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf sc->sc_tx_th.wt_antenna = antenna; bpf_mtap2(sc->sc_drvbpf, - &sc->sc_tx_th, sizeof(sc->sc_tx_th), m0); + &sc->sc_tx_th, sc->sc_tx_th_len, m0); } /* diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h index 13e7a60d32b..4bf5287ffc4 100644 --- a/sys/dev/ath/if_athvar.h +++ b/sys/dev/ath/if_athvar.h @@ -115,10 +115,12 @@ struct ath_softc { struct ath_tx_radiotap_header th; u_int8_t pad[64]; } u_tx_rt; + int sc_tx_th_len; union { struct ath_rx_radiotap_header th; u_int8_t pad[64]; } u_rx_rt; + int sc_rx_th_len; struct ath_desc *sc_desc; /* TX/RX descriptors */ bus_dma_segment_t sc_dseg; diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c index fb45ee94921..dc2e75e310c 100644 --- a/sys/dev/wi/if_wi.c +++ b/sys/dev/wi/if_wi.c @@ -482,15 +482,20 @@ wi_attach(device_t dev) &sc->sc_drvbpf); /* * Initialize constant fields. + * XXX make header lengths a multiple of 32-bits so subsequent + * headers are properly aligned; this is a kludge to keep + * certain applications happy. * * NB: the channel is setup each time we transition to the * RUN state to avoid filling it in for each frame. */ - sc->sc_tx_th.wt_ihdr.it_len = sizeof(sc->sc_tx_th); - sc->sc_tx_th.wt_ihdr.it_present = WI_TX_RADIOTAP_PRESENT; + sc->sc_tx_th_len = roundup(sizeof(sc->sc_tx_th), sizeof(u_int32_t)); + sc->sc_tx_th.wt_ihdr.it_len = htole16(sc->sc_tx_th_len); + sc->sc_tx_th.wt_ihdr.it_present = htole32(WI_TX_RADIOTAP_PRESENT); - sc->sc_rx_th.wr_ihdr.it_len = sizeof(sc->sc_rx_th); - sc->sc_rx_th.wr_ihdr.it_present = WI_RX_RADIOTAP_PRESENT; + sc->sc_rx_th_len = roundup(sizeof(sc->sc_rx_th), sizeof(u_int32_t)); + sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len); + sc->sc_rx_th.wr_ihdr.it_present = htole32(WI_RX_RADIOTAP_PRESENT); #endif return (0); } @@ -944,7 +949,7 @@ wi_start(struct ifnet *ifp) sc->sc_tx_th.wt_rate = ni->ni_rates.rs_rates[ni->ni_txrate]; bpf_mtap2(sc->sc_drvbpf, - &sc->sc_tx_th, sizeof(sc->sc_tx_th), m0); + &sc->sc_tx_th, sc->sc_tx_th_len, m0); } #endif m_copydata(m0, 0, sizeof(struct ieee80211_frame), @@ -1495,7 +1500,7 @@ wi_rx_intr(struct wi_softc *sc) if (frmhdr.wi_status & WI_STAT_PCF) sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_CFP; bpf_mtap2(sc->sc_drvbpf, - &sc->sc_rx_th, sizeof(sc->sc_rx_th), m); + &sc->sc_rx_th, sc->sc_rx_th_len, m); } #endif wh = mtod(m, struct ieee80211_frame *); diff --git a/sys/dev/wi/if_wivar.h b/sys/dev/wi/if_wivar.h index bd7e16b60cb..0a8388e77b7 100644 --- a/sys/dev/wi/if_wivar.h +++ b/sys/dev/wi/if_wivar.h @@ -168,10 +168,12 @@ struct wi_softc { struct wi_tx_radiotap_header th; u_int8_t pad[64]; } u_tx_rt; + int sc_tx_th_len; union { struct wi_rx_radiotap_header th; u_int8_t pad[64]; } u_rx_rt; + int sc_rx_th_len; }; #define sc_if sc_ic.ic_if #define sc_tx_th u_tx_rt.th