Documentation library

nRF5 SDK for Thread and Zigbee v2.0.0
Thread Sniffer based on nRF52840 with Wireshark

With the help of this SDK, you can set up a Thread Sniffer, which can help you to efficiently analyze Thread network traffic.

During development, you may need to check what kind of data is wirelessly transmitted over the Thread network. With the help of the following instructions, you can set up a sniffer which allows to dynamically monitor the IEEE 802.15.4 wireless traffic. The captured frames are passed to Wireshark, which allows to decode the Thread protocol and other protocols that it uses, like 6LoWPAN, IPv6, UDP, and CoAP. This provides complete information about the messages that are sent in the mesh network.

Required hardware

  • nRF52840 PCA10056 Development Kit
  • PC running a Linux based operating system or MacOS (Ubuntu 17.04 has been tested)

Required software

  • Wireshark 2.4.1 or newer
  • Python 2.7.10
  • nrfjprog – available in nRF5x-Command-Line-Tools
  • NCP firmware binary

Obtaining the firmware

To set up the Sniffer, you need the precompiled NCP hex file with native USB support. The file is delivered with this SDK and can be found in the following directory: <InstallFolder>/examples/thread/ncp/usb/hex.

Another alternative to obtain the firmware hex file is to build it yourself from the OpenThread repository. However, in such case the LEDs will not indicate the NCP state, because the Board Support Package is only available in the example provided in the SDK.

Compiling the hex file

For the compilation of the hex file, the following tools are required:

  • git
  • make
  • autotools-dev
  • python-setuptools
  • gnu-arm-embedded toolchain (for example, binutils-arm-none-eabi package)
  • nrfjprog (from the nRF5x-Command-Line-Tools)

To compile the hex file:

  1. Install the necessary tools on Ubuntu Linux.
    sudo apt-get install git python-setuptools make binutils-arm-none-eabi
  2. Run the following commands.
    git clone https://github.com/openthread/openthread.git
    cd openthread
    ./bootstrap
Note
  • During testing, the following OpenThread commit has been used to compile the hex file: https://github.com/openthread/openthread/commit/ec59d7ef
  • For native USB support, which is recommended due to higher stability, the USB=1 switch is appended to the make command. To use the standard UART transport through the J-Link USB port, you can omit USB=1.
    make -f <InstallFolder>/examples/Makefile-nrf52840 MAC_FILTER=1 USB=1
    arm-none-eabi-objcopy -O ihex <InstallFolder>/output/nrf52840/bin/ot-ncp-ftd output/nrf52840/bin/ot-ncp-ftd.hex

Flashing the firmware

Connect the nRF52840 Development Kit through the J-Link USB port and flash the NCP image.

Depending on your choice for obtaining the firmware:

  • For the precompiled hex found in the SDK:
    nrfjprog --chiperase --family NRF52 --program <InstallFolder>/examples/thread/ncp/usb/hex/nrf52840_xxaa.hex --reset
  • For the manually compiled hex file:
    nrfjprog --chiperase --family NRF52 --program <InstallFolder>/output/nrf52840/bin/ot-ncp-ftd.hex --reset

Installing Wireshark

On Ubuntu Linux, run the following commands.

sudo add-apt-repository ppa:dreibh/ppa
sudo apt-get update
sudo apt-get install wireshark

Connecting NCP to the host

Connect the flashed development kit to the host as shown in the image.

connect_ncp_usb.PNG
Connecting NCP to the host
Note
When the native USB port is used, use the nRF micro USB port and set the nRF power source switch to the USB position, as shown in the image.

