line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Net::Whois::Proxy; |
2
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
21241
|
use strict; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
119
|
|
4
|
2
|
|
|
2
|
|
12613
|
use IO::Socket; |
|
2
|
|
|
|
|
112613
|
|
|
2
|
|
|
|
|
15
|
|
5
|
2
|
|
|
2
|
|
2665
|
use vars qw ($VERSION); |
|
2
|
|
|
|
|
12
|
|
|
2
|
|
|
|
|
17833
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
$VERSION = $1 if('$Id: Proxy.pm,v 1.9 2005/05/22 02:40:36 cfaber Exp $' =~ /,v ([\d.]+) /); |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=head1 NAME |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
Net::Whois::Proxy - an easy to use recursive whois client library |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
=head1 DESCRIPTION |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
The Net::Whois::Proxy library is an easy to use recursive whois client library that does not do any additional parsing of the whois data. It's goal is to quickly track down domain, ipv4, ipv6, and BGP Anonymous System numbers. |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
=head1 SYNOPSIS |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
use Net::Whois::Proxy; |
20
|
|
|
|
|
|
|
my $whois = new Net::Whois::Proxy; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
my $record = $whois->whois('EXAMPLE.COM'); |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
print $record; |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
exit; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
Also see the whois.pl example script provided with the library distrobution |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=head1 METHODS |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
=cut |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
=head2 new(option => value) |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
Create a new Net::Whois::Proxy object. |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
Avaliable options: |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
=over |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=item * debug |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
Accepted values: |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
1 - turn on debugging, 0 - turn off debugging (default), *HANDLE - turn on debugging and send all debugging info to this file handle. |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
Option description: |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
Dump debugging information to STDOUT or a file handle. |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=item * stacked_results |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
Accepted values: |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
1 - turn on result stacking, 0 - turn off result stacking (default) |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
Option description: |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
Result stacking will result in the data found durning a whois crawl being stacked on top of each other with additional tags QUERY_#: tags beening added above each result chunk. |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
=item * clean_stack |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
Accepted values: |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
1 - turn on clean result stacking (default), 0 - turn off clean result stacking |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
Option description: |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
Using this option will disable the QUERY_#: entries from being added to a result stack. This option is only used if the B option is enabled. |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=item * master_ip_whois |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
Accepted values: |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
IP or Fully qualified domain name of a valid whois server (default: whois.arin.net) |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
Option description: |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
The master IP whois server to preform initial queries against. |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
=item * master_ip_port |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
Accepted values: |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
Ports 0 - 65535 (default: 43) |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
Option description: |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
The port number to use when querying the master IP whois server when preforming initial queries. |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=item * master_domain_whois |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
Accepted values: |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
IP or Fully qualified domain name of a valid whois server (default: whois.internet.net) |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
Option description: |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
The master domain whois server to preform initial queries against. |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=item * master_domain_port |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
Accepted values: |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
Ports 0 - 65535 (default: 43) |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
Option description: |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
The port number to use when querying the master domain whois server when preforming initial queries. |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=item * master_whois |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
Accepted values: |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
IP or Fully qualified domain name of a valid whois server (default: whois.internic.net) |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
Option description: |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
The master whois server that should be queried if both IP and domain whois queries fail. |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
=item * master_port |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
Accepted values: |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
Ports 0 - 65535 (default: 43) |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
Option description: |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
The port number to use when querying the master whois server. |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
=item * query_timeout |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
Accepted values: |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
Time in seconds (default: 10) |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
Option description: |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
Sets the amount of time allowed to elaspe before assuming the server has timed out. |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
=cut |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
sub new { |
148
|
1
|
|
|
1
|
1
|
17
|
my ($class, %opts) = @_; |
149
|
|
|
|
|
|
|
|
150
|
1
|
|
50
|
|
|
37
|
my $self = bless { |
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
151
|
|
|
|
|
|
|
debug => $opts{debug}, |
152
|
|
|
|
|
|
|
stacked_results => $opts{stacked_results}, |
153
|
|
|
|
|
|
|
clean_stack => $opts{clean_stack}, |
154
|
|
|
|
|
|
|
master_ip_whois => $opts{master_ip_whois} || 'whois.arin.net', |
155
|
|
|
|
|
|
|
master_ip_port => $opts{master_ip_port} || 43, |
156
|
|
|
|
|
|
|
master_whois => $opts{master_whois} || 'rs.internic.net', |
157
|
|
|
|
|
|
|
master_port => $opts{master_port} || 43, |
158
|
|
|
|
|
|
|
query_timeout => $opts{query_timeout} || 10 |
159
|
|
|
|
|
|
|
}, $class; |
160
|
|
|
|
|
|
|
|
161
|
1
|
|
33
|
|
|
14
|
$self->{master_domain_whois} = ($opts{master_domain_whois} || $self->{master_whois}); |
162
|
1
|
|
33
|
|
|
11
|
$self->{master_domain_port} = ($opts{master_domain_port} || $self->{master_port}); |
163
|
|
|
|
|
|
|
|
164
|
1
|
|
|
|
|
5
|
return $self; |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
=head2 whois(BGP AS # or IPv6 addr or IPv4 addr or PTR or FQDN or IPv4 addr to convert) |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
Attempt to preform useful commands on the data provided. |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
If the string provided is: 'AS #' or 'AS#' preform an anonymous system whois query on the IPv4 BGP tree. |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
Example: |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
print $whois->whois("AS 12345"); |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
If the string provided is an IPv6 address preform an whois query on it. |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
Example: |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
print $whois->whois("3ffe:b80:138c:1::59"); |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
If the string provided is an IPv4 address preform an whois query on it. |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
Example: |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
print $whois->whois("63.224.69.57"); |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
If the string provided starts with 'reverse' or 'dns' or 'rdns' and a dotted quad IPv4 address preform a PTR query. |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
Example: |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
print $whois->whois("reverse 63.224.69.57"); |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
If the string provided starts with 'convert' and a dotted quad IPv4 address or long integer address, convert the address to a long integer address or a dotted quad address |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
Example: |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
print $whois->whois("convert 63.224.69.57"); |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
=cut |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
sub whois { |
205
|
1
|
|
|
1
|
1
|
123
|
my ($self, $in) = @_; |
206
|
1
|
50
|
|
|
|
5
|
if((my $ip = $self->convert_ipv4($in))){ |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
207
|
0
|
|
|
|
|
0
|
return $self->whois_ipv4($ip); |
208
|
|
|
|
|
|
|
} elsif($in =~ /^[a-f0-9][a-f0-9][a-f0-9][a-f0-9]:/){ |
209
|
0
|
|
|
|
|
0
|
return $self->whois_ipv6($in); |
210
|
|
|
|
|
|
|
} elsif($in =~ /AS\s*?([0-9\s]+)/i){ |
211
|
0
|
|
|
|
|
0
|
return $self->whois_bgp_as("AS$1"); |
212
|
|
|
|
|
|
|
} elsif($in =~ /([A-Za-z0-9-]+\.[A-Za-z]{2,4})$/){ |
213
|
1
|
|
|
|
|
5
|
return $self->whois_domain($1); |
214
|
|
|
|
|
|
|
} elsif($in =~ /^(rev|r|dns)(erse|dns)?.*?\:?\s?(\d+\.\d+\.\d+\.\d+)/i){ |
215
|
0
|
|
|
|
|
0
|
return $self->whois_ptr($3); |
216
|
|
|
|
|
|
|
} elsif($in =~ /^(con|v)(ert|vert)?.*?:?\s?(\d+\.\d+\.\d+\.\d+|\d+)/i){ |
217
|
0
|
|
|
|
|
0
|
return $self->convert_ipv4($3); |
218
|
|
|
|
|
|
|
} else { |
219
|
0
|
|
|
|
|
0
|
return $self->_seterrstr("Unknown address type"); |
220
|
|
|
|
|
|
|
} |
221
|
|
|
|
|
|
|
} |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
=head2 convert_ipv4(###.###.###.### or long_int) |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
Take an IPv4 "dotted quad" address and convert it to long interger format, or an IPv4 long integer address and convert it to the "dotted quad" format. |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
=cut |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
sub convert_ipv4 { |
230
|
1
|
|
|
1
|
1
|
2
|
my ($self, $int) = @_; |
231
|
1
|
|
|
|
|
5
|
$self->_pd("checking IPv4 for conversion", caller); |
232
|
|
|
|
|
|
|
|
233
|
1
|
50
|
|
|
|
11
|
if($int =~ /^\d+$/){ |
|
|
50
|
|
|
|
|
|
234
|
0
|
|
|
|
|
0
|
$self->_pd("IPv4 is long integer format", caller); |
235
|
0
|
|
|
|
|
0
|
return inet_ntoa(pack "L", $int); |
236
|
|
|
|
|
|
|
} elsif($self->check_ipv4($int)) { |
237
|
0
|
|
|
|
|
0
|
$self->_pd("IPv4 is dotted quad format", caller); |
238
|
0
|
|
|
|
|
0
|
return unpack("L", inet_aton $int); |
239
|
|
|
|
|
|
|
} else { |
240
|
1
|
|
|
|
|
4
|
$self->_pd("address appears to be invalid", caller); |
241
|
1
|
|
|
|
|
24
|
return; |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
=head2 whois_ipv4(IPv4_dotted_quad or IPv4_long_integer[, whois, port, timeout]) |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
Preform a whois query on an IPv4 address of some type. Optionally query B on port B and timeout after B seconds. |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
=cut |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
sub whois_ipv4 { |
252
|
0
|
|
|
0
|
1
|
0
|
my ($self, $ip, $server, $port) = @_; |
253
|
|
|
|
|
|
|
|
254
|
0
|
0
|
|
|
|
0
|
if($ip =~ /^\d+$/){ |
255
|
0
|
|
0
|
|
|
0
|
$ip = $self->convert_ipv4($ip) || return undef; |
256
|
|
|
|
|
|
|
} |
257
|
|
|
|
|
|
|
|
258
|
0
|
0
|
|
|
|
0
|
$self->check_ipv4($ip) || return undef; |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
# This is our hints list to try and figure out where to look for more |
261
|
|
|
|
|
|
|
# ip information. The format is as follows: |
262
|
|
|
|
|
|
|
# whoisd => { port => port, s_flag => 'startflag', e_flag => 'stopflag', regexps => [re,re] } |
263
|
|
|
|
|
|
|
# |
264
|
|
|
|
|
|
|
|
265
|
0
|
|
|
|
|
0
|
my %hints = ( |
266
|
|
|
|
|
|
|
# LACNIC hints |
267
|
|
|
|
|
|
|
'whois.lacnic.net' => { |
268
|
|
|
|
|
|
|
port => 43, |
269
|
|
|
|
|
|
|
regexps => ['/LACNIC/'], |
270
|
|
|
|
|
|
|
}, |
271
|
|
|
|
|
|
|
# APNIC hints |
272
|
|
|
|
|
|
|
'whois.apnic.net' => { |
273
|
|
|
|
|
|
|
port => 43, |
274
|
|
|
|
|
|
|
regexps => ['/APNIC/'], |
275
|
|
|
|
|
|
|
}, |
276
|
|
|
|
|
|
|
# AUNIC hints |
277
|
|
|
|
|
|
|
'whois.aunic.net' => { |
278
|
|
|
|
|
|
|
port => 43, |
279
|
|
|
|
|
|
|
regexps => ['/AUNIC-AU/'], |
280
|
|
|
|
|
|
|
}, |
281
|
|
|
|
|
|
|
# RIPE hints |
282
|
|
|
|
|
|
|
'whois.ripe.net' => { |
283
|
|
|
|
|
|
|
port => 43, |
284
|
|
|
|
|
|
|
regexps => ['/(NET)?(BLK)?.*?-RIPE/'], |
285
|
|
|
|
|
|
|
}, |
286
|
|
|
|
|
|
|
# Brazilian NIC |
287
|
|
|
|
|
|
|
'whois.nic.br' => { |
288
|
|
|
|
|
|
|
port => 43, |
289
|
|
|
|
|
|
|
regexps => ['/NETBLK-BRAZIL/'], |
290
|
|
|
|
|
|
|
}, |
291
|
|
|
|
|
|
|
# Japan's NIC |
292
|
|
|
|
|
|
|
'whois.nic.ad.jp' => { |
293
|
|
|
|
|
|
|
port => 43, |
294
|
|
|
|
|
|
|
regexps => ['/JPNIC/'], |
295
|
|
|
|
|
|
|
e_flag => '/e', |
296
|
|
|
|
|
|
|
}, |
297
|
|
|
|
|
|
|
# Telstra NIC |
298
|
|
|
|
|
|
|
'whois.telstra.net' => { |
299
|
|
|
|
|
|
|
port => 43, |
300
|
|
|
|
|
|
|
regexps => ['/whois\.telstra/i'], |
301
|
|
|
|
|
|
|
}, |
302
|
|
|
|
|
|
|
# The Korean NIC |
303
|
|
|
|
|
|
|
'whois.nic.or.kr' => { |
304
|
|
|
|
|
|
|
port => 43, |
305
|
|
|
|
|
|
|
regexps => ['/whois.nic.or.kr/i'], |
306
|
|
|
|
|
|
|
}, |
307
|
|
|
|
|
|
|
# Some big rwhois servers. |
308
|
|
|
|
|
|
|
# The Exodus rwhois server |
309
|
|
|
|
|
|
|
'rwhois.exodus.net' => { |
310
|
|
|
|
|
|
|
port => 4321, |
311
|
|
|
|
|
|
|
regexps => ['/rwhois\.exodus/i'], |
312
|
|
|
|
|
|
|
}, |
313
|
|
|
|
|
|
|
# The DNAI rwhois server |
314
|
|
|
|
|
|
|
'rwhois.dnai.com' => { |
315
|
|
|
|
|
|
|
port => 4321, |
316
|
|
|
|
|
|
|
regexps => ['/rwhois\.dnai/i'], |
317
|
|
|
|
|
|
|
}, |
318
|
|
|
|
|
|
|
# The Digex rwhois server |
319
|
|
|
|
|
|
|
'rwhois.digex.net' => { |
320
|
|
|
|
|
|
|
port => 4321, |
321
|
|
|
|
|
|
|
regexps => ['/rwhois\.digex/i'], |
322
|
|
|
|
|
|
|
}, |
323
|
|
|
|
|
|
|
# The Internex rwhois server |
324
|
|
|
|
|
|
|
'rwhois.internex.net' => { |
325
|
|
|
|
|
|
|
port => 4321, |
326
|
|
|
|
|
|
|
regexps => ['/rwhois.internex/i'], |
327
|
|
|
|
|
|
|
}, |
328
|
|
|
|
|
|
|
# The XO/Concentric rwhois server |
329
|
|
|
|
|
|
|
'rwhois.concentric.net' => { |
330
|
|
|
|
|
|
|
port => 4321, |
331
|
|
|
|
|
|
|
regexps => ['/rwhois\.concentric/i'], |
332
|
|
|
|
|
|
|
}, |
333
|
|
|
|
|
|
|
); |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
# If we're not querying ARIN right off the bat then add it to our hints list. |
336
|
0
|
0
|
|
|
|
0
|
$server || ($server = $self->{master_ip_whois}); |
337
|
|
|
|
|
|
|
|
338
|
0
|
0
|
|
|
|
0
|
if($server !~ /whois\.arin\.net/i){ |
339
|
0
|
|
|
|
|
0
|
$hints{'whois.arin.net'}->{port} = 43; |
340
|
0
|
|
|
|
|
0
|
$hints{'whois.arin.net'}->{regexps} = ['/IANA-NETBLOCK/']; |
341
|
|
|
|
|
|
|
} |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
|
344
|
0
|
|
0
|
|
|
0
|
my $data = $self->_query_whois($ip, $server, $port || $self->{master_ip_port}, $self->{master_timeout}) || return; |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
# See if ``ReferralServer'' exists in the CDIR |
347
|
0
|
0
|
|
|
|
0
|
if($data =~ /ReferralServer\:\s*(?:whois:\/\/)?([A-Za-z0-9:.-]+)/){ |
348
|
0
|
|
|
|
|
0
|
my ($wi, $po) = split(/:/, $1, 2); |
349
|
0
|
|
0
|
|
|
0
|
$po ||= ($self->{master_whois_port} || 4321); |
|
|
|
0
|
|
|
|
|
350
|
|
|
|
|
|
|
|
351
|
0
|
|
|
|
|
0
|
$self->_pd("ReferralServer Match: $wi:$po", caller); |
352
|
0
|
|
0
|
|
|
0
|
my $data2 = $self->_query_whois($ip, $wi, $po, $self->{master_timeout}) || return; |
353
|
|
|
|
|
|
|
|
354
|
0
|
0
|
|
|
|
0
|
if($self->{stacked_results}){ |
355
|
0
|
|
|
|
|
0
|
$self->_pd("Stacking results", caller); |
356
|
0
|
0
|
|
|
|
0
|
return (!$self->{clean_stack} ? 'QUERY_0: ' . $server : undef) . "\n" . $data . "\n" . (!$self->{clean_stack} ? 'QUERY_1: ' . "$wi\:$po" : "") . "\n" . $data2; |
|
|
0
|
|
|
|
|
|
357
|
|
|
|
|
|
|
} else { |
358
|
0
|
0
|
|
|
|
0
|
return ($data2 ? $data2 : $data); |
359
|
|
|
|
|
|
|
} |
360
|
|
|
|
|
|
|
} |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
|
363
|
0
|
|
|
|
|
0
|
WHOIS: for my $whoisd (keys %hints){ |
364
|
0
|
|
|
|
|
0
|
$self->_pd($whoisd, caller); |
365
|
0
|
|
|
|
|
0
|
HINT: for my $re (@{$hints{$whoisd}->{regexps}}){ |
|
0
|
|
|
|
|
0
|
|
366
|
0
|
|
|
|
|
0
|
$re = "\$data =~ $re"; |
367
|
0
|
|
|
|
|
0
|
$self->_pd("Testing: $re", caller); |
368
|
0
|
0
|
|
|
|
0
|
if(eval $re){ |
369
|
0
|
|
|
|
|
0
|
$self->_pd("Match!", caller); |
370
|
0
|
|
0
|
|
|
0
|
my $data2 = $self->_query_whois($hints{$whoisd}->{'s_tag'} . $ip . $hints{$whoisd}->{'e_tag'}, $whoisd, $hints{$whoisd}->{'port'}, $hints{$whoisd}->{'timeout'} || $self->{master_timeout}) || |
371
|
|
|
|
|
|
|
return undef; |
372
|
0
|
0
|
|
|
|
0
|
if($self->{stacked_results}){ |
373
|
0
|
|
|
|
|
0
|
$self->_pd("Stacking results", caller); |
374
|
0
|
0
|
|
|
|
0
|
return (!$self->{clean_stack} ? 'QUERY_0: ' . $server : undef) . "\n" . $data . "\n" . (!$self->{clean_stack} ? 'QUERY_1: ' . $whoisd : undef) . "\n" . $data2; |
|
|
0
|
|
|
|
|
|
375
|
|
|
|
|
|
|
} else { |
376
|
0
|
0
|
|
|
|
0
|
return ($data2 ? $data2 : $data); |
377
|
|
|
|
|
|
|
} |
378
|
|
|
|
|
|
|
} |
379
|
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
} |
381
|
0
|
|
|
|
|
0
|
return $data; |
382
|
|
|
|
|
|
|
} |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
=head2 whois_ipv6(IPv6_address) |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
Preform an IPv6 whois query on B |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
=cut |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
sub whois_ipv6 { |
391
|
0
|
|
|
0
|
1
|
0
|
my ($self, @ip) = (shift, split(/:/, shift, 8)); |
392
|
|
|
|
|
|
|
# This is the IPv6 hints data |
393
|
|
|
|
|
|
|
# each regexp# represents a differnt chunk of the ipv6 ip block. |
394
|
|
|
|
|
|
|
# If you know if any pTLA's which aren't in this please |
395
|
|
|
|
|
|
|
# send me an email and ill add them cfaber@fpsn.net |
396
|
|
|
|
|
|
|
# |
397
|
0
|
|
|
|
|
0
|
my %hints = ( |
398
|
|
|
|
|
|
|
# The 6bone testbed pTLD |
399
|
|
|
|
|
|
|
'whois.6bone.net' => { |
400
|
|
|
|
|
|
|
port => 43, |
401
|
|
|
|
|
|
|
regexps => ['/^3ffe/i','/^5[fF][0-fF][0-fF]/'], |
402
|
|
|
|
|
|
|
}, |
403
|
|
|
|
|
|
|
# The APNIC IPv6 block |
404
|
|
|
|
|
|
|
'whois.apnic.net' => { |
405
|
|
|
|
|
|
|
port => 43, |
406
|
|
|
|
|
|
|
regexps => ['/^2001/','/^2[0-fF][0-fF]/'], |
407
|
|
|
|
|
|
|
}, |
408
|
|
|
|
|
|
|
# The ARIN IPv6 block |
409
|
|
|
|
|
|
|
'whois.arin.net' => { |
410
|
|
|
|
|
|
|
port => 43, |
411
|
|
|
|
|
|
|
regexps => ['/^2001/','/^4[0-fF][0-fF]/'], |
412
|
|
|
|
|
|
|
}, |
413
|
|
|
|
|
|
|
# The RIPE IPv6 block |
414
|
|
|
|
|
|
|
'whois.ripe.net' => { |
415
|
|
|
|
|
|
|
port => 43, |
416
|
|
|
|
|
|
|
regexps => ['/^2001/','/^6[0-fF][0-fF]/','/^2002/'], |
417
|
|
|
|
|
|
|
}, |
418
|
|
|
|
|
|
|
); |
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
|
421
|
0
|
|
|
|
|
0
|
WHOIS: for my $whoisd (keys %hints){ |
422
|
0
|
|
|
|
|
0
|
$self->_pd($whoisd, caller); |
423
|
0
|
|
|
|
|
0
|
HINT: for my $re (@{$hints{$whoisd}->{regexps}}){ |
|
0
|
|
|
|
|
0
|
|
424
|
0
|
|
|
|
|
0
|
$re = "\$ip[0] =~ $re"; |
425
|
0
|
|
|
|
|
0
|
$self->_pd("Testing: $re", caller); |
426
|
0
|
0
|
|
|
|
0
|
if(eval $re){ |
427
|
0
|
|
|
|
|
0
|
$self->_pd("Match!", caller); |
428
|
0
|
|
0
|
|
|
0
|
my $data = $self->_query_whois($hints{$whoisd}->{'s_tag'} . join(':', @ip) . $hints{$whoisd}->{'e_tag'}, $whoisd, $hints{$whoisd}->{'port'}, $hints{$whoisd}->{'timeout'} || $self->{master_timeout}) || return undef; |
429
|
0
|
|
|
|
|
0
|
return $data; |
430
|
|
|
|
|
|
|
} |
431
|
|
|
|
|
|
|
} |
432
|
|
|
|
|
|
|
} |
433
|
|
|
|
|
|
|
|
434
|
0
|
|
|
|
|
0
|
return $self->_seterrstr("IPv6 Lookup failure: Unknown mask range."); |
435
|
|
|
|
|
|
|
} |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
=head2 whois_bgp_as(ID) |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
Preform an whois query on an anonymous system number on the IPv4 BGP tree. |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
=cut |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
sub whois_bgp_as { |
445
|
0
|
|
|
0
|
1
|
0
|
my ($self, $id) = @_; |
446
|
0
|
|
|
|
|
0
|
$id =~ s/[^0-9]+//g; |
447
|
0
|
0
|
|
|
|
0
|
return $self->_seterrstr("whois_bgp_as() requires a valid id") if(!$id); |
448
|
|
|
|
|
|
|
|
449
|
0
|
|
|
|
|
0
|
my %as_table = ( |
450
|
|
|
|
|
|
|
'whois.arin.net' => { |
451
|
|
|
|
|
|
|
as_table => [ |
452
|
|
|
|
|
|
|
[1, 1876], |
453
|
|
|
|
|
|
|
[1902, 2042], |
454
|
|
|
|
|
|
|
[2044, 2046], |
455
|
|
|
|
|
|
|
[2048, 2106], |
456
|
|
|
|
|
|
|
[2137, 2584], |
457
|
|
|
|
|
|
|
[2615, 2772], |
458
|
|
|
|
|
|
|
[2823, 2829], |
459
|
|
|
|
|
|
|
[2880, 3153], |
460
|
|
|
|
|
|
|
[3354, 4607], |
461
|
|
|
|
|
|
|
[4865, 5376], |
462
|
|
|
|
|
|
|
[5632, 6655], |
463
|
|
|
|
|
|
|
[6912, 7466], |
464
|
|
|
|
|
|
|
[7723, 8191], |
465
|
|
|
|
|
|
|
[11264, 12287], |
466
|
|
|
|
|
|
|
[13312, 14335], |
467
|
|
|
|
|
|
|
], |
468
|
|
|
|
|
|
|
port => 43, |
469
|
|
|
|
|
|
|
's_tag' => 'AS', |
470
|
|
|
|
|
|
|
}, |
471
|
|
|
|
|
|
|
'whois.ripe.net' => { |
472
|
|
|
|
|
|
|
as_table => [ |
473
|
|
|
|
|
|
|
[1877, 1901], |
474
|
|
|
|
|
|
|
[2043], |
475
|
|
|
|
|
|
|
[2047], |
476
|
|
|
|
|
|
|
[2107, 2136], |
477
|
|
|
|
|
|
|
[2585, 2614], |
478
|
|
|
|
|
|
|
[2773, 2822], |
479
|
|
|
|
|
|
|
[2830, 2879], |
480
|
|
|
|
|
|
|
[3154, 3353], |
481
|
|
|
|
|
|
|
[5377, 5631], |
482
|
|
|
|
|
|
|
[6656, 6911], |
483
|
|
|
|
|
|
|
[8192, 9215], |
484
|
|
|
|
|
|
|
[12288, 13311], |
485
|
|
|
|
|
|
|
], |
486
|
|
|
|
|
|
|
port => 43, |
487
|
|
|
|
|
|
|
's_tag' => 'AS', |
488
|
|
|
|
|
|
|
}, |
489
|
|
|
|
|
|
|
'whois.apnic.net' => { |
490
|
|
|
|
|
|
|
as_table => [ |
491
|
|
|
|
|
|
|
[4608, 4864], |
492
|
|
|
|
|
|
|
[7467, 7722], |
493
|
|
|
|
|
|
|
[9216, 10239], |
494
|
|
|
|
|
|
|
], |
495
|
|
|
|
|
|
|
port => 43, |
496
|
|
|
|
|
|
|
's_tag' => 'AS', |
497
|
|
|
|
|
|
|
}, |
498
|
|
|
|
|
|
|
); |
499
|
|
|
|
|
|
|
|
500
|
0
|
|
|
|
|
0
|
for my $whoisd (keys %as_table){ |
501
|
0
|
|
|
|
|
0
|
for my $entry (@{$as_table{$whoisd}->{as_table}}){ |
|
0
|
|
|
|
|
0
|
|
502
|
0
|
0
|
0
|
|
|
0
|
if($entry->[0] && $entry->[1]){ |
|
|
0
|
|
|
|
|
|
503
|
0
|
0
|
0
|
|
|
0
|
if($id >= $entry->[0] && $id <= $entry->[1]){ |
504
|
0
|
|
0
|
|
|
0
|
my $data = $self->_query_whois($as_table{$whoisd}->{'s_tag'} . $id . $as_table{$whoisd}->{'e_tag'}, $whoisd, $as_table{$whoisd}->{port}, $as_table{$whoisd}->{timeout} || $self->{master_timeout}) || |
505
|
|
|
|
|
|
|
return undef; |
506
|
0
|
|
|
|
|
0
|
return $data; |
507
|
|
|
|
|
|
|
} |
508
|
|
|
|
|
|
|
} elsif($id == $entry->[0]){ |
509
|
0
|
|
0
|
|
|
0
|
my $data = $self->_query_whois($as_table{$whoisd}->{'s_tag'} . $id . $as_table{$whoisd}->{'e_tag'}, $whoisd, $as_table{$whoisd}->{port}, $as_table{$whoisd}->{timeout} || $self->{master_timeout}) || |
510
|
|
|
|
|
|
|
return undef; |
511
|
0
|
|
|
|
|
0
|
return $data; |
512
|
|
|
|
|
|
|
} |
513
|
|
|
|
|
|
|
} |
514
|
|
|
|
|
|
|
} |
515
|
|
|
|
|
|
|
|
516
|
0
|
|
|
|
|
0
|
return $self->_seterrstr("Unable to lookup entry for AS ID $id"); |
517
|
|
|
|
|
|
|
} |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
=head2 whois_domain(FQDN[, whois, port, timeout) |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
Preform a recursive whois lookup on a fully qualified domain name (FQDN), Optionally preform the initial query against the B whois server on port B with the timeout B. |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
=cut |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
sub whois_domain { |
526
|
1
|
|
|
1
|
1
|
3
|
my ($self, $domain, $server, $port, $timeout) = @_; |
527
|
1
|
|
|
|
|
4
|
my $nic; |
528
|
|
|
|
|
|
|
|
529
|
1
|
50
|
33
|
|
|
11
|
if(!$domain || $domain !~ /^[0-9A-Za-z-]+\.[A-Za-z]{2,4}$/){ |
530
|
0
|
|
|
|
|
0
|
return $self->_seterrstr("Domain name appears invalid"); |
531
|
|
|
|
|
|
|
} else { |
532
|
1
|
|
50
|
|
|
29
|
my $data = $self->_query_whois('=' . $domain, $server || $self->{master_domain_whois}, $port || $self->{master_domain_port}, $timeout || $self->{master_timeout}) || return $self->_seterrstr("_query_whois() failed to return any data. Possible error(s): " . ($self->errstr ? $self->errstr : 'Unknown')); |
533
|
|
|
|
|
|
|
|
534
|
0
|
0
|
|
|
|
0
|
if($data =~ /Whois\s?Server:\s?([A-Za-z0-9.-]+\.[A-Za-z]{2}[A-Za-z]?)/i){ |
535
|
0
|
|
|
|
|
0
|
$nic = $1; |
536
|
|
|
|
|
|
|
} |
537
|
|
|
|
|
|
|
|
538
|
0
|
0
|
0
|
|
|
0
|
if(!$nic && $data){ |
|
|
0
|
|
|
|
|
|
539
|
0
|
0
|
|
|
|
0
|
return ($data ? $data : 'Server returned no data'); |
540
|
|
|
|
|
|
|
} elsif($nic) { |
541
|
0
|
|
0
|
|
|
0
|
my $data2 = $self->_query_whois($domain, $nic, $port || $self->{master_domain_port}, $timeout || $self->{master_timeout}) || return $self->_seterrstr("_query_whois() failed to return any data. Possible error(s): " . ($self->errstr ? $self->errstr : 'Unknown')); |
542
|
|
|
|
|
|
|
|
543
|
0
|
0
|
|
|
|
0
|
if($self->{stacked_results}){ |
544
|
0
|
0
|
|
|
|
0
|
return (!$self->{clean_stack} ? 'QUERY_0: ' . $server : undef) . "\n" . $data . "\n" . (!$self->{clean_stack} ? 'QUERY_1: ' . $nic : undef) . "\n" . $data2; |
|
|
0
|
|
|
|
|
|
545
|
|
|
|
|
|
|
} else { |
546
|
0
|
0
|
|
|
|
0
|
return ($data2 ? $data2 : 'Server returned no data'); |
547
|
|
|
|
|
|
|
} |
548
|
|
|
|
|
|
|
} else { |
549
|
0
|
|
|
|
|
0
|
return $self->_seterrstr("Domain lookup failed."); |
550
|
|
|
|
|
|
|
} |
551
|
|
|
|
|
|
|
} |
552
|
|
|
|
|
|
|
} |
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
=head2 check_ipv4(IPv4_dotted_quad) |
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
Attempt to determin if an IPv4 address is syntaxually valid. |
557
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
=cut |
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
sub check_ipv4 { |
561
|
1
|
|
|
1
|
1
|
6
|
my ($self, @ip) = (shift, split(/\./, shift, 4)); |
562
|
|
|
|
|
|
|
|
563
|
1
|
50
|
33
|
|
|
12
|
if(!$ip[0] || $ip[-1] !~ /\d/ || $ip[0] > 255 || $ip[0] !~ /^\d+$/){ |
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
564
|
1
|
|
|
|
|
6
|
return $self->_seterrstr("Invalid IPv4 address"); |
565
|
|
|
|
|
|
|
} else { |
566
|
0
|
|
|
|
|
0
|
for my $i (1 .. 3){ |
567
|
0
|
0
|
0
|
|
|
0
|
if($ip[$i] > 255 || $ip[$i] !~ /^\d+$/){ |
568
|
0
|
|
|
|
|
0
|
return $self->_seterrstr("Invalid IPv4 address"); |
569
|
|
|
|
|
|
|
} |
570
|
|
|
|
|
|
|
} |
571
|
0
|
|
|
|
|
0
|
return join('.', @ip); |
572
|
|
|
|
|
|
|
} |
573
|
|
|
|
|
|
|
} |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
=head2 errstr() |
576
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
Return the last error message set. |
578
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
=cut |
580
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
sub errstr { |
582
|
5
|
|
|
5
|
1
|
6
|
my ($self, $err) = @_; |
583
|
5
|
100
|
|
|
|
14
|
$self->{errstr} = $err if($err); |
584
|
5
|
|
|
|
|
16
|
return $self->{errstr}; |
585
|
|
|
|
|
|
|
} |
586
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
=head2 whois_ptr(IPv4_dotted_quad_address); |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
Return the PTR / Reverse domain name of a dotted quad IPv4 address. |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
=cut |
592
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
sub whois_ptr { |
594
|
0
|
|
|
0
|
1
|
0
|
my ($self, $ip) = @_; |
595
|
0
|
|
|
|
|
0
|
my $name = (gethostbyaddr(pack('C4', split(/\./, $ip, 4)), 2))[0]; |
596
|
0
|
0
|
|
|
|
0
|
return ($name ? $name : $self->_seterrstr("The $ip failed to contain a valid PTR record")); |
597
|
|
|
|
|
|
|
} |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
=head2 whois_raw(command, server, port, timeout) |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
Preform a raw whois with B against the whois server B on the port B with the timeout B/ |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
=cut |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
sub whois_raw { |
606
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
607
|
0
|
|
|
|
|
0
|
return $self->_query_whois(@_); |
608
|
|
|
|
|
|
|
} |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
sub _query_whois { |
611
|
1
|
|
|
1
|
|
3
|
my ($self, $data, $serv, $port, $timeout) = @_; |
612
|
1
|
|
|
|
|
2
|
my $sock; |
613
|
|
|
|
|
|
|
|
614
|
1
|
|
50
|
|
|
7
|
$self->{master_timeout} ||= 10; |
615
|
|
|
|
|
|
|
|
616
|
1
|
|
33
|
|
|
12
|
$port ||= $self->{master_port}; |
617
|
1
|
|
33
|
|
|
4
|
$serv ||= $self->{master_serv}; |
618
|
1
|
|
33
|
|
|
8
|
$timeout ||= $self->{master_timeout}; |
619
|
|
|
|
|
|
|
|
620
|
1
|
|
|
|
|
8
|
$self->_pd("Attempting to connect to: $serv:$port (to: $timeout)", caller); |
621
|
|
|
|
|
|
|
|
622
|
1
|
|
|
|
|
3
|
eval { |
623
|
1
|
|
|
0
|
|
33
|
$SIG{ALRM} = sub { die 'timeout'; }; |
|
0
|
|
|
|
|
0
|
|
624
|
1
|
|
33
|
|
|
13
|
alarm(($timeout || $self->{master_timeout}) + 5); |
625
|
1
|
|
50
|
|
|
21
|
$sock = IO::Socket::INET->new( |
626
|
|
|
|
|
|
|
Proto => 'tcp', |
627
|
|
|
|
|
|
|
PeerAddr => $serv || $self->{master_whois}, |
628
|
|
|
|
|
|
|
PeerPort => $port || $self->{master_port}, |
629
|
|
|
|
|
|
|
Timeout => $timeout || $self->{master_timeout} |
630
|
|
|
|
|
|
|
) || die "Unable to create socket $!"; |
631
|
0
|
|
|
|
|
0
|
alarm(0); |
632
|
|
|
|
|
|
|
}; |
633
|
1
|
50
|
|
|
|
10017283
|
if($@ =~ /timeout/){ |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
634
|
0
|
|
|
|
|
0
|
$self->_pd("Timed out!", caller); |
635
|
0
|
|
0
|
|
|
0
|
return $self->_seterrstr("Connection to " . ($serv || $self->{master_whois}) . ':' . ($port || $self->{master_port}) . " was refused."); |
|
|
|
0
|
|
|
|
|
636
|
|
|
|
|
|
|
} elsif($@){ |
637
|
1
|
|
|
|
|
13
|
$self->_pd("Failure: $@", caller); |
638
|
1
|
|
33
|
|
|
16
|
return $self->_seterrstr("Unknown error while connecting to " . ($serv || $self->{master_whois}) . ':' . ($port || $self->{master_port}) . '.'); |
|
|
|
33
|
|
|
|
|
639
|
|
|
|
|
|
|
} elsif(!$sock){ |
640
|
0
|
|
|
|
|
0
|
$self->_pd("Failure: Connection failed", caller); |
641
|
0
|
|
0
|
|
|
0
|
return $self->_seterrstr("Unable to connect to " . ($serv || $self->{master_whois}) . ':' . ($port || $self->{master_port}) . '.'); |
|
|
|
0
|
|
|
|
|
642
|
|
|
|
|
|
|
} else { |
643
|
0
|
|
|
|
|
0
|
$self->_pd("Connected. Sending data: $data", caller, caller); |
644
|
0
|
0
|
|
|
|
0
|
$data .= "\r\n" if($data !~ /[\r\n]+$/); |
645
|
0
|
|
|
|
|
0
|
print $sock $data; |
646
|
0
|
|
|
|
|
0
|
my @data = <$sock>; |
647
|
0
|
0
|
0
|
|
|
0
|
return (@data && wantarray ? @data : (@data ? "@data" : $self->_seterrstr("Query on ``$data'' failed to return results" . ($! ? ': ' . $! : undef)))); |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
648
|
|
|
|
|
|
|
} |
649
|
|
|
|
|
|
|
} |
650
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
sub _seterrstr { |
652
|
3
|
|
|
3
|
|
6
|
my ($self, $err) = @_; |
653
|
3
|
|
|
|
|
17
|
$self->errstr($err); |
654
|
3
|
|
|
|
|
21
|
return; |
655
|
|
|
|
|
|
|
} |
656
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
sub _clean { |
658
|
0
|
|
|
0
|
|
0
|
my ($self, @lines) = @_; |
659
|
0
|
|
|
|
|
0
|
for(my $i = 0; $i < @lines; $i++){ |
660
|
0
|
|
|
|
|
0
|
$lines[$i] =~ s/^\s+|\s+$//g; |
661
|
0
|
|
|
|
|
0
|
$lines[$i] =~ s/[\r\n\x0A\x0D]+//g; |
662
|
|
|
|
|
|
|
} |
663
|
0
|
0
|
|
|
|
0
|
return (wantarray ? @lines : join("\n", @lines)); |
664
|
|
|
|
|
|
|
} |
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
sub _pd { |
667
|
4
|
|
|
4
|
|
12
|
my ($self, $msg, $pkg, $file, $line) = (shift, shift, @_); |
668
|
4
|
|
|
|
|
11
|
my ($l_pkg, $l_file, $l_line) = caller; |
669
|
|
|
|
|
|
|
|
670
|
4
|
|
|
|
|
10
|
$self->{_debug_cnt}++; |
671
|
4
|
50
|
|
|
|
12
|
if($self->{debug}){ |
672
|
0
|
|
|
|
|
0
|
my $str = sprintf("[%5d] internal->{ $l_pkg on $l_line line } external->{ $file\->$pkg on $line } data->{ %s }\r\n", $self->{_debug_cnt}, scalar $msg); |
673
|
0
|
0
|
|
|
|
0
|
if($self->{debug} eq 1){ |
674
|
0
|
|
|
|
|
0
|
print STDOUT $str; |
675
|
|
|
|
|
|
|
} else { |
676
|
0
|
|
|
|
|
0
|
my $handle = $self->{debug}; |
677
|
0
|
|
|
|
|
0
|
print $handle $str; |
678
|
|
|
|
|
|
|
} |
679
|
|
|
|
|
|
|
} |
680
|
4
|
|
|
|
|
9
|
return 1; |
681
|
|
|
|
|
|
|
} |
682
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
1; |
684
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
__END__ |