Notes on getting wireless monitor mode working on the Raspberry Pi Zero W

Recently I ordered a Raspberry Pi Zero W from Pimoroni and was pleased to discover that the wireless chipset is the same CYW43438 found in the Raspberry Pi 3, providing 802.11 wireless and bluetooth 4.0 connectivity. I've previously had success using nexmon on the Pi 3 so I hoped it would work just as well on the smaller Raspberry Pi Zero W

The Pi Zero W is physically very small and extremely frugal with power so it makes an excellent candidate to deploy in a variety of locations, perhaps powered by batteries or connected to a nearby USB power source..

" let go before it's too late or hang on and keep getting higher, posing the question: how long can you keep a grip on the rope?"

I thought building nexmon would simply be a case of changing some references to ARMv7 to ARMv6 and looking at open pull requests in the project I found that Github user NoobieDog had already done some of that work and submitted patches that adjust the Makefiles to add support for the ARMv6 based Pi Zero W and happily these worked well with only a few minor tweaks required. If you plan on trying this yourself you should read the prominent warning in the nexmon docs about potentially damaging your hardware!

I built directly on the Pi Zero W using the following process:

# become root sudo -i # ensure packages are up to date apt-get update apt-get upgrade # install prerequisites sudo apt install raspberrypi-kernel-headers git libgmp3-dev gawk # grab a copy of nexmon git clone https://github.com/NoobieDog/nexmon.git cd nexmon # setup env for build source setup_env.sh # "Compile some build tools and extract the ucode and flashpatches # from the original firmware files" make # compile patched firmware cd patches/bcm43438/7_45_41_26/nexmon/ make # backup existing firmware then install new make backup-firmware make install-firmware # build nexutil cd utilities/libnexio/ make cd utilities/nexutil/ make make install

Unfortunately when I tried to build libnexio I got an error:

/ndk-build NDK_APPLICATION_MK=`pwd`/Application.mk NDK_APP_OUT=. TARGET_PLATFORM=android-21 /bin/sh: 1: /ndk-build: not found Makefile:7: recipe for target 'libs/armeabi/libnexio.a' failed make: *** [libs/armeabi/libnexio.a] Error 127

..Suggesting that the Makefile thought this was an Android device..

as a workaround I adjusted the Makefile to this:

GIT_VERSION := $(shell git describe --abbrev=4 --dirty --always --tags) all: libs/armeabi/libnexio.a libs/armeabi/libnexio.a: libnexio.c gcc -c libnexio.c -o libnexio.o -DBUILD_ON_RPI -DVERSION=\"$GIT_VERSION\" -I../../patches/include ar rcs libnexio.a libnexio.o clean: rm -Rf libs rm -Rf local

"They're selling hippie wigs in Woolworth's, man"

At this point everything built successfully and the nexmon driver was loaded!

Nexmon is controlled using the nexutil command. Monitor mode with radiotap headers, which I needed to use, can be activated with 'nexutil -m2' and deactivated with 'nexutil -m0' which puts the interface back into 'managed' mode where it can send and receive as normal.

## ## Useful commands: ## # turn monitor mode on ifconfig wlan0 down nexutil -m2 ifconfig wlan0 up # turn monitor mode off ifconfig wlan0 down nexutil -m0 ifconfig wlan0 up # load original driver ifconfig wlan0 down rmmod brcmfmac modprobe brcmfmac ifconfig wlan0 up # load nexmon driver ifconfig wlan0 down rmmod brcmfmac insmod /root/nexmon/patches/bcm43438/7_45_41_26/nexmon/brcmfmac/brcmfmac.ko ifconfig wlan0 up

"The greatest decade in the history of mankind is over."

Unfortunately the usual commands to change channel wouldn't work with the nexmon driver but I found a workaround by loading the original driver, switching to ad-hoc mode and setting the channel there which persisted when the nexmon driver was reloaded:

ifconfig wlan0 down rmmod brcmfmac modprobe brcmfmac iwconfig wlan0 mode ad-hoc iwconfig wlan0 channel 3 rmmod brcmfmac insmod /root/nexmon/patches/bcm43438/7_45_41_26/nexmon/brcmfmac/brcmfmac.ko nexutil -m2 ifconfig wlan0 up

"As Presuming Ed here has so consistently pointed out, we have failed to paint it black."

As it isn't possible to use the wifi normally while in monitor mode I've been using an ersatz bluetooth shell I hacked together recently which, althought pretty limited, enables the interface to be taken in and out of monitor mode which is good enough to get things back into a state where I can SSH in.