Skip to content

Instantly share code, notes, and snippets.

@adkinss
Last active August 12, 2016 14:47
Show Gist options
  • Save adkinss/9375d9fb3e434ac81d3252669c59a2a3 to your computer and use it in GitHub Desktop.
Save adkinss/9375d9fb3e434ac81d3252669c59a2a3 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl -w
# Without parameters, the script displays all the CIDRs and corresponding networks.
# The script will also demonstrate convering a netmask back into a CIDR, but it
# appears that conversion is broken and needs to be looked at.
#
# With parameters, if display network netmask, broadcast, etc info about each IP
# address provided on the command line.
#
# Ultimately, this script intends to demostrate reusable functions that can be
# used in other scripts that help manipulate IP address data.
use strict;
sub ip_to_int ($)
{
my $addr = shift @_;
return unpack("N", pack("C4", split(/\./, $addr)));
}
sub int_to_ip ($)
{
my $addr = shift @_;
return join(".", unpack("C4", pack("N", $addr)));
}
sub netmask_to_cidr ($)
{
my $addr = shift @_;
return 32 if ip_to_int($addr) == (2**32) - 1;
return 31 - int(log(((2**32 - 1) ^ ip_to_int($addr))) / log(2))
}
sub cidr_to_netmask ($)
{
my $cidr = shift @_;
return int_to_ip(-1 << (32 - $cidr));
}
sub ip_info(@)
{
my $ip = ip_to_int(shift @_);
my $cidr = shift @_;
# don't return anything if nothing good was offered
return ("N/A", "N/A", "N/A", "N/A", "N/A", 0) if $cidr < 1 || $cidr > 32;
my $nm = -1 << (32 - $cidr);
my $nw = $ip & $nm;
my $bc = $nw | (~$nm);
# return Network, Netmask, Broadcast, FirstIP, LastIP, #Hosts
return (int_to_ip($nw), int_to_ip($nm), int_to_ip($bc), "N/A", "N/A", 0) if $cidr == 31;
return (int_to_ip($nw), int_to_ip($nm), int_to_ip($bc), int_to_ip($nw), int_to_ip($bc), 1) if $cidr == 32;
return (int_to_ip($nw), int_to_ip($nm), int_to_ip($bc), int_to_ip($nw+1), int_to_ip($bc-1), $bc-$nw-1);
}
if (@ARGV) {
while (@ARGV) {
my ($ip, $cidr) = split /\//, shift @ARGV;
$cidr = 32 unless $cidr;
$cidr = netmask_to_cidr($cidr) if $cidr =~ /^[0-9]+\./;
my ($network, $netmask, $broadcast, $firstip, $lastip, $numhosts) = ip_info($ip, $cidr);
print "IP/CIDR $ip/$cidr\n";
print "Network $network\n";
print "Netmask $netmask\n";
print "Broadcast $broadcast\n";
print "IP Range $firstip - $lastip ($numhosts hosts)\n\n";
}
exit(0);
}
for (my $i = 0; $i <= 32; $i++) {
printf("%4s --> %-15s --> /%s\n", "/$i", cidr_to_netmask($i), netmask_to_cidr(cidr_to_netmask($i)));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment