Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save forestjohnsonpeoplenet/db27b2d997960a59820287fc93d18deb to your computer and use it in GitHub Desktop.
Save forestjohnsonpeoplenet/db27b2d997960a59820287fc93d18deb to your computer and use it in GitHub Desktop.
Cidr subtract js
function ipStringToNumber(str) {
var arr = str.split(".");
if(arr.length != 4) {
return null;
}
var hexString = "";
for(var i = 0; i < arr.length; i++) {
var byte = Number(arr[i]);
if(byte == NaN || byte < 0 || byte > 255) {
return null;
}
byteHex = byte.toString(16);
if(byteHex.length == 1) {
byteHex = "0"+byteHex;
}
hexString += byteHex;
}
//console.log(hexString);
return parseInt(hexString, 16);
}
function toIpString(ipNumber) {
var hexString = ipNumber.toString(16);
while(hexString.length < 8) {
hexString = "0"+hexString;
}
//console.log("ipNumber: "+ ipNumber + ", hexString: " + hexString);
return parseInt(""+hexString[0]+hexString[1], 16)+"."+parseInt(""+hexString[2]+hexString[3], 16)+"."+parseInt(""+hexString[4]+hexString[5], 16)+"."+parseInt(""+hexString[6]+hexString[7], 16);
}
function parseCidr(cidrString) {
var arr = cidrString.split("/");
if(arr.length != 2) {
console.log("invalid cidr format: " + cidrString );
return;
}
var ipNumber = ipStringToNumber(arr[0]);
var sizeBits = Number(arr[1]);
if(ipNumber === null) {
console.log("invalid cidr IP: " + arr[0] );
return;
}
if(sizeBits < 0 || sizeBits > 32) {
console.log("invalid cidr sizeBits: " + arr[1]);
return;
}
var blockSize = (1 << (32-sizeBits));
if(ipNumber % blockSize != 0) {
ipNumber -= (ipNumber % blockSize);
console.log("warning: cidr start IP was not aligned with mask. assuming: " + toIpString(ipNumber)+"/"+sizeBits);
}
return {ipNumber: ipNumber, sizeBits:sizeBits};
}
function cidrObjectToString(cidrObject) {
return toIpString(cidrObject.ipNumber)+"/"+cidrObject.sizeBits;
}
function cidrSubtract(cidrToSubtractFrom, cidrToSubtract) {
if(typeof cidrToSubtractFrom == "string") {
cidrToSubtractFrom = parseCidr(cidrToSubtractFrom)
}
if(typeof cidrToSubtract == "string") {
cidrToSubtract = parseCidr(cidrToSubtract)
}
console.log("cidrToSubtractFrom: " + JSON.stringify(cidrToSubtractFrom, null, 2) + ", cidrToSubtract: " + JSON.stringify(cidrToSubtract, null, 2) );
var currentIp = cidrToSubtractFrom.ipNumber;
var currentSizeBits = cidrToSubtractFrom.sizeBits;
var results = [];
var itr = 0;
while(itr++ < 32) {
currentSizeBits += 1;
newBlockSize = Math.pow(2, 32-currentSizeBits);
isAlignedBlock = (currentIp % newBlockSize == 0);
isSmallEnough = (currentIp + (newBlockSize-1) < cidrToSubtract.ipNumber );
fits = (currentIp + newBlockSize === cidrToSubtract.ipNumber);
//console.log("currentIp: " +currentIp+", (newBlockSize-1): "+ (newBlockSize-1) + ", (newBlockSize): "+ (newBlockSize));
//console.log("currentIp + (newBlockSize-1): "+ (currentIp + (newBlockSize-1)) + " (" + toIpString(currentIp + (newBlockSize-1)) + "), cidrToSubtract.ipNumber: " + cidrToSubtract.ipNumber + " ("+ toIpString(cidrToSubtract.ipNumber) + ")");
//console.log(toIpString(currentIp)+"/"+currentSizeBits + ": isSmallEnough: " + isSmallEnough + " isAlignedBlock: " + isAlignedBlock + " fits: " + fits );
if(isAlignedBlock && isSmallEnough) {
results.push(cidrObjectToString({ipNumber: currentIp, sizeBits:currentSizeBits}));
currentIp += newBlockSize;
}
if(fits) {
break;
}
}
results.push("-------------");
var results2 = [];
currentSizeBits = cidrToSubtractFrom.sizeBits;
var blockSize = Math.pow(2, 32-currentSizeBits);
currentIp = cidrToSubtractFrom.ipNumber+blockSize;
var endOfCidrToSubtract = cidrToSubtract.ipNumber+Math.pow(2, 32-cidrToSubtract.sizeBits);
var itr = 0;
while(itr++ < 32) {
currentSizeBits += 1;
newBlockSize = Math.pow(2, 32-currentSizeBits);
isAlignedBlock = (currentIp % newBlockSize == 0);
isSmallEnough = (currentIp - (newBlockSize-1) > endOfCidrToSubtract );
fits = (currentIp - newBlockSize === endOfCidrToSubtract);
//console.log("currentIp: " +currentIp+", (newBlockSize-1): "+ (newBlockSize-1) + ", (newBlockSize): "+ (newBlockSize));
//console.log("currentIp - newBlockSize: (" + toIpString(currentIp - newBlockSize) + "), endOfCidrToSubtract: ("+ toIpString(endOfCidrToSubtract) + ")");
//console.log(toIpString(currentIp)+"/"+currentSizeBits + ": isSmallEnough: " + isSmallEnough + " isAlignedBlock: " + isAlignedBlock + " fits: " + fits );
if(isAlignedBlock && isSmallEnough) {
results2.unshift(cidrObjectToString({ipNumber: currentIp - newBlockSize, sizeBits:currentSizeBits}));
currentIp -= newBlockSize;
}
if(fits) {
break;
}
}
console.log(results.concat(results2).join("\n"));
}
cidrSubtract("0.0.0.0/0", "172.23.0.0/22")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment