Last active
September 1, 2015 16:26
-
-
Save icedraco/231b2e10e8027937cd6a to your computer and use it in GitHub Desktop.
JavaScript class that converts and allocates IP addresses in a given range
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Responsible for allocating and deallocating IP addresses in a given range. | |
| */ | |
| var ip = require('./iptools.js'); | |
| /** | |
| * @param {string} network IPv4 address of the network address (e.g. "10.0.0.0") | |
| * @param {number} prefix (optional) Network prefix (e.g. 24 for a 10.0.0.0/24 net) | |
| * @constructor | |
| */ | |
| function IpAllocator(network, prefix) { | |
| var self = this; | |
| self.prefix = prefix || 24; | |
| self.networkBits = ip.ip4ToInt(network, self.prefix); | |
| self.maxHostIndex = ip.maxHosts(self.prefix); | |
| self.nextHostIndex = 1; | |
| self.allocatedHosts = []; | |
| self.freeHosts = []; | |
| self.reservedHosts = []; | |
| //-----------------------------------------------------------------------// | |
| //--- High-Level Methods ------------------------------------------------// | |
| //-----------------------------------------------------------------------// | |
| /** | |
| * Allocate a new free address | |
| * | |
| * NOTE: "0.0.0.0" is returned if no free addresses left (i.e.: isEmpty()) | |
| * | |
| * @return {string} IPv4 address of the allocated IP, or "0.0.0.0" if N/A | |
| */ | |
| self.allocate = function() { | |
| var host = self.freeHosts.shift() || self.nextHost(); | |
| if (host > 0) { | |
| self.allocatedHosts.push(host); | |
| } | |
| return ip.intToIp4(host); | |
| }; | |
| /** | |
| * Reserve a specific IP address from being allocated | |
| * | |
| * NOTE: If the address was already allocated or it does not belong to the | |
| * given network, it will not be reserved! | |
| * | |
| * @param {string} addr IP address | |
| * @return {boolean} TRUE if reserved or FALSE if failed to do so | |
| */ | |
| self.reserve = function(addr) { | |
| if (!addr) { | |
| return false; // address not specified | |
| } | |
| if (ip.ip4ToInt(addr, self.prefix) != self.networkBits) { | |
| return false; // addr does not belong to the same network | |
| } | |
| var host = ip.ip4ToInt(addr); | |
| if (self.isHostAllocated(host)) { | |
| return false; // already allocated - cannot reserve | |
| } | |
| if (self.freeHosts.indexOf(host) >= 0) { | |
| // found in freeHosts - remove it form there | |
| self.freeHosts = self.freeHosts.filter(function(e){ return e != host }); | |
| } | |
| else { | |
| // nextHostIndex hasn't yet reached it - advance it | |
| var next; | |
| while ((next = self.nextHost()) < host) { | |
| self.freeHosts.push(next); | |
| } | |
| assert(next == host); | |
| } | |
| self.reservedHosts.push(host); | |
| return true; // reserved | |
| }; | |
| /** | |
| * Free a previously allocated address and make it available for allocation | |
| * @param {string} addr Previously allocated IPv4 address | |
| */ | |
| self.free = function(addr) { | |
| var host = ip.ip4ToInt(addr); | |
| var isAllocated = self.isHostAllocated(host); | |
| if (isAllocated) { | |
| self.allocatedHosts = self.allocatedHosts.filter(function(e){ return e != host }); | |
| self.freeHosts.push(host); | |
| } | |
| return isAllocated; | |
| }; | |
| /** | |
| * @return {boolean} TRUE if all the addresses have been allocated | |
| */ | |
| self.isEmpty = function() { | |
| return self.nextHostIndex > self.maxHostIndex; | |
| }; | |
| //-----------------------------------------------------------------------// | |
| //--- Low-Level Methods -------------------------------------------------// | |
| //-----------------------------------------------------------------------// | |
| self.nextHost = function() { | |
| return self.isEmpty() | |
| ? 0 | |
| : self.networkBits + self.nextHostIndex++; | |
| }; | |
| self.isHostAllocated = function(host) { | |
| return self.allocatedHosts.indexOf(host) >= 0; | |
| }; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // Exports | |
| //------------------------------------------------------------------------------ | |
| module.exports.IpAllocator = IpAllocator; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment