kismet_to_kml 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/kismet_to_kml +34 -0
- data/lib/kismet_to_kml/consts.rb +13 -0
- data/lib/kismet_to_kml/converter.rb +102 -0
- data/lib/kismet_to_kml/version.rb +3 -0
- data/lib/kismet_to_kml/wifi_network.rb +62 -0
- data/lib/kismet_to_kml.rb +8 -0
- metadata +79 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3f540fcf28b8a98c43eff929f14c25ada6130e9c5c42158df3bb9b47aa0449f6
|
4
|
+
data.tar.gz: ea132196932b1ffc258cd0380e7bcfd6b1f1c8b48a2ff2d50709c8f443951294
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 863e413e9ecf79bad149b50f871caa1acf52d2bd4de270f2328402d807a88daa113e41b6c21a487e280bc9582d9e6325cad805f865ef2f49309c8f7f5efc06eb
|
7
|
+
data.tar.gz: aa64e94b477f0c51a27c457e8b76370324e6a395b04b305cf26a6b206bc0bed91d93083b7cdf5a18767f2f6d71b5d626b2ff8ec28edcce0e0bd63d4c89b857c6
|
data/bin/kismet_to_kml
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "optparse"
|
4
|
+
|
5
|
+
require 'kismet_to_kml'
|
6
|
+
|
7
|
+
|
8
|
+
prog = File.basename(__FILE__)
|
9
|
+
|
10
|
+
options = {}
|
11
|
+
option_parser = OptionParser.new do |opts|
|
12
|
+
opts.banner = "Usage: #{prog} [options]"
|
13
|
+
|
14
|
+
opts.on("-n", "--netxml NETXML", "Netxml file (required)") do |v|
|
15
|
+
options[:netxml] = v
|
16
|
+
end
|
17
|
+
|
18
|
+
opts.on("-g", "--gpsxml GPSXML", "Gpsxml file (required)") do |v| options[:gpsxml] = v
|
19
|
+
end
|
20
|
+
|
21
|
+
opts.on("-o", "--output OUTPUT", "Output kml file (required)") do |v|
|
22
|
+
options[:output] = v
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
option_parser.parse!
|
27
|
+
|
28
|
+
if !(options[:netxml] && options[:gpsxml] && options[:output])
|
29
|
+
puts option_parser.help
|
30
|
+
exit 1
|
31
|
+
end
|
32
|
+
|
33
|
+
KismetToKml.run!(options[:gpsxml], options[:netxml], options[:output])
|
34
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module KismetToKml
|
2
|
+
module Consts
|
3
|
+
BSSID = "BSSID"
|
4
|
+
DATA_TYPE = "data"
|
5
|
+
ESSID = "essid"
|
6
|
+
GPSD_TRACKLOG_BSSID = "GP:SD:TR:AC:KL:OG"
|
7
|
+
NULL_BSSID = "00:00:00:00:00:00"
|
8
|
+
PROBE_RESPONSE = "Probe Response"
|
9
|
+
SSID = "SSID"
|
10
|
+
TYPE_ATTRIBUTE = "type"
|
11
|
+
UNKNOWN_SSID = "Unknown"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
require "optparse"
|
3
|
+
|
4
|
+
require_relative "consts"
|
5
|
+
require_relative "wifi_network"
|
6
|
+
|
7
|
+
module KismetToKml
|
8
|
+
class Converter
|
9
|
+
attr_accessor :gpsxml, :netxml, :wifi_networks, :kml_file
|
10
|
+
|
11
|
+
def initialize(gpsxml_file, netxml_file, output_file)
|
12
|
+
@kml_file = output_file
|
13
|
+
@gpsxml = Nokogiri::XML(File.read(gpsxml_file))
|
14
|
+
@netxml = Nokogiri::XML(File.read(netxml_file))
|
15
|
+
@wifi_networks = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def convert!
|
19
|
+
extract_networks
|
20
|
+
extract_points
|
21
|
+
generate_kml
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def extract_points
|
27
|
+
gps_points = gpsxml.xpath("//gps-point").to_a.each do |point|
|
28
|
+
next if useless_point(point)
|
29
|
+
add_point(point)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def useless_point(point)
|
34
|
+
point.attributes[Consts::BSSID.downcase].value == Consts::GPSD_TRACKLOG_BSSID
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_point(point)
|
38
|
+
wifi_networks[point.attributes[Consts::BSSID.downcase].value]&.add_point(point)
|
39
|
+
end
|
40
|
+
|
41
|
+
def extract_networks
|
42
|
+
netxml.xpath("//wireless-network").to_a.map do |node|
|
43
|
+
next if node_has_useless_bssid(node)
|
44
|
+
next if node_is_data_type(node)
|
45
|
+
next if node_is_probe_response(node)
|
46
|
+
next unless node_has_bssid(node)
|
47
|
+
|
48
|
+
wifi_network = WifiNetwork.new(node)
|
49
|
+
wifi_networks[wifi_network.bssid] = wifi_network
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def node_has_useless_bssid(node)
|
55
|
+
node.children.search(Consts::BSSID).first.text == Consts::NULL_BSSID
|
56
|
+
end
|
57
|
+
|
58
|
+
def node_is_data_type(node)
|
59
|
+
node.attributes[Consts::TYPE_ATTRIBUTE].value == Consts::DATA_TYPE
|
60
|
+
end
|
61
|
+
|
62
|
+
def node_is_probe_response(node)
|
63
|
+
ssid = node
|
64
|
+
.children
|
65
|
+
.search(Consts::SSID)
|
66
|
+
.search(Consts::TYPE_ATTRIBUTE)
|
67
|
+
.first
|
68
|
+
|
69
|
+
ssid && ssid.text == Consts::PROBE_RESPONSE
|
70
|
+
end
|
71
|
+
|
72
|
+
def node_has_bssid(node)
|
73
|
+
node.search(Consts::BSSID).first
|
74
|
+
end
|
75
|
+
|
76
|
+
def generate_kml
|
77
|
+
arbitrary_id = 0
|
78
|
+
builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
|
79
|
+
xml.kml(
|
80
|
+
"xmlns" => "http://www.opengis.net/kml/2.2",
|
81
|
+
"xmlns:gx" =>"http://www.google.com/kml/ext/2.2"
|
82
|
+
) do
|
83
|
+
xml.Document(id: arbitrary_id) do
|
84
|
+
arbitrary_id += 1
|
85
|
+
wifi_networks.values.map do |net|
|
86
|
+
xml.Placemark(id: arbitrary_id) do
|
87
|
+
arbitrary_id += 1
|
88
|
+
xml.name net.kml_name
|
89
|
+
xml.Point(id: arbitrary_id) do
|
90
|
+
arbitrary_id += 1
|
91
|
+
xml.coordinates net.kml_placement
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
File.write(kml_file, builder.to_xml)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require_relative "consts"
|
2
|
+
|
3
|
+
module KismetToKml
|
4
|
+
class WifiNetwork
|
5
|
+
def initialize(network_node)
|
6
|
+
@network_node = network_node
|
7
|
+
@gps_points = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def add_point(gps_point_node)
|
11
|
+
@gps_points << gps_point_node.attributes.values.map do |attr|
|
12
|
+
[
|
13
|
+
attr.name.gsub("-", "_").to_sym,
|
14
|
+
attr.value
|
15
|
+
]
|
16
|
+
end.to_h
|
17
|
+
end
|
18
|
+
|
19
|
+
def bssid
|
20
|
+
@network_node.search(Consts::BSSID).first.text
|
21
|
+
end
|
22
|
+
|
23
|
+
def ssid
|
24
|
+
begin
|
25
|
+
@network_node.search(Consts::SSID).first&.search(Consts::ESSID).first&.text || Consts::UNKNOWN_SSID
|
26
|
+
rescue
|
27
|
+
Consts::UNKNOWN_SSID
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def kml_name
|
32
|
+
"#{ssid} (#{bssid})"
|
33
|
+
end
|
34
|
+
|
35
|
+
def kml_placement
|
36
|
+
total_weight = 0
|
37
|
+
lat_sum = 0
|
38
|
+
lon_sum = 0
|
39
|
+
alt_sum = 0
|
40
|
+
|
41
|
+
@gps_points.each do |point|
|
42
|
+
lat = point[:lat].to_f
|
43
|
+
lon = point[:lon].to_f
|
44
|
+
dbm = point[:signal_dbm].to_i
|
45
|
+
alt = point[:alt].to_f
|
46
|
+
weight = 10 ** ( dbm / 10 )
|
47
|
+
|
48
|
+
lat_sum += lat * weight
|
49
|
+
lon_sum += lon * weight
|
50
|
+
alt_sum += alt
|
51
|
+
|
52
|
+
total_weight += weight
|
53
|
+
end
|
54
|
+
|
55
|
+
center_lat = (lat_sum / total_weight).round(6)
|
56
|
+
center_lon = (lon_sum / total_weight).round(6)
|
57
|
+
avg_alt = (alt_sum / @gps_points.count).round(3)
|
58
|
+
|
59
|
+
[center_lon, center_lat, avg_alt].join(",")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kismet_to_kml
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gabe Koss
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-01-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: nokogiri
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.14.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.14.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: optparse
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.3.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.3.1
|
41
|
+
description: Converter utility to convert Gpsxml and Netxml files produced by kismet
|
42
|
+
to KML
|
43
|
+
email: gabe@vermont.dev
|
44
|
+
executables:
|
45
|
+
- kismet_to_kml
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- bin/kismet_to_kml
|
50
|
+
- lib/kismet_to_kml.rb
|
51
|
+
- lib/kismet_to_kml/consts.rb
|
52
|
+
- lib/kismet_to_kml/converter.rb
|
53
|
+
- lib/kismet_to_kml/version.rb
|
54
|
+
- lib/kismet_to_kml/wifi_network.rb
|
55
|
+
homepage: https://github.com/granolocks/kismet_to_kml
|
56
|
+
licenses:
|
57
|
+
- MIT
|
58
|
+
metadata:
|
59
|
+
source_code_uri: https://github.com/granolocks/kismet_to_kml
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
requirements: []
|
75
|
+
rubygems_version: 3.2.22
|
76
|
+
signing_key:
|
77
|
+
specification_version: 4
|
78
|
+
summary: Convert Kismet GPS data to KML
|
79
|
+
test_files: []
|