\n'
if (netSize > maxNetSize) {
// This is wrong. Need to figure out a way to get the number of children so you can set rowspan and the number
// of ancestors so you can set colspan.
// DONE: If the subnet address (without the mask) matches a larger subnet address
// in the heirarchy that is a signal to add more join buttons to that row, since they start at the top row and
// via rowspan extend downward.
let matchingNetworkList = get_matching_network_list(network, subnetMap).slice(1)
for (const i in matchingNetworkList) {
let matchingNetwork = matchingNetworkList[i]
let networkChildrenCount = count_network_children(matchingNetwork, subnetMap, [])
newRow += '
/' + matchingNetwork.split('/')[1] + '
\n'
}
}
newRow += '
';
$('#calcbody').append(newRow)
}
// Helper Functions
function ip2int(ip) {
return ip.split('.').reduce(function(ipInt, octet) { return (ipInt<<8) + parseInt(octet, 10)}, 0) >>> 0;
}
function int2ip (ipInt) {
return ( (ipInt>>>24) +'.' + (ipInt>>16 & 255) +'.' + (ipInt>>8 & 255) +'.' + (ipInt & 255) );
}
function subnet_last_address(subnet, netSize) {
return subnet + subnet_addresses(netSize) - 1;
}
function subnet_addresses(netSize) {
return 2**(32-netSize);
}
function get_dict_max_depth(dict, curDepth) {
let maxDepth = curDepth
for (let mapKey in dict) {
let newDepth = get_dict_max_depth(dict[mapKey], curDepth + 1)
if (newDepth > maxDepth) { maxDepth = newDepth }
}
return maxDepth
}
function get_join_children(subnetTree, childCount) {
for (let mapKey in subnetTree) {
if (Object.keys(subnetTree[mapKey]).length > 0) {
childCount += get_join_children(subnetTree[mapKey])
} else {
return childCount
}
}
}
function count_network_children(network, subnetTree, ancestryList) {
// TODO: This might be able to be optimized. Ultimately it needs to count the number of keys underneath
// the current key are unsplit networks (IE rows in the table, IE keys with a value of {}).
let childCount = 0
for (let mapKey in subnetTree) {
if (Object.keys(subnetTree[mapKey]).length > 0) {
childCount += count_network_children(network, subnetTree[mapKey], ancestryList.concat([mapKey]))
} else {
if (ancestryList.includes(network)) {
childCount += 1
}
}
}
return childCount
}
function get_network_children(network, subnetTree) {
// TODO: This might be able to be optimized. Ultimately it needs to count the number of keys underneath
// the current key are unsplit networks (IE rows in the table, IE keys with a value of {}).
let subnetList = []
for (let mapKey in subnetTree) {
if (Object.keys(subnetTree[mapKey]).length > 0) {
subnetList.push.apply(subnetList, get_network_children(network, subnetTree[mapKey]))
} else {
subnetList.push(mapKey)
}
}
return subnetList
}
function get_matching_network_list(network, subnetTree) {
let subnetList = []
for (let mapKey in subnetTree) {
if (Object.keys(subnetTree[mapKey]).length > 0) {
subnetList.push.apply(subnetList, get_matching_network_list(network, subnetTree[mapKey]))
}
if (mapKey.split('/')[0] === network) {
subnetList.push(mapKey)
}
}
return subnetList
}
function get_network(networkInput, netSize) {
let ipInt = ip2int(networkInput)
netSize = parseInt(netSize)
for (let i=31-netSize; i>=0; i--) {
ipInt &= ~ 1< 0) {
mutate_subnet_map(verb, network, subnetTree[mapKey])
}
if (mapKey === network) {
let netSplit = mapKey.split('/')
let netSize = parseInt(netSplit[1])
if (verb === 'split') {
if (netSize < minSubnetSize) {
let new_networks = split_network(netSplit[0], netSize)
subnetTree[mapKey][new_networks[0]] = {}
subnetTree[mapKey][new_networks[1]] = {}
// Copy note to both children and delete Delete parent note
subnetNotes[new_networks[0]] = subnetNotes[mapKey]
subnetNotes[new_networks[1]] = subnetNotes[mapKey]
delete subnetNotes[mapKey]
}
} else if (verb === 'join') {
// Keep the note of the first subnet (which matches the network address) and lose the second subnet's note
// Could consider changing this to concatenate the notes into the parent, but I think this is more intuitive
// Find first (smallest) subnet note which matches the exact network address (this would be the top network in the join scope)
let smallestMatchingNetworkSize = 0
for (let subnetCidr in subnetNotes) {
if (subnetCidr.startsWith(netSplit[0])) {
if (parseInt(subnetCidr.split('/')[1]) > smallestMatchingNetworkSize) {
smallestMatchingNetworkSize = subnetCidr.split('/')[1]
}
}
}
subnetNotes[mapKey] = subnetNotes[netSplit[0] + '/' + smallestMatchingNetworkSize]
// Delete all notes of subnets under this collapsed subnet
let removeKeys = get_network_children(mapKey, subnetTree[mapKey], [])
for (let removeKey in removeKeys) {
subnetNotes[removeKey] = ''
}
// And delete the subnets themselves
subnetTree[mapKey] = {}
} else {
// How did you get here?
}
}
}
}
/*
function validate_cidr(network, netSize) {
let returnObj = {
'valid': false,
'errorNetwork': true,
'errorSize': true,
'cidr': false,
'network': false,
'netSize': false
}
returnObj['network'] = validate_network(network)
if (returnObj['network']) {
returnObj['errorNetwork'] = false;
}
if (!/^\d+$/.test(netSize)) {
returnObj['errorSize'] = true;
} else {
netSize = parseInt(netSize)
if ((netSize > 32) || (netSize < 0)) {
returnObj['errorSize'] = true;
} else {
returnObj['errorSize'] = false;
returnObj['netSize'] = netSize.toString()
}
}
if ((returnObj['errorNetwork'] === false) && (returnObj['errorSize'] === false)) {
returnObj['cidr'] = returnObj['network'] + '/' + returnObj['netSize']
returnObj['valid'] = true
}
return returnObj;
}
function validate_network(network) {
// This can probably be done with Regex but this is better.
let octets = network.split('.');
if (octets.length !== 4) { return false }
if (!/^\d+$/.test(octets[0])) { return false }
if (!/^\d+$/.test(octets[1])) { return false }
if (!/^\d+$/.test(octets[2])) { return false }
if (!/^\d+$/.test(octets[3])) { return false }
octets[0] = parseInt(octets[0])
octets[1] = parseInt(octets[1])
octets[2] = parseInt(octets[2])
octets[3] = parseInt(octets[3])
if ((octets[0] < 0) || (octets[0] > 255)) { return false }
if ((octets[1] < 0) || (octets[1] > 255)) { return false }
if ((octets[2] < 0) || (octets[2] > 255)) { return false }
if ((octets[3] < 0) || (octets[3] > 255)) { return false }
return octets.join('.')
}
*/
function show_warning_modal(message) {
var notifyModal = new bootstrap.Modal(document.getElementById("notifyModal"), {});
$('#notifyModal .modal-body').html(message)
notifyModal.show()
}
$( document ).ready(function() {
reset();
});