173 lines
4.7 KiB
Perl
173 lines
4.7 KiB
Perl
# ====================================================================
|
|
# Gossamer Threads Module Library - http://gossamer-threads.com/
|
|
#
|
|
# GT::IPCountry
|
|
# Author: Jason Rhinelander
|
|
# CVS Info : 087,071,086,086,085
|
|
# $Id: IPCountry.pm,v 1.1 2006/01/31 00:45:04 jagerman Exp $
|
|
#
|
|
# Copyright (c) 2006 Gossamer Threads Inc. All Rights Reserved.
|
|
# ====================================================================
|
|
#
|
|
# Description:
|
|
# Attempts to look up an IP's country using a variety of common CPAN modules.
|
|
#
|
|
|
|
package GT::IPCountry;
|
|
use strict;
|
|
require Exporter;
|
|
|
|
use vars qw/@EXPORT @ISA %MODULE/;
|
|
|
|
@ISA = 'Exporter';
|
|
@EXPORT = 'ip_to_country';
|
|
|
|
sub lookup_possible () {
|
|
_load_module() if not defined $MODULE{loaded};
|
|
return $MODULE{loaded};
|
|
}
|
|
|
|
sub ip_to_country ($) {
|
|
my $ip = shift;
|
|
|
|
lookup_possible or return (undef, undef);
|
|
|
|
my $country;
|
|
|
|
if ($MODULE{geoip}) { # Geo::IP
|
|
$country = $MODULE{geoip}->country_name_by_addr($ip);
|
|
}
|
|
elsif ($MODULE{ipc}) { # IP::Country & Geography::Countries
|
|
$country = $MODULE{ipc}->inet_ntocc(Socket::inet_aton($ip));
|
|
my %special = ( # Special codes returned that G::C can't handle:
|
|
AP => 'non-specific Asia-Pacific location',
|
|
CS => 'Czechoslovakia (former)',
|
|
EU => 'non-specific European Union location',
|
|
FX => 'France, Metropolitan',
|
|
PS => 'Palestinian Territory, Occupied',
|
|
'**' => 'Intranet address'
|
|
);
|
|
if ($special{$country}) { $country = $special{$country} }
|
|
elsif ($MODULE{geoc}) {
|
|
$country = Geography::Countries::country($country) || $country;
|
|
}
|
|
}
|
|
elsif ($MODULE{geoipfree}) { # Geo::IPfree
|
|
$country = ($MODULE{geoipfree}->LookUp($ip))[1];
|
|
}
|
|
|
|
return wantarray ? ($country, 1) : $country;
|
|
}
|
|
|
|
# Attempts to load various CPAN modules capable of going the IP -> country
|
|
# lookup. Sets $MODULE{loaded} to 1 if at least one of the modules was found,
|
|
# sets to 0 if none were loadable.
|
|
sub _load_module {
|
|
|
|
if (!defined $MODULE{geoip}) {
|
|
$MODULE{geoip} = eval { require Geo::IP; Geo::IP->new(Geo::IP::GEOIP_STANDARD()) } || 0;
|
|
if (!$MODULE{geoip}) {
|
|
$MODULE{geoipfree} = 0 && eval { require Geo::IPfree; Geo::IPfree->new } || 0;
|
|
}
|
|
if (!$MODULE{geoip}) {
|
|
$MODULE{ipc} = eval { require IP::Country::Fast; IP::Country::Fast->new } || 0;
|
|
}
|
|
if ($MODULE{ipc}) {
|
|
require Socket;
|
|
$MODULE{geoc} = eval { require Geography::Countries } || 0;
|
|
}
|
|
if (!$MODULE{ipc} and !$MODULE{geoipfree}) {
|
|
$MODULE{geoipfree} = 0 && eval { require Geo::IPfree; Geo::IPfree->new } || 0;
|
|
}
|
|
}
|
|
|
|
$MODULE{loaded} = $MODULE{geoip} || $MODULE{geoipfree} || $MODULE{ipc} ? 1 : 0;
|
|
}
|
|
|
|
1;
|
|
|
|
__END__
|
|
|
|
=head1 NAME
|
|
|
|
GT::IPCountry - Attempts to look up an IP's country using a variety of common
|
|
CPAN modules.
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
use GT::IPCountry;
|
|
|
|
my $country = ip_to_country("209.139.239.160");
|
|
|
|
my ($country, $lookup_okay) = ip_to_country("209.139.239.160");
|
|
|
|
my $can_lookup = GT::IPCountry::lookup_possible();
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
This module takes an IP address and returns the country name the IP is reserved
|
|
for. This module itself does no actual lookup, but is simply a wrapper around
|
|
serveral CPAN modules. If none of the modules are available, it simply returns
|
|
the value C<undef>.
|
|
|
|
=head1 FUNCTIONS
|
|
|
|
=head2 ip_to_country
|
|
|
|
This method takes a country name and returns two elements: the country name,
|
|
and a true/false value indicating whether one of the lookup modules was
|
|
available. In scalar context just the country name is returned. A country
|
|
name of C<undef> indicates that either the IP wasn't found, or no lookup module
|
|
was available.
|
|
|
|
C<ip_to_country> is exported by default.
|
|
|
|
=head2 lookup_possible
|
|
|
|
This method returns a true/false value indicating whether or not an IP ->
|
|
Country lookup can be done. It corresponds directly to the second return value
|
|
of C<ip_to_country>.
|
|
|
|
=head1 MODULES
|
|
|
|
GT::IPCountry attempts to use the following modules, in order, to perform a
|
|
country lookup:
|
|
|
|
=over 4
|
|
|
|
=item Geo::IP
|
|
|
|
Uses Geo::IP for the lookup.
|
|
|
|
=item IP::Country
|
|
|
|
Uses IP::Country for the lookup. Note that because IP::Country only returns a
|
|
country code, this module will attempt to use Geography::Countries to determine
|
|
the country name. If Geography::Countries isn't installed, you'll just get a
|
|
country code.
|
|
|
|
=item Geo::IPfree
|
|
|
|
Uses Geo::IPfree for the lookup.
|
|
|
|
=back
|
|
|
|
=head1 SEE ALSO
|
|
|
|
L<Geo::IP>
|
|
|
|
L<Geo::IPfree>
|
|
|
|
L<IP::Country>
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
Copyright (c) 2006 Gossamer Threads Inc. All Rights Reserved.
|
|
http://www.gossamer-threads.com/
|
|
|
|
=head1 VERSION
|
|
|
|
Revision: $Id: IPCountry.pm,v 1.1 2006/01/31 00:45:04 jagerman Exp $
|
|
|
|
=cut
|