#!/usr/bin/env python
#
# Currently a Proof of Concept:  
# Script parses kismet *.xml log files for GPS data and creates a map of access points.
# Output is an HTML file containing multiple <img> tags sourced from maps.google.com.
# Right hand column contains additional information on mapped APs, format:
#  SSID, channel, encryption modes
#
# Requires maps API Key - http://code.google.com/apis/maps/signup.html
#
# N.B. Google maps appears to have limit to the length of URLs it can handle, 
#  for this reason the script splits the data into groups of 50 Access points per map
#
# Unsecured APs are green, WEP secured are yellow, and WPA are red
#
# Andrew Waite - www.infosanity.co.uk
#
# Version: 0.3
# Date: 2009-07-05
#
# Modified original from http://perrygeo.googlecode.com/svn/trunk/gis-bin/kismet2kml.py by PerryGeo
# in turn: modified from http://www.larsen-b.com/Article/204.html by larson-b.com

import sys
try:
    from elementtree import ElementTree
except:
    from xml.etree import ElementTree

#Read Kismet log file (not *.gps)
try:
   file = sys.argv[1]
   data = open(file,'r').read()
except:
   print sys.argv[0] + " {kismet logfile}"
   sys.exit(1)

detection = ElementTree.XML(data)

#Setup google maps URL basics
url  = "http://maps.google.com/staticmap?"
url += "size=512x512"
# Place your API key here (remove chevrons)
url += "&key=<YOUR KEY HERE>"
url += "&markers="

#counter for number of plotted points
markers = 0
markerurl = ''

extrainfo = ''

#Print HTML Header
sys.stdout.write("<html>\n<head>\n<title>Kismet2gmapstatic - InfoSanity.co.uk</title>\n</head>\n")

#Print HTML Body & layout table (I know...)
sys.stdout.write("<body><table>")

for node in detection.getchildren():
   try:
      ssid = node.find('SSID').text
   except AttributeError:
      #hidden SSID
      ssid = "{unknown SSID}"

#   bssid = node.find('BSSID').text
   ssid = ssid.replace('&','')
   channel = node.find('channel').text
#   maxrate = node.find('maxrate').text 

#   encryption = node.find('encryption').text

   extrainfo += ssid + ", " + channel + ", "

   #read all found encryption types used by AP
   encryptiontypes =  node.findall('encryption')

   # Security level
   OPEN = 0
   WEP = 1
   WPA = 2

   #Assume no security
   APenc = 0

   for enctype in encryptiontypes:
      extrainfo += enctype.text + " "
      if enctype.text == "WPA":
         APenc = 2
      elif ( enctype.text == "WEP" and APenc < 2 ):
         APenc = 1
   extrainfo += "\n"
      
   #If Kismet did not recieve enough data on a given AP then max-lon or max-lat may be Null
   gps = node.find('gps-info')
   lon = gps.find('max-lon').text
   if lon == "0.000000":
      lon = gps.find('min-lon').text

   lat = gps.find('max-lat').text
   if lat == "0.000000":
      lat = gps.find('min-lon').text   

   # add pipe (|) seperator if not first marker
   if markers > 0:
      markerurl += "|"

   # add marker
   markerurl += lat + "," + lon

   # change marker colour depending on encryption level
   if APenc == 0:
      markerurl += ",green"
   elif APenc == 1:
      markerurl += ",yellow"
   elif APenc == 2:
      markerurl += ",red"
   else:
      sys.stdout.write("Ooppps, APenc is %s\n" %APenc)
      sys.exit(1)

   markers += 1
   if markers > 50:
      sys.stdout.write("<tr><td><img src=\""+ url + markerurl + "\"></td><td><textarea rows=30 cols=50>" + extrainfo + "</textArea><td></tr>\n")
      markerurl=''
      extrainfo=''
      markers = 0

#print end of .html
sys.stdout.write("\n</table></body>\n</html>")

#sys.stdout.write(url + "\n")
#sys.stdout.write("Number of markers: %i" %(markers))

