networkInterfaces() extended, networkStats() extended, bugfix windows

This commit is contained in:
Sebastian Hildebrandt 2019-01-03 20:46:44 +01:00
parent d3352ae2c1
commit 6b3fb2173b
7 changed files with 261 additions and 135 deletions

View File

@ -100,6 +100,7 @@ Other changes
| Version | Date | Comment | | Version | Date | Comment |
| -------------- | -------------- | -------- | | -------------- | -------------- | -------- |
| 3.55.0 | 2019-01-04 | `networkInterfaces()` extended, `networkStats()` extended, bugfix windows |
| 3.54.0 | 2018-12-30 | added TypeScript type definitions | | 3.54.0 | 2018-12-30 | added TypeScript type definitions |
| 3.53.1 | 2018-12-29 | `versions()` bug fix nginx version | | 3.53.1 | 2018-12-29 | `versions()` bug fix nginx version |
| 3.53.0 | 2018-12-29 | `versions()` added perl, python, gcc | | 3.53.0 | 2018-12-29 | `versions()` added perl, python, gcc |

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2018 Sebastian Hildebrandt Copyright (c) 2014-2019 Sebastian Hildebrandt
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in

View File

@ -14,19 +14,6 @@ Simple system and OS information library for [node.js][nodejs-url]
[![Caretaker][caretaker-image]][caretaker-url] [![Caretaker][caretaker-image]][caretaker-url]
[![MIT license][license-img]][license-url] [![MIT license][license-img]][license-url]
#### Happy christmas holiday
```
. * * *. * . * .
. . __ * . * . *
* * * . . _|__|_ * __ . *
. * /\ /\ * ('') * _|__|_ .
/ \ * / \ * . <( . )> * . ('') * *
* / \ / \ . * _(__.__)_ _ ,--<( . )> . .
/ \ / \ * | | )),` ( . ) *
...* `||` .. `||` . *. ... ==========='` ... '--`-` ... * ...
```
## Quick Start ## Quick Start
Lightweight collection of 35+ functions to retrieve detailed hardware, system and OS information. Lightweight collection of 35+ functions to retrieve detailed hardware, system and OS information.
@ -77,14 +64,13 @@ async function cpu() {
(last 7 major and minor version releases) (last 7 major and minor version releases)
- Version 3.55.0: `networkInterfaces()` extended, `networkStats()` extended, bugfix windows
- Version 3.54.0: added TypeScript type definitions - Version 3.54.0: added TypeScript type definitions
- Version 3.53.0: `versions()` added perl, python, gcc - Version 3.53.0: `versions()` added perl, python, gcc
- Version 3.52.0: `cpu()` added physical cores, processors, socket type - Version 3.52.0: `cpu()` added physical cores, processors, socket type
- Version 3.51.0: `processLoad()` added for windows - Version 3.51.0: `processLoad()` added for windows
- Version 3.50.0: `services()` added possibility to specify ALL services "*" for linux/win - Version 3.50.0: `services()` added possibility to specify ALL services "*" for linux/win
- Version 3.49.0: `uuid()` added - os specific uuid (per installation) - Version 3.49.0: `uuid()` added - os specific uuid (per installation)
- Version 3.48.0: `osInfo()` added build, serial (Windows/macOS)
- Version 3.47.0: `version()` added docker, postfix
- ... - ...
You can find all changes here: [detailed changelog][changelog-url] You can find all changes here: [detailed changelog][changelog-url]
@ -324,17 +310,28 @@ I also created a nice little command line tool called [mmon][mmon-github-url] (
| Function | Result object | Linux | BSD | Mac | Win | Sun | Comments | | Function | Result object | Linux | BSD | Mac | Win | Sun | Comments |
| --------------- | ------------- | ----- | ------- | --- | --- | --- | -------- | | --------------- | ------------- | ----- | ------- | --- | --- | --- | -------- |
| si.networkInterfaces(cb) | [{...}] | X | X | X | X | X | array of network interfaces | | si.networkInterfaces(cb) | [{...}] | X | X | X | X | X | array of network interfaces |
| | [0].iface | X | X | X | X | X | interface name | | | [0].iface | X | X | X | X | X | interface |
| | [0].ifaceName | X | X | X | X | X | interface name (differs on Windows) |
| | [0].ip4 | X | X | X | X | X | ip4 address | | | [0].ip4 | X | X | X | X | X | ip4 address |
| | [0].ip6 | X | X | X | X | X | ip6 address | | | [0].ip6 | X | X | X | X | X | ip6 address |
| | [0].mac | X | X | X | X | X | MAC address | | | [0].mac | X | X | X | X | X | MAC address |
| | [0].internal | X | X | X | X | X | true if internal interface | | | [0].internal | X | X | X | X | X | true if internal interface |
| | [0].operstate | X | | | X | | up / down |
| | [0].type | X | | | X | | wireless / wired |
| | [0].duplex | X | | | | | duplex |
| | [0].mtu | X | | | | | maximum transmission unit |
| | [0].speed | X | | | X | | speed in MBit / s |
| | [0].carrierChanges | X | | | | | # changes up/down |
| si.networkInterfaceDefault(cb) | : string | X | X | X | X | X | get name of default network interface | | si.networkInterfaceDefault(cb) | : string | X | X | X | X | X | get name of default network interface |
| si.networkStats(iface,cb) | {...} | X | X | X | X | | current network stats of given interface<br>iface parameter is optional<br>defaults to first external network interface| | si.networkStats(iface,cb) | {...} | X | X | X | X | | current network stats of given interface<br>iface parameter is optional<br>defaults to first external network interface|
| | iface | X | X | X | X | | interface | | | iface | X | X | X | X | | interface |
| | operstate | X | X | X | X | | up / down | | | operstate | X | X | X | X | | up / down |
| | rx | X | X | X | X | | received bytes overall | | | rx | X | X | X | X | | received bytes overall |
| | rx_dropped | X | X | X | X | | received dropped overall |
| | rx_errors | X | X | X | X | | received errors overall |
| | tx | X | X | X | X | | transferred bytes overall | | | tx | X | X | X | X | | transferred bytes overall |
| | tx_dropped | X | X | X | X | | transferred dropped overall |
| | tx_errors | X | X | X | X | | transferred errors overall |
| | rx_sec | X | X | X | X | | received bytes / second (* see notes) | | | rx_sec | X | X | X | X | | received bytes / second (* see notes) |
| | tx_sec | X | X | X | X | | transferred bytes per second (* see notes) | | | tx_sec | X | X | X | X | | transferred bytes per second (* see notes) |
| | ms | X | X | X | X | | interval length (for per second values) | | | ms | X | X | X | X | | interval length (for per second values) |
@ -633,7 +630,7 @@ All other trademarks are the property of their respective owners.
>The [`MIT`][license-url] License (MIT) >The [`MIT`][license-url] License (MIT)
> >
>Copyright &copy; 2014-2018 Sebastian Hildebrandt, [+innovations](http://www.plus-innovations.com). >Copyright &copy; 2014-2019 Sebastian Hildebrandt, [+innovations](http://www.plus-innovations.com).
> >
>Permission is hereby granted, free of charge, to any person obtaining a copy >Permission is hereby granted, free of charge, to any person obtaining a copy
>of this software and associated documentation files (the "Software"), to deal >of this software and associated documentation files (the "Software"), to deal

11
lib/index.d.ts vendored
View File

@ -274,17 +274,28 @@ export namespace Systeminformation {
interface NetworkInterfacesData { interface NetworkInterfacesData {
iface: string; iface: string;
ifaceName: string;
ip4: string; ip4: string;
ip6: string; ip6: string;
mac: string; mac: string;
internal: boolean; internal: boolean;
operstate: string;
type: string;
duplex: string;
mtu: number;
speed: number;
carrier_changes: number;
} }
interface NetworkStatsData { interface NetworkStatsData {
iface: string; iface: string;
operstate: string; operstate: string;
rx: number; rx: number;
rx_dropped: number;
rx_errors: number;
tx: number; tx: number;
tx_dropped: number;
tx_errors: number;
rx_sec: number; rx_sec: number;
tx_sec: number; tx_sec: number;
ms: number; ms: number;

View File

@ -29,6 +29,8 @@ const _sunos = (_platform === 'sunos');
let _network = {}; let _network = {};
let _default_iface; let _default_iface;
let _ifaces = [];
let _networkInterfaces = [];
let _mac = {}; let _mac = {};
let pathToIp; let pathToIp;
@ -145,19 +147,74 @@ exports.networkInterfaceDefault = networkInterfaceDefault;
// -------------------------- // --------------------------
// NET - interfaces // NET - interfaces
function parseLinesWindowsNics(sections) {
let nics = [];
for (let i in sections) {
if (sections.hasOwnProperty(i)) {
if (sections[i].trim() !== '') {
let lines = sections[i].trim().split('\r\n');
let netEnabled = util.getValue(lines, 'NetEnabled', '=');
if (netEnabled) {
const speed = parseInt(util.getValue(lines, 'speed', '=').trim(), 10);
nics.push({
mac: util.getValue(lines, 'MACAddress', '=').toLowerCase(),
name: util.getValue(lines, 'Name', '=').replace(/\]/g, ')').replace(/\[/g, '('),
netEnabled: netEnabled === 'TRUE',
speed: isNaN(speed) ? -1 : speed,
operstate: util.getValue(lines, 'NetConnectionStatus', '=') === '2' ? 'up' : 'down',
type: util.getValue(lines, 'MACAddress', '=') === '9' ? 'wireless' : 'wired'
});
}
}
}
}
return nics;
}
function getWindoesNics() {
const cmd = util.getWmic() + ' nic get MACAddress, name, NetEnabled, Speed, NetConnectionStatus, AdapterTypeId /value';
try {
const nsections = execSync(cmd, util.execOptsWin).split(/\n\s*\n/);
return (parseLinesWindowsNics(nsections));
} catch (e) {
return [];
}
}
function networkInterfaces(callback) { function networkInterfaces(callback) {
return new Promise((resolve) => { return new Promise((resolve) => {
process.nextTick(() => { process.nextTick(() => {
let ifaces = os.networkInterfaces(); let ifaces = os.networkInterfaces();
let result = []; let result = [];
let nics = [];
if (JSON.stringify(ifaces) === JSON.stringify(_ifaces)) {
// no changes - just return object
result = _networkInterfaces;
if (callback) { callback(result); }
resolve(result);
} else {
_ifaces = ifaces;
if (_windows) {
nics = getWindoesNics();
}
for (let dev in ifaces) { for (let dev in ifaces) {
let ip4 = ''; let ip4 = '';
let ip6 = ''; let ip6 = '';
let mac = ''; let mac = '';
let duplex = '';
let mtu = '';
let speed = -1;
let carrierChanges = 0;
let operstate = 'down';
let type = '';
if (ifaces.hasOwnProperty(dev)) { if (ifaces.hasOwnProperty(dev)) {
let ifaceName = dev;
ifaces[dev].forEach(function (details) { ifaces[dev].forEach(function (details) {
if (details.family === 'IPv4') { if (details.family === 'IPv4') {
ip4 = details.address; ip4 = details.address;
} }
@ -167,6 +224,7 @@ function networkInterfaces(callback) {
} }
} }
mac = details.mac; mac = details.mac;
// fallback due to https://github.com/nodejs/node/issues/13581 (node 8.1 - node 8.2)
if (mac.indexOf('00:00:0') > -1 && (_linux || _darwin)) { if (mac.indexOf('00:00:0') > -1 && (_linux || _darwin)) {
if (Object.keys(_mac).length === 0) { if (Object.keys(_mac).length === 0) {
_mac = getMacAddresses(); _mac = getMacAddresses();
@ -174,12 +232,82 @@ function networkInterfaces(callback) {
mac = _mac[dev] || ''; mac = _mac[dev] || '';
} }
}); });
if (_linux) {
let iface = dev.split(':')[0];
const cmd = `echo -n "addr_assign_type: "; cat /sys/class/net/${iface}/addr_assign_type 2>&1;
echo -n "address: "; cat /sys/class/net/${iface}/address 2>&1;
echo -n "addr_len: "; cat /sys/class/net/${iface}/addr_len 2>&1;
echo -n "broadcast: "; cat /sys/class/net/${iface}/broadcast 2>&1;
echo -n "carrier: "; cat /sys/class/net/${iface}/carrier 2>&1;
echo -n "carrier_changes: "; cat /sys/class/net/${iface}/carrier_changes 2>&1;
echo -n "dev_id: "; cat /sys/class/net/${iface}/dev_id 2>&1;
echo -n "dev_port: "; cat /sys/class/net/${iface}/dev_port 2>&1;
echo -n "dormant: "; cat /sys/class/net/${iface}/dormant 2>&1;
echo -n "duplex: "; cat /sys/class/net/${iface}/duplex 2>&1;
echo -n "flags: "; cat /sys/class/net/${iface}/flags 2>&1;
echo -n "gro_flush_timeout: "; cat /sys/class/net/${iface}/gro_flush_timeout 2>&1;
echo -n "ifalias: "; cat /sys/class/net/${iface}/ifalias 2>&1;
echo -n "ifindex: "; cat /sys/class/net/${iface}/ifindex 2>&1;
echo -n "iflink: "; cat /sys/class/net/${iface}/iflink 2>&1;
echo -n "link_mode: "; cat /sys/class/net/${iface}/link_mode 2>&1;
echo -n "mtu: "; cat /sys/class/net/${iface}/mtu 2>&1;
echo -n "netdev_group: "; cat /sys/class/net/${iface}/netdev_group 2>&1;
echo -n "operstate: "; cat /sys/class/net/${iface}/operstate 2>&1;
echo -n "proto_down: "; cat /sys/class/net/${iface}/proto_down 2>&1;
echo -n "speed: "; cat /sys/class/net/${iface}/speed 2>&1;
echo -n "tx_queue_len: "; cat /sys/class/net/${iface}/tx_queue_len 2>&1;
echo -n "type: "; cat /sys/class/net/${iface}/type 2>&1;
echo -n "wireless: "; cat /proc/net/wireless \| grep ${iface}; echo;`;
let lines = execSync(cmd).toString().split('\n');
duplex = util.getValue(lines, 'duplex');
duplex = duplex.startsWith('cat') ? '' : duplex;
mtu = parseInt(util.getValue(lines, 'mtu'), 10);
let myspeed = parseInt(util.getValue(lines, 'speed'), 10);
speed = isNaN(myspeed) ? -1 : myspeed;
carrierChanges = parseInt(util.getValue(lines, 'carrier_changes'), 10);
operstate = util.getValue(lines, 'operstate');
type = operstate === 'up' ? (util.getValue(lines, 'wireless').trim() ? 'wireless' : 'wired') : 'unknown';
// rx_bytes = parseInt(util.getValue(lines, 'rx_bytes'), 10);
// rx_dropped = parseInt(util.getValue(lines, 'rx_dropped'), 10);
// rx_errors = parseInt(util.getValue(lines, 'rx_errors'), 10);
// tx_bytes = parseInt(util.getValue(lines, 'tx_bytes'), 10);
// tx_dropped = parseInt(util.getValue(lines, 'tx_dropped'), 10);
// tx_errors = parseInt(util.getValue(lines, 'tx_errors'), 10);
}
if (_windows) {
nics.forEach(detail => {
if (detail.mac === mac) {
ifaceName = detail.name;
operstate = detail.operstate;
speed = detail.speed;
type = detail.type;
}
});
}
// if (_darwin) {
//
// }
let internal = (ifaces[dev] && ifaces[dev][0]) ? ifaces[dev][0].internal : null; let internal = (ifaces[dev] && ifaces[dev][0]) ? ifaces[dev][0].internal : null;
result.push({ iface: dev, ip4: ip4, ip6: ip6, mac: mac, internal: internal }); result.push({
iface: dev,
ifaceName,
ip4,
ip6,
mac,
internal,
operstate,
type,
duplex,
mtu,
speed,
carrierChanges,
});
} }
} }
if (callback) { callback(result); } if (callback) { callback(result); }
resolve(result); resolve(result);
}
}); });
}); });
} }
@ -189,12 +317,16 @@ exports.networkInterfaces = networkInterfaces;
// -------------------------- // --------------------------
// NET - Speed // NET - Speed
function calcNetworkSpeed(iface, rx, tx, operstate) { function calcNetworkSpeed(iface, rx, tx, operstate, rx_dropped, rx_errors, tx_dropped, tx_errors) {
let result = { let result = {
iface: iface, iface,
operstate: operstate, operstate,
rx: rx, rx,
tx: tx, rx_dropped,
rx_errors,
tx,
tx_dropped,
tx_errors,
rx_sec: -1, rx_sec: -1,
tx_sec: -1, tx_sec: -1,
ms: 0 ms: 0
@ -226,27 +358,6 @@ function calcNetworkSpeed(iface, rx, tx, operstate) {
function networkStats(iface, callback) { function networkStats(iface, callback) {
function parseLinesWindowsNics(sections) {
let nics = [];
for (let i in sections) {
if (sections.hasOwnProperty(i)) {
if (sections[i].trim() !== '') {
let lines = sections[i].trim().split('\r\n');
let netEnabled = util.getValue(lines, 'NetEnabled', '=');
if (netEnabled) {
nics.push({
mac: util.getValue(lines, 'MACAddress', '=').toLowerCase(),
name: util.getValue(lines, 'Name', '=').replace(/[()\[\] ]+/g, '').toLowerCase(),
netEnabled: netEnabled === 'TRUE'
});
}
}
}
}
return nics;
}
function parseLinesWindowsPerfData(sections) { function parseLinesWindowsPerfData(sections) {
let perfData = []; let perfData = [];
for (let i in sections) { for (let i in sections) {
@ -257,7 +368,11 @@ function networkStats(iface, callback) {
perfData.push({ perfData.push({
name: util.getValue(lines, 'Name', '=').replace(/[()\[\] ]+/g, '').toLowerCase(), name: util.getValue(lines, 'Name', '=').replace(/[()\[\] ]+/g, '').toLowerCase(),
rx: parseInt(util.getValue(lines, 'BytesReceivedPersec', '='), 10), rx: parseInt(util.getValue(lines, 'BytesReceivedPersec', '='), 10),
tx: parseInt(util.getValue(lines, 'BytesSentPersec', '='), 10) rx_errors: parseInt(util.getValue(lines, 'PacketsReceivedErrors', '='), 10),
rx_dropped: parseInt(util.getValue(lines, 'PacketsReceivedDiscarded', '='), 10),
tx: parseInt(util.getValue(lines, 'BytesSentPersec', '='), 10),
tx_errors: parseInt(util.getValue(lines, 'PacketsOutboundErrors', '='), 10),
tx_dropped: parseInt(util.getValue(lines, 'PacketsOutboundDiscarded', '='), 10)
}); });
} }
} }
@ -265,7 +380,6 @@ function networkStats(iface, callback) {
return perfData; return perfData;
} }
// fallback - if only callback is given // fallback - if only callback is given
if (util.isFunction(iface) && !callback) { if (util.isFunction(iface) && !callback) {
callback = iface; callback = iface;
@ -281,7 +395,11 @@ function networkStats(iface, callback) {
iface: iface, iface: iface,
operstate: 'unknown', operstate: 'unknown',
rx: 0, rx: 0,
rx_dropped: 0,
rx_errors: 0,
tx: 0, tx: 0,
tx_dropped: 0,
tx_errors: 0,
rx_sec: -1, rx_sec: -1,
tx_sec: -1, tx_sec: -1,
ms: 0 ms: 0
@ -290,6 +408,10 @@ function networkStats(iface, callback) {
let operstate = 'unknown'; let operstate = 'unknown';
let rx = 0; let rx = 0;
let tx = 0; let tx = 0;
let rx_dropped = 0;
let rx_errors = 0;
let tx_dropped = 0;
let tx_errors = 0;
let cmd, lines, stats; let cmd, lines, stats;
if (!_network[iface] || (_network[iface] && !_network[iface].ms) || (_network[iface] && _network[iface].ms && Date.now() - _network[iface].ms >= 500)) { if (!_network[iface] || (_network[iface] && !_network[iface].ms) || (_network[iface] && _network[iface].ms && Date.now() - _network[iface].ms >= 500)) {
@ -298,15 +420,23 @@ function networkStats(iface, callback) {
cmd = cmd =
'cat /sys/class/net/' + iface + '/operstate; ' + 'cat /sys/class/net/' + iface + '/operstate; ' +
'cat /sys/class/net/' + iface + '/statistics/rx_bytes; ' + 'cat /sys/class/net/' + iface + '/statistics/rx_bytes; ' +
'cat /sys/class/net/' + iface + '/statistics/tx_bytes; '; 'cat /sys/class/net/' + iface + '/statistics/tx_bytes; ' +
'cat /sys/class/net/' + iface + '/statistics/rx_dropped; ' +
'cat /sys/class/net/' + iface + '/statistics/rx_errors; ' +
'cat /sys/class/net/' + iface + '/statistics/rx_dropped; ' +
'cat /sys/class/net/' + iface + '/statistics/tx_errors; ';
exec(cmd, function (error, stdout) { exec(cmd, function (error, stdout) {
if (!error) { if (!error) {
lines = stdout.toString().split('\n'); lines = stdout.toString().split('\n');
operstate = lines[0].trim(); operstate = lines[0].trim();
rx = parseInt(lines[1]); rx = parseInt(lines[1], 10);
tx = parseInt(lines[2]); tx = parseInt(lines[2], 10);
rx_dropped = parseInt(lines[3], 10);
rx_errors = parseInt(lines[4], 10);
tx_dropped = parseInt(lines[5], 10);
tx_errors = parseInt(lines[6], 10);
result = calcNetworkSpeed(iface, rx, tx, operstate); result = calcNetworkSpeed(iface, rx, tx, operstate, rx_dropped, rx_errors, tx_dropped, tx_errors);
} }
if (callback) { callback(result); } if (callback) { callback(result); }
@ -318,7 +448,7 @@ function networkStats(iface, callback) {
} }
} }
if (_freebsd || _openbsd) { if (_freebsd || _openbsd) {
cmd = 'netstat -ibnI ' + iface; cmd = 'netstat -ibndI ' + iface;
exec(cmd, function (error, stdout) { exec(cmd, function (error, stdout) {
if (!error) { if (!error) {
lines = stdout.toString().split('\n'); lines = stdout.toString().split('\n');
@ -326,11 +456,15 @@ function networkStats(iface, callback) {
const line = lines[i].replace(/ +/g, ' ').split(' '); const line = lines[i].replace(/ +/g, ' ').split(' ');
if (line && line[0] && line[7] && line[10]) { if (line && line[0] && line[7] && line[10]) {
rx = rx + parseInt(line[7]); rx = rx + parseInt(line[7]);
if (stats[6].trim() !== '-') { rx_dropped = rx_dropped + parseInt(stats[6]); }
if (stats[5].trim() !== '-') { rx_errors = rx_errors + parseInt(stats[5]); }
tx = tx + parseInt(line[10]); tx = tx + parseInt(line[10]);
if (stats[12].trim() !== '-') { tx_dropped = tx_dropped + parseInt(stats[12]); }
if (stats[9].trim() !== '-') { tx_errors = tx_errors + parseInt(stats[9]); }
operstate = 'up'; operstate = 'up';
} }
} }
result = calcNetworkSpeed(iface, rx, tx, operstate); result = calcNetworkSpeed(iface, rx, tx, operstate, rx_dropped, rx_errors, tx_dropped, tx_errors);
} }
if (callback) { callback(result); } if (callback) { callback(result); }
resolve(result); resolve(result);
@ -342,7 +476,7 @@ function networkStats(iface, callback) {
result.operstate = (stdout.toString().split(':')[1] || '').trim(); result.operstate = (stdout.toString().split(':')[1] || '').trim();
result.operstate = (result.operstate || '').toLowerCase(); result.operstate = (result.operstate || '').toLowerCase();
result.operstate = (result.operstate === 'active' ? 'up' : (result.operstate === 'inactive' ? 'down' : 'unknown')); result.operstate = (result.operstate === 'active' ? 'up' : (result.operstate === 'inactive' ? 'down' : 'unknown'));
cmd = 'netstat -bI ' + iface; cmd = 'netstat -bdI ' + iface;
exec(cmd, function (error, stdout) { exec(cmd, function (error, stdout) {
if (!error) { if (!error) {
lines = stdout.toString().split('\n'); lines = stdout.toString().split('\n');
@ -352,9 +486,13 @@ function networkStats(iface, callback) {
// use the second line because it is tied to the NIC instead of the ipv4 or ipv6 address // use the second line because it is tied to the NIC instead of the ipv4 or ipv6 address
stats = lines[1].replace(/ +/g, ' ').split(' '); stats = lines[1].replace(/ +/g, ' ').split(' ');
rx = parseInt(stats[6]); rx = parseInt(stats[6]);
rx_dropped = parseInt(stats[11]);
rx_errors = parseInt(stats[5]);
tx = parseInt(stats[9]); tx = parseInt(stats[9]);
tx_dropped = parseInt(stats[11]);
tx_errors = parseInt(stats[8]);
result = calcNetworkSpeed(iface, rx, tx, result.operstate); result = calcNetworkSpeed(iface, rx, tx, result.operstate, rx_dropped, rx_errors, tx_dropped, tx_errors);
} }
} }
if (callback) { callback(result); } if (callback) { callback(result); }
@ -363,18 +501,10 @@ function networkStats(iface, callback) {
}); });
} }
if (_windows) { if (_windows) {
// NICs
let perfData = []; let perfData = [];
let nics = [];
cmd = util.getWmic() + ' nic get MACAddress, name, NetEnabled /value';
try {
exec(cmd, util.execOptsWin, function (error, stdout) {
if (!error) {
const nsections = stdout.split(/\n\s*\n/);
nics = parseLinesWindowsNics(nsections);
// Performance Data // Performance Data
cmd = util.getWmic() + ' path Win32_PerfRawData_Tcpip_NetworkInterface Get name,BytesReceivedPersec,BytesSentPersec,BytesTotalPersec /value'; cmd = util.getWmic() + ' path Win32_PerfRawData_Tcpip_NetworkInterface Get name,BytesReceivedPersec,BytesSentPersec,BytesTotalPersec,PacketsOutboundDiscarded,PacketsOutboundErrors,PacketsReceivedDiscarded,PacketsReceivedErrors /value';
exec(cmd, util.execOptsWin, function (error, stdout) { exec(cmd, util.execOptsWin, function (error, stdout) {
if (!error) { if (!error) {
const psections = stdout.split(/\n\s*\n/); const psections = stdout.split(/\n\s*\n/);
@ -383,47 +513,31 @@ function networkStats(iface, callback) {
// Network Interfaces // Network Interfaces
networkInterfaces().then(interfaces => { networkInterfaces().then(interfaces => {
// get mac from 'interfaces' by interfacename
let mac = '';
interfaces.forEach(detail => {
if (detail.iface === iface) {
mac = detail.mac;
}
});
// get name from 'nics' (by macadress)
let name = '';
nics.forEach(detail => {
if (detail.mac === mac) {
name = detail.name;
operstate = (detail.netEnabled ? 'up' : 'down');
}
});
// get bytes sent, received from perfData by name // get bytes sent, received from perfData by name
rx = 0; rx = 0;
tx = 0; tx = 0;
perfData.forEach(detail => { perfData.forEach(detail => {
if (detail.name === name) { interfaces.forEach(det => {
if (det.iface === iface && det.ifaceName.replace(/[()\[\] ]+/g, '').toLowerCase() === detail.name) {
rx = detail.rx; rx = detail.rx;
rx_dropped = detail.rx_dropped;
rx_errors = detail.rx_errors;
tx = detail.tx; tx = detail.tx;
tx_dropped = detail.tx_dropped;
tx_errors = detail.tx_errors;
operstate = det.operstate;
} }
}); });
});
if (rx && tx) { if (rx && tx) {
result = calcNetworkSpeed(iface, parseInt(rx), parseInt(tx), operstate); result = calcNetworkSpeed(iface, parseInt(rx), parseInt(tx), operstate, rx_dropped, rx_errors, tx_dropped, tx_errors);
} }
if (callback) { callback(result); } if (callback) { callback(result); }
resolve(result); resolve(result);
}); });
}); });
} }
});
} catch (e) {
if (callback) { callback(result); }
resolve(result);
}
}
} else { } else {
result.rx = _network[iface].rx; result.rx = _network[iface].rx;
result.tx = _network[iface].tx; result.tx = _network[iface].tx;

View File

@ -370,7 +370,7 @@ function versions(callback) {
functionProcessed(); functionProcessed();
}); });
if (_darwin) { if (_darwin) {
const cmdLineToolsExists = fs.existsSync('/Library/Developer/CommandLineTools/'); const cmdLineToolsExists = fs.existsSync('/Library/Developer/CommandLineTools/usr/bin/');
const xcodeAppExists = fs.existsSync('/Applications/Xcode.app/Contents/Developer/Tools'); const xcodeAppExists = fs.existsSync('/Applications/Xcode.app/Contents/Developer/Tools');
const xcodeExists = fs.existsSync('/Library/Developer/Xcode/'); const xcodeExists = fs.existsSync('/Library/Developer/Xcode/');
const gitHomebrewExists = fs.existsSync('/usr/local/Cellar/git'); const gitHomebrewExists = fs.existsSync('/usr/local/Cellar/git');

View File

@ -43,8 +43,10 @@
"block devices", "block devices",
"netstats", "netstats",
"network", "network",
"network interfaces",
"network connections", "network connections",
"network stats", "network stats",
"iface",
"processes", "processes",
"users", "users",
"internet", "internet",
@ -55,6 +57,7 @@
"graphics", "graphics",
"graphic card", "graphic card",
"graphic controller", "graphic controller",
"gpu",
"display", "display",
"smart", "smart",
"disk layout" "disk layout"