Skip to content

Instantly share code, notes, and snippets.

@jof
Created August 30, 2012 22:13
Show Gist options
  • Save jof/3542723 to your computer and use it in GitHub Desktop.
Save jof/3542723 to your computer and use it in GitHub Desktop.
"Loudest APs" Kismet Client
#!/usr/bin/env ruby
load '/Users/jof/src/kismet/ruby/kismet.rb'
require 'time'
require 'rubygems'
require 'pry'
require 'awesome_print'
require 'yaml'
CLEAR_SCREEN = "\e[2J"
aps = {} # 'bssid' => {}
freshness_threshold = 10 # Seconds
bssid_ap_mapping = YAML.load(File.read('bssids_aps.yaml'))
handle_bssid = Proc.new do |bssid,fields|
bssid = fields['bssid']
snr = (fields['noise_dbm'].to_f / fields['signal_dbm'].to_f).to_s[0..5]
type = fields['type']
last_time = Time.at(fields['lasttime'].to_i)
next unless type == '0'
next unless (Time.now - last_time) < freshness_threshold
if aps.include?(bssid)
aps[bssid].merge!(fields)
aps[bssid]['snr'] = snr
aps[bssid]['lasttime'] = last_time
else
aps[bssid] = fields
aps[bssid]['snr'] = snr
aps[bssid]['lasttime'] = last_time
end
end
handle_ssid = Proc.new do |ssid, fields|
bssid = fields['mac']
ssid = fields['ssid']
if aps.include?(bssid)
aps[bssid]['ssid'] = ssid
end
end
k = Kismet.new
k.connect
k.subscribe('bssid', [ 'bssid', 'type', 'lasttime', 'signal_dbm', 'noise_dbm' ], handle_bssid)
k.subscribe('ssid', [ 'mac', 'ssid' ], handle_ssid)
k.run
cache_freshness = Thread.new do
loop do
aps.each do |bssid, fields|
aps.delete(bssid) if Time.now - fields['lastseen'] > freshness_threshold
end
sleep 1
end
end
print_loudest = Thread.new do
loop do
print CLEAR_SCREEN
loudest = aps.to_a.sort_by { |bssid, fields| fields['snr'] }
loudest = loudest[-20, 20]
if loudest and loudest.length > 0
loudest = loudest.select { |bssid, fields| fields['ssid'] }
loudest.each do |bssid, fields|
#puts "SSID: #{fields['ssid']} \t\t SNR: #{fields['snr']} \t\t BSSID: #{fields['bssid']}"
#ap fields
ap_name = bssid_ap_mapping[bssid.downcase] ? bssid_ap_mapping[bssid.downcase] + '(' + bssid + ')' : bssid
puts "SNR: #{fields['snr']} \t ap: #{ap_name}"
end
end
sleep 0.5
end
end
trap ("INT") {
k.kill
Thread.kill(print_loudest)
Thread.kill(cache_freshness)
}
print_loudest.join
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment