Adding log file and generic wifilogger refactoring
authorJavier Palacios <javiplx@gmail.com>
Mon, 23 Jul 2012 08:18:43 +0000 (10:18 +0200)
committerJavier Palacios <javiplx@gmail.com>
Mon, 23 Jul 2012 08:18:43 +0000 (10:18 +0200)
wifisniffer/ieee80211.py
wifisniffer/wifilogger.py

index 0b38558..791de1d 100755 (executable)
@@ -69,7 +69,7 @@ radiotap_tx_flags = (
 
 
 # without IEEE80211_FC0_TYPE_
-frame_type = (
+frame_types = (
 ( "MGT"               , 0x00 ) ,
 ( "CTL"               , 0x04 ) ,
 ( "DATA"              , 0x08 )  
index 7d0bbc6..6163e9d 100755 (executable)
@@ -5,36 +5,37 @@ import struct
 
 iface = 'wlan0'
 
+import time
+
+from ieee80211 import *
+
+max_time = 15 * 60
+tstamp = time.time()
+
+logfile = open( "wifilogger.log" , "a" )
+
 max_bytes = 1024
 promiscuous = False
 read_timeout = 100 # in milliseconds
 pc = pcapy.open_live(iface, max_bytes, promiscuous, read_timeout)
 
-from ieee80211 import *
-
-import time
-
-max_time = 1
-tstamp = time.time()
-discovered = []
 
 def parse_radiotap( radiotap , it_present ) :
 
     fields = []
-    format , padstr = "<" , ""
+    rfmt , padstr = "<" , ""
     for name,bit,fmt,pad in ratiotap_header_bits :
-# What about  'it_present & ( 0x1 << bit )' ??
-        if it_present & pow(2,bit) == pow(2,bit) :
+        if it_present & ( 0x1 << bit ) :
             if not fmt :
-                print "Unknown bit %s (%d) set" % ( name , bit )
+                print "ERROR : unknown bit %s (%d) set" % ( name , bit )
                 return
             fields.append( name )
             if fmt == "hh" :
                 fields.append( "CHANNEL_BITMAP" )
-            format += fmt
+            rfmt += fmt
             if pad :
                 padstr += "x"
-    values = struct.unpack(format+padstr,radiotap])
+    values = struct.unpack(rfmt+padstr,radiotap)
 
     radio_hdr = {}
     for i in range(len(fields)) :
@@ -44,11 +45,11 @@ def parse_radiotap( radiotap , it_present ) :
     for name,value in radiotap_flags :
         if radio_hdr['FLAGS'] & value == value :
             flags.append( name )
-    radio_hdr['_flags'] = flags
     if radio_hdr['FLAGS'] != 16 and radio_hdr['FLAGS'] != 18 :
         # 16 - FCS
         # 18 - SHORTPRE , FCS
         print 'WARNING : Unexpected flags : (%s) %s' % ( radio_hdr['FLAGS'] , " , ".join( flags ) )
+    radio_hdr['_flags'] = flags
 
     channel = []
     for name,value in channel_flags :
@@ -63,76 +64,87 @@ def parse_radiotap( radiotap , it_present ) :
     return radio_hdr
 
 
+class CaptureEnd ( Exception ) : pass
+
+
 def dealWithPacket ( hdr , data ) :
 
     if hdr.getlen() != hdr.getcaplen() :
-        print "Error in header : %d vs. %d" % ( hdr.getlen() , hdr.getcaplen() )
+        print "ERROR : bad sizes in header : %d vs. %d" % ( hdr.getlen() , hdr.getcaplen() )
         return
     if len(data) != hdr.getlen() :
-        print "Data lenght does not match"
+        print "ERROR : Data lenght does not match"
         return
 
     it_version , it_len , it_present = struct.unpack("<Bxhl",data[:8])
     if it_version != 0 :
-        print "Bad version (%s), it is probably not radiotap header" % it_version
+        print "ERROR : Bad version (%s), it is probably not radiotap header" % it_version
         return
     if it_len <= 0 :
-        print "Bad length on radiotap header"
+        print "ERROR : Bad length on radiotap header"
+        return
+    if it_len != 32 :
+        print "ERROR : Strange length on radiotap header"
         return
 
     radio_hdr = parse_radiotap( data[8:it_len] , it_present )
     if not radio_hdr :
         return
 
-    payload = data[it_len:]
 
+    payload = data[it_len:]
 
-    pointer = 0
     pcktlen = len(payload)
 
-    frame_ctl , frame_subtype , duration_id = struct.unpack("BBh",payload[:4])
-    pointer += 4
+    frame_ctl , frame_ctl2 , duration_id = struct.unpack("BBh",payload[:4])
+    pointer  = 4
     pcktlen -= 4
 
-    for name,value in frame_type :
+
+    for name,value in frame_types :
         if frame_ctl & 0x0c == value :
-            type = name
+            frame_type = name
             break
     else :
-        print "Unknown frame type %s" % ( frame_ctl & 0x0c , )
+        print "ERROR : unknown frame type %s" % ( frame_ctl & 0x0c , )
         return
 
-    if type == "MGT" :
+    if frame_type == "MGT" :
         for name,value in management_subtypes :
             if frame_ctl & 0xf0 == value :
-                subtype = name
+                frame_subtype = name
                 break
         else :
-            print "Unknown MGT subtype %s" % ( frame_ctl & 0xf0 , )
+            print "ERROR : unknown MGT subtype %s" % ( frame_ctl & 0xf0 , )
             return
 
-    elif type == "CTL" :
+    elif frame_type == "CTL" :
         for name,value in control_subtypes :
             if frame_ctl & 0xf0 == value :
-                subtype = name
+                frame_subtype = name
                 break
         else :
-            print "Unknown CTL subtype %s" % ( frame_ctl & 0xf0 , )
+            print "ERROR : unknown CTL subtype %s" % ( frame_ctl & 0xf0 , )
             return
 
-    elif type == "DATA" :
+    elif frame_type == "DATA" :
         _subtype = []
         for name,value in data_subtypes :
             if frame_ctl & 0xf0 == value :
                 _subtype.append( name )
-        subtype = "-".join( _subtype )
+        frame_subtype = "-".join( _subtype )
+
+    else :
+        print "Handling of frame type %s not implemented" % frame_type
+        return
 
-    for name,value in directions :
-        if frame_subtype & 0x03 == value :
+
+    for name,value in directions : # Only for DATA frames ???
+        if frame_ctl2 & 0x03 == value :
             direction = name
             break
     else :
-        print "Unknown direction %s" % ( frame_subtype & 0x03 , )
+        print "ERROR : unknown direction %s" % ( frame_ctl2 & 0x03 , )
         return
 
 
@@ -144,37 +156,43 @@ def dealWithPacket ( hdr , data ) :
         maclist.append( mac_fmt % struct.unpack( mac_str , payload[pointer:pointer+6] ) )
         pointer += 6
         pcktlen -= 6
-        # FIXME : only CTL/ACK have single address ???
-        # FIXME : Is this the same than pcktlen == 2
         if pcktlen < 6 :
             break
 
-    sequence = struct.unpack("BB",payload[pointer:pointer+2])
-    pointer += 2
-    pcktlen -= 2
-
-#    print fields
-#    print values
-#    print "Radiotap flags : %s" % " ".join(flags)
-#    print "Channel %d (%s)" % ( values[3] , " ".join(channel) )
-##    print "Control info",frame_ctl,frame_subtype,duration_id,"seq",sequence
-#    print type,":",maclist,"->",pcktlen
-#    print
-
-    global tstamp,max_time,discovered
-    for mac in maclist :
-        if not mac in discovered :
-            tstamp = time.time()
-            discovered.append( mac )
-    if time.time()-tstamp > max_time :
-        fd = open( "discovered.list" , "a" )
-        for mac in discovered :
-            fd.write( "%s\n" % mac )
-        fd.close()
-        raise Exception( "Neighborhoud scan completed" )
-
-    print "%4s %13s %6s %4d %4d from %4d" % (type,subtype,direction,values[3],pcktlen,len(payload))," ; %4d %4d "%sequence,":"+" %s"*len(maclist) % tuple(maclist)
+
+    if frame_type != "CTL" :
+        sequence = struct.unpack("BB",payload[pointer:pointer+2])
+        pointer += 2
+        pcktlen -= 2
+    else :
+        sequence = ( -1 , -1 )
+
+
+    if frame_type == "DATA" :
+        maclist.append( mac_fmt % struct.unpack( mac_str , payload[pointer:pointer+6] ) )
+        pointer += 6
+        pcktlen -= 6
+
+
+    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) )
+    logfile.write( " = %s %s " % ( radio_hdr['DBM_ANTSIGNAL'] , radio_hdr['DBM_ANTNOISE'] ) )
+    logfile.write( " ; %4d %4d " % sequence )
+    logfile.write( " - %4d :" % duration_id )
+    logfile.write( " %s"*len(maclist) % tuple(maclist) )
+    logfile.write( "\n" )
+
+    curtime = time.time()
+    if curtime - tstamp > max_time :
+        raise CaptureEnd( "Neighborhoud scan completed" )
+
 
 packet_limit = -1 # infinite
-pc.loop( packet_limit , dealWithPacket )
+try :
+    pc.loop( packet_limit , dealWithPacket )
+except CaptureEnd , ex :
+    print "FINISED : %s" % ex
+except Exception , ex :
+    print "ERROR : %s" % ex
+
+logfile.close()