# This gem module provides a classes to find the right Regional Internet Registry # for a given IP Address. The query method will navigate each major RIR until a # response is found. # # Author:: Al Kivi <al.kivi@vizitrax.com> # License:: MIT module Vizi # This class includes a set of methods to navigate and query the regional whois servers class Gowhois # This method will navigate each whois server until a response is found def query (ipaddr) s = "arin" response = ruby_whois(ipaddr, s) if response.index("(NET") # look for dual NET blocks in ARIN responses t1 = response netaddrs = response.scan(/\(NET-\w+\-\w+\-\w+\-\w+\-\w+\)/) netaddr = netaddrs[netaddrs.length-1].scan(/NET-\w+\-\w+\-\w+\-\w+\-\w+/) response = ruby_whois(netaddr[0], s) end if response.index("whois.ripe.net") s = "ripe" response = ruby_whois(ipaddr, s) elsif response.index("whois.apnic.net") s = "apnic" response = ruby_whois(ipaddr, s) elsif response.index("whois.lacnic.net") s = "lacnic" response = ruby_whois(ipaddr, s) if response.length > 4000 # parse very long responses lines = response.split(/\r\n/) lines.delete_if { |e| e =~ /nserver:/ } lines.delete_if { |e| e =~ /nsstat:/ } lines.delete_if { |e| e =~ /nslastaa:/ } lines.delete_if { |e| e =~ /inetrev:/ } response="" i=0 while i<lines.length response = response+lines[i]+"\r\n" i = i+1 end end elsif response.index("whois.afrinic.net") s = "afrinic" response = ruby_whois(ipaddr, s) elsif response.length >250 and response.length < 500 str = response[100..250] x = str.index("(") y = str.index(")") if x != nil and y != nil net = str[x+1..y-1] response = ruby_whois(net, s) end end ccode = get_country(response) return response, ccode, s end # This method will parse the response to find the two character country code def get_country (response) temp = response.upcase temp.delete!("\t") temp.delete!(" ") x = temp.index("COUNTRY:") ccode = nil if x != nil ccode = temp[x+8..x+9] elsif temp.index(".BR") ccode = "BR" else ccode ="?" end return ccode end # This method the ruby version of the whois command function def ruby_whois (send_string, host) # p send_string + " .. " + host if host.index(".") == nil host = "whois."+host+".net" end add_string = "" add_string = "n " if host == "whois.arin.net" add_string = "n ! " if send_string.index("NET") == 0 s = TCPSocket.open(host,43) s.write(add_string+send_string+"\n") ret = "" while s.gets do ret += $_ end s.close return ret rescue # rescue logic if not found ret="Not found" return ret end end # This class will parse the response string from a Whois server class Formatter # This method will parse response string def parse (contents, country, server) name_list = ["COUNTRY","NETNAME","ORGNAME","ORG-NAME","CUSTNAME","OWNER","ADDRESS","DESCR","CITY","STATEPROV","POSTALCODE"] country_list = ["GERMANY","UNITED KINGDOM","UK","ENGLAND","INDIA","NETHERLANDS","SPAIN","BELGIUM","PR CHINA","NORWAY"] odd_list = ["EMAIL","CONTA","PHONE","ABUSE ","SENT ","SEND ","DATE ","ATTN ","INFRA","THIS ","ANTIA","*****","-----"] # formatted_file = File.open('./log/formatted.log', 'a') a = contents.upcase.split(/\n/) i = -1 line = [nil,nil] lastname = nil addressflag = false country_count = 0 da_count = 0 netname_count = 0 darray = [] outstring = "" # formatted_file.puts '+ ------------------------------------------------------' # formatted_file.puts '+ '+ country + ' - ' + server.upcase # formatted_file.puts '+ ------------------------------------------------------' while i < a.length-1 i = i + 1 line = [nil, nil] goodline = true current = a[i].chomp if current.length < 2 goodline = false else goodline = false if current[0] == "%" or current[0] == "#" end if goodline line = current.split(":") if line[1].nil? line[1] = "" if lastname == "ADDRESS" and line[0] != line[0].lstrip line[0] = lastname end else addressflag = true if line[0] == "ADDRESS" end line[1] = line[1].lstrip.gsub(".","") line[1] = line[1].lstrip.gsub(", ",",") line[1] = line[1].lstrip.gsub(" ,",",") line[1] = line[1].chomp(",") country_count = country_count + 1 if line[0] == "COUNTRY" da_count = da_count + 1 if line[0] == "DESCR" or line[0] == "ADDRESS" netname_count = netname_count + 1 if line[0] == "NETNAME" goodline = false if da_count > 10 or country_count > 4 or netname_count > 1 goodline = false if country_count > 1 and line[0] == "COUNTRY" goodline = false if line[1][0] == "-" goodline = false if country_list.index(line[1]) goodline = false if line[0] == "ADDRESS" and line[1] == country goodline = false if odd_list.index(line[1][0..4]) goodline = false if addressflag and line[0] == "DESCR" goodline = false if line[1].length < 2 goodline = false if darray.index(line[1]) darray << line[1] if goodline and (line[0] == "DESCR" or line[0] == "ADDRESS") if goodline country_count = country_count + 1 if line[0] == "COUNTRY" da_count = da_count + 1 if line[0] == "DESCR" or line[0] == "ADDRESS" end else line[0] = current line[1] = "" end lastname = line[0] if goodline if name_list.index(line[0]) newline = line[0] + ': ' + line[1] + '\n' # formatted_file.puts '+ ' + newline outstring = outstring + newline else # formatted_file.puts '. ' + line[0] + ':: ' + line[1] end else # formatted_file.puts '- ' + line[0] end end # formatted_file.puts '+ ' + country_count.to_s + ': ' + da_count.to_s return outstring end end end