thm 0.1.8

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