#!/usr/bin/ruby
#file: portscan.rb
require 'open-uri'
require 'socket'
require 'rexml/document'
include REXML
class PortScanner
def initialize(host, xmlfileout='portscan_result.xml')
high = 8192
service_url = "http://rorbuilder.info/r/service_ports.xml"
doc_result = main(service_url, host, high)
File.new(xmlfileout,'w').puts(doc_result)
end
def main(url, host, high)
buffer = open(url, "UserAgent" => "Ruby-PortScanner1.0")
doc = Document.new(buffer)
doc.root.elements.each('records/port') do |node|
new_node = Element.new('open')
new_node.text = 'n'
node.add_element new_node
end
for port in 1 .. high
begin
s = TCPsocket.open(host, port)
puts 'port ' + port.to_s
node_port = doc.root.elements["records/port[number='#{port.to_s}']"]
unless node_port.nil?
port_name = node_port.elements['name'].text.to_s
node_port.elements['open'].text = 'y'
else
port_name = 'unknown'
add_port(:doc => doc , :port => port , :name => port_name, :description => '')
end
printf "%s/%sopen\t%s\n", port, 'tcp'.ljust(11 - port.to_s.length), port_name
s.close
rescue Errno::ECONNREFUSED
next
end
end
return doc
end
def add_port(h)
node_port = Element.new('port')
add_child(node_port, 'number', h[:port])
add_child(node_port, 'name', h[:name])
add_child(node_port, 'description', h[:description])
h[:doc].root.elements['records'].add_element node_port
end
def add_child(node,nodename, value)
newnode = Element.new(nodename)
newnode.text = value
node.add_element(newnode)
end
end
if __FILE__ == $0 then
ps = PortScanner.new('192.168.1.106')
end