App-geoip
view release on metacpan or search on metacpan
lib/App/geoip.pm view on Meta::CPAN
$opt_v >= 7 and _dump ("Configuration", \%conf);
if (defined $opt_J) {
if ($opt_J) {
$conf{json_pretty}++;
$conf{json}++;
}
else {
$conf{json_pretty} = 0;
}
}
$conf{json} and $opt_J = $conf{json_pretty};
if (@ARGV == 0 and my $eh = $ENV{GEOIP_HOST}) {
$eh =~ s{[\s\r\n]+\z}{};
# No IPv6 support yet
if ($eh =~ m{^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$} and
$1 > 0 && $1 < 256 && $2 < 256 && $3 < 256 && $4 < 256) {
# Simplistic IPv4
push @ARGV => $eh;
}
elsif ($eh =~ m/^\w[-.\w]{0,252}\z/) { # Skip invalid clipboard content
# https://en.wikipedia.org/wiki/Hostname#Syntax
for (split m/\./ => $eh) {
m/^\w[-\w]{0,62}$/ or die "$eh is not a valid hostname or IPv4\n";
}
push @ARGV => $eh;
}
}
my $dbh = do {
my $dsn = $conf{dsn} =~ s{^b=(?=\w+:)}{}ir; # catch -DB=.. instead of --DB=
my $help = $dsn =~ m/^dbi:(\w+):/i
? "Did you forget to install DBD::$1?"
: "Maybe the matching DBD for $dsn is not installed";
eval {
my %seen;
my $fail = sub {
my $e = DBI->errstr or return;
!$seen{$e}++ and warn "$e\n";
};
local $SIG{__WARN__} = $fail;
local $SIG{__DIE__} = $fail;
DBI->connect ($conf{dsn}, undef, undef, {
AutoCommit => 0,
RaiseError => 1,
PrintError => 1,
ShowErrorStatement => 1,
});
} or die "Cannot continue without a working database\n$help\n";
};
sub _dump {
my ($label, $ref) = @_;
print STDERR $use_data_peek
? Data::Peek::DDumper ({ $label => $ref })
: Data::Dumper->Dump ([$ref], [$label]);
} # _dump
# Based on GeoIP2 CSV databases
# City: http://geolite.maxmind.com/download/geoip/database/GeoLite2-City-CSV.zip
# Country http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country-CSV.zip
# ASN http://geolite.maxmind.com/download/geoip/database/GeoLite2-ASN-CSV.zip
my $idx_type = $conf{dsn} =~ m/:Pg/ ? "using btree" : "";
my $truncate = $conf{dsn} =~ m/:SQLite/ ? "delete from" : "truncate table";
unless (grep m/\b country \b/ix => $dbh->tables (undef, undef, undef, undef)) {
say "Create table stamps";
$dbh->do (qq; create table stamps (
name text not null primary key,
stamp bigint);
);
say "Create table continent";
$dbh->do (qq; create table continent (
id char (4) not null primary key,
name text);
);
say "Create table country";
$dbh->do (qq; create table country (
id bigint not null primary key,
name text not null,
iso text,
continent char (4),
eu smallint);
);
say "Create table ipv4"; # Country based
$dbh->do (qq; create table ipv4 (
cidr cidr not null primary key,
id bigint,
ip_from text not null,
ip_to text not null,
ip_from_n bigint not null,
ip_to_n bigint not null,
reg_country_id bigint,
rep_country_id bigint,
anon_proxy smallint,
satellite smallint);
);
$dbh->do (qq; create index i_ipv4_ip on ipv4 $idx_type (ip_from_n, ip_to_n););
say "Create table provider";
$dbh->do (qq; create table provider (
cidr cidr not null primary key,
id bigint,
name text,
ip_from text,
ip_to text,
ip_from_n bigint,
ip_to_n bigint);
);
$dbh->do (qq; create index i_provider_ip on provider $idx_type (ip_from_n, ip_to_n););
say "Create table city";
$dbh->do (qq; create table city (
id bigint not null primary key,
name text,
country_id bigint,
metro_code text,
tz text,
eu smallint);
);
say "Create table ipc4"; # City based
$dbh->do (qq; create table ipc4 (
cidr cidr not null primary key,
lib/App/geoip.pm view on Meta::CPAN
default value : False
The default output for the information is plain text. With this option,
the output will be in JSON format. The default is not prettified.
=item json-pretty
command line option : C<-J> or C<--json-pretty>
default value : False
If set from the command-line, this implies the C<--json> option.
With this option, JSON output is done I<pretty> (indented).
=item local-location
command line option : C<-l lat/lon> or C<--local=lat/lon>
default value : Undefined
Sets the local location coordinates for use with distances.
When running the tool from a different location than where the IP access is
to be analyzed for or when the network connection will not report a location
that would make sense (like working from a cloud or running over one or more
VPN connections), one can set the location of the base in decimal notation.
(degree-minute-second-notation is not yet supported).
This is also useful when there is no outbound connection possible or when you
do not move location and you want to restrict network requests.
The notation is decimal (with a C<.>, no localization support) where latitude
and longitude are separated by a C</> or a C<,>, like C<-l 12.345678/-9.876543>
or C<--local=12,3456,45,6789>.
=item maxmind-account
command line option : none
default value : Undefined
Currently not (yet) used. Documentation only.
=item license-id
command line option : none
default value : Undefined
Currently not (yet) used. Documentation only.
=item license-key
command line option : none
default value : Undefined
As downloads are only allowed/possible using a valid MaxMind account, you need
to provide a valid license key in your configuration file. If you do not have
an account, you can sign up L<here|https://www.maxmind.com/en/geolite2/signup>.
=back
=head1 DATABASE
Currently PostgreSQL and SQLite have been tested, but others may (or may not)
work just as well. YMMV. Note that the database need to know the C<CIDR>
field type and is able to put a primary key on it.
MariaDB and MySQL are not supported, as they do not support the concept of
CIDR type fields.
The advantage of PostgreSQL over SQLite is that you can use it with multiple
users at the same time, and that you can share the database with other hosts
on the same network behind a firewall.
The advantage of SQLite over PostgreSQL is that it is a single file that you
can copy or move to your liking. This file will be somewhere around 500 Mb.
=head1 EXAMPLES
=head2 Configuration
$ cat ~/.config/geoip
use_distance : True
json-pretty : yes
=head2 Basic use
$ geoip --short 1.2.3.4
=head2 For automation
$ geoip --json --no-json-pretty 1.2.3.4
$ env GEOIP_HOST=1.2.3.4 geoip
=head2 Full report
$ geoip --dist --whois 1.2.3.4
=head2 Selecting CIDR's for countries
=head3 List all CIDR's for Vatican City
$ geoip --country=Vatican > vatican-city.cidr
=head3 Statistics
If you enable verbosity, the selected statistics will be presented at the
end of the CIDR-list: number of CIDR's, number of enclosed IP's, name of
the country and the continent. As the country name is just a perl regex,
you can select all countries with C<.>, or all countries that start with
a C<V>:
$ geoip --country=^V -v >/dev/null
Selected CIDR's
# CIDR # IP Country Continent
------ ---------- --------------------- ---------------
21 18176 Vanuatu Oceania
321 13056 Vatican City Europe
272 6798500 Venezuela South America
612 16014080 Vietnam Asia
=head1 TODO
=over 2
=item IPv6
The ZIP files also contain IPv6 information, but it is not (yet) converted
to the database, nor supported in analysis.
=item Modularization
Split up the different parts of the script to modules: fetch, extract,
check, database, external tools, reporting.
=item CPAN
Turn this into something like App::geoip, complete with Makefile.PL
=back
=head1 SEE ALSO
L<DBI>, L<Net::CIDR>, L<Math::Trig>, L<LWP::Simple>, L<Archive::ZIP>,
L<Text::CSV_XS>, L<JSON::PP>, L<GIS::Distance>, L<Net::Whois::IP>,
L<HTML::TreeBuilder>, L<Data::Dumper>, L<Data::Peek>, L<Socket>
L<Geo::Coder::HostIP>, L<Geo::IP>, L<Geo::IP2Location>, L<Geo::IP2Proxy>,
L<Geo::IP6>, L<Geo::IPfree>, L<Geo::IP::RU::IpGeoBase>, L<IP::Country>,
L<IP::Country::DB_File>, L<IP::Country::DNSBL>, L<IP::Info>, L<IP::Location>,
L<IP::QQWry>, L<IP::World>, L<Metabrik::Lookup::Iplocation>, L<Pcore::GeoIP>
L<IP::Geolocation::MMDB>
Check L<CPAN|https://metacpan.org/search?q=geoip> for more.
=head1 THANKS
Thanks to cavac for the inspiration
=head1 AUTHOR
H.Merijn Brand F<E<lt>hmbrand@cpan.orgE<gt>>, aka Tux.
=head1 COPYRIGHT AND LICENSE
The GeoLite2 end-user license agreement, which incorporates components of the
Creative Commons Attribution-ShareAlike 4.0 International License 1) can be found
L<here|https://www.maxmind.com/en/geolite2/eula> 2). The attribution requirement
may be met by including the following in all advertising and documentation
mentioning features of or use of this database.
This tool uses, but does not include, the GeoLite2 data created by MaxMind,
available from [http://www.maxmind.com](http://www.maxmind.com).
Copyright (C) 2018-2026 H.Merijn Brand. All rights reserved.
This library is free software; you can redistribute and/or modify it under
the same terms as Perl itself.
See L<here|https://opensource.org/licenses/Artistic-2.0> 3).
1) https://creativecommons.org/licenses/by-sa/4.0/
2) https://www.maxmind.com/en/geolite2/eula
3) https://opensource.org/licenses/Artistic-2.0
=for elvis
:ex:se gw=75|color guide #ff0000:
=cut
( run in 1.840 second using v1.01-cache-2.11-cpan-98e64b0badf )