def red; colorize(self, "\e[1m\e[31m"); end
def green; colorize(self, "\e[1m\e[32m"); end
def cyan; colorize(self, "\e[1;36m"); end
def bold; colorize(self, "\e[1m"); end
def colorize(text, color_code) "#{color_code}#{text}\e[0m" end
@options = OpenStruct.new
opts = OptionParser.new do |opts|
opts.banner = "Usage: #{__FILE__}.rb [options]"
opts.on('-c', '--connect',
"Connect to a remote host") do
@options.connection_type = :connect
opts.on('-l', '--listen',
"Listen for a remote host to connect to this host") do
@options.connection_type = :listen
opts.on('-r', '--remote-host HOSTNAME', String,
"Specify the host to connect to") do |hostname|
@options.hostname = hostname || '127.0.0.1'
opts.on('-p', '--port PORT', Integer,
"Specify the TCP port") do |port|
opts.on('-v', '--verbose') do
@options.verbose = :verbose
opts.on_tail('-h', '--help', "Show this message") do
rescue OptionParser::ParseError => err
if @options.connection_type == nil
puts "[!] ".red + "No Connection Type specified"
puts "[!] ".red + "No Port specified to #{@options.connection_type.to_s.capitalize}"
if @options.connection_type == :connect && @options.hostname == nil
puts "[!] ".red + "Connection type connect requires a hostname"
if @options.connection_type == :connect
puts "[+] ".green + "Connecting to " + "#{@options.hostname}".bold + " on port " + "#{@options.port}".bold if @options.verbose == :verbose
@socket = TCPSocket.open(@options.hostname, @options.port)
puts "[+] ".green + "Listing on port " + "#{@options.port}".bold if @options.verbose == :verbose
server = TCPServer.new(@options.port)
puts "[!] ".red + "Error [1]: " + "#{e}"
# Data Transfer Management
if IO.select([],[],[@socket, STDIN],0)
# Send command if done from receiving upto 2-billions bytes
while (data = @socket.recv_nonblock(2000000000)) != ""
# http://stackoverflow.com/questions/20604130/how-to-use-rubys-write-nonblock-read-nonblock-with-servers-clients
while (data = STDIN.read_nonblock(2000000000)) != ""
# http://stackoverflow.com/questions/20604130/how-to-use-rubys-write-nonblock-read-nonblock-with-servers-clients
# Get all remote system socket(STDIN, STDOUT, STDERR) To my STDIN
IO.select([@socket, STDIN], [@socket, STDIN], [@socket, STDIN])