Skip to content

Commit

Permalink
Added frame injection support
Browse files Browse the repository at this point in the history
  • Loading branch information
kimocoder committed Jan 18, 2019
1 parent ea24e4d commit b7160a6
Show file tree
Hide file tree
Showing 13 changed files with 550 additions and 214 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ _OS_INTFS_FILES := os_dep/osdep_service.o \
os_dep/linux/rtw_cfgvendor.o \
os_dep/linux/wifi_regd.o \
os_dep/linux/rtw_android.o \
os_dep/linux/rtw_radiotap.o \
os_dep/linux/rtw_proc.o

ifeq ($(CONFIG_MP_INCLUDED), y)
Expand Down Expand Up @@ -1887,7 +1888,7 @@ clean:
cd hal ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
cd core/efuse ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
cd core ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
cd os_dep/linux ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
cd os_dep/linux ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko .rtw_radiotap.o.d
cd os_dep ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
cd platform ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
rm -fr Module.symvers ; rm -fr Module.markers ; rm -fr modules.order
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# RTL8192EU
Linux driver for Realtek **RTL8192EU** based on official's **TP Link TL - WN823N V3 Beta** v5.2.19.1 from 2018-05-08
Supports monitor mode and frame injection for penetration testing abilities.

# Supported devices:
- DWA-131 _(untested)_
Expand All @@ -9,6 +10,7 @@ Linux driver for Realtek **RTL8192EU** based on official's **TP Link TL - WN823N
- TL-WN823N V3 _(tested)_

# Changelog:
- Added frame injection support
- Monitor mode is now supported
- Turned of powersaving
- Turned of debug
Expand Down
5 changes: 0 additions & 5 deletions clean

This file was deleted.

50 changes: 19 additions & 31 deletions core/rtw_mlme_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -7210,26 +7210,15 @@ void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
u8 wireless_mode;
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct sta_info *psta = NULL;
struct sta_priv *pstapriv = &padapter->stapriv;
struct sta_info *pbcmc_sta = NULL;

psta = rtw_get_stainfo(pstapriv, pattrib->ra);
pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;

pattrib->hdrlen = 24;
pattrib->nr_frags = 1;
pattrib->priority = 7;
pattrib->inject = 0xa5;

if (pbcmc_sta)
pattrib->mac_id = pbcmc_sta->cmn.mac_id;
else {
pattrib->mac_id = 0;
RTW_INFO("mgmt use mac_id 0 will affect RA\n");
}
pattrib->mac_id = 0;
pattrib->qsel = QSLT_MGNT;

pattrib->pktlen = 0;

if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
Expand All @@ -7238,22 +7227,22 @@ void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
wireless_mode = WIRELESS_11G;

pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
#ifdef CONFIG_80211AC_VHT
if (pHalData->rf_type == RF_1T1R)
pattrib->raid = RATEID_IDX_VHT_1SS;
else if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_2T4R)
pattrib->raid = RATEID_IDX_VHT_2SS;
else if (pHalData->rf_type == RF_3T3R)
pattrib->raid = RATEID_IDX_VHT_3SS;
else
pattrib->raid = RATEID_IDX_BGN_40M_1SS;
#endif
#ifdef CONFIG_80211AC_VHT
if (pHalData->rf_type == RF_1T1R)
pattrib->raid = RATEID_IDX_VHT_1SS;
else if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_2T4R)
pattrib->raid = RATEID_IDX_VHT_2SS;
else if (pHalData->rf_type == RF_3T3R)
pattrib->raid = RATEID_IDX_VHT_3SS;
else
pattrib->raid = RATEID_IDX_BGN_40M_1SS;
#endif

#ifdef CONFIG_80211AC_VHT
pattrib->rate = MGN_VHT1SS_MCS9;
#else
pattrib->rate = MGN_MCS7;
#endif
#ifdef CONFIG_80211AC_VHT
pattrib->rate = MGN_VHT1SS_MCS9;
#else
pattrib->rate = MGN_MCS7;
#endif

pattrib->encrypt = _NO_PRIVACY_;
pattrib->bswenc = _FALSE;
Expand All @@ -7266,14 +7255,13 @@ void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib)

