Tuesday 20 June 2017

Packet sniffing with KillerBee and a CC2530 / CC2531 Dongle

Previously I have blogged about the TI CC2530 and CC2531 ZigBee USB dongles, and getting packet sniffing working with the CC2530 (which I received from a Chinese vendor when I thought I was getting a CC2531).

Well, today I received a CC2531 dongle (again, from a Chinese supplier because they are a quarter of the price), which turned out to actually be a CC2531 dongle!


So this prompted me to complete some work I started on porting CC2530 support to the KillerBee utilities.  This was quite straight forward, given the reverse engineering of the CC2530/CC2531 packet sniffing protocol that has been done in the open source projects I previously identified, and the experience of the KillerBee drivers that I previously gained when fixing a packet truncation issue in the KillerBee RZUSBstick driver.

The result is a KillerBee driver for the CC2530 and CC2531 dongles that supports packet sniffing (so tools like zbdump and zbwireshark work).  This will be a great help for sniffing ZigBee traffic when one of my CC253x dongles while I'm simultaneously using my RZUSBstick to inject traffic.

This work can be found both in a branch on my KillerBee fork, as well as in a pull request that I've submitted back to the KillerBee project:
So it's up to the KillerBee project admins whether they want to integrate that with the KillerBee main branch.

Admittedly, it would have been easier if I'd simply have bought several RZUSBstick dongles... but that wouldn't have been anything like as interesting!

Thursday 15 June 2017

Packet sniffing with the CC2530 USB Stick

So yesterday I blogged about discovering that what I thought was a CC2531 USB dongle was actually a CC2530 dongle. And today I managed to get packet sniffing working under Linux!

Start Point

I used this CC2531 packet sniffing utility as a starting point:
I have chosen this as it is a very straight-forward python script, so adapting it for use with the CC2530 should be relatively simple, depending on what differences I find from the CC2531.

However, I can't use it as-is, because the idVendor and idProduct identifiers for the CC2530 and CC2531 are different, and (as I quickly found), there have been some changes to PyUSB 1.0 (the python USB support library) between when 'ccsniffer' was originally written (looks like it was written using one of the 1.0.0 alpha versions), and the official 1.0.0 release.  So I forked the github project, and created a branch so that I could work on it:
So I made the modifications for PyUSB and updated the idVendor and idProduct for my CC2530 USB Stick, and ran ccsniffer.

End Point

Running the modified ccsniffer now gives me the following error when the PyUSB 'read()' function is called to read packet data.

ValueError: Invalid endpoint address 0x83

I see that ccsniffer has defined the data endpoint as 0x83, and it seems my CC2530 dongle doesn't have a USB endpoint with that identifier.  I can find out the endpoints supported on my CC2530 dongle with 'lsusb' on Linux:

$ lsusb
Bus 001 Device 002: ID 0e0f:000b VMware, Inc. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 006: ID 11a0:eb20 Chipcon AS 
Bus 002 Device 004: ID 0e0f:0008 VMware, Inc. 
Bus 002 Device 003: ID 0e0f:0002 VMware, Inc. Virtual USB Hub
Bus 002 Device 002: ID 0e0f:0003 VMware, Inc. Virtual Mouse
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

So the CC2530 is on bus 2, device 6 (my Linux system is a virtual machine running under VMware, hence the VMware devices), so lsusb can show me more details of that device:

$ lsusb -v -s 2:6
Bus 002 Device 006: ID 11a0:eb20 Chipcon AS 
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x11a0 Chipcon AS
  idProduct          0xeb20 
  bcdDevice            0.50
  iManufacturer           1 Chipcon AS
  iProduct                2 SmartRF04EB
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x40
      (Missing must-be-set bit!)
      Self Powered
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    255 Vendor Specific Subclass
      bInterfaceProtocol    255 Vendor Specific Protocol
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               5
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               5
Device Status:     0x0000
  (Bus Powered)

This shows that the CC2530 USB Stick is made by Chipcon (a company that was acquired by TI, so that makes sense) and it only has a single input endpoint, with identifier 0x82, supporting bulk data transfer.  So this seems like a good candidate (the only candidate!) for the data endpoint used for  packet sniffing.

Result

Modifying the data endpoint in ccsniffer from 0x83 (for the CC2531) to 0x82 (for the CC2530) was the last change necessary - it seems that the CC2530 and CC2531 firmware is sufficiently similar for the remainder of the USB control commands to work, and ccsniffer (in my github branch above) now works for my CC2530 dongle.

Wednesday 14 June 2017

Which ZigBee sniffer do I have?

Recently I have been working with some ZigBee hardware on a number of projects.  It's useful to be able to sniff ZigBee traffic while developing an application, so two devices are needed: one device on which to develop the application, and one device to sniff ZigBee traffic.

My USB sniffer of choice is the Atmel RZUSBstick, because it has well-documented open source firmware, and I usually use it with the KillerBee tools, using the custom KillerBee firmware.

However, I also have a USB dongle based on a TI chipset, which is compatible with their Packet Sniffer software.  Now, the reason I say "a TI chipset" rather than being more specific is that I had intended to buy a TI CC2531 USB dongle (CC2531EMK) but these are quite expensive in the UK (about £40-£45) so I bought something that was described as a CC2531 USB dongle from a Chinese vendor on eBay (around £10).

When I received it, I ran it with the TI Packet Sniffer, which is only available on Windows.  It worked fine, so I didn't think any more of it.  However, most of my ZigBee work is done on Linux, so I wanted to find and use a packet sniffing utility on Linux that would work with my TI dongle.  I found the following projects that will do ZigBee packet sniffing with a CC2531 dongle:
It turned out that none of these recognised my dongle, and expected different USB idVendor and idProduct than those Linux was reporting for my dongle.  Linux reports the following when I plug my dongle in:

  [ 5301.740468] usb 2-2.2: New USB device found, idVendor=11a0, idProduct=eb20
  [ 5301.740472] usb 2-2.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
  [ 5301.740474] usb 2-2.2: Product: SmartRF04EB
  [ 5301.740475] usb 2-2.2: Manufacturer: Chipcon AS

Whereas the CC2531 and ccsniffer utilities were expecting:

  idVendor=0451, idProduct=16ae

So it looks like I have something different.  Closer inspection of the USB dongle itself shows that it is based on a CC2530 rather than a CC2531:


Unsurprisingly, the SmartRF04EB + CC2530 is supported by the Windows TI Packet Sniffer, but I'm unable to find a Linux packet sniffer that will work with the SmartRF04EB + CC2530.

After some investigation, it seems that the source code for the packet sniffer is not published by TI (see this forum post), and my guess is that the Linux utilities for the CC2531 above are using the results of reverse-engineering the USB protocol by observing the packet sniffer in use under Windows.

It looks like I may have to do this myself for my USB dongle if I want to use it for packet sniffing under Linux.