Skip to content

Commit

Permalink
Merge branch 'release/Net-Whois-RIPE-2.005001'
Browse files Browse the repository at this point in the history
  • Loading branch information
arhuman committed Oct 11, 2013
2 parents cb23e73 + 6aab00d commit 63c060b
Show file tree
Hide file tree
Showing 33 changed files with 3,857 additions and 119 deletions.
6 changes: 6 additions & 0 deletions Changes
@@ -1,6 +1,12 @@
Revision history for net-whois-ripe Revision history for net-whois-ripe




2.005001 2013-10-11
- Add support for APNIC objects through Net::Whois::Generic
- Simplify query options handling in Net::Whois::Generic
(remove keepalive options)
- Start adding some documentation (far from enough although)

2.005000 2013-10-10 2.005000 2013-10-10
- Add support for generic objects (from various sources, AFRINIC being the first implemented) - Add support for generic objects (from various sources, AFRINIC being the first implemented)
through Net::Whois::Generic through Net::Whois::Generic
Expand Down
21 changes: 21 additions & 0 deletions MANIFEST
Expand Up @@ -4,50 +4,69 @@ lib/Net/Whois/Generic.pm
lib/Net/Whois/Object.pm lib/Net/Whois/Object.pm
lib/Net/Whois/Object/AsBlock.pm lib/Net/Whois/Object/AsBlock.pm
lib/Net/Whois/Object/AsBlock/AFRINIC.pm lib/Net/Whois/Object/AsBlock/AFRINIC.pm
lib/Net/Whois/Object/AsBlock/APNIC.pm
lib/Net/Whois/Object/AsSet.pm lib/Net/Whois/Object/AsSet.pm
lib/Net/Whois/Object/AsSet/AFRINIC.pm lib/Net/Whois/Object/AsSet/AFRINIC.pm
lib/Net/Whois/Object/AsSet/APNIC.pm
lib/Net/Whois/Object/AutNum.pm lib/Net/Whois/Object/AutNum.pm
lib/Net/Whois/Object/AutNum/AFRINIC.pm lib/Net/Whois/Object/AutNum/AFRINIC.pm
lib/Net/Whois/Object/AutNum/APNIC.pm
lib/Net/Whois/Object/Domain.pm lib/Net/Whois/Object/Domain.pm
lib/Net/Whois/Object/Domain/AFRINIC.pm lib/Net/Whois/Object/Domain/AFRINIC.pm
lib/Net/Whois/Object/Domain/APNIC.pm
lib/Net/Whois/Object/FilterSet.pm lib/Net/Whois/Object/FilterSet.pm
lib/Net/Whois/Object/FilterSet/AFRINIC.pm lib/Net/Whois/Object/FilterSet/AFRINIC.pm
lib/Net/Whois/Object/FilterSet/APNIC.pm
lib/Net/Whois/Object/Inet6Num.pm lib/Net/Whois/Object/Inet6Num.pm
lib/Net/Whois/Object/Inet6Num/AFRINIC.pm lib/Net/Whois/Object/Inet6Num/AFRINIC.pm
lib/Net/Whois/Object/Inet6Num/APNIC.pm lib/Net/Whois/Object/Inet6Num/APNIC.pm
lib/Net/Whois/Object/InetNum.pm lib/Net/Whois/Object/InetNum.pm
lib/Net/Whois/Object/InetNum/AFRINIC.pm lib/Net/Whois/Object/InetNum/AFRINIC.pm
lib/Net/Whois/Object/InetNum/APNIC.pm
lib/Net/Whois/Object/InetRtr.pm lib/Net/Whois/Object/InetRtr.pm
lib/Net/Whois/Object/InetRtr/AFRINIC.pm lib/Net/Whois/Object/InetRtr/AFRINIC.pm
lib/Net/Whois/Object/Information.pm lib/Net/Whois/Object/Information.pm
lib/Net/Whois/Object/Information/AFRINIC.pm lib/Net/Whois/Object/Information/AFRINIC.pm
lib/Net/Whois/Object/Irt.pm lib/Net/Whois/Object/Irt.pm
lib/Net/Whois/Object/Irt/AFRINIC.pm lib/Net/Whois/Object/Irt/AFRINIC.pm
lib/Net/Whois/Object/Irt/APNIC.pm
lib/Net/Whois/Object/KeyCert.pm lib/Net/Whois/Object/KeyCert.pm
lib/Net/Whois/Object/KeyCert/AFRINIC.pm lib/Net/Whois/Object/KeyCert/AFRINIC.pm
lib/Net/Whois/Object/KeyCert/APNIC.pm
lib/Net/Whois/Object/Limerick.pm lib/Net/Whois/Object/Limerick.pm
lib/Net/Whois/Object/Limerick/AFRINIC.pm lib/Net/Whois/Object/Limerick/AFRINIC.pm
lib/Net/Whois/Object/Mntner.pm lib/Net/Whois/Object/Mntner.pm
lib/Net/Whois/Object/Mntner/AFRINIC.pm lib/Net/Whois/Object/Mntner/AFRINIC.pm
lib/Net/Whois/Object/Mntner/APNIC.pm
lib/Net/Whois/Object/Organisation.pm lib/Net/Whois/Object/Organisation.pm
lib/Net/Whois/Object/Organisation/AFRINIC.pm lib/Net/Whois/Object/Organisation/AFRINIC.pm
lib/Net/Whois/Object/Organisation/APNIC.pm
lib/Net/Whois/Object/PeeringSet.pm lib/Net/Whois/Object/PeeringSet.pm
lib/Net/Whois/Object/PeeringSet/AFRINIC.pm lib/Net/Whois/Object/PeeringSet/AFRINIC.pm
lib/Net/Whois/Object/PeeringSet/APNIC.pm
lib/Net/Whois/Object/Person.pm lib/Net/Whois/Object/Person.pm
lib/Net/Whois/Object/Person/AFRINIC.pm lib/Net/Whois/Object/Person/AFRINIC.pm
lib/Net/Whois/Object/Person/APNIC.pm
lib/Net/Whois/Object/Poem.pm lib/Net/Whois/Object/Poem.pm
lib/Net/Whois/Object/Poem/APNIC.pm
lib/Net/Whois/Object/PoeticForm.pm lib/Net/Whois/Object/PoeticForm.pm
lib/Net/Whois/Object/PoeticForm/APNIC.pm
lib/Net/Whois/Object/Response.pm lib/Net/Whois/Object/Response.pm
lib/Net/Whois/Object/Role.pm lib/Net/Whois/Object/Role.pm
lib/Net/Whois/Object/Role/AFRINIC.pm lib/Net/Whois/Object/Role/AFRINIC.pm
lib/Net/Whois/Object/Role/APNIC.pm
lib/Net/Whois/Object/Route.pm lib/Net/Whois/Object/Route.pm
lib/Net/Whois/Object/Route/AFRINIC.pm lib/Net/Whois/Object/Route/AFRINIC.pm
lib/Net/Whois/Object/Route/APNIC.pm
lib/Net/Whois/Object/Route6.pm lib/Net/Whois/Object/Route6.pm
lib/Net/Whois/Object/Route6/AFRINIC.pm lib/Net/Whois/Object/Route6/AFRINIC.pm
lib/Net/Whois/Object/Route6/APNIC.pm
lib/Net/Whois/Object/RouteSet.pm lib/Net/Whois/Object/RouteSet.pm
lib/Net/Whois/Object/RouteSet/AFRINIC.pm lib/Net/Whois/Object/RouteSet/AFRINIC.pm
lib/Net/Whois/Object/RouteSet/APNIC.pm
lib/Net/Whois/Object/RtrSet.pm lib/Net/Whois/Object/RtrSet.pm
lib/Net/Whois/Object/RtrSet/AFRINIC.pm lib/Net/Whois/Object/RtrSet/AFRINIC.pm
lib/Net/Whois/Object/RtrSet/APNIC.pm
lib/Net/Whois/RIPE.pm lib/Net/Whois/RIPE.pm
Makefile.PL Makefile.PL
MANIFEST MANIFEST
Expand Down Expand Up @@ -88,7 +107,9 @@ t/210-FilterSet.t
t/215-SyncUpdates.t t/215-SyncUpdates.t
t/216-SyncUpdates-Signed.t t/216-SyncUpdates-Signed.t
t/300-AFRINIC.t t/300-AFRINIC.t
t/305-APNIC.t
t/boilerplate.t t/boilerplate.t
t/common.pl t/common.pl
t/pod-coverage.t t/pod-coverage.t
t/pod.t t/pod.t
TODO
4 changes: 3 additions & 1 deletion TODO
@@ -1,3 +1,5 @@
* make abuse-c attribute mandatory by end of september * check abuse-c/abuse-mailbox status
* add option to query to get unfiltered data (-B on RIPE) and check for mail on aassad-ripe * add option to query to get unfiltered data (-B on RIPE) and check for mail on aassad-ripe
(make it default ?) (make it default ?)
* change hardcoded options on query to non RIPE sources (use RIPE model)
* Add more usage examples
134 changes: 61 additions & 73 deletions lib/Net/Whois/Generic.pm
Expand Up @@ -13,48 +13,56 @@ use constant {
SOON => 30, SOON => 30,
END_OF_OBJECT_MARK => "\n\n", END_OF_OBJECT_MARK => "\n\n",
EOL => "\015\012", EOL => "\015\012",
QUERY_KEEPALIVE => q{-k },
QUERY_NON_RECURSIVE => q{-r },
QUERY_REFERRAL => q{-R },
QUERY_GROUPING => q{-G },
QUERY_UNFILTERED => q{-B },
QUERY_LIST_OBJECTS => q{-qtypes }, QUERY_LIST_OBJECTS => q{-qtypes },
QUERY_LIST_SOURCES => q{-qsources },
QUERY_FETCH_TEMPLATE => q{-t%s },
QUERY_LIMIT_OBJECT_TYPE => q{-T%s },
}; };


