package KholinWhoIs;

##
##  Kholin WhoIs   ( http://www.topgen.net )
##  KholinWhoIs.pm
##
##  (c) George Kholin, 2007
##

require Exporter;
@ISA    = qw( Exporter );
@EXPORT = qw( WhoIs
              FindIp);

use strict;
use Socket qw(:DEFAULT :crlf);
use IO::Handle;

my %WIS = (				# WhoIs Servers
  ARIN    => 'whois.arin.net' ,		# North America
  RIPE    => 'whois.ripe.net' ,		# Europe
  APNIC   => 'whois.apnic.net',		# Asia
  LACNIC  => 'whois.lacnic.net',	# Latin America
  AFRINIC => 'whois.afrinic.net'	# Africa
);

sub WhoIs ($$$) {	# Args: host, port, request
  my $host = gethostbyname($_[0]) or return 0;
  my $dest = sockaddr_in($_[1], $host);
  socket(SOCK, PF_INET, SOCK_STREAM, 6) or return 0;
  connect(SOCK, $dest) or return 0;
  SOCK->autoflush(1);
  print SOCK "$_[2]$CRLF";
  $_ = join '', <SOCK>;
  chomp;
  close SOCK;
  $_
}

sub DetectRIR ($) {
  my @l = split /\n/;
  foreach my $l (@l) {
    0 <= index $l, 'OrgID: ' and do {
      foreach my $k (keys %WIS) {
        0 <= index $l, " $k" and return $WIS{$k}
      }
    }
  }
}

sub DetectSubNet ($) {
  my @l = split /\n/;
  for (my $i = @l - 1; $i >= 0; $i--) {
    0 <= index $l[$i], '(NET-' and return substr $l[$i], (1 + index $l[$i], '(NET-'), -2
  }
}

sub FindIp ($) {
  my $wi = WhoIs $WIS{ARIN}, 43, $_[0];
  if (0 <= index $wi, 'OrgID: ') {
    $wi = WhoIs DetectRIR $wi, 43, $_[0]
  } else {
    0 <= index $wi, '(NET-' and $wi = WhoIs $WIS{ARIN}, 43, DetectSubNet $wi
  }
  $wi
}

1