rbkb 0.6.12 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +15 -0
  2. data/.bnsignore +25 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/Gemfile.lock +27 -0
  6. data/History.txt +8 -0
  7. data/LICENSE.txt +22 -0
  8. data/Rakefile +10 -45
  9. data/experimental/cap2files +21 -0
  10. data/experimental/cap2yaml +20 -0
  11. data/experimental/colordif.rb +72 -0
  12. data/experimental/deezee +91 -0
  13. data/experimental/feed +225 -0
  14. data/experimental/fmagic.rb +51 -0
  15. data/experimental/magicrip.c +92 -0
  16. data/experimental/magicripper.rb +63 -0
  17. data/lib/rbkb.rb +2 -48
  18. data/lib/rbkb/cli.rb +3 -2
  19. data/lib/rbkb/cli/bgrep.rb +1 -4
  20. data/lib/rbkb/cli/blit.rb +4 -0
  21. data/lib/rbkb/cli/crc32.rb +4 -1
  22. data/lib/rbkb/cli/dedump.rb +1 -0
  23. data/lib/rbkb/cli/rstrings.rb +1 -7
  24. data/lib/rbkb/extends.rb +8 -787
  25. data/lib/rbkb/extends/array.rb +29 -0
  26. data/lib/rbkb/extends/common.rb +13 -0
  27. data/lib/rbkb/extends/enumerable.rb +9 -0
  28. data/lib/rbkb/extends/float.rb +17 -0
  29. data/lib/rbkb/extends/numeric.rb +83 -0
  30. data/lib/rbkb/extends/object.rb +7 -0
  31. data/lib/rbkb/extends/string.rb +624 -0
  32. data/lib/rbkb/extends/symbol.rb +8 -0
  33. data/lib/rbkb/plug/blit.rb +21 -1
  34. data/lib/rbkb/plug/peer.rb +5 -0
  35. data/lib/rbkb/plug/plug.rb +6 -2
  36. data/lib/rbkb/version.rb +3 -0
  37. data/rbkb.gemspec +20 -34
  38. data/reference/blackbag-0.9.1.tgz +0 -0
  39. data/reference/note_http_unit_tests +3 -0
  40. data/spec/spec_helper.rb +5 -14
  41. data/spec/string_extends_spec.rb +129 -0
  42. data/test/{test_cli_blit.rb → disabled_test_cli_blit.rb} +0 -0
  43. data/test/{test_cli_feed.rb → disabled_test_cli_feed.rb} +0 -0
  44. data/test/{test_cli_telson.rb → disabled_test_cli_telson.rb} +0 -0
  45. data/test/test_cli_chars.rb +2 -0
  46. data/test/test_cli_helper.rb +3 -5
  47. data/test/test_cli_rstrings.rb +2 -0
  48. data/test/test_helper.rb +8 -0
  49. metadata +107 -89
  50. 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
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format nested
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rbkb.gemspec
4
+ gemspec
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
- # Look in the tasks/setup.rb file for the various options that can be
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
- begin
6
- require 'bones'
7
- Bones.setup
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
- PROJ.rdoc.opts << '--line-numbers'
33
-
34
- #PROJ.rdoc.opts << '--diagram'
35
- PROJ.notes.tags << "X"+"XX" # muhah! so we don't note our-self
36
-
37
- # exclude rcov.rb and external libs from rcov report
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"
@@ -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
+