]> projects.mako.cc - selectricity/blob - lib/whois/whois.rb
merged back from production
[selectricity] / lib / whois / whois.rb
1 #!/usr/bin/ruby -w
2
3 require 'socket'
4 require 'resolv'
5 require 'ipaddr'
6 require 'yaml'
7 require 'timeout'
8
9 require File.dirname(__FILE__) + '/server/server'
10
11 # Module for manage all Whois Class
12 module Whois
13
14     # Base exception of Whois
15     class WhoisException < Exception
16     end
17
18     # Exception of Whois who made report a bug
19     class WhoisExceptionError < WhoisException
20         def initialize (i)
21             WhoisException.initialize('Report a bug with error #{i} to http://rubyforge.org/projects/whois/')
22         end
23     end
24
25     # Class to get all information about Host or IP with the Whois request
26     class Whois
27
28         Version = '0.4.0'
29
30         attr_reader :all
31         attr_reader :server
32         attr_reader :ip
33         attr_reader :host
34         attr_accessor :host_search
35
36         # Initialize with a request. The request must be an IPv4, or a host string
37         #
38         # The first params now is :
39         #  * a string which a Ipv4, Ipv6 or a host.
40         #  * A IPAddr instance
41         #
42         # A second param, host_search is optionnal. By default he is false.
43         # If this value is true, a resolv host is made for know the host to this IPv4
44         def initialize(request, host_search=false)
45             @host_search = host_search
46             @host = nil
47             if request.instance_of? IPAddr
48                 if request.ipv4?
49                     @ip = request
50                     @server = server_ipv4
51                 elsif request.ipv6?
52                     @ip = request
53                     @server = server_ipv6
54                 else
55                     raise WhoisExceptionError.new(1)
56                 end
57             elsif Resolv::IPv4::Regex =~ request
58                 ipv4_init request
59                 unless self.server
60                     raise WhoisException.new("no server found for this IPv4 : #{request}")
61                 end
62             elsif Resolv::IPv6::Regex =~ request
63                 ipv6_init request
64                 unless self.server
65                     raise WhoisException.new("no server found for this Ipv6 : #{request}")
66                 end
67             else
68                 # Test if the request is an host or not
69                 begin
70                     ip = Resolv.getaddress request
71                     @ip = IPAddr.new ip
72                     @server = server_ipv4
73                     @host = request
74                 rescue Resolv::ResolvError
75                     raise WhoisException.new('host #{request} has no DNS result')
76                 end
77             end
78             
79             search_host unless @host
80         end
81         
82         # Ask of whois server
83         def search_whois
84             s = TCPsocket.open(self.server.server, 43)
85             s.write("#{self.ip.to_s}\n")
86             ret = ''
87             while s.gets do ret += $_ end
88             s.close
89             @all = ret
90         end
91
92
93         # Search the host for this IPv4, if the value host_search is true, else host = nil
94         def search_host
95             begin
96                 if @host_search
97                    begin
98                      timeout(5) {@host = Resolv.getname self.ip.to_s}
99                    rescue Timeout::Error
100                      @host=nil
101                    end
102                 else
103                     @host = nil
104                 end
105             rescue Resolv::ResolvError
106                 @host = nil
107             end
108         end
109     
110     private
111     
112         # Init value for a ipv4 request
113         def ipv4_init (ip)
114             @ip = IPAddr.new ip
115             @server = server_ipv4
116         end
117
118         # Init value for a ipv6 request
119         def ipv6_init (ip)
120             @ip = IPAddr.new ip
121             @server = server_ipv6
122         end
123
124         # Return the Server with the hash of mask
125         def server_with_hash(ip_hash)
126           # Sort by mask of Ip Range
127           arr_tmp = ip_hash.sort{|b,c| c[0][/\/(.+)/, 1].to_i <=> b[0][/\/(.+)/, 1].to_i}
128           arr_tmp.each do |l|
129             ip_range = IPAddr.new l[0]
130             if ip_range.include? self.ip and l[1].length > 0
131               return Object.instance_eval("Server::#{l[1]}.new")
132             end
133             return Server::Arin.new
134           end
135         end
136
137         # Define the server of Whois in IPC6 list of YAML
138         def server_ipv6
139           ipv6_list = YAML::load_file(File.dirname(__FILE__) + '/data/ipv6.yaml')
140           server = server_with_hash(ipv6_list)
141           unless server.kind_of? Server::Server
142             return Server::Arin.new
143           else
144             return server
145           end
146         end
147         
148         # Define the server of Whois in IPV4 list of YAML
149         def server_ipv4
150           ipv4_list = YAML::load_file(File.dirname(__FILE__) + '/data/ipv4.yaml')
151           server = server_with_hash(ipv4_list)
152           unless server.kind_of? Server::Server
153             return Server::Ripe.new
154           else
155             return server
156           end
157         end
158     end
159 end
160
161
162 if $0 == __FILE__
163   w = Whois::Whois.new '218.14.221.147'
164   puts w.search_whois
165 end

Benjamin Mako Hill || Want to submit a patch?