<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
	<title>HP200LX.NET -- Main page</title>
</head>
<table width="100%" col=1><tr><td align="right"><strong>the HP200LX home</strong>
</td></tr></table>
<hr>
<align = left>
<body>
#!/usr/bin/perl -w

# 2/2000 krischan@jodies.cx
#
# 0.14    Release
# 0.14.1  Allow netmasks given as dotted quads
# 0.15    Colorize Classbits, Mark new bits in network

# Modified for Perl4 by Laust Brock-Nannestad. Please do not distribute.
# Original at http://jodies.cx/ipcalc

$version = "0.15pl4";


$private = "(Private Internet RFC 1918)";

@privmin[0] = "10.0.0.0";     
@privmin[1] = "172.16.0.0";
@privmin[2] = "192.168.0.0";

@privmax[0] = "10.255.255.255";
@privmax[1] = "172.31.255.255";
@privmax[2] = "192.168.255.255";

#$allhosts;
$mark_newbits = 0;

$qcolor = "\033[34m"; # dotted quads, blue
$ncolor = "\033[m";   # normal, black
$bcolor = "\033[33m"; # binary, yellow
$mcolor = "\033[31m"; # netmask, red
$ccolor = "\033[35m"; # classbits, magenta
$dcolor = "\033[32m"; # newbits, green



foreach (@privmin) {
    $_ = &bintoint(&dqtobin("$_"));
}

foreach (@privmax) {
    $_ = &bintoint(&dqtobin("$_"));
}


if (! defined ($ARGV[0])) {
    &usage;
}


if (defined ($ARGV[0]) && $ARGV[0] eq "-n") {
    shift @ARGV;
    $qcolor = '';
    $ncolor = '';
    $bcolor = '';
    $mcolor = '';
    $ccolor = '';
    $dcolor = '';
}

if (defined ($ARGV[0]) && $ARGV[0] eq "-h") {
    shift @ARGV;
    $qcolor = '<font color="#0000ff">' ;
    $ncolor = '<font color="#000000">';
    $bcolor = '<font color="#909090">';
    $mcolor = '<font color="#ff0000">';
    $ccolor = '<font color="#009900">';
    $dcolor = '<font color="#663366">';
    $private = "(<a href=\"http://www.ietf.org/rfc/rfc1918.txt\">Private 
Internet</a>)";
    print "<!-- Version $version -->\n";
}


$host  = "192.168.0.1";
$mask  = "24";
$mask2 = '24';

if (defined @ARGV[0]) {
    $host = @ARGV[0];
}
if (! ($host = &is_valid_dq($host)) ) {
    print "$mcolor Strange value for ADDRESS ($ARGV[0])$ncolor\n";
}



if (defined @ARGV[1]) {
    $mask = @ARGV[1];
    if (! ($mask = &is_valid_netmask($mask)) ) {
 print "$mcolor Strange value for NETMASK ($ARGV[1])$ncolor\n";
    }
}


if (defined (@ARGV[2])) {
    $mask2 = @ARGV[2];
    if (! ($mask2 = &is_valid_netmask($mask2)) ) {
 print "$mcolor Strange value for second NETMASK ($ARGV[2])$ncolor\n";
    } 
} else {
    $mask2 = $mask;
} 

print "\n";

print "Address:   $qcolor$host$ncolor\n";
print "Address:   " . &formatbin(&dqtobin($host),$mask,$bcolor,0) ."$ncolor\n";

$m  = pack("B*", ("1" x $mask) . ("0" x (32 - $mask)) );

print "Netmask:   $qcolor" . &bintodq($m) . " == $mask$ncolor\n";
print "Netmask:   " . &formatbin($m,$mask,$mcolor,0) . "$ncolor\n";
print "=>\n";

$h = &dqtobin($host);
$n = pack("L", unpack("L", $h) & unpack("L",$m));
#$realn = $h & $m;

#print "---h---> $h ", unpack("L", $h), "\n";
#print "---n---> $n\n";
#print "---m---> $m\n";
#print "-real--> $realn\n";

&printnet($n,$mask);


if ( $mask2 == $mask ) {
    exit;
}
if ($mask2 > $mask) {
    print "Subnets\n\n";
    $mark_newbits = 1;
    &subnets;
} else {
    print "Supernet\n\n";
    &supernet;
}