pattrib->seqnum = pmlmeext->mgnt_seq;

pattrib->retry_ctrl = _TRUE;
pattrib->retry_ctrl = _FALSE;

pattrib->mbssid = 0;
pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;

}


void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
{
u8 wireless_mode;
Expand Down
212 changes: 129 additions & 83 deletions core/rtw_xmit.c
Original file line number Diff line number Diff line change
Expand Up @@ -4206,6 +4206,16 @@ static void do_queue_select(_adapter *padapter, struct pkt_attrib *pattrib)
#endif /* CONFIG_MCC_MODE */
}


static inline void dump_buf(u8 *buf, u32 len)
{
u32 i;
printk("-----------------Len %d----------------\n", len);
for(i=0; i<len; i++)
printk("%2.2x-", *(buf+i));
printk("\n");
}

/*
* The main transmit(tx) entry
*
Expand All @@ -4214,7 +4224,14 @@ static void do_queue_select(_adapter *padapter, struct pkt_attrib *pattrib)
* 0 success, hardware will handle this xmit frame(packet)
* <0 fail
*/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24))
int rtw_ieee80211_radiotap_iterator_next(struct ieee80211_radiotap_iterator *iterator);
void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib);
int rtw_ieee80211_radiotap_iterator_init(
struct ieee80211_radiotap_iterator *iterator,
struct ieee80211_radiotap_header *radiotap_header,
int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns);

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24))
s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
{
int ret = 0;
Expand All @@ -4226,10 +4243,26 @@ s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
u16 frame_ctl;
unsigned char src_mac_addr[6];
unsigned char dst_mac_addr[6];
struct rtw_ieee80211_hdr *dot11_hdr;
struct ieee80211_hdr *dot11_hdr;
struct ieee80211_radiotap_header *rtap_hdr;
struct ieee80211_radiotap_iterator iterator;
u8 fixed_rate = MGN_1M, sgi = 0, bwidth = 0, ldpc = 0, stbc = 0;
u16 txflags = 0;
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);

struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
u8 *buf = skb->data;
u32 len = skb->len;
u8 category, action;
int type = -1;

//RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));

if (skb)
rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);

Expand All @@ -4244,107 +4277,120 @@ s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
if (unlikely(skb->len < rtap_len))
goto fail;

if (rtap_len != 12) {
RTW_INFO("radiotap len (should be 14): %d\n", rtap_len);
goto fail;
}

