rendered paste body#!bin/perl
#
# mask-cvt.pl -- a script to convert between the various
# methods of masking IP addresses
#
sub usage( ) {
print "mask-cvt [nwb] [nwb] {nnn.nnn.nnn.nnn|bbb}\n";
print " where the first argument, [nwba], specifies the input \n";
print " format as one of netmask, wildcard or number of \n";
print " bits and the second argument, [nwb], specifies \n";
print " the output format\n";
exit( );
}
if($#ARGV != 2) { usage( ); }
# get the input format style
$_ = @ARGV[0];
if(/[nN]/) {
# incoming format netmask, what's the outgoing
$_ = @ARGV[1];
if(/[nN]/) {
# no conversion
$output = @ARGV[2];
} elsif (/[wW]/) {
# out is wildcard
$output = do_subtract(@ARGV[2]);
} elsif (/[bB]/) {
# out is wildcard
$output = do_bits(@ARGV[2]);
} else {
usage( );
}
} elsif (/[wW]/) {
# incoming format wildcard, what's the outgoing
$_ = @ARGV[1];
if(/[wW]/) {
# no conversion
$output = @ARGV[2];
} elsif (/[nN]/) {
# out is wildcard
$output = do_subtract(@ARGV[2]);
} elsif (/[bB]/) {
# out is wildcard
$output = do_bits(do_subtract(@ARGV[2]));
} else {
usage( );
}
} elsif (/[bB]/) {
# remove any leading "/" in the bit count
$_ = @ARGV[2];
s/[-\/]//;
$bits = $_;
# incoming format is bit count, what's the outgoing
$_ = @ARGV[1];
if(/[bB]/) {
# no conversion
$output = @ARGV[2];
print "no conversion\n";
} elsif (/[nN]/) {
# out is netmask
$output = cvt_bits_mask($bits);
} elsif (/[wW]/) {
# out is wildcard
$output = do_subtract(cvt_bits_mask($bits));
} else {
usage( );
}
} else {
usage( );
}
print "$output\n";
sub do_subtract( ) {
local($ip) = @_;
# break up the bytes of the incoming IP address
$_ = $ip;
($a, $b, $c, $d) = split(/\./);
if ($a > 255 || $b > 255 || $c > 255 || $d > 255 || /[^0-9.]/) {
print "invalid input mask or wildcard\n";
exit( );
}
$a = 255 - $a;
$b = 255 - $b;
$c = 255 - $c;
$d = 255 - $d;
return ($a . "." . $b . "." . $c . "." . $d);
}
sub do_bits( ) {
local($ip) = @_;
# break up the bytes of the incoming IP address
$_ = $ip;
@ip_bytes = split(/\./);
if ($ip_bytes[0] > 255 || $ip_bytes[1] > 255 || $ip_bytes[2] > 255
|| $ip_bytes[3] > 255 || /[^0-9.]/ || $#ip_bytes != 3) {
print "invalid input mask or wildcard\n";
exit( );
}
$bits = 0;
for ($i=0; $i < 4 ; $i++) {
if ($ip_bytes[$i] > 0 && $bits < 8*$i) {
print "invalid mask for bit count format\n";
exit( );
}
if ($ip_bytes[$i] = = 255 ) { $bits += 8;
} elsif ($ip_bytes[$i] = = 254 ) { $bits += 7;
} elsif ($ip_bytes[$i] = = 252 ) { $bits += 6;
} elsif ($ip_bytes[$i] = = 248 ) { $bits += 5;
} elsif ($ip_bytes[$i] = = 240 ) { $bits += 4;
} elsif ($ip_bytes[$i] = = 224 ) { $bits += 3;
} elsif ($ip_bytes[$i] = = 192 ) { $bits += 2;
} elsif ($ip_bytes[$i] = = 128 ) { $bits += 1;
} elsif ($ip_bytes[$i] != 0 ) {
print "invalid mask for bit count format\n";
exit( );
}
}
return("/" . $bits);
}
sub cvt_bits_mask( ) {
local($bits) = @_;
if ($bits <= 8 ) {
$a = bits_to_dec($bits);
$b=$c=$d=0;
} else {
$a=255;
if ($bits <= 16 ) {
$b = bits_to_dec($bits-8);
$c=$d=0;
} else {
$b=255;
if ($bits <= 24 ) {
$c = bits_to_dec($bits-16);
$d=0;
} else {
$c=255;
if ($bits <= 32 ) {
$d = bits_to_dec($bits-24);
} else {
print "invalid bit count\n";
exit( );
}
}
}
}
return ($a . "." . $b . "." . $c . "." . $d);
}
sub bits_to_dec( ) {
local($bits) = @_;
if($bits = = 0 ) { return 0; }
if($bits = = 1 ) { return 128; }
if($bits = = 2 ) { return 192; }
if($bits = = 3 ) { return 224; }
if($bits = = 4 ) { return 240; }
if($bits = = 5 ) { return 248; }
if($bits = = 6 ) { return 252; }
if($bits = = 7 ) { return 254; }
if($bits = = 8 ) { return 255; }
}