sub supernet {
    $m  = pack( "B*",("1" x $mask2) . ("0" x (32 - $mask2)) );
    $n = $h & $m;
    print "Netmask:   $qcolor" . &bintodq($m) . " == $mask2$ncolor\n";
    print "Netmask:   "        . &formatbin($m,$mask2,$mcolor,0) . 
"$ncolor\n\n";
    &printnet($n,$mask2);
}

sub subnets {
    local ($subnets) = 0;
    local (@oldnet);
    local ($oldnet);
    local ($k);
    local (@nr);
    local ($nextnet);
    local ($l);


    $m  = pack( "B*",("1" x $mask2) . ("0" x (32 - $mask2)) );
    print "Netmask:   $qcolor" . &bintodq($m) . " == $mask2$ncolor\n";
    print "Netmask:   " . &formatbin($m,$mask2,$mcolor,0) . "$ncolor\n";
    print "\n";
    
    @oldnet = split (//,unpack("B*",$n));
    for ($k = 0 ; $k < $mask ; $k++) {
 $oldnet .= $oldnet[$k];
    }
    for ($k = 0 ; $k < ( 2 ** ($mask2 - $mask)) ; $k++) {
 @nr = split (//,unpack("b*",pack("L",$k)));
 $nextnet = $oldnet;
 for ($l = 0; $l < ($mask2 - $mask) ; $l++) {
     $nextnet .= $nr[$mask2 - $mask - $l - 1] ;
 }
 $n = pack ("B*",$nextnet);
 &printnet($n,$mask2);
 ++$subnets;
 if ($subnets >= 1000) {
     print "... stopped at 1000 subnets ...\n";
     last;
 }
    }

    if ( ($subnets < 1000) && ($mask2 > $mask) ){
 print "\nSubnets:   $qcolor$subnets $ncolor\n";
 print "Hosts:     $qcolor" . ($allhosts * $subnets) . "$ncolor\n";
    }
}

sub printnet {
    local($n) = @_[0];
    local($mask) = @_[1];
    local($nm);
    local($type);
    local($hmin);
    local($hmax); 
    local($hostn);
    local($p);
    local($i);

    
    $m  = pack( "B*",("1" x $mask) . ("0" x (32 - $mask)) );
    $nm = pack( "B*",("0" x $mask) . ("1" x (32 - $mask)) );

    $b = pack("L", unpack("L", $n) | unpack("L", $nm));
    $type = 1;
    while (unpack("B$type",$n) !~ /0/) {
 $type++;
    }
    if ($type > 5) {
 $type = '';
    } else {
 $type = "Class " . &chr($type+64);
    }
    
    $hmin  = pack("L", unpack("L", pack("B*", ("0"x31) ."1")) | unpack("L", 
$n));
    $hmax  = pack("L", unpack("L", pack("B*",("0" x $mask) . ("1" x (31 - 
$mask)) . "0" )) | unpack("L", $n));
# print "--hmin--> $hmax  ", &bintoint($hmin), "\n";
    $hostn = (2 ** (32 - $mask)) -2  ;
    $p = 0;
    for ($i=0; $i<3; $i++) {
 if ( (&bintoint($hmax) <= @privmax[$i])  && 
             (&bintoint($hmin) >= @privmin[$i]) ) {
     $p = $i +1;
     last;
 }
    }
    
    if ($p) {
 $p = $private;
    } else {
 $p = '';
    }


    print "Network:   $qcolor" . &bintodq($n) . "/$mask $ncolor($ccolor" 
.$type. "$ncolor) $p $ncolor\n";
    print "Network:   "        . &formatbin($n,$mask,$bcolor,1) . "$ncolor\n";

    print "Broadcast: $qcolor" . &bintodq($b) . "$ncolor\n";
    print "Broadcast: "        . &formatbin($b,$mask,$bcolor,0) . "$ncolor\n";


    print "HostMin:   $qcolor" . &bintodq($hmin) . "$ncolor\n";
    print "HostMin:   "        . &formatbin($hmin,$mask,$bcolor,0) . 
"$ncolor\n";
    
    print "HostMax:   $qcolor" . &bintodq($hmax) . "$ncolor\n";
    print "HostMax:   "        . &formatbin($hmax,$mask,$bcolor,0) . 
"$ncolor\n";


    print "Hosts:     $qcolor$hostn$ncolor\n\n";
    $allhosts = $hostn;
}



sub formatbin {
    local ($bin,$actual_mask,$color,$mark_classbits) = @_;
    local(@dq);
    local($dq);
    local(@dq2);
    local($is_classbit) = 1;
    local($bit);
    local($i);
    local($j);
    local($oldmask);
    local($newmask);

    if ($mask2 > $mask) {
 $oldmask = $mask;
 $newmask = $mask2;
 
    } else {
 $oldmask = $mask2;
 $newmask = $mask;
    }

    @dq = split (//,unpack("B*",$bin));
    if ($mark_classbits) {
 $dq = $ccolor;
    } else {
 $dq = $color;
    }
    for ($j = 0; $j < 4 ; $j++) {
 for ($i = 0; $i < 8; $i++) {
     if (! defined ($bit = $dq[$i+($j*8)]) ) {
  $bit = '0';
     }

     if ( $mark_newbits &&((($j*8) + $i + 1) == ($oldmask + 1)) ) {
  $dq .= "$dcolor";
     }


     $dq .= $bit;
     if ( ($mark_classbits && 
    $is_classbit && $bit == 0)) {
  $dq .= $color;
  $is_classbit = 0;
     }
     if ( (($j*8) + $i + 1) == $actual_mask ) {
  $dq .= " ";
     }

     if ( $mark_newbits &&((($j*8) + $i + 1) == $newmask) ) {
  $dq .= "$color";
     }

 }
 push (@dq2, $dq);
 $dq = '';
    }
    return (join (".",@dq2)) . $ncolor;
}

sub dqtobin {
    local(@dq);
 local($q);
 local($i);
 local($bin);

 foreach $q (split (/\./,@_[0])) {
  push (@dq,$q);
 }
 for ($i = 0; $i < 4 ; $i++) {
  if (! defined $dq[$i]) {
   push (@dq,0);
  }
 }
 $bin    = pack("CCCC",@dq);      # 4 unsigned chars
 return $bin;
}

sub bintodq {
 local($dq) = join (".",unpack("CCCC",@_[0]));
 return $dq;
}

sub bintoint {
 return unpack("N",@_[0]);
}


sub is_valid_dq {
 local($value) = @_[0];
 local($test) = $value;
  local($i);
 local($corrected);
 $test =~ s/\.//g;
 if ($test !~ /^\d+$/) {
  return 0;
 }
 local(@value) = split (/\./, $value, 4);
 for ($i = 0; $i<4; $i++) {
  if (! defined ($value[$i]) ) {
   $value[$i] = 0;
  }
  if ( ($value[$i] !~ /^\d+$/) ||
       ($value[$i] < 0) || 
                     ($value[$i] > 255) ) 
                {
   return 0;
  }
 }
 $corrected = join (".", @value);
 return $corrected;
}

sub is_valid_netmask {
 local ($mask) = @_[0];
 if ($mask =~ /^\d+$/) {
  if ( ($mask > 32) || ($mask < 1) ) {
   return 0;
  }
 } else {
  if (! ($mask = &is_valid_dq($mask)) ) {
   return 0;
  }
  $mask = &dqtocidr($mask);
 }
 return $mask;

}


sub dqtocidr {
 local($dq) = @_[0];
 $b = &dqtobin($dq);
 local($cidr) = 1;
 while (unpack("B$cidr",$b) !~ /0/) {
  $cidr++;
  last if ($cidr == 33);
 }
 $cidr--;
 return $cidr;
 
}

sub chr {
    return pack ("C", @_[0]);
}

sub usage {
print <<EOF
Usage: ipcalc [-n|-h] <ADDRESS> <NETMASK> [NETMASK]
Calculates network parameters given by ADDRESS an NETMASK and displays
them as dotted quads and binary values. If a second NETMASK is provided
the resulting super- or subnets of a transition to the new netmask are
displayed. ADDRESS can be the ip-address in the network of interest or part
of the network prefix.

 -n    Don't display ANSI color codes
 -h    Display results as HTML

Example:

ipcalc 192.168.0.1 24

EOF
;
 exit;
}


<hr>
<table width="100%" col=1><tr><td align="right"><a href="http://www.hp200lx.net">http://www.hp200lx.net/</a>
</td></tr></table>
sorry: problem with the site. please us this
<a href="http://www.hp200lx.net/index2.html">entry link instead</a>
</body>
</html>