# simplify if all servers happen to accept same options
our %RIR = ( our %RIR = (
apnic => { SERVER => 'whois.apnic.net', QUERY => \&apnic_query }, apnic => { SERVER => 'whois.apnic.net', QUERY_NON_RECURSIVE => q{-r }, QUERY_REFERRAL => q{-R }, QUERY_UNFILTERED => q{-B },},
ripe => { SERVER => 'whois.ripe.net', QUERY => \&ripe_query }, ripe => { SERVER => 'whois.ripe.net', QUERY_NON_RECURSIVE => q{-r }, QUERY_REFERRAL => q{-R }, QUERY_UNFILTERED => q{-B },},
arin => { SERVER => 'whois.arin.net', QUERY => \&arin_query }, arin => { SERVER => 'whois.arin.net', QUERY_NON_RECURSIVE => q{-r }, QUERY_REFERRAL => q{-R }, QUERY_UNFILTERED => q{-B },},
lacnic => { SERVER => 'whois.lacnic.net', QUERY => \&lacnic_query }, lacnic => { SERVER => 'whois.lacnic.net', QUERY_NON_RECURSIVE => q{-r }, QUERY_REFERRAL => q{-R }, QUERY_UNFILTERED => q{-B },},
afrinic => { SERVER => 'whois.afrinic.net', QUERY => \&afrinic_query }, afrinic => { SERVER => 'whois.afrinic.net', QUERY_NON_RECURSIVE => q{-r }, QUERY_REFERRAL => q{-R }, QUERY_UNFILTERED => q{-B },},
); );


