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 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,3 @@
1
+ module KismetToKml
2
+ VERSION = "0.0.1"
3
+ 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
@@ -0,0 +1,8 @@
1
+ require_relative "kismet_to_kml/converter"
2
+
3
+ module KismetToKml
4
+ def self.run!(gpsxml, netxml, output_path)
5
+ converter = Converter.new( gpsxml, netxml, output_path)
6
+ converter.convert!
7
+ end
8
+ 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: []