diff --git a/modules/util/Util/CIDR.pm b/modules/util/Util/CIDR.pm new file mode 100644 index 0000000000000000000000000000000000000000..5aaae89fd52669511524219586e5011363a9b5d4 --- /dev/null +++ b/modules/util/Util/CIDR.pm @@ -0,0 +1,127 @@ +#!/usr/bin/perl + +use strict; + +package Util::CIDR; + +use Net::CIDR; + +__PACKAGE__->main() unless caller(); + +sub new +{ + my $class= shift; + + my $self= { _cidr => {}, _ips => {} }; + bless ($self, $class); + $self->set(@_); + + $self; +} + +sub set +{ + my $self= shift; + my %pars= @_; + foreach my $par (keys %pars) + { + $self->{$par}= $pars{$par}; + } + $self; +} + +sub add_cidr +{ + my $self= shift; + my $ip_block= shift; + my $comment= shift; + + my $v= Net::CIDR::cidrvalidate($ip_block); + return undef unless (defined ($v) && $ip_block =~ m#/#); + + my $cidr= $self->{_cidr}; + + my $b; + unless (defined ($b= $cidr->{$ip_block})) + { + $b= $cidr->{$ip_block}= { ip_block => $ip_block }; + } + + if ($comment) + { + # print __LINE__, " comment=[$comment] b: ", main::Dumper($b); + my $c; + unless (defined ($c= $b->{comments})) { $c= $b->{comments}= [] } + push (@$c => $comment); + } + + $b; +} + +sub read_cidr_list +{ + my $self= shift; + my $fnm= shift; + + unless (open (FI, '<:utf8', $fnm)) + { + print __LINE__, " can't read CIDR list from fnm=[$fnm]\n"; + return 0; + } + + my $cnt= 0; + L: while (defined (my $l= <FI>)) + { + chop($l); + + next L if ($l eq '' || $l =~ m/^#/); + + my ($ip_block, $comment)= split(' ', $l, 2); + $self->add_cidr($ip_block, $comment); + + $cnt++; + } + close(FI); + + $cnt; +} + +=head2 lookup + +lookup IP address in cidr list and return structure pointing to the IP block and counter + +=cut + +sub lookup +{ + my $self= shift; + my $ip= shift; + + if (exists ($self->{_ips}->{$ip})) + { + my $x= $self->{_ips}->{$ip}; + $x->{count}++; + return $x; + } + + # not yet looked up... + my $x= $self->{_ips}->{$ip}= { count => 1 }; + my $c= $self->{_cidr}; + L: foreach my $cidr (keys %$c) + { + if (Net::CIDR::cidrlookup($ip, $cidr)) + { + my $b= $c->{$cidr}; + $x->{ip_block}= $b; + last; + } + } + + $x; +} + +sub main +{ + print join (' ', __FILE__, __LINE__, 'main: caller=['. caller(). ']'), "\n"; +} + diff --git a/modules/util/t_util_cidr.pl b/modules/util/t_util_cidr.pl new file mode 100755 index 0000000000000000000000000000000000000000..58db55c71b557626aca1927e433cf131d5a2518b --- /dev/null +++ b/modules/util/t_util_cidr.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl + +use lib '.'; + +use Util::CIDR; +use Data::Dumper; +$Data::Dumper::Indent= 1; +$Data::Dumper::Sortkeys= 1; + +my $uc= Util::CIDR->new(); + +$uc->add_cidr('111.121.0.0/16', 'blocked dv05'); +$uc->add_cidr('111.122.0.0/16', 'just looking'); +$uc->add_cidr('131.130.0.0/16', 'UNIVIE'); +$uc->add_cidr('85.208.96.0/24', 'US crawlers'); + +foreach my $ip (qw(111.121.2.3 131.130.2.194 84.83.32.81 85.208.96.212 1.2.3.4)) +{ + my $res= $uc->lookup($ip); + print __LINE__, " ip=[$ip] res: ", Dumper($res); +} + +print __LINE__, " uc: ", Dumper($uc); + +