Skip to content
Permalink
Browse files

report: include network interfaces in report

PR-URL: #28911
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
  • Loading branch information...
cjihrig authored and BridgeAR committed Jul 23, 2019
1 parent 57f5d50 commit 4b91e4dafdad472da4550aaab3c21727710a647d
Showing with 87 additions and 1 deletion.
  1. +10 −0 doc/api/report.md
  2. +53 −0 src/node_report.cc
  3. +24 −1 test/common/report.js
@@ -83,6 +83,16 @@ is provided below for reference.
"irq": 0
}
],
"networkInterfaces": [
{
"name": "en0",
"internal": false,
"mac": "13:10:de:ad:be:ef",
"address": "10.0.0.37",
"netmask": "255.255.255.0",
"family": "IPv4"
}
],
"host": "test_machine"
},
"javascriptStack": {
@@ -67,6 +67,7 @@ static void PrintLoadedLibraries(JSONWriter* writer);
static void PrintComponentVersions(JSONWriter* writer);
static void PrintRelease(JSONWriter* writer);
static void PrintCpuInfo(JSONWriter* writer);
static void PrintNetworkInterfaceInfo(JSONWriter* writer);

// External function to trigger a report, writing to file.
// The 'name' parameter is in/out: an input filename is used
@@ -318,6 +319,7 @@ static void PrintVersionInformation(JSONWriter* writer) {
}

PrintCpuInfo(writer);
PrintNetworkInterfaceInfo(writer);

char host[UV_MAXHOSTNAMESIZE];
size_t host_size = sizeof(host);
@@ -348,6 +350,57 @@ static void PrintCpuInfo(JSONWriter* writer) {
}
}

static void PrintNetworkInterfaceInfo(JSONWriter* writer) {
uv_interface_address_t* interfaces;
char ip[INET6_ADDRSTRLEN];
char netmask[INET6_ADDRSTRLEN];
char mac[18];
int count;

if (uv_interface_addresses(&interfaces, &count) == 0) {
writer->json_arraystart("networkInterfaces");

for (int i = 0; i < count; i++) {
writer->json_start();
writer->json_keyvalue("name", interfaces[i].name);
writer->json_keyvalue("internal", !!interfaces[i].is_internal);
snprintf(mac,
sizeof(mac),
"%02x:%02x:%02x:%02x:%02x:%02x",
static_cast<unsigned char>(interfaces[i].phys_addr[0]),
static_cast<unsigned char>(interfaces[i].phys_addr[1]),
static_cast<unsigned char>(interfaces[i].phys_addr[2]),
static_cast<unsigned char>(interfaces[i].phys_addr[3]),
static_cast<unsigned char>(interfaces[i].phys_addr[4]),
static_cast<unsigned char>(interfaces[i].phys_addr[5]));
writer->json_keyvalue("mac", mac);

if (interfaces[i].address.address4.sin_family == AF_INET) {
uv_ip4_name(&interfaces[i].address.address4, ip, sizeof(ip));
uv_ip4_name(&interfaces[i].netmask.netmask4, netmask, sizeof(netmask));
writer->json_keyvalue("address", ip);
writer->json_keyvalue("netmask", netmask);
writer->json_keyvalue("family", "IPv4");
} else if (interfaces[i].address.address4.sin_family == AF_INET6) {
uv_ip6_name(&interfaces[i].address.address6, ip, sizeof(ip));
uv_ip6_name(&interfaces[i].netmask.netmask6, netmask, sizeof(netmask));
writer->json_keyvalue("address", ip);
writer->json_keyvalue("netmask", netmask);
writer->json_keyvalue("family", "IPv6");
writer->json_keyvalue("scopeid",
interfaces[i].address.address6.sin6_scope_id);
} else {
writer->json_keyvalue("family", "unknown");
}

writer->json_end();
}

writer->json_arrayend();
uv_free_interface_addresses(interfaces, count);
}
}

// Report the JavaScript stack.
static void PrintJavaScriptStack(JSONWriter* writer,
Isolate* isolate,
@@ -2,6 +2,7 @@
'use strict';
const assert = require('assert');
const fs = require('fs');
const net = require('net');
const os = require('os');
const path = require('path');
const util = require('util');
@@ -73,7 +74,7 @@ function _validateContent(report) {
'componentVersions', 'release', 'osName', 'osRelease',
'osVersion', 'osMachine', 'cpus', 'host',
'glibcVersionRuntime', 'glibcVersionCompiler', 'cwd',
'reportVersion'];
'reportVersion', 'networkInterfaces'];
checkForUnknownFields(header, headerFields);
assert.strictEqual(header.reportVersion, 1); // Increment as needed.
assert.strictEqual(typeof header.event, 'string');
@@ -112,6 +113,28 @@ function _validateContent(report) {
return c.model === cpu.model;
}));
});

assert(Array.isArray(header.networkInterfaces));
header.networkInterfaces.forEach((iface) => {
assert.strictEqual(typeof iface.name, 'string');
assert.strictEqual(typeof iface.internal, 'boolean');
assert(/^([0-9A-F][0-9A-F]:){5}[0-9A-F]{2}$/i.test(iface.mac));

if (iface.family === 'IPv4') {
assert.strictEqual(net.isIPv4(iface.address), true);
assert.strictEqual(net.isIPv4(iface.netmask), true);
assert.strictEqual(iface.scopeid, undefined);
} else if (iface.family === 'IPv6') {
assert.strictEqual(net.isIPv6(iface.address), true);
assert.strictEqual(net.isIPv6(iface.netmask), true);
assert(Number.isInteger(iface.scopeid));
} else {
assert.strictEqual(iface.family, 'unknown');
assert.strictEqual(iface.address, undefined);
assert.strictEqual(iface.netmask, undefined);
assert.strictEqual(iface.scopeid, undefined);
}
});
assert.strictEqual(header.host, os.hostname());

// Verify the format of the javascriptStack section.

0 comments on commit 4b91e4d

Please sign in to comment.
You can’t perform that action at this time.