Pi Zero W Monitor Mode

"If you're hanging on to a rising balloon, you're presented with a difficult decision"

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

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"
# compile patched firmware
cd patches/bcm43438/7_45_41_26/nexmon/
# backup existing firmware then install new 
make backup-firmware
make install-firmware
# build nexutil
cd utilities/libnexio/
cd utilities/nexutil/
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

    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
Sketchy Bluetooth Shell

"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.