UNPKG

domotz-remote-pawn

Version:

Domotz Agent

249 lines (219 loc) 9.96 kB
/** This file is part of Domotz Agent. * Copyright (C) 2016 Domotz Ltd * * Domotz Agent is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Domotz Agent is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Domotz Agent. If not, see <http://www.gnu.org/licenses/>. **/ const MODULE = 'NETINFO'; const NO_ERROR = null; const ERROR_GET_PROVIDER = MODULE + ' (getProvider): IP address not specified'; const ERROR_EXTERNAL_IP_NAME = MODULE + ' (getExternalIPName): IP address not specified'; const ERROR_RETRIEVING_IP_ADDRESS = MODULE + ' (getExternalIPAddress): Get external IP address failed with message'; module.exports.factory = function (resourceLocator, parsers) { var path = resourceLocator.path; var request = resourceLocator.request; var dns = resourceLocator.networkTools.dns; var whois = resourceLocator.whois; var procUtils = resourceLocator.utils.proc; var fileUtils = resourceLocator.utils.file; var hostInfo = resourceLocator.discovery.host; var platform = resourceLocator.utils.platform; var myConsole = resourceLocator.log.decorateLogs(); var exec = procUtils.exec; function getInterfaces(callback) { var netInfoStyleInterfaces = [], interfacesList = hostInfo.getInterfacesList(), interfaces = Object.keys(interfacesList); interfaces.forEach(function (iface) { try { var i = { name: iface, address: hostInfo.getIP(iface), netmask: hostInfo.getNetmask(iface), mac: hostInfo.getMAC(iface), }; i.custom = hostInfo.isCustomInterface(iface); i.external = hostInfo.isExternalHostInterface(iface); netInfoStyleInterfaces.push(i); } catch (e) { myConsole.error('Unknown interface with name %s', iface); } }); callback(NO_ERROR, netInfoStyleInterfaces); } function getGateway(callback) { var gateway = hostInfo.getDefaultGateway(); callback(NO_ERROR, gateway); } function getGatewayFull(callback) { var gateway = { ip: hostInfo.getDefaultGateway(), mac: hostInfo.getDefaultGatewayMAC() }; callback(NO_ERROR, gateway); } function parseResolvConf(resolvConfPath, callback) { fileUtils .readFile(resolvConfPath, parsers.parseResolvConf, true) .then(function (dnsServers) { callback(NO_ERROR, dnsServers); }) .catch(callback); } function getDNSServers(callback) { var ubuntuCoreResolvConfPath = '/run/systemd/resolve/resolv.conf'; if (process.env.DPLATFORM === 'ubuntu_core' && fileUtils.getFileStats(ubuntuCoreResolvConfPath)) { parseResolvConf(ubuntuCoreResolvConfPath, callback); } else if (dns.hasOwnProperty('getServers')) { var dnsSettingsPrefix = 'configuration.settings.discovery.dns.'; var dnsRetryTimeout = resourceLocator.settingsManager.getSetting(dnsSettingsPrefix + 'retry_timeout', 1000); var dnsMaxRetries = resourceLocator.settingsManager.getSetting(dnsSettingsPrefix + 'max_retries', 10); var servers = []; var attempt = 1; var getServers = function () { servers = dns.getServers(); if (servers.length === 1 && servers[0] === '127.0.0.1') { if (attempt === dnsMaxRetries) { myConsole.warn('Failed to get DNS servers after %s attempts', dnsMaxRetries); callback(NO_ERROR, servers); return; } myConsole.info('DNS servers only contain 127.0.0.1 attempt=%s, retrying in %s...', attempt, dnsRetryTimeout); attempt++; setTimeout(getServers, dnsRetryTimeout); } else { callback(NO_ERROR, servers); } }; getServers(); } else { parseResolvConf('/etc/resolv.conf', callback); } } /** * @function getDHCPServers * @abstract Performs auto-discovery of DHCP servers * * @param {string} luascript - name of the LUA script used to discover DHCP servers * @param {Function} callback - will be called on success * */ function getDHCPServers(luascript, callback) { var dhcpScanOnDefaultInterface = resourceLocator.settingsManager.dhcpScanOnDefaultInterface(); var dhcpScanTimeout = resourceLocator.settingsManager.dhcpScanTimeout(); var dhcpScanEnabled = resourceLocator.settingsManager.getSetting('configuration.settings.dhcp.scan_enabled', true); if (!dhcpScanEnabled) { myConsole.info('DHCP scan disabled by settings'); callback(NO_ERROR, []); return; } var options; var cmd; var getScriptSubfolder = function (version) { if (version === '7.80') { return version; } return '7.92'; }; var res = platform.getNmapVersion(); res.then(function (data) { var subFolder = getScriptSubfolder(data); var scriptPath = path.join(process.env.DOMOTZ_REMOTE_PAWN_DIR, 'src', 'network_tools', 'nmap_scripts', subFolder, luascript); if (platform.isWindows()) { options = { shell: platform.getWindowsShell(), }; scriptPath = "'" + scriptPath + "'"; } var defaultInterfaceParam = dhcpScanOnDefaultInterface ? '-e ' + hostInfo.getInterface() : ''; var scriptTimeoutParam = dhcpScanTimeout ? ' --script-args timeout=' + dhcpScanTimeout : ''; cmd = (platform.needsSudo() ? 'sudo ' : '') + 'domotz_nmap -Pn -p67 ' + defaultInterfaceParam + ' --script ' + scriptPath + scriptTimeoutParam; myConsole.debug('Executing command for getting DHCP Servers: `%s`', cmd); exec(cmd, options) .then(function (report) { var serverIdentifiers = []; myConsole.info('(getDHCPServers): nmap report = %s', report); var nmapData = parsers.parseDHCPDiscoverOutput('broadcast-dhcp-discover', report); for (var i = 0; i < nmapData.length; i++) { if (nmapData[i]['Server Identifier']) { serverIdentifiers.push(nmapData[i]['Server Identifier']); } } serverIdentifiers.sort(); var dhcpservers = serverIdentifiers.filter(function (value, index) { return serverIdentifiers.indexOf(value) === index; }); callback(NO_ERROR, dhcpservers); }) .catch(function (err) { myConsole.warn('(getDHCPServers): Error in DHCP server recovery: %s', err.message); callback(NO_ERROR, []); }); }).catch(function (error) { myConsole.error('Error %s', error); }); } function getExternalIPAddress(callback) { myConsole.info('Retrieving WAN IP'); resourceLocator.engineRequest .cachedSendWithPromise('/public-ip', 'GET') .then(function (response) { myConsole.info('WAN IP %s', response.public_ip); return callback(NO_ERROR, response.public_ip); }) .catch(function (err) { myConsole.warn('Unable to retrieve WAN IP:', err.message); return callback(new Error(ERROR_RETRIEVING_IP_ADDRESS + ' ' + err.message)); }); } function getExternalIPName(ip, callback) { if (!ip) { myConsole.warn(ERROR_EXTERNAL_IP_NAME); return callback(new Error(ERROR_EXTERNAL_IP_NAME)); } dns.reverse(ip, function (err, resolvedip) { if (err) { // it is possible that an IP address does not have a reverse DNS name so the warn logging level myConsole.warn('(getExternalIpName): Unable to reverse resolve IP address %s. Error code: %s', ip, err.code); resolvedip = [ip]; } return callback(NO_ERROR, resolvedip[0]); }); } function getProvider(ip, callback) { if (!ip) { myConsole.warn(ERROR_GET_PROVIDER); return callback(new Error(ERROR_GET_PROVIDER)); } whois.lookup(ip, { timeout: 10000 }, function (err, data) { if (err) { myConsole.warn('(getProvider): Failed to lookup whois of ' + 'IP address %s . Error = "%s"', ip, err.message); return callback(err); } callback(NO_ERROR, parsers.parseWhoisOutput(data)); }); } return { getInterfaces: getInterfaces, getGateway: getGateway, getGatewayFull: getGatewayFull, getDNSServers: getDNSServers, getDHCPServers: getDHCPServers, getExternalIPAddress: getExternalIPAddress, getExternalIPName: getExternalIPName, getProvider: getProvider, }; };