=head1 NAME =head1 NAME
Net::Whois::Generic - a pure-Perl implementation of the RIPE Database client. Net::Whois::Generic - a pure-Perl implementation of a multi source Whois client.
=head1 VERSION =head1 VERSION
Version 2.004001 Version 2.005001
=cut =cut


our $VERSION = 2.004001; our $VERSION = 2.005001;


=head1 SYNOPSIS =head1 SYNOPSIS
Net::Whois::Generic is my first attempt to unify Whois information from different sources. Net::Whois::Generic is my first attempt to unify Whois information from different sources.
Historically Net::Whois::RIPE was the first written, then Net::Whois::Object was added to provide Historically Net::Whois::RIPE was the first written, then Net::Whois::Object was added to provide
a RPSL encapsultation of the data returned from RIPE database, with an API more object oriented. a RPSL encapsultation of the data returned from RIPE database, with an API more object oriented.
Net::Whois::Generic is a new interface designed to be more generic and encapsulated data from Net::Whois::Generic is a new interface designed to be more generic and to encapsulate data from
various sources (RIPE, but also AFRINIC, APNIC...) various sources (RIPE, but also AFRINIC, APNIC...)
The current implementation is barely a proof of concept, and AFINIC is the only other source implemented, The current implementation is barely a proof of concept, AFRINIC and APNIC are the only other sources implemented,
but I expect to turn it into a generic/robust implementation based on the users feedback. but I expect to turn it into a generic/robust implementation based on the users feedback.
Usage is very similar to the Net::Whois::Object :
my $c = Net::Whois::Generic->new( disconnected => 1, unfiltered => 1 );
my ($org) = $c->query( 'ORG-AFNC1-AFRINIC', { type => 'organisation' } );
# $org is a 'Net::Whois::Object::Organisation::AFRINIC' object;
my @o = $c->query('101.0.0.0/8');
# @o contains various Net::Whois::Object:Inetnum::APNIC, and Net::Whois::Object::Information objects
As Net::Whois::Generic started as an improvment of Net::Whois::RIPE, and have a good amount of code in common,
for this reason (and some others) it is currently bundled inside the the Net::Whois::RIPE package.
This might change in the future although.
=head1 METHODS =head1 METHODS
=head2 B<new( %options )> =head2 B<new( %options )>
Expand All @@ -81,12 +89,6 @@ The TCP port of the service to connect to
The time-out (in seconds) for the TCP connection. The time-out (in seconds) for the TCP connection.
=item B<keepalive> (boolean, default is C<false>)
Wherever we want (C<true>) or not (C<false>) to keep the connection to the
server open. This option implements the functionality available through RIPE
Database's "-k" parameter.
=item B<referral> (boolean, default is C<false>) =item B<referral> (boolean, default is C<false>)
When true, prevents the server from using the referral mechanism for domain When true, prevents the server from using the referral mechanism for domain
Expand Down Expand Up @@ -137,7 +139,6 @@ connection to the RIPE Database service desired.
hostname => 'whois.ripe.net', hostname => 'whois.ripe.net',
port => '43', port => '43',
timeout => 5, timeout => 5,
keepalive => 0,
referral => 0, referral => 0,
recursive => 0, recursive => 0,
grouping => 1, grouping => 1,
Expand Down Expand Up @@ -226,19 +227,6 @@ sub __boolean_accessor
return $self->{__options}{$attribute}; return $self->{__options}{$attribute};
} }


