Package killerbee
[hide private]
[frames] | no frames]

Source Code for Package killerbee

  1  import usb 
  2  import time 
  3  import struct 
  4  from pcapdump import * 
  5  from daintree import * 
  6  from dot154decode import * 
  7  from zigbeedecode import * 
  8  from pcapdlt import * 
  9  from kbutils import * 
 10   
 11  # Functions for RZUSBSTICK, not all are implemented in firmware 
 12  # Functions not used are commented out but retained for prosperity 
 13  #RZ_CMD_SIGN_OFF             = 0x00 
 14  #RZ_CMD_SIGN_ON              = 0x01 
 15  #RZ_CMD_GET_PARAMETER        = 0x02 
 16  #RZ_CMD_SET_PARAMETER        = 0x03 
 17  #RZ_CMD_SELF_TEST            = 0x04 
 18  #RZ_CMD_CHECK_STACK_USAGE    = 0x05 
 19  #RZ_CMD_MEMORY_TEST          = 0x06 
 20  RZ_CMD_SET_MODE             = 0x07  #: RZUSB opcode to specify operating mode 
 21  RZ_CMD_SET_CHANNEL          = 0x08  #: RZUSB opcode to specify the channel 
 22  RZ_CMD_OPEN_STREAM          = 0x09  #: RZUSB opcode to open a stream for packet injection 
 23  RZ_CMD_CLOSE_STREAM         = 0x0A  #: RZUSB opcode to close a stream for packet injection 
 24  #RZ_CMD_CHANNEL_SCAN         = 0x0B 
 25  #RZ_CMD_CHANNEL_SCAN_STOP    = 0x0C 
 26  RZ_CMD_INJECT_FRAME         = 0x0D  #: RZUSB opcode to specify a frame to inject 
 27  RZ_CMD_JAMMER_ON            = 0x0E  #: RZUSB opcode to turn the jammer function on 
 28  RZ_CMD_JAMMER_OFF           = 0x0F  #: RZUSB opcode to turn the jammer function off 
 29   
 30  # Operating modes following RZ_CMD_SET_MODE function 
 31  RZ_CMD_MODE_AC              = 0x00  #: RZUSB mode for aircapture (inject + sniff) 
 32  #RZ_CMD_MODE_HAL             = 0x01 
 33  #RZ_CMD_MODE_MAC             = 0x02 
 34  #RZ_CMD_MODE_NWK             = 0x03 
 35  RZ_CMD_MODE_NONE            = 0x04 #: RZUSB no mode specified 
 36   
 37  RZ_RESP_LOCAL_TIMEOUT       = 0x00 #: RZUSB Response: Local Timeout Error 
 38  RZ_RESP_SUCCESS             = 0x80 #: RZUSB Response: Success 
 39  RZ_RESP_SYNTACTICAL_ERROR   = 0x81 #: RZUSB Response: Syntactical Error 
 40  RZ_RESP_SEMANTICAL_ERROR    = 0x82 #: RZUSB Response: Semantical Error 
 41  RZ_RESP_HW_TIMEOUT          = 0x83 #: RZUSB Response: Hardware Timeout 
 42  RZ_RESP_SIGN_ON             = 0x84 #: RZUSB Response: Sign On 
 43  RZ_RESP_GET_PARAMETER       = 0x85 #: RZUSB Response: Get Parameter 
 44  RZ_RESP_TRX_READ_REGISTER   = 0x86 #: RZUSB Response: Transceiver Read Register Error 
 45  RZ_RESP_TRX_READ_FRAME      = 0x87 #: RZUSB Response: Transceiver Read Frame Error 
 46  RZ_RESP_TRX_READ_SRAM       = 0x88 #: RZUSB Response: Transceiver Read SRAM Error 
 47  RZ_RESP_TRX_GET_PIN         = 0x89 #: RZUSB Response: Transceiver Get PIN Error 
 48  RZ_RESP_TRX_BUSY            = 0x8A #: RZUSB Response: Transceiver Busy Error 
 49  RZ_RESP_PRITMITIVE_FAILED   = 0x8B #: RZUSB Response: Primitive Failed Error 
 50  RZ_RESP_PRITMITIVE_UNKNOWN  = 0x8C #: RZUSB Response: Primitive Unknown Error 
 51  RZ_RESP_COMMAND_UNKNOWN     = 0x8D #: RZUSB Response: Command Unknown Error 
 52  RZ_RESP_BUSY_SCANING        = 0x8E #: RZUSB Response: Busy Scanning Error 
 53  RZ_RESP_BUSY_CAPTURING      = 0x8F #: RZUSB Response: Busy Capturing Error 
 54  RZ_RESP_OUT_OF_MEMORY       = 0x90 #: RZUSB Response: Out of Memory Error  
 55  RZ_RESP_BUSY_JAMMING        = 0x91 #: RZUSB Response: Busy Jamming Error 
 56  RZ_RESP_NOT_INITIALIZED     = 0x92 #: RZUSB Response: Not Initialized Error 
 57  RZ_RESP_NOT_IMPLEMENTED     = 0x93 #: RZUSB Response: Opcode Not Implemented Error 
 58  RZ_RESP_PRIMITIVE_FAILED    = 0x94 #: RZUSB Response: Primitive Failed Error 
 59  RZ_RESP_VRT_KERNEL_ERROR    = 0x95 #: RZUSB Response: Could not execute due to vrt_kernel_error 
 60  RZ_RESP_BOOT_PARAM          = 0x96 #: RZUSB Response: Boot Param Error 
 61   
 62  RZ_EVENT_STREAM_AC_DATA          = 0x50 #: RZUSB Event Opcode: AirCapture Data 
 63  #RZ_EVENT_SNIFFER_SCAN_COMPLETE   = 0x51 #: RZUSB Event Opcode: Sniffer Scan Complete 
 64  #RZ_EVENT_SNIFFER_ERROR           = 0x52 #: RZUSB Event Opcode: Sniffer Error 
 65  #RZ_EVENT_NWK_DATA                = 0x53 #: RZUSB Event Opcode: NWK Data 
 66  #RZ_EVENT_NWK_JOIN                = 0x54 #: RZUSB Event Opcode: NWK Join Event 
 67  #RZ_EVENT_NWK_LEAVE               = 0x55 #: RZUSB Event Opcode: NWK Leave Event 
 68   
 69   
 70  RESPONSE_MAP = {RZ_RESP_LOCAL_TIMEOUT: "Local Timeout Error", 
 71                  RZ_RESP_SUCCESS : "Success", 
 72                  RZ_RESP_SYNTACTICAL_ERROR : "Syntactical Error", 
 73                  RZ_RESP_SEMANTICAL_ERROR : "Semantical Error", 
 74                  RZ_RESP_HW_TIMEOUT : "Hardware Timeout", 
 75                  RZ_RESP_SIGN_ON : "Sign On", 
 76                  RZ_RESP_GET_PARAMETER : "Get Parameter", 
 77                  RZ_RESP_TRX_READ_REGISTER : "Transceiver Read Register", 
 78                  RZ_RESP_TRX_READ_FRAME : "Transceiver Read Frame", 
 79                  RZ_RESP_TRX_READ_SRAM : "Transceiver Read SRAM", 
 80                  RZ_RESP_TRX_GET_PIN : "Transceiver Get PIN", 
 81                  RZ_RESP_TRX_BUSY : "Transceiver Busy", 
 82                  RZ_RESP_PRITMITIVE_FAILED : "Primitive Failed", 
 83                  RZ_RESP_PRITMITIVE_UNKNOWN : "Unknown Primitive", 
 84                  RZ_RESP_COMMAND_UNKNOWN : "Unknown Command", 
 85                  RZ_RESP_BUSY_SCANING : "Busy Scanning", 
 86                  RZ_RESP_BUSY_CAPTURING : "Busy Capturing", 
 87                  RZ_RESP_OUT_OF_MEMORY : "Out of Memory", 
 88                  RZ_RESP_BUSY_JAMMING : "Busy Jamming", 
 89                  RZ_RESP_NOT_INITIALIZED : "Not Initialized", 
 90                  RZ_RESP_NOT_IMPLEMENTED : "Not Implemented by USB firmware", 
 91                  RZ_RESP_PRIMITIVE_FAILED : "Primitive Failed", 
 92                  RZ_RESP_VRT_KERNEL_ERROR : "Could not execute due to vrt_kernel_error", 
 93                  RZ_RESP_BOOT_PARAM : "Boot Param Error"} #: Dictionary of RZUSB error to strings 
 94   
 95  RZ_USB_VEND_ID                = 0x03EB #: RZUSB USB VID 
 96  RZ_USB_PROD_ID                = 0x210A #: RZUSB USB PID 
 97  RZ_USB_COMMAND_EP             = 0x02 #: RZUSB USB Command Endpoint Identifier 
 98  RZ_USB_RESPONSE_EP            = 0x84 #: RZUSB USB Response Endpoint Identifier 
 99  RZ_USB_PACKET_EP              = 0x81 #: RZUSB USB Packet Endpoint Identifier 
