geoipdb tools: IPv6 support

This commit is contained in:
Jan Engelhardt
2011-01-04 03:49:44 +01:00
parent 25bf680ead
commit f180c0e5c6

View File

@@ -1,7 +1,7 @@
#!/usr/bin/perl #!/usr/bin/perl
# #
# Converter for MaxMind CSV database to binary, for xt_geoip # Converter for MaxMind CSV database to binary, for xt_geoip
# Copyright © Jan Engelhardt <jengelh@medozas.de>, 2008 # Copyright © Jan Engelhardt <jengelh@medozas.de>, 2008-2011
# #
# Use -b argument to create big-endian tables. # Use -b argument to create big-endian tables.
# #
@@ -11,7 +11,11 @@ use Text::CSV_XS; # or trade for Text::CSV
use strict; use strict;
my %country; my %country;
my $csv = Text::CSV_XS->new({binary => 0, eol => $/}); # or Text::CSV my $csv = Text::CSV_XS->new({
allow_whitespace => 1,
binary => 1,
eol => $/,
}); # or Text::CSV
my $target_dir = "."; my $target_dir = ".";
&Getopt::Long::Configure(qw(bundling)); &Getopt::Long::Configure(qw(bundling));
@@ -36,10 +40,16 @@ while (my $row = $csv->getline(*ARGV)) {
$country{$row->[4]} = { $country{$row->[4]} = {
name => $row->[5], name => $row->[5],
pool_v4 => [], pool_v4 => [],
pool_v6 => [],
}; };
} }
my $c = $country{$row->[4]}{pool_v4}; my $c = $country{$row->[4]};
push(@$c, [$row->[2], $row->[3]]); if ($row->[0] =~ /:/) {
push(@{$c->{pool_v6}},
[&ip6_pack($row->[0]), &ip6_pack($row->[1])]);
} else {
push(@{$c->{pool_v4}}, [$row->[2], $row->[3]]);
}
if ($. % 4096 == 0) { if ($. % 4096 == 0) {
print STDERR "\r\e[2K$. entries"; print STDERR "\r\e[2K$. entries";
} }
@@ -50,6 +60,27 @@ print STDERR "\r\e[2K$. entries total\n";
foreach my $iso_code (sort keys %country) { foreach my $iso_code (sort keys %country) {
my($file, $fh_le, $fh_be); my($file, $fh_le, $fh_be);
printf "%5u IPv6 ranges for %s %s\n",
scalar(@{$country{$iso_code}{pool_v6}}),
$iso_code, $country{$iso_code}{name};
$file = "$target_dir/LE/".uc($iso_code).".iv6";
if (!open($fh_le, "> $file")) {
print STDERR "Error opening $file: $!\n";
exit 1;
}
$file = "$target_dir/BE/".uc($iso_code).".iv6";
if (!open($fh_be, "> $file")) {
print STDERR "Error opening $file: $!\n";
exit 1;
}
foreach my $range (@{$country{$iso_code}{pool_v6}}) {
print $fh_be $range->[0], $range->[1];
print $fh_le &ip6_swap($range->[0]), &ip6_swap($range->[1]);
}
close $fh_le;
close $fh_be;
printf "%5u IPv4 ranges for %s %s\n", printf "%5u IPv4 ranges for %s %s\n",
scalar(@{$country{$iso_code}{pool_v4}}), scalar(@{$country{$iso_code}{pool_v4}}),
$iso_code, $country{$iso_code}{name}; $iso_code, $country{$iso_code}{name};
@@ -71,3 +102,24 @@ foreach my $iso_code (sort keys %country) {
close $fh_le; close $fh_le;
close $fh_be; close $fh_be;
} }
sub ip6_pack
{
my $addr = shift @_;
$addr =~ s{::}{:!:};
my @addr = split(/:/, $addr);
my @e = (0) x 8;
foreach (@addr) {
if ($_ eq "!") {
$_ = join(':', @e[0..(8-scalar(@addr))]);
}
}
@addr = split(/:/, join(':', @addr));
$_ = hex($_) foreach @addr;
return pack("n*", @addr);
}
sub ip6_swap
{
return pack("V*", unpack("N*", shift @_));
}