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:
parent
8329d4add7
commit
5088bbe600
44
calculations.js
Normal file
44
calculations.js
Normal 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
60
calculations_4.js
Normal 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
79
calculations_6.js
Normal 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;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<?
|
||||
for ($i=0;$i<=32; $i++) {
|
||||
<?php
|
||||
for ($i=0;$i<=128; $i++) {
|
||||
|
||||
$str = '/'.$i;
|
||||
$font = 2;
|
||||
|
526
subnets.html
526
subnets.html
@ -1,67 +1,89 @@
|
||||
<html>
|
||||
<head>
|
||||
<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>
|
||||
|
||||
<script language="javascript" type="text/javascript">
|
||||
var curNetwork = 0;
|
||||
var curMask = 0;
|
||||
|
||||
function updateNetwork()
|
||||
{
|
||||
var newNetworkStr = document.forms['calc'].elements['network'].value;
|
||||
var newMask = parseInt(document.forms['calc'].elements['netbits'].value);
|
||||
var curVersion = 4;
|
||||
|
||||
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) {
|
||||
alert('Invalid network address entered');
|
||||
alert("Invalid network address entered");
|
||||
return;
|
||||
}
|
||||
|
||||
var tmpNetwork = network_address(newNetwork, newMask);
|
||||
var tmpNetwork = network_address(newVersion, newNetwork, newMask);
|
||||
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;
|
||||
document.forms['calc'].elements['network'].value = inet_ntoa(tmpNetwork);
|
||||
document.forms["calc"].elements["network"].value = inet_ntoa(
|
||||
newVersion,
|
||||
tmpNetwork
|
||||
);
|
||||
}
|
||||
|
||||
if (newMask < 0 || newMask > 32) {
|
||||
alert('The network mask you have entered is invalid');
|
||||
if ((newVersion == 4 && (newMask < 0 || newMask > 32)) || (newVersion == 6 && (newMask < 0 || newMask > 128))) {
|
||||
alert("The network mask you have entered is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
if (curMask == 0) {
|
||||
curMask = newMask;
|
||||
curNetwork = newNetwork;
|
||||
curVersion = newVersion;
|
||||
startOver();
|
||||
}
|
||||
else if (curMask != newMask && confirm('You are changing the base network from /'+curMask+' to /'+newMask+'. This will reset any changes you have made. Proceed?')) {
|
||||
} else if (
|
||||
(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;
|
||||
curNetwork = newNetwork;
|
||||
curVersion = newVersion;
|
||||
|
||||
startOver();
|
||||
}
|
||||
else {
|
||||
document.forms['calc'].elements['netbits'].value = curMask;
|
||||
} else {
|
||||
document.forms["calc"].elements["netbits"].value = curMask;
|
||||
curNetwork = newNetwork;
|
||||
|
||||
recreateTables();
|
||||
}
|
||||
}
|
||||
|
||||
function startOver()
|
||||
{
|
||||
function startOver() {
|
||||
rootSubnet = [0, 0, null];
|
||||
|
||||
recreateTables();
|
||||
}
|
||||
|
||||
function recreateTables()
|
||||
{
|
||||
var calcbody = document.getElementById('calcbody');
|
||||
function recreateTables() {
|
||||
var calcbody = document.getElementById("calcbody");
|
||||
if (!calcbody) {
|
||||
alert('Body not found');
|
||||
alert("Body not found");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -72,36 +94,50 @@ function recreateTables()
|
||||
updateNumChildren(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('col_join').span = (rootSubnet[0] > 0 ? rootSubnet[0] : 1);
|
||||
document.getElementById("joinHeader").colSpan =
|
||||
rootSubnet[0] > 0 ? rootSubnet[0] : 1;
|
||||
document.getElementById("col_join").span =
|
||||
rootSubnet[0] > 0 ? rootSubnet[0] : 1;
|
||||
|
||||
/* Create the bookmark hyperlink */
|
||||
var link = document.getElementById('saveLink');
|
||||
var link = document.getElementById("saveLink");
|
||||
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]) {
|
||||
return '1'+nodeToString(node[2][0])+nodeToString(node[2][1]);
|
||||
}
|
||||
else {
|
||||
return '0';
|
||||
return "1" + nodeToString(node[2][0]) + nodeToString(node[2][1]);
|
||||
} else {
|
||||
return "0";
|
||||
}
|
||||
}
|
||||
|
||||
function binToAscii(str)
|
||||
{
|
||||
var curOut = '';
|
||||
function binToAscii(str) {
|
||||
var curOut = "";
|
||||
var curBit = 0;
|
||||
var curChar = 0;
|
||||
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
if (str.charAt(i) == '1') {
|
||||
if (str.charAt(i) == "1") {
|
||||
curChar |= 1 << curBit;
|
||||
}
|
||||
curBit++;
|
||||
@ -114,288 +150,249 @@ function binToAscii(str)
|
||||
if (curBit > 0) {
|
||||
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 res = re.exec(str);
|
||||
var len = res[1];
|
||||
var encoded = res[2];
|
||||
var out = '';
|
||||
var out = "";
|
||||
for (var i = 0; i < res[1]; i++) {
|
||||
var ch = parseInt(res[2].charAt(Math.floor(i / 4)), 16);
|
||||
var pos = i % 4;
|
||||
out += (ch & (1<<pos) ? '1' : '0');
|
||||
out += ch & (1 << pos) ? "1" : "0";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function createRow(calcbody, node, address, mask, labels, depth)
|
||||
{
|
||||
function createRow(calcbody, node, address, mask, labels, depth) {
|
||||
if (node[2]) {
|
||||
var newlabels = labels;
|
||||
newlabels.push(mask + 1);
|
||||
newlabels.push(node[2][0][1]);
|
||||
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.push(mask + 1);
|
||||
newlabels.push(node[2][1][1]);
|
||||
newlabels.push(node[2][1]);
|
||||
createRow(calcbody, node[2][1], address+subnet_addresses(mask+1), mask+1, newlabels, depth-1);
|
||||
}
|
||||
else {
|
||||
var newRow = document.createElement('TR');
|
||||
createRow(
|
||||
calcbody,
|
||||
node[2][1],
|
||||
address + subnet_addresses(curVersion, mask + 1),
|
||||
mask + 1,
|
||||
newlabels,
|
||||
depth - 1
|
||||
);
|
||||
} else {
|
||||
var newRow = document.createElement("TR");
|
||||
calcbody.appendChild(newRow);
|
||||
|
||||
/* subnet address */
|
||||
var newCell = document.createElement('TD');
|
||||
newCell.appendChild(document.createTextNode(inet_ntoa(address)+'/'+mask));
|
||||
var newCell = document.createElement("TD");
|
||||
newCell.appendChild(
|
||||
document.createTextNode(inet_ntoa(curVersion, address) + "/" + mask)
|
||||
);
|
||||
newRow.appendChild(newCell);
|
||||
|
||||
var addressFirst = address;
|
||||
var addressLast = subnet_last_address(address, mask);
|
||||
var useableFirst = address + 1;
|
||||
var useableLast = addressLast - 1;
|
||||
var addressLast = subnet_last_address(curVersion, address, mask);
|
||||
var useableFirst = subnet_first_address_useable(curVersion, address);
|
||||
var useableLast = subnet_last_address_useable(curVersion, addressLast);
|
||||
var numHosts;
|
||||
var addressRange;
|
||||
var usaebleRange;
|
||||
|
||||
if (mask == 32) {
|
||||
addressRange = inet_ntoa(addressFirst);
|
||||
if ((curVersion == 4 && mask == 32) || (curVersion == 6 && mask == 128)) {
|
||||
addressRange = inet_ntoa(curVersion, addressFirst);
|
||||
useableRange = addressRange;
|
||||
numHosts = 1;
|
||||
}
|
||||
else {
|
||||
addressRange = inet_ntoa(addressFirst)+' - '+inet_ntoa(addressLast);
|
||||
if (mask == 31) {
|
||||
} else {
|
||||
addressRange =
|
||||
inet_ntoa(curVersion, addressFirst) +
|
||||
" - " +
|
||||
inet_ntoa(curVersion, addressLast);
|
||||
if ( (curVersion == 4 && mask == 31) || (curVersion == 6 && mask == 127)) {
|
||||
useableRange = addressRange;
|
||||
numHosts = 2;
|
||||
}
|
||||
else {
|
||||
useableRange = inet_ntoa(useableFirst)+' - '+inet_ntoa(useableLast);
|
||||
numHosts = (1 + useableLast - useableFirst);
|
||||
} else {
|
||||
useableRange =
|
||||
inet_ntoa(curVersion, useableFirst) +
|
||||
" - " +
|
||||
inet_ntoa(curVersion, useableLast);
|
||||
numHosts = num_hosts(curVersion, useableFirst, useableLast);
|
||||
}
|
||||
}
|
||||
|
||||
/* netmask */
|
||||
var newCell = document.createElement('TD');
|
||||
newCell.appendChild(document.createTextNode(inet_ntoa(subnet_netmask(mask))));
|
||||
var newCell = document.createElement("TD");
|
||||
var netmask = subnet_netmask(curVersion, mask);
|
||||
if (netmask) {
|
||||
newCell.appendChild(
|
||||
document.createTextNode(inet_ntoa(curVersion, netmask))
|
||||
);
|
||||
}
|
||||
newRow.appendChild(newCell);
|
||||
|
||||
/* range of addresses */
|
||||
var newCell = document.createElement('TD');
|
||||
var newCell = document.createElement("TD");
|
||||
newCell.appendChild(document.createTextNode(addressRange));
|
||||
newRow.appendChild(newCell);
|
||||
|
||||
/* useable addresses */
|
||||
var newCell = document.createElement('TD');
|
||||
var newCell = document.createElement("TD");
|
||||
newCell.appendChild(document.createTextNode(useableRange));
|
||||
newRow.appendChild(newCell);
|
||||
|
||||
/* Hosts */
|
||||
var newCell = document.createElement('TD');
|
||||
var newCell = document.createElement("TD");
|
||||
newCell.appendChild(document.createTextNode(numHosts));
|
||||
newRow.appendChild(newCell);
|
||||
|
||||
/* actions */
|
||||
|
||||
var newCell = document.createElement('TD');
|
||||
var newCell = document.createElement("TD");
|
||||
newRow.appendChild(newCell);
|
||||
|
||||
if (mask == 32) {
|
||||
var newLink = document.createElement('SPAN');
|
||||
newLink.className = 'disabledAction';
|
||||
newLink.appendChild(document.createTextNode('Divide'));
|
||||
if ((curVersion == 4 && mask == 32) || (curVersion == 6 && mask == 128)) {
|
||||
var newLink = document.createElement("SPAN");
|
||||
newLink.className = "disabledAction";
|
||||
newLink.appendChild(document.createTextNode("Divide"));
|
||||
newCell.appendChild(newLink);
|
||||
}
|
||||
else {
|
||||
var newLink = document.createElement('A');
|
||||
newLink.href = '#';
|
||||
newLink.onclick = function () { divide(node); return false; }
|
||||
newLink.appendChild(document.createTextNode('Divide'));
|
||||
} else {
|
||||
var newLink = document.createElement("A");
|
||||
newLink.href = "#";
|
||||
newLink.onclick = function () {
|
||||
divide(node);
|
||||
return false;
|
||||
};
|
||||
newLink.appendChild(document.createTextNode("Divide"));
|
||||
newCell.appendChild(newLink);
|
||||
}
|
||||
|
||||
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 rowspan = labels[(i*3)+1];
|
||||
var joinnode = labels[(i*3)+2];
|
||||
var rowspan = labels[i * 3 + 1];
|
||||
var joinnode = labels[i * 3 + 2];
|
||||
|
||||
var newCell = document.createElement('TD');
|
||||
newCell.rowSpan = (rowspan > 1 ? rowspan : 1);
|
||||
newCell.colSpan = (colspan > 1 ? colspan : 1);
|
||||
var newCell = document.createElement("TD");
|
||||
newCell.rowSpan = rowspan > 1 ? rowspan : 1;
|
||||
newCell.colSpan = colspan > 1 ? colspan : 1;
|
||||
|
||||
if (i == (labels.length/3)-1) {
|
||||
newCell.className = 'maskSpan';
|
||||
}
|
||||
else {
|
||||
newCell.className = 'maskSpanJoinable';
|
||||
if (i == labels.length / 3 - 1) {
|
||||
newCell.className = "maskSpan";
|
||||
} else {
|
||||
newCell.className = "maskSpanJoinable";
|
||||
newCell.onclick = newJoin(joinnode);
|
||||
// newCell.onmouseover = function() { window.status = joinnode[0]+'---'+joinnode[1]+'---'+joinnode[2]+'>>>>>'+node[2];}
|
||||
}
|
||||
|
||||
var newImg = document.createElement('IMG');
|
||||
newImg.src = 'img/'+mask+'.gif';
|
||||
var newImg = document.createElement("IMG");
|
||||
newImg.src = "img/" + mask + ".gif";
|
||||
newCell.appendChild(newImg);
|
||||
newRow.appendChild(newCell);
|
||||
|
||||
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) };
|
||||
function newJoin(joinnode) {
|
||||
return function () {
|
||||
join(joinnode);
|
||||
};
|
||||
}
|
||||
|
||||
function divide(node)
|
||||
{
|
||||
function divide(node) {
|
||||
node[2] = new Array();
|
||||
node[2][0] = [0, 0, null];
|
||||
node[2][1] = [0, 0, null];
|
||||
recreateTables();
|
||||
}
|
||||
|
||||
function join(node)
|
||||
{
|
||||
function join(node) {
|
||||
/* easy as pie */
|
||||
node[2] = null;
|
||||
recreateTables();
|
||||
}
|
||||
|
||||
function updateNumChildren(node)
|
||||
{
|
||||
function updateNumChildren(node) {
|
||||
if (node[2] == null) {
|
||||
node[1] = 0;
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
node[1] = updateNumChildren(node[2][0]) + updateNumChildren(node[2][1]);
|
||||
} else {
|
||||
node[1] =
|
||||
updateNumChildren(node[2][0]) + updateNumChildren(node[2][1]);
|
||||
return node[1];
|
||||
}
|
||||
}
|
||||
|
||||
function updateDepthChildren(node)
|
||||
{
|
||||
function updateDepthChildren(node) {
|
||||
if (node[2] == null) {
|
||||
node[0] = 0;
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
node[0] = updateDepthChildren(node[2][0]) + updateDepthChildren(node[2][1]);
|
||||
} else {
|
||||
node[0] =
|
||||
updateDepthChildren(node[2][0]) + updateDepthChildren(node[2][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++) {
|
||||
if (res[i] < 0 || res[i] > 255) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return (res[1] << 24) | (res[2] << 16) | (res[3] << 8) | res[4];
|
||||
}
|
||||
|
||||
function network_address(ip, mask)
|
||||
{
|
||||
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()
|
||||
{
|
||||
function preloadSubnetImages() {
|
||||
if (document.images) {
|
||||
if (!document.preloadedImages) {
|
||||
document.preloadedImages = new Array();
|
||||
}
|
||||
|
||||
for (var i=0; i<=32; i++) {
|
||||
for (var i = 0; i <= 128; i++) {
|
||||
var img = new Image();
|
||||
img.src = 'img/'+i+'.gif';
|
||||
img.src = "img/" + i + ".gif";
|
||||
document.preloadedImages.push(img);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function calcOnLoad()
|
||||
{
|
||||
function calcOnLoad() {
|
||||
preloadSubnetImages();
|
||||
args = parseQueryString();
|
||||
if (args['network'] && args['mask'] && args['division']) {
|
||||
document.forms['calc'].elements['network'].value = args['network'];
|
||||
document.forms['calc'].elements['netbits'].value = args['mask'];
|
||||
if (args["network"] && args["mask"] && args["division"]) {
|
||||
document.forms["calc"].elements["version"].value = args["version"] || 4;
|
||||
document.forms["calc"].elements["network"].value = args["network"];
|
||||
document.forms["calc"].elements["netbits"].value = args["mask"];
|
||||
updateNetwork();
|
||||
var division = asciiToBin(args['division']);
|
||||
var division = asciiToBin(args["division"]);
|
||||
rootSubnet = [0, 0, null];
|
||||
if (division != '0') {
|
||||
if (division != "0") {
|
||||
loadNode(rootSubnet, division);
|
||||
}
|
||||
recreateTables();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
updateNetwork();
|
||||
}
|
||||
}
|
||||
|
||||
function loadNode(curNode, division)
|
||||
{
|
||||
if (division.charAt(0) == '0') {
|
||||
function loadNode(curNode, division) {
|
||||
if (division.charAt(0) == "0") {
|
||||
return division.substr(1);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
curNode[2] = new Array();
|
||||
curNode[2][0] = [0, 0, null];
|
||||
curNode[2][1] = [0, 0, null];
|
||||
@ -406,18 +403,18 @@ function loadNode(curNode, division)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function parseQueryString (str)
|
||||
{
|
||||
function parseQueryString(str) {
|
||||
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();
|
||||
if (query) {
|
||||
var fields = query.split('&');
|
||||
var fields = query.split("&");
|
||||
for (var f = 0; f < fields.length; f++) {
|
||||
var field = fields[f].split('=');
|
||||
args[unescape(field[0].replace(/\+/g, ' '))] =
|
||||
unescape(field[1].replace(/\+/g, ' '));
|
||||
var field = fields[f].split("=");
|
||||
|
||||
args[unescape(field[0].replace(/\+/g, " "))] = unescape(
|
||||
field[1].replace(/\+/g, " ")
|
||||
);
|
||||
}
|
||||
}
|
||||
return args;
|
||||
@ -425,25 +422,20 @@ function parseQueryString (str)
|
||||
|
||||
window.onload = calcOnLoad;
|
||||
|
||||
function toggleColumn(cb)
|
||||
{
|
||||
var colName = 'col_'+(cb.id.substr(3));
|
||||
function toggleColumn(cb) {
|
||||
var colName = "col_" + cb.id.substr(3);
|
||||
var col = document.getElementById(colName);
|
||||
|
||||
if (cb.checked) {
|
||||
col.style.display = 'block';
|
||||
}
|
||||
else {
|
||||
col.style.display = 'none';
|
||||
col.style.display = "block";
|
||||
} else {
|
||||
col.style.display = "none";
|
||||
}
|
||||
recreateTables(); /* because IE draws lines all over the place with border-collapse */
|
||||
}
|
||||
|
||||
//-->
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
H1 {
|
||||
font-family: Arial, Verdana, sans-serif;
|
||||
font-size: 18pt;
|
||||
@ -458,7 +450,6 @@ P {
|
||||
font-size: 75%;
|
||||
}
|
||||
|
||||
|
||||
.label {
|
||||
font-family: Arial, Verdana, sans-serif;
|
||||
font-size: 60%;
|
||||
@ -496,69 +487,133 @@ P {
|
||||
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<table width="100%">
|
||||
<tr valign=top>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
|
||||
<h1>Visual Subnet Calculator</h1>
|
||||
|
||||
<p>Enter the network you wish to subnet:</p>
|
||||
|
||||
<form name="calc" onsubmit="updateNetwork(); return false;">
|
||||
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<td class="label">IPv4 / IPv6</td>
|
||||
<td class="label">Network Address</td>
|
||||
<td class="label">Mask bits</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="text" name="network" size="15" maxlength="15" value="192.168.0.0"></td>
|
||||
<td>/<input type="text" name="netbits" size="2" maxlength="2" 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>
|
||||
<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>
|
||||
|
||||
<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>
|
||||
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>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>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<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">
|
||||
<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>
|
||||
@ -580,6 +635,5 @@ If you wish to save this subnetting for later, bookmark <a href="subnets.html" i
|
||||
</tr-->
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
x
Reference in New Issue
Block a user