#!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; } }