… | |
… | |
4 | |
4 | |
5 | use Socket; |
5 | use Socket; |
6 | use Fcntl; |
6 | use Fcntl; |
7 | |
7 | |
8 | use Coro; |
8 | use Coro; |
9 | use Coro::Event; |
9 | use Coro::EV; |
10 | use Coro::Semaphore; |
10 | use Coro::Semaphore; |
11 | use Coro::SemaphoreSet; |
11 | use Coro::SemaphoreSet; |
12 | use Coro::Socket; |
12 | use Coro::Socket; |
|
|
13 | use Coro::Timer; |
13 | |
14 | |
14 | use BerkeleyDB; |
15 | use BerkeleyDB; |
15 | |
|
|
16 | $Event::DIED = sub { |
|
|
17 | Event::verbose_exception_handler(@_); |
|
|
18 | #Event::unloop_all(); |
|
|
19 | }; |
|
|
20 | |
16 | |
21 | tie %netgeo::whois, BerkeleyDB::Btree, |
17 | tie %netgeo::whois, BerkeleyDB::Btree, |
22 | -Env => $db_env, |
18 | -Env => $db_env, |
23 | -Filename => "whois", |
19 | -Filename => "whois", |
24 | -Flags => DB_CREATE, |
20 | -Flags => DB_CREATE, |
… | |
… | |
29 | -Flags => DB_CREATE, |
25 | -Flags => DB_CREATE, |
30 | or die "unable to create/open iprange table"; |
26 | or die "unable to create/open iprange table"; |
31 | |
27 | |
32 | package Whois; |
28 | package Whois; |
33 | |
29 | |
34 | use Coro::Event; |
30 | use Coro::EV; |
35 | |
31 | |
36 | sub new { |
32 | sub new { |
37 | my $class = shift; |
33 | my $class = shift; |
38 | my $name = shift; |
34 | my $name = shift; |
39 | my $ip = shift; |
35 | my $ip = shift; |
… | |
… | |
83 | $timeout *= 2; |
79 | $timeout *= 2; |
84 | $timeout = 1 if $timeout > 600; |
80 | $timeout = 1 if $timeout > 600; |
85 | } else { |
81 | } else { |
86 | last; |
82 | last; |
87 | } |
83 | } |
|
|
84 | } else { |
|
|
85 | # only retry once a minute |
|
|
86 | print STDERR "unable to connect to $self->{ip} ($self->{name}), retrying...\n"; |
|
|
87 | Coro::Timer::sleep 300; |
88 | } |
88 | } |
89 | } |
89 | } |
90 | |
90 | |
91 | $netgeo::whois{$id} = $whois; |
91 | $netgeo::whois{$id} = $whois; |
92 | } |
92 | } |
… | |
… | |
115 | sub ip_request { |
115 | sub ip_request { |
116 | my ($self, $ip) = @_; |
116 | my ($self, $ip) = @_; |
117 | |
117 | |
118 | my $whois = $self->whois_request($ip); |
118 | my $whois = $self->whois_request($ip); |
119 | |
119 | |
120 | return () if $whois =~ /^No match/; |
120 | return if $whois =~ /^No match/; |
121 | |
121 | |
122 | if ($whois =~ /^To single out one record/m) { |
122 | if ($whois =~ /^To single out one record/m) { |
123 | my $handle; |
123 | my $handle; |
124 | while ($whois =~ /\G\S.*\(([A-Z0-9\-]+)\).*\n/mg) { |
124 | while ($whois =~ /\G\S.*\(([A-Z0-9\-]+)\).*\n/mg) { |
125 | $handle = $1; |
125 | $handle = $1; |
126 | #return if $handle =~ /-(RIPE|APNIC)/; # heuristic, bbut bad because ripe might not have better info |
126 | #return if $handle =~ /-(RIPE|APNIC)/; # heuristic, but bad because ripe might not have better info |
127 | } |
127 | } |
128 | $handle or die "$whois ($ip): unparseable multimatch\n"; |
128 | $handle or die "$whois ($ip): unparseable multimatch\n"; |
129 | $whois = $self->whois_request("!$handle"); |
129 | $whois = $self->whois_request("!$handle"); |
130 | } |
130 | } |
131 | |
131 | |
… | |
… | |
183 | s/^admin-c:\s+/*ac: /gm; |
183 | s/^admin-c:\s+/*ac: /gm; |
184 | s/^tech-c:\s+/*tc: /gm; |
184 | s/^tech-c:\s+/*tc: /gm; |
185 | s/^owner-c:\s+/*oc: /gm; |
185 | s/^owner-c:\s+/*oc: /gm; |
186 | s/^country:\s+/*cy: /gm; |
186 | s/^country:\s+/*cy: /gm; |
187 | s/^phone:\s+/*ph: /gm; |
187 | s/^phone:\s+/*ph: /gm; |
188 | s/^remarks:\s+/*re: /gm; |
188 | s/^remarks:\s+/*rm: /gm; |
189 | s/^changed:\s+/*ch: /gm; |
189 | s/^changed:\s+/*ch: /gm; |
190 | s/^created:\s+/*cr: /gm; |
190 | s/^created:\s+/*cr: /gm; |
191 | s/^address:\s+/*ad: /gm; |
191 | s/^address:\s+/*ad: /gm; |
192 | s/^status:\s+/*st: /gm; |
192 | s/^status:\s+/*st: /gm; |
193 | s/^inetrev:\s+/*ir: /gm; |
193 | s/^inetrev:\s+/*ir: /gm; |
… | |
… | |
225 | }gex; |
225 | }gex; |
226 | |
226 | |
227 | $whois =~ /^\*in: 0\.0\.0\.0 - 255\.255\.255\.255/ |
227 | $whois =~ /^\*in: 0\.0\.0\.0 - 255\.255\.255\.255/ |
228 | and return; |
228 | and return; |
229 | |
229 | |
|
|
230 | $whois =~ /^\*de: This network range is not allocated to /m # APINIC e.g. 24.0.0.0 |
|
|
231 | and return; |
|
|
232 | |
230 | $whois =~ /^\*ac: XXX0/m # 192.0.0.0 |
233 | $whois =~ /^\*ac: XXX0/m # 192.0.0.0 |
231 | and return; |
234 | and return; |
232 | |
235 | |
233 | $whois =~ /^\*st: (?:ALLOCATED )?UNSPECIFIED/m |
236 | $whois =~ /^\*st: (?:ALLOCATED )?UNSPECIFIED/m |
234 | and return; |
237 | and return; |
… | |
… | |
263 | s/^ip-network-block:/*in:/gm; |
266 | s/^ip-network-block:/*in:/gm; |
264 | s/^country-code:/*cy:/gm; |
267 | s/^country-code:/*cy:/gm; |
265 | s/^tech-contact;i:/*tc:/gm; |
268 | s/^tech-contact;i:/*tc:/gm; |
266 | s/^updated:/*ch:/gm; |
269 | s/^updated:/*ch:/gm; |
267 | s/^street-address:/*ad:/gm; |
270 | s/^street-address:/*ad:/gm; |
268 | s/^org-name:/*re:/gm; |
271 | s/^org-name:/*rm:/gm; |
269 | s/^created:/*cr:/gm; |
272 | s/^created:/*cr:/gm; |
270 | |
273 | |
271 | $_; |
274 | $_; |
272 | } |
275 | } |
273 | |
276 | |
… | |
… | |
311 | |
314 | |
312 | our %WHOIS; |
315 | our %WHOIS; |
313 | |
316 | |
314 | #$WHOIS{ARIN} = new Whois::ARIN ARIN => "whois.arin.net", port => 43, maxjobs => 12; |
317 | #$WHOIS{ARIN} = new Whois::ARIN ARIN => "whois.arin.net", port => 43, maxjobs => 12; |
315 | $WHOIS{ARIN} = new Whois::RWHOIS ARIN => "rwhois.arin.net", port => 4321, maxjobs => 12; |
318 | $WHOIS{ARIN} = new Whois::RWHOIS ARIN => "rwhois.arin.net", port => 4321, maxjobs => 12; |
316 | $WHOIS{RIPE} = new Whois::RIPE RIPE => "whois.ripe.net", port => 43, rflags => "-FSTin ", maxjobs => 20; |
319 | $WHOIS{RIPE} = new Whois::RIPE RIPE => "whois.ripe.net", port => 43, rflags => "-FTin ", maxjobs => 20; |
317 | $WHOIS{APNIC} = new Whois::RIPE APNIC => "whois.apnic.net", port => 43, rflags => "-FSTin ", maxjobs => 20; |
320 | $WHOIS{APNIC} = new Whois::RIPE APNIC => "whois.apnic.net", port => 43, rflags => "-FTin ", maxjobs => 20; |
318 | $WHOIS{LACNIC} = new Whois::RIPE LACNIC => "whois.lacnic.net", port => 43, maxjobs => 20; |
321 | $WHOIS{LACNIC} = new Whois::RIPE LACNIC => "whois.lacnic.net", port => 43, maxjobs => 20; |
319 | |
322 | |
320 | $whoislock = new Coro::SemaphoreSet; |
323 | $whoislock = new Coro::SemaphoreSet; |
321 | |
324 | |
322 | sub ip_request { |
325 | sub ip_request { |
… | |
… | |
336 | } |
339 | } |
337 | |
340 | |
338 | my ($arin, $ripe, $apnic); |
341 | my ($arin, $ripe, $apnic); |
339 | |
342 | |
340 | $whois = $WHOIS{RIPE}->ip_request($ip) |
343 | $whois = $WHOIS{RIPE}->ip_request($ip) |
341 | || $WHOIS{LACNIC}->ip_request($ip) |
|
|
342 | || $WHOIS{APNIC} ->ip_request($ip) |
344 | || $WHOIS{APNIC} ->ip_request($ip) |
343 | || $WHOIS{ARIN} ->ip_request($ip) |
345 | || $WHOIS{ARIN} ->ip_request($ip) |
|
|
346 | # || $WHOIS{LACNIC}->ip_request($ip) |
344 | ; |
347 | ; |
345 | |
348 | |
346 | $whois =~ /^\*in: ([0-9.]+)\s+-\s+([0-9.]+)\s*$/mi |
349 | $whois =~ /^\*in: ([0-9.]+)\s+-\s+([0-9.]+)\s*$/mi |
347 | or do { warn "$whois($ip): no addresses found\n", last }; |
350 | or do { warn "$whois($ip): no addresses found\n", last }; |
348 | |
351 | |
… | |
… | |
372 | #print "\n\n"; |
375 | #print "\n\n"; |
373 | #print ip_request "62.116.167.250"; |
376 | #print ip_request "62.116.167.250"; |
374 | #print "\n\n"; |
377 | #print "\n\n"; |
375 | #print ip_request "133.11.128.254"; # jp |
378 | #print ip_request "133.11.128.254"; # jp |
376 | #print "\n\n"; |
379 | #print "\n\n"; |
377 | #print ip_request "151.197.52.251"; |
380 | print ip_request "80.131.153.93"; |
378 | #print "\n\n"; |
381 | print "\n\n"; |
379 | } |
382 | } |
380 | |
383 | |
381 | 1; |
384 | 1; |
382 | |
385 | |
383 | |
386 | |