Package killerbee :: Package openear :: Module scanner
[hide private]
[frames] | no frames]

Source Code for Module killerbee.openear.scanner

  1  #!/usr/bin/env python 
  2  # ZBScanner 
  3  # rmelgares 2011 
  4  # Promiscious capture on multiple channels at once 
  5   
  6  import gps, time, os, signal, sys, operator, threading 
  7  import string, socket, struct, datetime 
  8   
  9  from killerbee import * 
 10  import Queue 
 11   
 12  # Globals 
 13  session = "" 
 14  active_queues = [] 
 15  arg_verbose = False 
 16  arg_ppi = False 
 17  arg_db = False 
 18  arg_gps = False 
 19  arg_gps_devstring = "" 
 20  latitude = "" 
 21  longitude = "" 
 22  altitude = "" 
 23  last_seen = "" 
 24   
25 -def broadcast_event(data):
26 ''' Send broadcast data to all active threads ''' 27 print "\nShutting down threads." 28 for q in active_queues: 29 q.put(data)
30
31 -class LocationThread(threading.Thread):
32 ''' Thread to update gps location from gpsd '''
33 - def __init__(self):
34 global active_queues 35 threading.Thread.__init__(self) 36 self.mesg = Queue.Queue() 37 active_queues.append(self.mesg)
38
39 - def run(self):
40 global session 41 global active_queues 42 global longitude, latitude, altitude, last_seen 43 message = "" 44 last_seen = datetime.datetime.now() 45 while(1): 46 try: 47 message = self.mesg.get(timeout=.00001) 48 except Queue.Empty: 49 pass 50 if message == "shutdown": 51 break 52 session.poll() 53 t_latitude = session.fix.latitude 54 t_longitude = session.fix.longitude 55 t_altitude = session.fix.altitude 56 if(t_latitude != latitude and t_longitude != longitude and t_altitude != altitude): 57 latitude = t_latitude 58 longitude = t_longitude 59 altitude = t_altitude 60 last_seen = datetime.datetime.now() 61 else: 62 end_time = datetime.datetime.now() 63 elapsed_time = end_time - last_seen 64 print chr(0x1b) + "[2;5fElapsed time since last location change: %s" % str(elapsed_time) 65 print chr(0x1b) + "[3;5fLat: %f, Long: %f, Alt: %f." % (latitude, longitude, altitude) 66 time.sleep(1)
67 68
69 -class CaptureThread(threading.Thread):
70 ''' Thread to capture on a given channel, using a given device, to a given pcap file, exits when it receives a broadcast shutdown message via Queue.Queue'''
71 - def __init__(self, dev, channel, pd):
72 global active_queues 73 threading.Thread.__init__(self) 74 self.mesg = Queue.Queue() 75 active_queues.append(self.mesg) 76 self.channel = channel 77 self.freq = (channel - 10) * 5 + 2400 78 self.dev = dev 79 self.pd = pd 80 self.packetcount = 0
81
82 - def run(self):
83 global active_queues 84 global longitude, latitude, altitude 85 self.kb = KillerBee(device=self.dev) 86 self.kb.set_channel(self.channel) 87 self.kb.sniffer_on() 88 89 # loop capturing packets to dblog and file 90 message = "" 91 while (True): 92 try: 93 message = self.mesg.get(timeout=.00001) 94 except Queue.Empty: 95 pass 96 if message == "shutdown": 97 break 98 packet = self.kb.pnext() 99 if packet != None: 100 self.packetcount+=1 101 if arg_gps: 102 gpsdata = (longitude, latitude, altitude) 103 self.pd.pcap_dump(packet['bytes'], ant_dbm=packet['dbm'], freq_mhz=self.freq, location=map(float, gpsdata)) 104 if arg_db:self.kb.dblog.add_packet(full=packet, location=gpsdata) 105 else: 106 self.pd.pcap_dump(packet['bytes']) 107 if arg_db:self.kb.dblog.add_packet(full=packet) 108 print chr(0x1b) + "[%d;5fChannel %d: %d packets captured." % (self.channel - 6, self.channel, self.packetcount) 109 # trigger threading.Event set to false, so shutdown thread 110 if arg_verbose: 111 print "%s on channel %d shutting down..." % (threading.currentThread().getName(), self.channel) 112 self.kb.sniffer_off() 113 self.kb.close() 114 self.pd.close() 115 print "%d packets captured on channel %d" % (self.packetcount, self.channel)
116
117 -def signal_handler(signal, frame):
118 ''' Signal handler called on keyboard interrupt to exit threads and exit scanner script''' 119 os.system('clear') 120 broadcast_event("shutdown") 121 time.sleep(1) 122 sys.exit(0)
123
124 -def main(args):
125 global arg_verbose 126 global arg_gps, arg_gps_devstring 127 global session 128 global longitude, latitude, altitude 129 # parse command line options 130 while len(args) > 1: 131 op = args.pop(1) 132 if op == '-v': # Verbose mode 133 arg_verbose = True 134 if op == '-g': # GPS device 135 arg_gps_devstring = sys.argv.pop(1) 136 arg_gps = True 137 if op == '-p': # PCAP PPI geolocation support 138 arg_ppi = True 139 if op == '-d': # Database logging 140 arg_db = True 141 142 signal.signal(signal.SIGINT, signal_handler) 143 144 if arg_gps: 145 kbdev_info = kbutils.devlist(gps=arg_gps_devstring) 146 else: 147 kbdev_info = kbutils.devlist() 148 channel = 11 149 print "Found %d devices." % len(kbdev_info) 150 if len(kbdev_info) < 1: 151 exit(1) 152 if arg_gps == True: 153 print "Initializing GPS device %s ... "% (arg_gps_devstring), 154 session = gps.gps() 155 session.poll() 156 session.stream() 157 print "Waiting for fix... ", 158 while(session.fix.mode == 1): 159 session.poll() 160 print "Fix acquired!" 161 t = LocationThread() 162 t.start() 163 time.sleep(2) 164 for i in range(0, len(kbdev_info)): 165 if kbdev_info[i][0] == arg_gps_devstring: 166 print "Skipping device %s" % arg_gps_devstring 167 else: 168 print 'Device at %s: \'%s\'' % (kbdev_info[i][0], kbdev_info[i][1]) 169 if channel <= 26: 170 print '\tAssigning to channel %d.' % channel 171 timeLabel = datetime.datetime.now().strftime('%Y%m%d-%H%M') 172 fname = 'zb_c%s_%s.pcap' % (channel, timeLabel) #fname is -w equiv 173 pcap = PcapDumper(DLT_IEEE802_15_4, fname, ppi=arg_ppi) 174 t = CaptureThread(kbdev_info[i][0], channel, pcap) 175 t.start() 176 channel += 1 177 os.system('clear') 178 print chr(0x1b) + "[1;5fLive Stats:" 179 while True: pass
180