diff --git a/lib/network.js b/lib/network.js index b9a2928..c19dfbf 100644 --- a/lib/network.js +++ b/lib/network.js @@ -183,18 +183,22 @@ exports.networkInterfaceDefault = networkInterfaceDefault; // -------------------------- // NET - interfaces -function parseLinesWindowsNics(sections) { +function parseLinesWindowsNics(sections, nconfigsections) { let nics = []; for (let i in sections) { if (sections.hasOwnProperty(i)) { + if (sections[i].trim() !== '') { - + let lines = sections[i].trim().split('\r\n'); + let linesNicConfig = nconfigsections[i].trim().split('\r\n'); let netEnabled = util.getValue(lines, 'NetEnabled', '='); + if (netEnabled) { const speed = parseInt(util.getValue(lines, 'speed', '=').trim(), 10) / 1000000; nics.push({ mac: util.getValue(lines, 'MACAddress', '=').toLowerCase(), + dhcp: util.getValue(linesNicConfig, 'dhcpEnabled', '=').toLowerCase(), name: util.getValue(lines, 'Name', '=').replace(/\]/g, ')').replace(/\[/g, '('), netEnabled: netEnabled === 'TRUE', speed: isNaN(speed) ? -1 : speed, @@ -210,14 +214,183 @@ function parseLinesWindowsNics(sections) { function getWindowsNics() { const cmd = util.getWmic() + ' nic get MACAddress, name, NetEnabled, Speed, NetConnectionStatus, AdapterTypeId /value'; + const cmdnicconfig = util.getWmic() + ' nicconfig get dhcpEnabled /value'; try { const nsections = execSync(cmd, util.execOptsWin).split(/\n\s*\n/); - return (parseLinesWindowsNics(nsections)); + const nconfigsections = execSync(cmdnicconfig, util.execOptsWin).split(/\n\s*\n/); + return (parseLinesWindowsNics(nsections, nconfigsections)); } catch (e) { return []; } } +function getWindowsDNSsuffixes() { + + let iface = {}; + + let dnsSuffixes = { + primaryDNS: '', + exitCode: 0, + ifaces: [], + }; + + try { + const ipconfig = execSync('ipconfig /all', util.execOptsWin); + const ipconfigArray = ipconfig.split('\r\n\r\n'); + + ipconfigArray.forEach( (element, index) => { + + if(index == 1) { + const longPrimaryDNS = element.split('\r\n').filter((element) => { + return element.toUpperCase().includes('DNS'); + }); + const primaryDNS = longPrimaryDNS[0].substring(longPrimaryDNS[0].lastIndexOf(":")+1); + dnsSuffixes.primaryDNS = primaryDNS.trim(); + if(!dnsSuffixes.primaryDNS) dnsSuffixes.primaryDNS = 'Not defined'; + } + if(index > 1) { + if(index % 2 == 0){ + const name = element.substring(element.lastIndexOf(" ")+1).replace(':', ''); + iface.name = name; + }else { + const connectionSpecificDNS = element.split('\r\n').filter((element) => { + return element.toUpperCase().includes('DNS') + }); + const dnsSuffix = connectionSpecificDNS[0].substring(connectionSpecificDNS[0].lastIndexOf(":")+1); + iface.dnsSuffix = dnsSuffix.trim(); + dnsSuffixes.ifaces.push(iface); + iface = {}; + } + } + }); + + return dnsSuffixes; + } catch (error) { + console.log('An error occurred trying to bring the Connection-specific DNS suffix', error.message); + return { + primaryDNS: '', + exitCode: 0, + ifaces: [], + }; + } + +} + +function getWindowsIfaceDNSsuffix(ifaces, ifacename) { + let dnsSuffix = ''; + // Adding (.) to ensure ifacename compatibility when duplicated iface-names + const interfaceName = ifacename + '.'; + try { + const connectionDnsSuffix = ifaces.filter((iface) => { + return interfaceName.includes(iface.name + '.'); + }).map((iface) => iface.dnsSuffix); + if(connectionDnsSuffix[0]) { + dnsSuffix = connectionDnsSuffix[0]; + } + if(!dnsSuffix) dnsSuffix = ''; + return dnsSuffix ; + } catch (error) { + console.log('Error getting Connection-specific DNS suffix: ', error.message); + return 'Unknown'; + } +} + +function getWindowsWiredProfilesInformation() { + try { + const result = execSync('netsh lan show profiles', util.execOptsWin); + const profileList = result.split('\r\nProfile on interface'); + return profileList; + } catch (error) { + if(error.status === 1 && error.stdout.includes('AutoConfig')){ + return 'Disabled'; + } + return []; + } +} + +function getWindowsWirelessIfaceSSID(interfaceName){ + try { + const result = execSync(`netsh wlan show interface name="${interfaceName}" | findstr "SSID"`, util.execOptsWin); + const SSID = result.split('\r\n').shift(); + const parseSSID = SSID.split(':').pop(); + return parseSSID; + } catch (error) { + return 'Unknown'; + } +} +function getWindowsIEEE8021x(connectionType, iface, ifaces) { + let i8021x = { + state: 'Unknown', + protocol: 'Unknown', + }; + + if(ifaces === 'Disabled'){ + i8021x.state = "Disabled"; + i8021x.protocol = "Not defined"; + return i8021x; + } + + if(connectionType == 'wired' && ifaces.length > 0){ + try { + // Get 802.1x information by interface name + const iface8021xInfo = ifaces.find((element) => { + return element.includes(iface + '\r\n'); + }); + + const arrayIface8021xInfo = iface8021xInfo.split('\r\n') + + const state8021x = arrayIface8021xInfo.find((element) => { + return element.includes('802.1x'); + }); + + if(state8021x.includes('Disabled')){ + i8021x.state = "Disabled"; + i8021x.protocol = "Not defined"; + + } else if (state8021x.includes('Enabled')) { + const protocol8021x = arrayIface8021xInfo.find((element) => { + return element.includes('EAP'); + }); + + i8021x.protocol = protocol8021x.split(':').pop(); + i8021x.state = "Enabled"; + } + + } catch (error) { + // console.log('Error getting wired information:', error); + return i8021x; + } + } else if (connectionType == 'wireless'){ + + let i8021xState = ''; + let i8021xProtocol = ''; + + + + try { + const SSID = getWindowsWirelessIfaceSSID(iface); + if(SSID !== 'Unknown') { + i8021xState = execSync(`netsh wlan show profiles "${SSID}" | findstr "802.1X"`, util.execOptsWin); + i8021xProtocol = execSync(`netsh wlan show profiles "${SSID}" | findstr "EAP"`, util.execOptsWin); + } + + if (i8021xState.includes(':') && i8021xProtocol.includes(':')) { + i8021x.state = i8021xState.split(':').pop(); + i8021x.protocol = i8021xProtocol.split(':').pop(); + } + } catch (error) { + // console.log('Error getting wireless information:', error); + if(error.status === 1 && error.stdout.includes('AutoConfig')){ + i8021x.state = "Disabled"; + i8021x.protocol = "Not defined"; + } + return i8021x; + } + } + + return i8021x; +} + function splitSectionsNics(lines) { const result = []; let section = []; @@ -304,6 +477,92 @@ function getDarwinNics() { } } + +function getLinuxIfaceConnectionName(interfaceName) { + const cmd = `nmcli device status | grep ${interfaceName}`; + + try { + const result = execSync(cmd).toString(); + const resultFormat = result.replace(/\s+/g,' ').trim(); + const connectionNameLines = resultFormat.split(" ").slice(3); + const connectionName = connectionNameLines.join(' '); + return connectionName != '--' ? connectionName : ''; + } catch (e) { + return ''; + } +} + +function getLinuxIfaceDHCPstatus(connectionName) { + if(connectionName) { + const cmd = `nmcli connection show "${connectionName}" \| grep ipv4.method;`; + try { + const result = execSync(cmd).toString(); + const resultFormat = result.replace(/\s+/g,' ').trim(); + + let dhcStatus = resultFormat.split(" ").slice(1).toString(); + switch (dhcStatus) { + case 'auto': + dhcStatus = true; + break; + + default: + dhcStatus = false; + break; + } + return dhcStatus; + } catch (e) { + return 'Unknown'; + } + } else { + return 'Unknown'; + } +} + +function getLinuxIfaceDNSsuffix(connectionName) { + if(connectionName) { + const cmd = `nmcli connection show "${connectionName}" \| grep ipv4.dns-search;`; + try { + const result = execSync(cmd).toString(); + const resultFormat = result.replace(/\s+/g,' ').trim(); + const dnsSuffix = resultFormat.split(" ").slice(1).toString(); + return dnsSuffix == '--' ? 'Not defined': dnsSuffix; + } catch (e) { + return 'Unknown'; + } + } else { + return 'Unknown'; + } +} + +function getLinuxIfaceAuth8021x(connectionName) { + if(connectionName) { + const cmd = `nmcli connection show "${connectionName}" \| grep 802-1x.eap;`; + try { + const result = execSync(cmd).toString(); + const resultFormat = result.replace(/\s+/g,' ').trim(); + const authenticationProtocol = resultFormat.split(" ").slice(1).toString(); + + + return authenticationProtocol == '--' ? '': authenticationProtocol; + } catch (e) { + return 'Not defined'; + } + } else { + return 'Not defined'; + } +} + +function getLinuxIfaceState8021x(authenticationProtocol) { + if(authenticationProtocol) { + if(authenticationProtocol == 'Not defined'){ + return 'Disabled'; + } + return 'Enabled'; + } else { + return 'Unknown'; + } +} + function testVirtualNic(iface, ifaceName, mac) { 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']; if (mac) { @@ -326,12 +585,12 @@ function networkInterfaces(callback) { let ifaces = os.networkInterfaces(); let result = []; let nics = []; + let dnsSuffixes = []; + let nics8021xInfo = []; // seperate handling in OSX if (_darwin || _freebsd || _openbsd || _netbsd) { nics = getDarwinNics(); - // console.log(nics); - // console.log('-------'); - // console.log(ifaces); + nics.forEach(nic => { result.push({ @@ -362,7 +621,9 @@ function networkInterfaces(callback) { } else { _ifaces = ifaces; if (_windows) { + nics8021xInfo = getWindowsWiredProfilesInformation(); nics = getWindowsNics(); + dnsSuffixes = getWindowsDNSsuffixes(); } for (let dev in ifaces) { let ip4 = ''; @@ -373,12 +634,15 @@ function networkInterfaces(callback) { let speed = -1; let carrierChanges = 0; let operstate = 'down'; + let dhcp = false; + let dnsSuffix = ''; + let auth8021x = ''; + let state8021x = ''; let type = ''; if (ifaces.hasOwnProperty(dev)) { let ifaceName = dev; ifaces[dev].forEach(function (details) { - if (details.family === 'IPv4') { ip4 = details.address; } @@ -421,11 +685,19 @@ function networkInterfaces(callback) { echo -n "speed: "; cat /sys/class/net/${iface}/speed 2>/dev/null; echo; echo -n "tx_queue_len: "; cat /sys/class/net/${iface}/tx_queue_len 2>/dev/null; echo; echo -n "type: "; cat /sys/class/net/${iface}/type 2>/dev/null; echo; - echo -n "wireless: "; cat /proc/net/wireless 2>/dev/null \| grep ${iface}; echo + echo -n "wireless: "; cat /proc/net/wireless 2>/dev/null \| grep ${iface}; echo; echo -n "wirelessspeed: "; iw dev ${iface} link 2>&1 \| grep bitrate; echo;`; - let lines = []; + + let lines = []; try { + const connectionName = getLinuxIfaceConnectionName(iface); + dhcp = getLinuxIfaceDHCPstatus(connectionName); + dnsSuffix = getLinuxIfaceDNSsuffix(connectionName); + auth8021x = getLinuxIfaceAuth8021x(connectionName); + state8021x = getLinuxIfaceState8021x(auth8021x); lines = execSync(cmd).toString().split('\n'); + + } catch (e) { util.noop(); } @@ -445,17 +717,26 @@ function networkInterfaces(callback) { if (iface === 'lo' || iface.startsWith('bond')) { type = 'virtual'; } } if (_windows) { + + + dnsSuffix = getWindowsIfaceDNSsuffix(dnsSuffixes.ifaces, dev); nics.forEach(detail => { if (detail.mac === mac) { ifaceName = detail.name; + dhcp = detail.dhcp; operstate = detail.operstate; speed = detail.speed; type = detail.type; } }); - if (dev.toLowerCase().indexOf('wlan') >= 0 || ifaceName.toLowerCase().indexOf('wlan') >= 0 || ifaceName.toLowerCase().indexOf('wireless') >= 0) { + + 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) { type = 'wireless'; } + + const IEEE8021x = getWindowsIEEE8021x(type, dev, nics8021xInfo); + auth8021x = IEEE8021x.protocol; + state8021x = IEEE8021x.state; } let internal = (ifaces[dev] && ifaces[dev][0]) ? ifaces[dev][0].internal : null; const virtual = internal ? false : testVirtualNic(dev, ifaceName, mac); @@ -472,6 +753,10 @@ function networkInterfaces(callback) { duplex, mtu, speed, + dhcp, + dnsSuffix, + auth8021x, + state8021x, carrierChanges, }); }