ehdonhon has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I'm having a bit of difficulty with Net::Netmask. I am not sure if its because I'm doing something wrong, or if the module is not working correctly.

perl -MNet::Netmask my $b = new2 Net::Netmask( '218.0.0.0 - 221.255.255.255' ); if ( $b->match('216.23.234.32') ) { print "Match!\n"; }
Output:
Match!

The IP I am trying to match is certainly not within the netblock I have constructed, yet the Netmask object believes that it is. Is this a bug?

Replies are listed 'Best First'.
Re: Unexpected behavior with Net::Netmask
by ferrency (Deacon) on Jul 31, 2002 at 20:02 UTC
    My initial guess would be that a range of IPs as you've specified will only work correctly if Net::Netmask can make it into a bit mask, and that it doesn't work with generic IP ranges. The lowest 4 bits of 218 are "1010" and th e lowest 4 bits of 221 are "1101". You can't make a single bitmask which only covers that range.

    Update:Or, maybe Net::Netmask builds the smallest netmask which will cover both of the IPs specified; in which case, if they don't mark the boundaries of a net block, then the netmask ends up specifying a larger netblock than you intended. I'd use the mask() method to print out the netmask it thinks it has.

    Alan

Re: Unexpected behavior with Net::Netmask
by Chmrr (Vicar) on Jul 31, 2002 at 20:14 UTC

    ferrancy has almost certainly hit the nail on the head. A bit of simple testing with the following program:

    use Net::Netmask; use strict; use warnings; my $b = new2 Net::Netmask( '218.0.0.0 - '.shift(@ARGV).'.255.255.255') or die "Argh: $Net::Netmask::error"; print map "$_\n", $b->base, $b->mask, $b->size, $b->next;

    ..shows that it can't deal with many of the ranges around there, ("could not fine exact fit for...") but erroneously thinks that it finds one with a range of 216.0.0.0 - 219.255.255.255 when you ask it for your particular case, 218.0.0.0 - 221.255.255.255! Why it does that instead of erroring out, I don't know; my guess is that t'is a bug.

    perl -pe '"I lo*`+$^X$\"$]!$/"=~m%(.*)%s;$_=$1;y^`+*^e v^#$&V"+@( NO CARRIER'

Re: Unexpected behavior with Net::Netmask
by runrig (Abbot) on Jul 31, 2002 at 22:39 UTC
    Give Net::CIDR::Lite a try. It's not quite as flexible in accepting input formats as Net::Netmask is, but it will take ranges that are not necessarily netblocks (and it should take the format you have in your example).
    use Net::CIDR::Lite; my $b = Net::CIDR::Lite->new( '218.0.0.0 - 221.255.255.255' ); print "Match!\n" if $b->find('216.23.234.32');
    Alternatively for the simple case you have (and requiring no extra modules as well as probably being the most efficient solution):
    use Socket; my $ip1 = inet_aton('218.0.0.0'); my $ip2 = inet_aton('221.255.255.255'); my $ip3 = inet_aton('216.23.234.32'); print "Match!\n" if $ip1 <= $ip3 and $ip3 <= $ip2;
RESOLUTION: Unexpected behavior with Net::Netmask
by ehdonhon (Curate) on Aug 06, 2002 at 17:09 UTC

    Turns out that there was a bug in Net::Netmask (version 1.9002). It only happened in the very specific case when you were constructing a netblock using the beginning and ending IP. Netmask was incorrectly assuming that if the number of IP's between the beginning and ending block was a power of 2 then it must be a valid netblock.

    While it is true that all valid netblocks have a size that is a power of 2, it is not true that all netblocks with a size that is a power of 2 are valid.

    I sent the author a bug report and a diff that will patch the bug. We'll see how long it takes to get updated.