thm 0.1.8

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
+ SHA1:
3
+ metadata.gz: 91428c60a9b74ea883550ea758c66868d9dff5df
4
+ data.tar.gz: 78114801f27854edd1133d5b9d1852594040fe01
5
+ SHA512:
6
+ metadata.gz: 4669fd20a613c0ebd2434671d1abc5f1eaa8f8177edc0bfd17f572fd014feba1d0d2d0714589117a1054fb9154152b41cdbe11ce02a2503cdd6776eb4b7c4660
7
+ data.tar.gz: c976aa7fa719c269906e22fdbb2008c4f634e379e13549792c08190592eaa6573e4cd53219b42eddd9294665b1b4b949e1c2fdd17cc4d0155dd719e09f74a769
data/README.1ST ADDED
@@ -0,0 +1,38 @@
1
+ Threatmonitor Overview
2
+ ======================
3
+
4
+
5
+ Sending data to a RabbitMQ queue so you can grab the data later.
6
+
7
+ Please note that the queue prefix -q the queue will end up named wifi_iptables etc ...
8
+
9
+ ruby thm-producer.rb -m capture -q wifi
10
+
11
+ Loading your data into a database.
12
+
13
+ You can change the queue it reads from / databases tables it loads into in the code just make sure you've created the database tables.
14
+
15
+ obj = Thm::Consumer.new
16
+ obj.queueprefix = "wifi"
17
+ obj.tblname_ippacket = "wifi_ippacket"
18
+ obj.tblname_tcppacket = "wifi_tcppacket"
19
+ obj.tblname_udppacket = "wifi_udppacket"
20
+
21
+ ruby thm-consumer.rb
22
+
23
+ How to load a pcap file.
24
+
25
+ obj = Thm::Localmachine.new
26
+ obj.tblname_ippacket = "wifi_ippacket"
27
+ obj.tblname_tcppacket = "wifi_tcppacket"
28
+ obj.tblname_udppacket = "wifi_udppacket"
29
+ obj.dbconnect
30
+
31
+ ruby thm-pcap.rb -f Example2.pcap
32
+
33
+ Thats really all the is to it.
34
+
35
+ Enjoy!
36
+
37
+ Brian Hood
38
+
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+
2
+ Threatmonitor - Packet Analysis suite with MonetDB / MySQL - RabbitMQ & PCap integration
3
+
4
+ ![GeoIP](https://raw.githubusercontent.com/puppetpies/threatmonitor/master/screenshot-3-geo.jpg)
5
+
6
+ Getting Started
7
+
8
+ Things you need
9
+
10
+ RabbitMQ
11
+
12
+ MonetDB or MySQL
13
+
14
+ Ruby
15
+
16
+ Pcaplet - https://github.com/ahobson/ruby-pcap
17
+
18
+ PCAPRUB - https://github.com/puppetpies/pcaprub - For Interface Realtime capture / dumping to disk
19
+
20
+ ![Dashboard](https://raw.githubusercontent.com/puppetpies/threatmonitor/master/screenshot-1.jpg)
21
+
22
+ To build:
23
+
24
+ You'll need PCAP / Development Header files
25
+
26
+ gem build pcap.gemspec
27
+ gem install pcap-0.7.7.gem
28
+
29
+ GEMS: AMQP, Bunny, Eventmachine, guid, MonetDB, mysql, pcaplet
30
+
31
+ This is all experimental but i believe it works well so far.
32
+
33
+ Features ability to push pcap data to Message Queue.
34
+
35
+ Read data from disk into message queue
36
+
37
+ Write data from message queue to disk.
38
+
39
+ Allows you to easily move IP / TCP / UDP data with ease and analyze else where
40
+
41
+ Creating your database once you've installed MonetDB
42
+
43
+ monetdbd create /path/to/dbfarm
44
+
45
+ monetdbd start /path/to/dbfarm
46
+
47
+ monetdb create threatmonitor
48
+
49
+ monetdb release threatmonitor
50
+
51
+ monetdb start threatmonitor
52
+
53
+ Import the schema from the SQL provided now moved to sql/
54
+
55
+ I've now included MySQL Database support also however if your going to create big data sets i think i would use MonetDB
56
+
57
+ ![Dashboard Other](https://raw.githubusercontent.com/puppetpies/threatmonitor/master/screenshot-2.jpg)
58
+
59
+ Have fun !
data/bin/thm-consumer ADDED
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/ruby
2
+ ########################################################################
3
+ #
4
+ # Author: Brian Hood
5
+ #
6
+ # Description: Threatmonitor Consumer
7
+ #
8
+ # Producer - Save data from queue to Database
9
+ #
10
+ ########################################################################
11
+ #puts Dir.getwd
12
+ require 'getoptlong'
13
+ require File.expand_path(File.join(
14
+ File.dirname(__FILE__),
15
+ "../lib/thm.rb", "../../config.rb"))
16
+
17
+ include Thm::Defaults
18
+
19
+ ARGV[0] = "--help" if ARGV[0] == nil
20
+
21
+ banner = "\e[1;34mWelcome to Threatmonitor Consumer \e[0m\ \n"
22
+ banner << "\e[1;34m=================================\e[0m\ \n"
23
+
24
+ opts = GetoptLong.new(
25
+ [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
26
+ [ '--infinite', '-i', GetoptLong::NO_ARGUMENT ],
27
+ [ '--passes', '-p', GetoptLong::REQUIRED_ARGUMENT ],
28
+ [ '--runonce', '-r', GetoptLong::NO_ARGUMENT ]
29
+ )
30
+
31
+ opts.each do |opt, arg|
32
+ case opt
33
+ when '--help'
34
+ helper = %q[
35
+ -h, --help:
36
+ show help
37
+
38
+ -i, --infinite [ For consuming live captures ]
39
+
40
+ -p, --passes number of passes [ For medium / larger queues ]
41
+
42
+ -r, --runonce [ Just as it says ]
43
+
44
+ NOTES:
45
+
46
+ Press CTRL+C to exit Reactor thread at anytime to move on to next queue.
47
+ There are currently 3 queues ippacket, tcppacket, udppacket
48
+
49
+ ]
50
+ puts banner
51
+ puts helper
52
+ exit
53
+ when '--infinite'
54
+ @infinite = arg
55
+ when '--passes'
56
+ @passes = arg
57
+ when '--runonce'
58
+ @runonce = arg
59
+ end
60
+ end
61
+
62
+ puts banner
63
+ # See thmmq.rb for list for variables
64
+ obj = Thm::Consumer.new
65
+ obj.datastore = DATASTORE
66
+ obj.mqhost = MQHOST
67
+ obj.mquser = MQUSER
68
+ obj.mqpass = MQPASS
69
+ obj.mqvhost = MQVHOST
70
+ obj.dbhost = DBHOST
71
+ obj.dbuser = DBUSER
72
+ obj.dbpass = DBPASS
73
+ obj.dbname = DBNAME
74
+ obj.queueprefix = QUEUEPREFIX
75
+ obj.tblname_ippacket = TBLNAME_IPPACKET
76
+ obj.tblname_tcppacket = TBLNAME_TCPPACKET
77
+ obj.tblname_udppacket = TBLNAME_UDPPACKET
78
+ obj.mqconnect
79
+ obj.dbconnect
80
+ # Send data to database from queue
81
+ if @infinite.nil? == false
82
+ obj.infinite
83
+ elsif @passes.nil? == false
84
+ obj.passes(@passes.to_i)
85
+ elsif @runonce.nil? == false
86
+ obj.from_mq_to_db
87
+ end
88
+ obj.mqclose
89
+
data/bin/thm-pcap ADDED
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/ruby
2
+ ########################################################################
3
+ #
4
+ # Author: Brian Hood
5
+ #
6
+ # Description: Threatmonitor Pcap
7
+ #
8
+ # Producer - Save data from Pcap file(s) to Database
9
+ #
10
+ ########################################################################
11
+
12
+ require 'getoptlong'
13
+ require File.expand_path(File.join(
14
+ File.dirname(__FILE__),
15
+ "../lib/thm.rb", "../../config.rb"))
16
+
17
+ include Thm::Defaults
18
+
19
+ ARGV[0] = "--help" if ARGV[0] == nil
20
+
21
+ banner = "\e[1;34mWelcome to Threatmonitor PCap Loader \e[0m\ \n"
22
+ banner << "\e[1;34m===================================\e[0m\ \n"
23
+
24
+ opts = GetoptLong.new(
25
+ [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
26
+ [ '--pcapfile', '-f', GetoptLong::OPTIONAL_ARGUMENT ]
27
+ )
28
+
29
+ opts.each do |opt, arg|
30
+ case opt
31
+ when '--help'
32
+ helper = %q[
33
+ -h, --help:
34
+ show help
35
+
36
+ -f, --pcapfile [ REQUIRED ]
37
+ ]
38
+ puts banner
39
+ puts helper
40
+ exit
41
+ when '--pcapfile'
42
+ @pcapfile = arg
43
+ end
44
+ end
45
+
46
+ puts banner
47
+ # See thmmq.rb for list for variables
48
+ obj = Thm::Localmachine.new
49
+ obj.datastore = DATASTORE
50
+ obj.mqhost = MQHOST
51
+ obj.mquser = MQUSER
52
+ obj.mqpass = MQPASS
53
+ obj.mqvhost = MQVHOST
54
+ obj.dbhost = DBHOST
55
+ obj.dbuser = DBUSER
56
+ obj.dbpass = DBPASS
57
+ obj.dbname = DBNAME
58
+ obj.queueprefix = QUEUEPREFIX
59
+ obj.tblname_ippacket = TBLNAME_IPPACKET
60
+ obj.tblname_tcppacket = TBLNAME_TCPPACKET
61
+ obj.tblname_udppacket = TBLNAME_UDPPACKET
62
+ obj.dbconnect
63
+ # Send data to database from queue
64
+ if @pcapfile.nil? == false
65
+ obj.from_pcap_db("#{@pcapfile}")
66
+ end
67
+
data/bin/thm-producer ADDED
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/ruby
2
+ ########################################################################
3
+ #
4
+ # Author: Brian Hood
5
+ #
6
+ # Description: Threatmonitor Producer
7
+ #
8
+ # Producer - Load data Database to RabbitMQ for distrubition or Packet
9
+ # Trace live data and send to RabbitMQ
10
+ ########################################################################
11
+
12
+ require 'getoptlong'
13
+ require File.expand_path(File.join(
14
+ File.dirname(__FILE__),
15
+ "../lib/thm.rb", "../../config.rb"))
16
+
17
+ include Thm::Defaults
18
+
19
+ ARGV[0] = "--help" if ARGV[0] == nil
20
+
21
+ opts = GetoptLong.new(
22
+ [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
23
+ [ '--mode', '-m', GetoptLong::REQUIRED_ARGUMENT ],
24
+ [ '--queueprefix', '-q', GetoptLong::OPTIONAL_ARGUMENT ],
25
+ [ '--interface', '-i', GetoptLong::REQUIRED_ARGUMENT ],
26
+ [ '--filter', '-f', GetoptLong::REQUIRED_ARGUMENT ]
27
+ )
28
+
29
+ banner = "\e[1;34mWelcome to Threatmonitor Producer \e[0m\ \n"
30
+ banner << "\e[1;34m=================================\e[0m\ \n"
31
+
32
+ opts.each do |opt, arg|
33
+ case opt
34
+ when '--help'
35
+ helper = %q[
36
+ -h, --help:
37
+ show help
38
+
39
+ -m, --mode database / capture [ REQUIRED ]
40
+
41
+ -q, --queueprefix queue name [ OPTIONAL ] [ Uses config.rb ]
42
+
43
+ -i --interface network interface [ REQUIRED ]
44
+
45
+ -f --filter your pcap / tcpdump style filter [ OPTIONAL ]
46
+ ]
47
+ puts banner
48
+ puts helper
49
+ exit
50
+ when '--mode'
51
+ @modeparam = arg
52
+ when '--queueprefix'
53
+ @queueprefix = arg
54
+ when '--interface'
55
+ @interface = arg
56
+ when '--filter'
57
+ @filter = arg
58
+ end
59
+ end
60
+
61
+ puts banner
62
+ # See thmmq.rb for list for variables
63
+ obj = Thm::Producer.new
64
+ obj.datastore = DATASTORE
65
+ obj.mqhost = MQHOST
66
+ obj.mquser = MQUSER
67
+ obj.mqpass = MQPASS
68
+ obj.mqvhost = MQVHOST
69
+ obj.dbhost = DBHOST
70
+ obj.dbuser = DBUSER
71
+ obj.dbpass = DBPASS
72
+ obj.dbname = DBNAME
73
+ if !defined? @queueprefix
74
+ obj.queueprefix = QUEUEPREFIX
75
+ else
76
+ obj.queueprefix = @queueprefix
77
+ end
78
+ obj.tblname_ippacket = TBLNAME_IPPACKET
79
+ obj.tblname_tcppacket = TBLNAME_TCPPACKET
80
+ obj.tblname_udppacket = TBLNAME_UDPPACKET
81
+ obj.mqconnect
82
+ obj.dbconnect unless @modeparam == "capture"
83
+ mode = @modeparam
84
+
85
+ if mode == "database"
86
+ # Send data from Database to RabbitMQ for Fanout etc
87
+ ippacketsql = "SELECT * FROM \"threatmonitor\".#{obj.tblname_ippacket} LIMIT 300 OFFSET 400000"
88
+ obj.from_db_to_mq(ippacketsql)
89
+
90
+ elsif mode == "capture"
91
+ # From Pcap to RabbitMQ for Fanout etc.
92
+ #
93
+ # Standard Pcap / Wireshark filters
94
+ # 'tcp port not 22 and not arp and udp port not 53 and udp portrange not 67-69 and tcp port not 8443 and host not 78.47.223.130'
95
+ if %x{id -u}.strip != "0"
96
+ puts "Require superuser privileges"
97
+ exit
98
+ end
99
+ obj.from_interface_to_mq("#{@interface}", "#{@filter}")
100
+ #obj.from_pcap_to_mq("wlo1", "tcp port not 22")
101
+ obj.mqclose
102
+ end
data/bin/thm-session ADDED
@@ -0,0 +1,319 @@
1
+ #!/usr/bin/ruby
2
+ ########################################################################
3
+ #
4
+ # Author: Brian Hood
5
+ #
6
+ # Description: Threatmonitor User Administration / Dashboard
7
+ # Codename: Deedrah
8
+ #
9
+ # Extends the functionality of the Thm module adding Authorization
10
+ # Adding Session Login / Sinatra / Web Interface functionality
11
+ #
12
+ ########################################################################
13
+
14
+ require 'rubygems' if RUBY_VERSION < "1.9"
15
+ require 'chartkick'
16
+ require 'sinatra/base'
17
+ require 'slim'
18
+ require 'colorize'
19
+
20
+ require File.expand_path(File.join(
21
+ File.dirname(__FILE__),
22
+ "../thm-authentication.rb"))
23
+
24
+ RELEASE = "Deedrah"
25
+
26
+ class Sinatra::Base
27
+
28
+ class << self
29
+
30
+ def getpost(path, opts={}, &block)
31
+ get(path, opts, &block)
32
+ post(path, opts, &block)
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+
39
+
40
+ class Geocounter
41
+
42
+ # Create / Add to instance variable
43
+ def geocount(country)
44
+ country.gsub!(" ", "_") # no spaces or case
45
+ if !instance_variable_get("@#{country}")
46
+ instance_variable_set("@#{country}", 1)
47
+ else
48
+ instance_variable_set("@#{country}", instance_variable_get("@#{country}") + 1)
49
+ end
50
+ puts "Country: #{country} Value: "+instance_variable_get("@#{country}").to_s
51
+ end
52
+
53
+ # Read a single country
54
+ def geocount_reader(country)
55
+ country.gsub!(" ", "_") # no spaces or case
56
+ valnum = instance_variable_get("@#{country}")
57
+ return valnum
58
+ end
59
+
60
+ # Compile in array with the totals of all instance variables
61
+ def geocount_compile
62
+ countrycounts = Array.new
63
+ instance_variables.each {|n|
64
+ t = n.to_s.gsub("@", "")
65
+ countrycounts << ["#{t}", instance_variable_get("#{n}")]
66
+ }
67
+ return countrycounts
68
+ countrycounts
69
+ end
70
+
71
+ end
72
+
73
+ module ThmUI extend self
74
+
75
+ class Deedrah < Sinatra::Base
76
+
77
+ attr_reader :thmsession
78
+
79
+ include Chartkick::Helper
80
+
81
+ set :server, :puma
82
+ set :logging, :true
83
+ set :app_file, __FILE__
84
+
85
+ configure do
86
+ enable :session
87
+ end
88
+
89
+ before do
90
+ content_type :html
91
+ end
92
+
93
+ set :title, "Threatmonitor - Packet Analysis Suite #{RELEASE}"
94
+ set :port, 4567
95
+ set :bind, "0.0.0.0"
96
+ # Global helpers
97
+ #helpers ApplicationHelper
98
+
99
+ # Set folders for template to
100
+ set :root, File.expand_path(File.join(File.dirname(__FILE__), '../'))
101
+ puts root.green
102
+
103
+ templateroot = File.expand_path(File.join(File.dirname(__FILE__), '../views'))
104
+ set :sessions,
105
+ :httponly => true,
106
+ :secure => production?,
107
+ :expire_after => 3600, # 1 hour
108
+ #:views => File.expand_path(File.expand_path('../../views/', __FILE__)),
109
+ :views => Proc.new { File.join(root, "views") },
110
+ #:layout_engine => :slim,
111
+ :public_folder => File.dirname(__FILE__) + '/bin'
112
+
113
+ enable :method_override
114
+
115
+ puts "TemplateRoot: #{templateroot}".to_s
116
+ def objstart!
117
+ @sessobj = Thm::Authorization::Authentication.new
118
+ @sessobj.datastore = "monetdb"
119
+ @sessobj.dbconnect
120
+ end
121
+
122
+ # NOTE: Monkey patch Sinatra initialize
123
+ # If you go to /dashboard without logging in @sessobj it won't have been created
124
+ # So if you create it objstart! in the Sinatra's initialize your sorted.
125
+ # Page requests will come in a @sessobj will always exist and be the same one no headaches
126
+ def initialize(app = nil)
127
+ super()
128
+ objstart! # Little trick here patch so i can get objstart! out of the box!
129
+ @app = app
130
+ @template_cache = Tilt::Cache.new
131
+ yield self if block_given?
132
+ end
133
+
134
+ def login_session?
135
+ if @sessobj.login_session? == false
136
+ puts "Not logged in"
137
+ else
138
+ return true
139
+ end
140
+ end
141
+
142
+ def get_session_info?
143
+ puts "Sinatra: #{Sinatra::VERSION} / Thmsession: #{@sessobj.thmsession}"
144
+ end
145
+
146
+ def login(username, password)
147
+ @sessobj.login("#{username}", "#{password}")
148
+ if login_session?
149
+ puts "\e[1;32m\Welcome to Threatmonitor \e[0m\ "
150
+ puts "Thm Session: #{@sessobj.thmsession}"
151
+ return true
152
+ else
153
+ return false
154
+ end
155
+ end
156
+
157
+ def logout
158
+ @sessobj.thmsesslock = "DEADBEEF"
159
+ end
160
+
161
+ def login_lock?
162
+ if @sessobj.thmsesslock != "OK"
163
+ puts "Session doesn't exist redirecting to Login..."
164
+ redirect '/'
165
+ end
166
+ end
167
+
168
+ # Sinatra routings
169
+
170
+ getpost '/' do
171
+ if params[:submit] != nil
172
+ @sessthm = login(params[:username], params[:password])
173
+ end
174
+ if @sessobj.thmsesslock == "OK"
175
+ puts "Session created redirecting to Dashboard ..."
176
+ redirect '/dashboard'
177
+ end
178
+ slim :authenticate
179
+ end
180
+
181
+ def geoiplookup(ip)
182
+ query = "SELECT continent_name, country_name FROM geoipdata_ipv4blocks_country a JOIN geoipdata_locations_country b ON (a.geoname_id = b.geoname_id) WHERE network LIKE '#{ip.split(".")[0]}.#{ip.split(".")[1]}.%' GROUP BY b.continent_name, b.country_name LIMIT 1;"
183
+ resusrcnt = @sessobj.query("#{query}")
184
+ while row = resusrcnt.fetch_hash do
185
+ continent_name = row["continent_name"].to_s
186
+ country_name = row["country_name"].to_s
187
+ #if continent_name == ""
188
+ cname = "(#{country_name})"
189
+ #else
190
+ # cname = "(#{continent_name})"
191
+ #end
192
+ end
193
+ # geoipcount(
194
+ return cname
195
+ end
196
+
197
+ def packetcounts(proto)
198
+ # Retrieve
199
+ query = "select count(*) as num2, ip_dst from wifi_ippacket a JOIN wifi_#{proto}packet b on (a.guid = b.guid) JOIN service_definitions s on (s.num = b.#{proto}_dport) where #{proto}_dport > 0 and #{proto}_dport < 10000 and s.protocol = '#{proto.upcase}' and ip_dst not in ('255.255.255.255') group by b.#{proto}_dport, a.ip_dst;"
200
+ resusrcnt = @sessobj.query("#{query}")
201
+ rowusrcnt = Array.new
202
+ @gcnt = Geocounter.new
203
+ while row = resusrcnt.fetch_hash do
204
+ num2 = row["num2"].to_s
205
+ ip_dst = row["ip_dst"].to_s
206
+ location = geoiplookup(ip_dst)
207
+ locfix = location.to_s.gsub("(", "").gsub(")", "") # Yawn
208
+ if location != nil or location == ""
209
+ @gcnt.geocount("#{locfix}")
210
+ end
211
+ rowusrcnt << ["#{ip_dst} #{location}", "#{num2}"]
212
+ end
213
+ return rowusrcnt
214
+ end
215
+
216
+ def servicecounts(proto)
217
+ query = "select num, description, count(*) as num2 from wifi_ippacket a JOIN wifi_#{proto}packet b on (a.guid = b.guid) JOIN service_definitions s on (s.num = b.#{proto}_dport) where #{proto}_dport > 0 and #{proto}_dport < 10000 and s.protocol = '#{proto.upcase}' and ip_dst not in ('255.255.255.255') group by b.#{proto}_dport, a.ip_dst, s.description, s.num;"
218
+ resusrcnt = @sessobj.query("#{query}")
219
+ rowusrcnt = Array.new
220
+ while row = resusrcnt.fetch_hash do
221
+ num = row["num"].to_s
222
+ desc = row["description"].to_s
223
+ count = row["num2"].to_s
224
+ rowusrcnt << ["#{desc} (#{num})", "#{count}"]
225
+ end
226
+ return rowusrcnt
227
+ end
228
+
229
+ def toptalkers(proto)
230
+ query = "select count(*) as num2, #{proto}_dport, ip_dst from wifi_ippacket a JOIN wifi_#{proto}packet b on (a.guid = b.guid) JOIN service_definitions s on (s.num = b.#{proto}_dport) where #{proto}_dport > 0 and #{proto}_dport < 10000 and s.protocol = '#{proto.upcase}' and ip_dst not in ('255.255.255.255') group by b.#{proto}_dport, a.ip_dst order by num2 desc;"
231
+ resusrcnt = @sessobj.query("#{query}")
232
+ rowusrcnt = Array.new
233
+ while row = resusrcnt.fetch_hash do
234
+ ip_dst = row["ip_dst"].to_s
235
+ num = row["#{proto}_dport"].to_s
236
+ count = row["num2"].to_s
237
+ location = geoiplookup(ip_dst)
238
+ rowusrcnt << ["#{ip_dst} #{location} (#{num})", "#{count}"]
239
+ end
240
+ return rowusrcnt
241
+ end
242
+
243
+ getpost '/dashboard' do
244
+ login_lock?
245
+ # UDP
246
+ @rowusrcnt = packetcounts("udp")
247
+ # TCP
248
+ @rowusrcnt2 = packetcounts("tcp")
249
+ # Service chart UDP
250
+ @rowusrcnt3 = servicecounts("udp")
251
+ # Service chart TCP
252
+ @rowusrcnt4 = servicecounts("tcp")
253
+ # Top TCP/IP Talkers
254
+ @rowusrcnt5 = toptalkers("udp")
255
+ # Top UDP/IP Talkers
256
+ @rowusrcnt6 = toptalkers("tcp")
257
+ @rowgeocount = @gcnt.geocount_compile
258
+ puts "Geo Data:"
259
+ @rowgeocount.each {|n, x|
260
+ puts "#{n} #{x}"
261
+ }
262
+ erb :dashboard
263
+ end
264
+
265
+ get '/status' do
266
+ # Informational / Debug
267
+ get_session_info?
268
+ end
269
+
270
+ get '/logout' do
271
+ # Logout and remove thmsesslock
272
+ if @sessobj.thmsesslock == "OK"
273
+ logout
274
+ redirect '/'
275
+ end
276
+ slim :logout
277
+ end
278
+
279
+ get '/stylesheets/screen.css' do
280
+ send_file 'stylesheets/screen.css', :type => :css
281
+ end
282
+
283
+ get '/js/chartkick.js' do
284
+ send_file 'js/chartkick.js', :type => :js
285
+ end
286
+
287
+ get '/js/jquery.min.js' do
288
+ send_file 'js/jquery.min.js', :type => :js
289
+ end
290
+
291
+ get '/js/JSXTransformer.js' do
292
+ send_file 'js/JSXTransformer.js', :type => :js
293
+ end
294
+
295
+ get '/js/marked.min.js' do
296
+ send_file 'js/marked.min.js', :type => :js
297
+ end
298
+
299
+ get '/js/react.js' do
300
+ send_file 'js/react.js', :type => :js
301
+ end
302
+
303
+ get '/js/files/authenticate.jsx' do
304
+ send_file 'js/files/authenticate.jsx', :type => :js
305
+ end
306
+
307
+ get '/js/jsapi.js' do
308
+ send_file 'js/jsapi.js', :type => :js
309
+ end
310
+
311
+ run!
312
+
313
+ end
314
+
315
+ end
316
+
317
+ # Start Dashboard Release
318
+
319
+ Deedrah.new