Sure. You know how simple this task is when you have an event loop, right? Here, I'll write a port scanner right now:
class HostProbe
module Probe
attr_accessor :bp
def connection_completed
@win = true
end
def unbind
self.bp.closed(self, @win)
end
end
def closed(obj, won)
@inflight_now -= 1
port = @inflight_q.delete(obj)
if won
puts "%TARGET-LISTENING: #{ @target }:#{ port }"
end
fill()
end
def sweep
Generator.new do |g|
(1..65535).each {|port| g.yield port}
end
end
def fill
@inflight_now.upto(@inflight_max) {
@inflight_now += 1
if(port = @sweep.next)
EventMachine::connect(@target, port, Probe) do |c|
c.bp = self
@inflight_q[c] = port
end
end
}
end
def initialize(host, opts={})
@target = host
@sweep = sweep
@inflight_q = {}
@inflight_now = 0
@inflight_max = opts[:inflight_max] || 10
fill()
end
end
EventMachine::run {
HostProbe.new(ARGV[0])
}
I think that may be it? I'm not even going to bother seeing if it evaluates. I write that stupid script once a month or so. There is probably a set of nmap options that crushes it for speed, but with the default options and a firewalled target network (ie: most professional nmap targets), I lap nmap with it.