Add IPv6 support

Split IPv4 and IPv6 calculations into different JS files to make them easier to understand.

IDE decided to format HTML code and I left it as-is.
This commit is contained in:
Yehuda Katz 2021-12-08 00:13:30 -05:00
parent 8329d4add7
commit 5088bbe600
No known key found for this signature in database
GPG Key ID: 6AFEF232927278DD
5 changed files with 750 additions and 513 deletions

44
calculations.js Normal file
View File

@ -0,0 +1,44 @@
function inet_ntoa(mode, addrint) {
var fn = "inet_ntoa_" + mode;
return window[fn](addrint);
}
function inet_aton(mode, addrint) {
var fn = "inet_aton_" + mode;
return window[fn](addrint);
}
function network_address(mode, addrint) {
var fn = "network_address_" + mode;
return window[fn](addrint);
}
function subnet_addresses(mode, addrint) {
var fn = "subnet_addresses_" + mode;
return window[fn](addrint);
}
function subnet_first_address_useable(mode, addrint) {
var fn = "subnet_first_address_useable_" + mode;
return window[fn](addrint);
}
function subnet_last_address_useable(mode, addrint) {
var fn = "subnet_last_address_useable_" + mode;
return window[fn](addrint);
}
function subnet_last_address(mode, subnet, mask) {
var fn = "subnet_last_address_" + mode;
return window[fn](mode, subnet, mask);
}
function subnet_netmask(mode, addrint) {
var fn = "subnet_netmask_" + mode;
return window[fn](addrint);
}
function num_hosts(mode, useableFirst, useableLast) {
var fn = "num_hosts_" + mode;
return window[fn](useableFirst, useableLast);
}

60
calculations_4.js Normal file
View File

@ -0,0 +1,60 @@
function inet_ntoa_4(addrint) {
return (
((addrint >> 24) & 0xff) +
"." +
((addrint >> 16) & 0xff) +
"." +
((addrint >> 8) & 0xff) +
"." +
(addrint & 0xff)
);
};
function inet_aton_4(addrstr) {
var re = /^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/;
var res = re.exec(addrstr);
if (res === null) {
return null;
}
for (var i = 1; i <= 4; i++) {
if (res[i] < 0 || res[i] > 255) {
return null;
}
}
return (res[1] << 24) | (res[2] << 16) | (res[3] << 8) | res[4];
}
function network_address_4(ip, mask) {
var maskbits = 0;
for (var i = 31 - mask; i >= 0; i--) {
ip &= ~1 << i;
}
return ip;
}
function subnet_addresses_4(mask) {
return 1 << (32 - mask);
}
function subnet_first_address_useable_4(addrint) {
return addrint + 1;
}
function subnet_last_address_useable_4(addrint) {
return addrint - 1;
}
function subnet_last_address_4(mode, subnet, mask) {
return subnet + subnet_addresses(mode, mask) - 1;
}
function subnet_netmask_4(mask) {
return network_address(4, 0xffffffff, mask);
}
function num_hosts_4(useableFirst, useableLast) {
return 1 + useableLast - useableFirst;
}

79
calculations_6.js Normal file
View File

@ -0,0 +1,79 @@
function inet_ntoa_6(addrint) {
return "" +
((addrint >> 112n) & BigInt(0xffff)).toString(16) +
":" +
((addrint >> 96n) & BigInt(0xffff)).toString(16) +
":" +
((addrint >> 80n) & BigInt(0xffff)).toString(16) +
":" +
((addrint >> 64n) & BigInt(0xffff)).toString(16) +
":" +
((addrint >> 48n) & BigInt(0xffff)).toString(16) +
":" +
((addrint >> 32n) & BigInt(0xffff)).toString(16) +
":" +
((addrint >> 16n) & BigInt(0xffff)).toString(16) +
":" +
(addrint & BigInt(0xffff)).toString(16);
}
function inet_aton_6(addrstr) {
var re =
/^([0-9a-f]{1,4})\:([0-9a-f]{1,4})\:([0-9a-f]{1,4})\:([0-9a-f]{1,4})\:([0-9a-f]{1,4})\:([0-9a-f]{1,4})\:([0-9a-f]{1,4})\:([0-9a-f]{1,4})$/;
var res = re.exec(addrstr);
if (res === null) {
return null;
}
for (var i = 1; i <= 8; i++) {
if (res[i] < 0 || res[i] > 0xffff) {
return null;
}
}
var r1 = BigInt(parseInt(res[1], 16)) << 112n;
var r2 = BigInt(parseInt(res[2], 16)) << 96n;
var r3 = BigInt(parseInt(res[3], 16)) << 80n;
var r4 = BigInt(parseInt(res[4], 16)) << 64n;
var r5 = BigInt(parseInt(res[5], 16)) << 48n;
var r6 = BigInt(parseInt(res[6], 16)) << 32n;
var r7 = BigInt(parseInt(res[7], 16)) << 16n;
var r8 = BigInt(parseInt(res[8], 16));
var rt = r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8;
return rt;
}
function network_address_6(ip, mask) {
var maskbits = 0;
for (var i = 128 - mask; i >= 0; i--) {
ip &= ~1 << i;
}
return ip;
}
function subnet_addresses_6(mask) {
return 1n << (128n - BigInt(mask));
}
function subnet_first_address_useable_6(addrint) {
return addrint + 1n;
}
function subnet_last_address_useable_6(addrint) {
return addrint - 1n;
}
function subnet_last_address_6(mode, subnet, mask) {
return subnet + subnet_addresses(mode, mask) - 1n;
}
function subnet_netmask_6(mask) {
return undefined;
}
function num_hosts_6(useableFirst, useableLast) {
return 1n + useableLast - useableFirst;
}

