rbkb 0.6.12 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.bnsignore +25 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +27 -0
- data/History.txt +8 -0
- data/LICENSE.txt +22 -0
- data/Rakefile +10 -45
- data/experimental/cap2files +21 -0
- data/experimental/cap2yaml +20 -0
- data/experimental/colordif.rb +72 -0
- data/experimental/deezee +91 -0
- data/experimental/feed +225 -0
- data/experimental/fmagic.rb +51 -0
- data/experimental/magicrip.c +92 -0
- data/experimental/magicripper.rb +63 -0
- data/lib/rbkb.rb +2 -48
- data/lib/rbkb/cli.rb +3 -2
- data/lib/rbkb/cli/bgrep.rb +1 -4
- data/lib/rbkb/cli/blit.rb +4 -0
- data/lib/rbkb/cli/crc32.rb +4 -1
- data/lib/rbkb/cli/dedump.rb +1 -0
- data/lib/rbkb/cli/rstrings.rb +1 -7
- data/lib/rbkb/extends.rb +8 -787
- data/lib/rbkb/extends/array.rb +29 -0
- data/lib/rbkb/extends/common.rb +13 -0
- data/lib/rbkb/extends/enumerable.rb +9 -0
- data/lib/rbkb/extends/float.rb +17 -0
- data/lib/rbkb/extends/numeric.rb +83 -0
- data/lib/rbkb/extends/object.rb +7 -0
- data/lib/rbkb/extends/string.rb +624 -0
- data/lib/rbkb/extends/symbol.rb +8 -0
- data/lib/rbkb/plug/blit.rb +21 -1
- data/lib/rbkb/plug/peer.rb +5 -0
- data/lib/rbkb/plug/plug.rb +6 -2
- data/lib/rbkb/version.rb +3 -0
- data/rbkb.gemspec +20 -34
- data/reference/blackbag-0.9.1.tgz +0 -0
- data/reference/note_http_unit_tests +3 -0
- data/spec/spec_helper.rb +5 -14
- data/spec/string_extends_spec.rb +129 -0
- data/test/{test_cli_blit.rb → disabled_test_cli_blit.rb} +0 -0
- data/test/{test_cli_feed.rb → disabled_test_cli_feed.rb} +0 -0
- data/test/{test_cli_telson.rb → disabled_test_cli_telson.rb} +0 -0
- data/test/test_cli_chars.rb +2 -0
- data/test/test_cli_helper.rb +3 -5
- data/test/test_cli_rstrings.rb +2 -0
- data/test/test_helper.rb +8 -0
- metadata +107 -89
- data/test/test_rbkb.rb +0 -19
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NmUwMGU3OGM4ZTEwZTZjMWViOTQxODg1NWNjODVmZWRhOWI1ZTY3Mg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YWIwMTg4MjliZWVjOTZjNjg3ZjQ4YWI5NTE2MTQ5ZDk1MzNhNTQwMg==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MzAwYjE4ZDEyNDdjZDZhZTJiODFkNDc5MWU0NDNhZjQ4YTM4Y2JiMzY4NWQx
|
10
|
+
MzMwMDk5MTJjNzA1OGM0ZGRhOTU3NDRiNTVhMWIzNGJlYWU5NjBjZTYwZDc4
|
11
|
+
Y2Q0ODY0YjE3NGNjOGY4ZTE3MmY0MTA3MTY0NmI2YWZiMGMzMDU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ODkwNzFkZWY2ZmQ2NzIzZWM2NWNmM2NkMDIyM2ZkYWQzNjcwYjQwZTc0NzM2
|
14
|
+
MzE2YjBhN2E4NjQ3YWU1NjkzMTY0NTg0Y2UzMzZlMjk2M2Y3ZWJmODBiZDY2
|
15
|
+
MDBhNjdiNDc2YTY3YzE2M2RjMzhjY2FkMzg5NjEwMzA1OTZjOTc=
|
data/.bnsignore
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# The list of files that should be ignored by Mr Bones.
|
2
|
+
# Lines that start with '#' are comments.
|
3
|
+
#
|
4
|
+
# A .gitignore file can be used instead by setting it as the ignore
|
5
|
+
# file in your Rakefile:
|
6
|
+
#
|
7
|
+
# PROJ.ignore_file = '.gitignore'
|
8
|
+
#
|
9
|
+
# For a project with a C extension, the following would be a good set of
|
10
|
+
# exclude patterns (uncomment them if you want to use them):
|
11
|
+
# *.[oa]
|
12
|
+
|
13
|
+
.*
|
14
|
+
*~
|
15
|
+
*.swp
|
16
|
+
.*.swp
|
17
|
+
.yardoc
|
18
|
+
announcement.txt
|
19
|
+
coverage*/
|
20
|
+
doc
|
21
|
+
pkg
|
22
|
+
bin/experimental
|
23
|
+
reference
|
24
|
+
*.gem
|
25
|
+
.DS_Store
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
rbkb (0.7.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
diff-lcs (1.2.1)
|
10
|
+
rake (10.1.0)
|
11
|
+
rspec (2.13.0)
|
12
|
+
rspec-core (~> 2.13.0)
|
13
|
+
rspec-expectations (~> 2.13.0)
|
14
|
+
rspec-mocks (~> 2.13.0)
|
15
|
+
rspec-core (2.13.1)
|
16
|
+
rspec-expectations (2.13.0)
|
17
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
18
|
+
rspec-mocks (2.13.0)
|
19
|
+
|
20
|
+
PLATFORMS
|
21
|
+
ruby
|
22
|
+
|
23
|
+
DEPENDENCIES
|
24
|
+
bundler (~> 1.3)
|
25
|
+
rake
|
26
|
+
rbkb!
|
27
|
+
rspec
|
data/History.txt
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== 0.6.14 / 2010-11-29
|
2
|
+
* Minor fixes to cli offset and integer hexification formatting
|
3
|
+
* Unit tests got some more love for ruby 1.9 unit test compatability
|
4
|
+
|
5
|
+
== 0.6.13 / 2009-10-15
|
6
|
+
* got strings working using scan() in 1.9 had to punt ':align' option for now
|
7
|
+
* Added -S (starttls) arg. to blit for initiating SSL on a plug peer
|
8
|
+
|
1
9
|
== 0.6.12 / 2009-10-15
|
2
10
|
* better ruby 1.8 <-> 1.9 portability
|
3
11
|
* tweaked rotate_bytes to "wrap" on char boundary and rotate backwards safely
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2009 Eric Monti
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
CHANGED
@@ -1,47 +1,12 @@
|
|
1
|
-
|
2
|
-
# configured in this Rakefile. The .rake files in the tasks directory
|
3
|
-
# are where the options are used.
|
1
|
+
require "bundler/gem_tasks"
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
rescue LoadError
|
9
|
-
begin
|
10
|
-
load 'tasks/setup.rb'
|
11
|
-
rescue LoadError
|
12
|
-
raise RuntimeError, '### please install the "bones" gem ###'
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
ensure_in_path 'lib'
|
17
|
-
require 'rbkb'
|
18
|
-
|
19
|
-
task :default => 'test:run'
|
20
|
-
|
21
|
-
PROJ.name = 'rbkb'
|
22
|
-
PROJ.authors = 'Eric Monti'
|
23
|
-
PROJ.email = 'emonti@matasano.com'
|
24
|
-
PROJ.description = 'Rbkb is a collection of ruby-based pen-testing and reversing tools. Inspired by Matasano Blackbag.'
|
25
|
-
PROJ.url = 'http://emonti.github.com/rbkb'
|
26
|
-
PROJ.version = Rbkb::VERSION
|
27
|
-
PROJ.rubyforge.name = 'rbkb'
|
28
|
-
PROJ.readme_file = 'README.rdoc'
|
29
|
-
|
30
|
-
PROJ.spec.opts << '--color'
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
RSpec::Core::RakeTask.new
|
5
|
+
task :default => :spec
|
31
6
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
PROJ.rcov.opts += [
|
39
|
-
"--exclude", "rcov.rb",
|
40
|
-
"--exclude", "eventmachine",
|
41
|
-
"--exclude", "pcap_misc.rb",
|
42
|
-
"--exclude", "pcaplet.rb"
|
43
|
-
]
|
44
|
-
|
45
|
-
depend_on 'eventmachine', '>= 0.12.8'
|
46
|
-
|
47
|
-
# EOF
|
7
|
+
require 'rake/testtask'
|
8
|
+
Rake::TestTask.new do |t|
|
9
|
+
t.libs << "test"
|
10
|
+
t.test_files = FileList['test/test*.rb']
|
11
|
+
t.verbose = true
|
12
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# extracts UDP/TCP data payload from packets to numbered files
|
3
|
+
# Usage: cap2files out_prefix pcap-file [filter]]
|
4
|
+
|
5
|
+
require 'rbkb/plug/feed_import'
|
6
|
+
|
7
|
+
begin
|
8
|
+
unless prefix = ARGV.shift and file = ARGV.shift
|
9
|
+
raise "Usage: #{File.basename $0} out_prefix pcap-file [filter]"
|
10
|
+
end
|
11
|
+
|
12
|
+
filter = ARGV.join(" ")
|
13
|
+
|
14
|
+
caps = FeedImport.import_pcap(file, filter)
|
15
|
+
i=0
|
16
|
+
caps.each {|p| File.open("#{prefix}.#{i}", "w") {|f| f.write p }; i+=1 }
|
17
|
+
rescue
|
18
|
+
STDERR.puts $!
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# extracts UDP/TCP data payload from packets to an array encapsulated in yaml
|
3
|
+
# Usage: cap2yaml pcap-file [filter]]
|
4
|
+
|
5
|
+
require 'rbkb/plug/feed_import'
|
6
|
+
|
7
|
+
begin
|
8
|
+
unless file = ARGV.shift
|
9
|
+
raise "Usage: #{File.basename $0} pcap-file [filter]"
|
10
|
+
end
|
11
|
+
|
12
|
+
filter = ARGV.join(" ")
|
13
|
+
|
14
|
+
caps = FeedImport.import_pcap(file, filter)
|
15
|
+
puts caps.to_yaml
|
16
|
+
rescue
|
17
|
+
STDERR.puts $!
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Sort of like vbindiff, except smaller with less functionality, and in our toolshed ;)
|
4
|
+
# Useful for encoded HTTP parameters, raw dumped pkts and other little things
|
5
|
+
# todo: print out like hexdump -C
|
6
|
+
# Chris at mtso
|
7
|
+
|
8
|
+
module ColorConstants
|
9
|
+
BLACK = "\e[1;30m"
|
10
|
+
RED = "\e[1;31m"
|
11
|
+
GREEN = "\e[1;32m"
|
12
|
+
BROWN = "\e[1;33m"
|
13
|
+
BLUE = "\e[1;34m"
|
14
|
+
PURPLE = "\e[1;35m"
|
15
|
+
CYAN = "\e[1;36m"
|
16
|
+
GRAY = "\e[1;37m"
|
17
|
+
NO_COLOR = "\e[0m"
|
18
|
+
end
|
19
|
+
|
20
|
+
class ColorDif
|
21
|
+
|
22
|
+
attr_accessor :file1, :file2
|
23
|
+
|
24
|
+
def initialize(file1, file2)
|
25
|
+
@file1 = IO.read(file1)
|
26
|
+
@file2 = IO.read(file2)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Theres definitely a more elegant way to do this, whatever ...
|
30
|
+
def diffem
|
31
|
+
puts "\nFile 1 [#{file1.size} bytes]"
|
32
|
+
puts "File 2 [#{file2.size} bytes]\n\n"
|
33
|
+
|
34
|
+
count = 0
|
35
|
+
|
36
|
+
@file1.each_byte do |byte|
|
37
|
+
if byte == @file2[count]
|
38
|
+
print sprintf(ColorConstants::BLUE + "%02x ", byte)
|
39
|
+
else
|
40
|
+
print sprintf(ColorConstants::RED + "%02x ", byte)
|
41
|
+
end
|
42
|
+
|
43
|
+
count = count+1
|
44
|
+
|
45
|
+
if count % 32 == 0
|
46
|
+
print "\n"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
puts ColorConstants::NO_COLOR + "\n---"
|
51
|
+
count = 0
|
52
|
+
|
53
|
+
@file2.each_byte do |byte|
|
54
|
+
if byte == @file1[count]
|
55
|
+
print sprintf(ColorConstants::BLUE + "%02x ", byte)
|
56
|
+
else
|
57
|
+
print sprintf(ColorConstants::RED + "%02x ", byte)
|
58
|
+
end
|
59
|
+
|
60
|
+
count = count+1
|
61
|
+
|
62
|
+
if count % 32 == 0
|
63
|
+
print "\n"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
f = ColorDif.new(ARGV[0], ARGV[1])
|
70
|
+
f.diffem
|
71
|
+
|
72
|
+
puts ColorConstants::NO_COLOR + "\n\n"
|
data/experimental/deezee
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# (emonti at matasano) Matasano Security LLC 2008
|
3
|
+
|
4
|
+
require 'rbkb'
|
5
|
+
require 'rbkb/command_line'
|
6
|
+
require 'stringio'
|
7
|
+
|
8
|
+
include RBkB::CommandLine
|
9
|
+
|
10
|
+
first = 0
|
11
|
+
last = nil
|
12
|
+
verbose=true
|
13
|
+
|
14
|
+
#------------------------------------------------------------------------------
|
15
|
+
# Init options and arg parsing
|
16
|
+
OPTS = {:len => 16}
|
17
|
+
arg = bkb_stdargs(nil, OPTS)
|
18
|
+
|
19
|
+
arg.banner += " <input-file | blank for stdin>"
|
20
|
+
|
21
|
+
arg.on("-q", "--[no-]quiet", "Stifle extra data info") {|q| verbose=(!q)}
|
22
|
+
arg.on("-s", "--start=OFF", Numeric, "Start at offset") {|s| first=s}
|
23
|
+
arg.on("-e", "--end=OFF", Numeric, "End at offset") {|e| last=e}
|
24
|
+
|
25
|
+
begin
|
26
|
+
#----------------------------------------------------------------------------
|
27
|
+
# Parse arguments
|
28
|
+
|
29
|
+
arg.parse!(ARGV)
|
30
|
+
|
31
|
+
inp = nil
|
32
|
+
|
33
|
+
if inpname=ARGV.shift
|
34
|
+
inp=File.open(inpname, "rb") rescue "Error: Can't open file '#{a}'"
|
35
|
+
else
|
36
|
+
inp = StringIO.new(STDIN.read())
|
37
|
+
inpname="stdin"
|
38
|
+
end
|
39
|
+
|
40
|
+
# catchall
|
41
|
+
if ARGV.length != 0
|
42
|
+
raise "bad arguments - #{ARGV.join(' ')}"
|
43
|
+
end
|
44
|
+
|
45
|
+
#----------------------------------------------------------------------------
|
46
|
+
# Do stuff
|
47
|
+
|
48
|
+
# Right now this only handles gzip files... no deflate, no stream, no raw LZ
|
49
|
+
gzc = "\x1f\x8b"
|
50
|
+
|
51
|
+
off = inp.pos = first
|
52
|
+
until inp.eof? or (last and inp.pos >= last)
|
53
|
+
# grab 2 byte signature
|
54
|
+
sig = inp.read(2)
|
55
|
+
|
56
|
+
break if inp.eof?
|
57
|
+
|
58
|
+
# compare with gzip signature
|
59
|
+
if sig == gzc
|
60
|
+
# return to start position
|
61
|
+
off = (inp.pos -= 2)
|
62
|
+
|
63
|
+
begin
|
64
|
+
gz = Zlib::GzipReader.new(inp)
|
65
|
+
dat = gz.read
|
66
|
+
gz_size = inp.pos
|
67
|
+
|
68
|
+
STDERR.puts "** %d bytes of gzip @ %0.8x" %[gz_size, off]
|
69
|
+
if verbose
|
70
|
+
STDERR.puts " Extra info:"
|
71
|
+
STDERR.puts " inflated size = #{ dat.size}"
|
72
|
+
gz.get_xtra_info.sort {|a,b| a.to_s <=> b.to_s }.each do |k,v|
|
73
|
+
STDERR.puts "#{k.to_s.rjust(18)} = #{v.inspect}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# XXX assuming no better than 15% compression rate?
|
78
|
+
inp.pos = inp.pos / 4
|
79
|
+
next
|
80
|
+
rescue
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# start again from next byte
|
85
|
+
off = (inp.pos -= 1)
|
86
|
+
end
|
87
|
+
rescue
|
88
|
+
bail $!
|
89
|
+
end
|
90
|
+
|
91
|
+
|
data/experimental/feed
ADDED
@@ -0,0 +1,225 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# feed <emonti at matasano> 3/15/2008
|
3
|
+
#----------------------------------------------------------------------
|
4
|
+
#
|
5
|
+
# This is an eventmachine message feeder from static data sources.
|
6
|
+
# The "feed" handles messages opaquely and just plays them in the given
|
7
|
+
# sequence.
|
8
|
+
#
|
9
|
+
# Feed can do the following things with minimum fuss:
|
10
|
+
# - Import messages from files, yaml, or pcap
|
11
|
+
# - Inject custom/modified messages with "blit"
|
12
|
+
# - Run as a server or client using UDP or TCP
|
13
|
+
# - Bootstrap protocols without a lot of work up front
|
14
|
+
# - Skip uninteresting messages and focus attention on the fun ones.
|
15
|
+
# - Replay conversations for relatively unfamiliar protocols.
|
16
|
+
# - Observe client/server behaviors using different messages at
|
17
|
+
# various phases of a conversation.
|
18
|
+
#
|
19
|
+
#----------------------------------------------------------------------
|
20
|
+
#
|
21
|
+
# Usage: feed -h
|
22
|
+
#
|
23
|
+
#----------------------------------------------------------------------
|
24
|
+
# To-dos / Ideas:
|
25
|
+
# - Unix Domain Socket support?
|
26
|
+
# - more import options?
|
27
|
+
# - dynamic feed elements?
|
28
|
+
# - add/control feed elements while 'stepping'?
|
29
|
+
#
|
30
|
+
|
31
|
+
require 'rubygems'
|
32
|
+
require 'eventmachine'
|
33
|
+
require 'rbkb'
|
34
|
+
require 'rbkb/plug'
|
35
|
+
require 'rbkb/plug/feed_import'
|
36
|
+
require 'rbkb/command_line'
|
37
|
+
|
38
|
+
include RBkB::CommandLine
|
39
|
+
|
40
|
+
## Default "UI" options
|
41
|
+
Plug::UI::LOGCFG[:verbose] = true
|
42
|
+
Plug::UI::LOGCFG[:dump] = :hex
|
43
|
+
|
44
|
+
## Default options sent to the Feed handler
|
45
|
+
FEED_OPTS = {
|
46
|
+
:close_at_end => false,
|
47
|
+
:step => false,
|
48
|
+
:go_first => false
|
49
|
+
}
|
50
|
+
|
51
|
+
my_addr = "0.0.0.0"
|
52
|
+
my_port = nil
|
53
|
+
listen = false
|
54
|
+
persist = false
|
55
|
+
|
56
|
+
transport = :TCP
|
57
|
+
|
58
|
+
svr_method = :start_server
|
59
|
+
cli_method = :connect
|
60
|
+
|
61
|
+
|
62
|
+
b_addr = Plug::Blit::DEFAULT_IPADDR
|
63
|
+
b_port = Plug::Blit::DEFAULT_PORT
|
64
|
+
|
65
|
+
## Parse command-line options
|
66
|
+
arg = bkb_stdargs(nil, {})
|
67
|
+
arg.banner += " host:port"
|
68
|
+
|
69
|
+
arg.separator " Options:"
|
70
|
+
|
71
|
+
arg.on("-o", "--output=FILE", "Output to file") do |o|
|
72
|
+
Plug::UI::LOGCFG[:out] = File.open(o, "w")
|
73
|
+
end
|
74
|
+
|
75
|
+
arg.on("-l", "--listen=(ADDR:?)PORT", "Server - on port (and addr?)") do |p|
|
76
|
+
if m=/^(?:([\w\.]+):)?(\d+)$/.match(p)
|
77
|
+
my_addr = $1 if $1
|
78
|
+
my_port = $2.to_i
|
79
|
+
listen = true
|
80
|
+
else
|
81
|
+
raise "Invalid listen argument: #{p.inspect}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
arg.on("-b", "--blit=(ADDR:)?PORT", "Where to listen for blit") do |b|
|
86
|
+
puts b
|
87
|
+
unless(m=/^(?:([\w\.]+):)?(\d+)$/.match(b))
|
88
|
+
raise "Invalid blit argument: #{b.inspect}"
|
89
|
+
end
|
90
|
+
b_port = m[2].to_i
|
91
|
+
b_addr = m[1] if m[1]
|
92
|
+
end
|
93
|
+
|
94
|
+
arg.on("-i", "--[no-]initiate", "Send the first message on connect") do |i|
|
95
|
+
FEED_OPTS[:go_first] = i
|
96
|
+
end
|
97
|
+
|
98
|
+
arg.on("-e", "--[no-]end", "End connection when feed is exhausted") do |c|
|
99
|
+
FEED_OPTS[:close_at_end] = c
|
100
|
+
end
|
101
|
+
|
102
|
+
arg.on("-s", "--[no-]step", "'Continue' prompt between messages") do |s|
|
103
|
+
FEED_OPTS[:step] = s
|
104
|
+
end
|
105
|
+
|
106
|
+
arg.on("-u", "--udp", "Use UDP instead of TCP" ) do
|
107
|
+
transport = :UDP
|
108
|
+
svr_method = cli_method = :open_datagram_socket
|
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("-S", "--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
|
+
|
153
|
+
arg.parse!(ARGV) rescue bail "Error: #{$!}\nUse -h|--help for more info."
|
154
|
+
|
155
|
+
# parse OptionParser and import feed
|
156
|
+
begin
|
157
|
+
arg.parse!(ARGV)
|
158
|
+
|
159
|
+
# Prepare EventMachine arguments based on whether we are a client or server
|
160
|
+
if listen
|
161
|
+
evma_addr = my_addr
|
162
|
+
evma_port = my_port
|
163
|
+
meth = svr_method
|
164
|
+
FEED_OPTS[:kind] = :server
|
165
|
+
else
|
166
|
+
|
167
|
+
## Get target/listen argument for client mode
|
168
|
+
unless (m = /^([\w\.]+):(\d+)$/.match(ARGV.shift)) and ARGV.shift.nil?
|
169
|
+
bail arg
|
170
|
+
end
|
171
|
+
|
172
|
+
t_addr = m[1]
|
173
|
+
t_port = m[2].to_i
|
174
|
+
|
175
|
+
if transport == :UDP
|
176
|
+
evma_addr = my_addr
|
177
|
+
evma_port = my_port || 0
|
178
|
+
else
|
179
|
+
evma_addr = t_addr
|
180
|
+
evma_port = t_port
|
181
|
+
end
|
182
|
+
|
183
|
+
meth = cli_method
|
184
|
+
FEED_OPTS[:kind] = :client
|
185
|
+
end
|
186
|
+
|
187
|
+
FEED_OPTS[:feed] ||= []
|
188
|
+
Plug::UI.verbose "** FEED CONTAINS #{FEED_OPTS[:feed].size} MESSAGES"
|
189
|
+
|
190
|
+
## error out on unexpected arguments
|
191
|
+
raise "too many arguments" if ARGV.shift
|
192
|
+
rescue
|
193
|
+
bail "Error: #{$!}\nUse -h|--help for more information"
|
194
|
+
end
|
195
|
+
|
196
|
+
|
197
|
+
em_args=[
|
198
|
+
meth,
|
199
|
+
evma_addr,
|
200
|
+
evma_port,
|
201
|
+
Plug::ArrayFeeder,
|
202
|
+
transport,
|
203
|
+
FEED_OPTS
|
204
|
+
].flatten
|
205
|
+
|
206
|
+
|
207
|
+
## Start the eventmachine
|
208
|
+
loop do
|
209
|
+
EventMachine::run do
|
210
|
+
EventMachine.send(*em_args) do |c|
|
211
|
+
EventMachine.start_server(b_addr, b_port, Plug::Blit, :TCP, c)
|
212
|
+
Plug::UI::verbose("** BLITSRV-#{b_addr}:#{b_port}(TCP) Started")
|
213
|
+
|
214
|
+
# if this is a UDP client, we will always send the first message
|
215
|
+
if transport == :UDP and c.kind == :client and
|
216
|
+
c.feed_data(c.peers.add_peer_manually(t_addr, t_port))
|
217
|
+
c.go_first = false
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
break unless persist
|
223
|
+
Plug::UI::verbose("** RECONNECTING")
|
224
|
+
end
|
225
|
+
|