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 newNetwork = inet_aton(newNetworkStr); if (newNetwork === null) { alert('Invalid network address entered'); return; } var tmpNetwork = network_address(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)+'.'); newNetwork = tmpNetwork; document.forms['calc'].elements['network'].value = inet_ntoa(tmpNetwork); } if (newMask < 0 || newMask > 32) { alert('The network mask you have entered is invalid'); return; } if (curMask == 0) { curMask = newMask; curNetwork = newNetwork; 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?')) { curMask = newMask; curNetwork = newNetwork; startOver(); } else { document.forms['calc'].elements['netbits'].value = curMask; curNetwork = newNetwork; recreateTables(); } } function startOver() { rootSubnet = [0, 0, null]; recreateTables(); } function recreateTables() { var calcbody = document.getElementById('calcbody'); if (!calcbody) { alert('Body not found'); return; } while (calcbody.hasChildNodes()) { calcbody.removeChild(calcbody.firstChild); } updateNumChildren(rootSubnet); updateDepthChildren(rootSubnet); 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); /* Create the bookmark hyperlink */ var link = document.getElementById('saveLink'); if (link) { link.href = 'index.html?network='+inet_ntoa(curNetwork)+'&mask='+curMask+'&division='+binToAscii(nodeToString(rootSubnet)); } } function nodeToString(node) { if (node[2]) { return '1'+nodeToString(node[2][0])+nodeToString(node[2][1]); } else { return '0'; } } function binToAscii(str) { var curOut = ''; var curBit = 0; var curChar = 0; for (var i=0; i 3) { curOut += curChar.toString(16); curChar = 0; curBit = 0; } } if (curBit > 0) { curOut += curChar.toString(16); } return str.length+'.'+curOut; } 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 = ''; 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<=0; i--) { var mask = labels[i*3]; 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); 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+'.png'; 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 divide(node) { node[2] = new Array(); node[2][0] = [0, 0, null]; node[2][1] = [0, 0, null]; recreateTables(); } function join(node) { /* easy as pie */ node[2] = null; recreateTables(); } function updateNumChildren(node) { if (node[2] == null) { node[1] = 0; return 1; } else { node[1] = updateNumChildren(node[2][0]) + updateNumChildren(node[2][1]); return node[1]; } } function updateDepthChildren(node) { if (node[2] == null) { node[0] = 0; return 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<