Added Intel AMT scanning using TCP connections

Ylian Saint-Hilaire committed May 17, 2018 at 16:30 UTC 37f73a2bb7bcc9df99f154e00893a2214bf9f68d
2 files changed +34 -10
amtscanner.js
+33 -9
@@ -11,6 +11,7 @@ module.exports.CreateAmtScanner = function (parent) {
11 var obj = {};
12 obj.active = false;
13 obj.parent = parent;
14 + obj.net = require('net');
15 obj.dns = require('dns');
16 obj.dgram = require('dgram');
17 obj.common = require('./common.js');
@@ -107,26 +108,34 @@ module.exports.CreateAmtScanner = function (parent) {
108
109 // Look for all AMT computers that may be locally reachable and poll their presence
110 obj.performScan = function () {
111 + //console.log('performScan');
112 if (obj.action == false) { return false; }
113 obj.parent.db.getLocalAmtNodes(function (err, docs) {
114 for (var i in obj.scanTable) { obj.scanTable[i].present = false; }
115 if (err == null && docs.length > 0) {
116 for (var i in docs) {
115 - var doc = docs[i];
116 - var host = doc.host.toLowerCase();
117 + var doc = docs[i], host = doc.host.toLowerCase();
118 if ((host != '127.0.0.1') && (host != '::1') && (host != 'localhost')) { // Don't scan localhost
119 var scaninfo = obj.scanTable[doc._id];
120 if (scaninfo == undefined) {
121 var tag = obj.nextTag++;
122 obj.scanTableTags[tag] = obj.scanTable[doc._id] = scaninfo = { nodeinfo: doc, present: true, tag: tag, state: 0 };
123 + //console.log('Scan ' + host + ', state=' + scaninfo.state + ', delta=' + delta);
124 } else {
125 scaninfo.present = true;
124 - if (scaninfo.state == 1) {
125 - var delta = Date.now() - scaninfo.lastpong;
126 - if (delta > PeriodicScanTimeout) { // More than 10 seconds without a response, mark the node as unknown state
127 - scaninfo.state = 0;
128 - obj.parent.ClearConnectivityState(scaninfo.nodeinfo.meshid, scaninfo.nodeinfo._id, 4); // Clear connectivity state
129 - }
126 + var delta = Date.now() - scaninfo.lastpong;
127 + //console.log('Rescan ' + host + ', state=' + scaninfo.state + ', delta=' + delta);
128 + if ((scaninfo.state == 1) && (delta >= PeriodicScanTimeout)) {
129 + // More than 2 minutes without a response, mark the node as unknown state
130 + scaninfo.state = 0;
131 + obj.parent.ClearConnectivityState(scaninfo.nodeinfo.meshid, scaninfo.nodeinfo._id, 4); // Clear connectivity state
132 + } else if ((scaninfo.tcp == null) && ((scaninfo.state == 0) || isNaN(delta) || (delta > PeriodicScanTime))) {
133 + // More than 30 seconds without a response, try TCP detection
134 + obj.checkTcpPresence(host, (doc.intelamt.tls == 1) ? 16993 : 16992, scaninfo, function (tag, result) {
135 + if (result == false) return;
136 + tag.lastpong = Date.now();
137 + if (tag.state == 0) { tag.state = 1; obj.parent.SetConnectivityState(tag.nodeinfo.meshid, tag.nodeinfo._id, tag.lastpong, 4, 7); } // Report power state as "present" (7).
138 + });
139 }
140 }
141 // Start scanning this node
@@ -146,7 +155,7 @@ module.exports.CreateAmtScanner = function (parent) {
155 return true;
156 }
157
149 - // Check the presense of a specific Intel AMT computer
158 + // Check the presense of a specific Intel AMT computer using RMCP
159 obj.checkAmtPresence = function (host, tag) {
160 var serverid = Math.floor(tag / 255);
161 var servertag = (tag % 255);
@@ -286,5 +295,20 @@ module.exports.CreateAmtScanner = function (parent) {
295 return false;
296 }
297
298 + // Check that we can connect TCP to a given port
299 + obj.checkTcpPresence = function (host, port, scaninfo, func) {
300 + //console.log('checkTcpPresence(' + host + ':' + port + ')');
301 + var client = new obj.net.Socket();
302 + client.scaninfo = scaninfo;
303 + client.func = func;
304 + client.setTimeout(10000);
305 + client.connect(port, host, function () { if (this.scaninfo.tcp != null) { delete this.scaninfo.tcp; try { this.destroy(); } catch (ex) { } this.func(this.scaninfo, true); } });
306 + client.on('data', function (data) { });
307 + client.on('close', function () { if (this.scaninfo.tcp != null) { delete this.scaninfo.tcp; try { this.destroy(); } catch (ex) { } this.func(this.scaninfo, false); } });
308 + client.on('error', function () { if (this.scaninfo.tcp != null) { delete this.scaninfo.tcp; try { this.destroy(); } catch (ex) { } this.func(this.scaninfo, false); } });
309 + client.on('timeout', function () { if (this.scaninfo.tcp != null) { delete this.scaninfo.tcp; try { this.destroy(); } catch (ex) { } this.func(this.scaninfo, false); } });
310 + scaninfo.tcp = client;
311 + }
312 +
313 return obj;
314 }
\ No newline at end of file
package.json
+1 -1
@@ -1,6 +1,6 @@
1 {
2 "name": "meshcentral",
3 - "version": "0.1.7-l",
3 + "version": "0.1.7-m",
4 "keywords": [
5 "Remote Management",
6 "Intel AMT",