Starting Wireshark with the Sniffer

  1. Clone the pyspinel repository that will be used as an interface between NCP and Wireshark. Pyspinel commit c1ec011826 has been tested.
    git clone https://github.com/openthread/pyspinel.git
    cd pyspinel
    sudo easy_install pip
    pip install --user pyserial
    pip install --user ipaddress
  2. Configure Wireshark permissions.
    sudo usermod -a -G dialout $USER
    sudo groupadd wireshark
    sudo usermod -a -G wireshark $USER
    sudo chgrp wireshark /usr/bin/dumpcap
    sudo chmod o-rx /usr/bin/dumpcap
    sudo setcap 'CAP_NET_RAW+eip CAP_NET_ADMIN+eip' /usr/bin/dumpcap
    sudo getcap /usr/bin/dumpcap
  3. Start Wireshark.
    python ./sniffer.py -c 11 -n 1 -b 115200 --crc -u /dev/ttyACM0 --no-reset | wireshark -k -i -
    The parameters stand for the following:
    • -c – Thread Channel
    • -n – Node ID
    • –crc – Disables the wrong FCS warning resulting from the fact that Nordic radio replaces one byte of CRC with LQI after a packet is received and verified.
    • –no-reset – Used when NCP is connected via the native USB connection, otherwise this parameter should be omitted.
  4. Press Ctrl + Shift + P to enter the Wireshark preferences.
  5. Go to Protocols -> IEEE 802.15.4.
    wireshark_preferences.PNG
    Wireshark - Preferences
  6. Edit the Decryption Keys.
    • Decryption key: 00112233445566778899aabbccddeeff
    • Decryption key index: 1
    • Key hash: Thread hash
      decryption_keys.PNG
      Decryption Keys
  7. Go to Protocols -> Thread and edit the settings.
    • Decode CoAP for Thread: Selected
    • Thread sequence counter: 00000000
    • Use PAN ID as first two octets of master key: Deselected
    • Automatically acquire Thread sequence counter: Selected
  8. Go to Protocols -> 6LoWPAN and edit the settings.
    • Derive ID according to RFC 4944: Deselected
    • Context 0: fdde:ad00:beef:0::/64 You can also add additional contexts, for example, for working with Nordic Thread Border Router:
    • Context 1: 64:FF9B::/96
    • Context 2: Native IPv6 global prefix that is being propagated in the Thread Network.

Troubleshooting

This section contains some known issues that you can encounter when setting up the Thread Sniffer.

No such file or directory when starting Wireshark

Issue:
"/usr/bin/env: 'python -u': No such file or directory"
Solution:
The issue appears when running the following command:

sudo ./sniffer.py -c 11 -n 1 -b 115200 --crc -u /dev/ttyACM0 --no-reset | wireshark -k -i -

Instead of this command, run the following one:

sudo python ./sniffer.py -c 11 -n 1 -b 115200 --crc -u /dev/ttyACM0 --no-reset | wireshark -k -i -


Permission denied for /usr/bin/dumpcap

Issue:
"Couldn't run /usr/bin/dumpcap in child process: Permission denied."
Solution:
Change ownership of dumpcap to the current USER group:

sudo chgrp USER /usr/bin/dumpcap


Failed to initialize sniffer

Issue:

Initializing sniffer...
MAC_FILTER_MODE set failed
ERROR: failed to initialize sniffer
End of file on pipe magic during open.

Solution:
Power cycle the board and run the following command.

python ./sniffer.py -c 11 -n 1 -b 115200 --crc -u /dev/ttyACM0 --no-reset | wireshark -k -i -


Could not open port /dev/ttyACM0

Issue:

Traceback (most recent call last):
File "/home/repo/pyspinel/spinel/stream.py", line 57, in __init__
self.serial = serial.Serial(dev, baudrate)
File "/home/.local/lib/python2.7/site-packages/serial/serialutil.py", line 240, in __init__
self.open()
File "/home/.local/lib/python2.7/site-packages/serial/serialposix.py", line 268, in open
raise SerialException(msg.errno, "could not open port {}: {}".format(self._port, msg))
SerialException: [Errno 2] could not open port /dev/ttyACM0: [Errno 2] No such file or directory: '/dev/ttyACM0'
Initializing sniffer...
Traceback (most recent call last):
File "./sniffer.py", line 214, in <module>
main()
File "./sniffer.py", line 146, in main
result = sniffer_init(wpan_api, options)
File "./sniffer.py", line 81, in sniffer_init
wpan_api.cmd_send(SPINEL.CMD_RESET)
File "/home/repo/pyspinel/spinel/codec.py", line 1047, in cmd_send
self.transact(command_id, payload, tid)
File "/home/repo/pyspinel/spinel/codec.py", line 902, in transact
self.stream_tx(pkt)
File "/home/repo/pyspinel/spinel/codec.py", line 940, in stream_tx
self.stream.write(pkt)
File "/home/repo/pyspinel/spinel/stream.py", line 63, in write
self.serial.write(data)
AttributeError: 'StreamSerial' object has no attribute 'serial'

Solution:
This issue indicates that NCP is not connected or a wrong /dev/ttyACM* is specified, for example there are multiple ACM devices connected to the system and the sniffer is visible as /dev/ttyACM1.

Sniffing has started but no data is visible

Issue:
Sniffing has started but no data is visible in Wireshark, or sniffing has hung and no more data can be observed.
Solution:
When this issue appears, power cycle the board and run the following command.

python ./sniffer.py -c 11 -n 1 -b 115200 --crc -u /dev/ttyACM0 --no-reset | wireshark -k -i -


Additional information

For additional documentation, see Spinel Sniffer Reference on GitHub.