100   
101  KB_CAPAB_NONE               = 0x00 #: Capabilities Flag: No Capabilities 
102  KB_CAPAB_SNIFF              = 0x01 #: Capabilities Flag: Can Sniff 
103  KB_CAPAB_SETCHAN            = 0x02 #: Capabilities Flag: Can Set the Channel 
104  KB_CAPAB_INJECT             = 0x03 #: Capabilities Flag: Can Inject Frames 
105  KB_CAPAB_PHYJAM             = 0x04 #: Capabilities Flag: Can Jam PHY Layer 
106  KB_CAPAB_SELFACK            = 0x05 #: Capabilities Flag: Can ACK Frames Automatically 
107   
108 -class KillerBee:
109 - def __init__(self, device=None):
110 ''' 111 Instantiates the KillerBee class. 112 113 @type device: String 114 @param device: USB device identifier 115 @return: None 116 @rtype: None 117 ''' 118 # Tracking the command operating mode (None or AirCapture Mode) 119 self.__cmdmode = RZ_CMD_MODE_NONE 120 121 # Tracking if the RZ_CMD_OPEN_STREAM parameter is set for packet reception 122 self.__stream_open = False 123 124 # Capabilities list, initialized to false until otherwise set by 125 # __set_??_capabilities() 126 self._capabilities = { 127 KB_CAPAB_NONE : False, 128 KB_CAPAB_SNIFF : False, 129 KB_CAPAB_SETCHAN : False, 130 KB_CAPAB_INJECT : False, 131 KB_CAPAB_PHYJAM : False, 132 KB_CAPAB_SELFACK: False} 133 134 self.handle = None 135 self.dev = None 136 self.__bus = None 137 138 self.__busses = usb.busses() 139 for bus in self.__busses: 140 if self.__search_bus(bus, device) == True: 141 self.__bus = bus 142 break 143 else: 144 self.dev = None 145 146 if self.dev != None: 147 # Open the device handle 148 self.__handle_open() 149 else: 150 raise Exception('No interface found')
151
152 - def __search_bus(self, bus, device):
153 devices = bus.devices 154 for self.dev in devices: 155 if self.dev.idVendor == RZ_USB_VEND_ID and self.dev.idProduct == RZ_USB_PROD_ID: 156 if device == None or (device == (''.join([bus.dirname, ":", self.dev.filename]))): 157 # Populate the capability information for this device 158 self.__set_rz_capabilities() 159 return True 160 return False
161
162 - def check_capability(self, capab):
163 ''' 164 Uses the specified capability to determine if the opened device 165 is supported. Returns True when supported, else False. 166 167 @rtype: Boolean 168 ''' 169 try: 170 return self._capabilities[capab] 171 except KeyError: 172 return False
173
174 - def get_capabilities(self):
175 ''' 176 Returns a list of capability information for the device. 177 178 @rtype: List 179 @return: Capability information for the opened device. 180 ''' 181 return self._capabilities
182
183 - def __set_rz_capabilities(self):
184 ''' 185 Sets the capability information for RZUSB devices. This should not be 186 called outside of the class. 187 188 @rtype: None 189 @return: None 190 ''' 191 # Examine the product string for this device, setting the capability 192 # information appropriately. 193 prod = self.dev.open().getString(self.dev.iProduct, 50) 194 195 if prod == "RZUSBSTICK": 196 self._capabilities[KB_CAPAB_SNIFF] = True 197 self._capabilities[KB_CAPAB_SETCHAN] = True 198 return 199 elif prod == "KILLERB001": 200 self._capabilities[KB_CAPAB_SNIFF] = True 201 self._capabilities[KB_CAPAB_SETCHAN] = True 202 self._capabilities[KB_CAPAB_INJECT] = True 203 return 204 else: 205 return
206
207 - def __usb_write(self, endpoint, data):
208 ''' 209 Write data to the USB device opened as self.handle. 210 211 @type endpoint: Integer 212 @param endpoint: The USB endpoint to write to 213 @type data: Mixed 214 @param data: The data to send to the USB endpoint 215 ''' 216 try: 217 self.handle.bulkWrite(endpoint, data) 218 # Returns a tuple, first value is an int as the RZ_RESP_* code 219 response = self.handle.bulkRead(RZ_USB_RESPONSE_EP, 1)[0] 220 except usb.USBError, e: 221 if e.args != ('No error',): # http://bugs.debian.org/476796 222 raise e 223 try: 224 if response != RZ_RESP_SUCCESS: 225 raise Exception("Error: %s" % RESPONSE_MAP[response]) 226 except KeyError: 227 raise Exception("Unknown USB write error: 0x%02x" % response)
228
229 - def __usb_read(self, endpoint, timeout=100):
230 ''' 231 Reads data from the USB device on the specified endpoint. 232 233 @type endpoint: Integer 234 @param endpoint: The USB endpoint to read from 235 @type timeout: Integer 236 @param timeout: Timeout in usec for read operation before return 237 @rtype: String 238 @return: Data returned from USB device 239 ''' 240 dataread = [RZ_RESP_LOCAL_TIMEOUT,] 241 dataread = self.handle.bulkRead(endpoint, timeout) 242 243 # First byte of the return data is the success/failure code 244 response = dataread[0] 245 try: 246 if response != RZ_RESP_SUCCESS: 247 raise Exception("Error: %s" % RESPONSE_MAP[response]) 248 except KeyError: 249 raise Exception("Unknown USB read error: 0x%02x" % response)
250 251
252 - def _set_mode(self, mode):
253 ''' 254 Change the operating mode of the USB device to one of the RZ_CMD_MODE_* 255 values. Currently, RZ_CMD_MODE_AC (Air Capture) is the only mode that is 256 used other than RZ_CMD_MODE_NONE. 257 @type mode: Integer 258 @param mode: Operating mode for the USB stick 259 @rtype: None 260 ''' 261 self.__usb_write(RZ_USB_COMMAND_EP, [RZ_CMD_SET_MODE, RZ_CMD_MODE_AC]) 262 self.__cmdmode = mode
263
264 - def _open_stream(self):
265 ''' 266 Opens a data stream for receiving packets. 267 ''' 268 self.__usb_write(RZ_USB_COMMAND_EP, [RZ_CMD_OPEN_STREAM]) 269 self.__stream_open = True
270
271 - def _close_stream(self):
272 ''' 273 Closes a data stream. 274 ''' 275 self.__usb_write(RZ_USB_COMMAND_EP, [RZ_CMD_CLOSE_STREAM]) 276 self.__stream_open = False
277
278 - def sniffer_on(self, channel=None):
279 ''' 280 Turns the sniffer on such that pnext() will start returning observed 281 data. Will set the command mode to Air Capture if it is not already 282 set. 283 @type channel: Integer 284 @param channel: Sets the channel, optional 285 @rtype: None 286 ''' 287 if self.check_capability(KB_CAPAB_SNIFF) != True: 288 raise Exception('Selected hardware does not support sniffing') 289 290 if self.__cmdmode != RZ_CMD_MODE_AC: 291 self._set_mode(RZ_CMD_MODE_AC) 292 293 if channel != None: 294 self.set_channel(channel) 295 296 self._open_stream()
297
298 - def sniffer_off(self):
299 ''' 300 Turns the sniffer off, freeing the hardware for other functions. It is 301 not necessary to call this function before closing the interface with 302 close(). 303 @rtype: None 304 ''' 305 self._close_stream()
306
307 - def jammer_on(self, channel=None):
308 ''' 309 Not yet implemented. Stay tuned. 310 @type channel: Integer 311 @param channel: Sets the channel, optional 312 @rtype: None 313 ''' 314 if self.check_capability(KB_CAPAB_PHYJAM) != True: 315 raise Exception('Selected hardware does not support PHY jamming') 316 317 if self.__cmdmode != RZ_CMD_MODE_AC: 318 self._set_mode(RZ_CMD_MODE_AC) 319 320 if channel != None: 321 self.set_channel(channel) 322 323 self.__usb_write(RZ_USB_COMMAND_EP, [RZ_CMD_JAMMER_ON])
324
325 - def jammer_off(self, channel=None):
326 ''' 327 Not yet implemented. Stay tuned. 328 @return: None 329 @rtype: None 330 ''' 331 self.__usb_write(RZ_USB_COMMAND_EP, [RZ_CMD_JAMMER_OFF])
332
333 - def set_channel(self, channel):
334 ''' 335 Sets the radio interface to the specifid channel. Currently, support is 336 limited to 2.4 GHz channels 11 - 26. 337 @type channel: Integer 338 @param channel: Sets the channel, optional 339 @rtype: None 340 ''' 341 if self.check_capability(KB_CAPAB_SETCHAN) != True: 342 raise Exception('Selected hardware does not support setting the channel') 343 344 if self.__cmdmode != RZ_CMD_MODE_AC: 345 self._set_mode(RZ_CMD_MODE_AC) 346 347 if channel >= 10 or channel <= 26: 348 self.__usb_write(RZ_USB_COMMAND_EP, [RZ_CMD_SET_CHANNEL, channel]) 349 else: 350 raise Exception('Invalid channel')
351
352 - def inject(self, packet, channel=None, count=1, delay=0):
353 ''' 354 Injects the specified packet contents. 355 @type packet: String 356 @param packet: Packet contents to transmit, without FCS. 357 @type channel: Integer 358 @param channel: Sets the channel, optional 359 @type count: Integer 360 @param count: Transmits a specified number of frames, def=1 361 @type delay: Float 362 @param delay: Delay between each frame, def=1 363 @rtype: None 364 ''' 365 if self.check_capability(KB_CAPAB_INJECT) != True: 366 raise Exception('Selected hardware does not support packet injection') 367 368 if self.__cmdmode != RZ_CMD_MODE_AC: 369 self._set_mode(RZ_CMD_MODE_AC) 370 371 if len(packet) < 1: 372 raise Exception('Empty packet') 373 if len(packet) > 125: # 127 - 2 to accommodate FCS 374 raise Exception('Packet too long') 375 376 if channel != None: 377 self.set_channel(channel) 378 379 # Append two bytes to be replaced with FCS by firmware. 380 packet = ''.join([packet, "\x00\x00"]) 381 382 for pnum in range(0, count): 383 # Format for packet is opcode RZ_CMD_INJECT_FRAME, one-byte length, 384 # packet data 385 self.__usb_write(RZ_USB_COMMAND_EP, struct.pack("B", RZ_CMD_INJECT_FRAME) + struct.pack("B", len(packet)) + packet) 386 time.sleep(delay)
387
388 - def pnext(self, timeout=100):
389 ''' 390 Returns packet data as a string, else None. 391 @type timeout: Integer 392 @param timeout: Timeout to wait for packet reception in usec 393 @rtype: List 394 @return: Returns None is timeout expires and no packet received. When a packet is received, a list is returned, in the form [ String: packet contents | Bool: Valid CRC | Int: Unscaled RSSI ] 395 ''' 396 if self.__stream_open == False: 397 # Turn the sniffer on 398 self.sniffer_on() 399 400 # The RZ_USB_PACKET_EP doesn't return error codes like the standard 401 # RZ_USB_RESPONSE_EP does, so we don't use __usb_read() here. 402 pdata = None 403 try: 404 pdata = self.handle.bulkRead(RZ_USB_PACKET_EP, timeout) 405 except usb.USBError, e: 406 if e.args != ('No error',): # http://bugs.debian.org/476796 407 raise e 408 409 # PyUSB returns an empty tuple occasionally, handle as "no data" 410 if pdata == None or pdata == (): 411 return None 412 413 if pdata[0] == RZ_EVENT_STREAM_AC_DATA: 414 rssi = int(pdata[6]) 415 validcrc = True if (pdata[7] == 1) else False 416 frame = pdata[9:] 417 # Convert the tuple response data to a string (by way of a list) 418 framedata = [] 419 for byteval in frame: 420 framedata.append(struct.pack("B", byteval)) 421 return [''.join(framedata), validcrc, rssi] 422 else: 423 return None
424 #raise Exception("Unrecognized AirCapture Data Response: 0x%02x" % pdata[0]) 425 426
427 - def ping(self, da, panid, sa, channel=None):
428 ''' 429 Not yet implemented. 430 @return: None 431 @rtype: None 432 ''' 433 raise Exception('Not yet implemented')
434
435 - def __handle_open(self):
436 ''' 437 Opens the device identified as self.dev, populating self.handle 438 ''' 439 try: 440 config = self.dev.configurations[0] 441 intf = config.interfaces[0] 442 alt = intf[0] 443 self.handle = self.dev.open() 444 self.handle.reset() 445 self.handle.setConfiguration(config) 446 self.handle.claimInterface(alt) 447 self.handle.setAltInterface(alt) 448 except: 449 raise Exception("Unable to open device. Ensure the device is free and plugged-in.")
450
451 - def close(self):
452 ''' 453 Closes the device handle. To be re-used, class should be 454 re-instantiated. 455 @return: None 456 @rtype: None 457 ''' 458 self.handle.releaseInterface()
459
460 - def get_dev_info(self):
461 ''' 462 Returns device information in a list identifying the device identifier, 463 product string and serial number in a list of strings. 464 @rtype: List 465 @return: List of strings identifying device. 466 ''' 467 return [''.join([self.__bus.dirname, ":", self.dev.filename]), self.dev.open().getString(self.dev.iProduct, 50), self.dev.open().getString(self.dev.iSerialNumber, 12)]
468
469 - def dev_list(self):
470 ''' 471 Return device information for all present devices. 472 @rtype: List 473 @return: List of device information present. 474 ''' 475 devlist = [] 476 for bus in self.__busses: 477 devices = bus.devices 478 for dev in devices: 479 if dev.idVendor == RZ_USB_VEND_ID and dev.idProduct == RZ_USB_PROD_ID: 480 481 devlist.append([''.join([bus.dirname + ":" + dev.filename]), dev.open().getString(dev.iProduct, 50), dev.open().getString(dev.iSerialNumber, 12)]) 482 return devlist
483