dockerized_openAger/nodered/rootfs/data/node_modules/ip-address/lib/ipv4.js
2020-10-17 18:42:50 +02:00

320 lines
7.1 KiB
JavaScript

'use strict';
var BigInteger = require('jsbn').BigInteger;
var common = require('./common.js');
var sprintf = require('sprintf-js').sprintf;
var _ = require('lodash');
var constants = require('./v4/constants.js');
/**
* Represents an IPv4 address
* @class Address4
* @param {string} address - An IPv4 address string
*/
function Address4(address) {
this.valid = false;
this.address = address;
this.groups = constants.GROUPS;
this.v4 = true;
this.subnet = '/32';
this.subnetMask = 32;
var subnet = constants.RE_SUBNET_STRING.exec(address);
if (subnet) {
this.parsedSubnet = subnet[0].replace('/', '');
this.subnetMask = parseInt(this.parsedSubnet, 10);
this.subnet = '/' + this.subnetMask;
if (this.subnetMask < 0 || this.subnetMask > constants.BITS) {
this.valid = false;
this.error = 'Invalid subnet mask.';
return;
}
address = address.replace(constants.RE_SUBNET_STRING, '');
}
this.addressMinusSuffix = address;
this.parsedAddress = this.parse(address);
}
/*
* Parses a v4 address
*/
Address4.prototype.parse = function (address) {
var groups = address.split('.');
if (address.match(constants.RE_ADDRESS)) {
this.valid = true;
} else {
this.error = 'Invalid IPv4 address.';
}
return groups;
};
/**
* Return true if the address is valid
* @memberof Address4
* @instance
* @returns {Boolean}
*/
Address4.prototype.isValid = function () {
return this.valid;
};
/**
* Returns the correct form of an address
* @memberof Address4
* @instance
* @returns {String}
*/
Address4.prototype.correctForm = function () {
return this.parsedAddress.map(function (part) {
return parseInt(part, 10);
}).join('.');
};
/**
* Returns true if the address is correct, false otherwise
* @memberof Address4
* @instance
* @returns {Boolean}
*/
Address4.prototype.isCorrect = common.isCorrect(constants.BITS);
/**
* Converts a hex string to an IPv4 address object
* @memberof Address4
* @static
* @param {string} hex - a hex string to convert
* @returns {Address4}
*/
Address4.fromHex = function (hex) {
var padded = _.padStart(hex.replace(/:/g, ''), 8, '0');
var groups = [];
var i;
for (i = 0; i < 8; i += 2) {
var h = padded.slice(i, i + 2);
groups.push(parseInt(h, 16));
}
return new Address4(groups.join('.'));
};
/**
* Converts an integer into a IPv4 address object
* @memberof Address4
* @static
* @param {integer} integer - a number to convert
* @returns {Address4}
*/
Address4.fromInteger = function (integer) {
return Address4.fromHex(integer.toString(16));
};
/**
* Converts an IPv4 address object to a hex string
* @memberof Address4
* @instance
* @returns {String}
*/
Address4.prototype.toHex = function () {
return this.parsedAddress.map(function (part) {
return sprintf('%02x', parseInt(part, 10));
}).join(':');
};
/**
* Converts an IPv4 address object to an array of bytes
* @memberof Address4
* @instance
* @returns {Array}
*/
Address4.prototype.toArray = function () {
return this.parsedAddress.map(function (part) {
return parseInt(part, 10);
});
};
/**
* Converts an IPv4 address object to an IPv6 address group
* @memberof Address4
* @instance
* @returns {String}
*/
Address4.prototype.toGroup6 = function () {
var output = [];
var i;
for (i = 0; i < constants.GROUPS; i += 2) {
var hex = sprintf('%02x%02x',
parseInt(this.parsedAddress[i], 10),
parseInt(this.parsedAddress[i + 1], 10));
output.push(sprintf('%x', parseInt(hex, 16)));
}
return output.join(':');
};
/**
* Returns the address as a BigInteger
* @memberof Address4
* @instance
* @returns {BigInteger}
*/
Address4.prototype.bigInteger = function () {
if (!this.valid) {
return null;
}
return new BigInteger(this.parsedAddress.map(function (n) {
return sprintf('%02x', parseInt(n, 10));
}).join(''), 16);
};
/**
* Helper function getting start address.
* @memberof Address4
* @instance
* @returns {BigInteger}
*/
Address4.prototype._startAddress = function () {
return new BigInteger(
this.mask() + _.repeat('0', constants.BITS - this.subnetMask), 2
);
};
/**
* The first address in the range given by this address' subnet.
* Often referred to as the Network Address.
* @memberof Address4
* @instance
* @returns {Address4}
*/
Address4.prototype.startAddress = function () {
return Address4.fromBigInteger(this._startAddress());
};
/**
* The first host address in the range given by this address's subnet ie
* the first address after the Network Address
* @memberof Address4
* @instance
* @returns {Address4}
*/
Address4.prototype.startAddressExclusive = function () {
var adjust = new BigInteger('1');
return Address4.fromBigInteger(this._startAddress().add(adjust));
};
/**
* Helper function getting end address.
* @memberof Address4
* @instance
* @returns {BigInteger}
*/
Address4.prototype._endAddress = function () {
return new BigInteger(
this.mask() + _.repeat('1', constants.BITS - this.subnetMask), 2
);
};
/**
* The last address in the range given by this address' subnet
* Often referred to as the Broadcast
* @memberof Address4
* @instance
* @returns {Address4}
*/
Address4.prototype.endAddress = function () {
return Address4.fromBigInteger(this._endAddress());
};
/**
* The last host address in the range given by this address's subnet ie
* the last address prior to the Broadcast Address
* @memberof Address4
* @instance
* @returns {Address4}
*/
Address4.prototype.endAddressExclusive = function () {
var adjust = new BigInteger('1');
return Address4.fromBigInteger(this._endAddress().subtract(adjust));
};
/**
* Converts a BigInteger to a v4 address object
* @memberof Address4
* @static
* @param {BigInteger} bigInteger - a BigInteger to convert
* @returns {Address4}
*/
Address4.fromBigInteger = function (bigInteger) {
return Address4.fromInteger(parseInt(bigInteger.toString(), 10));
};
/**
* Returns the first n bits of the address, defaulting to the
* subnet mask
* @memberof Address4
* @instance
* @returns {String}
*/
Address4.prototype.mask = function (optionalMask) {
if (optionalMask === undefined) {
optionalMask = this.subnetMask;
}
return this.getBitsBase2(0, optionalMask);
};
/**
* Returns the bits in the given range as a base-2 string
* @memberof Address4
* @instance
* @returns {string}
*/
Address4.prototype.getBitsBase2 = function (start, end) {
return this.binaryZeroPad().slice(start, end);
};
/**
* Returns true if the given address is in the subnet of the current address
* @memberof Address4
* @instance
* @returns {boolean}
*/
Address4.prototype.isInSubnet = common.isInSubnet;
/**
* Returns true if the given address is a multicast address
* @memberof Address4
* @instance
* @returns {boolean}
*/
Address4.prototype.isMulticast = function () {
return this.isInSubnet(new Address4('224.0.0.0/4'));
};
/**
* Returns a zero-padded base-2 string representation of the address
* @memberof Address4
* @instance
* @returns {string}
*/
Address4.prototype.binaryZeroPad = function () {
return _.padStart(this.bigInteger().toString(2), constants.BITS, '0');
};
module.exports = Address4;