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

Source Code for Package killerbee

  1  import struct 
  2  import glob 
  3  from warnings import warn 
  4   
  5  from pcapdump import * 
  6  from daintree import * 
  7  from pcapdlt import * 
  8   
  9  from kbutils import *      #provides serial, usb, USBVER 
 10  from zigbeedecode import * #would like to import only within killerbee class 
 11  from dot154decode import * #would like to import only within killerbee class 
 12  from config import *       #to get DEV_ENABLE_* variables 
13 14 # Utility Functions 15 -def getKillerBee(channel):
16 ''' 17 Returns an instance of a KillerBee device, setup on the given channel. 18 Error handling for KillerBee creation and setting of the channel is wrapped 19 and will raise an Exception(). 20 @return: A KillerBee instance initialized to the given channel. 21 ''' 22 kb = KillerBee() 23 if kb is None: 24 raise Exception("Failed to create a KillerBee instance.") 25 try: 26 kb.set_channel(channel) 27 except Exception, e: 28 raise Exception('Error: Failed to set channel to %d' % channel, e) 29 return kb
30
31 -def kb_dev_list(vendor=None, product=None):
32 '''Deprecated. Use show_dev or call kbutils.devlist.''' 33 return kbutils.devlist(vendor=None, product=None)
34
35 -def show_dev(vendor=None, product=None, gps=None, include=None):
36 ''' 37 A basic function to output the device listing. 38 Placed here for reuse, as many tool scripts were implementing it. 39 @param gps: Provide device names in this argument (previously known as 40 'gps') which you wish to not be enumerated. Aka, exclude these items. 41 @param include: Provide device names in this argument if you would like only 42 these to be enumerated. Aka, include only these items. 43 ''' 44 print("{: >14} {: <20} {: >10}".format("Dev", "Product String", "Serial Number")) 45 for dev in kbutils.devlist(vendor=vendor, product=product, gps=gps, include=include): 46 print("{0: >14} {1: <20} {2: >10}".format(dev[0], dev[1], dev[2]))
47
48 # KillerBee Class 49 -class KillerBee:
50 - def __init__(self, device=None, datasource=None, gps=None):
51 ''' 52 Instantiates the KillerBee class. 53 54 @type device: String 55 @param device: Device identifier, either USB vendor:product, serial device node, or IP address 56 @type datasource: String 57 @param datasource: A known datasource type that is used 58 by dblog to record how the data was captured. 59 @type gps: String 60 @param gps: Optional serial device identifier for an attached GPS 61 unit. If provided, or if global variable has previously been set, 62 KillerBee skips that device in initalization process. 63 @return: None 64 @rtype: None 65 ''' 66 67 global gps_devstring 68 if gps_devstring is None and gps is not None: 69 gps_devstring = gps 70 71 self.dev = None 72 self.__bus = None 73 self.driver = None 74 75 # IP devices may be the most straightforward, and we aren't doing 76 # discovery, just connecting to defined addresses, so we'll check 77 # first to see if we have an IP address given as our device parameter. 78 if (device is not None) and kbutils.isIpAddr(device): 79 from dev_wislab import isWislab 80 if isWislab(device): 81 from dev_wislab import WISLAB 82 self.driver = WISLAB(dev=device) #give it the ip address 83 else: del isWislab 84 85 # Figure out a device is one is not set, trying USB devices next 86 if self.driver is None: 87 if device is None: 88 result = kbutils.search_usb(None) 89 if result != None: 90 if USBVER == 0: 91 (self.__bus, self.dev) = result 92 elif USBVER == 1: 93 #TODO remove self.__bus attribute, not needed in 1.x as all info in self.dev 94 self.dev = result 95 # Recognize if device is provided in the USB format (like a 012:456 string): 96 elif ":" in device: 97 result = kbutils.search_usb(device) 98 if result == None: 99 raise KBInterfaceError("Did not find a USB device matching %s." % device) 100 else: 101 if USBVER == 0: 102 (self.__bus, self.dev) = result 103 elif USBVER == 1: 104 #TODO remove self.__bus attribute, not needed in 1.x as all info in self.dev 105 self.dev = result 106 107 if self.dev is not None: 108 if self.__device_is(RZ_USB_VEND_ID, RZ_USB_PROD_ID): 109 from dev_rzusbstick import RZUSBSTICK 110 self.driver = RZUSBSTICK(self.dev, self.__bus) 111 elif self.__device_is(ZN_USB_VEND_ID, ZN_USB_PROD_ID): 112 raise KBInterfaceError("Zena firmware not yet implemented.") 113 else: 114 raise KBInterfaceError("KillerBee doesn't know how to interact with USB device vendor=%04x, product=%04x.".format(self.dev.idVendor, self.dev.idProduct)) 115 116 # Figure out a device from serial if one is not set 117 #TODO be able to try more than one serial device here (merge with devlist code somehow) 118 # if device == None: 119 # seriallist = get_serial_ports() 120 # if len(seriallist) > 0: 121 # device = seriallist[0] 122 123 # If a USB device driver was not loaded, now we try serial devices 124 if self.driver is None: 125 # If no device was specified 126 if device is None: 127 glob_list = get_serial_ports() 128 if len(glob_list) > 0: 129 #TODO be able to check other devices if this one is not correct 130 device = glob_list[0] 131 # Recognize if device specified by serial string: 132 if (device is not None) and kbutils.isSerialDeviceString(device): 133 self.dev = device 134 if (self.dev == gps_devstring): 135 pass 136 elif (DEV_ENABLE_ZIGDUINO and kbutils.iszigduino(self.dev)): 137 from dev_zigduino import ZIGDUINO 138 self.driver = ZIGDUINO(self.dev) 139 elif (DEV_ENABLE_FREAKDUINO and kbutils.isfreakduino(self.dev)): 140 from dev_freakduino import FREAKDUINO 141 self.driver = FREAKDUINO(self.dev) 142 else: 143 gfccspi,subtype = isgoodfetccspi(self.dev) 144 if gfccspi and subtype == 0: 145 from dev_telosb import TELOSB 146 self.driver = TELOSB(self.dev) 147 elif gfccspi and subtype == 1: 148 from dev_apimote import APIMOTE 149 self.driver = APIMOTE(self.dev, revision=1) 150 elif gfccspi and subtype == 2: 151 from dev_apimote import APIMOTE 152 self.driver = APIMOTE(self.dev, revision=2) 153 else: 154 raise KBInterfaceError("KillerBee doesn't know how to interact with serial device at '%s'." % self.dev) 155 # Otherwise unrecognized device string type was provided: 156 else: 157 raise KBInterfaceError("KillerBee doesn't understand device given by '%s'." % device) 158 159 # Start a connection to the remote packet logging server, if able: 160 if datasource is not None: 161 try: 162 import dblog 163 self.dblog = dblog.DBLogger(datasource) 164 except Exception as e: 165 warn("Error initializing DBLogger (%s)." % e) 166 datasource = None #give up nicely if error connecting, etc.
167
168 - def __device_is(self, vendorId, productId):
169 ''' 170 Compares KillerBee class' device data to a known USB vendorId and productId 171 @type vendorId: 172 @type productId: 173 @rtype: Boolean 174 @return: True if KillerBee class has device matching the vendor and product IDs provided. 175 ''' 176 if self.dev.idVendor == vendorId and self.dev.idProduct == productId: return True 177 else: return False
178 179 #Deprecated in class
180 - def __search_usb(self, device, vendor=None, product=None):
181 ''' 182 Deprecated in class, use kbutils.search_usb(device, vendor, product) instead of class version. 183 ''' 184 raise DeprecationWarning("Use kbutils.search_usb(device, vendor, product) instead of class version.")
185 #return kbutils.search_usb(device, vendor, product) 186 187 #Deprecated in class
188 - def __search_usb_bus(self, bus, device, vendor=None, product=None):
189 ''' 190 Deprecated in class, use kbutils.search_usb_bus(bus, device, vendor, product) instead of class version. 191 ''' 192 raise DeprecationWarning("Use kbutils.search_usb_bus(bus, device, vendor, product) instead of class version.")
193 #return kbutils.search_usb_bus(bus, device, vendor, product) 194 195 #Deprecated in class
196 - def dev_list(self, vendor=None, product=None):
197 ''' 198 Deprecated in class, use kbutils.devlist() instead. 199 ''' 200 raise DeprecationWarning("Use kbutils.devlist(vendor, product) instead of class version.")
201 #return kb_dev_list(vendor, product) 202
203 - def get_dev_info(self):
204 ''' 205 Returns device information in a list identifying the device. Implemented by the loaded driver. 206 @rtype: List 207 @return: List of 3 strings identifying device. 208 ''' 209 return self.driver.get_dev_info()
210
211 - def close(self):
212 ''' 213 Closes the device out. 214 @return: None 215 @rtype: None 216 ''' 217 if self.driver != None: self.driver.close() 218 if hasattr(self, "dblog") and (self.dblog is not None): 219 self.dblog.close()
220
221 - def check_capability(self, capab):
222 ''' 223 Uses the specified capability to determine if the opened device 224 is supported. Returns True when supported, else False. 225 @rtype: Boolean 226 ''' 227 return self.driver.capabilities.check(capab)
228
229 - def get_capabilities(self):
230 ''' 231 Returns a list of capability information for the device. 232 @rtype: List 233 @return: Capability information for the opened device. 234 ''' 235 return self.driver.capabilities.getlist()
236
237 - def sniffer_on(self, channel=None):
238 ''' 239 Turns the sniffer on such that pnext() will start returning observed 240 data. Will set the command mode to Air Capture if it is not already 241 set. 242 @type channel: Integer 243 @param channel: Sets the channel, optional 244 @rtype: None 245 ''' 246 return self.driver.sniffer_on(channel)
247
248 - def sniffer_off(self):
249 ''' 250 Turns the sniffer off, freeing the hardware for other functions. It is 251 not necessary to call this function before closing the interface with 252 close(). 253 @rtype: None 254 ''' 255 return self.driver.sniffer_off()
256 257 @property
258 - def channel(self):
259 """Getter function for the channel that was last set on the device.""" 260 # Driver must have this variable name set in it's set_channel function 261 return self.driver._channel
262
263 - def set_channel(self, channel):
264 ''' 265 Sets the radio interface to the specifid channel. Currently, support is 266 limited to 2.4 GHz channels 11 - 26. 267 @type channel: Integer 268 @param channel: Sets the channel, optional 269 @rtype: None 270 ''' 271 if hasattr(self, "dblog"): 272 self.dblog.set_channel(channel) 273 self.driver.set_channel(channel)
274
275 - def is_valid_channel(self, channel):
276 ''' 277 Based on sniffer capabilities, return if this is an OK channel number. 278 @rtype: Boolean 279 ''' 280 return self.driver.capabilities.is_valid_channel(channel)
281
282 - def inject(self, packet, channel=None, count=1, delay=0):
283 ''' 284 Injects the specified packet contents. 285 @type packet: String 286 @param packet: Packet contents to transmit, without FCS. 287 @type channel: Integer 288 @param channel: Sets the channel, optional 289 @type count: Integer 290 @param count: Transmits a specified number of frames, def=1 291 @type delay: Float 292 @param delay: Delay between each frame, def=1 293 @rtype: None 294 ''' 295 return self.driver.inject(packet, channel, count, delay)
296
297 - def pnext(self, timeout=100):
298 ''' 299 Returns packet data as a string, else None. 300 @type timeout: Integer 301 @param timeout: Timeout to wait for packet reception in usec 302 @rtype: List 303 @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 ] 304 ''' 305 return self.driver.pnext(timeout)
306
307 - def jammer_on(self, channel=None):
308 ''' 309 Attempts reflexive jamming on all 802.15.4 frames. 310 Targeted frames must be >12 bytes for reliable jamming in current firmware. 311 @type channel: Integer 312 @param channel: Sets the channel, optional. 313 @rtype: None 314 ''' 315 return self.driver.jammer_on(channel=channel)
316