10 read_timeout = 100 # in milliseconds
11 pc = pcapy.open_live(iface, max_bytes, promiscuous, read_timeout)
13 from ieee80211 import *
21 def parse_radiotap( radiotap , it_present ) :
24 format , padstr = "<" , ""
25 for name,bit,fmt,pad in ratiotap_header_bits :
26 # What about 'it_present & ( 0x1 << bit )' ??
27 if it_present & pow(2,bit) == pow(2,bit) :
29 print "Unknown bit %s (%d) set" % ( name , bit )
33 fields.append( "CHANNEL_BITMAP" )
37 values = struct.unpack(format+padstr,radiotap])
40 for i in range(len(fields)) :
41 radio_hdr[fields[i]] = values[i]
44 for name,value in radiotap_flags :
45 if radio_hdr['FLAGS'] & value == value :
47 radio_hdr['_flags'] = flags
48 if radio_hdr['FLAGS'] != 16 and radio_hdr['FLAGS'] != 18 :
51 print 'WARNING : Unexpected flags : (%s) %s' % ( radio_hdr['FLAGS'] , " , ".join( flags ) )
54 for name,value in channel_flags :
55 if radio_hdr['CHANNEL_BITMAP'] & value == value :
56 channel.append( name )
57 if radio_hdr['CHANNEL_BITMAP'] != 160 and radio_hdr['CHANNEL_BITMAP'] != 192 :
60 print 'WARNING : Unexpected channel flags : (%s) %s' % ( radio_hdr['CHANNEL_BITMAP'] , " , ".join( channel ) )
61 radio_hdr['_channel_bitmap'] = channel
66 def dealWithPacket ( hdr , data ) :
68 if hdr.getlen() != hdr.getcaplen() :
69 print "Error in header : %d vs. %d" % ( hdr.getlen() , hdr.getcaplen() )
71 if len(data) != hdr.getlen() :
72 print "Data lenght does not match"
75 it_version , it_len , it_present = struct.unpack("<Bxhl",data[:8])
77 print "Bad version (%s), it is probably not radiotap header" % it_version
80 print "Bad length on radiotap header"
83 radio_hdr = parse_radiotap( data[8:it_len] , it_present )
87 payload = data[it_len:]
91 pcktlen = len(payload)
93 frame_ctl , frame_subtype , duration_id = struct.unpack("BBh",payload[:4])
97 for name,value in frame_type :
98 if frame_ctl & 0x0c == value :
102 print "Unknown frame type %s" % ( frame_ctl & 0x0c , )
106 for name,value in management_subtypes :
107 if frame_ctl & 0xf0 == value :
111 print "Unknown MGT subtype %s" % ( frame_ctl & 0xf0 , )
115 for name,value in control_subtypes :
116 if frame_ctl & 0xf0 == value :
120 print "Unknown CTL subtype %s" % ( frame_ctl & 0xf0 , )
123 elif type == "DATA" :
125 for name,value in data_subtypes :
126 if frame_ctl & 0xf0 == value :
127 _subtype.append( name )
128 subtype = "-".join( _subtype )
130 for name,value in directions :
131 if frame_subtype & 0x03 == value :
135 print "Unknown direction %s" % ( frame_subtype & 0x03 , )
139 mac_str = "BBBBBB" # is leading '<' required
140 mac_fmt = "%02X:%02X:%02X:%02X:%02X:%02X"
144 maclist.append( mac_fmt % struct.unpack( mac_str , payload[pointer:pointer+6] ) )
147 # FIXME : only CTL/ACK have single address ???
148 # FIXME : Is this the same than pcktlen == 2
152 sequence = struct.unpack("BB",payload[pointer:pointer+2])
158 # print "Radiotap flags : %s" % " ".join(flags)
159 # print "Channel %d (%s)" % ( values[3] , " ".join(channel) )
160 ## print "Control info",frame_ctl,frame_subtype,duration_id,"seq",sequence
161 # print type,":",maclist,"->",pcktlen
164 global tstamp,max_time,discovered
166 if not mac in discovered :
168 discovered.append( mac )
169 if time.time()-tstamp > max_time :
170 fd = open( "discovered.list" , "a" )
171 for mac in discovered :
172 fd.write( "%s\n" % mac )
174 raise Exception( "Neighborhoud scan completed" )
176 print "%4s %13s %6s %4d %4d from %4d" % (type,subtype,direction,values[3],pcktlen,len(payload))," ; %4d %4d "%sequence,":"+" %s"*len(maclist) % tuple(maclist)
178 packet_limit = -1 # infinite
179 pc.loop( packet_limit , dealWithPacket )