=head2 B<keepalive()>
Accessor to the keepalive configuration option. Accepts an optional keepalive,
always return the current keepalive.
=cut

sub keepalive
{
my $self = shift;
return $self->__boolean_accessor('keepalive', @_);
}

=head2 B<referral()> =head2 B<referral()>
Accessor to the referral configuration option. Accepts an optional referral, Accessor to the referral configuration option. Accepts an optional referral,
Expand Down Expand Up @@ -321,9 +309,6 @@ sub connect
else { else {
$self->{__state}{ioselect} = IO::Select->new($socket); $self->{__state}{ioselect} = IO::Select->new($socket);
} }

# Set RIPE Database's "keepalive" capability
$self->send(QUERY_KEEPALIVE) if $self->keepalive;
} }


=head2 B<ios()> =head2 B<ios()>
Expand Down Expand Up @@ -440,33 +425,29 @@ sub _find_rir


my $rir; my $rir;


#
# AFRINIC has been allocated the
# IPv4 address blocks
# 41.0.0.0/8
# 102.0.0.0/8
# 105.0.0.0/8
# 154.0.0.0/8
# 197.0.0.0/8
# 196.0.0.0/8
# IPv6 blocks
# 2c00::/12
# 2001:4200::/23
#
if ( ($query =~ /^(41|102|105|154|196|197)\.\d+\.\d+\.\d+/) if ( ($query =~ /^(41|102|105|154|196|197)\.\d+\.\d+\.\d+/)
or ($query =~ /AFRINIC/i) or ($query =~ /AFRINIC/i)
or ($query =~ /^2c00::/)) or ($query =~ /^2c00::/i))
{ {
$rir = 'afrinic'; $rir = 'afrinic';
} }
elsif ( ( $query =~ /^(23|34|50|64|64|65|66|67|68|69|70|71|72|73|74|75|76|96|97|98|9|100|104|107|108|135|136|142|147|162|166|172|173|174|184|192|198|199|204|205|206|207|208|209|216)/ elsif ( ( $query =~ /^(23|34|50|64|64|65|66|67|68|69|70|71|72|73|74|75|76|96|97|98|9|100|104|107|108|135|136|142|147|162|166|172|173|174|184|192|198|199|204|205|206|207|208|209|216)/
or ($query =~ /^(2001:0400|2001:1800|2001:4800:|2600|2610:0000):/) or ($query =~ /^(2001:0400|2001:1800|2001:4800:|2600|2610:0000):/i)
or $query =~ /ARIN/ or $query =~ /ARIN/
) )
) )
{ {
$rir = 'arin'; $rir = 'arin';


}
elsif ( ( $query =~ /^(10|14|27|36|39|42|49|58|59|60|61|101|103|106|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|169\.208|175|180|182|183|202|203|210|211|218|219|220|221|222|223)\.\d+\.\d+/
or ($query =~ /^(2001:0200|2001:0C00|2001:0E00|2001:4400|2001:8000|2001:A000|2001:B000|2400:0000|2001:0DC0|2001:0DE8|2001:0DF0|2001:07FA|2001:0DE0|2001:0DB8):/i)
or $query =~ /APNIC/
)
)
{
$rir = 'apnic';

} }
else { else {
$rir = 'ripe'; $rir = 'ripe';
Expand All @@ -489,14 +470,9 @@ sub adapt_query


# determine RIR unless $rir; # determine RIR unless $rir;
$rir = $self->_find_rir($query) unless $rir; $rir = $self->_find_rir($query) unless $rir;

if ($rir eq 'ripe') { if ($rir eq 'ripe') {
$self->hostname($RIR{ripe}{SERVER}); $self->hostname($RIR{ripe}{SERVER});
my $parameters = "";
$parameters .= q{ } . QUERY_KEEPALIVE if $self->keepalive;
$parameters .= q{ } . QUERY_UNFILTERED if $self->unfiltered;
$parameters .= q{ } . QUERY_NON_RECURSIVE unless $self->recursive;
$parameters .= q{ } . QUERY_REFERRAL if $self->referral;
$fullquery = $parameters . $query;
} }
elsif ($rir eq 'afrinic') { elsif ($rir eq 'afrinic') {
$fullquery = '-V Md5.0 ' . $query; $fullquery = '-V Md5.0 ' . $query;
Expand All @@ -508,6 +484,15 @@ sub adapt_query
elsif ($rir eq 'lacnic') { elsif ($rir eq 'lacnic') {
$self->hostname($RIR{lacnic}{SERVER}); $self->hostname($RIR{lacnic}{SERVER});
} }
elsif ($rir eq 'apnic') {
$self->hostname($RIR{apnic}{SERVER});
}

my $parameters = "";
$parameters .= q{ } . $RIR{$rir}{QUERY_UNFILTERED} if $self->unfiltered;
$parameters .= q{ } . $RIR{$rir}{QUERY_NON_RECURSIVE} unless $self->recursive;
$parameters .= q{ } . $RIR{$rir}{QUERY_REFERRAL} if $self->referral;
$fullquery = $parameters . $query;


return $fullquery; return $fullquery;
} }
Expand Down Expand Up @@ -536,13 +521,7 @@ sub query
} }


