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.
@@ -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
+