<?php
# PHP parser for kismet netxml files
# 
# Author: Patrick Salecker 
# URL: http://www.salecker.org/software/netxml2kml/en

function netxml($fp)
{
	$xml_parser = xml_parser_create();
	global $netxml_aps,$parent,$ap;
	$parent=array();
	$netxml_aps=array();
	xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true);
	xml_set_element_handler($xml_parser, "netxml_startElement", "netxml_endElement");
	xml_set_character_data_handler($xml_parser, "netxml_characterData");
	
	while ($data = fread($fp, 4096)) 
	{
		if (!xml_parse($xml_parser, $data, feof($fp))) 
		{
			die(sprintf("XML error: %s at line %d",
					xml_error_string(xml_get_error_code($xml_parser)),
					xml_get_current_line_number($xml_parser)));
		}
	}
	
	xml_parser_free($xml_parser);
	fclose($fp);

	return $netxml_aps;
}
function netxml_startElement($parser, $name, $attrs) 
{
	#echo "<$name>";
	global $parent,$ap;
	$parent[2]=$parent[1];
	$parent[1]=$parent[0];
	$parent[0]=$name;

	if($name=="WIRELESS-NETWORK" and $attrs['TYPE']=="infrastructure")
	{
		$ap=array();
		$ap['first']= strtotime($attrs['FIRST-TIME']);
		$ap['last']= strtotime($attrs['LAST-TIME']);
		$ap['crypts']=array();
	}
}

function netxml_endElement($parser, $name) 
{
	#echo "</$name>";
	global $parent,$ap,$netxml_aps;
	$parent[0]=$parent[1];
	$parent[1]=$parent[2];
	$parent[2]="";

	if($name=="WIRELESS-NETWORK" and is_array($ap))
	{
		if(count($ap['crypts'])>0)
		{
			if(in_array("WPA",$ap['crypts']))
				$ap['crypt']="WPA";
			elseif(in_array("WEP",$ap['crypts']))
				$ap['crypt']="WEP";
			elseif(in_array("None",$ap['crypts']))
				$ap['crypt']="None";
			# SVN commit 2889 http://kismetwireless.net/blog/index.php?entry=/checkins/1246898501.txt
			foreach($ap['crypts'] as $crypt)
			{
				if(!isset($ap['crypt']))
				{
					if(substr($crypt,0,3)=="WPA")
						$ap['crypt']="WPA";
				}
			}
			if(!isset($ap['crypt']))
			{
				$ap['crypt']="None";
				#pa($ap['crypts']);
			}
		}
		else
			$ap['crypt']="None";
		unset($ap['crypts']);
		$netxml_aps[]=$ap;
		#print_r($ap);
		$ap="";
	}
}

function netxml_characterData($parser, $data) 
{
	//echo $data;
	global $parent,$ap;
	$data=trim($data);
	if($data!="" and !in_array("WIRELESS-CLIENT",$parent) and is_array($ap))
	{
		if($parent[0]=="ESSID")
			$ap['ssid']=$data;
		elseif($parent[0]=="BSSID")
			$ap['mac']=$data;
		elseif($parent[0]=="CHANNEL")
			$ap['channel']=$data;
		elseif($parent[0]=="ENCRYPTION")
			$ap['crypts'][]=$data;
		elseif($parent[1]=="GPS-INFO")
		{
			if($parent[0]=="AVG-LAT")
				$ap['lat']=$data;
			elseif($parent[0]=="AVG-LON")
				$ap['lon']=$data;
		}
		#else
			#echo $parent[2].">\t".$parent[1].">\t".$parent[0]."=".$data."\n";
	}
}

# usage example
# file or url to read
$filename="http://www.salecker.org/files/software/netxml2kml/sample.netxml"; 
# open the file
$f=fopen($filename,"r");
# parse the file
$aps=netxml($f);
# print the accesspoints
print_r($aps);

?>