/* Skip the ratio tap header */
skb_pull(skb, rtap_len);
ret = rtw_ieee80211_radiotap_iterator_init(&iterator, rtap_hdr, skb->len, NULL);
while (!ret) {
ret = rtw_ieee80211_radiotap_iterator_next(&iterator);

dot11_hdr = (struct rtw_ieee80211_hdr *)skb->data;
frame_ctl = le16_to_cpu(dot11_hdr->frame_ctl);
/* Check if the QoS bit is set */

if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {

struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
u8 *buf = skb->data;
u32 len = skb->len;
u8 category, action;
int type = -1;

pmgntframe = alloc_mgtxmitframe(pxmitpriv);
if (pmgntframe == NULL) {
rtw_udelay_os(500);
goto fail;
}
pattrib = &pmgntframe->attrib;

update_monitor_frame_attrib(padapter, pattrib);

pattrib->retry_ctrl = _FALSE;

_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);

pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;

_rtw_memcpy(pframe, (void *)buf, len);

pattrib->pktlen = len;

pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
if (ret)
continue;

if (is_broadcast_mac_addr(pwlanhdr->addr3) || is_broadcast_mac_addr(pwlanhdr->addr1))
pattrib->rate = MGN_24M;
/* see if this argument is something we can use */
switch (iterator.this_arg_index) {

pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
pattrib->seqnum = pmlmeext->mgnt_seq;
pmlmeext->mgnt_seq++;
case IEEE80211_RADIOTAP_RATE: /* u8 */
fixed_rate = *iterator.this_arg;
break;

pattrib->last_txcmdsz = pattrib->pktlen;
case IEEE80211_RADIOTAP_TX_FLAGS:
txflags = get_unaligned_le16(iterator.this_arg);
break;

dump_mgntframe(padapter, pmgntframe);
case IEEE80211_RADIOTAP_MCS: { /* u8,u8,u8 */
u8 mcs_have = iterator.this_arg[0];
if (mcs_have & IEEE80211_RADIOTAP_MCS_HAVE_MCS) {
fixed_rate = iterator.this_arg[2] & 0x7f;
if(fixed_rate > 31)
fixed_rate = 0;
fixed_rate += MGN_MCS0;
}
if ((mcs_have & 4) &&
(iterator.this_arg[1] & 4))
sgi = 1;
if ((mcs_have & 1) &&
(iterator.this_arg[1] & 1))
bwidth = 1;
if ((mcs_have & 0x10) &&
(iterator.this_arg[1] & 0x10))
ldpc = 1;
if ((mcs_have & 0x20))
stbc = (iterator.this_arg[1] >> 5) & 3;
}
break;

} else {
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
u8 *buf = skb->data;
u32 len = skb->len;
u8 category, action;
int type = -1;
case IEEE80211_RADIOTAP_VHT: {
/* u16 known, u8 flags, u8 bandwidth, u8 mcs_nss[4], u8 coding, u8 group_id, u16 partial_aid */
u8 known = iterator.this_arg[0];
u8 flags = iterator.this_arg[2];
unsigned int mcs, nss;
if((known & 4) && (flags & 4))
sgi = 1;
if((known & 1) && (flags & 1))
stbc = 1;
if(known & 0x40) {
bwidth = iterator.this_arg[3] & 0x1f;
if(bwidth>=1 && bwidth<=3)
bwidth = 1; // 40 MHz
else if(bwidth>=4 && bwidth<=10)
bwidth = 2; // 80 MHz
else
bwidth = 0; // 20 MHz
}
if(iterator.this_arg[8] & 1)
ldpc = 1;
mcs = (iterator.this_arg[4]>>4) & 0x0f;
nss = iterator.this_arg[4] & 0x0f;
if(nss > 0) {
if(nss > 4) nss = 4;
if(mcs > 9) mcs = 9;
fixed_rate = MGN_VHT1SS_MCS0 + ((nss-1)*10 + mcs);
}
}
break;

pmgntframe = alloc_mgtxmitframe(pxmitpriv);
if (pmgntframe == NULL)
goto fail;
default:
break;
}
}
/* Skip the ratio tap header */
skb_pull(skb, rtap_len);

pattrib = &pmgntframe->attrib;
update_mgntframe_attrib(padapter, pattrib);
pattrib->retry_ctrl = _FALSE;
// dot11_hdr = (struct ieee80211_hdr *)skb->data;
// frame_ctl = le16_to_cpu(dot11_hdr->frame_control);
/* Check if the QoS bit is set */

_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) {
rtw_udelay_os(500);
goto fail;
}
pattrib = &pmgntframe->attrib;
update_monitor_frame_attrib(padapter, pattrib);

pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);

_rtw_memcpy(pframe, (void *)buf, len);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;

pattrib->pktlen = len;
_rtw_memcpy(pframe, (void*)skb->data, skb->len);

pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
pattrib->pktlen = skb->len;

pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
pattrib->seqnum = pmlmeext->mgnt_seq;
pmlmeext->mgnt_seq++;
pattrib->rate = fixed_rate;
pattrib->sgi = sgi;
pattrib->bwmode = bwidth; // 0-20 MHz, 1-40 MHz, 2-80 MHz
pattrib->ldpc = ldpc;
pattrib->stbc = stbc;
pattrib->retry_ctrl = (txflags & 0x08)?_FALSE:_TRUE;

pattrib->last_txcmdsz = pattrib->pktlen;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;

dump_mgntframe(padapter, pmgntframe);
pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
pattrib->seqnum = pmlmeext->mgnt_seq;
pmlmeext->mgnt_seq++;

}
pattrib->last_txcmdsz = pattrib->pktlen;
dump_mgntframe(padapter, pmgntframe);

fail:

rtw_skb_free(skb);

return 0;
}
#endif
Expand Down
Loading

0 comments on commit b7160a6

Please sign in to comment.