Skip to content

Commit e15c9d4

Browse files
0 parents  commit e15c9d4

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed

pykismetstats.py

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
#!/usr/bin/env python
2+
'''
3+
pykismetstats parse .netxml file generated by kismet
4+
and write statistics to CSV file.
5+
6+
XML parsing based on pykismetkml
7+
http://code.google.com/p/pykismetkml
8+
9+
Following stats are implemented:
10+
- channel usage ( how many networks works on each channel )
11+
- manufacturer ( how many AP by each vendor )
12+
- encryption ( none/wep/wpa+wpa2, do not distinguish between wpa/wpa2 )
13+
14+
15+
@author: ziherung.pl
16+
'''
17+
import optparse
18+
import xml.dom.minidom
19+
import csv
20+
21+
class OptionParser (optparse.OptionParser):
22+
def check_required (self, opt, stop):
23+
option = self.get_option(opt)
24+
if getattr(self.values, option.dest) is None:
25+
if stop:
26+
return False
27+
else:
28+
self.error("%s option not supplied" % option)
29+
else:
30+
return True
31+
32+
def parse(filename,networks):
33+
34+
document = xml.dom.minidom.parse(filename)
35+
items = document.getElementsByTagName("wireless-network")
36+
37+
for item in items:
38+
network = dict()
39+
# work only on 'infrastructure' networks
40+
if item.getAttribute('type') == 'infrastructure':
41+
42+
# get ssid / cloaked
43+
if ( item.getElementsByTagName('essid').item(0).getAttribute('cloaked') ) == 'false':
44+
network['cloaked'] = 'false'
45+
network['ssid'] = item.getElementsByTagName('essid').item(0).firstChild.data
46+
else:
47+
network['cloaked'] = 'true'
48+
network['ssid'] = ' '
49+
50+
network['manuf'] = item.getElementsByTagName('manuf').item(0).firstChild.data
51+
network['channel'] = item.getElementsByTagName('channel').item(0).firstChild.data
52+
network['encryption'] = item.getElementsByTagName('encryption').item(0).firstChild.data
53+
network['bssid'] = item.getElementsByTagName('BSSID').item(0).firstChild.data
54+
55+
networks.append(network)
56+
57+
def save_output(outputfile,networks,stats):
58+
'''Save parsed data to .csv'''
59+
with open(outputfile,'wb') as csvoutput:
60+
csvwriter = csv.writer(csvoutput,delimiter=';',quotechar='"')
61+
62+
for el in stats:
63+
csvwriter.writerow(el)
64+
65+
csvwriter.writerow(['ssid','cloaked','encryption','manufacturer','channel','bssid'])
66+
for net in networks:
67+
csvwriter.writerow([net['ssid'],net['cloaked'],net['encryption'],net['manuf'],
68+
net['channel'],net['bssid']])
69+
70+
71+
72+
def make_stats(networks,stats):
73+
'''Function get statistics about channel usage, encryption and AP manufacturers'''
74+
75+
channels_desc = range(1,15,1)
76+
channels_amount = [0]*14
77+
78+
manuf = dict()
79+
enc = {'wpa/wpa2':0,'wep':0,'none':0}
80+
81+
for net in networks:
82+
channels_amount[int(net['channel'])-1]+=1
83+
if manuf.has_key(net['manuf']):
84+
manuf[net['manuf']]+=1
85+
else:
86+
manuf[net['manuf']]=1
87+
if net['encryption'].find('WPA') != -1:
88+
enc['wpa/wpa2']+=1
89+
elif net['encryption'].find('WEP') != -1:
90+
enc['wep']+=1
91+
else:
92+
enc['none']+=1
93+
94+
95+
96+
97+
stats.append(['channel usage:'])
98+
stats.append(channels_desc)
99+
stats.append(channels_amount)
100+
101+
stats.append(['----------'])
102+
stats.append(['manufacturer','amount'])
103+
for k,v in manuf.iteritems():
104+
stats.append([k,v])
105+
106+
stats.append(['----------'])
107+
stats.append(['encryption','amount'])
108+
for k,v in enc.iteritems():
109+
stats.append([k,v])
110+
111+
stats.append(['----------'])
112+
113+
114+
115+
116+
117+
if __name__ == '__main__':
118+
usage = "%prog -i <kismet_netxml_file> [ optional -o <csv_output> ]"
119+
parser = OptionParser(usage=usage)
120+
parser.add_option("-i","--input", dest="netxml",help="NetXML input file generated by kismet")
121+
parser.add_option("-o", "--output", dest="csvoutput", help="( Optional ) Path to CSV output file, out.csv if not specified.")
122+
123+
(options, args) = parser.parse_args()
124+
parser.check_required("-i", False)
125+
filename = options.netxml
126+
127+
if parser.check_required("-o", True):
128+
outputfile = options.csvoutput
129+
else:
130+
outputfile = "out.csv"
131+
132+
networks = []
133+
stats = []
134+
135+
parse(filename,networks)
136+
make_stats(networks, stats)
137+
save_output(outputfile,networks,stats)
138+

0 commit comments

Comments
 (0)