pax_global_header 0000666 0000000 0000000 00000000064 14140537103 0014510 g ustar 00root root 0000000 0000000 52 comment=4ae72efb0424ba7d6cab0ee94ec9be5004083def ipcalc-0.51/ 0000775 0000000 0000000 00000000000 14140537103 0012670 5 ustar 00root root 0000000 0000000 ipcalc-0.51/README.md 0000664 0000000 0000000 00000002405 14140537103 0014150 0 ustar 00root root 0000000 0000000 # ipcalc This is the ipv6 capable continuation of the subnet calculator from http://jodies.de/ipcalc.
> ipcalc 192.168.1.1/24 Address: 192.168.1.1 11000000.10101000.00000001. 00000001 Netmask: 255.255.255.0 = 24 11111111.11111111.11111111. 00000000 Wildcard: 0.0.0.255 00000000.00000000.00000000. 11111111 => Network: 192.168.1.0/24 11000000.10101000.00000001. 00000000 HostMin: 192.168.1.1 11000000.10101000.00000001. 00000001 HostMax: 192.168.1.254 11000000.10101000.00000001. 11111110 Broadcast: 192.168.1.255 11000000.10101000.00000001. 11111111 Hosts/Net: 254 Class C, Private Internet > ipcalc fde6:36fc:c985:0:c2c1:c0ff:fe1d:cc7f 64 Address: fde6:36fc:c985::c2c1:c0ff:fe1d:cc7f 1111110111100110:0011011011111100:1100100110000101:0000000000000000:1100001011000001:1100000011111111:1111111000011101:1100110001111111 Netmask: 64 1111111111111111:1111111111111111:1111111111111111:1111111111111111:0000000000000000:0000000000000000:0000000000000000:0000000000000000 Prefix: fde6:36fc:c985::/64 1111110111100110:0011011011111100:1100100110000101:0000000000000000:0000000000000000:0000000000000000:0000000000000000:0000000000000000 ipcalc-0.51/changelog 0000664 0000000 0000000 00000010017 14140537103 0014541 0 ustar 00root root 0000000 0000000 0.14 Release 0.14.1 Allow netmasks given as dotted quads 0.15 Colorize Classbits, Mark new bits in network 0.16 25.9.2000 Accept/ as first argument Print tag in the script 0.17 Bugfix 0.18 Replace \n with\n"; print "\n"; } exit; } sub supernet { my ($network,$mask1,$mask2) = @_; $network = $network & $mask2; printline ("Netmask", $mask2 ,$mask2,$mask1,1); printline ("Wildcard", ~$mask2 ,$mask2,$mask1); print "\n"; printnet($network,$mask2,$mask1); } sub subnets { my ($network,$mask1,$mask2) = @_; my $subnet=0; my $bitcountmask1 = ntobitcountmask($mask1); my $bitcountmask2 = ntobitcountmask($mask2); html('
in HTML to make konqueror work. Argh. 0.19 HTML modified again to make Internet Exploder work. Argh ** 2 Added -v Option 0.2 New Tabular Format. Idea by Kevin Ivory 0.21 0.22 Don't show -1 if netmask is 32 (Sven Anderson) 0.23 Removed broken prototyping. Thanks to Scott Davis sdavis(a)austin-texas.net 0.31 4/1/2001 Print cisco wildcard (inverse netmask). Idea by Denis Alan Hainsworth denis(a)ans.net 0.32 5/21/2001 - Accepts now inverse netmask as argument (Alan's idea again) Fixed missing trailing zeros in sub/supernets Warns now when given netmasks are illegal Added option to suppress the binary output Added help text 0.33 5/21/2001 Cosmetic 0.34 6/19/2001 Use default netmask of class when no netmask is given 0.35 12/2/2001 Fixed big-endian bug in subnets(). This was reported by Igor Zozulya and Steve Kent. Thank you for your help and access to your sparc machine! 0.35a ??? [Never released] Fixed broken HTML: missing tags. Thanks to Torgen Foertsch 0.35.1 Repairing HTML 0.35.2 Again repair HTML. Thanks to Lars Mueller. 0.36-pre1 + getopts + split_network + deaggregate + rename dqtobin bintodq + netblocks + accept hex netmasks (contribution) + remove garbage + rework argument handling + work all the time on integers, not machine type representations (pack) + eliminated unnessessary globals + replaced is_valid... + rewrote format_bin + various changes + applied fix for colorchange in format_bin scott baker 0.36-pre3 removed print_netmask sticked formatbin and printline together to printline (this marks new bits in supernets (former version didn't) use label to decide what sfx to print 0.36-pre4 made subnets supernets split / deaggregate work with new parameters removed old functions how to handle /31 and /32? 0.36-pre5 removed debug output in deaggregate 0.36-pre6 started netblocks rework getclass 0.36 /31 2004 0.37-pre5 +handle /31 /32 +new html +wrap_html +GPL Header 0.37 2004-05-14 debian asked for a bug fix in 0.35 0.38 2004-10-08 ipcalc did not work on 64bit architectures. Thanks to Foxfair Hufor finding this bug 0.39 2005-07-07 Added output of class only option (-c --class), that was accidentally removed in 0.36 Changed console color of bits back from white to yellow. (Requested by Oliver Seufer) Added ipcalc.cgi and images to the package Added license file to the package Added license text in cgi-wrapper Added contributors file to the package 0.40 2005-07-07 Make -c really do what it did before. (Giving the "natural" mask). Thanks to Bartosz Fenski. Include style sheet into ipcalc.cgi 0.41 2006-07-27 CGI-Script: Replaced REQUEST_URI with SCRIPT_URL to prevent cross-site-scripting attacks Thanks to Tim Brown 0.5 2017-06-09 Fixed typo in help text. Thank you Edward! Accept ipv6 addresses and masks Output very basic information about the ipv6 address Move code to github Applied patches by Bartosz Fenski - If running inside Emacs M-x shell, turn of colors by default - Applied patch by Bartosz Fenski Adjust usage() text - add table tag at the end of supernets adds tag at the end of supernet output when in html mode Add manpage of Nick Clifford Applied patch of Victor Engmark: Description: fixes overzealous input checking Netmask /0 is perfectly fine, with this patch it's possible to use it. 0.51 2021-06-20 bugifx: split_network results were wrong since introduction of bignum. log function replaced with loop. Thanks to Christian Ebnöter for finding thix bug ipcalc-0.51/contributors 0000664 0000000 0000000 00000000601 14140537103 0015345 0 ustar 00root root 0000000 0000000 Thanks for your ideas and help to make this tool more useful: Bartosz Fenski Christan Ebnöther Denis A. Hainsworth Edward Foxfair Hu Frank Quotschalla Hermann J. Beckers Igor Zozulya Kevin Ivory Lars Mueller Lutz Pressler Nick Clifford Oliver Seufer Scott Davis Steve Kent Sven Anderson Torgen Foertsch Tim Brown Victor Engmark ipcalc-0.51/ipcalc 0000775 0000000 0000000 00000077741 14140537103 0014071 0 ustar 00root root 0000000 0000000 #!/usr/bin/perl -w # IPv4 Calculator # Copyright (C) Krischan Jodies 2000 - 2021 # krischan()jodies.de, http://jodies.de/ipcalc # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. use strict; use bignum; my $version = '0.51'; my @class = qw (0 8 16 24 4 5 5); my $quads_color = "\033[34m"; # dotted quads, blue my $norml_color = "\033[m"; # normal, black #my $binry_color = "\033[1m\033[46m\033[37m"; # binary, yellow my $binry_color = "\033[33m"; # binary, yellow my $mask_color = "\033[31m"; # netmask, red my $class_color = "\033[35m"; # classbits, magenta my $subnt_color = "\033[0m\033[32m"; # subnet bits, green my $error_color = "\033[31m"; my $sfont = ""; my $break ="\n"; my $color_old = ""; my $color_actual = ""; my $opt_text = 1; my $opt_html = 0; my $opt_color = 0; my $opt_print_bits = 1; my $opt_print_only_class = 0; my $opt_split = 0; my $opt_deaggregate = 0; my $opt_version = 0; my $opt_help = 0; my @opt_split_sizes; my @arguments; my $error = ""; my $thirtytwobits = 4294967295; # for masking bitwise not on 64 bit arch my $ipv6 = 0; main(); exit; sub main { my $address = -1; my $address2 = -1; my $network = -1; my $mask1 = -1; my $mask2 = -1; if (! defined ($ARGV[0])) { usage(); exit(); } @ARGV = getopts(); if ($opt_help) { help(); exit; } if ($opt_version) { print "$version\n"; exit; } #print "opt_html $opt_html\n"; #print "opt_color $opt_color\n"; #print "opt_print_bits $opt_print_bits\n"; #print "opt_print_only_class $opt_print_only_class\n"; #print "opt_deaggregate $opt_deaggregate\n"; if (! $opt_color) { $quads_color = ''; $norml_color = ''; $binry_color = ''; $mask_color = ''; $class_color = ''; $subnt_color = ''; $sfont = ''; } if ($opt_html) { $quads_color = '' ; $norml_color = ''; $binry_color = ''; $mask_color = ''; $class_color = ''; $subnt_color = ''; $sfont = ''; $break = "
"; #$private = "(Private Internet)"; # print "\n"; print << 'EOF';Bla EOF print "\n"; } # foreach (@arguments) { # print "arguments: $_\n"; # } # foreach (@ARGV) { # print "ARGV: $_\n"; # } # get base address if (defined $ARGV[0]) { $address = argton($ARGV[0],0); } if ($address == -1) { $error .= "INVALID ADDRESS: $ARGV[0]\n"; $address = argton("192.168.1.1",0); # default to sample ipv6 address if $ipv6 == 1 } if ($opt_print_only_class) { print getclass($address,1); exit; } # if deaggregate get last address if ($opt_deaggregate) { if (defined $ARGV[1]) { $address2 = argton($ARGV[1],0); } if ($address2 == -1) { $error .= "INVALID ADDRESS2: $ARGV[1]\n"; $address2 = argton("192.168.1.1",0); } } if ($opt_deaggregate) { if ($error) { print "$error\n"; } print "deaggregate ".ntoa($address) . " - " . ntoa($address2)."\n"; deaggregate($address,$address2); exit; } # get netmasks if ($ipv6) { if (defined $ARGV[1]) { $mask1 = check_mask6($ARGV[1]); if ($mask1 == -1) { print "INVALID MASK1\n\n"; exit; } } else { $mask1 = 64; } } else { if (defined $ARGV[1]) { $mask1 = argton($ARGV[1],1); } else { #get natural mask *** $mask1 = argton(24,1); } if ($mask1 == -1) { $error .= "INVALID MASK1: $ARGV[1]\n"; $mask1 = argton(24,1); } if (defined $ARGV[2]) { $mask2 = argton($ARGV[2],1); } else { $mask2 = $mask1; } if ($mask2 == -1) { $error .= "INVALID MASK2: $ARGV[2]\n"; $mask2 = argton(24,1); } } if ($error) { if ($opt_color) { print set_color($error_color); } print "$error\n"; print set_color($norml_color); exit; } # print "Address: ".ntoa($address)."\n"; # print "mask1: ($mask1) ".ntoa($mask1)."\n"; # print "mask2: ($mask2) ".ntoa($mask2)."\n"; if ($ipv6) { ipcalc6($address,$address2,$mask1,$mask2); exit; } html(''); html("\n"); printline ("Address", $address ,$mask1,$mask1,1); printline ("Netmask", $mask1 ,$mask1,$mask1); printline ("Wildcard", ~$mask1 ,$mask1,$mask1); html("
\n"); if ($opt_deaggregate) { deaggregate(); } if ($opt_split) { split_network($network,$mask1,$mask2,@opt_split_sizes); exit; } if ($mask1 < $mask2) { print "Subnets after transition from /" . ntobitcountmask($mask1); print " to /". ntobitcountmask($mask2) . "\n\n"; subnets($network,$mask1,$mask2); } if ($mask1 > $mask2) { print "Supernet\n\n"; supernet($network,$mask1,$mask2); if ($opt_html) { html("\n"); } } if ($opt_html) { print << 'EOF'; EOF } exit; } # --------------------------------------------------------------------- sub end { if ($opt_html) { # print "\n\n"); html(' \n"); print "\n"; $network = $address & $mask1; printnet($network,$mask1,$mask1); html("'); print "=>"; html(" \n"); html("'); html("\n"); printline ("Netmask", $mask2 ,$mask2,$mask1,1); printline ("Wildcard", ~$mask2 ,$mask2,$mask1); html("
\n"); print "\n"; for ($subnet=0; $subnet < (1 << ($bitcountmask2-$bitcountmask1)); $subnet++) { my $net = $network | ($subnet << (32-$bitcountmask2)); print " ". ($subnet+1) .".\n"; html(''); html("\n"); printnet($net,$mask2,$mask1); html("
\n"); if ($subnet >= 1000) { print "... stopped at 1000 subnets ...$break"; last; } } $subnet = (1 << ($bitcountmask2-$bitcountmask1)); my $hostn = ($network | ((~$mask2) & $thirtytwobits)) - $network - 1; if ($hostn > -1) { print "\nSubnets: $quads_color$subnet"; html(''); print "$norml_color$break"; html(''); } if ($hostn < 1 ) { $hostn = 1; } print "Hosts: $quads_color" . ($hostn * $subnet); html(''); print "$norml_color$break"; html(''); } sub getclass { my $network = shift; my $numeric = shift; my $class = 1; # print "n $network bit ". (1 << (32-$class)) . " & " . while (($network & (1 << (32-$class))) == (1 << (32-$class)) ) { $class++; if ($class > 5) { return "invalid"; } } if ($numeric) { return $class[$class]; } else { return chr($class+64); } } sub printnet { my ($network,$mask1,$mask2) = @_; my $hmin; my $hmax; my $hostn; my $mask; my $broadcast = $network | ((~$mask1) & $thirtytwobits); $hmin = $network + 1; $hmax = $broadcast - 1; $hostn = $hmax - $hmin + 1; $mask = ntobitcountmask($mask1); if ($mask == 31) { $hmax = $broadcast; $hmin = $network; $hostn = 2; } if ($mask == 32) { $hostn = 1; } #if ($hmax < $hmin) { # $hmax = $hmin; # $hostn = 1; #} #private... #$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 = ''; #} if ($mask == 32) { printline ("Hostroute", $network ,$mask1,$mask2,1); } else { printline ("Network", $network ,$mask1,$mask2,1); printline ("HostMin", $hmin ,$mask1,$mask2); printline ("HostMax", $hmax ,$mask1,$mask2); printline ("Broadcast", $broadcast,$mask1,$mask2) if $mask < 31; } # html("\n"); # html(''); # html("\n"); html("
\n"); html(' \n"); html("\n"); text("\n"); text("\n"); ##printf "Class %s, ",getclass($network); ##printf "%s",netblock($network,$mask1); # my ($label,$address,$mask1,$mask2,$classbitcolor_on,$is_netmask) = @_; # print $sfont . $norml_color; # print "$break\n"; # exit; return $hostn; } sub get_description { my $network = shift; my $mask = shift; my @description; my $field; # class if ($opt_color || $opt_html) { $field = set_color($class_color) . "Class " . getclass($network); if ($opt_html) { $field .= ''; } $field .= set_color($norml_color); push @description, $field # push @description, set_color($class_color) . "Class " . # getclass($network) . set_color($norml_color); } else { push @description, "Class " . getclass($network); } # netblock my ($netblock_txt,$netblock_url) = split ",",netblock($network,$mask); if (defined $netblock_txt) { if ($opt_html) { $netblock_txt = '' . $netblock_txt . ''; } #warn "DESC: '$netblock_txt'"; push @description,$netblock_txt; } # /31 if (ntobitcountmask($mask) == 31) { if ($opt_html) { push @description,"PtP Link"; } else { push @description,"PtP Link RFC 3021"; } } #$rfc3021 = "Point-to-Point #Link"; return join ", ",@description; } sub printline { my ($label,$address,$mask1,$mask2,$html_fillup) = @_; $mask1 = ntobitcountmask($mask1); $mask2 = ntobitcountmask($mask2); my $line = ""; my $bit; my $newbitcolor_on = 0; my $toggle_newbitcolor = 0; my $bit_color; my $additional_info = ''; my $classbitcolor_on; my $second_field; if ($label eq 'Netmask') { $additional_info = " = $mask1"; } if ($label eq 'Network') { $classbitcolor_on = 1; $additional_info = "/$mask1"; } if ($label eq 'Hostroute' && $mask1 == 32) { $classbitcolor_on = 1; } html("'); #label print set_color($norml_color); print "Hosts/Net: " ; html(" \n"); html(''); # printf $norml_color . "Hosts/Net: $quads_color%-22s",$hostn; # html(" "); print set_color($quads_color); printf "%-22s",$hostn; # printf "%-22s", (ntoa($address).$additional_info); html(" \n"); html(""); #label if ($opt_html) { #warn "HTML\n"; print wrap_html(30,get_description($network,$mask1)); } else { print get_description($network,$mask1); } html(" \n"); html("\n"); html(" \n"); html("\n"); text("\n"); #print $sfont . $break; } sub text { my $str = shift; if ($opt_text) { print "$str"; } } sub html { my $str = shift; if ($opt_html) { print "$str"; } } sub set_color { my $new_color = shift; my $return; if ($new_color eq $color_old) { # print "SETCOLOR saved one dupe\n"; # $return = 'x'; $return = ''; } if ($new_color eq 'oldcolor') { $new_color = $color_old; } $color_old = $color_actual; #$return .= "$color_actual" . "old"; $color_actual = $new_color; #return $new_color; $return .= $new_color; return $return; } sub split_network { my $network = shift; my $mask1 = shift; my $mask2 = shift; my @sizes = @_; my $first_address = $network; my $broadcast = $network | ((~$mask1) & $thirtytwobits); my @network; my $i=0; my @net; my @mask; my $needed_addresses = 0; my $needed_size; foreach (@sizes) { $needed_size = round2powerof2($_+2); push @network , $needed_size .":".$i++; $needed_addresses += $needed_size; } @network = sort { ($b =~ /(.+):/)[0] <=> ($a =~ /(.+):/)[0] } @network; foreach (@network) { my ($size,$nr) = split ":",$_; $net[$nr]= $network; $mask[$nr]= size2bitcountmask($size); $network += $size; } $i = -1; while ($i++ < $#sizes) { printf "%d. Requested size: %d hosts\n", $i+1,$sizes[$i]; ###$mask = $mask[$i]; #$mark_newbits = 1; ###print_netmask(bitcountmasktobin($mask[$i]),$mask); printline("Netmask",bitcountmaskton($mask[$i]),bitcountmaskton($mask[$i]),$mask2); printnet($net[$i],bitcountmaskton($mask[$i]),$mask2); } my $used_mask = size2bitcountmask($needed_addresses); if ($used_mask < ntobitcountmask($mask1)) { print "Network is too small\n"; } print "Needed size: ". $needed_addresses . " addresses.\n"; print "Used network: ". ntoa($first_address) ."/$used_mask\n"; print "Unused:\n"; deaggregate($network,$broadcast); } sub round2powerof2 { my $i=0; while ($_[0] > ( 1 << $i)) { $i++; } return 1 << $i; } sub size2bitcountmask { my $size = shift; my $i = 0; while ($size > ( 1 << $i)) { $i++; } return 32-$i; } # Deaggregate address range # expects: range: (dotted quads)start (dotted quads)end sub deaggregate { my $start = shift; my $end = shift; my $base = $start; my $step; while ($base <= $end) { $step = 0; while (($base | (1 << $step)) != $base) { if (($base | (((~0) & $thirtytwobits) >> (31-$step))) > $end) { last; } $step++; } print ntoa($base)."/" .(32-$step); print "\n"; $base += 1 << $step; } } sub getopts # expects nothing # returns @ARGV without options # sets global opt variables # -h --html # -h without further opts -> help # (workaround: can't change meaning of -h since this would # break old cgi_wrapper scripts) # --help # -n --nocolor # -v --version # -c --class print natural class # -s --split # -b --nobinary # -d --deaggregate { my @arguments; my $arg; my $prefix; my $nr_opts = 0; my @tmp; # opt_color defaults to 1 when connected to a terminal if (-t STDOUT) { $opt_color = 1; } # Under Emacs, do not use colors by default. The TERM is for older # Emacs versions. if ( !defined($ENV{'TERM'}) or $ENV{'TERM'} =~ /dumb/i or $ENV{'INSIDE_EMACS'} ) { $opt_color = 0; } while (has_opts()) { $arg = shift @ARGV; if ($arg =~ /^--(.+)/) { $nr_opts += read_opt('--',$1); } elsif ($arg =~ /^-(.+)/) { $nr_opts += read_opt('-',split //,$1); } else { push @tmp, $arg; } } # foreach (@arguments) { # print "arg: $_\n"; # } foreach (@ARGV) { push @tmp,$_; } # extract base address and netmasks and ranges foreach (@tmp) { if (/^(.+?)\/(.+)$/) { push @arguments,$1; push @arguments,$2; } elsif (/^(.+)\/$/) { push @arguments,$1; } elsif (/^(.+)\-(.+)$/) { push @arguments,$1; push @arguments,$2; $opt_deaggregate = 1; } elsif (/^\-$/) { $opt_deaggregate = 1; } else { push @arguments, $_; } } if ($#arguments == 2 && $arguments[1] eq '-') { @arguments = ($arguments[0],$arguments[2]); $opt_deaggregate = 1; } # workaround for -h if ($opt_html && $nr_opts == 1 && $#arguments == -1) { $opt_help = 1; } if ($error) { print "$error"; exit; } return @arguments; sub read_opt { my $prefix = shift; my $opts_read = 0; foreach my $opt (@_) { ++$opts_read; if ($opt eq 'h' || $opt eq 'html') { $opt_html = 1; $opt_text = 0; } elsif ($opt eq 'help') { $opt_help = 1; } elsif ($opt eq 'c' || $opt eq 'color') { $opt_color = 1; } elsif ($opt eq 'n' || $opt eq 'nocolor') { $opt_color = 0; } elsif ($opt eq 'v' || $opt eq 'version') { $opt_version = 1; } elsif ($opt eq 'b' || $opt eq 'nobinary') { $opt_print_bits = 0; } elsif ($opt eq 'c' || $opt eq 'class') { $opt_print_only_class = 1; } elsif ($opt eq 'r' || $opt eq 'range') { $opt_deaggregate = 1; } elsif ($opt eq 's' || $opt eq 'split') { $opt_split = 1; while (defined $ARGV[0] && $ARGV[0] =~ /^\d+$/) { push @opt_split_sizes, shift @ARGV; } if ($#opt_split_sizes < 0) { $error .= "Argument for ". $prefix . $opt . " is missing or invalid \n"; } } else { $error .= "Unknown option: " . $prefix . $opt . "\n"; --$opts_read; } } return $opts_read; } sub has_opts { foreach (@ARGV) { return 1 if /^-/; } return 0; } } # expects int width # string # returns wrapped string sub wrap_html { my $width = shift; my $str = shift; #warn "WRAP: '$str'\n"; my @str = split //,$str; my $result; my $current_pos = 0; my $start = 0; my $last_pos = 0; my $line; while ($current_pos < $#str) { #warn "$current_pos\n"; #warn "$current_pos: $str[$current_pos]\n"; # find next blank while ($current_pos < $#str && $str[$current_pos] ne ' ') { # ignore tags if ($str[$current_pos] eq '<') { $current_pos++; while ($str[$current_pos] ne '>') { $current_pos++; } } $current_pos++; } # fits in one line?... $line = substr($str,$start,$current_pos-$start); $line =~ s/<.+?>//g; if ( length($line) <= $width) { # ... yes. keep position in mind and try next $last_pos = $current_pos; $current_pos++; next; } else { # ...no. wrap at last position (if there was one, # otherwise wrap here) if ($last_pos ne $start) { $current_pos = $last_pos; } $line = substr($str,$start,$current_pos-$start); $current_pos++; $start = $current_pos; $last_pos = $start; # no output if end of string is reached because # rest of string is treated after this block if ($current_pos < $#str) { #warn "RESULT+ '$line'\n"; $result .= "$line"); #label print set_color($norml_color); if ($opt_html && $html_fillup) { print "$label:"; print " " x (11 - length($label)); } else { printf "%-11s","$label:"; } html(" \n"); #address html(""); print set_color($quads_color); #printf "%s-22s",(ntoa($address).$additional_info); #printf "%s%-11s$sfont%s",set_color($norml_color),"$label:",set_color($quads_color); $second_field = ntoa($address).$additional_info; if ($opt_html && $html_fillup) { print $second_field; print " " x (21 - length($second_field)); } else { printf "%-21s", (ntoa($address).$additional_info); } html(" \n"); if ($opt_print_bits) { html(""); $bit_color = set_color($binry_color); if ($label eq 'Netmask') { $bit_color = set_color($mask_color); } if ($classbitcolor_on) { $line .= set_color($class_color); } else { $line .= set_color($bit_color); } for (my $i=1;$i<33;$i++) { $bit = 0; if (($address & (1 << 32-$i)) == (1 << 32-$i)) { $bit = 1; } $line .= $bit; if ($classbitcolor_on && $bit == 0) { $classbitcolor_on = 0; if ($newbitcolor_on) { $line .= set_color($subnt_color); } else { $line .= set_color($bit_color); } } # print "$mask1 $i % 8 == " . (($i) % 8) . "\n"; if ($i % 8 == 0 && $i < 32) { $line .= set_color($norml_color) . '.'; $line .= set_color('oldcolor'); } if ($i == $mask1) { $line .= " "; } if (($i == $mask1 || $i == $mask2) && $mask1 != $mask2) { if ($newbitcolor_on) { $newbitcolor_on = 0; $line .= set_color($bit_color) if ! $classbitcolor_on; } else { $newbitcolor_on = 1; $line .= set_color($subnt_color) if ! $classbitcolor_on; } } } $line .= set_color($norml_color); print "$line"; html(" \n"); } html("
"; } } } $line = substr($str,$start,$current_pos-$start); $result .= "$line"; #warn "'return RESULT $result'\n"; return $result; } # gets network address as dq # returns string description,string url sub netblock { my ($mynetwork_start,$mymask) = @_; my $mynetwork_end = $mynetwork_start | ((~$mymask) & $thirtytwobits); my %netblocks = ( "192.168.0.0/16" => "Private Internet,http://www.ietf.org/rfc/rfc1918.txt", "172.16.0.0/12" => "Private Internet,http://www.ietf.org/rfc/rfc1918.txt", "10.0.0.0/8" => "Private Internet,http://www.ietf.org/rfc/rfc1918.txt", "169.254.0.0/16" => "APIPA,http://www.ietf.org/rfc/rfc3330.txt", "127.0.0.0/8" => "Loopback,http://www.ietf.org/rfc/rfc1700.txt", "224.0.0.0/4" => "Multicast,http://www.ietf.org/rfc/rfc3171.txt" ); my $match = 0; # foreach (keys %netblocks) { my ($network,$mask) = split "/",$_; my $start = argton($network,0); my $end = $start + (1 << (32-$mask)) -1; # mynetwork starts within block if ($mynetwork_start >= $start && $mynetwork_start <= $end) { $match++; } # mynetwork ends within block if ($mynetwork_end >= $start && $mynetwork_end <= $end) { $match++; } # block is part of mynetwork if ($start > $mynetwork_start && $end < $mynetwork_end) { $match = 1; } if ($match == 1) { return "In Part ".$netblocks{$_}; } if ($match == 2) { return $netblocks{$_}; } } return ""; } sub p2 { my $x = shift; return 1 << $x } sub ntob6 { my $n = shift; my $b;# = ""; #my $nr = 0; #$b = "$n "; for(my $i=127;$i>-1;$i--) { #print "$i "; #print 1 << $i; #print "\n"; #$nr++; if (($n & (1 << $i)) == (1 << $i)) { $b .= "1"; } else { $b .= "0"; } if ($i % 16 == 0 && $i != 0) { $b .= ":"; } } return $b; # . " " . $nr; } sub print_summary6 { my $address = shift; my $netmask = shift; printf "%-9s","Address:"; printf "%-40s",ntoip6($address); printf "%-130s",ntob6($address); print "\n"; printf "%-9s","Netmask:"; printf "%-40s",$netmask; printf "%-130s",ntob6(prefixlenton($netmask)); print "\n"; printf "%-9s","Prefix:"; printf "%-40s",ntoip6($address & prefixlenton($netmask))."/".$netmask; printf "%-130s",ntob6($address & prefixlenton($netmask)); print "\n"; print "\n"; } sub ipcalc6 { #print "welcome to ipv6\n"; my $address = shift; my $address2 = shift; my $mask1 = shift; my $mask2 = shift; #print "$address\n"; #print ntoip6($address); #print "\n"; print_summary6($address,$mask1); exit; } # ------- converter --------------------------------------------- sub ntoip6 { my $n = shift; my $slice; my @slices; my $result; for (my $i=7;$i>-1;$i--) { $slice = ($n >> ($i*16)) & 65535; push @slices,sprintf "%x",$slice; } $result = join ":",@slices; # compress my $length = 0; my $max_length = 0; my $start = 0; for (my $i=0;$i<8;$i++) { $length = 0; while (($i+$length < 8) && $slices[$i+$length] eq "0") { $length++; } if ($length > $max_length) { $start = $i; $max_length = $length; } } if ($max_length > 0) { $result = ""; if ($start == 0) { $result = "::"; } for (my $i = 0; $i<8;$i++) { if (! ($i>=$start && $i<$start+$max_length)) { $result .= $slices[$i]; if ($i < 7) { $result .= ":"; } if ($i+1 == $start) { $result .= ":"; } } } } return $result; } sub bitcountmaskton { my $bitcountmask = shift; my $n; for (my $i=0;$i<$bitcountmask;$i++) { $n |= 1 << (31-$i); } return $n; } sub ip6ton { my $arg = shift; my $n = 0; my @slice; my $compressed = 0; $arg = lc($arg); my @tmp; my $test = $arg; $test =~ s/[0-9a-f:]//g; if ($test ne '') { ###print "Illegal chars\n"; return -1; } $test = $arg; if ($arg =~ /^::/) { $arg = "0".$arg; } if ($arg =~/::$/) { $arg = $arg."0"; } @tmp = split ":",$arg; #foreach my $x (@tmp) #{ # print "- '$x'\n"; #} foreach my $slice (@tmp) { #print "- '$slice'\n"; if ($slice eq '') { if ($compressed) { ###print "multiple ::\n"; return -1; } for (my $i=0;$i<8-$#tmp;$i++) { push @slice,0; $compressed = 1; } } else { push @slice,$slice; } } #foreach my $s (@slice) { # print "- $s\n"; #} #print $#slice; #print "\n"; if ($#slice != 7) { #print "nr of slices != 8\n"; return -1; } for (my $i=0;$i<8;$i++) { $n += hex($slice[$i]) << 16*(7-$i); #print "n += $slice[$i] << ".16*(7-$i) ." $n\n"; #print ntob($n); #print "\n"; #print "\n"; } return $n; } sub prefixlenton { my $prefixlen = shift; my $n = 0; for (my $i=128;$i>127-$prefixlen;$i--) { $n += p2($i); } return $n; } sub check_mask6 { my $mask = shift; if ($mask !~ /^\d{1,3}$/ || $mask < 0 || $mask > 128) { return -1; } return $mask; } sub argton # expects 1. an address as dotted decimals, bit-count-mask, or hex # 2. netmask flag. if set -> check netmask and negate wildcard # masks # returns integer or -1 if invalid { my $arg = shift; my $netmask_flag = shift; my $i = 24; my $n = 0; # ipv6 #print "arg = '$arg'\n"; #print "netmask_flag = '$netmask_flag'\n"; if ($netmask_flag == 0 && $arg =~ /^[0-9a-fA-F:]+$/) { # check syntax $ipv6 = 1; return ip6ton($arg); } # dotted decimals if ($arg =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/) { my @decimals = ($1,$2,$3,$4); foreach (@decimals) { if ($_ > 255 || $_ < 0) { return -1; } $n += $_ << $i; $i -= 8; } if ($netmask_flag) { return validate_netmask($n); } return $n; } # bit-count-mask (24 or /24) $arg =~ s/^\/(\d+)$/$1/; # ipv6 # for ipv6 this code is never reached: if ($ipv6) { if ($arg !~ /^\d{1,3}$/ || $arg < 0 || $arg > 128) { return -1; } return prefixlenton($arg); } # ipv4 if ($arg =~ /^\d{1,2}$/) { if ($arg < 0 || $arg > 32) { return -1; } for ($i=0;$i<$arg;$i++) { $n |= 1 << (31-$i); } return $n; } # hex if ($arg =~ /^[0-9A-Fa-f]{8}$/ || $arg =~ /^0x[0-9A-Fa-f]{8}$/ ) { if ($netmask_flag) { return validate_netmask(hex($arg)); } return hex($arg); } # invalid return -1; sub validate_netmask { my $mask = shift; my $saw_zero = 0; # negate wildcard if (($mask & (1 << 31)) == 0) { print "WILDCARD\n"; $mask = ~$mask; } # find ones following zeros for (my $i=0;$i<32;$i++) { if (($mask & (1 << (31-$i))) == 0) { $saw_zero = 1; } else { if ($saw_zero) { print "INVALID NETMASK\n"; return -1; } } } return $mask; } } sub ntoa { return join ".",unpack("CCCC",pack("N",shift)); } sub ntobitcountmask # expects integer # returns bitcountmask { my $mask = shift; my $bitcountmask = 0; # find first zero while ( ($mask & (1 << (31-$bitcountmask))) != 0 ) { if ($bitcountmask > 31) { last; } $bitcountmask++; } return $bitcountmask; } # ------- documentation ---------------------------------------- sub usage { print << "EOF"; Usage: ipcalc [options] [[/]] [NETMASK] ipcalc takes an IP address and netmask and calculates the resulting broadcast, network, Cisco wildcard mask, and host range. By giving a second netmask, you can design sub- and supernetworks. It is also intended to be a teaching tool and presents the results as easy-to-understand binary values. -n --nocolor Don't display ANSI color codes. -c --color Display ANSI color codes (default). -b --nobinary Suppress the bitwise output. -c --class Just print bit-count-mask of given address. -h --html Display results as HTML (not finished in this version). -v --version Print Version. -s --split n1 n2 n3 Split into networks of size n1, n2, n3. -r --range Deaggregate address range. --help Longer help text. Examples: ipcalc 192.168.0.1/24 ipcalc 192.168.0.1/255.255.128.0 ipcalc 192.168.0.1 255.255.128.0 255.255.192.0 ipcalc 192.168.0.1 0.0.63.255 ipcalc - deaggregate address range ipcalc / --s a b c split network to subnets where a b c fits in. ! New HTML support not yet finished. ipcalc $version EOF } sub help { print << "EOF"; IP Calculator $version Enter your netmask(s) in CIDR notation (/25) or dotted decimals (255.255.255.0). Inverse netmask are recognized. If you omit the netmask, ipcalc uses the default netmask for the class of your network. Look at the space between the bits of the addresses: The bits before it are the network part of the address, the bits after it are the host part. You can see two simple facts: In a network address all host bits are zero, in a broadcast address they are all set. The class of your network is determined by its first bits. If your network is a private internet according to RFC 1918 this is remarked. When displaying subnets the new bits in the network part of the netmask are marked in a different color. The wildcard is the inverse netmask as used for access control lists in Cisco routers. You can also enter netmasks in wildcard notation. Do you want to split your network into subnets? Enter the address and netmask of your original network and play with the second netmask until the result matches your needs. Questions? Comments? Drop me a mail: krischan at jodies.de http://jodies.de/ipcalc Thanks for your nice ideas and help to make this tool more useful: Bartosz Fenski Denis A. Hainsworth Foxfair Hu Frank Quotschalla Hermann J. Beckers Igor Zozulya Kevin Ivory Lars Mueller Lutz Pressler Oliver Seufer Scott Davis Steve Kent Sven Anderson Torgen Foertsch Edward Nick Clifford Victor Engmark EOF usage(); exit; } ipcalc-0.51/ipcalc.1 0000664 0000000 0000000 00000003624 14140537103 0014212 0 ustar 00root root 0000000 0000000 .\" -*- nroff -*- .\" .\" ipcalc.1 .\" .\" This program was written by .\" Krischan Jodies .\" .\" This manpage was created by: .\" Nick Clifford .\" .\" The author of the program retains copyrights to the program, however .\" his manpage is Copyright (c) 2003 Nick Clifford .\" .\" This program and this manpage is distributed under the terms of the .\" GNU General Public License. See COPYING for additional information. .\" .TH ipcalc 1 .\" "ipcalc Manual" "Jan 25, 2003" .SH NAME ipcalc - An IPv4 Netmask/broadcast/etc calculator .SH SYNOPSIS \fB ipcalc \fR [options] \fIADDRESS\fR[[/]\fINETMASK\fR] [\fINETMASK\fR] .SH DESCRIPTION \fBipcalc\fR takes an IPv4 address and netmask and calculates the resulting broadcast, network, Cisco wildcard mask, and host range. By giving a second netmask, you can design sub- and supernetworks. It is also intended to be a teaching tool and presents the results as easy-to-understand binary values. .TP \fB--help\fR Display help usage .TP \fB-n\fR, \fB--nocolor\fR Don't display ANSI color codes .TP \fB-b\fR, \fB--nobinary\fR Suppress the bitwise output .TP \fB-c\fR, \fB--class\fR Just print bit-count-mask of given address .TP \fB-h\fR, \fB--html\fR Display results as HTML .TP \fB-v\fR, \fB--version\fR Print Version .TP \fB-s\fR, \fB--split\fR \fIn1\fR \fIn2\fR \fIn3\fR. Split into networks of size n1, n2, n3 .TP \fB-r\fR, \fB--range\fR Deaggregate address range .SH EXAMPLES ipcalc 192.168.0.1/24 .PP ipcalc 192.168.0.1/255.255.128.0 .PP ipcalc 192.168.0.1 255.255.128.0 255.255.192.0 .PP ipcalc 192.168.0.1 0.0.63.255 .PP deaggregate address range .RS \fBipcalc - \fP .RE .PP split network to subnets where a b c fits in .RS \fBipcalc / -s a b c\fP .RE .SH AUTHOR Written by Krischan Jodies .SH "SEE ALSO" .BR ipsc (1) .BR gipsc (1) .PP The ipcalc website: http://jodies.de/ipcalc ipcalc-0.51/ipcalc.cgi 0000775 0000000 0000000 00000022317 14140537103 0014617 0 ustar 00root root 0000000 0000000 #!/usr/bin/perl # CGI Wrapper for IPv4 Calculator # # Copyright (C) Krischan Jodies 2000 - 2021 # krischan()jodies.de, http://jodies.de/ipcalc # # Copyright (C) for the graphics ipcalc.gif and ipcalculator.png # Frank Quotschalla. 2002 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # 0.14.3 # 0.15 25.09.2000 Added link to this wrapper # 0.16 07.11.2000 Get version from ipcalc # 0.17 09.01.2001 Added screenshot # 0.18 02.02.2001 Played with the html # 0.18.1 03.02.2001 Played even more with the html # 0.19 01.04.2001 Help text for wildcard netmask / Credits # 0.20 20.05.2001 Changed error messages # 0.21 19.06.2001 Adapted to new -c option # 0.22 30.07.2002 Stole javascript at dict.leo.org # 0.23 28.10.2004 Remove whitespace in input fields # Idea by David Shirlay David.Shirley(a)team.telstra.com # 0.24 07.07.2005 Added license text to cgi-wrapper. Add style into cgi script # 0.25 11.01.2006 Link to screenshot was wrong. # 0.26 27.07.2006 Replaced REQUEST_URI with SCRIPT_URL to prevent cross-site-scripting attacks $|=1; $ipcalc = "/usr/local/bin/ipcalc"; $MAIL_ADDRESS="ipcalc-200502@jodies.de"; # history: # 200404 $actionurl = $ENV{'SCRIPT_URL'}; $actionurl =~ s/&/&/g; use CGI; $query = new CGI; $host = $query->param('host'); $mask1 = $query->param('mask1'); $mask2 = $query->param('mask2'); $help = $query->param('help'); $host =~ s/ //g; $mask1 =~ s/ //g; $mask2 =~ s/ //g; $version = qx($ipcalc -v); chomp $version; if (! defined $host) { $host = ''; } if (! defined $mask1) { $mask1 = ''; $help = 1; } if (! defined $mask2) { $mask2 = ''; } if ($mask2 eq $mask1) { $mask2 = ''; } if ($host eq '') { $error .= " No host given\n"; $host = '192.168.0.1'; } $testhost = $host; $testhost =~ s/\.//g; if ($testhost !~ /^\d+$/) { $error .= " Illegal value for host ('$host')\n"; $host = '192.168.0.1'; } if ($mask1 eq '') { $error .= " No netmask given (using default netmask of your network's class)\n"; $mask1 = qx($ipcalc -c $host); } $testhost = $mask1; $testhost =~ s/\.//g; if ($testhost !~ /^\d+$/) { $error .= " Illegal value for netmask ('$mask1')\n"; $mask1 = 24; } if ($mask2 ne '') { $testhost = $mask2; $testhost =~ s/\.//g; if ($testhost !~ /^\d+$/) { $error .= " Illegal value for netmask for sub/supernet ('$mask2')\n"; $mask2 = ''; } } print $query->header; print << "EOF"; IP Calculator / IP Subnetting EOF #print "$ENV{HTTP_USER_AGENT}
\n"; print << "EOF";EOF ipcalc-0.51/ipcalc.gif 0000664 0000000 0000000 00000015075 14140537103 0014622 0 ustar 00root root 0000000 0000000 GIF89ad _ $6hhhMNO165"$ *6CRAk!yd12?97R_``mLLpWj" W~u)(0kqZz>>U.KJJLM6nQRr32evvv@@d(@6*>*>Pza_yR^+A 710ii{98w(&W2!>*(@32vZ(jhhXrr32X℀DFFfՊ:ʾr,fWt@BzT`YX]MLdr?BCREk.>K9fO..yTT}>ʾ2'> A# Ae
EOF if ($help) { print << "EOF";
EOF } print <<"EOF";
IP Calculator
ipcalc takes an IP address and netmask and calculates the resulting broadcast, network, Cisco wildcard mask, and host range. By giving a second netmask, you can design subnets and supernets. It is also intended to be a teaching tool and presents the subnetting results as easy-to-understand binary values.
Enter your netmask(s) in CIDR notation (/25) or dotted decimals (255.255.255.0). Inverse netmasks are recognized. If you omit the netmask ipcalc uses the default netmask for the class of your network.
Look at the space between the bits of the addresses: The bits before it are the network part of the address, the bits after it are the host part. You can see two simple facts: In a network address all host bits are zero, in a broadcast address they are all set.
The class of your network is determined by its first bits.
If your network is a private internet according to RFC 1918 this is remarked. When displaying subnets the new bits in the network part of the netmask are marked in a different color
The wildcard is the inverse netmask as used for access control lists in Cisco routers.
Do you want to split your network into subnets? Enter the address and netmask of your original network and play with the second netmask until the result matches your needs.
You can have all this fun at your shell prompt. Originally ipcalc was not intended for creating HTML and still works happily in /usr/local/bin/ :-)
Questions? Comments? Drop me a mail...
Thanks for your ideas and help to make this tool more useful:
Bartosz Fenski Christan Ebnoether Denis A. Hainsworth Edward Foxfair Hu Frank Quotschalla Hermann J. Beckers Igor Zozulya Kevin Ivory Lars Mueller Lutz Pressler Nick Clifford Oliver Seufer Scott Davis Steve Kent Sven Anderson Torgen Foertsch Tim Brown Victor EngmarkEOF if (defined $error) { $error =~ s/</gm; $error =~ s/>/>/gm; $error =~ s/\n/
/g; print qq(\n); print "$error
"; print qq(\n); } system("$ipcalc -h $host $mask1 $mask2"); print <<"EOF";
Version $version
Download
Screenshot (ipcalc works also at the prompt)
CGI wrapper that produced this page.
Archive
Have a look in the archives for the new version 0.38, with the capability to deaggregate network ranges
How to run this under windows
Debian users can apt-get install ipcalc
2000-2021 Krischan Jodies,&WZPK_X`V0'{dL|<;?FFhFFjbKLZZwQR..DPDV52O,'&:rr)'Lvv%#Zjb+7vs_z/.iTT<'*y92>pqpg}77xzz10``^~E7hss2.C[QeM>.]\\ jUjXVs!I6.>LL|%&kk<CGAQ<\q88l`bml%#{v{qn"4@S-<%&$"Jy=0STGBfJN+!6-.2k`x:6>F:N]2.Wyz@FNl歼;:`fhbvED:ւRTSRa! , d _ H*\Ȱ#J谢ŋN(0Ǐ rI#%\aJ-毘_C; 5#4pAWr Iװ{V2