network.js 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729
  1. 'use strict';
  2. // @ts-check
  3. // ==================================================================================
  4. // network.js
  5. // ----------------------------------------------------------------------------------
  6. // Description: System Information - library
  7. // for Node.js
  8. // Copyright: (c) 2014 - 2022
  9. // Author: Sebastian Hildebrandt
  10. // ----------------------------------------------------------------------------------
  11. // License: MIT
  12. // ==================================================================================
  13. // 9. Network
  14. // ----------------------------------------------------------------------------------
  15. const os = require('os');
  16. const exec = require('child_process').exec;
  17. const execSync = require('child_process').execSync;
  18. const fs = require('fs');
  19. const util = require('./util');
  20. let _platform = process.platform;
  21. const _linux = (_platform === 'linux' || _platform === 'android');
  22. const _darwin = (_platform === 'darwin');
  23. const _windows = (_platform === 'win32');
  24. const _freebsd = (_platform === 'freebsd');
  25. const _openbsd = (_platform === 'openbsd');
  26. const _netbsd = (_platform === 'netbsd');
  27. const _sunos = (_platform === 'sunos');
  28. let _network = {};
  29. let _default_iface = '';
  30. let _ifaces = {};
  31. let _dhcpNics = [];
  32. let _networkInterfaces = [];
  33. let _mac = {};
  34. let pathToIp;
  35. function getDefaultNetworkInterface() {
  36. let ifacename = '';
  37. let ifacenameFirst = '';
  38. try {
  39. let ifaces = os.networkInterfaces();
  40. let scopeid = 9999;
  41. // fallback - "first" external interface (sorted by scopeid)
  42. for (let dev in ifaces) {
  43. if ({}.hasOwnProperty.call(ifaces, dev)) {
  44. ifaces[dev].forEach(function (details) {
  45. if (details && details.internal === false) {
  46. ifacenameFirst = ifacenameFirst || dev; // fallback if no scopeid
  47. if (details.scopeid && details.scopeid < scopeid) {
  48. ifacename = dev;
  49. scopeid = details.scopeid;
  50. }
  51. }
  52. });
  53. }
  54. }
  55. ifacename = ifacename || ifacenameFirst || '';
  56. if (_windows) {
  57. // https://www.inetdaemon.com/tutorials/internet/ip/routing/default_route.shtml
  58. let defaultIp = '';
  59. const cmd = 'netstat -r';
  60. const result = execSync(cmd, util.execOptsWin);
  61. const lines = result.toString().split(os.EOL);
  62. lines.forEach(line => {
  63. line = line.replace(/\s+/g, ' ').trim();
  64. if (line.indexOf('0.0.0.0 0.0.0.0') > -1 && !(/[a-zA-Z]/.test(line))) {
  65. const parts = line.split(' ');
  66. if (parts.length >= 5) {
  67. defaultIp = parts[parts.length - 2];
  68. }
  69. }
  70. });
  71. if (defaultIp) {
  72. for (let dev in ifaces) {
  73. if ({}.hasOwnProperty.call(ifaces, dev)) {
  74. ifaces[dev].forEach(function (details) {
  75. if (details && details.address && details.address === defaultIp) {
  76. ifacename = dev;
  77. }
  78. });
  79. }
  80. }
  81. }
  82. }
  83. if (_linux) {
  84. let cmd = 'ip route 2> /dev/null | grep default';
  85. let result = execSync(cmd);
  86. let parts = result.toString().split('\n')[0].split(/\s+/);
  87. if (parts[0] === 'none' && parts[5]) {
  88. ifacename = parts[5];
  89. } else if (parts[4]) {
  90. ifacename = parts[4];
  91. }
  92. if (ifacename.indexOf(':') > -1) {
  93. ifacename = ifacename.split(':')[1].trim();
  94. }
  95. }
  96. if (_darwin || _freebsd || _openbsd || _netbsd || _sunos) {
  97. let cmd = '';
  98. if (_linux) { cmd = 'ip route 2> /dev/null | grep default | awk \'{print $5}\''; }
  99. if (_darwin) { cmd = 'route -n get default 2>/dev/null | grep interface: | awk \'{print $2}\''; }
  100. if (_freebsd || _openbsd || _netbsd || _sunos) { cmd = 'route get 0.0.0.0 | grep interface:'; }
  101. // console.log('SYNC - default darwin 3');
  102. let result = execSync(cmd);
  103. ifacename = result.toString().split('\n')[0];
  104. if (ifacename.indexOf(':') > -1) {
  105. ifacename = ifacename.split(':')[1].trim();
  106. }
  107. }
  108. } catch (e) {
  109. util.noop();
  110. }
  111. if (ifacename) { _default_iface = ifacename; }
  112. return _default_iface;
  113. }
  114. exports.getDefaultNetworkInterface = getDefaultNetworkInterface;
  115. function getMacAddresses() {
  116. let iface = '';
  117. let mac = '';
  118. let result = {};
  119. if (_linux || _freebsd || _openbsd || _netbsd) {
  120. if (typeof pathToIp === 'undefined') {
  121. try {
  122. const lines = execSync('which ip').toString().split('\n');
  123. if (lines.length && lines[0].indexOf(':') === -1 && lines[0].indexOf('/') === 0) {
  124. pathToIp = lines[0];
  125. } else {
  126. pathToIp = '';
  127. }
  128. } catch (e) {
  129. pathToIp = '';
  130. }
  131. }
  132. try {
  133. const cmd = 'export LC_ALL=C; ' + ((pathToIp) ? pathToIp + ' link show up' : '/sbin/ifconfig') + '; unset LC_ALL';
  134. let res = execSync(cmd);
  135. const lines = res.toString().split('\n');
  136. for (let i = 0; i < lines.length; i++) {
  137. if (lines[i] && lines[i][0] !== ' ') {
  138. if (pathToIp) {
  139. let nextline = lines[i + 1].trim().split(' ');
  140. if (nextline[0] === 'link/ether') {
  141. iface = lines[i].split(' ')[1];
  142. iface = iface.slice(0, iface.length - 1);
  143. mac = nextline[1];
  144. }
  145. } else {
  146. iface = lines[i].split(' ')[0];
  147. mac = lines[i].split('HWaddr ')[1];
  148. }
  149. if (iface && mac) {
  150. result[iface] = mac.trim();
  151. iface = '';
  152. mac = '';
  153. }
  154. }
  155. }
  156. } catch (e) {
  157. util.noop();
  158. }
  159. }
  160. if (_darwin) {
  161. try {
  162. const cmd = '/sbin/ifconfig';
  163. // console.log('SYNC - macAde darwin 6');
  164. let res = execSync(cmd);
  165. const lines = res.toString().split('\n');
  166. for (let i = 0; i < lines.length; i++) {
  167. if (lines[i] && lines[i][0] !== '\t' && lines[i].indexOf(':') > 0) {
  168. iface = lines[i].split(':')[0];
  169. } else if (lines[i].indexOf('\tether ') === 0) {
  170. mac = lines[i].split('\tether ')[1];
  171. if (iface && mac) {
  172. result[iface] = mac.trim();
  173. iface = '';
  174. mac = '';
  175. }
  176. }
  177. }
  178. } catch (e) {
  179. util.noop();
  180. }
  181. }
  182. return result;
  183. }
  184. function networkInterfaceDefault(callback) {
  185. return new Promise((resolve) => {
  186. process.nextTick(() => {
  187. let result = getDefaultNetworkInterface();
  188. if (callback) { callback(result); }
  189. resolve(result);
  190. });
  191. });
  192. }
  193. exports.networkInterfaceDefault = networkInterfaceDefault;
  194. // --------------------------
  195. // NET - interfaces
  196. function parseLinesWindowsNics(sections, nconfigsections) {
  197. let nics = [];
  198. for (let i in sections) {
  199. if ({}.hasOwnProperty.call(sections, i)) {
  200. if (sections[i].trim() !== '') {
  201. let lines = sections[i].trim().split('\r\n');
  202. let linesNicConfig = nconfigsections && nconfigsections[i] ? nconfigsections[i].trim().split('\r\n') : [];
  203. let netEnabled = util.getValue(lines, 'NetEnabled', ':');
  204. let adapterType = util.getValue(lines, 'AdapterTypeID', ':') === '9' ? 'wireless' : 'wired';
  205. let ifacename = util.getValue(lines, 'Name', ':').replace(/\]/g, ')').replace(/\[/g, '(');
  206. let iface = util.getValue(lines, 'NetConnectionID', ':').replace(/\]/g, ')').replace(/\[/g, '(');
  207. if (ifacename.toLowerCase().indexOf('wi-fi') >= 0 || ifacename.toLowerCase().indexOf('wireless') >= 0) {
  208. adapterType = 'wireless';
  209. }
  210. if (netEnabled !== '') {
  211. const speed = parseInt(util.getValue(lines, 'speed', ':').trim(), 10) / 1000000;
  212. nics.push({
  213. mac: util.getValue(lines, 'MACAddress', ':').toLowerCase(),
  214. dhcp: util.getValue(linesNicConfig, 'dhcpEnabled', ':').toLowerCase() === 'true',
  215. name: ifacename,
  216. iface,
  217. netEnabled: netEnabled === 'TRUE',
  218. speed: isNaN(speed) ? null : speed,
  219. operstate: util.getValue(lines, 'NetConnectionStatus', ':') === '2' ? 'up' : 'down',
  220. type: adapterType
  221. });
  222. }
  223. }
  224. }
  225. }
  226. return nics;
  227. }
  228. function getWindowsNics() {
  229. // const cmd = util.getWmic() + ' nic get /value';
  230. // const cmdnicconfig = util.getWmic() + ' nicconfig get dhcpEnabled /value';
  231. return new Promise((resolve) => {
  232. process.nextTick(() => {
  233. let cmd = 'Get-WmiObject Win32_NetworkAdapter | fl *' + '; echo \'#-#-#-#\';';
  234. cmd += 'Get-WmiObject Win32_NetworkAdapterConfiguration | fl DHCPEnabled' + '';
  235. try {
  236. util.powerShell(cmd).then(data => {
  237. data = data.split('#-#-#-#');
  238. const nsections = (data[0] || '').split(/\n\s*\n/);
  239. const nconfigsections = (data[1] || '').split(/\n\s*\n/);
  240. resolve(parseLinesWindowsNics(nsections, nconfigsections));
  241. });
  242. } catch (e) {
  243. resolve([]);
  244. }
  245. });
  246. });
  247. }
  248. function getWindowsDNSsuffixes() {
  249. let iface = {};
  250. let dnsSuffixes = {
  251. primaryDNS: '',
  252. exitCode: 0,
  253. ifaces: [],
  254. };
  255. try {
  256. const ipconfig = execSync('ipconfig /all', util.execOptsWin);
  257. const ipconfigArray = ipconfig.split('\r\n\r\n');
  258. ipconfigArray.forEach((element, index) => {
  259. if (index == 1) {
  260. const longPrimaryDNS = element.split('\r\n').filter((element) => {
  261. return element.toUpperCase().includes('DNS');
  262. });
  263. const primaryDNS = longPrimaryDNS[0].substring(longPrimaryDNS[0].lastIndexOf(':') + 1);
  264. dnsSuffixes.primaryDNS = primaryDNS.trim();
  265. if (!dnsSuffixes.primaryDNS) { dnsSuffixes.primaryDNS = 'Not defined'; }
  266. }
  267. if (index > 1) {
  268. if (index % 2 == 0) {
  269. const name = element.substring(element.lastIndexOf(' ') + 1).replace(':', '');
  270. iface.name = name;
  271. } else {
  272. const connectionSpecificDNS = element.split('\r\n').filter((element) => {
  273. return element.toUpperCase().includes('DNS');
  274. });
  275. const dnsSuffix = connectionSpecificDNS[0].substring(connectionSpecificDNS[0].lastIndexOf(':') + 1);
  276. iface.dnsSuffix = dnsSuffix.trim();
  277. dnsSuffixes.ifaces.push(iface);
  278. iface = {};
  279. }
  280. }
  281. });
  282. return dnsSuffixes;
  283. } catch (error) {
  284. // console.log('An error occurred trying to bring the Connection-specific DNS suffix', error.message);
  285. return {
  286. primaryDNS: '',
  287. exitCode: 0,
  288. ifaces: [],
  289. };
  290. }
  291. }
  292. function getWindowsIfaceDNSsuffix(ifaces, ifacename) {
  293. let dnsSuffix = '';
  294. // Adding (.) to ensure ifacename compatibility when duplicated iface-names
  295. const interfaceName = ifacename + '.';
  296. try {
  297. const connectionDnsSuffix = ifaces.filter((iface) => {
  298. return interfaceName.includes(iface.name + '.');
  299. }).map((iface) => iface.dnsSuffix);
  300. if (connectionDnsSuffix[0]) {
  301. dnsSuffix = connectionDnsSuffix[0];
  302. }
  303. if (!dnsSuffix) { dnsSuffix = ''; }
  304. return dnsSuffix;
  305. } catch (error) {
  306. // console.log('Error getting Connection-specific DNS suffix: ', error.message);
  307. return 'Unknown';
  308. }
  309. }
  310. function getWindowsWiredProfilesInformation() {
  311. try {
  312. const result = execSync('netsh lan show profiles', util.execOptsWin);
  313. const profileList = result.split('\r\nProfile on interface');
  314. return profileList;
  315. } catch (error) {
  316. if (error.status === 1 && error.stdout.includes('AutoConfig')) {
  317. return 'Disabled';
  318. }
  319. return [];
  320. }
  321. }
  322. function getWindowsWirelessIfaceSSID(interfaceName) {
  323. try {
  324. const result = execSync(`netsh wlan show interface name="${interfaceName}" | findstr "SSID"`, util.execOptsWin);
  325. const SSID = result.split('\r\n').shift();
  326. const parseSSID = SSID.split(':').pop();
  327. return parseSSID;
  328. } catch (error) {
  329. return 'Unknown';
  330. }
  331. }
  332. function getWindowsIEEE8021x(connectionType, iface, ifaces) {
  333. let i8021x = {
  334. state: 'Unknown',
  335. protocol: 'Unknown',
  336. };
  337. if (ifaces === 'Disabled') {
  338. i8021x.state = 'Disabled';
  339. i8021x.protocol = 'Not defined';
  340. return i8021x;
  341. }
  342. if (connectionType == 'wired' && ifaces.length > 0) {
  343. try {
  344. // Get 802.1x information by interface name
  345. const iface8021xInfo = ifaces.find((element) => {
  346. return element.includes(iface + '\r\n');
  347. });
  348. const arrayIface8021xInfo = iface8021xInfo.split('\r\n');
  349. const state8021x = arrayIface8021xInfo.find((element) => {
  350. return element.includes('802.1x');
  351. });
  352. if (state8021x.includes('Disabled')) {
  353. i8021x.state = 'Disabled';
  354. i8021x.protocol = 'Not defined';
  355. } else if (state8021x.includes('Enabled')) {
  356. const protocol8021x = arrayIface8021xInfo.find((element) => {
  357. return element.includes('EAP');
  358. });
  359. i8021x.protocol = protocol8021x.split(':').pop();
  360. i8021x.state = 'Enabled';
  361. }
  362. } catch (error) {
  363. // console.log('Error getting wired information:', error);
  364. return i8021x;
  365. }
  366. } else if (connectionType == 'wireless') {
  367. let i8021xState = '';
  368. let i8021xProtocol = '';
  369. try {
  370. const SSID = getWindowsWirelessIfaceSSID(iface);
  371. if (SSID !== 'Unknown') {
  372. i8021xState = execSync(`netsh wlan show profiles "${SSID}" | findstr "802.1X"`, util.execOptsWin);
  373. i8021xProtocol = execSync(`netsh wlan show profiles "${SSID}" | findstr "EAP"`, util.execOptsWin);
  374. }
  375. if (i8021xState.includes(':') && i8021xProtocol.includes(':')) {
  376. i8021x.state = i8021xState.split(':').pop();
  377. i8021x.protocol = i8021xProtocol.split(':').pop();
  378. }
  379. } catch (error) {
  380. // console.log('Error getting wireless information:', error);
  381. if (error.status === 1 && error.stdout.includes('AutoConfig')) {
  382. i8021x.state = 'Disabled';
  383. i8021x.protocol = 'Not defined';
  384. }
  385. return i8021x;
  386. }
  387. }
  388. return i8021x;
  389. }
  390. function splitSectionsNics(lines) {
  391. const result = [];
  392. let section = [];
  393. lines.forEach(function (line) {
  394. if (!line.startsWith('\t') && !line.startsWith(' ')) {
  395. if (section.length) {
  396. result.push(section);
  397. section = [];
  398. }
  399. }
  400. section.push(line);
  401. });
  402. if (section.length) {
  403. result.push(section);
  404. }
  405. return result;
  406. }
  407. function parseLinesDarwinNics(sections) {
  408. let nics = [];
  409. sections.forEach(section => {
  410. let nic = {
  411. iface: '',
  412. mtu: null,
  413. mac: '',
  414. ip6: '',
  415. ip4: '',
  416. speed: null,
  417. type: '',
  418. operstate: '',
  419. duplex: '',
  420. internal: false
  421. };
  422. const first = section[0];
  423. nic.iface = first.split(':')[0].trim();
  424. let parts = first.split('> mtu');
  425. nic.mtu = parts.length > 1 ? parseInt(parts[1], 10) : null;
  426. if (isNaN(nic.mtu)) {
  427. nic.mtu = null;
  428. }
  429. nic.internal = parts[0].toLowerCase().indexOf('loopback') > -1;
  430. section.forEach(line => {
  431. if (line.trim().startsWith('ether ')) {
  432. nic.mac = line.split('ether ')[1].toLowerCase().trim();
  433. }
  434. if (line.trim().startsWith('inet6 ') && !nic.ip6) {
  435. nic.ip6 = line.split('inet6 ')[1].toLowerCase().split('%')[0].split(' ')[0];
  436. }
  437. if (line.trim().startsWith('inet ') && !nic.ip4) {
  438. nic.ip4 = line.split('inet ')[1].toLowerCase().split(' ')[0];
  439. }
  440. });
  441. let speed = util.getValue(section, 'link rate');
  442. nic.speed = speed ? parseFloat(speed) : null;
  443. if (nic.speed === null) {
  444. speed = util.getValue(section, 'uplink rate');
  445. nic.speed = speed ? parseFloat(speed) : null;
  446. if (nic.speed !== null && speed.toLowerCase().indexOf('gbps') >= 0) {
  447. nic.speed = nic.speed * 1000;
  448. }
  449. } else {
  450. if (speed.toLowerCase().indexOf('gbps') >= 0) {
  451. nic.speed = nic.speed * 1000;
  452. }
  453. }
  454. nic.type = util.getValue(section, 'type').toLowerCase().indexOf('wi-fi') > -1 ? 'wireless' : 'wired';
  455. nic.operstate = util.getValue(section, 'status').toLowerCase().indexOf('active') > -1 ? 'up' : 'down';
  456. nic.duplex = util.getValue(section, 'media').toLowerCase().indexOf('half-duplex') > -1 ? 'half' : 'full';
  457. if (nic.ip6 || nic.ip4 || nic.mac) {
  458. nics.push(nic);
  459. }
  460. });
  461. return nics;
  462. }
  463. function getDarwinNics() {
  464. const cmd = '/sbin/ifconfig -v';
  465. try {
  466. // console.log('SYNC - Nics darwin 12');
  467. const lines = execSync(cmd, { maxBuffer: 1024 * 20000 }).toString().split('\n');
  468. const nsections = splitSectionsNics(lines);
  469. return (parseLinesDarwinNics(nsections));
  470. } catch (e) {
  471. return [];
  472. }
  473. }
  474. function getLinuxIfaceConnectionName(interfaceName) {
  475. const cmd = `nmcli device status 2>/dev/null | grep ${interfaceName}`;
  476. try {
  477. const result = execSync(cmd).toString();
  478. const resultFormat = result.replace(/\s+/g, ' ').trim();
  479. const connectionNameLines = resultFormat.split(' ').slice(3);
  480. const connectionName = connectionNameLines.join(' ');
  481. return connectionName != '--' ? connectionName : '';
  482. } catch (e) {
  483. return '';
  484. }
  485. }
  486. function checkLinuxDCHPInterfaces(file) {
  487. let result = [];
  488. try {
  489. let cmd = `cat ${file} 2> /dev/null | grep 'iface\\|source'`;
  490. const lines = execSync(cmd, { maxBuffer: 1024 * 20000 }).toString().split('\n');
  491. lines.forEach(line => {
  492. const parts = line.replace(/\s+/g, ' ').trim().split(' ');
  493. if (parts.length >= 4) {
  494. if (line.toLowerCase().indexOf(' inet ') >= 0 && line.toLowerCase().indexOf('dhcp') >= 0) {
  495. result.push(parts[1]);
  496. }
  497. }
  498. if (line.toLowerCase().includes('source')) {
  499. let file = line.split(' ')[1];
  500. result = result.concat(checkLinuxDCHPInterfaces(file));
  501. }
  502. });
  503. } catch (e) {
  504. util.noop();
  505. }
  506. return result;
  507. }
  508. function getLinuxDHCPNics() {
  509. // alternate methods getting interfaces using DHCP
  510. let cmd = 'ip a 2> /dev/null';
  511. let result = [];
  512. try {
  513. const lines = execSync(cmd, { maxBuffer: 1024 * 20000 }).toString().split('\n');
  514. const nsections = splitSectionsNics(lines);
  515. result = (parseLinuxDHCPNics(nsections));
  516. } catch (e) {
  517. util.noop();
  518. }
  519. try {
  520. result = checkLinuxDCHPInterfaces('/etc/network/interfaces');
  521. } catch (e) {
  522. util.noop();
  523. }
  524. return result;
  525. }
  526. function parseLinuxDHCPNics(sections) {
  527. const result = [];
  528. if (sections && sections.length) {
  529. sections.forEach(lines => {
  530. if (lines && lines.length) {
  531. const parts = lines[0].split(':');
  532. if (parts.length > 2) {
  533. for (let line of lines) {
  534. if (line.indexOf(' inet ') >= 0 && line.indexOf(' dynamic ') >= 0) {
  535. const parts2 = line.split(' ');
  536. const nic = parts2[parts2.length - 1].trim();
  537. result.push(nic);
  538. break;
  539. }
  540. }
  541. }
  542. }
  543. });
  544. }
  545. return result;
  546. }
  547. function getLinuxIfaceDHCPstatus(iface, connectionName, DHCPNics) {
  548. let result = false;
  549. if (connectionName) {
  550. const cmd = `nmcli connection show "${connectionName}" 2>/dev/null | grep ipv4.method;`;
  551. try {
  552. const lines = execSync(cmd).toString();
  553. const resultFormat = lines.replace(/\s+/g, ' ').trim();
  554. let dhcStatus = resultFormat.split(' ').slice(1).toString();
  555. switch (dhcStatus) {
  556. case 'auto':
  557. result = true;
  558. break;
  559. default:
  560. result = false;
  561. break;
  562. }
  563. return result;
  564. } catch (e) {
  565. return (DHCPNics.indexOf(iface) >= 0);
  566. }
  567. } else {
  568. return (DHCPNics.indexOf(iface) >= 0);
  569. }
  570. }
  571. function getDarwinIfaceDHCPstatus(iface) {
  572. let result = false;
  573. const cmd = `ipconfig getpacket "${iface}" 2>/dev/null | grep lease_time;`;
  574. try {
  575. // console.log('SYNC - DHCP status darwin 17');
  576. const lines = execSync(cmd).toString().split('\n');
  577. if (lines.length && lines[0].startsWith('lease_time')) {
  578. result = true;
  579. }
  580. } catch (e) {
  581. util.noop();
  582. }
  583. return result;
  584. }
  585. function getLinuxIfaceDNSsuffix(connectionName) {
  586. if (connectionName) {
  587. const cmd = `nmcli connection show "${connectionName}" 2>/dev/null | grep ipv4.dns-search;`;
  588. try {
  589. const result = execSync(cmd).toString();
  590. const resultFormat = result.replace(/\s+/g, ' ').trim();
  591. const dnsSuffix = resultFormat.split(' ').slice(1).toString();
  592. return dnsSuffix == '--' ? 'Not defined' : dnsSuffix;
  593. } catch (e) {
  594. return 'Unknown';
  595. }
  596. } else {
  597. return 'Unknown';
  598. }
  599. }
  600. function getLinuxIfaceIEEE8021xAuth(connectionName) {
  601. if (connectionName) {
  602. const cmd = `nmcli connection show "${connectionName}" 2>/dev/null | grep 802-1x.eap;`;
  603. try {
  604. const result = execSync(cmd).toString();
  605. const resultFormat = result.replace(/\s+/g, ' ').trim();
  606. const authenticationProtocol = resultFormat.split(' ').slice(1).toString();
  607. return authenticationProtocol == '--' ? '' : authenticationProtocol;
  608. } catch (e) {
  609. return 'Not defined';
  610. }
  611. } else {
  612. return 'Not defined';
  613. }
  614. }
  615. function getLinuxIfaceIEEE8021xState(authenticationProtocol) {
  616. if (authenticationProtocol) {
  617. if (authenticationProtocol == 'Not defined') {
  618. return 'Disabled';
  619. }
  620. return 'Enabled';
  621. } else {
  622. return 'Unknown';
  623. }
  624. }
  625. function testVirtualNic(iface, ifaceName, mac) {
  626. const virtualMacs = ['00:00:00:00:00:00', '00:03:FF', '00:05:69', '00:0C:29', '00:0F:4B', '00:0F:4B', '00:13:07', '00:13:BE', '00:15:5d', '00:16:3E', '00:1C:42', '00:21:F6', '00:21:F6', '00:24:0B', '00:24:0B', '00:50:56', '00:A0:B1', '00:E0:C8', '08:00:27', '0A:00:27', '18:92:2C', '16:DF:49', '3C:F3:92', '54:52:00', 'FC:15:97'];
  627. if (mac) {
  628. return virtualMacs.filter(item => { return mac.toUpperCase().toUpperCase().startsWith(item.substr(0, mac.length)); }).length > 0 ||
  629. iface.toLowerCase().indexOf(' virtual ') > -1 ||
  630. ifaceName.toLowerCase().indexOf(' virtual ') > -1 ||
  631. iface.toLowerCase().indexOf('vethernet ') > -1 ||
  632. ifaceName.toLowerCase().indexOf('vethernet ') > -1 ||
  633. iface.toLowerCase().startsWith('veth') ||
  634. ifaceName.toLowerCase().startsWith('veth') ||
  635. iface.toLowerCase().startsWith('vboxnet') ||
  636. ifaceName.toLowerCase().startsWith('vboxnet');
  637. } else { return false; }
  638. }
  639. function networkInterfaces(callback, rescan, defaultString) {
  640. if (typeof callback === 'string') {
  641. defaultString = callback;
  642. rescan = true;
  643. callback = null;
  644. }
  645. if (typeof callback === 'boolean') {
  646. rescan = callback;
  647. callback = null;
  648. defaultString = '';
  649. }
  650. if (typeof rescan === 'undefined') {
  651. rescan = true;
  652. }
  653. defaultString = defaultString || '';
  654. defaultString = '' + defaultString;
  655. return new Promise((resolve) => {
  656. process.nextTick(() => {
  657. let ifaces = os.networkInterfaces();
  658. let result = [];
  659. let nics = [];
  660. let dnsSuffixes = [];
  661. let nics8021xInfo = [];
  662. // seperate handling in OSX
  663. if (_darwin || _freebsd || _openbsd || _netbsd) {
  664. if ((JSON.stringify(ifaces) === JSON.stringify(_ifaces)) && !rescan) {
  665. // no changes - just return object
  666. result = _networkInterfaces;
  667. if (callback) { callback(result); }
  668. resolve(result);
  669. } else {
  670. const defaultInterface = getDefaultNetworkInterface();
  671. _ifaces = JSON.parse(JSON.stringify(ifaces));
  672. nics = getDarwinNics();
  673. nics.forEach(nic => {
  674. if ({}.hasOwnProperty.call(ifaces, nic.iface)) {
  675. ifaces[nic.iface].forEach(function (details) {
  676. if (details.family === 'IPv4' || details.family === 4) {
  677. nic.ip4subnet = details.netmask;
  678. }
  679. if (details.family === 'IPv6' || details.family === 6) {
  680. nic.ip6subnet = details.netmask;
  681. }
  682. });
  683. }
  684. result.push({
  685. iface: nic.iface,
  686. ifaceName: nic.iface,
  687. default: nic.iface === defaultInterface,
  688. ip4: nic.ip4,
  689. ip4subnet: nic.ip4subnet || '',
  690. ip6: nic.ip6,
  691. ip6subnet: nic.ip6subnet || '',
  692. mac: nic.mac,
  693. internal: nic.internal,
  694. virtual: nic.internal ? false : testVirtualNic(nic.iface, nic.iface, nic.mac),
  695. operstate: nic.operstate,
  696. type: nic.type,
  697. duplex: nic.duplex,
  698. mtu: nic.mtu,
  699. speed: nic.speed,
  700. dhcp: getDarwinIfaceDHCPstatus(nic.iface),
  701. dnsSuffix: '',
  702. ieee8021xAuth: '',
  703. ieee8021xState: '',
  704. carrierChanges: 0
  705. });
  706. });
  707. _networkInterfaces = result;
  708. if (defaultString.toLowerCase().indexOf('default') >= 0) {
  709. result = result.filter(item => item.default);
  710. if (result.length > 0) {
  711. result = result[0];
  712. } else {
  713. result = [];
  714. }
  715. }
  716. if (callback) { callback(result); }
  717. resolve(result);
  718. }
  719. }
  720. if (_linux) {
  721. if ((JSON.stringify(ifaces) === JSON.stringify(_ifaces)) && !rescan) {
  722. // no changes - just return object
  723. result = _networkInterfaces;
  724. if (callback) { callback(result); }
  725. resolve(result);
  726. } else {
  727. _ifaces = JSON.parse(JSON.stringify(ifaces));
  728. _dhcpNics = getLinuxDHCPNics();
  729. const defaultInterface = getDefaultNetworkInterface();
  730. for (let dev in ifaces) {
  731. let ip4 = '';
  732. let ip4subnet = '';
  733. let ip6 = '';
  734. let ip6subnet = '';
  735. let mac = '';
  736. let duplex = '';
  737. let mtu = '';
  738. let speed = null;
  739. let carrierChanges = 0;
  740. let dhcp = false;
  741. let dnsSuffix = '';
  742. let ieee8021xAuth = '';
  743. let ieee8021xState = '';
  744. let type = '';
  745. if ({}.hasOwnProperty.call(ifaces, dev)) {
  746. let ifaceName = dev;
  747. ifaces[dev].forEach(function (details) {
  748. if (details.family === 'IPv4' || details.family === 4) {
  749. ip4 = details.address;
  750. ip4subnet = details.netmask;
  751. }
  752. if (details.family === 'IPv6' || details.family === 6) {
  753. if (!ip6 || ip6.match(/^fe80::/i)) {
  754. ip6 = details.address;
  755. ip6subnet = details.netmask;
  756. }
  757. }
  758. mac = details.mac;
  759. // fallback due to https://github.com/nodejs/node/issues/13581 (node 8.1 - node 8.2)
  760. const nodeMainVersion = parseInt(process.versions.node.split('.'), 10);
  761. if (mac.indexOf('00:00:0') > -1 && (_linux || _darwin) && (!details.internal) && nodeMainVersion >= 8 && nodeMainVersion <= 11) {
  762. if (Object.keys(_mac).length === 0) {
  763. _mac = getMacAddresses();
  764. }
  765. mac = _mac[dev] || '';
  766. }
  767. });
  768. let iface = dev.split(':')[0].trim().toLowerCase();
  769. const cmd = `echo -n "addr_assign_type: "; cat /sys/class/net/${iface}/addr_assign_type 2>/dev/null; echo;
  770. echo -n "address: "; cat /sys/class/net/${iface}/address 2>/dev/null; echo;
  771. echo -n "addr_len: "; cat /sys/class/net/${iface}/addr_len 2>/dev/null; echo;
  772. echo -n "broadcast: "; cat /sys/class/net/${iface}/broadcast 2>/dev/null; echo;
  773. echo -n "carrier: "; cat /sys/class/net/${iface}/carrier 2>/dev/null; echo;
  774. echo -n "carrier_changes: "; cat /sys/class/net/${iface}/carrier_changes 2>/dev/null; echo;
  775. echo -n "dev_id: "; cat /sys/class/net/${iface}/dev_id 2>/dev/null; echo;
  776. echo -n "dev_port: "; cat /sys/class/net/${iface}/dev_port 2>/dev/null; echo;
  777. echo -n "dormant: "; cat /sys/class/net/${iface}/dormant 2>/dev/null; echo;
  778. echo -n "duplex: "; cat /sys/class/net/${iface}/duplex 2>/dev/null; echo;
  779. echo -n "flags: "; cat /sys/class/net/${iface}/flags 2>/dev/null; echo;
  780. echo -n "gro_flush_timeout: "; cat /sys/class/net/${iface}/gro_flush_timeout 2>/dev/null; echo;
  781. echo -n "ifalias: "; cat /sys/class/net/${iface}/ifalias 2>/dev/null; echo;
  782. echo -n "ifindex: "; cat /sys/class/net/${iface}/ifindex 2>/dev/null; echo;
  783. echo -n "iflink: "; cat /sys/class/net/${iface}/iflink 2>/dev/null; echo;
  784. echo -n "link_mode: "; cat /sys/class/net/${iface}/link_mode 2>/dev/null; echo;
  785. echo -n "mtu: "; cat /sys/class/net/${iface}/mtu 2>/dev/null; echo;
  786. echo -n "netdev_group: "; cat /sys/class/net/${iface}/netdev_group 2>/dev/null; echo;
  787. echo -n "operstate: "; cat /sys/class/net/${iface}/operstate 2>/dev/null; echo;
  788. echo -n "proto_down: "; cat /sys/class/net/${iface}/proto_down 2>/dev/null; echo;
  789. echo -n "speed: "; cat /sys/class/net/${iface}/speed 2>/dev/null; echo;
  790. echo -n "tx_queue_len: "; cat /sys/class/net/${iface}/tx_queue_len 2>/dev/null; echo;
  791. echo -n "type: "; cat /sys/class/net/${iface}/type 2>/dev/null; echo;
  792. echo -n "wireless: "; cat /proc/net/wireless 2>/dev/null | grep ${iface}; echo;
  793. echo -n "wirelessspeed: "; iw dev ${iface} link 2>&1 | grep bitrate; echo;`;
  794. let lines = [];
  795. try {
  796. lines = execSync(cmd).toString().split('\n');
  797. const connectionName = getLinuxIfaceConnectionName(iface);
  798. dhcp = getLinuxIfaceDHCPstatus(iface, connectionName, _dhcpNics);
  799. dnsSuffix = getLinuxIfaceDNSsuffix(connectionName);
  800. ieee8021xAuth = getLinuxIfaceIEEE8021xAuth(connectionName);
  801. ieee8021xState = getLinuxIfaceIEEE8021xState(ieee8021xAuth);
  802. } catch (e) {
  803. util.noop();
  804. }
  805. duplex = util.getValue(lines, 'duplex');
  806. duplex = duplex.startsWith('cat') ? '' : duplex;
  807. mtu = parseInt(util.getValue(lines, 'mtu'), 10);
  808. let myspeed = parseInt(util.getValue(lines, 'speed'), 10);
  809. speed = isNaN(myspeed) ? null : myspeed;
  810. let wirelessspeed = util.getValue(lines, 'wirelessspeed').split('tx bitrate: ');
  811. if (speed === null && wirelessspeed.length === 2) {
  812. myspeed = parseFloat(wirelessspeed[1]);
  813. speed = isNaN(myspeed) ? null : myspeed;
  814. }
  815. carrierChanges = parseInt(util.getValue(lines, 'carrier_changes'), 10);
  816. const operstate = util.getValue(lines, 'operstate');
  817. type = operstate === 'up' ? (util.getValue(lines, 'wireless').trim() ? 'wireless' : 'wired') : 'unknown';
  818. if (iface === 'lo' || iface.startsWith('bond')) { type = 'virtual'; }
  819. let internal = (ifaces[dev] && ifaces[dev][0]) ? ifaces[dev][0].internal : false;
  820. if (dev.toLowerCase().indexOf('loopback') > -1 || ifaceName.toLowerCase().indexOf('loopback') > -1) {
  821. internal = true;
  822. }
  823. const virtual = internal ? false : testVirtualNic(dev, ifaceName, mac);
  824. result.push({
  825. iface,
  826. ifaceName,
  827. default: iface === defaultInterface,
  828. ip4,
  829. ip4subnet,
  830. ip6,
  831. ip6subnet,
  832. mac,
  833. internal,
  834. virtual,
  835. operstate,
  836. type,
  837. duplex,
  838. mtu,
  839. speed,
  840. dhcp,
  841. dnsSuffix,
  842. ieee8021xAuth,
  843. ieee8021xState,
  844. carrierChanges,
  845. });
  846. }
  847. }
  848. _networkInterfaces = result;
  849. if (defaultString.toLowerCase().indexOf('default') >= 0) {
  850. result = result.filter(item => item.default);
  851. if (result.length > 0) {
  852. result = result[0];
  853. } else {
  854. result = [];
  855. }
  856. }
  857. if (callback) { callback(result); }
  858. resolve(result);
  859. }
  860. }
  861. if (_windows) {
  862. if ((JSON.stringify(ifaces) === JSON.stringify(_ifaces)) && !rescan) {
  863. // no changes - just return object
  864. result = _networkInterfaces;
  865. if (callback) { callback(result); }
  866. resolve(result);
  867. } else {
  868. _ifaces = JSON.parse(JSON.stringify(ifaces));
  869. const defaultInterface = getDefaultNetworkInterface();
  870. getWindowsNics().then(function (nics) {
  871. nics.forEach(nic => {
  872. let found = false;
  873. Object.keys(ifaces).forEach(key => {
  874. if (!found) {
  875. ifaces[key].forEach(value => {
  876. if (Object.keys(value).indexOf('mac') >= 0) {
  877. found = value['mac'] === nic.mac;
  878. }
  879. });
  880. }
  881. });
  882. if (!found) {
  883. ifaces[nic.name] = [{ mac: nic.mac }];
  884. }
  885. });
  886. nics8021xInfo = getWindowsWiredProfilesInformation();
  887. dnsSuffixes = getWindowsDNSsuffixes();
  888. for (let dev in ifaces) {
  889. let iface = dev;
  890. let ip4 = '';
  891. let ip4subnet = '';
  892. let ip6 = '';
  893. let ip6subnet = '';
  894. let mac = '';
  895. let duplex = '';
  896. let mtu = '';
  897. let speed = null;
  898. let carrierChanges = 0;
  899. let operstate = 'down';
  900. let dhcp = false;
  901. let dnsSuffix = '';
  902. let ieee8021xAuth = '';
  903. let ieee8021xState = '';
  904. let type = '';
  905. if ({}.hasOwnProperty.call(ifaces, dev)) {
  906. let ifaceName = dev;
  907. ifaces[dev].forEach(function (details) {
  908. if (details.family === 'IPv4' || details.family === 4) {
  909. ip4 = details.address;
  910. ip4subnet = details.netmask;
  911. }
  912. if (details.family === 'IPv6' || details.family === 6) {
  913. if (!ip6 || ip6.match(/^fe80::/i)) {
  914. ip6 = details.address;
  915. ip6subnet = details.netmask;
  916. }
  917. }
  918. mac = details.mac;
  919. // fallback due to https://github.com/nodejs/node/issues/13581 (node 8.1 - node 8.2)
  920. const nodeMainVersion = parseInt(process.versions.node.split('.'), 10);
  921. if (mac.indexOf('00:00:0') > -1 && (_linux || _darwin) && (!details.internal) && nodeMainVersion >= 8 && nodeMainVersion <= 11) {
  922. if (Object.keys(_mac).length === 0) {
  923. _mac = getMacAddresses();
  924. }
  925. mac = _mac[dev] || '';
  926. }
  927. });
  928. dnsSuffix = getWindowsIfaceDNSsuffix(dnsSuffixes.ifaces, dev);
  929. let foundFirst = false;
  930. nics.forEach(detail => {
  931. if (detail.mac === mac && !foundFirst) {
  932. iface = detail.iface || iface;
  933. ifaceName = detail.name;
  934. dhcp = detail.dhcp;
  935. operstate = detail.operstate;
  936. speed = detail.speed;
  937. type = detail.type;
  938. foundFirst = true;
  939. }
  940. });
  941. if (dev.toLowerCase().indexOf('wlan') >= 0 || ifaceName.toLowerCase().indexOf('wlan') >= 0 || ifaceName.toLowerCase().indexOf('802.11n') >= 0 || ifaceName.toLowerCase().indexOf('wireless') >= 0 || ifaceName.toLowerCase().indexOf('wi-fi') >= 0 || ifaceName.toLowerCase().indexOf('wifi') >= 0) {
  942. type = 'wireless';
  943. }
  944. const IEEE8021x = getWindowsIEEE8021x(type, dev, nics8021xInfo);
  945. ieee8021xAuth = IEEE8021x.protocol;
  946. ieee8021xState = IEEE8021x.state;
  947. let internal = (ifaces[dev] && ifaces[dev][0]) ? ifaces[dev][0].internal : false;
  948. if (dev.toLowerCase().indexOf('loopback') > -1 || ifaceName.toLowerCase().indexOf('loopback') > -1) {
  949. internal = true;
  950. }
  951. const virtual = internal ? false : testVirtualNic(dev, ifaceName, mac);
  952. result.push({
  953. iface,
  954. ifaceName,
  955. default: iface === defaultInterface,
  956. ip4,
  957. ip4subnet,
  958. ip6,
  959. ip6subnet,
  960. mac,
  961. internal,
  962. virtual,
  963. operstate,
  964. type,
  965. duplex,
  966. mtu,
  967. speed,
  968. dhcp,
  969. dnsSuffix,
  970. ieee8021xAuth,
  971. ieee8021xState,
  972. carrierChanges,
  973. });
  974. }
  975. }
  976. _networkInterfaces = result;
  977. if (defaultString.toLowerCase().indexOf('default') >= 0) {
  978. result = result.filter(item => item.default);
  979. if (result.length > 0) {
  980. result = result[0];
  981. } else {
  982. result = [];
  983. }
  984. }
  985. if (callback) { callback(result); }
  986. resolve(result);
  987. });
  988. }
  989. }
  990. });
  991. });
  992. }
  993. exports.networkInterfaces = networkInterfaces;
  994. // --------------------------
  995. // NET - Speed
  996. function calcNetworkSpeed(iface, rx_bytes, tx_bytes, operstate, rx_dropped, rx_errors, tx_dropped, tx_errors) {
  997. let result = {
  998. iface,
  999. operstate,
  1000. rx_bytes,
  1001. rx_dropped,
  1002. rx_errors,
  1003. tx_bytes,
  1004. tx_dropped,
  1005. tx_errors,
  1006. rx_sec: null,
  1007. tx_sec: null,
  1008. ms: 0
  1009. };
  1010. if (_network[iface] && _network[iface].ms) {
  1011. result.ms = Date.now() - _network[iface].ms;
  1012. result.rx_sec = (rx_bytes - _network[iface].rx_bytes) >= 0 ? (rx_bytes - _network[iface].rx_bytes) / (result.ms / 1000) : 0;
  1013. result.tx_sec = (tx_bytes - _network[iface].tx_bytes) >= 0 ? (tx_bytes - _network[iface].tx_bytes) / (result.ms / 1000) : 0;
  1014. _network[iface].rx_bytes = rx_bytes;
  1015. _network[iface].tx_bytes = tx_bytes;
  1016. _network[iface].rx_sec = result.rx_sec;
  1017. _network[iface].tx_sec = result.tx_sec;
  1018. _network[iface].ms = Date.now();
  1019. _network[iface].last_ms = result.ms;
  1020. _network[iface].operstate = operstate;
  1021. } else {
  1022. if (!_network[iface]) { _network[iface] = {}; }
  1023. _network[iface].rx_bytes = rx_bytes;
  1024. _network[iface].tx_bytes = tx_bytes;
  1025. _network[iface].rx_sec = null;
  1026. _network[iface].tx_sec = null;
  1027. _network[iface].ms = Date.now();
  1028. _network[iface].last_ms = 0;
  1029. _network[iface].operstate = operstate;
  1030. }
  1031. return result;
  1032. }
  1033. function networkStats(ifaces, callback) {
  1034. let ifacesArray = [];
  1035. return new Promise((resolve) => {
  1036. process.nextTick(() => {
  1037. // fallback - if only callback is given
  1038. if (util.isFunction(ifaces) && !callback) {
  1039. callback = ifaces;
  1040. ifacesArray = [getDefaultNetworkInterface()];
  1041. } else {
  1042. if (typeof ifaces !== 'string' && ifaces !== undefined) {
  1043. if (callback) { callback([]); }
  1044. return resolve([]);
  1045. }
  1046. ifaces = ifaces || getDefaultNetworkInterface();
  1047. ifaces.__proto__.toLowerCase = util.stringToLower;
  1048. ifaces.__proto__.replace = util.stringReplace;
  1049. ifaces.__proto__.trim = util.stringTrim;
  1050. ifaces = ifaces.trim().toLowerCase().replace(/,+/g, '|');
  1051. ifacesArray = ifaces.split('|');
  1052. }
  1053. const result = [];
  1054. const workload = [];
  1055. if (ifacesArray.length && ifacesArray[0].trim() === '*') {
  1056. ifacesArray = [];
  1057. networkInterfaces(false).then(allIFaces => {
  1058. for (let iface of allIFaces) {
  1059. ifacesArray.push(iface.iface);
  1060. }
  1061. networkStats(ifacesArray.join(',')).then(result => {
  1062. if (callback) { callback(result); }
  1063. resolve(result);
  1064. });
  1065. });
  1066. } else {
  1067. for (let iface of ifacesArray) {
  1068. workload.push(networkStatsSingle(iface.trim()));
  1069. }
  1070. if (workload.length) {
  1071. Promise.all(
  1072. workload
  1073. ).then(data => {
  1074. if (callback) { callback(data); }
  1075. resolve(data);
  1076. });
  1077. } else {
  1078. if (callback) { callback(result); }
  1079. resolve(result);
  1080. }
  1081. }
  1082. });
  1083. });
  1084. }
  1085. function networkStatsSingle(iface) {
  1086. function parseLinesWindowsPerfData(sections) {
  1087. let perfData = [];
  1088. for (let i in sections) {
  1089. if ({}.hasOwnProperty.call(sections, i)) {
  1090. if (sections[i].trim() !== '') {
  1091. let lines = sections[i].trim().split('\r\n');
  1092. perfData.push({
  1093. name: util.getValue(lines, 'Name', ':').replace(/[()[\] ]+/g, '').replace('#', '_').toLowerCase(),
  1094. rx_bytes: parseInt(util.getValue(lines, 'BytesReceivedPersec', ':'), 10),
  1095. rx_errors: parseInt(util.getValue(lines, 'PacketsReceivedErrors', ':'), 10),
  1096. rx_dropped: parseInt(util.getValue(lines, 'PacketsReceivedDiscarded', ':'), 10),
  1097. tx_bytes: parseInt(util.getValue(lines, 'BytesSentPersec', ':'), 10),
  1098. tx_errors: parseInt(util.getValue(lines, 'PacketsOutboundErrors', ':'), 10),
  1099. tx_dropped: parseInt(util.getValue(lines, 'PacketsOutboundDiscarded', ':'), 10)
  1100. });
  1101. }
  1102. }
  1103. }
  1104. return perfData;
  1105. }
  1106. return new Promise((resolve) => {
  1107. process.nextTick(() => {
  1108. let ifaceSanitized = '';
  1109. const s = util.isPrototypePolluted() ? '---' : util.sanitizeShellString(iface);
  1110. for (let i = 0; i <= util.mathMin(s.length, 2000); i++) {
  1111. if (!(s[i] === undefined)) {
  1112. ifaceSanitized = ifaceSanitized + s[i];
  1113. }
  1114. }
  1115. let result = {
  1116. iface: ifaceSanitized,
  1117. operstate: 'unknown',
  1118. rx_bytes: 0,
  1119. rx_dropped: 0,
  1120. rx_errors: 0,
  1121. tx_bytes: 0,
  1122. tx_dropped: 0,
  1123. tx_errors: 0,
  1124. rx_sec: null,
  1125. tx_sec: null,
  1126. ms: 0
  1127. };
  1128. let operstate = 'unknown';
  1129. let rx_bytes = 0;
  1130. let tx_bytes = 0;
  1131. let rx_dropped = 0;
  1132. let rx_errors = 0;
  1133. let tx_dropped = 0;
  1134. let tx_errors = 0;
  1135. let cmd, lines, stats;
  1136. if (!_network[ifaceSanitized] || (_network[ifaceSanitized] && !_network[ifaceSanitized].ms) || (_network[ifaceSanitized] && _network[ifaceSanitized].ms && Date.now() - _network[ifaceSanitized].ms >= 500)) {
  1137. if (_linux) {
  1138. if (fs.existsSync('/sys/class/net/' + ifaceSanitized)) {
  1139. cmd =
  1140. 'cat /sys/class/net/' + ifaceSanitized + '/operstate; ' +
  1141. 'cat /sys/class/net/' + ifaceSanitized + '/statistics/rx_bytes; ' +
  1142. 'cat /sys/class/net/' + ifaceSanitized + '/statistics/tx_bytes; ' +
  1143. 'cat /sys/class/net/' + ifaceSanitized + '/statistics/rx_dropped; ' +
  1144. 'cat /sys/class/net/' + ifaceSanitized + '/statistics/rx_errors; ' +
  1145. 'cat /sys/class/net/' + ifaceSanitized + '/statistics/tx_dropped; ' +
  1146. 'cat /sys/class/net/' + ifaceSanitized + '/statistics/tx_errors; ';
  1147. exec(cmd, function (error, stdout) {
  1148. if (!error) {
  1149. lines = stdout.toString().split('\n');
  1150. operstate = lines[0].trim();
  1151. rx_bytes = parseInt(lines[1], 10);
  1152. tx_bytes = parseInt(lines[2], 10);
  1153. rx_dropped = parseInt(lines[3], 10);
  1154. rx_errors = parseInt(lines[4], 10);
  1155. tx_dropped = parseInt(lines[5], 10);
  1156. tx_errors = parseInt(lines[6], 10);
  1157. result = calcNetworkSpeed(ifaceSanitized, rx_bytes, tx_bytes, operstate, rx_dropped, rx_errors, tx_dropped, tx_errors);
  1158. }
  1159. resolve(result);
  1160. });
  1161. } else {
  1162. resolve(result);
  1163. }
  1164. }
  1165. if (_freebsd || _openbsd || _netbsd) {
  1166. cmd = 'netstat -ibndI ' + ifaceSanitized; // lgtm [js/shell-command-constructed-from-input]
  1167. exec(cmd, function (error, stdout) {
  1168. if (!error) {
  1169. lines = stdout.toString().split('\n');
  1170. for (let i = 1; i < lines.length; i++) {
  1171. const line = lines[i].replace(/ +/g, ' ').split(' ');
  1172. if (line && line[0] && line[7] && line[10]) {
  1173. rx_bytes = rx_bytes + parseInt(line[7]);
  1174. if (line[6].trim() !== '-') { rx_dropped = rx_dropped + parseInt(line[6]); }
  1175. if (line[5].trim() !== '-') { rx_errors = rx_errors + parseInt(line[5]); }
  1176. tx_bytes = tx_bytes + parseInt(line[10]);
  1177. if (line[12].trim() !== '-') { tx_dropped = tx_dropped + parseInt(line[12]); }
  1178. if (line[9].trim() !== '-') { tx_errors = tx_errors + parseInt(line[9]); }
  1179. operstate = 'up';
  1180. }
  1181. }
  1182. result = calcNetworkSpeed(ifaceSanitized, rx_bytes, tx_bytes, operstate, rx_dropped, rx_errors, tx_dropped, tx_errors);
  1183. }
  1184. resolve(result);
  1185. });
  1186. }
  1187. if (_darwin) {
  1188. cmd = 'ifconfig ' + ifaceSanitized + ' | grep "status"'; // lgtm [js/shell-command-constructed-from-input]
  1189. exec(cmd, function (error, stdout) {
  1190. result.operstate = (stdout.toString().split(':')[1] || '').trim();
  1191. result.operstate = (result.operstate || '').toLowerCase();
  1192. result.operstate = (result.operstate === 'active' ? 'up' : (result.operstate === 'inactive' ? 'down' : 'unknown'));
  1193. cmd = 'netstat -bdI ' + ifaceSanitized; // lgtm [js/shell-command-constructed-from-input]
  1194. exec(cmd, function (error, stdout) {
  1195. if (!error) {
  1196. lines = stdout.toString().split('\n');
  1197. // if there is less than 2 lines, no information for this interface was found
  1198. if (lines.length > 1 && lines[1].trim() !== '') {
  1199. // skip header line
  1200. // use the second line because it is tied to the NIC instead of the ipv4 or ipv6 address
  1201. stats = lines[1].replace(/ +/g, ' ').split(' ');
  1202. const offset = stats.length > 11 ? 1 : 0;
  1203. rx_bytes = parseInt(stats[offset + 5]);
  1204. rx_dropped = parseInt(stats[offset + 10]);
  1205. rx_errors = parseInt(stats[offset + 4]);
  1206. tx_bytes = parseInt(stats[offset + 8]);
  1207. tx_dropped = parseInt(stats[offset + 10]);
  1208. tx_errors = parseInt(stats[offset + 7]);
  1209. result = calcNetworkSpeed(ifaceSanitized, rx_bytes, tx_bytes, result.operstate, rx_dropped, rx_errors, tx_dropped, tx_errors);
  1210. }
  1211. }
  1212. resolve(result);
  1213. });
  1214. });
  1215. }
  1216. if (_windows) {
  1217. let perfData = [];
  1218. let ifaceName = ifaceSanitized;
  1219. // Performance Data
  1220. util.powerShell('Get-WmiObject Win32_PerfRawData_Tcpip_NetworkInterface | select Name,BytesReceivedPersec,PacketsReceivedErrors,PacketsReceivedDiscarded,BytesSentPersec,PacketsOutboundErrors,PacketsOutboundDiscarded | fl').then((stdout, error) => {
  1221. if (!error) {
  1222. const psections = stdout.toString().split(/\n\s*\n/);
  1223. perfData = parseLinesWindowsPerfData(psections);
  1224. }
  1225. // Network Interfaces
  1226. networkInterfaces(false).then(interfaces => {
  1227. // get bytes sent, received from perfData by name
  1228. rx_bytes = 0;
  1229. tx_bytes = 0;
  1230. perfData.forEach(detail => {
  1231. interfaces.forEach(det => {
  1232. if ((det.iface.toLowerCase() === ifaceSanitized.toLowerCase() ||
  1233. det.mac.toLowerCase() === ifaceSanitized.toLowerCase() ||
  1234. det.ip4.toLowerCase() === ifaceSanitized.toLowerCase() ||
  1235. det.ip6.toLowerCase() === ifaceSanitized.toLowerCase() ||
  1236. det.ifaceName.replace(/[()[\] ]+/g, '').replace('#', '_').toLowerCase() === ifaceSanitized.replace(/[()[\] ]+/g, '').replace('#', '_').toLowerCase()) &&
  1237. (det.ifaceName.replace(/[()[\] ]+/g, '').replace('#', '_').toLowerCase() === detail.name)) {
  1238. ifaceName = det.iface;
  1239. rx_bytes = detail.rx_bytes;
  1240. rx_dropped = detail.rx_dropped;
  1241. rx_errors = detail.rx_errors;
  1242. tx_bytes = detail.tx_bytes;
  1243. tx_dropped = detail.tx_dropped;
  1244. tx_errors = detail.tx_errors;
  1245. operstate = det.operstate;
  1246. }
  1247. });
  1248. });
  1249. if (rx_bytes && tx_bytes) {
  1250. result = calcNetworkSpeed(ifaceName, parseInt(rx_bytes), parseInt(tx_bytes), operstate, rx_dropped, rx_errors, tx_dropped, tx_errors);
  1251. }
  1252. resolve(result);
  1253. });
  1254. });
  1255. }
  1256. } else {
  1257. result.rx_bytes = _network[ifaceSanitized].rx_bytes;
  1258. result.tx_bytes = _network[ifaceSanitized].tx_bytes;
  1259. result.rx_sec = _network[ifaceSanitized].rx_sec;
  1260. result.tx_sec = _network[ifaceSanitized].tx_sec;
  1261. result.ms = _network[ifaceSanitized].last_ms;
  1262. result.operstate = _network[ifaceSanitized].operstate;
  1263. resolve(result);
  1264. }
  1265. });
  1266. });
  1267. }
  1268. exports.networkStats = networkStats;
  1269. // --------------------------
  1270. // NET - connections (sockets)
  1271. function networkConnections(callback) {
  1272. return new Promise((resolve) => {
  1273. process.nextTick(() => {
  1274. let result = [];
  1275. if (_linux || _freebsd || _openbsd || _netbsd) {
  1276. let cmd = 'export LC_ALL=C; netstat -tunap | grep "ESTABLISHED\\|SYN_SENT\\|SYN_RECV\\|FIN_WAIT1\\|FIN_WAIT2\\|TIME_WAIT\\|CLOSE\\|CLOSE_WAIT\\|LAST_ACK\\|LISTEN\\|CLOSING\\|UNKNOWN"; unset LC_ALL';
  1277. if (_freebsd || _openbsd || _netbsd) { cmd = 'export LC_ALL=C; netstat -na | grep "ESTABLISHED\\|SYN_SENT\\|SYN_RECV\\|FIN_WAIT1\\|FIN_WAIT2\\|TIME_WAIT\\|CLOSE\\|CLOSE_WAIT\\|LAST_ACK\\|LISTEN\\|CLOSING\\|UNKNOWN"; unset LC_ALL'; }
  1278. exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
  1279. let lines = stdout.toString().split('\n');
  1280. if (!error && (lines.length > 1 || lines[0] != '')) {
  1281. lines.forEach(function (line) {
  1282. line = line.replace(/ +/g, ' ').split(' ');
  1283. if (line.length >= 7) {
  1284. let localip = line[3];
  1285. let localport = '';
  1286. let localaddress = line[3].split(':');
  1287. if (localaddress.length > 1) {
  1288. localport = localaddress[localaddress.length - 1];
  1289. localaddress.pop();
  1290. localip = localaddress.join(':');
  1291. }
  1292. let peerip = line[4];
  1293. let peerport = '';
  1294. let peeraddress = line[4].split(':');
  1295. if (peeraddress.length > 1) {
  1296. peerport = peeraddress[peeraddress.length - 1];
  1297. peeraddress.pop();
  1298. peerip = peeraddress.join(':');
  1299. }
  1300. let connstate = line[5];
  1301. // if (connstate === 'VERBUNDEN') connstate = 'ESTABLISHED';
  1302. let proc = line[6].split('/');
  1303. if (connstate) {
  1304. result.push({
  1305. protocol: line[0],
  1306. localAddress: localip,
  1307. localPort: localport,
  1308. peerAddress: peerip,
  1309. peerPort: peerport,
  1310. state: connstate,
  1311. pid: proc[0] && proc[0] !== '-' ? parseInt(proc[0], 10) : null,
  1312. process: proc[1] ? proc[1].split(' ')[0] : ''
  1313. });
  1314. }
  1315. }
  1316. });
  1317. if (callback) {
  1318. callback(result);
  1319. }
  1320. resolve(result);
  1321. } else {
  1322. cmd = 'ss -tunap | grep "ESTAB\\|SYN-SENT\\|SYN-RECV\\|FIN-WAIT1\\|FIN-WAIT2\\|TIME-WAIT\\|CLOSE\\|CLOSE-WAIT\\|LAST-ACK\\|LISTEN\\|CLOSING"';
  1323. exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
  1324. if (!error) {
  1325. let lines = stdout.toString().split('\n');
  1326. lines.forEach(function (line) {
  1327. line = line.replace(/ +/g, ' ').split(' ');
  1328. if (line.length >= 6) {
  1329. let localip = line[4];
  1330. let localport = '';
  1331. let localaddress = line[4].split(':');
  1332. if (localaddress.length > 1) {
  1333. localport = localaddress[localaddress.length - 1];
  1334. localaddress.pop();
  1335. localip = localaddress.join(':');
  1336. }
  1337. let peerip = line[5];
  1338. let peerport = '';
  1339. let peeraddress = line[5].split(':');
  1340. if (peeraddress.length > 1) {
  1341. peerport = peeraddress[peeraddress.length - 1];
  1342. peeraddress.pop();
  1343. peerip = peeraddress.join(':');
  1344. }
  1345. let connstate = line[1];
  1346. if (connstate === 'ESTAB') { connstate = 'ESTABLISHED'; }
  1347. if (connstate === 'TIME-WAIT') { connstate = 'TIME_WAIT'; }
  1348. let pid = null;
  1349. let process = '';
  1350. if (line.length >= 7 && line[6].indexOf('users:') > -1) {
  1351. let proc = line[6].replace('users:(("', '').replace(/"/g, '').split(',');
  1352. if (proc.length > 2) {
  1353. process = proc[0].split(' ')[0];
  1354. pid = parseInt(proc[1], 10);
  1355. }
  1356. }
  1357. if (connstate) {
  1358. result.push({
  1359. protocol: line[0],
  1360. localAddress: localip,
  1361. localPort: localport,
  1362. peerAddress: peerip,
  1363. peerPort: peerport,
  1364. state: connstate,
  1365. pid,
  1366. process
  1367. });
  1368. }
  1369. }
  1370. });
  1371. }
  1372. if (callback) {
  1373. callback(result);
  1374. }
  1375. resolve(result);
  1376. });
  1377. }
  1378. });
  1379. }
  1380. if (_darwin) {
  1381. let cmd = 'netstat -natv | grep "ESTABLISHED\\|SYN_SENT\\|SYN_RECV\\|FIN_WAIT1\\|FIN_WAIT2\\|TIME_WAIT\\|CLOSE\\|CLOSE_WAIT\\|LAST_ACK\\|LISTEN\\|CLOSING\\|UNKNOWN"';
  1382. exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
  1383. if (!error) {
  1384. let lines = stdout.toString().split('\n');
  1385. lines.forEach(function (line) {
  1386. line = line.replace(/ +/g, ' ').split(' ');
  1387. if (line.length >= 8) {
  1388. let localip = line[3];
  1389. let localport = '';
  1390. let localaddress = line[3].split('.');
  1391. if (localaddress.length > 1) {
  1392. localport = localaddress[localaddress.length - 1];
  1393. localaddress.pop();
  1394. localip = localaddress.join('.');
  1395. }
  1396. let peerip = line[4];
  1397. let peerport = '';
  1398. let peeraddress = line[4].split('.');
  1399. if (peeraddress.length > 1) {
  1400. peerport = peeraddress[peeraddress.length - 1];
  1401. peeraddress.pop();
  1402. peerip = peeraddress.join('.');
  1403. }
  1404. let connstate = line[5];
  1405. let pid = parseInt(line[8], 10);
  1406. if (connstate) {
  1407. result.push({
  1408. protocol: line[0],
  1409. localAddress: localip,
  1410. localPort: localport,
  1411. peerAddress: peerip,
  1412. peerPort: peerport,
  1413. state: connstate,
  1414. pid: pid,
  1415. process: ''
  1416. });
  1417. }
  1418. }
  1419. });
  1420. if (callback) {
  1421. callback(result);
  1422. }
  1423. resolve(result);
  1424. }
  1425. });
  1426. }
  1427. if (_windows) {
  1428. let cmd = 'netstat -nao';
  1429. try {
  1430. exec(cmd, util.execOptsWin, function (error, stdout) {
  1431. if (!error) {
  1432. let lines = stdout.toString().split('\r\n');
  1433. lines.forEach(function (line) {
  1434. line = line.trim().replace(/ +/g, ' ').split(' ');
  1435. if (line.length >= 4) {
  1436. let localip = line[1];
  1437. let localport = '';
  1438. let localaddress = line[1].split(':');
  1439. if (localaddress.length > 1) {
  1440. localport = localaddress[localaddress.length - 1];
  1441. localaddress.pop();
  1442. localip = localaddress.join(':');
  1443. }
  1444. let peerip = line[2];
  1445. let peerport = '';
  1446. let peeraddress = line[2].split(':');
  1447. if (peeraddress.length > 1) {
  1448. peerport = peeraddress[peeraddress.length - 1];
  1449. peeraddress.pop();
  1450. peerip = peeraddress.join(':');
  1451. }
  1452. let pid = util.toInt(line[4]);
  1453. let connstate = line[3];
  1454. if (connstate === 'HERGESTELLT') { connstate = 'ESTABLISHED'; }
  1455. if (connstate.startsWith('ABH')) { connstate = 'LISTEN'; }
  1456. if (connstate === 'SCHLIESSEN_WARTEN') { connstate = 'CLOSE_WAIT'; }
  1457. if (connstate === 'WARTEND') { connstate = 'TIME_WAIT'; }
  1458. if (connstate === 'SYN_GESENDET') { connstate = 'SYN_SENT'; }
  1459. if (connstate === 'LISTENING') { connstate = 'LISTEN'; }
  1460. if (connstate === 'SYN_RECEIVED') { connstate = 'SYN_RECV'; }
  1461. if (connstate === 'FIN_WAIT_1') { connstate = 'FIN_WAIT1'; }
  1462. if (connstate === 'FIN_WAIT_2') { connstate = 'FIN_WAIT2'; }
  1463. if (connstate) {
  1464. result.push({
  1465. protocol: line[0].toLowerCase(),
  1466. localAddress: localip,
  1467. localPort: localport,
  1468. peerAddress: peerip,
  1469. peerPort: peerport,
  1470. state: connstate,
  1471. pid,
  1472. process: ''
  1473. });
  1474. }
  1475. }
  1476. });
  1477. if (callback) {
  1478. callback(result);
  1479. }
  1480. resolve(result);
  1481. }
  1482. });
  1483. } catch (e) {
  1484. if (callback) { callback(result); }
  1485. resolve(result);
  1486. }
  1487. }
  1488. });
  1489. });
  1490. }
  1491. exports.networkConnections = networkConnections;
  1492. function networkGatewayDefault(callback) {
  1493. return new Promise((resolve) => {
  1494. process.nextTick(() => {
  1495. let result = '';
  1496. if (_linux || _freebsd || _openbsd || _netbsd) {
  1497. let cmd = 'ip route get 1';
  1498. try {
  1499. exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
  1500. if (!error) {
  1501. let lines = stdout.toString().split('\n');
  1502. const line = lines && lines[0] ? lines[0] : '';
  1503. let parts = line.split(' via ');
  1504. if (parts && parts[1]) {
  1505. parts = parts[1].split(' ');
  1506. result = parts[0];
  1507. }
  1508. if (callback) {
  1509. callback(result);
  1510. }
  1511. resolve(result);
  1512. } else {
  1513. if (callback) {
  1514. callback(result);
  1515. }
  1516. resolve(result);
  1517. }
  1518. });
  1519. } catch (e) {
  1520. if (callback) { callback(result); }
  1521. resolve(result);
  1522. }
  1523. }
  1524. if (_darwin) {
  1525. let cmd = 'route -n get default';
  1526. try {
  1527. exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
  1528. if (!error) {
  1529. const lines = stdout.toString().split('\n').map(line => line.trim());
  1530. result = util.getValue(lines, 'gateway');
  1531. }
  1532. if (!result) {
  1533. cmd = 'netstat -rn | awk \'/default/ {print $2}\'';
  1534. exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
  1535. const lines = stdout.toString().split('\n').map(line => line.trim());
  1536. result = lines.find(line => (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(line)));
  1537. if (callback) {
  1538. callback(result);
  1539. }
  1540. resolve(result);
  1541. });
  1542. } else {
  1543. if (callback) {
  1544. callback(result);
  1545. }
  1546. resolve(result);
  1547. }
  1548. });
  1549. } catch (e) {
  1550. if (callback) { callback(result); }
  1551. resolve(result);
  1552. }
  1553. }
  1554. if (_windows) {
  1555. try {
  1556. exec('netstat -r', util.execOptsWin, function (error, stdout) {
  1557. const lines = stdout.toString().split(os.EOL);
  1558. lines.forEach(line => {
  1559. line = line.replace(/\s+/g, ' ').trim();
  1560. if (line.indexOf('0.0.0.0 0.0.0.0') > -1 && !(/[a-zA-Z]/.test(line))) {
  1561. const parts = line.split(' ');
  1562. if (parts.length >= 5 && (parts[parts.length - 3]).indexOf('.') > -1) {
  1563. result = parts[parts.length - 3];
  1564. }
  1565. }
  1566. });
  1567. if (!result) {
  1568. util.powerShell('Get-CimInstance -ClassName Win32_IP4RouteTable | Where-Object { $_.Destination -eq \'0.0.0.0\' -and $_.Mask -eq \'0.0.0.0\' }')
  1569. .then(data => {
  1570. let lines = data.toString().split('\r\n');
  1571. if (lines.length > 1 && !result) {
  1572. result = util.getValue(lines, 'NextHop');
  1573. if (callback) {
  1574. callback(result);
  1575. }
  1576. resolve(result);
  1577. // } else {
  1578. // exec('ipconfig', util.execOptsWin, function (error, stdout) {
  1579. // let lines = stdout.toString().split('\r\n');
  1580. // lines.forEach(function (line) {
  1581. // line = line.trim().replace(/\. /g, '');
  1582. // line = line.trim().replace(/ +/g, '');
  1583. // const parts = line.split(':');
  1584. // if ((parts[0].toLowerCase().startsWith('standardgate') || parts[0].toLowerCase().indexOf('gateway') > -1 || parts[0].toLowerCase().indexOf('enlace') > -1) && parts[1]) {
  1585. // result = parts[1];
  1586. // }
  1587. // });
  1588. // if (callback) { callback(result); }
  1589. // resolve(result);
  1590. // });
  1591. }
  1592. });
  1593. } else {
  1594. if (callback) {
  1595. callback(result);
  1596. }
  1597. resolve(result);
  1598. }
  1599. });
  1600. } catch (e) {
  1601. if (callback) { callback(result); }
  1602. resolve(result);
  1603. }
  1604. }
  1605. });
  1606. });
  1607. }
  1608. exports.networkGatewayDefault = networkGatewayDefault;