View File

@ -1,5 +1,5 @@
<? <?php
for ($i=0;$i<=32; $i++) { for ($i=0;$i<=128; $i++) {
$str = '/'.$i; $str = '/'.$i;
$font = 2; $font = 2;

View File

@ -1,67 +1,89 @@
<html> <html>
<head> <head>
<title>Visual Subnet Calculator</title> <title>Visual Subnet Calculator</title>
<script language="javascript" type="text/javascript"> <script src="calculations_4.js"></script>
<!-- <script src="calculations_6.js"></script>
<script src="calculations.js"></script>
var curNetwork = 0; <script language="javascript" type="text/javascript">
var curMask = 0; var curNetwork = 0;
var curMask = 0;
function updateNetwork() var curVersion = 4;
{
var newNetworkStr = document.forms['calc'].elements['network'].value;
var newMask = parseInt(document.forms['calc'].elements['netbits'].value);
var newNetwork = inet_aton(newNetworkStr); function updateNetwork() {
var newNetworkStr = document.forms["calc"].elements["network"].value;
var newMask = parseInt(
document.forms["calc"].elements["netbits"].value
);
var newVersion = parseInt(
document.forms["calc"].elements["version"].value
);
var newNetwork = inet_aton(newVersion, newNetworkStr);
if (newNetwork === null) { if (newNetwork === null) {
alert('Invalid network address entered'); alert("Invalid network address entered");
return; return;
} }
var tmpNetwork = network_address(newNetwork, newMask); var tmpNetwork = network_address(newVersion, newNetwork, newMask);
if (newNetwork != tmpNetwork) { if (newNetwork != tmpNetwork) {
alert('The network address entered is not on a network boundary for this mask.\nIt has been changed to '+inet_ntoa(tmpNetwork)+'.'); alert(
"The network address entered is not on a network boundary for this mask.\nIt has been changed to " +
inet_ntoa(newVersion, tmpNetwork) +
"."
);
newNetwork = tmpNetwork; newNetwork = tmpNetwork;
document.forms['calc'].elements['network'].value = inet_ntoa(tmpNetwork); document.forms["calc"].elements["network"].value = inet_ntoa(
newVersion,
tmpNetwork
);
} }
if (newMask < 0 || newMask > 32) { if ((newVersion == 4 && (newMask < 0 || newMask > 32)) || (newVersion == 6 && (newMask < 0 || newMask > 128))) {
alert('The network mask you have entered is invalid'); alert("The network mask you have entered is invalid");
return; return;
} }
if (curMask == 0) { if (curMask == 0) {
curMask = newMask; curMask = newMask;
curNetwork = newNetwork; curNetwork = newNetwork;
curVersion = newVersion;
startOver(); startOver();
} } else if (
else if (curMask != newMask && confirm('You are changing the base network from /'+curMask+' to /'+newMask+'. This will reset any changes you have made. Proceed?')) { (curMask != newMask || curVersion != newVersion) &&
confirm(
"You are changing the base network from /" +
curMask + "(v" + curVersion +
") to /" +
newMask + "(v" + newVersion +
"). This will reset any changes you have made. Proceed?"
)
) {
curMask = newMask; curMask = newMask;
curNetwork = newNetwork; curNetwork = newNetwork;
curVersion = newVersion;
startOver(); startOver();
} } else {
else { document.forms["calc"].elements["netbits"].value = curMask;
document.forms['calc'].elements['netbits'].value = curMask;
curNetwork = newNetwork; curNetwork = newNetwork;
recreateTables(); recreateTables();
} }
} }
function startOver() function startOver() {
{
rootSubnet = [0, 0, null]; rootSubnet = [0, 0, null];
recreateTables(); recreateTables();
} }
function recreateTables() function recreateTables() {
{ var calcbody = document.getElementById("calcbody");
var calcbody = document.getElementById('calcbody');
if (!calcbody) { if (!calcbody) {
alert('Body not found'); alert("Body not found");
return; return;
} }
@ -72,37 +94,51 @@ function recreateTables()
updateNumChildren(rootSubnet); updateNumChildren(rootSubnet);
updateDepthChildren(rootSubnet); updateDepthChildren(rootSubnet);
createRow(calcbody, rootSubnet, curNetwork, curMask, [curMask, rootSubnet[1], rootSubnet], rootSubnet[0]); createRow(
calcbody,
rootSubnet,
curNetwork,
curMask,
[curMask, rootSubnet[1], rootSubnet],
rootSubnet[0]
);
document.getElementById('joinHeader').colSpan = (rootSubnet[0] > 0 ? rootSubnet[0] : 1); document.getElementById("joinHeader").colSpan =
document.getElementById('col_join').span = (rootSubnet[0] > 0 ? rootSubnet[0] : 1); rootSubnet[0] > 0 ? rootSubnet[0] : 1;
document.getElementById("col_join").span =
rootSubnet[0] > 0 ? rootSubnet[0] : 1;
/* Create the bookmark hyperlink */ /* Create the bookmark hyperlink */
var link = document.getElementById('saveLink'); var link = document.getElementById("saveLink");
if (link) { if (link) {
link.href = 'subnets.html?network='+inet_ntoa(curNetwork)+'&mask='+curMask+'&division='+binToAscii(nodeToString(rootSubnet)); link.href =
"subnets.html?version=" +
curVersion +
"&network=" +
inet_ntoa(curVersion, curNetwork) +
"&mask=" +
curMask +
"&division=" +
binToAscii(nodeToString(rootSubnet));
}
} }
}
function nodeToString(node) function nodeToString(node) {
{
if (node[2]) { if (node[2]) {
return '1'+nodeToString(node[2][0])+nodeToString(node[2][1]); return "1" + nodeToString(node[2][0]) + nodeToString(node[2][1]);
} else {
return "0";
} }
else {
return '0';
} }
}
function binToAscii(str) function binToAscii(str) {
{ var curOut = "";
var curOut = '';
var curBit = 0; var curBit = 0;
var curChar = 0; var curChar = 0;
for (var i=0; i<str.length; i++) { for (var i = 0; i < str.length; i++) {
if (str.charAt(i) == '1') { if (str.charAt(i) == "1") {
curChar |= 1<<curBit; curChar |= 1 << curBit;
} }
curBit++; curBit++;
if (curBit > 3) { if (curBit > 3) {
@ -114,288 +150,249 @@ function binToAscii(str)
if (curBit > 0) { if (curBit > 0) {
curOut += curChar.toString(16); curOut += curChar.toString(16);
} }
return str.length+'.'+curOut; return str.length + "." + curOut;
} }
function asciiToBin(str) function asciiToBin(str) {
{
var re = /([0-9]+)\.([0-9a-f]+)/; var re = /([0-9]+)\.([0-9a-f]+)/;
var res = re.exec(str); var res = re.exec(str);
var len = res[1]; var len = res[1];
var encoded = res[2]; var encoded = res[2];
var out = ''; var out = "";
for (var i=0; i< res[1]; i++) { for (var i = 0; i < res[1]; i++) {
var ch = parseInt(res[2].charAt(Math.floor(i/4)), 16); var ch = parseInt(res[2].charAt(Math.floor(i / 4)), 16);
var pos = i % 4; var pos = i % 4;
out += (ch & (1<<pos) ? '1' : '0'); out += ch & (1 << pos) ? "1" : "0";
} }
return out; return out;
} }
function createRow(calcbody, node, address, mask, labels, depth) function createRow(calcbody, node, address, mask, labels, depth) {
{
if (node[2]) { if (node[2]) {
var newlabels = labels; var newlabels = labels;
newlabels.push(mask+1); newlabels.push(mask + 1);
newlabels.push(node[2][0][1]); newlabels.push(node[2][0][1]);
newlabels.push(node[2][0]); newlabels.push(node[2][0]);
createRow(calcbody, node[2][0], address, mask+1, newlabels, depth-1); createRow(
calcbody,
node[2][0],
address,
mask + 1,
newlabels,
depth - 1
);
newlabels = new Array(); newlabels = new Array();
newlabels.push(mask+1); newlabels.push(mask + 1);
newlabels.push(node[2][1][1]); newlabels.push(node[2][1][1]);
newlabels.push(node[2][1]); newlabels.push(node[2][1]);
createRow(calcbody, node[2][1], address+subnet_addresses(mask+1), mask+1, newlabels, depth-1); createRow(
} calcbody,
else { node[2][1],
var newRow = document.createElement('TR'); address + subnet_addresses(curVersion, mask + 1),
mask + 1,
newlabels,
depth - 1
);
} else {
var newRow = document.createElement("TR");
calcbody.appendChild(newRow); calcbody.appendChild(newRow);
/* subnet address */ /* subnet address */
var newCell = document.createElement('TD'); var newCell = document.createElement("TD");
newCell.appendChild(document.createTextNode(inet_ntoa(address)+'/'+mask)); newCell.appendChild(
document.createTextNode(inet_ntoa(curVersion, address) + "/" + mask)
);
newRow.appendChild(newCell); newRow.appendChild(newCell);
var addressFirst = address; var addressFirst = address;
var addressLast = subnet_last_address(address, mask); var addressLast = subnet_last_address(curVersion, address, mask);
var useableFirst = address + 1; var useableFirst = subnet_first_address_useable(curVersion, address);
var useableLast = addressLast - 1; var useableLast = subnet_last_address_useable(curVersion, addressLast);
var numHosts; var numHosts;
var addressRange; var addressRange;
var usaebleRange; var usaebleRange;
if (mask == 32) { if ((curVersion == 4 && mask == 32) || (curVersion == 6 && mask == 128)) {
addressRange = inet_ntoa(addressFirst); addressRange = inet_ntoa(curVersion, addressFirst);
useableRange = addressRange; useableRange = addressRange;
numHosts = 1; numHosts = 1;
} } else {
else { addressRange =
addressRange = inet_ntoa(addressFirst)+' - '+inet_ntoa(addressLast); inet_ntoa(curVersion, addressFirst) +
if (mask == 31) { " - " +
inet_ntoa(curVersion, addressLast);
if ( (curVersion == 4 && mask == 31) || (curVersion == 6 && mask == 127)) {
useableRange = addressRange; useableRange = addressRange;
numHosts = 2; numHosts = 2;
} } else {
else { useableRange =
useableRange = inet_ntoa(useableFirst)+' - '+inet_ntoa(useableLast); inet_ntoa(curVersion, useableFirst) +
numHosts = (1 + useableLast - useableFirst); " - " +
inet_ntoa(curVersion, useableLast);
numHosts = num_hosts(curVersion, useableFirst, useableLast);
} }
} }
/* netmask */ /* netmask */
var newCell = document.createElement('TD'); var newCell = document.createElement("TD");
newCell.appendChild(document.createTextNode(inet_ntoa(subnet_netmask(mask)))); var netmask = subnet_netmask(curVersion, mask);
if (netmask) {
newCell.appendChild(
document.createTextNode(inet_ntoa(curVersion, netmask))
);
}
newRow.appendChild(newCell); newRow.appendChild(newCell);
/* range of addresses */ /* range of addresses */
var newCell = document.createElement('TD'); var newCell = document.createElement("TD");
newCell.appendChild(document.createTextNode(addressRange)); newCell.appendChild(document.createTextNode(addressRange));
newRow.appendChild(newCell); newRow.appendChild(newCell);
/* useable addresses */ /* useable addresses */
var newCell = document.createElement('TD'); var newCell = document.createElement("TD");
newCell.appendChild(document.createTextNode(useableRange)); newCell.appendChild(document.createTextNode(useableRange));
newRow.appendChild(newCell); newRow.appendChild(newCell);
/* Hosts */ /* Hosts */
var newCell = document.createElement('TD'); var newCell = document.createElement("TD");
newCell.appendChild(document.createTextNode(numHosts)); newCell.appendChild(document.createTextNode(numHosts));
newRow.appendChild(newCell); newRow.appendChild(newCell);
/* actions */ /* actions */
var newCell = document.createElement('TD'); var newCell = document.createElement("TD");
newRow.appendChild(newCell); newRow.appendChild(newCell);
if (mask == 32) { if ((curVersion == 4 && mask == 32) || (curVersion == 6 && mask == 128)) {
var newLink = document.createElement('SPAN'); var newLink = document.createElement("SPAN");
newLink.className = 'disabledAction'; newLink.className = "disabledAction";
newLink.appendChild(document.createTextNode('Divide')); newLink.appendChild(document.createTextNode("Divide"));
newCell.appendChild(newLink); newCell.appendChild(newLink);
} } else {
else { var newLink = document.createElement("A");
var newLink = document.createElement('A'); newLink.href = "#";
newLink.href = '#'; newLink.onclick = function () {
newLink.onclick = function () { divide(node); return false; } divide(node);
newLink.appendChild(document.createTextNode('Divide')); return false;
};
newLink.appendChild(document.createTextNode("Divide"));
newCell.appendChild(newLink); newCell.appendChild(newLink);
} }
var colspan = depth - node[0]; var colspan = depth - node[0];
for (var i=(labels.length/3)-1; i>=0; i--) { for (var i = labels.length / 3 - 1; i >= 0; i--) {
var mask = labels[i*3]; var mask = labels[i * 3];
var rowspan = labels[(i*3)+1]; var rowspan = labels[i * 3 + 1];
var joinnode = labels[(i*3)+2]; var joinnode = labels[i * 3 + 2];
var newCell = document.createElement('TD'); var newCell = document.createElement("TD");
newCell.rowSpan = (rowspan > 1 ? rowspan : 1); newCell.rowSpan = rowspan > 1 ? rowspan : 1;
newCell.colSpan = (colspan > 1 ? colspan : 1); newCell.colSpan = colspan > 1 ? colspan : 1;
if (i == (labels.length/3)-1) { if (i == labels.length / 3 - 1) {
newCell.className = 'maskSpan'; newCell.className = "maskSpan";
} } else {
else { newCell.className = "maskSpanJoinable";
newCell.className = 'maskSpanJoinable';
newCell.onclick = newJoin(joinnode); newCell.onclick = newJoin(joinnode);
// newCell.onmouseover = function() { window.status = joinnode[0]+'---'+joinnode[1]+'---'+joinnode[2]+'>>>>>'+node[2];} // newCell.onmouseover = function() { window.status = joinnode[0]+'---'+joinnode[1]+'---'+joinnode[2]+'>>>>>'+node[2];}
} }
var newImg = document.createElement('IMG'); var newImg = document.createElement("IMG");
newImg.src = 'img/'+mask+'.gif'; newImg.src = "img/" + mask + ".gif";
newCell.appendChild(newImg); newCell.appendChild(newImg);
newRow.appendChild(newCell); newRow.appendChild(newCell);
colspan = 1; // reset for subsequent cells colspan = 1; // reset for subsequent cells
} }
} }
}
} /* This is necessary because 'joinnode' changes during the scope of the caller */
function newJoin(joinnode) {
return function () {
join(joinnode);
};
}
/* This is necessary because 'joinnode' changes during the scope of the caller */ function divide(node) {
function newJoin(joinnode)
{
return function() { join(joinnode) };
}
function divide(node)
{
node[2] = new Array(); node[2] = new Array();
node[2][0] = [0, 0, null]; node[2][0] = [0, 0, null];
node[2][1] = [0, 0, null]; node[2][1] = [0, 0, null];
recreateTables(); recreateTables();
} }
function join(node) function join(node) {
{
/* easy as pie */ /* easy as pie */
node[2] = null; node[2] = null;
recreateTables(); recreateTables();
} }
function updateNumChildren(node) function updateNumChildren(node) {
{
if (node[2] == null) { if (node[2] == null) {
node[1] = 0; node[1] = 0;
return 1; return 1;
} } else {
else { node[1] =
node[1] = updateNumChildren(node[2][0]) + updateNumChildren(node[2][1]); updateNumChildren(node[2][0]) + updateNumChildren(node[2][1]);
return node[1]; return node[1];
} }
} }
function updateDepthChildren(node) function updateDepthChildren(node) {
{
if (node[2] == null) { if (node[2] == null) {
node[0] = 0; node[0] = 0;
return 1; return 1;
} } else {
else { node[0] =
node[0] = updateDepthChildren(node[2][0]) + updateDepthChildren(node[2][1]); updateDepthChildren(node[2][0]) + updateDepthChildren(node[2][1]);
return node[1]; return node[1];
} }
}
var rootSubnet;
// each node is Array:
// [0] => depth of children, total number of visible children, children
function inet_ntoa(addrint)
{
return ((addrint >> 24) & 0xff)+'.'+
((addrint >> 16) & 0xff)+'.'+
((addrint >> 8) & 0xff)+'.'+
(addrint & 0xff);
}
function inet_aton(addrstr)
{
var re = /^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/;
var res = re.exec(addrstr);
if (res === null) {
return null;
} }
for (var i=1; i<=4; i++) { var rootSubnet;
if (res[i] < 0 || res[i] > 255) {
return null;
}
}
return (res[1] << 24) | (res[2] << 16) | (res[3] << 8) | res[4]; // each node is Array:
} // [0] => depth of children, total number of visible children, children
function network_address(ip, mask) function preloadSubnetImages() {
{
var maskbits = 0;
for (var i=31-mask; i>=0; i--) {
ip &= ~ 1<<i;
}
return ip;
}
function subnet_addresses(mask)
{
return 1<<(32-mask);
}
function subnet_last_address(subnet, mask)
{
return subnet + subnet_addresses(mask) - 1;
}
function subnet_netmask(mask)
{
return network_address(0xffffffff, mask);
}
function preloadSubnetImages()
{
if (document.images) { if (document.images) {
if (!document.preloadedImages) { if (!document.preloadedImages) {
document.preloadedImages = new Array(); document.preloadedImages = new Array();
} }
for (var i=0; i<=32; i++) { for (var i = 0; i <= 128; i++) {
var img = new Image(); var img = new Image();
img.src = 'img/'+i+'.gif'; img.src = "img/" + i + ".gif";
document.preloadedImages.push(img); document.preloadedImages.push(img);
} }
} }
} }
function calcOnLoad() {
function calcOnLoad()
{
preloadSubnetImages(); preloadSubnetImages();
args = parseQueryString(); args = parseQueryString();
if (args['network'] && args['mask'] && args['division']) { if (args["network"] && args["mask"] && args["division"]) {
document.forms['calc'].elements['network'].value = args['network']; document.forms["calc"].elements["version"].value = args["version"] || 4;
document.forms['calc'].elements['netbits'].value = args['mask']; document.forms["calc"].elements["network"].value = args["network"];
document.forms["calc"].elements["netbits"].value = args["mask"];
updateNetwork(); updateNetwork();
var division = asciiToBin(args['division']); var division = asciiToBin(args["division"]);
rootSubnet = [0, 0, null]; rootSubnet = [0, 0, null];
if (division != '0') { if (division != "0") {
loadNode(rootSubnet, division); loadNode(rootSubnet, division);
} }
recreateTables(); recreateTables();
} } else {
else {
updateNetwork(); updateNetwork();
} }
}
function loadNode(curNode, division)
{
if (division.charAt(0) == '0') {
return division.substr(1);
} }
else {
function loadNode(curNode, division) {
if (division.charAt(0) == "0") {
return division.substr(1);
} else {
curNode[2] = new Array(); curNode[2] = new Array();
curNode[2][0] = [0, 0, null]; curNode[2][0] = [0, 0, null];
curNode[2][1] = [0, 0, null]; curNode[2][1] = [0, 0, null];
@ -404,182 +401,239 @@ function loadNode(curNode, division)
division = loadNode(curNode[2][1], division); division = loadNode(curNode[2][1], division);
return division; return division;
} }
} }
function parseQueryString(str) {
function parseQueryString (str)
{
str = str ? str : location.search; str = str ? str : location.search;
var query = str.charAt(0) == '?' ? str.substring(1) : str; var query = str.charAt(0) == "?" ? str.substring(1) : str;
var args = new Object(); var args = new Object();
if (query) { if (query) {
var fields = query.split('&'); var fields = query.split("&");
for (var f = 0; f < fields.length; f++) { for (var f = 0; f < fields.length; f++) {
var field = fields[f].split('='); var field = fields[f].split("=");
args[unescape(field[0].replace(/\+/g, ' '))] =
unescape(field[1].replace(/\+/g, ' ')); args[unescape(field[0].replace(/\+/g, " "))] = unescape(
field[1].replace(/\+/g, " ")
);
} }
} }
return args; return args;
} }
window.onload = calcOnLoad; window.onload = calcOnLoad;
function toggleColumn(cb) function toggleColumn(cb) {
{ var colName = "col_" + cb.id.substr(3);
var colName = 'col_'+(cb.id.substr(3));
var col = document.getElementById(colName); var col = document.getElementById(colName);
if (cb.checked) { if (cb.checked) {
col.style.display = 'block'; col.style.display = "block";
} } else {
else { col.style.display = "none";
col.style.display = 'none';
} }
recreateTables(); /* because IE draws lines all over the place with border-collapse */ recreateTables(); /* because IE draws lines all over the place with border-collapse */
} }
</script>
//--> <style type="text/css">
</script> H1 {
<style type="text/css">
H1 {
font-family: Arial, Verdana, sans-serif; font-family: Arial, Verdana, sans-serif;
font-size: 18pt; font-size: 18pt;
} }
BODY { BODY {
font-family: Arial, Verdana, sans-serif; font-family: Arial, Verdana, sans-serif;
} }
P { P {
font-family: Arial, Verdana, sans-serif; font-family: Arial, Verdana, sans-serif;
font-size: 75%; font-size: 75%;
} }
.label {
.label {
font-family: Arial, Verdana, sans-serif; font-family: Arial, Verdana, sans-serif;
font-size: 60%; font-size: 60%;
} }
.calc { .calc {
font-family: Arial, Verdana, sans-serif; font-family: Arial, Verdana, sans-serif;
font-size: 80%; font-size: 80%;
border-collapse: collapse; border-collapse: collapse;
} }
.calc td { .calc td {
border: 1px solid black; border: 1px solid black;
} }
.calc thead { .calc thead {
font-weight: bold; font-weight: bold;
background-color: #eeeeee; background-color: #eeeeee;
} }
.disabledAction { .disabledAction {
color: #dddddd; color: #dddddd;
} }
.maskSpan { .maskSpan {
background-color: #cccccc; background-color: #cccccc;
text-align: right; text-align: right;
} }
.maskSpanJoinable { .maskSpanJoinable {
background-color: #cccccc; background-color: #cccccc;
text-align: right; text-align: right;
cursor: hand; cursor: hand;
} }
.maskSpanRotate { .maskSpanRotate {
filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1); filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
background-color:green; background-color: green;
} }
</style>
</head>
<body>
<table width="100%">
<tr valign="top">
<td>
<h1>Visual Subnet Calculator</h1>
</style> <p>Enter the network you wish to subnet:</p>
</head>
<body>
<table width="100%"> <form name="calc" onsubmit="updateNetwork(); return false;">
<tr valign=top> <table cellspacing="0">
<td> <tr>
<td class="label">IPv4 / IPv6</td>
<td class="label">Network Address</td>
<td class="label">Mask bits</td>
</tr>
<tr>
<td>
<input type="radio" name="version" value="4" checked />
<input type="radio" name="version" value="6" />
</td>
<td>
<input
type="text"
name="network"
size="15"
maxlength="45"
value="192.168.0.0"
/>
</td>
<td>
/<input
type="text"
name="netbits"
size="3"
maxlength="3"
value="16"
/>
</td>
<td>
<input type="submit" value="Update" />
<input
type="button"
value="Reset"
onclick="if (confirm('This will reset all subnet divisions you have made. Proceed?')) startOver();"
/>
</td>
</tr>
</table>
<h1>Visual Subnet Calculator</h1> <p>
Show columns:
<input
type="checkbox"
id="cb_subnet"
checked
onclick="toggleColumn(this)"
/><label for="cb_subnet">Subnet address</label>
<input
type="checkbox"
id="cb_netmask"
onclick="toggleColumn(this)"
/><label for="cb_netmask">Netmask</label>
<input
type="checkbox"
id="cb_range"
checked
onclick="toggleColumn(this)"
/><label for="cb_range">Range of addresses</label>
<input
type="checkbox"
id="cb_useable"
checked
onclick="toggleColumn(this)"
/><label for="cb_useable">Useable IPs</label>
<input
type="checkbox"
id="cb_hosts"
checked
onclick="toggleColumn(this)"
/><label for="cb_hosts">Hosts</label>
<input
type="checkbox"
id="cb_divide"
checked
onclick="toggleColumn(this)"
/><label for="cb_divide">Divide</label>
<input
type="checkbox"
id="cb_join"
checked
onclick="toggleColumn(this)"
/><label for="cb_join">Join</label>
</p>
</form>
<p>Enter the network you wish to subnet:</p> <p>
Click below to split and join subnets.<br />
If you wish to save this subnetting for later, bookmark
<a href="subnets.html" id="saveLink">this hyperlink</a>.
</p>
</td>
<td align="right">
<a href="https://github.com/davidc/subnets"
><img
alt="Fork me on GitHub"
src="https://github.blog/wp-content/uploads/2008/12/forkme_right_white_ffffff.png"
style="right: 0; top: 0; position: absolute"
/></a>
</td>
</tr>
</table>
<form name="calc" onsubmit="updateNetwork(); return false;"> <br />
<hr noshade color="black" size="1" />
<br />
<table cellspacing="0"> <table class="calc" cellspacing="0" cellpadding="2">
<tr> <colgroup>
<td class="label">Network Address</td> <col id="col_subnet" />
<td class="label">Mask bits</td> <col id="col_netmask" style="display: none" />
</tr> <col id="col_range" />
<tr> <col id="col_useable" />
<td><input type="text" name="network" size="15" maxlength="15" value="192.168.0.0"></td> <col id="col_hosts" />
<td>/<input type="text" name="netbits" size="2" maxlength="2" value="16"></td> <col id="col_divide" />
<td><input type="submit" value="Update"> <col id="col_join" />
<input type="button" value="Reset" onclick="if (confirm('This will reset all subnet divisions you have made. Proceed?')) startOver();"> </colgroup>
</td> <thead>
</tr> <tr>
</table> <td>Subnet address</td>
<td>Netmask</td>
<p>Show columns: <td>Range of addresses</td>
<input type="checkbox" id="cb_subnet" checked onclick="toggleColumn(this)"><label for="cb_subnet">Subnet address</label> <td>Useable IPs</td>
<input type="checkbox" id="cb_netmask" onclick="toggleColumn(this)"><label for="cb_netmask">Netmask</label> <td>Hosts</td>
<input type="checkbox" id="cb_range" checked onclick="toggleColumn(this)"><label for="cb_range">Range of addresses</label> <td>Divide</td>
<input type="checkbox" id="cb_useable" checked onclick="toggleColumn(this)"><label for="cb_useable">Useable IPs</label> <td id="joinHeader">Join</td>
<input type="checkbox" id="cb_hosts" checked onclick="toggleColumn(this)"><label for="cb_hosts">Hosts</label> </tr>
<input type="checkbox" id="cb_divide" checked onclick="toggleColumn(this)"><label for="cb_divide">Divide</label> </thead>
<input type="checkbox" id="cb_join" checked onclick="toggleColumn(this)"><label for="cb_join">Join</label> <tbody id="calcbody">
</p> <!--tr>
</form>
<p>Click below to split and join subnets.<br>
If you wish to save this subnetting for later, bookmark <a href="subnets.html" id="saveLink">this hyperlink</a>.</p>
</td>
<td align="right">
<a href="https://github.com/davidc/subnets"><img alt="Fork me on GitHub" src="https://github.blog/wp-content/uploads/2008/12/forkme_right_white_ffffff.png" style="right: 0;top: 0;position: absolute;" ></a>
</td>
</tr>
</table>
<br>
<hr noshade color="black" size="1">
<br>
<table class="calc" cellspacing="0" cellpadding="2">
<colgroup>
<col id="col_subnet">
<col id="col_netmask" style="display: none">
<col id="col_range">
<col id="col_useable">
<col id="col_hosts">
<col id="col_divide">
<col id="col_join">
</colgroup>
<thead>
<tr>
<td>Subnet address</td>
<td>Netmask</td>
<td>Range of addresses</td>
<td>Useable IPs</td>
<td>Hosts</td>
<td>Divide</td>
<td id="joinHeader">Join</td>
</tr>
</thead>
<tbody id="calcbody">
<!--tr>
<td>130.94.203.0/24</td> <td>130.94.203.0/24</td>
<td>130.94.203.0 - 130.94.203.255</td> <td>130.94.203.0 - 130.94.203.255</td>
<td>130.94.203.1 - 130.94.203.254 (254)</td> <td>130.94.203.1 - 130.94.203.254 (254)</td>
<td>Divide</td> <td>Divide</td>
</tr--> </tr-->
</tbody> </tbody>
</table> </table>
</body>
</body>
</html> </html>