I hope you're permitted to use modules that ship with perl. Socket has what you need.
You should use numeric addresses instead of dotted quads for range calculations. That will save you fooling around with nested loops. Socket::inet_aton() and Socket::inet_ntoa() will convert between the two.
Update: Here is a shorty that prints the quads in a range of 2000 above a base address, omitting network addresses.
use Socket qw/inet_aton inet_ntoa/;
my $base = '1.1.1.1';
my $nbase = unpack 'N',inet_aton($base);
my @quads = map { inet_ntoa(pack('N', $_)) }
grep { $_ % 256 }
$nbase .. 2000 + $nbase;
{
local $, = ' ';
print @quads, $/;
}
To omit broadcast, too, you just need to
and the grep condition with
($_ % 256) != 255.
Added unpack/pack to fix byte order for arithmetic. The numeric representation for inet_* is in network order.