Created
August 23, 2023 18:49
-
-
Save lwhsu/ba24d4fcb5f2e47bfc64819d8d4b1077 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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