patronus_fati 0.8.0
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/.gitignore +20 -0
- data/.rspec +2 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/LICENSE +165 -0
- data/README.md +29 -0
- data/Rakefile +21 -0
- data/bin/patronus_fati +54 -0
- data/kismet_configs/pat_fat_startup.sh +3 -0
- data/kismet_configs/patronus_fati_kismet.conf +88 -0
- data/lib/patronus_fati/cap_struct.rb +97 -0
- data/lib/patronus_fati/connection.rb +85 -0
- data/lib/patronus_fati/consts.rb +85 -0
- data/lib/patronus_fati/data_mapper/crypt_flags.rb +83 -0
- data/lib/patronus_fati/data_mapper/null_table_prefix.rb +7 -0
- data/lib/patronus_fati/data_models/access_point.rb +74 -0
- data/lib/patronus_fati/data_models/alert.rb +24 -0
- data/lib/patronus_fati/data_models/ap_frequency.rb +14 -0
- data/lib/patronus_fati/data_models/ap_signal.rb +12 -0
- data/lib/patronus_fati/data_models/client.rb +69 -0
- data/lib/patronus_fati/data_models/client_frequency.rb +14 -0
- data/lib/patronus_fati/data_models/client_signal.rb +12 -0
- data/lib/patronus_fati/data_models/common.rb +49 -0
- data/lib/patronus_fati/data_models/connection.rb +48 -0
- data/lib/patronus_fati/data_models/mac.rb +48 -0
- data/lib/patronus_fati/data_models/probe.rb +13 -0
- data/lib/patronus_fati/data_models/ssid.rb +35 -0
- data/lib/patronus_fati/data_observers/access_point_observer.rb +53 -0
- data/lib/patronus_fati/data_observers/alert_observer.rb +12 -0
- data/lib/patronus_fati/data_observers/client_observer.rb +52 -0
- data/lib/patronus_fati/data_observers/connection_observer.rb +66 -0
- data/lib/patronus_fati/data_observers/probe_observer.rb +11 -0
- data/lib/patronus_fati/data_observers/ssid_observer.rb +53 -0
- data/lib/patronus_fati/event_handler.rb +27 -0
- data/lib/patronus_fati/factory_base.rb +56 -0
- data/lib/patronus_fati/message_models/ack.rb +5 -0
- data/lib/patronus_fati/message_models/alert.rb +10 -0
- data/lib/patronus_fati/message_models/battery.rb +6 -0
- data/lib/patronus_fati/message_models/bssid.rb +43 -0
- data/lib/patronus_fati/message_models/bssidsrc.rb +15 -0
- data/lib/patronus_fati/message_models/btscandev.rb +11 -0
- data/lib/patronus_fati/message_models/capability.rb +5 -0
- data/lib/patronus_fati/message_models/channel.rb +13 -0
- data/lib/patronus_fati/message_models/client.rb +45 -0
- data/lib/patronus_fati/message_models/clisrc.rb +17 -0
- data/lib/patronus_fati/message_models/clitag.rb +6 -0
- data/lib/patronus_fati/message_models/common.rb +15 -0
- data/lib/patronus_fati/message_models/critfail.rb +5 -0
- data/lib/patronus_fati/message_models/error.rb +6 -0
- data/lib/patronus_fati/message_models/gps.rb +6 -0
- data/lib/patronus_fati/message_models/info.rb +11 -0
- data/lib/patronus_fati/message_models/kismet.rb +8 -0
- data/lib/patronus_fati/message_models/nettag.rb +6 -0
- data/lib/patronus_fati/message_models/packet.rb +10 -0
- data/lib/patronus_fati/message_models/plugin.rb +8 -0
- data/lib/patronus_fati/message_models/protocols.rb +5 -0
- data/lib/patronus_fati/message_models/remove.rb +6 -0
- data/lib/patronus_fati/message_models/source.rb +10 -0
- data/lib/patronus_fati/message_models/spectrum.rb +8 -0
- data/lib/patronus_fati/message_models/ssid.rb +25 -0
- data/lib/patronus_fati/message_models/status.rb +5 -0
- data/lib/patronus_fati/message_models/string.rb +6 -0
- data/lib/patronus_fati/message_models/terminate.rb +5 -0
- data/lib/patronus_fati/message_models/time.rb +6 -0
- data/lib/patronus_fati/message_models/trackinfo.rb +8 -0
- data/lib/patronus_fati/message_models/wepkey.rb +6 -0
- data/lib/patronus_fati/message_models.rb +39 -0
- data/lib/patronus_fati/message_parser.rb +44 -0
- data/lib/patronus_fati/message_processor/alert.rb +15 -0
- data/lib/patronus_fati/message_processor/bssid.rb +47 -0
- data/lib/patronus_fati/message_processor/capability.rb +24 -0
- data/lib/patronus_fati/message_processor/client.rb +55 -0
- data/lib/patronus_fati/message_processor/critfail.rb +8 -0
- data/lib/patronus_fati/message_processor/error.rb +7 -0
- data/lib/patronus_fati/message_processor/protocols.rb +7 -0
- data/lib/patronus_fati/message_processor/ssid.rb +48 -0
- data/lib/patronus_fati/message_processor.rb +52 -0
- data/lib/patronus_fati/version.rb +3 -0
- data/lib/patronus_fati.rb +68 -0
- data/patronus_fati.gemspec +41 -0
- data/spec/data_models/access_point_spec.rb +26 -0
- data/spec/data_models/alert_spec.rb +12 -0
- data/spec/data_models/client_spec.rb +25 -0
- data/spec/data_models/connection_spec.rb +86 -0
- data/spec/data_models/mac_spec.rb +26 -0
- data/spec/patronus_fati_spec.rb +13 -0
- data/spec/spec_helper.rb +71 -0
- data/wrapper.rb +19 -0
- 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,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,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,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,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,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,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,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,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,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,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
|