use strict; use warnings; use feature qw{ say }; use Socket; my $ipAddr = shift; my( $quad, $mask ) = split m{/}, $ipAddr; die qq{Bad IP\n} unless my $binAddr = inet_aton( $quad ); my $rxValidMask = do { local $" = q{|}; my @vals = ( 8 .. 30 ); qr{^(?:@vals)$}; }; die qq{Bad mask\n} unless $mask =~ $rxValidMask; my $value = 0xffffffff; $value = do { no warnings qw{ portable }; ( $value <<= 1 ) % 0x100000000; } for 1 .. ( 32 - $mask ); my $binMask = pack q{N}, $value; my $network = $binAddr & $binMask; my $lowMask = $network ^ pack q{H*}, q{00000001}; my $lowAddr = $network | $lowMask; my $highMask = $binMask ^ pack q{H*}, q{ffffffff}; my $highAddr = $network | $highMask; my $hrNetwork = inet_ntoa( $network ) . q{/} . ( unpack( q{B*}, $binMask ) =~ tr{1}{} ); print qq{\n}; my $lineFmt = qq{%-13s: %s %s %s %s : %s\n}; printf $lineFmt x 5, q{IP address}, unpack( q{(a8)*}, unpack( q{B*}, $binAddr ) ), $quad, q{Netmask}, unpack( q{(a8)*}, unpack( q{B*}, $binMask ) ), inet_ntoa( $binMask ), q{Network}, unpack( q{(a8)*}, unpack( q{B*}, $network ) ), $hrNetwork, q{Low address}, unpack( q{(a8)*}, unpack( q{B*}, $lowAddr ) ), inet_ntoa( $lowAddr ), q{High address}, unpack( q{(a8)*}, unpack( q{B*}, $highAddr ) ), inet_ntoa( $highAddr ); print qq{\nAddress range\n}; do { say q{ }, inet_ntoa( $lowAddr ); $lowAddr = pack q{N}, 1 + ( unpack q{N}, $lowAddr ); } while $lowAddr le $highAddr;