]> git.ipfire.org Git - thirdparty/xtables-addons.git/commitdiff
geoipdb tools: IPv6 support
authorJan Engelhardt <jengelh@medozas.de>
Tue, 4 Jan 2011 02:49:44 +0000 (03:49 +0100)
committerJan Engelhardt <jengelh@medozas.de>
Thu, 27 Jan 2011 01:57:00 +0000 (02:57 +0100)
geoip/xt_geoip_build

index 5016ff35d3bdf2d9f29f3a954d22c2fbb96f2f2e..933bc17e7343297dfa79467aa11ee33dba6bc9e1 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/perl
 #
 #      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.
 #
@@ -11,7 +11,11 @@ use Text::CSV_XS; # or trade for Text::CSV
 use strict;
 
 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 = ".";
 
 &Getopt::Long::Configure(qw(bundling));
@@ -36,10 +40,16 @@ while (my $row = $csv->getline(*ARGV)) {
                $country{$row->[4]} = {
                        name => $row->[5],
                        pool_v4 => [],
+                       pool_v6 => [],
                };
        }
-       my $c = $country{$row->[4]}{pool_v4};
-       push(@$c, [$row->[2], $row->[3]]);
+       my $c = $country{$row->[4]};
+       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) {
                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) {
        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",
                scalar(@{$country{$iso_code}{pool_v4}}),
                $iso_code, $country{$iso_code}{name};
@@ -71,3 +102,24 @@ foreach my $iso_code (sort keys %country) {
        close $fh_le;
        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 @_));
+}