patronus_fati 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|