package Net::pWhoIs; use strict; use Socket; use IO::Socket::INET; use Scalar::Util 'reftype'; our $VERSION = '0.02'; $| = 1; ###################################################### sub new { ###################################################### my ($class, $args) = @_; my $self; my %defaults = ( pwhoisserver => 'whois.pwhois.org', port => 43, ); # Apply defaults. for my $key (keys %defaults) { $self->{$key} = $defaults{$key}; } # Apply arguments passed by human. # They may clobber our defaults. for my $key (keys %{$args}) { $self->{$key} = $args->{$key}; } bless $self, $class; return $self; } ###################################################### sub resolveReq { ###################################################### my $self = shift; my $what = shift; if ($what !~ /\\d+\\.\\d+\\.\\d+\\.\\d+/) { my @host = gethostbyname($what); if (scalar(@host) == 0) { die "Failed host to resolve to IP: $what\n"; } else { return Socket::inet_ntoa($host[4]); } } } ###################################################### sub pwhois { ###################################################### my $self = shift; my $what = shift; my @req; if (Scalar::Util::reftype($what) eq 'ARRAY') { @req = @{$what}; } else { push @req, $what; } my $socket = new IO::Socket::INET ( PeerHost => $self->{pwhoisserver}, PeerPort => $self->{port}, Proto => 'tcp', ); die "Cannot connect to server $!\n" unless $socket; # Build request my $request = "begin\n"; for my $elmt (@req) { my $resolved = $self->resolveReq($elmt); $request .= "$resolved\n"; } $request .= "end\n"; $socket->send($request); shutdown($socket, 1); my $responses; while (my $line = $socket->getline) { $responses .= $line; } $socket->close(); my %results; my $cntr = 0; for my $response (split /\n\n/, $responses) { my $formatted = $self->formatResponse($response); $results{$req[$cntr++]} = $formatted; } return \%results; } ###################################################### sub formatResponse { ###################################################### my $self = shift; my $what = shift; my @lines = split /\n/, $what; my %formatted; for my $line (@lines) { my ($name, $value) = split /:\s/, $line; if ($name && $value) { $formatted{lc($name)} = $value; } } return \%formatted; } ###################################################### sub printReport { ###################################################### my $self = shift; my $what = shift; my $report; for my $req (keys %{$what}) { $report .= sprintf ("Request: %s\n", $req); for my $key (keys %{$what->{$req}}) { $report .= sprintf("%-22s : %s\n", $key, $what->{$req}{$key}); } } return $report; } 1; =head1 NAME Net::pWhoIs - Client library for Prefix WhoIs (pWhois) =head1 SYNOPSIS use Net::pWhoIs; my $obj = Net::pWhoIs->new(); # You may pass hostnames or IP addresses. my @array = qw( 166.70.12.30 207.20.243.105 67.225.131.208 perlmonks.org 8.8.8.8 12.12.12.12 ftp2.freebsd.org ); # You can pass an array. my $output = $obj->pwhois(\@array); # Or you can pass a single string. my $output = $obj->pwhois('8.8.8.8'); # Generate a formatted report. print $obj->printReport($output); # Or manipulate the data yourself. for my $req (keys %{$output}) { printf ("Request: %s\n", $req); for my $key (keys %{$output->{$req}}) { print sprintf("%-22s : %s\n", $key, $output->{$req}{$key}); } } =head1 DESCRIPTION Client library for pWhois service. Includes support for bulk queries. =head1 CONSTRUCTOR =over 4 =item $obj = Net::pWhoIs->new( %options ) Construct a new C<Net::pWhoIs> object and return it. Key/value pair arguments may be provided to set up the initial state. The only require argument is: req. pwhoisserver whois.pwhois.org port 43 req Required argument, value must be an array reference. =back =head1 METHODS The following methods are available: =over 4 =item Net::pWhoIs->pwhois() Perform queries on passed arrayref. Supports single or bulk query. Returns a hash of hashrefs. =back =over 4 =item Net::pWhoIs->printReport() Perform queries on passed arrayref. Supports single or bulk query. Returns a hash of hashrefs. =back =head1 Client A full featured client is included: pwhoiscli.pl. Pass it hostnames or IP seperated by space. =head1 OUTPUT HASHREF KEYS The following is the list hashref keys returned by pwhois. as-org-name as-path cache-date city country country-code ip latitude longitude net-name org-name origin-as prefix region route-originated-date route-originated-ts =head1 AUTHOR Matt Hersant <matt_hersant@yahoo.com> =cut