itrp 0.1.0

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