rbkb 0.6.10
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.
- data/History.txt +74 -0
- data/README.rdoc +149 -0
- data/Rakefile +47 -0
- data/bin/b64 +5 -0
- data/bin/bgrep +5 -0
- data/bin/blit +5 -0
- data/bin/c +5 -0
- data/bin/crc32 +5 -0
- data/bin/d64 +5 -0
- data/bin/dedump +5 -0
- data/bin/feed +5 -0
- data/bin/hexify +5 -0
- data/bin/len +5 -0
- data/bin/plugsrv +271 -0
- data/bin/rex +10 -0
- data/bin/rstrings +5 -0
- data/bin/slice +5 -0
- data/bin/telson +5 -0
- data/bin/unhexify +5 -0
- data/bin/urldec +5 -0
- data/bin/urlenc +5 -0
- data/bin/xor +5 -0
- data/cli_usage.rdoc +285 -0
- data/doctor-bag.jpg +0 -0
- data/lib/rbkb.rb +51 -0
- data/lib/rbkb/cli.rb +219 -0
- data/lib/rbkb/cli/b64.rb +35 -0
- data/lib/rbkb/cli/bgrep.rb +86 -0
- data/lib/rbkb/cli/blit.rb +89 -0
- data/lib/rbkb/cli/chars.rb +24 -0
- data/lib/rbkb/cli/crc32.rb +35 -0
- data/lib/rbkb/cli/d64.rb +28 -0
- data/lib/rbkb/cli/dedump.rb +52 -0
- data/lib/rbkb/cli/feed.rb +229 -0
- data/lib/rbkb/cli/hexify.rb +65 -0
- data/lib/rbkb/cli/len.rb +76 -0
- data/lib/rbkb/cli/rstrings.rb +108 -0
- data/lib/rbkb/cli/slice.rb +47 -0
- data/lib/rbkb/cli/telson.rb +87 -0
- data/lib/rbkb/cli/unhexify.rb +50 -0
- data/lib/rbkb/cli/urldec.rb +35 -0
- data/lib/rbkb/cli/urlenc.rb +35 -0
- data/lib/rbkb/cli/xor.rb +43 -0
- data/lib/rbkb/extends.rb +725 -0
- data/lib/rbkb/http.rb +21 -0
- data/lib/rbkb/http/base.rb +172 -0
- data/lib/rbkb/http/body.rb +214 -0
- data/lib/rbkb/http/common.rb +74 -0
- data/lib/rbkb/http/headers.rb +370 -0
- data/lib/rbkb/http/parameters.rb +104 -0
- data/lib/rbkb/http/request.rb +58 -0
- data/lib/rbkb/http/response.rb +86 -0
- data/lib/rbkb/plug.rb +9 -0
- data/lib/rbkb/plug/blit.rb +222 -0
- data/lib/rbkb/plug/cli.rb +83 -0
- data/lib/rbkb/plug/feed_import.rb +74 -0
- data/lib/rbkb/plug/peer.rb +67 -0
- data/lib/rbkb/plug/plug.rb +215 -0
- data/lib/rbkb/plug/proxy.rb +26 -0
- data/lib/rbkb/plug/unix_domain.rb +75 -0
- data/lib_usage.rdoc +176 -0
- data/rbkb.gemspec +38 -0
- data/spec/rbkb_spec.rb +7 -0
- data/spec/spec_helper.rb +16 -0
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +292 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- data/test/test_cli_b64.rb +35 -0
- data/test/test_cli_bgrep.rb +137 -0
- data/test/test_cli_blit.rb +11 -0
- data/test/test_cli_chars.rb +21 -0
- data/test/test_cli_crc32.rb +108 -0
- data/test/test_cli_d64.rb +22 -0
- data/test/test_cli_dedump.rb +118 -0
- data/test/test_cli_feed.rb +11 -0
- data/test/test_cli_helper.rb +96 -0
- data/test/test_cli_hexify.rb +63 -0
- data/test/test_cli_len.rb +96 -0
- data/test/test_cli_rstrings.rb +15 -0
- data/test/test_cli_slice.rb +73 -0
- data/test/test_cli_telson.rb +11 -0
- data/test/test_cli_unhexify.rb +43 -0
- data/test/test_cli_urldec.rb +50 -0
- data/test/test_cli_urlenc.rb +44 -0
- data/test/test_cli_xor.rb +71 -0
- data/test/test_helper.rb +5 -0
- data/test/test_http.rb +27 -0
- data/test/test_http_helper.rb +60 -0
- data/test/test_http_request.rb +136 -0
- data/test/test_http_response.rb +222 -0
- data/test/test_rbkb.rb +19 -0
- metadata +238 -0
data/lib/rbkb/cli/b64.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rbkb/cli'
|
2
|
+
|
3
|
+
# Copyright 2009 emonti at matasano.com
|
4
|
+
# See README.rdoc for license information
|
5
|
+
#
|
6
|
+
# b64 converts strings or raw data to base-64 encoding.
|
7
|
+
class Rbkb::Cli::B64 < Rbkb::Cli::Executable
|
8
|
+
def make_parser
|
9
|
+
super()
|
10
|
+
arg = @oparse
|
11
|
+
arg.banner += " <data | blank for stdin>"
|
12
|
+
|
13
|
+
add_std_file_opt(:indat)
|
14
|
+
|
15
|
+
arg.on("-l", "--length LEN", Numeric, "Output LEN chars per line") do |l|
|
16
|
+
bail("length must be > 0") unless l > 0
|
17
|
+
@opts[:len] = l
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def parse(*args)
|
22
|
+
super(*args)
|
23
|
+
parse_string_argument(:indat)
|
24
|
+
parse_file_argument(:indat)
|
25
|
+
parse_catchall()
|
26
|
+
@opts[:indat] ||= @stdin.read
|
27
|
+
end
|
28
|
+
|
29
|
+
def go(*args)
|
30
|
+
super(*args)
|
31
|
+
@stdout << @opts[:indat].b64(opts[:len]).chomp + "\n"
|
32
|
+
self.exit(0)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'rbkb/cli'
|
2
|
+
|
3
|
+
# Copyright 2009 emonti at matasano.com
|
4
|
+
# See README.rdoc for license information
|
5
|
+
#
|
6
|
+
# searches for a binary string in input. string can be provided 'hexified'
|
7
|
+
class Rbkb::Cli::Bgrep < Rbkb::Cli::Executable
|
8
|
+
def initialize(*args)
|
9
|
+
super(*args) do |this|
|
10
|
+
this.opts[:start_off] ||= 0
|
11
|
+
this.opts[:end_off] ||= -1
|
12
|
+
this.opts[:include_fname] ||= true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def make_parser
|
17
|
+
arg = super()
|
18
|
+
arg.banner += " <search> <file | blank for stdin>"
|
19
|
+
|
20
|
+
arg.on("-x", "--[no-]hex", "Search for hex (default: false)") do |x|
|
21
|
+
@opts[:hex] = x
|
22
|
+
end
|
23
|
+
|
24
|
+
arg.on("-r", "--[no-]regex", "Search for regex (default: false)") do |r|
|
25
|
+
@opts[:rx] = r
|
26
|
+
end
|
27
|
+
|
28
|
+
arg.on("-a", "--align=BYTES", Numeric,
|
29
|
+
"Only match on alignment boundary") do |a|
|
30
|
+
@opts[:align] = a
|
31
|
+
end
|
32
|
+
|
33
|
+
arg.on("-n", "--[no-]filename",
|
34
|
+
"Toggle filenames. (Default: #{@opts[:include_fname]})") do |n|
|
35
|
+
@opts[:include_fname] = n
|
36
|
+
end
|
37
|
+
return arg
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def parse(*args)
|
42
|
+
super(*args)
|
43
|
+
|
44
|
+
bail "need search argument" unless @find = @argv.shift
|
45
|
+
|
46
|
+
if @opts[:hex] and @opts[:rx]
|
47
|
+
bail "-r and -x are mutually exclusive"
|
48
|
+
end
|
49
|
+
|
50
|
+
# ... filenames vs. stdin will be parsed in 'go'
|
51
|
+
end
|
52
|
+
|
53
|
+
def go(*args)
|
54
|
+
super(*args)
|
55
|
+
|
56
|
+
if @opts[:hex]
|
57
|
+
bail "you specified -x for hex and the subject isn't" unless @find.ishex?
|
58
|
+
@find = @find.unhexify
|
59
|
+
elsif @opts[:rx]
|
60
|
+
@find = Regexp.new(@find, Regexp::MULTILINE)
|
61
|
+
end
|
62
|
+
|
63
|
+
if fname = @argv.shift
|
64
|
+
dat = do_file_read(fname)
|
65
|
+
fname = nil unless @argv[0] # only print filenames for multiple files
|
66
|
+
else
|
67
|
+
dat = @stdin.read
|
68
|
+
end
|
69
|
+
|
70
|
+
loop do
|
71
|
+
dat.bgrep(@find, @opts[:align]) do |hit_start, hit_end, match|
|
72
|
+
@stdout.write "#{fname}:" if fname and @opts[:include_fname]
|
73
|
+
|
74
|
+
@stdout.write(
|
75
|
+
"#{(hit_start).to_hex.rjust(8,"0")}:"+
|
76
|
+
"#{(hit_end).to_hex.rjust(8,"0")}:b:"+
|
77
|
+
"#{match.inspect}\n")
|
78
|
+
end
|
79
|
+
|
80
|
+
break unless fname=@argv.shift
|
81
|
+
dat = do_file_read(fname)
|
82
|
+
end
|
83
|
+
self.exit(0)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'rbkb/cli'
|
2
|
+
require 'rbkb/plug'
|
3
|
+
|
4
|
+
# Copyright 2009 emonti at matasano.com
|
5
|
+
# See README.rdoc for license information
|
6
|
+
#
|
7
|
+
# blit is for use with any of the "plug" tools such as telson, feed, blitplug.
|
8
|
+
# It is used to send data over a socket via their OOB blit listener.
|
9
|
+
class Rbkb::Cli::Blit < Rbkb::Cli::Executable
|
10
|
+
attr_accessor :blit_msg
|
11
|
+
|
12
|
+
def initialize(*args)
|
13
|
+
super(*args)
|
14
|
+
{
|
15
|
+
:b_addr => Plug::Blit::DEFAULT_IPADDR,
|
16
|
+
:b_port => Plug::Blit::DEFAULT_PORT,
|
17
|
+
:bp_proto => :TCP,
|
18
|
+
:b_peeridx => 0,
|
19
|
+
}.each {|k, v| @opts[k] ||= v}
|
20
|
+
end
|
21
|
+
|
22
|
+
def make_parser()
|
23
|
+
super()
|
24
|
+
add_std_file_opt(:indat)
|
25
|
+
arg = @oparse
|
26
|
+
|
27
|
+
arg.banner += " <data | blank for stdin>"
|
28
|
+
|
29
|
+
arg.on("-t", "--trans-protocol=PROTO",
|
30
|
+
"Blit transport protocol TCP/UDP") do |t|
|
31
|
+
@opts[:b_proto] = t.upcase.to_sym
|
32
|
+
end
|
33
|
+
|
34
|
+
arg.on("-b", "--blitsrv=ADDR:PORT",
|
35
|
+
"Where to send blit messages") do |b|
|
36
|
+
|
37
|
+
unless(m=/^(?:([\w\.]+):)?(\d+)$/.match(b))
|
38
|
+
bail "invalid blit address/port"
|
39
|
+
end
|
40
|
+
@opts[:b_port] = m[2].to_i
|
41
|
+
@opts[:b_port] = m[1] if m[1]
|
42
|
+
end
|
43
|
+
|
44
|
+
arg.on("-i", "--peer-index=IDX", Numeric,
|
45
|
+
"Index for remote peer to receive") do |i|
|
46
|
+
@opts[:b_peeridx] = i
|
47
|
+
end
|
48
|
+
|
49
|
+
arg.on("-l", "--list-peers", "Lists the peer array for the target") do
|
50
|
+
@blit_msg = Plug::Blit.make_list_peers
|
51
|
+
end
|
52
|
+
|
53
|
+
arg.on("-k", "--kill", "Stops the remote event loop.") do
|
54
|
+
@blit_msg = Plug::Blit.make_kill
|
55
|
+
end
|
56
|
+
|
57
|
+
return arg
|
58
|
+
end
|
59
|
+
|
60
|
+
def parse(*args)
|
61
|
+
super(*args)
|
62
|
+
|
63
|
+
unless @blit_msg
|
64
|
+
if @opts[:indat].nil?
|
65
|
+
@opts[:indat] = (@argv.length > 0)? @argv.join(" ") : @stdin.read()
|
66
|
+
end
|
67
|
+
@blit_msg = Plug::Blit.make_sendmsg(@opts[:b_peeridx], @opts[:indat])
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def go(*args)
|
72
|
+
super(*args)
|
73
|
+
|
74
|
+
begin
|
75
|
+
Plug::Blit.blit_init(
|
76
|
+
:addr => @opts[:b_addr],
|
77
|
+
:port => @opts[:b_port],
|
78
|
+
:protocol => @opts[:b_proto]
|
79
|
+
)
|
80
|
+
|
81
|
+
Plug::Blit.blit_raw(@blit_msg)
|
82
|
+
rescue
|
83
|
+
bail($!)
|
84
|
+
end
|
85
|
+
|
86
|
+
self.exit(0)
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rbkb/cli'
|
2
|
+
|
3
|
+
# Copyright 2009 emonti at matasano.com
|
4
|
+
# See README.rdoc for license information
|
5
|
+
#
|
6
|
+
# Repeats an argument N times
|
7
|
+
class Rbkb::Cli::Chars < Rbkb::Cli::Executable
|
8
|
+
def make_parser
|
9
|
+
super()
|
10
|
+
@oparse.banner += " 100 A; # print 100 A's"
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse(*args)
|
14
|
+
super(*args)
|
15
|
+
bail_args @argv.join(' ') unless @argv.size == 2
|
16
|
+
end
|
17
|
+
|
18
|
+
def go(*args)
|
19
|
+
super(*args)
|
20
|
+
@stdout << @argv[1] * @argv[0].to_i
|
21
|
+
self.exit(0)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rbkb/cli'
|
2
|
+
|
3
|
+
# Copyright 2009 emonti at matasano.com
|
4
|
+
# See README.rdoc for license information
|
5
|
+
#
|
6
|
+
# crc32 returns a crc32 checksum in hex from stdin or a file
|
7
|
+
class Rbkb::Cli::Crc32 < Rbkb::Cli::Executable
|
8
|
+
def initialize(*args)
|
9
|
+
super(*args)
|
10
|
+
@opts[:first] ||= 0
|
11
|
+
@opts[:last] ||= -1
|
12
|
+
end
|
13
|
+
|
14
|
+
def make_parser()
|
15
|
+
arg = super()
|
16
|
+
arg.banner += " [filename]"
|
17
|
+
add_std_file_opt(:indat)
|
18
|
+
add_range_opts(:first, :last)
|
19
|
+
end
|
20
|
+
|
21
|
+
def parse(*args)
|
22
|
+
super(*args)
|
23
|
+
parse_file_argument(:indat)
|
24
|
+
parse_catchall()
|
25
|
+
end
|
26
|
+
|
27
|
+
def go(*args)
|
28
|
+
super(*args)
|
29
|
+
@opts[:indat] ||= @stdin.read()
|
30
|
+
@stdout.puts @opts[:indat][ @opts[:first] .. @opts[:last] ].crc32.to_hex
|
31
|
+
self.exit(0)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
data/lib/rbkb/cli/d64.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rbkb/cli'
|
2
|
+
|
3
|
+
# Copyright 2009 emonti at matasano.com
|
4
|
+
# See README.rdoc for license information
|
5
|
+
#
|
6
|
+
# d64 converts a base-64 encoded string back to its orginal form.
|
7
|
+
class Rbkb::Cli::D64 < Rbkb::Cli::Executable
|
8
|
+
def make_parser
|
9
|
+
super()
|
10
|
+
@oparse.banner += " <data | blank for stdin>"
|
11
|
+
add_std_file_opt(:indat)
|
12
|
+
end
|
13
|
+
|
14
|
+
def parse(*args)
|
15
|
+
super(*args)
|
16
|
+
parse_string_argument(:indat)
|
17
|
+
parse_file_argument(:indat)
|
18
|
+
parse_catchall()
|
19
|
+
@opts[:indat] ||= @stdin.read
|
20
|
+
end
|
21
|
+
|
22
|
+
def go(*args)
|
23
|
+
super(*args)
|
24
|
+
@stdout << @opts[:indat].d64
|
25
|
+
self.exit(0)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'rbkb/cli'
|
2
|
+
|
3
|
+
# Copyright 2009 emonti at matasano.com
|
4
|
+
# See README.rdoc for license information
|
5
|
+
#
|
6
|
+
# Reverses a hexdump back to raw data. Designed to work with hexdumps created
|
7
|
+
# by Unix utilities like 'xxd' as well as 'hexdump -C'.
|
8
|
+
class Rbkb::Cli::Dedump < Rbkb::Cli::Executable
|
9
|
+
def initialize(*args)
|
10
|
+
super(*args) {|this|
|
11
|
+
this.opts[:len] ||= 16
|
12
|
+
yield this if block_given?
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def make_parser()
|
17
|
+
arg = super()
|
18
|
+
arg.banner += " <input-file | blank for stdin>"
|
19
|
+
|
20
|
+
arg.on("-l", "--length LEN", Numeric,
|
21
|
+
"Bytes per line in hexdump (Default: #{@opts[:len]})") do |l|
|
22
|
+
bail("Length must be greater than zero") unless (@opts[:len] = l) > 0
|
23
|
+
end
|
24
|
+
return arg
|
25
|
+
end
|
26
|
+
|
27
|
+
def parse(*args)
|
28
|
+
super(*args)
|
29
|
+
parse_file_argument(:indat)
|
30
|
+
parse_catchall()
|
31
|
+
end
|
32
|
+
|
33
|
+
def go(*args)
|
34
|
+
super(*args)
|
35
|
+
|
36
|
+
# Default to standard input
|
37
|
+
@opts[:indat] ||= @stdin.read()
|
38
|
+
|
39
|
+
self.exit(1) unless((@opts[:len] ||= @opts[:indat].length) > 0)
|
40
|
+
|
41
|
+
begin
|
42
|
+
@opts[:indat].dehexdump( :len => @opts[:len], :out => @stdout)
|
43
|
+
rescue
|
44
|
+
bail "Error: #{$!}"
|
45
|
+
end
|
46
|
+
|
47
|
+
self.exit(0)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
|
@@ -0,0 +1,229 @@
|
|
1
|
+
require 'rbkb/cli'
|
2
|
+
require 'rbkb/plug'
|
3
|
+
require 'rbkb/plug/feed_import'
|
4
|
+
require 'eventmachine'
|
5
|
+
|
6
|
+
# Copyright 2009 emonti at moatasano dot com
|
7
|
+
# See README.rdoc for license information
|
8
|
+
#
|
9
|
+
# This is a plug-board message feeder from static data sources.
|
10
|
+
# The "feed" handles messages opaquely and just plays them in the given
|
11
|
+
# sequence.
|
12
|
+
#
|
13
|
+
# Feed can do the following things with minimum fuss:
|
14
|
+
# - Import messages from files, yaml, or pcap
|
15
|
+
# - Inject custom/modified messages with "blit"
|
16
|
+
# - Run as a server or client using UDP or TCP
|
17
|
+
# - Bootstrap protocols without a lot of work up front
|
18
|
+
# - Skip uninteresting messages and focus attention on the fun ones.
|
19
|
+
# - Replay conversations for relatively unfamiliar protocols.
|
20
|
+
# - Observe client/server behaviors using different messages at
|
21
|
+
# various phases of a conversation.
|
22
|
+
#
|
23
|
+
# To-dos / Ideas:
|
24
|
+
# - Unix Domain Socket support?
|
25
|
+
# - more import options?
|
26
|
+
# - dynamic feed elements?
|
27
|
+
# - add/control feed elements while 'stepping'?
|
28
|
+
#
|
29
|
+
|
30
|
+
class Rbkb::Cli::Feed < Rbkb::Cli::Executable
|
31
|
+
def initialize(*args)
|
32
|
+
@local_addr = "0.0.0.0"
|
33
|
+
@local_port = nil
|
34
|
+
@listen = false
|
35
|
+
@persist = false
|
36
|
+
@transport = :TCP
|
37
|
+
@svr_method = :start_server
|
38
|
+
@cli_method = :bind_connect
|
39
|
+
@blit_addr = Plug::Blit::DEFAULT_IPADDR
|
40
|
+
@blit_port = Plug::Blit::DEFAULT_PORT
|
41
|
+
|
42
|
+
|
43
|
+
## Default options sent to the Feed handler
|
44
|
+
@feed_opts = {
|
45
|
+
:close_at_end => false,
|
46
|
+
:step => false,
|
47
|
+
:go_first => false
|
48
|
+
}
|
49
|
+
|
50
|
+
super(*args)
|
51
|
+
|
52
|
+
# TODO Plug::UI obviously need fixing.
|
53
|
+
# TODO It shouldn't be driven by constants for configuration
|
54
|
+
Plug::UI::LOGCFG[:verbose] = true
|
55
|
+
Plug::UI::LOGCFG[:dump] = :hex
|
56
|
+
Plug::UI::LOGCFG[:out] = @stderr
|
57
|
+
end
|
58
|
+
|
59
|
+
def make_parser()
|
60
|
+
arg = super()
|
61
|
+
arg.banner += " host:port"
|
62
|
+
|
63
|
+
arg.on("-o", "--output=FILE", "Output to file") do |o|
|
64
|
+
Plug::UI::LOGCFG[:out] = File.open(o, "w")
|
65
|
+
end
|
66
|
+
|
67
|
+
arg.on("-l", "--listen=(ADDR:?)PORT", "Server - on port (and addr?)") do |p|
|
68
|
+
if m=/^(?:([\w\._-]+):)?(\d+)$/.match(p)
|
69
|
+
@local_addr = $1 if $1
|
70
|
+
@local_port = $2.to_i
|
71
|
+
@listen = true
|
72
|
+
else
|
73
|
+
raise "Invalid listen argument: #{p.inspect}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
arg.on("-s", "--source=(ADDR:?)PORT", "Bind client on port and addr") do |p|
|
78
|
+
if m=/^(?:([\w\.]+):)?(\d+)$/.match(p)
|
79
|
+
@local_addr = $1 if $1
|
80
|
+
@local_port = $2.to_i
|
81
|
+
else
|
82
|
+
bail("Invalid source argument: #{p.inspect}")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
arg.on("-b", "--blit=(ADDR:)?PORT", "Where to listen for blit") do |b|
|
87
|
+
puts b
|
88
|
+
unless(m=/^(?:([\w\._-]+):)?(\d+)$/.match(b))
|
89
|
+
raise "Invalid blit argument: #{b.inspect}"
|
90
|
+
end
|
91
|
+
@blit_port = m[2].to_i
|
92
|
+
@blit_addr = m[1] if m[1]
|
93
|
+
end
|
94
|
+
|
95
|
+
arg.on("-i", "--[no-]initiate", "Send the first message on connect") do |i|
|
96
|
+
@feed_opts[:go_first] = i
|
97
|
+
end
|
98
|
+
|
99
|
+
arg.on("-e", "--[no-]end", "End connection when feed is exhausted") do |c|
|
100
|
+
@feed_opts[:close_at_end] = c
|
101
|
+
end
|
102
|
+
|
103
|
+
arg.on("--[no-]step", "'Continue' prompt between messages") do |s|
|
104
|
+
@feed_opts[:step] = s
|
105
|
+
end
|
106
|
+
|
107
|
+
arg.on("-u", "--udp", "Use UDP instead of TCP" ) do
|
108
|
+
@transport = :UDP
|
109
|
+
end
|
110
|
+
|
111
|
+
arg.on("-r", "--reconnect", "Attempt to reconnect endlessly.") do
|
112
|
+
@persist=true
|
113
|
+
end
|
114
|
+
|
115
|
+
arg.on("-q", "--quiet", "Suppress verbose messages/dumps") do
|
116
|
+
Plug::UI::LOGCFG[:verbose] = false
|
117
|
+
end
|
118
|
+
|
119
|
+
arg.on("-Q", "--squelch-exhausted", "Squelch 'FEED EXHAUSTED' messages") do |s|
|
120
|
+
@feed_opts[:squelch_exhausted] = true
|
121
|
+
end
|
122
|
+
|
123
|
+
arg.separator " Sources: (can be combined)"
|
124
|
+
|
125
|
+
arg.on("-f", "--from-files=GLOB", "Import messages from raw files") do |f|
|
126
|
+
@feed_opts[:feed] ||= []
|
127
|
+
@feed_opts[:feed] += FeedImport.import_rawfiles(f)
|
128
|
+
end
|
129
|
+
|
130
|
+
arg.on("-x", "--from-hex=FILE", "Import messages from hexdumps") do |x|
|
131
|
+
@feed_opts[:feed] ||= []
|
132
|
+
@feed_opts[:feed] += FeedImport.import_dump(x)
|
133
|
+
end
|
134
|
+
|
135
|
+
arg.on("-y", "--from-yaml=FILE", "Import messages from yaml") do |y|
|
136
|
+
@feed_opts[:feed] ||= []
|
137
|
+
@feed_opts[:feed] += FeedImport.import_yaml(y)
|
138
|
+
end
|
139
|
+
|
140
|
+
arg.on("-p", "--from-pcap=FILE[:FILTER]", "Import messages from pcap") do |p|
|
141
|
+
if /^([^:]+):(.+)$/.match(p)
|
142
|
+
file = $1
|
143
|
+
filter = $2
|
144
|
+
else
|
145
|
+
file = p
|
146
|
+
filter = nil
|
147
|
+
end
|
148
|
+
|
149
|
+
@feed_opts[:feed] ||= []
|
150
|
+
@feed_opts[:feed] += FeedImport.import_pcap(file, filter)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def parse(*args)
|
155
|
+
super(*args)
|
156
|
+
|
157
|
+
if @transport == :UDP
|
158
|
+
@svr_method = @cli_method = :open_datagram_socket
|
159
|
+
end
|
160
|
+
|
161
|
+
@local_port ||= 0
|
162
|
+
# Prepare EventMachine arguments based on whether we are a client or server
|
163
|
+
if @listen # server
|
164
|
+
@meth = @svr_method
|
165
|
+
addr_args = [@local_addr, @local_port]
|
166
|
+
@feed_opts[:kind] = :server
|
167
|
+
@feed_opts[:no_stop_on_unbind] = true
|
168
|
+
else # client
|
169
|
+
|
170
|
+
## Get target/listen argument for client mode
|
171
|
+
unless (m = /^([\w\.]+):(\d+)$/.match(tgt=@argv.shift))
|
172
|
+
bail_args tgt
|
173
|
+
end
|
174
|
+
|
175
|
+
@target_addr = m[1]
|
176
|
+
@target_port = m[2].to_i
|
177
|
+
|
178
|
+
if @transport == :UDP
|
179
|
+
addr_args = [@local_addr, @local_port]
|
180
|
+
else
|
181
|
+
addr_args = [@local_addr, @local_port, @target_addr, @target_port]
|
182
|
+
end
|
183
|
+
|
184
|
+
@meth = @cli_method
|
185
|
+
@feed_opts[:kind] = :client
|
186
|
+
end
|
187
|
+
|
188
|
+
@feed_opts[:feed] ||= []
|
189
|
+
|
190
|
+
@em_args=[
|
191
|
+
@meth,
|
192
|
+
addr_args,
|
193
|
+
Plug::ArrayFeeder,
|
194
|
+
@transport,
|
195
|
+
@feed_opts
|
196
|
+
].flatten
|
197
|
+
|
198
|
+
parse_catchall()
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
def go(*args)
|
203
|
+
super(*args)
|
204
|
+
|
205
|
+
Plug::UI.verbose "** FEED CONTAINS #{@feed_opts[:feed].size} MESSAGES"
|
206
|
+
|
207
|
+
## Start the eventmachine
|
208
|
+
loop do
|
209
|
+
EventMachine::run do
|
210
|
+
EventMachine.send(*@em_args) do |c|
|
211
|
+
EventMachine.start_server(@blit_addr, @blit_port, Plug::Blit, :TCP, c)
|
212
|
+
Plug::UI::verbose("** BLITSRV-#{@blit_addr}:#{@blit_port}(TCP) Started")
|
213
|
+
|
214
|
+
# if this is a UDP client, we will always send the first message
|
215
|
+
if [:UDP, :client] == [@transport, c.kind]
|
216
|
+
peer = c.peers.add_peer_manually(@target_addr, @target_port)
|
217
|
+
c.feed_data(peer)
|
218
|
+
c.go_first = false
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
break unless @persist
|
224
|
+
Plug::UI::verbose("** RECONNECTING")
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|