$query = $self->adapt_query($query); $query = $self->adapt_query($query);
my $parameters = ""; my $iterator = $self->__query($query);
$parameters .= q{ } . QUERY_KEEPALIVE if $self->keepalive;
$parameters .= q{ } . QUERY_UNFILTERED if $self->unfiltered;
$parameters .= q{ } . QUERY_NON_RECURSIVE unless $self->recursive;
$parameters .= q{ } . QUERY_REFERRAL if $self->referral;
my $fullquery = $parameters . $query;
my $iterator = $self->__query($fullquery);


my @objects = Net::Whois::Object->new($iterator); my @objects = Net::Whois::Object->new($iterator);


Expand Down Expand Up @@ -577,15 +556,14 @@ sub __query


$self->connect; $self->connect;


# $self->reconnect unless $self->keepalive;
# die "Not connected" unless $self->is_connected; # die "Not connected" unless $self->is_connected;


if ($self->ios->can_write(SOON + $self->timeout)) { if ($self->ios->can_write(SOON + $self->timeout)) {
$self->socket->print($query, EOL); $self->socket->print($query, EOL);


return Iterator->new( return Iterator->new(
sub { sub {
local $/ = "\n\n"; local $/ = END_OF_OBJECT_MARK;
if ($self->ios->can_read(SOON + $self->timeout)) { if ($self->ios->can_read(SOON + $self->timeout)) {
my $block = $self->socket->getline; my $block = $self->socket->getline;
return $block if defined $block; return $block if defined $block;
Expand Down Expand Up @@ -658,7 +636,7 @@ Update of objects from database other than RIPE is not currently implemented...
=item B<Sources> =item B<Sources>
Currently the only sources implemented are RIPE, and AFRINIC. Currently the only sources implemented are RIPE, AFRINIC, and APNIC.
=item B<Maturity> =item B<Maturity>
Expand All @@ -677,14 +655,24 @@ L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=net-whois-ripe>. I will be
notified, and then you'll automatically be notified of progress on your bug as notified, and then you'll automatically be notified of progress on your bug as
I make changes. I make changes.
=head1 SEE ALSO
There are several tools similar to L<Net::Whois::Generic>, I'll list some of them below and some reasons why Net::Whois::Generic exists anyway:
L<Net::Whois::IANA> - A universal WHOIS extractor: update not possible, no RPSL parser
L<Net::Whois::ARIN> - ARIN whois client: update not possible, only subset of ARIN objects handled
L<Net::Whois::Parser> - Module for parsing whois information: no query handling, parser can (must?) be added
L<Net::Whois::RIPE> - RIPE whois client: the basis for L<Net::Whois::Generic> but only handle RIPE.
=head1 SUPPORT =head1 SUPPORT
You can find documentation for this module with the perldoc command. You can find documentation for this module with the perldoc command.
perldoc Net::Whois::Generic perldoc Net::Whois::Generic
You can also look for information at: You can also look for information at:
=over 4 =over 4
Expand Down
4 changes: 4 additions & 0 deletions lib/Net/Whois/Object.pm
Expand Up @@ -999,6 +999,10 @@ sub _TYPE {
$TYPES{ ref $_[0] || $_[0] } ||= {}; $TYPES{ ref $_[0] || $_[0] } ||= {};
} }


=head1 SEE ALSO
Please take a look at L<Net::Whois::Generic> the more generic whois client built on top of Net::Whois::RIPE.
=head1 TODO =head1 TODO
The update part (in RIPE database) still needs a lot of work. The update part (in RIPE database) still needs a lot of work.
Expand Down

0 comments on commit 63c060b

Please sign in to comment.