Today's entry is a script I wrote some time ago after I'd explained how subnets work, and how to determine if two IP addresses were on the same network or if they had to be routed. It also was an opportunity for me to use the pack and unpack functions of perl, which I hadn't done before. The script takes three arguments -- two IP addresses (or host names if your box will resolve them) and a netmask (in either decimal or hex notation -- both 255.255.254.0 and fffffe00 are acceptable). It then shows you the hexadecimal and ascii representations of the network each host/IP is on, and tells you if you would be routing between the two (originally it only returned "route" or "no routing," but I wanted to see the network numbers so the output is currently a bit redundant).
Without further ado:
#!/usr/bin/perl
use strict;
my ($address1, $address2, $mask, $and1, $and2);
if (@ARGV != 3) { die "should be called with three arguments: source, destination, and netmask\n"}
$address1 = $ARGV[0];
$address2 = $ARGV[1];
$mask = $ARGV[2];
unless ($address1 =~ /\d.\d/) {
$address1 = join(".",unpack("C"x4,gethostbyname($address1)));
}
unless ($address2 =~ /\d.\d/) {
$address2 = join(".",unpack("C"x4,gethostbyname($address2)));
}
if ($mask =~ /[a-e]/) { # hex formatted mask (e.g., fffffe00)
my $sm1 = substr($mask,0,2);
my $sm2 = substr($mask,2,2);
my $sm3 = substr($mask,4,2);
my $sm4 = substr($mask,6,2);
$sm1=hex($sm1);
$sm2=hex($sm2);
$sm3=hex($sm3);
$sm4=hex($sm4);
$mask = "$sm1.$sm2.$sm3.$sm4";
}
# unpack to hex format so it is printable -- e.g., aa0bc000 (just doing for debugging)
$and1 = unpack "H*",(pack("C"x4,(split(/\./,$address1))) & pack("C"x4,(split(/\./,$mask))));
$and2 = unpack "H*",(pack("C"x4,(split(/\./,$address2))) & pack("C"x4,(split(/\./,$mask))));
print "network 1 $and1 " . hex(substr($and1,0,2)) . "." . hex(substr($and1,2,2)) . "." . hex(substr($and1,4,2)) . "." . hex(substr($and1,6,2)) . "\n";
print "network 2 $and2 " . hex(substr($and2,0,2)) . "." . hex(substr($and2,2,2)) . "." . hex(substr($and2,4,2)) . "." . hex(substr($and2,6,2)) . "\n";
if ($and1 =~ /$and2/) { print "no routing\n" } else { print "route\n"}
No comments:
Post a Comment