Today I decided to make my own IPCalc program. I had two reason for that. First to learn perl’s binary operations and second one to make some IP calculation points more clear for me.
There is some listing of my script I hope this example help you to understand some fundamental points in IP math.
#!/usr/local/bin/perl
# Written by Andrii Grytsenko 2010
# PP: http://andriigrytsenko.net
use POSIX;
sub hex2bin {
my $hex = shift;
my $pack = unpack("B32",pack("N",$hex));
my $pack = substr($pack,-8);
return $pack;
}
sub bin2hex {
my $bin = shift;
return unpack("N", pack("B32", substr("0" x 32 . $bin, -32)))
}
sub bin2ip {
my $bin = shift;
my $type = shift;
my $ip;
$ip .= bin2hex(substr($bin,0,8)) ."\.";
$ip .= bin2hex(substr($bin,8,8)) ."\.";
$ip .= bin2hex(substr($bin,16,8)) ."\.";
if ( $type eq 'first') {
$ip .= bin2hex(substr($bin,24,8)) + 1 ;
} elsif ($type eq 'broad') {
$ip .= bin2hex(substr($bin,24,8)) - 1 ;
} else {
$ip .= bin2hex(substr($bin,24,8));
}
return $ip;
}
sub normalization {
my $line = shift;
my ($ip,$mask) = split(/\//,$line);
return($ip,$mask);
}
my ($ip,$net_mask) = normalization(@ARGV[0]);
my $host_mask = 32-$net_mask;
my $max_host = POSIX::pow(2,$host_mask)-2;
my $bin_mask = "1" x $net_mask . "0" x $host_mask;
my $bin_ip ;
$bin_ip .= hex2bin($_) foreach (split(/\./,$ip));
my $min = $bin_ip & $bin_mask;
my $max_mask = "0" x $net_mask . "1" x $host_mask;
my $max = $bin_ip | $max_mask;
my $min_ip = bin2ip($min);
my $min_host_ip = bin2ip($min,'first');
my $max_ip = bin2ip($max);
my $max_host_ip = bin2ip($max,'broad');
print \<\< EOF
IP ADDRESS:\t $ip\t $bin_ip
NETWORK MASK:\t \/$net_mask\t\t $bin_mask
WILDCARD:\t \/$host_mask\t\t $max_mask
NETWORK IP:\t $min_ip\/$net_mask\t $min
BROADCAST ADDR:\t $max_ip\t $max
FIRST ADDR:\t $min_host_ip
LAST ADDR:\t $max_host_ip
MAX HOSTS\t $max_host
EOF
Run scripts with one argument ip/netmask… Unfortunately, you can use only short network mask type :
./ipcalc 192.157.9.3/21
the output looks like this:
IP ADDRESS: 192.157.9.3 11000000100111010000100100000011 NETWORK MASK: /21 11111111111111111111100000000000 WILDCARD: /11 00000000000000000000011111111111 NETWORK IP: 192.157.8.0/21 11000000100111010000100000000000 BROADCAST ADDR: 192.157.15.255 11000000100111010000111111111111 FIRST ADDR: 192.157.8.1 LAST ADDR: 192.157.15.254 MAX HOSTS 2046