Skip to content

Instantly share code, notes, and snippets.

@rainux
Created March 8, 2010 14:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rainux/325200 to your computer and use it in GitHub Desktop.
Save rainux/325200 to your computer and use it in GitHub Desktop.
Find out reachable IP addresses for given host.
#!/usr/bin/env ruby
require 'open-uri'
require 'ping'
Signal.trap('INT') { exit }
ServiceBaseUrl = 'http://just-dnslookup.com/'
ServiceUrl = "#{ServiceBaseUrl}index.php?vh=%s&c=&s=dns+lookup!"
domain = ARGV.first.to_s.strip
port_to_test = ARGV.last.to_i
port_to_test = 80 unless (1..65535).include? port_to_test
if domain == ''
puts <<-TEXT
Usage: #{File.basename $0} <host> [port]
Find out reachable IP addresses for given host by 2 steps:
* Query just-dnslookup.com to get an IP address list for the host.
* Use a TCP echo (not an ICMP echo) to determine if they are reachable.
Port are optional, default to 80.
TEXT
exit
end
puts 'Querying just-dnslookup.com...'
urls = []
begin
open(ServiceUrl % domain) do |f|
urls = f.read.scan(/xmlreqGET\s*\(\s*['"]\s*([^'"]+)['"]/).flatten.collect do |path|
"#{ServiceBaseUrl}#{path}"
end
end
rescue Timeout::Error
puts "\nMaybe just-dnslookup.com not reachable or this script need an update."
exit
rescue Errno::ECONNRESET
puts %(\nThe host string "#{domain}" seems be blocked as a keyword by GFW.)
exit
end
ip_list = []
urls.each do |url|
country_code = url.match(/&cp=(\w+)/)[1]
puts "Querying just-dnslookup.com with country code #{country_code}..."
begin
open(url) do |f|
data = f.read
if data['::']
data = data.split('::')
ip_list << data.first if data.last['good']
else
puts " Unexpected response for country code #{country_code}:"
puts " #{data.inspect}"
end
end
rescue Timeout::Error, Errno::ECONNRESET
end
end
ip_list.sort!.uniq!
if ip_list.empty?
puts <<-TEXT
No IP addresses collected, maybe just-dnslookup.com not reachable or this
script need an update.
TEXT
exit
end
ENV.delete 'http_proxy'
ip_table = {}
ip_list.each do |ip|
start_time = Time.now
if Ping.pingecho(ip, 2, port_to_test)
ip_table[Time.now - start_time] = ip
end
end
if ip_table.empty?
puts "\nAll IP addresses of #{domain} are not reachable."
else
puts "\nReachable IP addresses of #{domain}:"
puts 'IP | TCP echo time (ms)'
ip_table.sort.each do |item|
printf "%-16s| %.1f\n", item.last, item.first * 1000
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment