diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/internal/os.js | 41 | ||||
-rw-r--r-- | lib/os.js | 67 |
2 files changed, 57 insertions, 51 deletions
diff --git a/lib/internal/os.js b/lib/internal/os.js deleted file mode 100644 index 74ed6e767e..0000000000 --- a/lib/internal/os.js +++ /dev/null @@ -1,41 +0,0 @@ -'use strict'; - -function getCIDRSuffix(mask, protocol = 'ipv4') { - const isV6 = protocol === 'ipv6'; - const bitsString = mask - .split(isV6 ? ':' : '.') - .filter((v) => !!v) - .map((v) => pad(parseInt(v, isV6 ? 16 : 10).toString(2), isV6)) - .join(''); - - if (isValidMask(bitsString)) { - return countOnes(bitsString); - } else { - return null; - } -} - -function pad(binaryString, isV6) { - const groupLength = isV6 ? 16 : 8; - const binLen = binaryString.length; - - return binLen < groupLength ? - `${'0'.repeat(groupLength - binLen)}${binaryString}` : binaryString; -} - -function isValidMask(bitsString) { - const firstIndexOfZero = bitsString.indexOf(0); - const lastIndexOfOne = bitsString.lastIndexOf(1); - - return firstIndexOfZero < 0 || firstIndexOfZero > lastIndexOfOne; -} - -function countOnes(bitsString) { - return bitsString - .split('') - .reduce((acc, bit) => acc += parseInt(bit, 10), 0); -} - -module.exports = { - getCIDRSuffix -}; @@ -24,7 +24,6 @@ const { pushValToArrayMax, safeGetenv } = process.binding('util'); const constants = process.binding('constants').os; const { deprecate } = require('internal/util'); -const { getCIDRSuffix } = require('internal/os'); const isWindows = process.platform === 'win32'; const { ERR_SYSTEM_ERROR } = require('internal/errors'); @@ -144,19 +143,67 @@ function endianness() { } endianness[Symbol.toPrimitive] = () => kEndianness; +// Returns the number of ones in the binary representation of the decimal +// number. +function countBinaryOnes(n) { + let count = 0; + // Remove one "1" bit from n until n is the power of 2. This iterates k times + // while k is the number of "1" in the binary representation. + // For more check https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators + while (n !== 0) { + n = n & (n - 1); + count++; + } + return count; +} + +function getCIDR({ address, netmask, family }) { + let ones = 0; + let split = '.'; + let range = 10; + let groupLength = 8; + let hasZeros = false; + + if (family === 'IPv6') { + split = ':'; + range = 16; + groupLength = 16; + } + + const parts = netmask.split(split); + for (var i = 0; i < parts.length; i++) { + if (parts[i] !== '') { + const binary = parseInt(parts[i], range); + const tmp = countBinaryOnes(binary); + ones += tmp; + if (hasZeros) { + if (tmp !== 0) { + return null; + } + } else if (tmp !== groupLength) { + if ((binary & 1) !== 0) { + return null; + } + hasZeros = true; + } + } + } + + return `${address}/${ones}`; +} + function networkInterfaces() { const interfaceAddresses = getInterfaceAddresses(); - return Object.entries(interfaceAddresses).reduce((acc, [key, val]) => { - acc[key] = val.map((v) => { - const protocol = v.family.toLowerCase(); - const suffix = getCIDRSuffix(v.netmask, protocol); - const cidr = suffix ? `${v.address}/${suffix}` : null; + const keys = Object.keys(interfaceAddresses); + for (var i = 0; i < keys.length; i++) { + const arr = interfaceAddresses[keys[i]]; + for (var j = 0; j < arr.length; j++) { + arr[j].cidr = getCIDR(arr[j]); + } + } - return Object.assign({}, v, { cidr }); - }); - return acc; - }, {}); + return interfaceAddresses; } module.exports = { |