I was looking at this module, and noticed a couple of short-comings.

(1) it doesn't return a failure code, only blurts a message via "confess"
   with things go wrong;

(2) it doesn't allow you to save a pointer into each address block/range
and then retrieve it later and allow you to use it as a cookie or a handle
  to another object.

(3) it doesn't allow you to insert "0.0.0.0/0" into the list.

These are issues that will need to be resolved before this package is
more generally useful.

I wanted to put a prototype filter up on the wiki, but adding workarounds
to these deficiences in Net::CIDR::Lite ended up being almost as long as
the "useful" part of the filter itself.

Anyone want to work with me on getting patches worked out, tested,
and integrated into the next version?  I can attach what I've done so far...

-Philip

*** Lite.pm.bak	2005-05-21 01:53:57.000000000 -0600
--- Lite.pm	2006-01-14 17:59:28.000000000 -0700
***************
*** 2,14 ****
  
  use strict;
  use vars qw($VERSION);
- use Carp qw(confess);
  
  $VERSION = '0.18';
  
  my %masks;
  my @fields = qw(PACK UNPACK NBITS MASKS);
  
  # Preloaded methods go here.
  
  sub new {
--- 2,15 ----
  
  use strict;
  use vars qw($VERSION);
  
  $VERSION = '0.18';
  
  my %masks;
  my @fields = qw(PACK UNPACK NBITS MASKS);
  
+ my $errstr = '';
+ 
  # Preloaded methods go here.
  
  sub new {
***************
*** 35,46 ****
  sub add {
      my $self = shift;
      my ($ip, $mask) = split "/", shift;
!     $self->_init($ip) || confess "Can't determine ip format" unless %$self;
!     confess "Bad mask $mask"
!         unless $mask =~ /^\d+$/ and 2 <= $mask and $mask <= $self->{NBITS};
      $mask += 8;
!     my $start = $self->{PACK}->($ip) & $self->{MASKS}[$mask]
!         or confess "Bad ip address: $ip";
      my $end = $self->_add_bit($start, $mask);
      ++$$self{RANGES}{$start} || delete $$self{RANGES}{$start};
      --$$self{RANGES}{$end}   || delete $$self{RANGES}{$end};
--- 36,56 ----
  sub add {
      my $self = shift;
      my ($ip, $mask) = split "/", shift;
!     unless ($self->_init($ip) || %$self) {
!          $errstr = "Can't determine ip format";
!          return undef;
!     }
!     
!     unless ($mask =~ /^\d+$/ and 2 <= $mask and $mask <= $self->{NBITS}) {
!         $errstr = "Bad mask $mask";
!         return undef;
!     }
      $mask += 8;
!     my $start = $self->{PACK}->($ip) & $self->{MASKS}[$mask];
!     unless ($start) {
!         $errstr = "Bad IP address: $ip";
!         return undef;
!     }
      my $end = $self->_add_bit($start, $mask);
      ++$$self{RANGES}{$start} || delete $$self{RANGES}{$start};
      --$$self{RANGES}{$end}   || delete $$self{RANGES}{$end};
***************
*** 181,188 ****
  sub add_ip {
      my $self = shift;
      my $ip = shift;
!     $self->_init($ip) || confess "Can't determine ip format" unless %$self;
!     my $start = $self->{PACK}->($ip) or confess "Bad ip address: $ip";
      my $end = $self->_add_bit($start, $self->{NBITS});
      ++$$self{RANGES}{$start} || delete $$self{RANGES}{$start};
      --$$self{RANGES}{$end}   || delete $$self{RANGES}{$end};
--- 191,205 ----
  sub add_ip {
      my $self = shift;
      my $ip = shift;
!     unless ($self->_init($ip) || %$self) {
!         $errstr = "Can't determine ip format";
!         return undef;
!     }
!     my $start = $self->{PACK}->($ip);
!     unless ($start) {
!         $errstr = "Bad IP address: $ip";
!         return undef;
!     }
      my $end = $self->_add_bit($start, $self->{NBITS});
      ++$$self{RANGES}{$start} || delete $$self{RANGES}{$start};
      --$$self{RANGES}{$end}   || delete $$self{RANGES}{$end};
***************
*** 194,207 ****
      my $self = shift;
      local $_ = shift;
      my ($ip_start, $ip_end, $crud) = split /\s*-\s*/;
!     confess "Only one hyphen allowed in range" if defined $crud;
!     $self->_init($ip_start) || confess "Can't determine ip format"
!       unless %$self;
!     my $start = $self->{PACK}->($ip_start)
!       or confess "Bad ip address: $ip_start";
!     my $end = $self->{PACK}->($ip_end)
!       or confess "Bad ip address: $ip_end";
!     confess "Start IP is greater than end IP" if $start gt $end;
      $end = $self->_add_bit($end, $$self{NBITS});
      ++$$self{RANGES}{$start} || delete $$self{RANGES}{$start};
      --$$self{RANGES}{$end}   || delete $$self{RANGES}{$end};
--- 211,238 ----
      my $self = shift;
      local $_ = shift;
      my ($ip_start, $ip_end, $crud) = split /\s*-\s*/;
!     if (defined $crud) {
!         $errstr = "Only one hyphen allowed in range";
!         return undef;
!     }
!     unless ($self->_init($ip_start) || %$self) {
!         $errstr = "Can't determine ip format";
!         return undef;
!     }
!     my $start = $self->{PACK}->($ip_start);
!     unless ($start) {
!         $errstr = "Bad IP address: $ip_start";
!         return undef;
!     }
!     my $end = $self->{PACK}->($ip_end);
!     unless ($end) {
!         $errstr = "Bad IP address: $ip_end";
!         return undef;
!     }
!     if ($start gt $end) {
!         $errstr = "Start IP is greater than end IP";
!         return undef;
!     }
      $end = $self->_add_bit($end, $$self{NBITS});
      ++$$self{RANGES}{$start} || delete $$self{RANGES}{$start};
      --$$self{RANGES}{$end}   || delete $$self{RANGES}{$end};
***************
*** 212,218 ****
  sub add_cidr {
      my $self = shift;
      my $cidr = shift;
!     confess "Not a CIDR object" unless UNIVERSAL::isa($cidr, 'Net::CIDR::Lite');
      unless (%$self) {
          @[EMAIL PROTECTED] = @[EMAIL PROTECTED];
      }
--- 243,252 ----
  sub add_cidr {
      my $self = shift;
      my $cidr = shift;
!     unless (UNIVERSAL::isa($cidr, 'Net::CIDR::Lite')) {
!         $errstr = "Not a CIDR object";
!         return undef;
!     }
      unless (%$self) {
          @[EMAIL PROTECTED] = @[EMAIL PROTECTED];
      }
***************
*** 301,308 ****
  sub _packer { shift->{PACK} }
  sub _unpacker { shift->{UNPACK} }
  
  package Net::CIDR::Lite::Span;
- use Carp qw(confess);
  
  sub new {
      my $proto = shift;
--- 335,345 ----
  sub _packer { shift->{PACK} }
  sub _unpacker { shift->{UNPACK} }
  
+ sub lasterr {
+     $errstr;
+ }
+ 
  package Net::CIDR::Lite::Span;
  
  sub new {
      my $proto = shift;
***************
*** 339,345 ****
      return {} unless @_;
      return { map { $_ => {} } @_ } unless @{$self->{FIND}};
      return $self->bin_find(@_) if @_/@{$self->{FIND}} < $self->{PCT};
!     my @ips = sort map { $pack->($_) || confess "Bad IP: $_" } @_;
      my $last;
      for my $ip (@{$self->{FIND}}) {
          if ($ips[0] lt $ip) {
--- 376,387 ----
      return {} unless @_;
      return { map { $_ => {} } @_ } unless @{$self->{FIND}};
      return $self->bin_find(@_) if @_/@{$self->{FIND}} < $self->{PCT};
!     my $bad_ip = '';
!     my @ips = sort map { $pack->($_) || ($bad_ip = $_) } @_;
!     if ($bad_ip) {
!         $errstr = "Bad IP address: $bad_ip";
!         return undef;
!     }
      my $last;
      for my $ip (@{$self->{FIND}}) {
          if ($ips[0] lt $ip) {
***************
*** 365,371 ****
      my $unpack = $self->{UNPACK};
      my $find   = $self->{FIND};
      my %results;
!     for my $ip ( map { $pack->($_) || confess "Bad IP: $_" } @_) {
          my ($start, $end) = (0, $#$find);
          $results{$unpack->($ip)} = $self->_in_range, next
            unless $ip ge $find->[$start] and $ip lt $find->[$end];
--- 407,414 ----
      my $unpack = $self->{UNPACK};
      my $find   = $self->{FIND};
      my %results;
!     my $bad_ip = '';
!     for my $ip ( map { $pack->($_) || ($bad_ip = $_) } @_) {
          my ($start, $end) = (0, $#$find);
          $results{$unpack->($ip)} = $self->_in_range, next
            unless $ip ge $find->[$start] and $ip lt $find->[$end];
***************
*** 381,386 ****
--- 424,433 ----
          }
          $results{$unpack->($ip)} = $self->_in_range($find->[$start]);
      }
+     if ($bad_ip) {
+         $errstr = "Bad IP address: $bad_ip";
+         return undef;
+     }
      \%results;
  }
  
_______________________________________________
NOTE: If there is a disclaimer or other legal boilerplate in the above
message, it is NULL AND VOID.  You may ignore it.

Visit http://www.mimedefang.org and http://www.roaringpenguin.com
MIMEDefang mailing list MIMEDefang@lists.roaringpenguin.com
http://lists.roaringpenguin.com/mailman/listinfo/mimedefang

Reply via email to