Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save forestjohnsonpeoplenet/db27b2d997960a59820287fc93d18deb to your computer and use it in GitHub Desktop.

Select an option

Save forestjohnsonpeoplenet/db27b2d997960a59820287fc93d18deb to your computer and use it in GitHub Desktop.

Revisions

  1. forestjohnsonpeoplenet created this gist Jan 14, 2019.
    128 changes: 128 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,128 @@



    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")