Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add monitor mode support for Raspberry Pi Pico W (bcm43439a0) FW 7_95_49_2271bb6 #579

Merged
merged 2 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 62 additions & 2 deletions firmwares/bcm43439a0/structs.common.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@
#define PAD _XSTR(__LINE__)
#endif

struct wl_rxsts {
uint pkterror;
uint phytype;
uint16 chanspec;
uint16 datarate;
uint8 mcs;
uint8 htflags;
uint antenna;
uint pktlength;
uint32 mactime;
uint sq;
int32 signal;
int32 noise;
uint preamble;
uint encoding;
uint nfrmtype;
struct wl_if *wlif;
} __attribute__((packed));

struct sk_buff {
union { /* 0x000 */
uint32 u32;
Expand Down Expand Up @@ -953,6 +972,47 @@ struct wlc_hw_info {
uint32 PAD; /* 0x168 */
} __attribute__((packed));

struct wlc_if_stats {
/* transmit stat counters */
uint32 txframe; /* tx data frames */
uint32 txbyte; /* tx data bytes */
uint32 txerror; /* tx data errors (derived: sum of others) */
uint32 txnobuf; /* tx out of buffer errors */
uint32 txrunt; /* tx runt frames */
uint32 txfail; /* tx failed frames */
uint32 rxframe; /* rx data frames */
uint32 rxbyte; /* rx data bytes */
uint32 rxerror; /* rx data errors (derived: sum of others) */
uint32 rxnobuf; /* rx out of buffer errors */
uint32 rxrunt; /* rx runt frames */
uint32 rxfragerr; /* rx fragment errors */
uint32 txretry; /* tx retry frames */
uint32 txretrie; /* tx multiple retry frames */
uint32 txfrmsnt; /* tx sent frames */
uint32 txmulti; /* tx mulitcast sent frames */
uint32 txfrag; /* tx fragments sent */
uint32 rxmulti; /* rx multicast frames */
};

struct wl_if {
struct wlc_if *wlcif;
struct hndrte_dev *dev;
};

struct wlc_if {
struct wlc_if *next;
uint8 type;
uint8 index;
uint8 flags;
struct wl_if *wlif;
void *qi;
union {
struct scb *scb;
struct wlc_bsscfg *bsscfg;
} u;
struct wlc_if_stats _cnt;
};

struct wlc_info {
void *pub; /* 0x000 */
void *osh; /* 0x004 */
Expand Down Expand Up @@ -1083,7 +1143,7 @@ struct wlc_info {
uint32 PAD; /* 0x1f8 */
uint32 PAD; /* 0x1fc */
uint32 PAD; /* 0x200 */
uint32 PAD; /* 0x204 */
uint32 monitor; /* 0x204 */
uint32 PAD; /* 0x208 */
uint32 PAD; /* 0x20c */
uint32 PAD; /* 0x210 */
Expand Down Expand Up @@ -1320,7 +1380,7 @@ struct wlc_info {
uint32 PAD; /* 0x5ac */
uint32 PAD; /* 0x5b0 */
uint32 PAD; /* 0x5b4 */
uint32 PAD; /* 0x5b8 */
struct wlc_if *wlcif_list; /* 0x5b8 */
uint32 PAD; /* 0x5bc */
uint32 PAD; /* 0x5c0 */
uint32 PAD; /* 0x5c4 */
Expand Down
39 changes: 39 additions & 0 deletions patches/bcm43439a0/7_95_49_2271bb6/nexmon/include/brcm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/***************************************************************************
* *
* ########### ########### ########## ########## *
* ############ ############ ############ ############ *
* ## ## ## ## ## ## ## *
* ## ## ## ## ## ## ## *
* ########### #### ###### ## ## ## ## ###### *
* ########### #### # ## ## ## ## # # *
* ## ## ###### ## ## ## ## # # *
* ## ## # ## ## ## ## # # *
* ############ ##### ###### ## ## ## ##### ###### *
* ########### ########### ## ## ## ########## *
* *
* S E C U R E M O B I L E N E T W O R K I N G *
* *
* This file is part of NexMon. *
* *
* Copyright (c) 2016 NexMon Team *
* *
* NexMon is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* NexMon is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with NexMon. If not, see <http://www.gnu.org/licenses/>. *
* *
**************************************************************************/

#pragma once

#include "../include/types.h"
#define WL_CHANSPEC_CHAN_MASK 0x00ff
#define CHSPEC_CHANNEL(chspec) ((uint8_t)((chspec) & WL_CHANSPEC_CHAN_MASK))
88 changes: 88 additions & 0 deletions patches/bcm43439a0/7_95_49_2271bb6/nexmon/include/d11.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/***************************************************************************
* *
* ########### ########### ########## ########## *
* ############ ############ ############ ############ *
* ## ## ## ## ## ## ## *
* ## ## ## ## ## ## ## *
* ########### #### ###### ## ## ## ## ###### *
* ########### #### # ## ## ## ## # # *
* ## ## ###### ## ## ## ## # # *
* ## ## # ## ## ## ## # # *
* ############ ##### ###### ## ## ## ##### ###### *
* ########### ########### ## ## ## ########## *
* *
* S E C U R E M O B I L E N E T W O R K I N G *
* *
* This file is part of NexMon. *
* *
* Copyright (c) 2016 NexMon Team *
* *
* NexMon is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* NexMon is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with NexMon. If not, see <http://www.gnu.org/licenses/>. *
* *
**************************************************************************/

#pragma once

struct d11rxhdr {
unsigned short RxFrameSize; /* Actual byte length of the frame data received */
unsigned short PAD;
unsigned short PhyRxStatus_0; /* PhyRxStatus 15:0 */
unsigned short PhyRxStatus_1; /* PhyRxStatus 31:16 */
unsigned short PhyRxStatus_2; /* PhyRxStatus 47:32 */
unsigned short PhyRxStatus_3; /* PhyRxStatus 63:48 */
unsigned short PhyRxStatus_4; /* PhyRxStatus 79:64 */
unsigned short PhyRxStatus_5; /* PhyRxStatus 95:80 */
unsigned short RxStatus1; /* MAC Rx status */
unsigned short RxStatus2; /* extended MAC Rx status */
unsigned short RxTSFTime; /* RxTSFTime time of first MAC symbol + M_PHY_PLCPRX_DLY */
unsigned short RxChan; /* gain code, channel radio code, and phy type -> looks like chanspec */
} __attribute__((packed));

/* ucode RxStatus1: */
#define RXS_BCNSENT 0x8000
#define RXS_SECKINDX_MASK 0x07e0
#define RXS_SECKINDX_SHIFT 5
#define RXS_DECERR (1 << 4)
#define RXS_DECATMPT (1 << 3)
/* PAD bytes to make IP data 4 bytes aligned */
#define RXS_PBPRES (1 << 2)
#define RXS_RESPFRAMETX (1 << 1)
#define RXS_FCSERR (1 << 0)

/* ucode RxStatus2: */
#define RXS_AMSDU_MASK 1
#define RXS_AGGTYPE_MASK 0x6
#define RXS_AGGTYPE_SHIFT 1
#define RXS_PHYRXST_VALID (1 << 8)
#define RXS_RXANT_MASK 0x3
#define RXS_RXANT_SHIFT 12

/* RxChan */
#define RXS_CHAN_40 0x1000
#define RXS_CHAN_5G 0x0800
#define RXS_CHAN_ID_MASK 0x07f8
#define RXS_CHAN_ID_SHIFT 3
#define RXS_CHAN_PHYTYPE_MASK 0x0007
#define RXS_CHAN_PHYTYPE_SHIFT 0

struct wlc_d11rxhdr {
struct d11rxhdr rxhdr;
unsigned int tsf_l;
char rssi; /* computed instanteneous RSSI in BMAC */
char rxpwr0;
char rxpwr1;
char do_rssi_ma; /* do per-pkt sampling for per-antenna ma in HIGH */
char rxpwr[4]; /* rssi for supported antennas */
} __attribute__((packed));

40 changes: 40 additions & 0 deletions patches/bcm43439a0/7_95_49_2271bb6/nexmon/include/local_wrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/***************************************************************************
* *
* ########### ########### ########## ########## *
* ############ ############ ############ ############ *
* ## ## ## ## ## ## ## *
* ## ## ## ## ## ## ## *
* ########### #### ###### ## ## ## ## ###### *
* ########### #### # ## ## ## ## # # *
* ## ## ###### ## ## ## ## # # *
* ## ## # ## ## ## ## # # *
* ############ ##### ###### ## ## ## ##### ###### *
* ########### ########### ## ## ## ########## *
* *
* S E C U R E M O B I L E N E T W O R K I N G *
* *
* This file is part of NexMon. *
* *
* Copyright (c) 2016 NexMon Team *
* *
* NexMon is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* NexMon is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with NexMon. If not, see <http://www.gnu.org/licenses/>. *
* *
**************************************************************************/

#ifndef LOCAL_WRAPPER_H
#define LOCAL_WRAPPER_H

#include "../src/local_wrapper.c" // wrapper definitions for functions that already exist in the firmware

#endif /*LOCAL_WRAPPER_H*/
113 changes: 113 additions & 0 deletions patches/bcm43439a0/7_95_49_2271bb6/nexmon/src/monitormode.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/***************************************************************************
* *
* ########### ########### ########## ########## *
* ############ ############ ############ ############ *
* ## ## ## ## ## ## ## *
* ## ## ## ## ## ## ## *
* ########### #### ###### ## ## ## ## ###### *
* ########### #### # ## ## ## ## # # *
* ## ## ###### ## ## ## ## # # *
* ## ## # ## ## ## ## # # *
* ############ ##### ###### ## ## ## ##### ###### *
* ########### ########### ## ## ## ########## *
* *
* S E C U R E M O B I L E N E T W O R K I N G *
* *
* This file is part of NexMon. *
* *
* Copyright (c) 2016 NexMon Team *
* *
* NexMon is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* NexMon is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with NexMon. If not, see <http://www.gnu.org/licenses/>. *
* *
**************************************************************************/

#pragma NEXMON targetregion "patch"

#include <firmware_version.h>
#include <wrapper.h> // wrapper definitions for functions that already exist in the firmware
#include <structs.h> // structures that are used by the code in the firmware
#include <patcher.h>
#include <helper.h>
#include "d11.h"
#include "brcm.h"

//#define RADIOTAP_MCS
#include <ieee80211_radiotap.h>

#define MONITOR_DISABLED 0
#define MONITOR_IEEE80211 1
#define MONITOR_RADIOTAP 2
#define MONITOR_LOG_ONLY 3
#define MONITOR_DROP_FRM 4
#define MONITOR_IPV4_UDP 5

void
wl_monitor_radiotap(struct wl_info *wl, struct wl_rxsts *sts, struct sk_buff *p) {
struct sk_buff *p_new = pkt_buf_get_skb(wl->wlc->osh, p->len + sizeof(struct nexmon_radiotap_header));
struct nexmon_radiotap_header *frame = (struct nexmon_radiotap_header *) p_new->data;
struct tsf tsf;
wlc_bmac_read_tsf(wl->wlc_hw, &tsf.tsf_l, &tsf.tsf_h);

frame->header.it_version = 0;
frame->header.it_pad = 0;
frame->header.it_len = sizeof(struct nexmon_radiotap_header);
frame->header.it_present =
(1<<IEEE80211_RADIOTAP_TSFT)
| (1<<IEEE80211_RADIOTAP_FLAGS)
| (1<<IEEE80211_RADIOTAP_CHANNEL)
| (1<<IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
frame->tsf.tsf_l = tsf.tsf_l;
frame->tsf.tsf_h = tsf.tsf_h;
frame->flags = IEEE80211_RADIOTAP_F_FCS;
frame->chan_freq = wlc_phy_channel2freq(CHSPEC_CHANNEL(sts->chanspec));
frame->chan_flags = 0;
frame->dbm_antsignal = sts->signal;

memcpy(p_new->data + sizeof(struct nexmon_radiotap_header), p->data + 6, p->len - 6);

p_new->len -= 6;

if (wl->wlc->wlcif_list->next)
wl->wlc->wlcif_list->wlif->dev->chained->funcs->xmit(wl->wlc->wlcif_list->wlif->dev, wl->wlc->wlcif_list->wlif->dev->chained, p_new);
else
wl->dev->chained->funcs->xmit(wl->dev, wl->dev->chained, p_new);
}

void
wl_monitor_hook(struct wl_info *wl, struct wl_rxsts *sts, struct sk_buff *p) {
switch(wl->wlc->monitor & 0xFF) {
case MONITOR_RADIOTAP:
wl_monitor_radiotap(wl, sts, p);
break;

case MONITOR_IEEE80211:
wl_monitor(wl, sts, p);
break;

case MONITOR_LOG_ONLY:
printf("frame received\n");
break;

case MONITOR_DROP_FRM:
break;

case MONITOR_IPV4_UDP:
printf("%s: udp tunneling not implemented\n");
// not implemented yet
break;
}
}

__attribute__((at(0x81F6D6, "flashpatch", CHIP_VER_BCM43439a0, FW_VER_ALL)))
BLPatch(flash_patch_76, wl_monitor_hook);
Loading