fix DXCIDR, show/badip, difft, speedup is_ipaddr()
[spider.git] / perl / DXCIDR.pm
index 821152209a73c6e7cd7353f3bf2b25e8de905d1c..680c66ddaa6fd29138d78143dfb5d46203059feb 100644 (file)
@@ -38,13 +38,25 @@ sub _read
        $fn .= ".$suffix" if $suffix;
        my $fh = IO::File->new($fn);
        my @out;
+       my $ecount;
+       my $line;
+       
 
        if ($fh) {
                while (<$fh>) {
                        chomp;
+                       ++$line;
                        next if /^\s*\#/;
                        next unless /[\.:]/;
                        next unless $_;
+                       unless (is_ipaddr($_)) {
+                               ++$ecount;
+                               LogDbg('err', qq(DXCIDR: $fn line $line: '$_' not an ip address));
+                               if ($ecount > 10) {
+                                       LogDbg('err', qq(DXCIDR: More than 10 errors in $fn at/after line $line: '$_' - INVALID INPUT FILE));
+                                       return ();
+                               }
+                       }
                        push @out, $_;
                }
                $fh->close;
@@ -56,8 +68,10 @@ sub _read
 
 sub _load
 {
+       return unless $active;
        my $suffix = shift;
        my @in = _read($suffix);
+       return 0 unless @in;
        return scalar add(@in);
 }
 
@@ -109,19 +123,30 @@ sub add
 {
        return 0 unless $active;
        my $count = 0;
+       my @out;
        
        for my $ip (@_) {
                # protect against stupid or malicious
+               next unless is_ipaddr($ip);
                next if $ip =~ /^127\./;
                next if $ip =~ /^::1$/;
+#              next if find($ip);
                if ($ip =~ /\./) {
-                       $ipv4->add_any($ip);
-                       ++$count;
-                       ++$count4;
+                       eval {$ipv4->add_any($ip)};
+                       if ($@) {
+                               push @out, $@;
+                       } else {
+                               ++$count;
+                               ++$count4;
+                       }
                } elsif ($ip =~ /:/) {
-                       $ipv6->add_any($ip);
-                       ++$count;
-                       ++$count6;
+                       eval {$ipv6->add_any($ip)};
+                       if ($@) {
+                               push @out, $@;
+                       } else {
+                               ++$count;
+                               ++$count6;
+                       }
                } else {
                        LogDbg('err', "DXCIDR::add non-ip address '$ip' read");
                }
@@ -147,10 +172,27 @@ sub _sort
 {
        my @in;
        my @out;
-       for (@_) {
-               push @in, [inet_pton(m|:|?AF_INET6:AF_INET, $_), split m|/|];
+       my $c;
+       for my $i (@_) {
+               my @s;
+               
+               my @ip = split m|/|, $i;
+               if ($ip[0] =~ /:/) {
+                       @s = map{$_ ? hex($_) : 0} split /:/, $ip[0];
+               } else {
+                       @s = map{$_ ? $_+0 : 0} split /\./, $ip[0];
+               }
+               while (@s < 8) {
+                       push @s, 0;
+               }
+#              my $s = pack "S*", reverse @s;
+               my $s = pack "n*", @s; 
+#              my $s = join ':', map {sprintf "%04d:", $_} @s;
+#              push @in, [inet_pton(m|:|?AF_INET6:AF_INET, $ip[0]), @ip];
+               push @in, [$s, @ip];
        }
-       @out = sort {$a->[0] <=> $b->[0]} @in;
+       @out = sort {$a->[0] cmp $b->[0]} @in;
+#      @out = sort {$a->[0] <=> $b->[0]} @in;
        return map { "$_->[1]/$_->[2]"} @out;
 }
 
@@ -182,7 +224,12 @@ sub init
                return;
        }
 
-       import Net::CIDR::Lite;
+       eval {import Net::CIDR::Lite };
+       if ($@) {
+               LogDbg('DXProt', "DXCIDR: import Net::CIDR::Lite error $@");
+               return;
+       }
+
        $active = 1;
 
        my $fn = _fn();