rbkb 0.6.12 → 0.7.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 +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
|
+
|