Sunday, July 27, 2014

nRF24L01+ sniffer - part 2

Hardware

The requirement to use cheap commodity hardware resulted in the use of a standard Arduino Uno R3 and a single nRF24L01+ module. Some male-female Dupont cables connect the radio to the Arduino. Other Arduino's based on AtMega328 should also work, as long as they have a serial interface to the PC and 3.3V power supply for the radio (the nRF24 I/O pins are 5V tolerant).
Be careful as multiple variants exist of the nRF24L01+ modules, and they don't all use the same layout for the pin header!

Connect the two as follows:
nRF24L01+ module pinout


FunctionArduino Uno pinnRF24L01+
pin
GND
GND
-
1
3.3V
3.3V
-
2
CE
9
-
3
CSN/CS
10
-
4
SCK
13
-
5
MOSI
11
-
6
MISO
12
-
7
IRQ
2
-
8

Some applications don't connect the IRQ line, but the sniffer requires it to quickly respond to received packets.
This is what my sniffer looks like:

nRF24 sniffer hardware: Arduino Uno, prototype shield, some Dupont cables and nRF24L01+ module
I didn't have any male-female Dupont cables at hand, so I put a prototype shield inbetween to turn the female headers into male.


Software

The required software is split in the following parts:
  • Sketch running on the Arduino: configures the nRF24 radio and reads any messages received using SPI. It determines the actual payload size for each message and adds a microsecond-resolution timestamp. The messages are buffered in the Atmega328 and sent to the host over a serial connection. It keeps track of the number of lost messages, when the buffer is full.
  • Console application 'Nrf24Sniff.exe' (currently only Windows) which sends configuration data to the Arduino sketch and reads captured packets from the sketch, using a serial connection. The packets received are forwarded in libpcap-format to a named pipe. Wireshark will be instructed to capture from this named pipe (too bad it cannot capture directly from a serial connection).
  • Wireshark to visualize the captured packets, filter them and gather statistics.
  • Wireshark will be extended with one or more plugins (called dissectors, currently only precompiled for Windows) which recognize the nRF24 packet format and take it apart. Protocols which use the nRF24 as transport layer (e.g. MySensors) require a separate dissector.

Installation

As you can see in the description above, the console application and Wireshark dissectors are currently only available for Windows (anyone who volunteers to port them to Linux and/or Mac, please do so and let me know).
In the description below I assume you've already downloaded and installed:
  • Wireshark - I used 1.10.8, either 32- or 64-bits
  • Arduino IDE - I used 1.5.6-r2, but I guess any 1.5.x version will do
First download and extract the software I developed as a single zip-file from my GitHub repository.

Arduino sniffer sketch
Either move the contents from the 'Arduino' directory to your Arduino users' directory (c:\users\<yourname>\Documents\Arduino) or copy it elsewhere and instruct the Arduino IDE to use that directory by pointing Preferences -> Sketchbook location to it and restart. I'm a bit reluctant when it comes to copying libraries to your regular users' Arduino directory as it might conflict with any libraries already present. Beware that I changed some small thinks in the RF24 library that's included.
Start the Arduino IDE, load the NRF24_sniff sketch, connect the hardware setup as described above, select the correct board & comport and download the compiled sketch.

Nrf24Sniff.exe
The Windows console application which transfers captured data from a serial interface to a named pipe can be found in the 'SerialToPipe/bin/Win32' directory. Just copy this executable somewhere convenient.

Wireshark dissector(s)
Choose the directory matching your 32- or 64-bits install from 'Wireshark/bin/Win32' or 'Wireshark/bin/Win64' and copy the nrf24.dll to the Wireshark plugins directory, e.g. 'c:\Program Files\Wireshark\plugins\1.10.8\'.
Those using the MySensors library can also copy either mysensors1.dll (version 1.3 of the library) or mysensors2.dll (version 1.4beta), depending on the library version you're working with. Better not copy both of them as these are heuristic dissectors which have problems detecting the protocol version reliably.

Running

Connect the hardware running the sniffer sketch to your PC (either using an RS232 connection or a serial-to-USB bridge as present on the Arduino Uno). Note the comport assigned by Windows (the same port as in the Arduino IDE). Assure the Arduino IDE's Serial Monitor is not running as it will block access to the serial port.

Nrf24sniff.exe can be started from a cmd-window. It supports a number of commandline parameters which control its behaviour (display them using 'Nrf24Sniff.exe -h'):


For example, when monitoring MySensors 1.4beta traffic (at non-default 1Mb/s), using the Arduino Uno sniffer connected to com17, I run the tool as follows:

Nrf24Sniff.exe -P17 -c76 -r0 -l5 -p4 -a0xA8A8E1FC00 -C2

The address length is set to 5 bytes (-l5), of which 4 bytes are used as base address (-p4) (Please refer to part 1 of this series for a description of addressing schemes). Passing only the comport would have been sufficient in this case, as the rest of the parameters are all set to defaults.

Now run it:


Keep it running and open another console window to start Wireshark:


