itrp 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/Gemfile +19 -0
- data/Gemfile.lock +86 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +23 -0
- data/Rakefile +51 -0
- data/VERSION +1 -0
- data/lib/cmd_base.rb +106 -0
- data/lib/cmd_root.rb +20 -0
- data/lib/handlers/alert.rb +27 -0
- data/lib/handlers/counter.rb +49 -0
- data/lib/handlers/delete_alerts.rb +43 -0
- data/lib/handlers/flow.rb +29 -0
- data/lib/handlers/fts.rb +32 -0
- data/lib/handlers/getkey.rb +38 -0
- data/lib/handlers/getlabel.rb +39 -0
- data/lib/handlers/help.rb +13 -0
- data/lib/handlers/list.rb +13 -0
- data/lib/handlers/list_counters.rb +32 -0
- data/lib/handlers/meters.rb +40 -0
- data/lib/handlers/options.rb +33 -0
- data/lib/handlers/query_alerts.rb +77 -0
- data/lib/handlers/query_flow.rb +73 -0
- data/lib/handlers/query_fts.rb +51 -0
- data/lib/handlers/query_resource.rb +68 -0
- data/lib/handlers/resolve.rb +34 -0
- data/lib/handlers/resource.rb +30 -0
- data/lib/handlers/set.rb +35 -0
- data/lib/handlers/timeslices.rb +31 -0
- data/lib/handlers/toppers.rb +41 -0
- data/lib/handlers/trackers.rb +49 -0
- data/lib/handlers/traffic.rb +68 -0
- data/lib/itrp.rb +140 -0
- data/test/helper.rb +34 -0
- data/test/test_itrp.rb +7 -0
- metadata +179 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
module ITRP
|
2
|
+
|
3
|
+
class Cmd_query_resource < Cmd
|
4
|
+
def initialize (e)
|
5
|
+
super(e)
|
6
|
+
@enabled_in_state = :resource
|
7
|
+
@attach_cmd = ''
|
8
|
+
@trigger = 'query'
|
9
|
+
end
|
10
|
+
|
11
|
+
def completions(patt)
|
12
|
+
TRP::QueryResourcesRequest
|
13
|
+
.fields
|
14
|
+
.values
|
15
|
+
.collect { |a| a.name }
|
16
|
+
.grep( /^#{Regexp.escape(patt)}/i)
|
17
|
+
end
|
18
|
+
|
19
|
+
def enter(patt)
|
20
|
+
|
21
|
+
terms = patt.scan( /(\w+)\s*=\s*([\w\-_\.\:]+)+/ )
|
22
|
+
|
23
|
+
qparams = terms.inject({}) { |acc,t| acc.store( t[0].to_sym, t[1]);acc}
|
24
|
+
|
25
|
+
[:maxitems].each do |a|
|
26
|
+
qparams[a] = qparams[a].to_i if qparams.key? a
|
27
|
+
end
|
28
|
+
|
29
|
+
p qparams
|
30
|
+
|
31
|
+
# meter names
|
32
|
+
req =mk_request(TRP::Message::Command::QUERY_RESOURCES_REQUEST,
|
33
|
+
{
|
34
|
+
:resource_group => appstate(:cgguid),
|
35
|
+
:time_interval => appstate(:time_interval)
|
36
|
+
}.merge(qparams))
|
37
|
+
|
38
|
+
rows = []
|
39
|
+
|
40
|
+
get_response_zmq(@appenv.zmq_endpt,req) do |resp|
|
41
|
+
|
42
|
+
resp.resources.each do | res |
|
43
|
+
|
44
|
+
rows << [ "#{res.resource_id}",
|
45
|
+
Time.at( res.time.tv_sec).to_s(),
|
46
|
+
res.source_ip.label,
|
47
|
+
res.source_port.label,
|
48
|
+
res.destination_ip.label,
|
49
|
+
res.destination_port.label,
|
50
|
+
wrap(res.uri,50),
|
51
|
+
wrap(res.userlabel,40)
|
52
|
+
]
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
table = Terminal::Table.new(
|
58
|
+
:headings => %w(ID Time SourceIP Port DestIP Port URI Label ),
|
59
|
+
:rows => rows)
|
60
|
+
puts(table)
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module ITRP
|
2
|
+
|
3
|
+
class Cmd_resolve < Cmd
|
4
|
+
def initialize (e)
|
5
|
+
super(e)
|
6
|
+
@enabled_in_state = :counter
|
7
|
+
@attach_cmd = ''
|
8
|
+
@trigger = 'resolve'
|
9
|
+
end
|
10
|
+
|
11
|
+
def enter(cmdline)
|
12
|
+
|
13
|
+
patt = cmdline.scan(/resolve\s+(\S*)/).flatten.first
|
14
|
+
|
15
|
+
patt.split(',')
|
16
|
+
|
17
|
+
req =mk_request(TRP::Message::Command::KEY_LOOKUP_REQUEST,
|
18
|
+
:counter_group => appstate(:cgguid),
|
19
|
+
:keys => patt.split(','))
|
20
|
+
|
21
|
+
|
22
|
+
rows = []
|
23
|
+
get_response_zmq(@appenv.zmq_endpt,req) do |resp|
|
24
|
+
resp.keys.each do |k|
|
25
|
+
rows << [ k.key, k.label, k.readable ]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
table = Terminal::Table.new( :headings => %w(Key Label Readable ), :rows => rows)
|
30
|
+
puts(table)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module ITRP
|
2
|
+
|
3
|
+
class Cmd_resource < Cmd
|
4
|
+
def initialize (e)
|
5
|
+
super(e)
|
6
|
+
@enabled_in_state = :any
|
7
|
+
@attach_cmd = 'set'
|
8
|
+
@trigger = 'resource'
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
def completions(patt)
|
13
|
+
[ "HTTP URIs {4EF9DEB9-4332-4867-A667-6A30C5900E9E} ",
|
14
|
+
"DNS Resources {D1E27FF0-6D66-4E57-BB91-99F76BB2143E} ",
|
15
|
+
"SSL Certs {5AEE3F0B-9304-44BE-BBD0-0467052CF468} ",
|
16
|
+
].grep( /#{Regexp.escape(patt)}/i)
|
17
|
+
end
|
18
|
+
|
19
|
+
def enter(s)
|
20
|
+
patt = s.scan(/set\s+resource\s+(.*)\s+({.*}$)/).flatten
|
21
|
+
patt[0].strip!
|
22
|
+
print("\nContext set to resource group [#{patt[0]}] [#{patt[1]}]\n\n")
|
23
|
+
@appenv.prompt = "iTRP R:(#{patt[0]})> "
|
24
|
+
@appenv.context_data[:cgguid] = patt[1]
|
25
|
+
@appenv.context_data[:cgname] = patt[0]
|
26
|
+
@appenv.context = :resource
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/lib/handlers/set.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module ITRP
|
2
|
+
|
3
|
+
class Cmd_set < Cmd
|
4
|
+
def initialize (e)
|
5
|
+
super(e)
|
6
|
+
@enabled_in_state = :any
|
7
|
+
@attach_cmd = ''
|
8
|
+
@trigger = 'set'
|
9
|
+
end
|
10
|
+
|
11
|
+
def enter(cmdline)
|
12
|
+
print("\nCurrent state\n")
|
13
|
+
print_state
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Cmd_reset < Cmd
|
18
|
+
def initialize (e)
|
19
|
+
super(e)
|
20
|
+
@enabled_in_state = :any
|
21
|
+
@attach_cmd = ''
|
22
|
+
@trigger = 'reset'
|
23
|
+
end
|
24
|
+
|
25
|
+
def enter(cmdline)
|
26
|
+
@appenv.prompt = "iTRP> "
|
27
|
+
@appenv.context = :any
|
28
|
+
print_state
|
29
|
+
print("\nReset state OK\n")
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ITRP
|
2
|
+
|
3
|
+
class Cmd_timeslices < Cmd
|
4
|
+
def initialize (e)
|
5
|
+
super(e)
|
6
|
+
@enabled_in_state = :any
|
7
|
+
@attach_cmd = ''
|
8
|
+
@trigger = 'timeslices'
|
9
|
+
end
|
10
|
+
|
11
|
+
def enter(cmdline)
|
12
|
+
|
13
|
+
req =mk_request(TRP::Message::Command::TIMESLICES_REQUEST,{:context=>0})
|
14
|
+
|
15
|
+
rows = []
|
16
|
+
|
17
|
+
get_response_zmq(@appenv.zmq_endpt,req) do |resp|
|
18
|
+
resp.slices.each do | window |
|
19
|
+
rows << [ Time.at(window.from.tv_sec), Time.at(window.to.tv_sec) ]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
table = Terminal::Table.new(
|
24
|
+
:headings => %w(From To),
|
25
|
+
:rows => rows)
|
26
|
+
puts(table)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module ITRP
|
2
|
+
|
3
|
+
class Cmd_toppers < Cmd
|
4
|
+
def initialize (e)
|
5
|
+
super(e)
|
6
|
+
@enabled_in_state = :counter
|
7
|
+
@attach_cmd = ''
|
8
|
+
@trigger = 'toppers'
|
9
|
+
end
|
10
|
+
|
11
|
+
def enter(cmdline)
|
12
|
+
|
13
|
+
patt = cmdline.scan(/toppers ([0-9]+)/).flatten.first
|
14
|
+
|
15
|
+
req =TrisulRP::Protocol.mk_request(TRP::Message::Command::COUNTER_GROUP_REQUEST,
|
16
|
+
:counter_group => @appenv.context_data[:cgguid],
|
17
|
+
:meter => patt.to_i,
|
18
|
+
:resolve_keys => true,
|
19
|
+
:time_interval => mk_time_interval(@appenv.context_data[:time_window]))
|
20
|
+
|
21
|
+
TrisulRP::Protocol.get_response_zmq(@appenv.zmq_endpt,req) do |resp|
|
22
|
+
print "Counter Group = #{resp.counter_group}\n"
|
23
|
+
print "Meter = #{resp.meter}\n"
|
24
|
+
|
25
|
+
rows = []
|
26
|
+
resp.keys.each do |key|
|
27
|
+
rows << [ key.key,
|
28
|
+
key.label,
|
29
|
+
key.readable,
|
30
|
+
key.metric ]
|
31
|
+
end
|
32
|
+
|
33
|
+
table = Terminal::Table.new :headings => ["Key", "Label", "Readable", "Metric"], :rows => rows
|
34
|
+
puts(table)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module ITRP
|
2
|
+
|
3
|
+
class Cmd_flow_trackers < Cmd
|
4
|
+
def initialize (e)
|
5
|
+
super(e)
|
6
|
+
@enabled_in_state = :flow
|
7
|
+
@attach_cmd = ''
|
8
|
+
@trigger = 'tracker'
|
9
|
+
end
|
10
|
+
|
11
|
+
def enter(cmdline)
|
12
|
+
|
13
|
+
patt = cmdline.scan(/tracker\s+([0-9]+)/).flatten.first
|
14
|
+
|
15
|
+
req =TrisulRP::Protocol.mk_request(TRP::Message::Command::SESSION_TRACKER_REQUEST,
|
16
|
+
:session_group => appstate(:cgguid),
|
17
|
+
:time_interval => appstate(:time_interval),
|
18
|
+
:resolve_keys => true,
|
19
|
+
:tracker_id => patt.to_i)
|
20
|
+
|
21
|
+
rows = []
|
22
|
+
TrisulRP::Protocol.get_response_zmq(@appenv.zmq_endpt,req) do |resp|
|
23
|
+
|
24
|
+
resp.sessions.each do | sess |
|
25
|
+
|
26
|
+
rows << [ "#{sess.session_key}",
|
27
|
+
Time.at( sess.time_interval.from.tv_sec).to_s(),
|
28
|
+
sess.protocol.label,
|
29
|
+
sess.key1A.label,
|
30
|
+
sess.key1Z.label,
|
31
|
+
sess.key2A.label,
|
32
|
+
sess.key2Z.label,
|
33
|
+
sess.tracker_statval
|
34
|
+
]
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
table = Terminal::Table.new(
|
40
|
+
:headings => %w(Key Last-Seen Prot SourceIP DestIP SPort DPort TrackerVal),
|
41
|
+
:rows => rows)
|
42
|
+
puts(table)
|
43
|
+
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module ITRP
|
2
|
+
|
3
|
+
class Cmd_traffic < Cmd
|
4
|
+
def initialize (e)
|
5
|
+
super(e)
|
6
|
+
@enabled_in_state = :counter
|
7
|
+
@attach_cmd = ''
|
8
|
+
@trigger = 'traffic'
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
def enter(cmdline)
|
14
|
+
|
15
|
+
patt = cmdline.scan(/traffic (.*)/).flatten.first
|
16
|
+
patt ||= "0"
|
17
|
+
showmeters = patt.split(',').map(&:to_i)
|
18
|
+
|
19
|
+
# meter names
|
20
|
+
req =mk_request(TRP::Message::Command::COUNTER_GROUP_INFO_REQUEST,
|
21
|
+
:counter_group => @appenv.context_data[:cgguid],
|
22
|
+
:get_meter_info => true )
|
23
|
+
|
24
|
+
colnames = ["Timestamp"]
|
25
|
+
get_response_zmq(@appenv.zmq_endpt,req) do |resp|
|
26
|
+
resp.group_details.each do |group_detail|
|
27
|
+
group_detail.meters.each do |meter|
|
28
|
+
colnames << meter.name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
req =TrisulRP::Protocol.mk_request(TRP::Message::Command::COUNTER_ITEM_REQUEST,
|
35
|
+
:counter_group => @appenv.context_data[:cgguid],
|
36
|
+
:key => @appenv.context_data[:cgkey],
|
37
|
+
:time_interval => mk_time_interval(@appenv.context_data[:time_window]) )
|
38
|
+
|
39
|
+
rows = []
|
40
|
+
|
41
|
+
|
42
|
+
TrisulRP::Protocol.get_response_zmq(@appenv.zmq_endpt,req) do |resp|
|
43
|
+
print "Counter Group = #{resp.stats.counter_group}\n"
|
44
|
+
print "Key = #{resp.stats.key}\n"
|
45
|
+
|
46
|
+
tseries = {}
|
47
|
+
resp.stats.meters.each do |meter|
|
48
|
+
meter.values.each do |val|
|
49
|
+
tseries[ val.ts.tv_sec ] ||= []
|
50
|
+
tseries[ val.ts.tv_sec ] << val.val
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
rows = []
|
56
|
+
tseries.each do |ts,valarr|
|
57
|
+
rows << [ ts, valarr ].flatten
|
58
|
+
end
|
59
|
+
|
60
|
+
table = Terminal::Table.new(:headings => colnames, :rows => rows )
|
61
|
+
puts(table)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
data/lib/itrp.rb
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
# Trisul Remote Protocol iTRP (Interactive TRP)
|
2
|
+
#
|
3
|
+
# NSM (Network Security & Traffic Monitoring) Console App
|
4
|
+
#
|
5
|
+
# Full interactive shell app (Work in Progress)
|
6
|
+
#
|
7
|
+
# ruby itrp.rb tcp://192.168.1.8:5555
|
8
|
+
#
|
9
|
+
#
|
10
|
+
require 'trisulrp'
|
11
|
+
require 'readline'
|
12
|
+
require 'fileutils'
|
13
|
+
|
14
|
+
require_relative 'cmd_base'
|
15
|
+
require_relative 'cmd_root'
|
16
|
+
|
17
|
+
# Check arguments
|
18
|
+
raise %q{
|
19
|
+
itrp.rb - interactive TRP shell
|
20
|
+
|
21
|
+
Usage : itrp.rb trisul-zmq-endpt
|
22
|
+
Example : itrp.rb tcp://192.168.1.8:5555
|
23
|
+
} unless ARGV.length==1
|
24
|
+
|
25
|
+
HISTFILE=File.expand_path("~/.itrp_history")
|
26
|
+
DEFAULT_PROMPT="iTRP> "
|
27
|
+
|
28
|
+
class ITRPEnv
|
29
|
+
attr_accessor :prompt
|
30
|
+
attr_accessor :context
|
31
|
+
attr_accessor :context_data
|
32
|
+
attr_accessor :zmq_endpt
|
33
|
+
end
|
34
|
+
Appenv = ITRPEnv.new
|
35
|
+
Appenv.prompt = DEFAULT_PROMPT
|
36
|
+
Appenv.zmq_endpt = ARGV.shift
|
37
|
+
Appenv.context = :any
|
38
|
+
Appenv.context_data = { }
|
39
|
+
|
40
|
+
|
41
|
+
print("\n\niTRP Interactive TRP Shell for Trisul\n");
|
42
|
+
|
43
|
+
class Dispatches
|
44
|
+
|
45
|
+
def initialize()
|
46
|
+
|
47
|
+
# load handlers
|
48
|
+
reload
|
49
|
+
|
50
|
+
# root proc
|
51
|
+
@cmd_roots = { :any => ITRP::Cmd_root.new(Appenv) }
|
52
|
+
@cmd_roots[:any].set_time_window
|
53
|
+
|
54
|
+
|
55
|
+
# build command tree
|
56
|
+
(ITRP::constants-[:Cmd, :Cmd_root]).each do |k|
|
57
|
+
kls = ITRP::const_get(k)
|
58
|
+
ins = kls.new(Appenv)
|
59
|
+
@cmd_roots[ins.enabled_in_state] ||= ITRP::Cmd_root.new(Appenv)
|
60
|
+
@cmd_roots[ins.enabled_in_state].place_node(ins)
|
61
|
+
end
|
62
|
+
|
63
|
+
# hook up autocompletion
|
64
|
+
Readline.completion_proc = proc do |s|
|
65
|
+
buff = Readline.line_buffer()
|
66
|
+
|
67
|
+
[Appenv.context, :any].uniq.collect do |ctx|
|
68
|
+
node = @cmd_roots[ctx].find_node(buff.split(' '))
|
69
|
+
(node or @cmd_roots[:any]).completions(s)
|
70
|
+
end.flatten
|
71
|
+
end
|
72
|
+
|
73
|
+
# history load
|
74
|
+
if File.exist? HISTFILE
|
75
|
+
File.readlines(HISTFILE).each do |l|
|
76
|
+
Readline::HISTORY.push(l.chop)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
def invoke(cmdline)
|
82
|
+
# system commands
|
83
|
+
case cmdline.scan(/(\w+)/).flatten.first
|
84
|
+
when 'reload' ; reload
|
85
|
+
when 'quit' ; quit
|
86
|
+
when 'help' ; help
|
87
|
+
when 'clear' ; system("clear")
|
88
|
+
else;
|
89
|
+
end
|
90
|
+
|
91
|
+
# dispatch to correct plugin w/ context
|
92
|
+
[Appenv.context, :any].uniq.collect do |ctx|
|
93
|
+
node = @cmd_roots[ctx].find_node(cmdline.strip.split(' '))
|
94
|
+
node.enter(cmdline.strip) and return if node
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def reload
|
99
|
+
print("Loading command handlers ")
|
100
|
+
Dir.glob("handlers/*rb") do |f|
|
101
|
+
load(f)
|
102
|
+
print('.')
|
103
|
+
end
|
104
|
+
print("done\n")
|
105
|
+
end
|
106
|
+
|
107
|
+
def help
|
108
|
+
@cmd_roots.each do |k,v|
|
109
|
+
print "Context :#{k}\n"
|
110
|
+
v.treeprint
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def quit
|
115
|
+
|
116
|
+
File.open( HISTFILE, "w") do |h|
|
117
|
+
Readline::HISTORY.to_a.uniq.each do |l|
|
118
|
+
h.write(l + "\n" )
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
exit 0
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
dispatches = Dispatches.new()
|
130
|
+
while cmd = Readline.readline(Appenv.prompt, true)
|
131
|
+
begin
|
132
|
+
dispatches.invoke(cmd)
|
133
|
+
Readline::HISTORY.push(cmd)
|
134
|
+
rescue Exception => e
|
135
|
+
if e.message == 'exit' ; exit; end
|
136
|
+
puts "Error " + e.message
|
137
|
+
puts "Error " + e.backtrace.join('\n')
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|