patronus_fati 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.rspec +2 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +165 -0
  7. data/README.md +29 -0
  8. data/Rakefile +21 -0
  9. data/bin/patronus_fati +54 -0
  10. data/kismet_configs/pat_fat_startup.sh +3 -0
  11. data/kismet_configs/patronus_fati_kismet.conf +88 -0
  12. data/lib/patronus_fati/cap_struct.rb +97 -0
  13. data/lib/patronus_fati/connection.rb +85 -0
  14. data/lib/patronus_fati/consts.rb +85 -0
  15. data/lib/patronus_fati/data_mapper/crypt_flags.rb +83 -0
  16. data/lib/patronus_fati/data_mapper/null_table_prefix.rb +7 -0
  17. data/lib/patronus_fati/data_models/access_point.rb +74 -0
  18. data/lib/patronus_fati/data_models/alert.rb +24 -0
  19. data/lib/patronus_fati/data_models/ap_frequency.rb +14 -0
  20. data/lib/patronus_fati/data_models/ap_signal.rb +12 -0
  21. data/lib/patronus_fati/data_models/client.rb +69 -0
  22. data/lib/patronus_fati/data_models/client_frequency.rb +14 -0
  23. data/lib/patronus_fati/data_models/client_signal.rb +12 -0
  24. data/lib/patronus_fati/data_models/common.rb +49 -0
  25. data/lib/patronus_fati/data_models/connection.rb +48 -0
  26. data/lib/patronus_fati/data_models/mac.rb +48 -0
  27. data/lib/patronus_fati/data_models/probe.rb +13 -0
  28. data/lib/patronus_fati/data_models/ssid.rb +35 -0
  29. data/lib/patronus_fati/data_observers/access_point_observer.rb +53 -0
  30. data/lib/patronus_fati/data_observers/alert_observer.rb +12 -0
  31. data/lib/patronus_fati/data_observers/client_observer.rb +52 -0
  32. data/lib/patronus_fati/data_observers/connection_observer.rb +66 -0
  33. data/lib/patronus_fati/data_observers/probe_observer.rb +11 -0
  34. data/lib/patronus_fati/data_observers/ssid_observer.rb +53 -0
  35. data/lib/patronus_fati/event_handler.rb +27 -0
  36. data/lib/patronus_fati/factory_base.rb +56 -0
  37. data/lib/patronus_fati/message_models/ack.rb +5 -0
  38. data/lib/patronus_fati/message_models/alert.rb +10 -0
  39. data/lib/patronus_fati/message_models/battery.rb +6 -0
  40. data/lib/patronus_fati/message_models/bssid.rb +43 -0
  41. data/lib/patronus_fati/message_models/bssidsrc.rb +15 -0
  42. data/lib/patronus_fati/message_models/btscandev.rb +11 -0
  43. data/lib/patronus_fati/message_models/capability.rb +5 -0
  44. data/lib/patronus_fati/message_models/channel.rb +13 -0
  45. data/lib/patronus_fati/message_models/client.rb +45 -0
  46. data/lib/patronus_fati/message_models/clisrc.rb +17 -0
  47. data/lib/patronus_fati/message_models/clitag.rb +6 -0
  48. data/lib/patronus_fati/message_models/common.rb +15 -0
  49. data/lib/patronus_fati/message_models/critfail.rb +5 -0
  50. data/lib/patronus_fati/message_models/error.rb +6 -0
  51. data/lib/patronus_fati/message_models/gps.rb +6 -0
  52. data/lib/patronus_fati/message_models/info.rb +11 -0
  53. data/lib/patronus_fati/message_models/kismet.rb +8 -0
  54. data/lib/patronus_fati/message_models/nettag.rb +6 -0
  55. data/lib/patronus_fati/message_models/packet.rb +10 -0
  56. data/lib/patronus_fati/message_models/plugin.rb +8 -0
  57. data/lib/patronus_fati/message_models/protocols.rb +5 -0
  58. data/lib/patronus_fati/message_models/remove.rb +6 -0
  59. data/lib/patronus_fati/message_models/source.rb +10 -0
  60. data/lib/patronus_fati/message_models/spectrum.rb +8 -0
  61. data/lib/patronus_fati/message_models/ssid.rb +25 -0
  62. data/lib/patronus_fati/message_models/status.rb +5 -0
  63. data/lib/patronus_fati/message_models/string.rb +6 -0
  64. data/lib/patronus_fati/message_models/terminate.rb +5 -0
  65. data/lib/patronus_fati/message_models/time.rb +6 -0
  66. data/lib/patronus_fati/message_models/trackinfo.rb +8 -0
  67. data/lib/patronus_fati/message_models/wepkey.rb +6 -0
  68. data/lib/patronus_fati/message_models.rb +39 -0
  69. data/lib/patronus_fati/message_parser.rb +44 -0
  70. data/lib/patronus_fati/message_processor/alert.rb +15 -0
  71. data/lib/patronus_fati/message_processor/bssid.rb +47 -0
  72. data/lib/patronus_fati/message_processor/capability.rb +24 -0
  73. data/lib/patronus_fati/message_processor/client.rb +55 -0
  74. data/lib/patronus_fati/message_processor/critfail.rb +8 -0
  75. data/lib/patronus_fati/message_processor/error.rb +7 -0
  76. data/lib/patronus_fati/message_processor/protocols.rb +7 -0
  77. data/lib/patronus_fati/message_processor/ssid.rb +48 -0
  78. data/lib/patronus_fati/message_processor.rb +52 -0
  79. data/lib/patronus_fati/version.rb +3 -0
  80. data/lib/patronus_fati.rb +68 -0
  81. data/patronus_fati.gemspec +41 -0
  82. data/spec/data_models/access_point_spec.rb +26 -0
  83. data/spec/data_models/alert_spec.rb +12 -0
  84. data/spec/data_models/client_spec.rb +25 -0
  85. data/spec/data_models/connection_spec.rb +86 -0
  86. data/spec/data_models/mac_spec.rb +26 -0
  87. data/spec/patronus_fati_spec.rb +13 -0
  88. data/spec/spec_helper.rb +71 -0
  89. data/wrapper.rb +19 -0
  90. metadata +393 -0
