nRF5 SDK for Thread and Zigbee v1.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, CoAP, providing complete information about the messages that are sent in the mesh network.

Required hardware

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

Required software

  1. Wireshark 2.4.1 or newer
  2. Python 2.7.10
  3. nrfjprog - available in nRF5x-Command-Line-Tools
  4. 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. Note however, that 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.

To compile the HEX file, the following tools are required:

Compiling 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

Flashing the firmware

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

For the prebuilt HEX found in the SDK:

nrfjprog --chiperase --family NRF52 --program <InstallFolder>/examples/thread/ncp/usb/hex/nrf52840_xxaa.hex --reset

For the manually built 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. First, you must clone the pyspinel repository which 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
    sudo pip install --user pyserial
    sudo pip install --user ipaddress
  2. Start Wireshark.
    sudo 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.
  3. Press Ctrl + Shift + P to enter the Wireshark preferences.
  4. Go to Protocols -> IEEE 802.15.4.
    wireshark_preferences.PNG
    Wireshark Preferences
  5. Edit the Decryption Keys.
    • Decryption key: 00112233445566778899aabbccddeeff
    • Decryption key index: 1
    • Key hash: Thread hash
      decryption_keys.PNG
      Decryption Keys
  6. 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
  7. 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: fdff:cafe:cafe:cafe::/64
    • Context 2: fd00:64:123:4567::/64
    • Context 3: 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.

Issue:
"/usr/bin/env: 'python -u': No such file or directory"
Solution:
Instead of running:

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

, run the following command:

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



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



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.

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



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, e.g. there are multiple ACM devices connected to the system and the sniffer is visible as /dev/ttyACM1.

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.

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


Documentation feedback | Developer Zone | Subscribe | Updated