Skip to content

Instantly share code, notes, and snippets.

@lwhsu
Created August 23, 2023 18:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lwhsu/ba24d4fcb5f2e47bfc64819d8d4b1077 to your computer and use it in GitHub Desktop.
Save lwhsu/ba24d4fcb5f2e47bfc64819d8d4b1077 to your computer and use it in GitHub Desktop.
diff --git a/sys/dev/wtap/if_wtap.c b/sys/dev/wtap/if_wtap.c
index 529de1d53728..0e2bbcfb3d0b 100644
--- a/sys/dev/wtap/if_wtap.c
+++ b/sys/dev/wtap/if_wtap.c
@@ -191,6 +191,43 @@ wtap_reset_vap(struct ieee80211vap *vap, u_long cmd)
return 0;
}
+static void
+wtap_tx_tap(struct wtap_softc *sc)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ const struct ieee80211_rate_table *rt = ic->ic_rt;
+ struct wtap_tx_radiotap_header *th = &sc->sc_tx_th;
+
+ th->wt_flags = 0;
+ if (rt->rateCount) {
+ /* choose the fastest rate */
+ th->wt_rate = IEEE80211_RV(rt->info[rt->rateCount - 1].dot11Rate);
+ }
+ th->wt_chan_flags = IEEE80211_CHAN_2GHZ;
+ th->wt_chan_freq = ic->ic_curchan->ic_freq;
+ th->wt_chan_ieee = ic->ic_curchan->ic_ieee;
+ th->wt_chan_maxpow = 0;
+}
+
+static void
+wtap_rx_tap(struct wtap_softc *sc, uint64_t tsf)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+ const struct ieee80211_rate_table *rt = ic->ic_rt;
+ struct wtap_rx_radiotap_header *rh = &sc->sc_rx_th;
+
+ rh->wr_tsf = tsf;
+ rh->wr_flags = 0;
+ if (rt->rateCount) {
+ /* choose the fastest rate */
+ rh->wr_rate = IEEE80211_RV(rt->info[rt->rateCount - 1].dot11Rate);
+ }
+ rh->wr_chan_flags = IEEE80211_CHAN_2GHZ;
+ rh->wr_chan_freq = ic->ic_curchan->ic_freq;
+ rh->wr_chan_ieee = ic->ic_curchan->ic_ieee;
+ rh->wr_chan_maxpow = 0;
+}
+
static void
wtap_beacon_update(struct ieee80211vap *vap, int item)
{
@@ -264,8 +301,10 @@ wtap_beacon_intrp(void *arg)
wh = mtod(m, struct ieee80211_frame *);
memcpy(&wh[1], &tsf, sizeof(tsf));
- if (ieee80211_radiotap_active_vap(vap))
- ieee80211_radiotap_tx(vap, m);
+ if (ieee80211_radiotap_active_vap(vap)) {
+ wtap_tx_tap(sc);
+ ieee80211_radiotap_tx(vap, m);
+ }
#if 0
medium_transmit(avp->av_md, avp->id, m);
@@ -300,6 +339,7 @@ wtap_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
switch (vap->iv_opmode) {
case IEEE80211_M_IBSS:
case IEEE80211_M_MBSS:
+ case IEEE80211_M_HOSTAP:
/*
* Stop any previous beacon callout. This may be
* necessary, for example, when an ibss merge
@@ -424,6 +464,15 @@ wtap_parent(struct ieee80211com *ic)
struct wtap_softc *sc = ic->ic_softc;
if (ic->ic_nrunning > 0) {
+ /*
+ * There is a race of issuing scanning process between
+ * IF UP and wpa_supplicant(8). The pause() here is to
+ * delay the issuing of scanning process in IF up
+ * and let wpa_supplicant(8) win the race. (so the scan
+ * request and scan flags in wpa_supplicant(8) can pass
+ * into net80211 and take effect)
+ */
+ pause("wtap_parent", hz);
sc->up = 1;
ieee80211_start_all(ic);
} else
@@ -466,8 +515,22 @@ wtap_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
#endif
struct ieee80211vap *vap = ni->ni_vap;
struct wtap_vap *avp = WTAP_VAP(vap);
+ struct wtap_softc *sc = vap->iv_ic->ic_softc;
+ struct ieee80211_frame *wh;
+ int subtype, tsf;
+
+ wh = mtod(m, struct ieee80211_frame *);
+ subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+
+ /* Insert TSFT if the frame is a probe response */
+ if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
+ tsf = wtap_hal_get_tsf(sc->hal);
+ wh = mtod(m, struct ieee80211_frame *);
+ memcpy(&wh[1], &tsf, sizeof(tsf));
+ }
if (ieee80211_radiotap_active_vap(vap)) {
+ wtap_tx_tap(sc);
ieee80211_radiotap_tx(vap, m);
}
if (m->m_flags & M_TXCB)
@@ -531,6 +594,10 @@ wtap_rx_proc(void *arg, int npending)
#if 0
ieee80211_dump_pkt(ic, mtod(m, caddr_t), 0,0,0);
#endif
+ if (ieee80211_radiotap_active(ic)) {
+ uint64_t tsf = wtap_hal_get_tsf(sc->hal);
+ wtap_rx_tap(sc, tsf);
+ }
/*
* Locate the node for sender, track state, and then
@@ -596,12 +663,35 @@ wtap_transmit(struct ieee80211com *ic, struct mbuf *m)
(struct ieee80211_node *) m->m_pkthdr.rcvif;
struct ieee80211vap *vap = ni->ni_vap;
struct wtap_vap *avp = WTAP_VAP(vap);
+ struct ieee80211_key *k = NULL;
+ struct ieee80211_frame *wh = NULL;
+ struct wtap_softc *sc = vap->iv_ic->ic_softc;
if(ni == NULL){
printf("m->m_pkthdr.rcvif is NULL we cant radiotap_tx\n");
}else{
- if (ieee80211_radiotap_active_vap(vap))
+ wh = mtod(m, struct ieee80211_frame *);
+
+ if (IEEE80211_IS_PROTECTED(wh)) {
+ k = ieee80211_crypto_encap(ni, m);
+
+ /*
+ * This can happen when the key is yanked after the
+ * frame was queued. Just discard the frame; the
+ * 802.11 layer counts failures and provides
+ * debugging/diagnostics.
+ */
+ if (k == NULL) {
+ m_free(m);
+ ieee80211_free_node(ni);
+ return 0;
+ }
+ }
+
+ if (ieee80211_radiotap_active_vap(vap)) {
+ wtap_tx_tap(sc);
ieee80211_radiotap_tx(vap, m);
+ }
}
if (m->m_flags & M_TXCB)
ieee80211_process_callback(ni, m, 0);
@@ -653,7 +743,13 @@ wtap_attach(struct wtap_softc *sc, const uint8_t *macaddr)
ic->ic_name = sc->name;
ic->ic_phytype = IEEE80211_T_DS;
ic->ic_opmode = IEEE80211_M_MBSS;
- ic->ic_caps = IEEE80211_C_MBSS | IEEE80211_C_IBSS;
+ ic->ic_caps =
+ IEEE80211_C_MBSS /* mesh point link mode */
+ | IEEE80211_C_IBSS /* ibss, nee adhoc, mode */
+ | IEEE80211_C_STA /* station mode */
+ | IEEE80211_C_MONITOR
+ | IEEE80211_C_HOSTAP /* hostap mode */
+ | IEEE80211_C_WPA; /* capable of WPA1+WPA2 */
ic->ic_max_keyix = 128; /* A value read from Atheros ATH_KEYMAX */
diff --git a/sys/dev/wtap/if_wtapioctl.h b/sys/dev/wtap/if_wtapioctl.h
index 6cde392ab7c1..8e389fdb475b 100644
--- a/sys/dev/wtap/if_wtapioctl.h
+++ b/sys/dev/wtap/if_wtapioctl.h
@@ -139,41 +139,42 @@ struct wtap_stats {
/*
* Radio capture format.
*/
-#define WTAP_RX_RADIOTAP_PRESENT ( \
+#define WTAP_RX_RADIOTAP_PRESENT ( \
+ (1 << IEEE80211_RADIOTAP_TSFT) | \
+ (1 << IEEE80211_RADIOTAP_FLAGS) | \
+ (1 << IEEE80211_RADIOTAP_RATE) | \
+ (1 << IEEE80211_RADIOTAP_XCHANNEL) | \
0)
struct wtap_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
-#if 0
+
u_int64_t wr_tsf;
u_int8_t wr_flags;
u_int8_t wr_rate;
- int8_t wr_antsignal;
- int8_t wr_antnoise;
- u_int8_t wr_antenna;
- u_int8_t wr_pad[3];
+ u_int8_t wr_pad[2];
u_int32_t wr_chan_flags;
u_int16_t wr_chan_freq;
u_int8_t wr_chan_ieee;
- int8_t wr_chan_maxpow;
-#endif
+ u_int8_t wr_chan_maxpow;
} __packed __aligned(8);
-#define WTAP_TX_RADIOTAP_PRESENT ( \
+#define WTAP_TX_RADIOTAP_PRESENT ( \
+ (1 << IEEE80211_RADIOTAP_FLAGS) | \
+ (1 << IEEE80211_RADIOTAP_RATE) | \
+ (1 << IEEE80211_RADIOTAP_XCHANNEL) | \
0)
struct wtap_tx_radiotap_header {
struct ieee80211_radiotap_header wt_ihdr;
-#if 0
+
u_int8_t wt_flags;
u_int8_t wt_rate;
- u_int8_t wt_txpower;
- u_int8_t wt_antenna;
+ u_int8_t wr_pad[2];
u_int32_t wt_chan_flags;
u_int16_t wt_chan_freq;
u_int8_t wt_chan_ieee;
- int8_t wt_chan_maxpow;
-#endif
-} __packed;
+ u_int8_t wt_chan_maxpow;
+} __packed __aligned(8);
#endif
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 201cfbcca725..20765b65b130 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -417,6 +417,7 @@ SUBDIR= \
wlan_xauth \
${_wpi} \
${_wpifw} \
+ wtap \
${_x86bios} \
xdr \
xl \
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment