itrp 0.1.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/.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
|
+
|