Class: Rbkb::Cli::Feed
- Inherits:
-
Executable
- Object
- Executable
- Rbkb::Cli::Feed
- Defined in:
- lib/rbkb/cli/feed.rb
Overview
Copyright 2009 emonti at moatasano dot com See README.rdoc for license information
This is a plug-board message feeder from static data sources. The “feed” handles messages opaquely and just plays them in the given sequence.
Feed can do the following things with minimum fuss:
- Import messages from files, yaml, or pcap
- Inject custom/modified messages with "blit"
- Run as a server or client using UDP or TCP
- Bootstrap protocols without a lot of work up front
- Skip uninteresting messages and focus attention on the fun ones.
- Replay conversations for relatively unfamiliar protocols.
- Observe client/server behaviors using different messages at
various phases of a conversation.
To-dos / Ideas:
- Unix Domain Socket support?
- more import options?
- dynamic feed elements?
- add/control feed elements while 'stepping'?
Instance Attribute Summary
Attributes inherited from Executable
#argv, #exit_status, #oparse, #opts, #stderr, #stdin, #stdout
Instance Method Summary collapse
- #go(*args) ⇒ Object
-
#initialize(*args) ⇒ Feed
constructor
A new instance of Feed.
- #make_parser ⇒ Object
- #parse(*args) ⇒ Object
Methods inherited from Executable
#bail, #bail_args, #exit, run
Constructor Details
#initialize(*args) ⇒ Feed
Returns a new instance of Feed.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/rbkb/cli/feed.rb', line 31 def initialize(*args) @local_addr = "0.0.0.0" @local_port = nil @listen = false @persist = false @transport = :TCP @svr_method = :start_server @cli_method = :connect @blit_addr = Plug::Blit::DEFAULT_IPADDR @blit_port = Plug::Blit::DEFAULT_PORT ## Default options sent to the Feed handler @feed_opts = { :close_at_end => false, :step => false, :go_first => false } super(*args) # TODO Plug::UI obviously need fixing. # TODO It shouldn't be driven by constants for configuration Plug::UI::LOGCFG[:verbose] = true Plug::UI::LOGCFG[:dump] = :hex Plug::UI::LOGCFG[:out] = @stderr end |
Instance Method Details
#go(*args) ⇒ Object
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/rbkb/cli/feed.rb', line 196 def go(*args) super(*args) Plug::UI.verbose "** FEED CONTAINS #{@feed_opts[:feed].size} MESSAGES" ## Start the eventmachine loop do EventMachine::run do EventMachine.send(*@em_args) do |c| EventMachine.start_server(@blit_addr, @blit_port, Plug::Blit, :TCP, c) Plug::UI::verbose("** BLITSRV-#{@blit_addr}:#{@blit_port}(TCP) Started") # if this is a UDP client, we will always send the first message if [:UDP, :client] == [@transport, c.kind] peer = c.peers.add_peer_manually(@target_addr, @target_port) c.feed_data(peer) c.go_first = false end end end break unless @persist Plug::UI::verbose("** RECONNECTING") end end |
#make_parser ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/rbkb/cli/feed.rb', line 59 def make_parser() arg = super() arg. += " host:port" arg.on("-o", "--output=FILE", "Output to file") do |o| Plug::UI::LOGCFG[:out] = File.open(o, "w") end arg.on("-l", "--listen=(ADDR:?)PORT", "Server - on port (and addr?)") do |p| if m=/^(?:([\w\._-]+):)?(\d+)$/.match(p) @local_addr = $1 if $1 @local_port = $2.to_i @listen = true else raise "Invalid listen argument: #{p.inspect}" end end arg.on("-b", "--blit=(ADDR:)?PORT", "Where to listen for blit") do |b| puts b unless(m=/^(?:([\w\._-]+):)?(\d+)$/.match(b)) raise "Invalid blit argument: #{b.inspect}" end @blit_port = m[2].to_i @blit_addr = m[1] if m[1] end arg.on("-i", "--[no-]initiate", "Send the first message on connect") do |i| @feed_opts[:go_first] = i end arg.on("-e", "--[no-]end", "End connection when feed is exhausted") do |c| @feed_opts[:close_at_end] = c end arg.on("-s", "--[no-]step", "'Continue' prompt between messages") do |s| @feed_opts[:step] = s end arg.on("-u", "--udp", "Use UDP instead of TCP" ) do @transport = :UDP end arg.on("-r", "--reconnect", "Attempt to reconnect endlessly.") do @persist=true end arg.on("-q", "--quiet", "Suppress verbose messages/dumps") do Plug::UI::LOGCFG[:verbose] = false end arg.on("-Q", "--squelch-exhausted", "Squelch 'FEED EXHAUSTED' messages") do |s| @feed_opts[:squelch_exhausted] = true end arg.separator " Sources: (can be combined)" arg.on("-f", "--from-files=GLOB", "Import messages from raw files") do |f| @feed_opts[:feed] ||= [] @feed_opts[:feed] += FeedImport.import_rawfiles(f) end arg.on("-x", "--from-hex=FILE", "Import messages from hexdumps") do |x| @feed_opts[:feed] ||= [] @feed_opts[:feed] += FeedImport.import_dump(x) end arg.on("-y", "--from-yaml=FILE", "Import messages from yaml") do |y| @feed_opts[:feed] ||= [] @feed_opts[:feed] += FeedImport.import_yaml(y) end arg.on("-p", "--from-pcap=FILE[:FILTER]", "Import messages from pcap") do |p| if /^([^:]+):(.+)$/.match(p) file = $1 filter = $2 else file = p filter = nil end @feed_opts[:feed] ||= [] @feed_opts[:feed] += FeedImport.import_pcap(file, filter) end end |
#parse(*args) ⇒ Object
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/rbkb/cli/feed.rb', line 145 def parse(*args) super(*args) if @transport == :UDP @svr_method = @cli_method = :open_datagram_socket end # Prepare EventMachine arguments based on whether we are a client or server if @listen @evma_addr = @local_addr @evma_port = @local_port @meth = @svr_method @feed_opts[:kind] = :server @feed_opts[:no_stop_on_unbind] = true else ## Get target/listen argument for client mode unless (m = /^([\w\.]+):(\d+)$/.match(tgt=@argv.shift)) bail_args tgt end @target_addr = m[1] @target_port = m[2].to_i if @transport == :UDP @evma_addr = @local_addr @evma_port = @local_port || 0 else @evma_addr = @target_addr @evma_port = @target_port end @meth = @cli_method @feed_opts[:kind] = :client end @feed_opts[:feed] ||= [] @em_args=[ @meth, @evma_addr, @evma_port, Plug::ArrayFeeder, @transport, @feed_opts ].flatten parse_catchall() end |