10 wlan = pyiw.WirelessInterface(iface)
14 from ieee80211 import *
15 from wificards import *
20 logfile = open( "wifilogger.log" , "a" )
24 read_timeout = 100 # in milliseconds
25 pc = pcapy.open_live(iface, max_bytes, promiscuous, read_timeout)
28 fd = open( "discovered.list" )
29 for line in fd.readlines() :
30 items = line[:-1].split()
32 discovered[ mac ] = card( mac )
33 discovered[mac].from_string( items )
34 if discovered[mac].tipo not in ( 'AP' , 'STA' , 'CELL' ) :
35 print "Unknwon type '%s' for %s" % ( discovered[mac].tipo , mac )
39 channel_hop = [ 30.0 , False ]
41 def channel_change ( ) :
43 wlan["channel"] = ( wlan["channel"] ) % 12 + 1
44 except pyiw.error, error:
45 print "PYIW error : %s" % error
48 channel_hop[1] = threading.Timer( channel_hop[0] , channel_change )
49 channel_hop[1].start()
52 def parse_radiotap( radiotap , it_present ) :
55 rfmt , padstr = "<" , ""
56 for name,bit,fmt,pad in ratiotap_header_bits :
57 if it_present & ( 0x1 << bit ) :
59 print "ERROR : unknown bit %s (%d) set" % ( name , bit )
63 fields.append( "CHANNEL_BITMAP" )
67 values = struct.unpack(rfmt+padstr,radiotap)
70 for i in range(len(fields)) :
71 radio_hdr[fields[i]] = values[i]
74 for name,value in radiotap_flags :
75 if radio_hdr['FLAGS'] & value == value :
77 if radio_hdr['FLAGS'] != 16 and radio_hdr['FLAGS'] != 18 :
80 print 'WARNING : Unexpected flags : (%s) %s' % ( radio_hdr['FLAGS'] , " , ".join( flags ) )
81 radio_hdr['_flags'] = flags
84 for name,value in channel_flags :
85 if radio_hdr['CHANNEL_BITMAP'] & value == value :
86 channel.append( name )
87 if radio_hdr['CHANNEL_BITMAP'] != 160 and radio_hdr['CHANNEL_BITMAP'] != 192 :
90 print 'WARNING : Unexpected channel flags : (%s) %s' % ( radio_hdr['CHANNEL_BITMAP'] , " , ".join( channel ) )
91 radio_hdr['_channel_bitmap'] = channel
96 class CaptureEnd ( Exception ) : pass
99 def dealWithPacket ( hdr , data ) :
101 if hdr.getlen() != hdr.getcaplen() :
102 print "ERROR : bad sizes in header : %d vs. %d" % ( hdr.getlen() , hdr.getcaplen() )
104 if len(data) != hdr.getlen() :
105 print "ERROR : Data lenght does not match"
108 it_version , it_len , it_present = struct.unpack("<Bxhl",data[:8])
110 print "ERROR : Bad version (%s), it is probably not radiotap header" % it_version
113 print "ERROR : Bad length on radiotap header"
116 print "ERROR : Strange length on radiotap header"
119 radio_hdr = parse_radiotap( data[8:it_len] , it_present )
124 payload = data[it_len:]
126 pcktlen = len(payload)
128 frame_ctl , frame_ctl2 , duration_id = struct.unpack("BBh",payload[:4])
133 for name,value in frame_types :
134 if frame_ctl & 0x0c == value :
138 print "ERROR : unknown frame type %s" % ( frame_ctl & 0x0c , )
141 if frame_type == "MGT" :
142 for name,value in management_subtypes :
143 if frame_ctl & 0xf0 == value :
147 print "ERROR : unknown MGT subtype %s" % ( frame_ctl & 0xf0 , )
150 elif frame_type == "CTL" :
151 for name,value in control_subtypes :
152 if frame_ctl & 0xf0 == value :
156 if frame_ctl & 0xf0 == 144 :
157 frame_subtype = "CF_END_ACK"
158 elif frame_ctl & 0xf0 == 128 :
159 frame_subtype = "UNKNOWN_1"
161 print "ERROR : unknown CTL subtype %s" % ( frame_ctl & 0xf0 , )
164 elif frame_type == "DATA" :
166 for name,value in data_subtypes :
167 if frame_ctl & 0xf0 == value :
168 _subtype.append( name )
169 frame_subtype = "-".join( _subtype )
172 print "Handling of frame type %s not implemented" % frame_type
176 for name,value in directions : # Only for DATA frames ???
177 if frame_ctl2 & 0x03 == value :
181 print "ERROR : unknown direction %s" % ( frame_ctl2 & 0x03 , )
185 mac_str = "BBBBBB" # is leading '<' required
186 mac_fmt = "%02X:%02X:%02X:%02X:%02X:%02X"
190 maclist.append( mac_fmt % struct.unpack( mac_str , payload[pointer:pointer+6] ) )
197 if frame_type != "CTL" :
198 sequence = struct.unpack("BB",payload[pointer:pointer+2])
202 sequence = ( -1 , -1 )
205 if frame_type == "DATA" and pcktlen > 6 :
206 maclist.append( mac_fmt % struct.unpack( mac_str , payload[pointer:pointer+6] ) )
211 if frame_type == "MGT" : # addresses : dest orig BSSID
212 if len(maclist) != 3 :
213 print "ERROR : insuficientes macs (%d) en un MGT",len(maclist),pcktlen," %s"*len(maclist) % tuple(maclist)
215 if frame_subtype == "BEACON" :
216 if maclist[0] == "FF:FF:FF:FF:FF:FF" :
217 add_full_card ( maclist[1] , 'AP' , frame_subtype , radio_hdr )
218 discovered[ maclist[1] ].add_rssi( radio_hdr )
219 if maclist[1] != maclist[2] :
220 add_full_card ( maclist[2] , 'CELL' , frame_subtype , radio_hdr )
221 if maclist[1] not in discovered[ maclist[2] ].sta :
222 discovered[ maclist[2] ].add_sta( maclist[1] )
224 print "ERROR : non broadcast BEACON : %s %s %s" % tuple(maclist)
225 elif frame_subtype == "PROBE_REQ" : # Pueden ser al broadcast o una "reasociacion ??
226 if maclist[0] == maclist[2] :
227 add_full_card ( maclist[1] , 'STA' , frame_subtype , radio_hdr )
228 discovered[ maclist[1] ].add_rssi( radio_hdr )
229 if maclist[0] != "FF:FF:FF:FF:FF:FF" :
230 add_full_card ( maclist[0] , 'AP' , frame_subtype , radio_hdr )
231 if maclist[1] not in discovered[ maclist[0] ].sta :
232 discovered[ maclist[0] ].add_sta( maclist[1] )
234 print "ERROR : broken PROBE_REQ : %s %s %s" % tuple(maclist)
236 print "WARNING : unhandled MGT subtype %s" % frame_subtype
239 logfile.write( "%4s %13s %6s %4d [ %2d %2d ] read %4d missing %4d" % (frame_type,frame_subtype,direction,radio_hdr['CHANNEL'],radio_hdr['FLAGS'],radio_hdr['CHANNEL_BITMAP'],pointer,pcktlen) )
240 logfile.write( " = %s %s " % ( radio_hdr['DBM_ANTSIGNAL'] , radio_hdr['DBM_ANTNOISE'] ) )
241 logfile.write( " ; %4d %4d " % sequence )
242 logfile.write( " - %4d :" % duration_id )
243 logfile.write( " %s"*len(maclist) % tuple(maclist) )
244 logfile.write( "\n" )
246 curtime = time.time()
247 if curtime - tstamp > max_time :
249 raise CaptureEnd( "Neighborhoud scan completed" )
253 channel_hop[1] = threading.Timer( channel_hop[0] , channel_change )
254 channel_hop[1].start()
257 packet_limit = -1 # infinite
259 pc.loop( packet_limit , dealWithPacket )
260 except CaptureEnd , ex :
261 print "FINISED : %s" % ex
262 except Exception , ex :
264 print "ERROR : %s" % ex
268 fd = open( "discovered.list" , "w" )
269 for mac in discovered.keys() :
270 fd.write( "%s\n" % discovered[mac] )