@@ -0,0 +1,66 @@
1
+ module PatronusFati::DataObservers
2
+ class ConnectionObserver
3
+ include DataMapper::Observer
4
+
5
+ observe PatronusFati::DataModels::Connection
6
+
7
+ before :save do
8
+ next unless self.valid?
9
+ @change_type = self.new? ? :new : :changed
10
+
11
+ if @change_type == :changed
12
+ dirty = self.dirty_attributes.map { |a| a.first.name }.map(&:to_s)
13
+ dirty.delete('last_seen_at')
14
+
15
+ # If there weren't any meaningful changes, don't print out anything
16
+ # after we save.
17
+ if dirty.empty?
18
+ @change_type = nil
19
+ next
20
+ end
21
+
22
+ changes = dirty.map do |attr|
23
+ clean = original_attributes[PatronusFati::DataModels::Connection.properties[attr]]
24
+ dirty = dirty_attributes[PatronusFati::DataModels::Connection.properties[attr]]
25
+
26
+ [attr, [clean, dirty]]
27
+ end
28
+
29
+ @change_list = Hash[changes]
30
+ end
31
+ end
32
+
33
+ after :save do
34
+ next unless @change_type
35
+
36
+ client.mac.update_cached_counts!
37
+ access_point.mac.update_cached_counts!
38
+
39
+ if @change_type == :new
40
+ if disconnected_at.nil?
41
+ PatronusFati.event_handler.event(
42
+ :connection,
43
+ :connect,
44
+ self.full_state
45
+ )
46
+ else
47
+ # Weird situation, new record that is already disconnected...
48
+ warn('Connection (%i) created that is already disconnected' % id)
49
+ end
50
+ else
51
+ if @change_list.keys.include?('disconnected_at') && @change_list['disconnected_at'][0] == nil && !disconnected_at.nil?
52
+ PatronusFati.event_handler.event(
53
+ :connection,
54
+ :disconnect,
55
+ self.full_state.merge(duration: duration)
56
+ )
57
+ else
58
+ warn('Connection (%i) updated in a weird way: %s' % [id, @change_list.inspect])
59
+ end
60
+ end
61
+
62
+ @change_type = nil
63
+ @change_list = nil
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,11 @@
1
+ module PatronusFati::DataObservers
2
+ class ProbeObserver
3
+ include DataMapper::Observer
4
+
5
+ observe PatronusFati::DataModels::Probe
6
+
7
+ after :save do
8
+ PatronusFati.event_handler.event(:client, :changed, self.client.full_state)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,53 @@
1
+ module PatronusFati::DataObservers
2
+ class SsidObserver
3
+ include DataMapper::Observer
4
+
5
+ observe PatronusFati::DataModels::Ssid
6
+
7
+ before :save do
8
+ next unless self.valid?
9
+
10
+ # We're about to report this, make sure the attribute gets saved
11
+ old_ro_val = reported_online
12
+ self.reported_online = true
13
+
14
+ @change_list = {
15
+ ssids: [
16
+ [],
17
+ [full_state]
18
+ ]
19
+ }
20
+
21
+ unless self.new?
22
+ dirty = self.dirty_attributes.map { |a| a.first.name }.map(&:to_s)
23
+ dirty.delete('last_seen_at')
24
+
25
+ # If there weren't any meaningful changes, don't print out anything
26
+ # after we save.
27
+ if dirty.empty?
28
+ @change_list = nil
29
+ self.reported_online = old_ro_val
30
+ next
31
+ end
32
+
33
+ tmp_obj = Hash[original_attributes.map { |k,v| [k.name, v] }]
34
+ @change_list[:ssids][0] = PatronusFati::DataModels::Ssid.new(tmp_obj).full_state
35
+ end
36
+ end
37
+
38
+ after :save do
39
+ next unless @change_list
40
+
41
+ access_point.mac.update_cached_counts!
42
+
43
+ PatronusFati.event_handler.event(
44
+ :access_point,
45
+ :changed,
46
+ self.access_point.full_state,
47
+ @change_list
48
+ )
49
+
50
+ @change_list = nil
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,27 @@
1
+ module PatronusFati
2
+ class EventHandler
3
+ def handlers
4
+ @handlers ||= {}
5
+ end
6
+
7
+ def handlers_for(asset_type, event_type)
8
+ handlers[asset_type] ||= (asset_type == :any ? [] : {})
9
+ Array(handlers[:any]) | Array(handlers[asset_type][:any]) | Array(handlers[asset_type][event_type])
10
+ end
11
+
12
+ def on(asset_type, event_type = :any, &handler)
13
+ if asset_type == :any
14
+ handlers[:any] ||= []
15
+ handlers[:any].push(handler)
16
+ else
17
+ handlers[asset_type] ||= {}
18
+ handlers[asset_type][event_type] ||= []
19
+ handlers[asset_type][event_type].push(handler)
20
+ end
21
+ end
22
+
23
+ def event(asset_type, event_type, msg, optional = {})
24
+ handlers_for(asset_type, event_type).each { |h| h.call(asset_type, event_type, msg, optional) }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,56 @@
1
+ module PatronusFati
2
+ # This module provides the basis for an automatic Factory registration and
3
+ # generation system. Other modules that wish to make use of this
4
+ # functionality should extend this module. Those modules should then in turn
5
+ # be included by their respective generators.
6
+ module FactoryBase
7
+ # Turns the name of a class into it's snake cased equivalent.
8
+ #
9
+ # @param [Object] klass
10
+ # @return [Symbol]
11
+ def class_to_name(klass)
12
+ klass.to_s.split('::').last.scan(/[A-Z][a-z]*/).map(&:downcase)
13
+ .join('_').to_sym
14
+ end
15
+
16
+ # Factory method for triggering the lookup and return of the specific
17
+ # requested type of factory.
18
+ #
19
+ # @param [Symbol] type Type of generator to create
20
+ # @param [Hash<Symbol=>String>] options
21
+ def factory(type, opts = {})
22
+ return if ignored_types.include?(type)
23
+ if registered_factories[type].nil?
24
+ warn("Unknown factory #{type} (Available: #{registered_factories.keys})")
25
+ #puts opts.inspect
26
+ return
27
+ end
28
+ registered_factories[type].process(opts)
29
+ end
30
+
31
+ # Placeholder mechanism to allow sub-generators to not generate any
32
+ # warnings for specific types.
33
+ #
34
+ # @return [Array<Symbol>]
35
+ def ignored_types
36
+ []
37
+ end
38
+
39
+ # Trigger for when this module gets included to register it with the
40
+ # factory.
41
+ #
42
+ # @param [Object#create] klass
43
+ # @return [Object]
44
+ def included(klass)
45
+ registered_factories[class_to_name(klass)] = klass
46
+ end
47
+
48
+ # Returns the hash containing the set of registered factories or
49
+ # initializes it if one doesn't exist.
50
+ #
51
+ # @return [Hash<Symbol=>Object>]
52
+ def registered_factories
53
+ @registered_factories ||= {}
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,5 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Ack = CapStruct.new(:cmdid, :text)
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Alert = CapStruct.new(
4
+ :sec, :usec, :header, :bssid, :source, :dest, :other, :channel, :text
5
+ )
6
+
7
+ Alert.set_data_filter(:bssid, :source, :dest, :other) { |val| val.downcase }
8
+ Alert.set_data_filter(:sec, :usec, :channel) { |val| val.to_i }
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Battery = CapStruct.new(:percentage, :charging, :ac, :remaining)
4
+ Battery.set_data_filter(:percentage, :charging, :ac, :remaining) { |val| val.to_i }
5
+ end
6
+ end
@@ -0,0 +1,43 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Bssid = CapStruct.new(
4
+ :bssid, :type, :llcpackets, :datapackets, :cryptpackets, :manuf, :channel,
5
+ :firsttime, :lasttime, :atype, :rangeip, :netmaskip, :gatewayip, :gpsfixed,
6
+ :minlat, :minlon, :minalt, :minspd, :maxlat, :maxlon, :maxalt, :maxspd,
7
+ :signal_dbm, :noise_dbm, :minsignal_dbm, :minnoise_dbm, :maxsignal_dbm,
8
+ :maxnoise_dbm, :signal_rssi, :noise_rssi, :minsignal_rssi, :minnoise_rssi,
9
+ :maxsignal_rssi, :maxnoise_rssi, :bestlat, :bestlon, :bestalt, :agglat,
10
+ :agglon, :aggalt, :aggpoints, :datasize, :turbocellnid, :turbocellmode,
11
+ :turbocellsat, :carrierset, :maxseenrate, :encodingset, :decrypted,
12
+ :dupeivpackets, :bsstimestamp, :cdpdevice, :cdpport, :fragments, :retries,
13
+ :newpackets, :freqmhz, :datacryptset
14
+ )
15
+ Bssid.set_data_filter(:bssid) { |val| val.downcase }
16
+ Bssid.set_data_filter(:llcpackets, :datapackets, :cryptpackets,
17
+ :firsttime, :lasttime, :atype, :gpsfixed, :minlat,
18
+ :minlon, :minalt, :minspd, :maxlat, :maxlon, :maxalt,
19
+ :maxspd, :signal_dbm, :noise_dbm, :minsignal_dbm,
20
+ :minnoise_dbm, :maxsignal_dbm, :maxnoise_dbm,
21
+ :signal_rssi, :noise_rssi, :minsignal_rssi,
22
+ :minnoise_rssi, :maxsignal_rssi, :maxnoise_rssi,
23
+ :bestlat, :bestlon, :bestalt, :agglat, :agglon,
24
+ :aggalt, :aggpoints, :datasize, :turbocellnid,
25
+ :turbocellmode, :turbocellsat, :carrierset, :channel,
26
+ :maxseenrate, :encodingset, :decrypted, :dupeivpackets,
27
+ :bsstimestamp, :fragments, :retries, :newpackets) { |val| val.to_i }
28
+
29
+ # Attempt to map the returned BSSID type to one we know about it and
30
+ # convert it to a string. In the event we don't know it will leave this as
31
+ # an integer field.
32
+ #
33
+ # @param [String] bssid_type The string is actually an integer value in
34
+ # numeric form (this is how it's received from the network).
35
+ Bssid.set_data_filter(:type) { |val| BSSID_TYPE_MAP[val.to_i] || val.to_i }
36
+ Bssid.set_data_filter(:rangeip, :netmaskip, :gatewayip) { |val| (val == "0.0.0.0") ? nil : val }
37
+
38
+ Bssid.set_data_filter(:freqmhz) do |val|
39
+ raw = val.split('*').reject { |i| i.strip.empty? }.map { |v| v.split(':').map(&:to_i) }
40
+ Hash[raw]
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,15 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Bssidsrc = CapStruct.new(
4
+ :bssid, :uuid, :lasttime, :numpackets, :signal_dbm, :noise_dbm,
5
+ :minsignal_dbm, :minnoise_dbm, :maxsignal_dbm, :maxnoise_dbm, :signal_rssi,
6
+ :noise_rssi, :minsignal_rssi, :minnoise_rssi, :maxsignal_rssi,
7
+ :maxnoise_rssi
8
+ )
9
+ Bssidsrc.set_data_filter(:bssid) { |val| val.downcase }
10
+ Bssidsrc.set_data_filter(:numpackets, :signal_dbm, :noise_dbm, :firsttime,
11
+ :lasttime, :minsignal_dbm, :minnoise_dbm, :maxsignal_dbm, :maxnoise_dbm,
12
+ :signal_rssi, :noise_rssi, :minsignal_rssi, :minnoise_rssi,
13
+ :maxsignal_rssi, :maxnoise_rssi) { |val| val.to_i }
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Btscandev = CapStruct.new(
4
+ :bdaddr, :name, :class, :firsttime, :lasttime, :packets, :gpsfixed,
5
+ :minlat, :minlon, :minalt, :minspd, :maxlat, :maxlon, :maxalt, :maxspd,
6
+ :agglat, :agglon, :aggalt, :aggpoints
7
+ )
8
+ Btscandev.set_data_filter(:bdaddr) { |val| val.downcase }
9
+ Bssid.set_data_filter(:firsttime, :lasttime) { |val| val.to_i }
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Capability = CapStruct.new(:name, :capabilities)
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Channel = CapStruct.new(
4
+ :channel, :time_on, :packets, :packetsdelta, :usecused, :bytes,
5
+ :bytesdelta, :networks, :maxsignal_dbm, :maxsignal_rssi, :maxnoise_dbm,
6
+ :maxnoise_rssi, :activenetworks
7
+ )
8
+ Channel.set_data_filter(:channel, :time_on, :packets, :packetsdelta,
9
+ :usecused, :bytes, :bytesdelta, :networks, :maxsignal_dbm,
10
+ :maxsignal_dbm, :maxsignal_rssi, :maxnoise_dbm, :maxnoise_rssi,
11
+ :activenetworks) { |val| val.to_i }
12
+ end
13
+ end
@@ -0,0 +1,45 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Client = CapStruct.new(
4
+ :bssid, :mac, :type, :firsttime, :lasttime, :manuf, :llcpackets,
5
+ :datapackets, :cryptpackets, :gpsfixed, :minlat, :minlon, :minalt,
6
+ :minspd, :maxlat, :maxlon, :maxalt, :maxspd, :agglat, :agglon, :aggalt,
7
+ :aggpoints, :signal_dbm, :noise_dbm, :minsignal_dbm, :minnoise_dbm,
8
+ :maxsignal_dbm, :maxnoise_dbm, :signal_rssi, :noise_rssi,
9
+ :minsignal_rssi, :minnoise_rssi, :maxsignal_rssi, :maxnoise_rssi,
10
+ :bestlat, :bestlon, :bestalt, :atype, :ip, :gatewayip, :datasize,
11
+ :maxseenrate, :encodingset, :carrierset, :decrypted, :channel,
12
+ :fragments, :retries, :newpackets, :freqmhz, :cdpdevice, :cdpport,
13
+ :dot11d, :dhcphost, :dhcpvendor, :datacryptset
14
+ )
15
+ Client.set_data_filter(:bssid, :mac) { |val| val.downcase }
16
+
17
+ # Attempt to map the returned client type to one we know about it and
18
+ # convert it to a string. In the event we don't know it will leave this as
19
+ # an integer field.
20
+ #
21
+ # @param [String] client_type The string is actually an integer value in
22
+ # numeric form (this is how it's received from the network).
23
+ Client.set_data_filter(:type) { |val| CLIENT_TYPE_MAP[val.to_i] || val.to_i }
24
+ Client.set_data_filter(:firsttime, :lasttime, :llcpackets, :datapackets,
25
+ :cryptpackets, :minlat, :minlon, :minalt, :minspd,
26
+ :maxlat, :maxlon, :maxalt, :maxspd, :agglat,
27
+ :agglon, :aggalt, :aggpoints, :signal_dbm,
28
+ :noise_dbm, :minsignal_dbm, :minnoise_dbm,
29
+ :maxsignal_dbm, :maxnoise_dbm, :signal_rssi,
30
+ :noise_rssi, :minsignal_rssi, :minnoise_rssi,
31
+ :maxsignal_rssi, :maxnoise_rssi, :bestlat, :bestlon,
32
+ :bestalt, :atype, :datasize, :maxseenrate,
33
+ :encodingset, :carrierset, :decrypted, :channel,
34
+ :fragments, :retries, :newpackets) { |val| val.to_i }
35
+ Client.set_data_filter(:gpsfixed) { |val| val.to_i == 1 }
36
+
37
+ Client.set_data_filter(:ip, :gatewayip) { |val| (val == "0.0.0.0") ? nil : val }
38
+ Client.set_data_filter(:dhcphost) { |val| val.strip.empty? ? nil : val }
39
+
40
+ Client.set_data_filter(:freqmhz) do |val|
41
+ raw = val.split('*').reject { |i| i.strip.empty? }.map { |v| v.split(':').map(&:to_i) }
42
+ Hash[raw]
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,17 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Clisrc = CapStruct.new(
4
+ :bssid, :mac, :uuid, :lasttime, :numpackets, :signal_dbm, :noise_dbm,
5
+ :minsignal_dbm, :minnoise_dbm, :maxsignal_dbm, :maxnoise_dbm,
6
+ :signal_rssi, :noise_rssi, :minsignal_rssi, :minnoise_rssi,
7
+ :maxsignal_rssi, :maxnoise_rssi
8
+ )
9
+
10
+ Clisrc.set_data_filter(:bssid, :mac) { |val| val.downcase }
11
+ Clisrc.set_data_filter(:lasttime, :numpackets, :signal_dbm, :noise_dbm,
12
+ :minsignal_dbm, :minnoise_dbm, :maxsignal_dbm,
13
+ :maxnoise_dbm, :signal_rssi, :noise_rssi,
14
+ :minsignal_rssi, :minnoise_rssi, :maxsignal_rssi,
15
+ :maxnoise_rssi) { |val| val.to_i }
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Clitag = CapStruct.new(:bssid, :mac, :tag, :value)
4
+ Clitag.set_data_filter(:bssid, :mac) { |val| val.downcase }
5
+ end
6
+ end
@@ -0,0 +1,15 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Common = CapStruct.new(
4
+ :phytype, :macaddr, :firsttime, :lasttime, :packets, :llcpackets,
5
+ :errorpackets, :datapackets, :cryptpackets, :datasize, :newpackets,
6
+ :channel, :frequency, :freqmhz, :gpsfixed, :minlat, :minlon, :minalt,
7
+ :minspd, :maxlat, :maxlon, :maxalt, :maxspd, :signaldbm, :noisedbm,
8
+ :minsignaldbm, :minnoisedbm, :signalrssi, :noiserssi, :minsignalrssi,
9
+ :minnoiserssi, :maxsignalrssi, :maxnoiserssi, :bestlat, :bestlon,
10
+ :bestalt, :agglat, :agglon, :aggalt, :aggpoints
11
+ )
12
+ Common.set_data_filter(:macaddr) { |val| val.downcase }
13
+ Common.set_data_filter(:firsttime, :lasttime) { |val| val.to_i }
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Critfail = CapStruct.new(:id, :time, :message)
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Error = CapStruct.new(:cmdid, :text)
4
+ Error.set_data_filter(:cmdid) { |val| val.to_i }
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Gps = CapStruct.new(:lat, :lon, :alt, :spd, :heading, :fix, :satinfo, :hdop, :vdop, :connected)
4
+ Gps.set_data_filter(:lat, :lon, :alt, :spd, :heading, :fix, :hdop, :vdop) { |val| val.to_i }
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Info = CapStruct.new(
4
+ :networks, :packets, :crypt, :noise, :dropped, :rate, :filtered, :clients,
5
+ :llcpackets, :datapackets, :numsources, :numerrorsources
6
+ )
7
+ Info.set_data_filter(:networks, :packets, :crypt, :noise, :dropped, :rate,
8
+ :filtered, :clients, :llcpackets, :datapackets,
9
+ :numsources, :numerrorsources) { |val| val.to_i }
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Kismet = CapStruct.new(
4
+ :version, :starttime, :servername, :dumpfiles, :uid
5
+ )
6
+ Kismet.set_data_filter(:starttime) { |val| val.to_i }
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Nettag = CapStruct.new(:bssid, :tag, :value)
4
+ Nettag.set_data_filter(:bssid) { |val| val.downcase }
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Packet = CapStruct.new(
4
+ :type, :subtype, :timesec, :encrypted, :weak, :beaconrate, :sourcemac,
5
+ :destmac, :bssid, :ssid, :prototype, :sourceip, :destip, :sourceport,
6
+ :destport, :nbtype, :nbsource, :sourcename
7
+ )
8
+ Packet.set_data_filter(:bssid, :destmac, :sourcemac) { |val| val.downcase }
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Plugin = CapStruct.new(
4
+ :filename, :name, :version, :description, :unloadable, :root
5
+ )
6
+ Plugin.set_data_filter(:unloadable, :root) { |val| val.to_i }
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Protocols = CapStruct.new(:protocols)
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Remove = CapStruct.new(:bssid)
4
+ Remove.set_data_filter(:bssid) { |val| val.downcase }
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Source = CapStruct.new(
4
+ :interface, :type, :username, :channel, :uuid, :packets, :hop, :velocity,
5
+ :dwell, :hop_time_sec, :hop_time_usec
6
+ )
7
+ Source.set_data_filter(:channel, :dwell, :hop_time_sec, :hop_time_usec,
8
+ :hop, :packets, :velocity) { |val| val.to_i }
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Spectrum = CapStruct.new(
4
+ :devname, :amp_offset_mdbm, :amp_res_mdbm, :rssi_max, :start_khz,
5
+ :res_hz, :num_samples, :samples
6
+ )
7
+ end
8
+ end
@@ -0,0 +1,25 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Ssid = CapStruct.new(
4
+ :mac, :checksum, :type, :ssid, :beaconinfo, :cryptset, :cloaked,
5
+ :firsttime, :lasttime, :maxrate, :beaconrate
6
+ )
7
+ Ssid.set_data_filter(:mac) { |val| val.downcase }
8
+ Ssid.set_data_filter(:checksum, :firsttime, :lasttime, :maxrate,
9
+ :beaconrate) { |val| val.to_i }
10
+ Ssid.set_data_filter(:cloaked) { |val| val.to_i == 1 }
11
+ Ssid.set_data_filter(:cryptset) do |val|
12
+ val = val.to_i
13
+ next [SSID_CRYPT_MAP[0]] if val == 0
14
+ SSID_CRYPT_MAP.select { |k, _| (k & val) != 0 }.map { |_, v| v }
15
+ end
16
+
17
+ # Attempt to map the returned SSID type to one we know about it and convert
18
+ # it to a string. In the event we don't know it will leave this as an
19
+ # integer field.
20
+ #
21
+ # @param [String] ssid_type The string is actually an integer value in
22
+ # numeric form (this is how it's received from the network).
23
+ Ssid.set_data_filter(:type) { |val| SSID_TYPE_MAP[val.to_i] || val.to_i }
24
+ end
25
+ end
@@ -0,0 +1,5 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Status = CapStruct.new(:text, :flags)
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ String = CapStruct.new(:bssid, :source, :dest, :string)
4
+ String.set_data_filter(:bssid) { |val| val.downcase }
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Terminate = CapStruct.new(:text)
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Time = CapStruct.new(:timesec)
4
+ Time.set_data_filter(:timesec) { |val| val.to_i }
5
+ end
6
+ end
@@ -0,0 +1,8 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Trackinfo = CapStruct.new(
4
+ :devices, :packets, :datapackets, :cryptpackets, :errorpackets,
5
+ :filterpackets, :packetrate
6
+ )
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ module PatronusFati
2
+ module MessageModels
3
+ Wepkey = CapStruct.new(:origin, :bssid, :key, :encrypted, :failed)
4
+ Wepkey.set_data_filter(:bssid) { |val| val.downcase }
5
+ end
6
+ end
@@ -0,0 +1,39 @@
1
+ require 'patronus_fati/message_models/ack'
2
+ require 'patronus_fati/message_models/alert'
3
+ require 'patronus_fati/message_models/battery'
4
+ require 'patronus_fati/message_models/bssid'
5
+ require 'patronus_fati/message_models/bssidsrc'
6
+ require 'patronus_fati/message_models/btscandev'
7
+ require 'patronus_fati/message_models/capability'
8
+ require 'patronus_fati/message_models/channel'
9
+ require 'patronus_fati/message_models/client'
10
+ require 'patronus_fati/message_models/clisrc'
11
+ require 'patronus_fati/message_models/clitag'
12
+ require 'patronus_fati/message_models/common'
13
+ require 'patronus_fati/message_models/critfail'
14
+ require 'patronus_fati/message_models/error'
15
+ require 'patronus_fati/message_models/gps'
16
+ require 'patronus_fati/message_models/info'
17
+ require 'patronus_fati/message_models/kismet'
18
+ require 'patronus_fati/message_models/nettag'
19
+ require 'patronus_fati/message_models/packet'
20
+ require 'patronus_fati/message_models/plugin'
21
+ require 'patronus_fati/message_models/protocols'
22
+ require 'patronus_fati/message_models/remove'
23
+ require 'patronus_fati/message_models/source'
24
+ require 'patronus_fati/message_models/spectrum'
25
+ require 'patronus_fati/message_models/ssid'
26
+ require 'patronus_fati/message_models/status'
27
+ require 'patronus_fati/message_models/string'
28
+ require 'patronus_fati/message_models/terminate'
29
+ require 'patronus_fati/message_models/time'
30
+ require 'patronus_fati/message_models/trackinfo'
31
+ require 'patronus_fati/message_models/wepkey'
32
+
33
+ module MessageModels
34
+ # @note In all of the message models the ordering of the attributes is
35
+ # actually important, as these are the default orderings provided by the
36
+ # server I was developing against. The casing of the name is also important
37
+ # as the best we can automatically do from the header information is a
38
+ # downcase and capitalize.
39
+ end