From c8327eab5be246d4b517afdba034775f00afa988 Mon Sep 17 00:00:00 2001 From: Shen Mintao Date: Fri, 7 Aug 2026 16:15:12 +0800 Subject: [PATCH] feat: enable monitor packet injection Build the existing monitor transmit path by default. Validate the radiotap header before parsing it and align the transmit prototype with netdev_tx_t. Hardware-tested-by: jkroepke (GitHub) --- drivers/aic8800/aic8800_fdrv/Makefile | 2 +- drivers/aic8800/aic8800_fdrv/rwnx_tx.c | 43 ++++++++++++++------------ drivers/aic8800/aic8800_fdrv/rwnx_tx.h | 3 +- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/drivers/aic8800/aic8800_fdrv/Makefile b/drivers/aic8800/aic8800_fdrv/Makefile index 21ebf91..b2a3514 100644 --- a/drivers/aic8800/aic8800_fdrv/Makefile +++ b/drivers/aic8800/aic8800_fdrv/Makefile @@ -172,7 +172,7 @@ CONFIG_RWNX_BCMC ?= y # Enable Monitor+Data interface support (need FW support) CONFIG_RWNX_MON_DATA =n -CONFIG_RWNX_MON_XMIT ?= n +CONFIG_RWNX_MON_XMIT ?= y CONFIG_RWNX_MON_RXFILTER ?= n CONFIG_FILTER_TCP_ACK =y diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_tx.c b/drivers/aic8800/aic8800_fdrv/rwnx_tx.c index 8d2ab4a..2cec672 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_tx.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_tx.c @@ -1991,7 +1991,7 @@ free_use: netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *dev) { - int rtap_len, ret, idx, tmp_len; + int rtap_len, ret, idx; struct ieee80211_radiotap_header *rtap_hdr; // net/ieee80211_radiotap.h struct ieee80211_radiotap_iterator iterator; // net/cfg80211.h u8_l *rtap_buf = (u8_l *)skb->data; @@ -2012,10 +2012,30 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d bool offchan = false; int nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX; - rtap_hdr = (struct ieee80211_radiotap_header*)(rtap_buf); - rtap_len = ieee80211_get_radiotap_len(rtap_buf);//max_length frame_len = skb->len; + if (unlikely(skb->len < sizeof(*rtap_hdr))) { + AICWFDBG(LOGERROR, "%s radiotap header is truncated\n", __func__); + goto free_tag; + } + + rtap_hdr = (struct ieee80211_radiotap_header*)(rtap_buf); + if (unlikely(rtap_hdr->it_version)) { + AICWFDBG(LOGERROR, "%s itv \r\n", __func__); + goto free_tag; + } + + rtap_len = ieee80211_get_radiotap_len(rtap_buf);//max_length + if (unlikely(rtap_len < sizeof(*rtap_hdr))) { + AICWFDBG(LOGERROR, "%s rtap_len < sizeof(struct ieee80211_radiotap_header) \r\n", __func__); + goto free_tag; + } + + if (unlikely(skb->len < rtap_len)) { + AICWFDBG(LOGERROR, "%s skb->len < rtap_len \r\n", __func__); + goto free_tag; + } + AICWFDBG(LOGINFO, "rwnx_start_monitor_if_xmit, skb_len=%d, rtap_len=%d\n", skb->len, rtap_len); //rwnx_data_dump((char*)__func__, skb->data, skb->len); if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || @@ -2023,23 +2043,6 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){ nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX_FOR_OLD_IC; } - - - if (unlikely(rtap_hdr->it_version)){ - AICWFDBG(LOGERROR, "%s itv \r\n", __func__); - goto free_tag; - } - - if (unlikely(skb->len < rtap_len)){ - AICWFDBG(LOGERROR, "%s skb->len < rtap_len \r\n", __func__); - goto free_tag; - } - - if (unlikely(rtap_len < sizeof(struct ieee80211_radiotap_header))){ - AICWFDBG(LOGERROR, "%s rtap_len < sizeof(struct ieee80211_radiotap_header) \r\n", __func__); - goto free_tag; - } - frame_len -= rtap_len; pframe = rtap_buf + rtap_len; diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_tx.h b/drivers/aic8800/aic8800_fdrv/rwnx_tx.h index 772e2d1..532ffab 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_tx.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_tx.h @@ -172,7 +172,8 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta, u64 *cookie); #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */ #ifdef CONFIG_RWNX_MON_XMIT -int rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *dev); +netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, + struct net_device *dev); #endif int rwnx_txdatacfm(void *pthis, void *host_id);