in reply to Checking IP's with an IP/mask

There might be a CPAN module to do this, but in case there isn't:
#!/usr/bin/perl -w use strict; use Socket; sub MaskbitsToNetmask { my ($bits) = @_; return 0xFFFFFFFF-((1<<(32-$bits))-1); } sub MaskToRange { my ($range) = @_; my ($ip,$mask) = split (/\//, $range); $ip = CompactIP($ip); return ($ip, $ip | (1<<(32-$mask) - 1)); } sub ExpandIP ($) { return inet_ntoa (pack ("N", @_)); } sub CompactIP ($) { return unpack ("N", inet_aton (@_)); } sub IsInRange { my ($ip, $range) = @_; $ip = CompactIP($ip); my ($range_low, $range_hi) = MaskToRange ($range); return (($range_low <= $ip) && ($ip <= $range_hi)); }
Here's some examples:
print IsInRange ("192.168.2.42","192.168.0.0/16"),"\n"; # 1 print IsInRange ("192.168.2.42","192.168.0.0/24"),"\n"; # undef print IsInRange ("192.168.2.42","192.168.2.0/24"),"\n"; # 1 print IsInRange ("24.123.234.1","24.0.0.0/8"),"\n"; # 1
Of course, this is just off the top, so YMMV.

Some notes:

Replies are listed 'Best First'.
Re: Re: Checking IP's with an IP/mask
by repson (Chaplain) on Apr 24, 2001 at 09:40 UTC
    I don't know much about network addresses, but isn't something like this sufficient?
    use Socket; sub IsInRange { my ($addr,$base) = @_; my $bits; ($base, $bits) = split /\//, $base; return ( (unpack("N", inet_aton($base)) >> (32 - $bits)) == (unpack ("N", inet_aton($addr)) >> (32 - $bits)) ); }
      This should work too, and is probably better because of simplicity.

      For those wondering, what this code effectively does is compare the network numbers of the $addr and the $base specification by shifting the host bits off the end (with the >> operator). What I was doing was building a range specification, which given the task, is really overkill.

      Well put.