145 lines
4.4 KiB
JavaScript
145 lines
4.4 KiB
JavaScript
|
|
'use strict';
|
||
|
|
|
||
|
|
const os = require('os');
|
||
|
|
|
||
|
|
|
||
|
|
function isValid(address, options) {
|
||
|
|
if (typeof options.internal === 'boolean' && address.internal !== options.internal) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (options.ipVersion === 4 && address.family !== 'IPv4') {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (options.ipVersion === 6 && address.family !== 'IPv6') {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function findAddresses(interfaceName, options = {}) {
|
||
|
|
const addresses = os.networkInterfaces()[interfaceName];
|
||
|
|
if (!addresses) {
|
||
|
|
throw new Error(`Network interface "${interfaceName}" does not exist`);
|
||
|
|
}
|
||
|
|
|
||
|
|
const result = [];
|
||
|
|
|
||
|
|
|
||
|
|
for (const address of addresses) {
|
||
|
|
if (isValid(address, options)) {
|
||
|
|
result.push(address);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns an IP address on the given interface name, filtered by the given options
|
||
|
|
*
|
||
|
|
* @param {string} interfaceName
|
||
|
|
* @param {Object} [options]
|
||
|
|
* @param {boolean} [options.internal] If given, returns only internal addresses if true, or only external if false
|
||
|
|
* @param {integer} [options.ipVersion] If given, returns only addresses who match this IP version (4 or 6)
|
||
|
|
* @returns {string} The first IP address found
|
||
|
|
*/
|
||
|
|
exports.toIp = function (interfaceName, options) {
|
||
|
|
const addresses = findAddresses(interfaceName, options);
|
||
|
|
|
||
|
|
if (addresses.length === 0) {
|
||
|
|
throw new Error(`No suitable IP address found on interface "${interfaceName}"`);
|
||
|
|
}
|
||
|
|
|
||
|
|
return addresses[0].address;
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns all IP addresses on the given interface name, filtered by the given options
|
||
|
|
*
|
||
|
|
* @param {string} interfaceName
|
||
|
|
* @param {Object} [options]
|
||
|
|
* @param {boolean} [options.internal] If given, returns only internal addresses if true, or only external if false
|
||
|
|
* @param {integer} [options.ipVersion] If given, returns only addresses who match this IP version (4 or 6)
|
||
|
|
* @returns {string[]} All matching IP addresses
|
||
|
|
*/
|
||
|
|
exports.toIps = function (interfaceName, options) {
|
||
|
|
return findAddresses(interfaceName, options).map((address) => address.address);
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns a network interface name for the given IP address, filtered by the given options
|
||
|
|
*
|
||
|
|
* @param {string} ip
|
||
|
|
* @param {Object} [options]
|
||
|
|
* @param {boolean} [options.internal] If given, only evaluates internal addresses if true, or only external if false
|
||
|
|
* @param {integer} [options.ipVersion] If given, only evaluates addresses who match this IP version (4 or 6)
|
||
|
|
* @returns {string} The interface name that the given IP is bound to
|
||
|
|
*/
|
||
|
|
exports.fromIp = function (ip, options) {
|
||
|
|
const interfaces = os.networkInterfaces();
|
||
|
|
const interfaceNames = Object.keys(interfaces);
|
||
|
|
|
||
|
|
for (const interfaceName of interfaceNames) {
|
||
|
|
for (const address of interfaces[interfaceName]) {
|
||
|
|
if (address.address === ip && isValid(address, options)) {
|
||
|
|
return interfaceName;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
throw new Error(`No suitable interfaces were found with IP address "${ip}"`);
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the first network interface name that contains at least one IP address that matches the given options
|
||
|
|
*
|
||
|
|
* @param {Object} [options]
|
||
|
|
* @param {boolean} [options.internal] If given, only evaluates internal addresses if true, or only external if false
|
||
|
|
* @param {integer} [options.ipVersion] If given, only evaluates addresses who match this IP version (4 or 6)
|
||
|
|
* @returns {string} The matching interface name
|
||
|
|
*/
|
||
|
|
exports.getInterface = function (options) {
|
||
|
|
const interfaces = os.networkInterfaces();
|
||
|
|
const interfaceNames = Object.keys(interfaces);
|
||
|
|
|
||
|
|
for (const interfaceName of interfaceNames) {
|
||
|
|
if (findAddresses(interfaceName, options).length > 0) {
|
||
|
|
return interfaceName;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
throw new Error(`No suitable interfaces were found`);
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns all network interface names that contain at least one IP address that matches the given options
|
||
|
|
*
|
||
|
|
* @param {Object} [options]
|
||
|
|
* @param {boolean} [options.internal] If given, only evaluates internal addresses if true, or only external if false
|
||
|
|
* @param {integer} [options.ipVersion] If given, only evaluates addresses who match this IP version (4 or 6)
|
||
|
|
* @returns {string[]} The matching interface names
|
||
|
|
*/
|
||
|
|
exports.getInterfaces = function (options) {
|
||
|
|
const interfaces = os.networkInterfaces();
|
||
|
|
const interfaceNames = Object.keys(interfaces);
|
||
|
|
|
||
|
|
const result = [];
|
||
|
|
|
||
|
|
for (const interfaceName of interfaceNames) {
|
||
|
|
if (findAddresses(interfaceName, options).length > 0) {
|
||
|
|
result.push(interfaceName);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
};
|