This instructs Wireshark to start capturing from interface (-i) \\.\pipe\wireshark (that's the named pipe Nrf24Sniff.exe will be writing to) and to start capturing immediately (-k). More commandline options for Wireshark can be found here.

After Wireshark starts capturing, the Nrf24Sniff console window will display a 'Wait for sniffer to restart' message for a few seconds (at most):


If it hangs here, restart the sniffer hardware manually by pressing the reset button on the Arduino (I'm working on that...).

As Wireshark has no clue how to interpret the data coming through our named pipe, we have to tell it which dissector to use.
Switch over to Wireshark and select Edit -> Preferences.
In the preferences window, open the protocols tree, scroll down and select DLT_USER.
Press the edit button for the 'Encapsulations table' and press New. Enter the data as in the screenshot below:

Press OK, OK, OK. Any packets on air that match the radio configuration should now be captured in Wireshark!


The Nrf24Sniff console shows a count of packets captured and lost:


What's next

The next and last part of this series will dive into the possibilities of Wireshark and the dissectors I've implemented for nRF24 packets and the MySensors protocol.

Updates
Aug 3 - statically linked Nrf24sniff.exe, so dependency on msvcr110.dll no longer exists. Should also work on WinXP now.

41 comments:

  1. When i upload the sniffer.ino , i get the error: circularbuffer.h is missed??
    i use arduino 1.5.8

    ReplyDelete
  2. You need first to Import the libraries CircularBuffer and RF24

    ReplyDelete
  3. I use wireshark 1.12.1 and receive and error
    "The procedure entry point tvb_length cold not be located in the dynamic library......"
    Some one cold help me?

    ReplyDelete
  4. Hey Ariel,

    I developed using Wireshark 1.10.8. Probably the API has slightly changed since then.
    Please try with Wireshark 1.10.x.

    ReplyDelete
  5. Is it possible to use this with an Arduino Mega 2560 or an Arduino Pro?

    ReplyDelete
    Replies
    1. In principle it should work (maybe you have to change some pin assignments). I didn't test it, though.

      Delete
  6. Hi.. I experimented a bit with your code and found some things I'd like to mention for others:

    The code seems to be only able to capture Enhanced Shock Burst messages. I've also experienced problems whithout enabling the dynamic payload length bit on the TX device. The mentioned limitation in part 3 (node addresses can only be 1 byte long), isn't present in the nrf24 dissector... It's only in the mysensors dissector.

    Anyways... Good work... I'll try to port the PC stuff to linux... If I succeed I'll contact you on github.

    ReplyDelete
    Replies
    1. Hey Didi!

      Thanks for the remarks! You're right about the node address: it used to be present, but I added a piece of configuration data (after writing this article) which is exchanged between the sniffer and the nrf24 dissector. I forgot to remove the limitation from this article ;-)
      It would be very nice if we could have a shared codebase for both Windows & Linux. Keep me informed!

      Cheerz,

      Yveaux

      Delete
    2. Sure.. I'm trying to change as little as possible... I will definitely not touch the Arduino Code for example, because I've got no clue of that and it seems to be a solid working piece of code which doesn't really come with any limitations... (Am I right assuming that it would even be possible to capture normal messages (Non Enhanced Shockburst) with just a new nrf24 dissector?)

      There are major differences in serial connection handling on windows and linux though...

      Greetings, Didi

      Delete
    3. Edit:
      Have you ever tried to receive Enhanced ShockBurst message with NoAck Bit set? I'm not sure wheter I've made a mistake in my TX code or not... I'll try to debug that anyways sooner or later, but it would be awesome if you could save me some time with that information. :)

      Greetings, Didi

      Delete
  7. Hi,

    I ported the Serial2Pipe Tool to linux and filed a pull request on Github.

    I was also able to answer my questions above on my own:
    The Arduino code is also assuming Enhanced Shockburst messages with a dynamic payload.
    The error seems to be in my TX code. So this project just works like expected.

    Greetings, Didi.

    ReplyDelete
  8. This comment has been removed by the author.

    ReplyDelete
  9. Hello. I copied files to "d:\Program Files\Wireshark\plugins\2.0.2\nrf24.dll"
    But I received an error. Please, see the picture

    https://www.dropbox.com/s/9domyxzd0u1u4ig/Problem.png?dl=0

    ReplyDelete
    Replies
    1. Use Wireshark 1.10.8, as I did. Wireshark tends to change their plugin interface regularly and this is what you've probably ran into.
      You can get it here: https://www.wireshark.org/download/win32/all-versions/

      Good luck!

      Delete
    2. This comment has been removed by the author.

      Delete
    3. Thank You very much for reply. It worked. I receive no errors, but I can't catch any packets.
      I connected GateWay and a node with humidity sensor. Domotics is receiving data but I can't see it in the Wireshark. Can You, please, help me?
      I'm using Mysensors 1.5

      Connect Wireshark to \\.\pipe\wireshark to continue...
      Wait for sniffer to restart Ok

      Channel: 76
      Datarate: 1Mb/s
      Address: 0xa8a8e1fc**
      Max payload: 32
      CRC length: 2
      Captured 0 packets, Lost 0 packets

      Delete
    4. Here is data from serial (I stopped Wireshark for this and commented binary_output )

      -- RF24 Sniff --
      4e 4c00050400fce1a8a80000000220 Channel: 76
      Datarate: 1Mb/s
      Address: 0xA8A8E1FC**
      Max payload: 32
      CRC length: 2

      STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
      RX_ADDR_P0-1 = 0xa8a8e1fc 0xc2c2c2c2

      //Some other data

      Listening...

      And this is all.
      What am I doing wrong?

      Delete
    5. This comment has been removed by the author.

      Delete
    6. I changed to -r2 and it works :)

      Delete
    7. Yup, -r2 sets datarate to 250KBit/s, which is default for MySensors.
      Great to hear you finally gor it working!
      To anybody else not capturing any packets: check-double-check the wireless parameters! Wrong configuration will cause you to capture nothing.

      Delete
  10. I set up everything as per your instructions, but Wireshark doesn't sniff any traffic. No errors, just captured 0 packets, lost 0 packets. When I unplug nRF24L01+ from Arduino during the sniffing process it shows me "illegal serial packet size 9". Any ideas what I could possibly do wrong? I checked and doublechecked all the instructions everything 100 times. Thanks in advance.

    ReplyDelete
    Replies
    1. I`m getting the same problem.
      any ideas how to solve this?

      Delete
    2. Did you connect the IRQ line from the nRF24 to the Arduino?
      It has to be connected for incoming packets to be captured.

      Delete
  11. This comment has been removed by the author.

    ReplyDelete
  12. Hi. Is it possible to record data by Raspberry Pi and then analyse on the PC? I need to log data from the chineese power meter "mhf120200P" that uses nrf24 to transmit data. But I do not know the detailes of the signal (channel, etc..)

    ReplyDelete
  13. I get the following error message after starting the sniffer:

    "M:\Arduino\Projecten\NRF24_Sniffer-master\SerialToPipe\bin\Win32>nrf24sniff.exe -P9 -r2 -c76 -l5 -p4 -C2-a0xA8A8E1FC00

    Connect Wireshark to \\.\pipe\wireshark to continue...
    Wait for sniffer to restart -
    ALERT: Failed waiting for sniffer to restart"

    The Sniffer exits as soon as I start Wireshark....any suggestion?

    ReplyDelete
    Replies
    1. Problem solved!! Forgot to uncomment #define BINARY_OUTPUT

      Delete
  14. Thanks you so much for this wonderful tool! I am trying this to reverse engineering the dimplex connex protocol used on electric baseboard heaters. The chip used is NRFLE1F. So far, I have not been able to sniff any packets. Do you think there is potential for success here?

    ReplyDelete
    Replies
    1. Hi Jared,

      Any luck with this? I am just about to give it a try here...

      Delete
  15. Hi,

    is this sniffer working with the 2.3 lib of mysensor ?

    many thanks

    Gerard

    ReplyDelete
  16. the interface of wireshark has changed in the version 2.6 to parameter the DLT_user. when typing nrf24, an error occurs : protocol not known. i have copied the correct plugins in teh wareskark directory.
    is someone how to configure the decoding of NRF24 with this new version ?

    Thanks in advance
    gerard


    do you kon

    ReplyDelete
  17. Hi everybody, specially Yveaux!
    Thanks for this great tool.
    What is the latest version of WireShark possible to use?
    I'm using 3.2.2 and got message file not found.
    //./pipe is also not available. Must I make this directory or is it automatically made?

    ReplyDelete
  18. This is great project! I worked it out on ESP32 as a Arduino host.
    Check out @ https://github.com/Gobol/esp32_rf24_sniffer

    ReplyDelete
  19. Hello, I have another NRF24L01 conencted to a Nano transmitting and I have tested the sniffing NRF24L01 (hooked up to a Mega board) and using a receiver sketch on the mega it is able to receive the messages from the nano, I have tried and I am unable to find out why I can't get it to work with wireshark, when trying to boot up the nrf24Sniff I get this message.

    "
    Channel: 1
    Datarate: 1Mb/s
    Address: 0xa8a8e1fc**
    Max payload: 32
    CRC length: 2
    Captured 0 packets, Lost 0 packets
    "

    I have tried pressing the reset button but that does not acheive anything, and my Wireshark just looks empty.

    Any ideas?

    I plan on eventually using it to try and sniff out the data from a wireless dmx receiver that uses NRF24l01.

    ReplyDelete
  20. I am getting dissector not found when adding nrf24. The nrf24.dll is in the plugins diretory. Wiresharek 3.2

    ReplyDelete
    Replies
    1. Hello!
      If the problem is still relevant, then I recommend installing the version of the program as the author and everything will work. I did it and it worked for me.

      Delete
  21. This is a definitely awesome project, but I got stuck at "Wait for sniffer to restart". I already tried manually pressing the reset button on Arduino board. Is there anyone can help me?

    ReplyDelete
    Replies
    1. I debugged on visual studio, looks like serial port only receive 2 bytes(stat.cbInQue) after restarting, while lenAndType has size of 1 and config has size of 14.

      Delete
    2. Have same problem, any ideas how to solve it?

      Delete