-
+
+
@@ -520,9 +591,9 @@
Fetches all nodes from this OID to the end of the table.
msg.host
may contain the host.
msg.community
may contain the community.
-
msg.username
may contain the username.
-
msg.authkey
may contain the digest security key.
-
msg.privkey
may contain the encryption security key.
+
msg.username
may contain the username. (V3 only)
+
msg.authkey
may contain the digest security key. (V3 only)
+
msg.privkey
may contain the encryption security key. (V3 only)
msg.oid
may contain the oid of a table to request.
OID must be numeric. iso. is the same a 1.
The node will output msg.payload
and msg.oid
.
@@ -539,15 +610,17 @@
version: { value: "v1", required: true },
timeout: { value: 5 },
community: { value: "public" },
- username: { value: "" },
auth: { value: "noAuthNoPriv", required: true },
- authprot: { value: "None", required: true },
- privprot: { value: "None", required: true },
- authkey: { value: "" },
- privkey: { value: "" },
+ authprot: { value: "MD5", required: true },
+ privprot: { value: "DES", required: true },
oids: { value: "" },
name: { value: "" }
},
+ credentials: {
+ username: { type: "text" },
+ authkey: { type: "password" },
+ privkey: { type: "password" }
+ },
inputs: 1,
outputs: 1,
icon: "snmp.png",
@@ -556,6 +629,9 @@
},
labelStyle: function () {
return this.name ? "node_label_italic" : "";
+ },
+ oneditprepare: function () {
+ node_snmp_common.oneditprepare(this);
}
});
diff --git a/io/snmp/snmp.js b/io/snmp/snmp.js
index 29fd102e..501b4af9 100644
--- a/io/snmp/snmp.js
+++ b/io/snmp/snmp.js
@@ -1,429 +1,479 @@
module.exports = function (RED) {
"use strict";
- var snmp = require("net-snmp");
-
- var sessions = {};
-
- function openSession(host, data, options) {
- //console.log({data});
- //console.log({options});
- var sessionid = data.sessionid;
- options.port = 161;
- if (host.indexOf(":") !== -1) {
- options.port = host.split(":")[1];
- host = host.split(":")[0];
- }
- // SNMPv3 call
- if (options.version === "v3"){
- var user = {};
- options.version = snmp.Version3;
- user.name = data.name || "";
- user.level = snmp.SecurityLevel.noAuthNoPriv;
- if (data.auth === "authNoPriv" || data.auth === "authPriv" ) {
- user.level = snmp.SecurityLevel.authNoPriv;
- user.authKey = data.authkey || "";
- user.authProtocol = (data.authprot === "SHA") ? snmp.AuthProtocols.sha : snmp.AuthProtocols.md5;
- if (data.auth === "authPriv" ) {
- user.level = snmp.SecurityLevel.authPriv;
- if (data.privprot === "DES" || data.privprot === "AES"){
- user.privProtocol = (data.privprot === "AES") ? snmp.PrivProtocols.aes : snmp.PrivProtocols.des;
- user.privKey = data.privkey || "";
- }
- }
+ const SNMP = require("net-snmp");
+ const sessions = {};
+ function generateUUID() {
+ let d = Date.now();
+ let d2 = ((typeof performance !== 'undefined') && performance.now && (performance.now() * 1000)) || (Date.now() * Math.random() * 100000);//Time in microseconds since load
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+ let r = Math.random() * 16;//random number between 0 and 16
+ if (d > 0) {//Use timestamp until depleted
+ r = (d + r) % 16 | 0;
+ d = Math.floor(d / 16);
+ } else {//Use microseconds since page-load if supported
+ r = (d2 + r) % 16 | 0;
+ d2 = Math.floor(d2 / 16);
}
- sessions[sessionid] = snmp.createV3Session(host, user, options);
+ return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
+ });
+ }
+ function openSession(sessionid, host, user, options) {
+ // SNMPv3 call
+ if (options.version === SNMP.Version3) {
+ sessions[sessionid] = SNMP.createV3Session(host, user, options);
}
// SNMPv1 or SNMPv2c call
- else{
- var community = data.community;
- options.version = (options.version === "v2c") ? snmp.Version2c : snmp.Version1;
- sessions[sessionid] = snmp.createSession(host, community, options);
+ else {
+ sessions[sessionid] = SNMP.createSession(host, user.community, options);
}
return sessions[sessionid];
}
// Any session needs to be closed after completion
function closeSession(sessionid) {
- //console.log("closing session");
- sessions[sessionid].close();
+ try {
+ sessions[sessionid].removeAllListeners();
+ } catch (e) { }
+ try {
+ sessions[sessionid].close();
+ } catch (e) { }
+ delete sessions[sessionid];
}
- function SnmpNode(n) {
- RED.nodes.createNode(this, n);
- this.community = n.community;
- this.host = n.host;
- this.version = n.version;
- this.username = n.username;
- this.auth = n.auth;
- this.authprot = n.authprot;
- this.privprot = n.privprot;
- this.authkey = n.authkey;
- this.privkey = n.privkey;
- this.oids = n.oids.replace(/\s/g, "");
- this.timeout = Number(n.timeout || 5) * 1000;
- var node = this;
+ function initSnmpNode(node, config) {
+ node.community = config.community;
+ node.host = config.host;
+ node.version = config.version;
+ node.auth = config.auth;
+ node.authprot = config.authprot;
+ node.privprot = config.privprot;
+ if (node.credentials) {
+ node.username = node.credentials.username;
+ node.authkey = node.credentials.authkey;
+ node.privkey = node.credentials.privkey;
+ }
+ node.timeout = Number(config.timeout || 5) * 1000;
+ }
- this.on("input", function (msg) {
- var host = node.host || msg.host;
- var version = node.version;
- var community = node.community || msg.community;
- var username = node.username || msg.username;
- var auth = node.auth;
- var authprot = node.authprot;
- var privprot = node.privprot;
- var authkey = node.authkey || msg.authkey;
- var privkey = node.privkey || msg.privkey;
- var oids = node.oids || msg.oid;
- var sessionid = Date.now(); // Create an unique session ID for each call
- var data = {};
- data.community = community;
- data.name = username;
- data.auth = auth;
- data.authprot = authprot;
- data.privprot = privprot;
- data.authkey = authkey;
- data.privkey = privkey;
- data.sessionid = sessionid;
- var options = {};
- options.version = version;
- options.timeout = node.timeout;
+ function prepareSnmpOptions(node, msg) {
+ let host = node.host || msg.host;
+ const sessionid = generateUUID();
+ const user = {}
+ const options = {};
+
+ options.version = node.version;
+ if (node.version === "v1") {
+ options.version = SNMP.Version1;
+ user.community = node.community || msg.community;
+ } else if (node.version === "v2c") {
+ options.version = SNMP.Version2c;
+ user.community = node.community || msg.community;
+ } else if (node.version === "v3") {
+ user.name = node.username || msg.username || "";
+ user.level = SNMP.SecurityLevel.noAuthNoPriv;
+ user.authProtocol = SNMP.AuthProtocols.none;
+ user.authKey = "";
+ user.privProtocol = SNMP.PrivProtocols.none;
+ user.privKey = "";
+ options.version = SNMP.Version3;
+ if (node.auth === "authNoPriv" || node.auth === "authPriv") {
+ user.level = SNMP.SecurityLevel.authNoPriv;
+ user.authProtocol = (node.authprot === "SHA") ? SNMP.AuthProtocols.sha : SNMP.AuthProtocols.md5;
+ user.authKey = node.authkey || msg.authkey || "";
+ if (node.auth === "authPriv") {
+ user.level = SNMP.SecurityLevel.authPriv;
+ if (node.privprot === "DES" || node.privprot === "AES") {
+ user.privProtocol = (node.privprot === "AES") ? SNMP.PrivProtocols.aes : SNMP.PrivProtocols.des;
+ user.privKey = node.privkey || msg.privkey || "";
+ }
+ }
+ }
+ }
+
+ options.timeout = node.timeout;
+ options.debug = msg.debug || undefined;
+ options.port = options.port || 161;
+ options.retries = options.retries || 1;
+
+ if (msg.engineID) {
+ options.engineID = msg.engineID;//The engineID used for SNMPv3 communications, given as a hex string - defaults to a system-generated engineID containing elements of random
+ }
+ if (msg.backoff) {
+ options.backoff = msg.backoff;//The factor by which to increase the timeout for every retry, defaults to 1 for no increase
+ }
+ if (msg.backwardsGetNexts) {
+ options.backwardsGetNexts = msg.backwardsGetNexts;//boolean to allow GetNext operations to retrieve lexicographically preceding OIDs
+ }
+ if (msg.idBitsSize === 16 || msg.idBitsSize === 32) {
+ options.idBitsSize = msg.idBitsSize;//Either 16 or 32, defaults to 32. Used to reduce the size of the generated id for compatibility with some older devices.
+ }
+ const ipv = parseIP(host);
+ if (ipv.version === 4) {
+ host = ipv.ip;
+ options.port = ipv.port || options.port;
+ options.transport = 'udp4';
+ } else if (ipv.version === 6) {
+ host = ipv.ip;
+ options.port = ipv.port || options.port;
+ options.transport = 'udp6';
+ } else {
+ //probably a host name
+ if (host.indexOf(":") > 0) {
+ host = host.split(":")[0];
+ options.port = host.split(":")[1];
+ }
+ }
+ return {
+ host: host,
+ sessionid: sessionid,
+ user: user,
+ options: options,
+ }
+ }
+ function parseIP(ip) {
+ const IPV4_PAT = /^(\d+)\.(\d+)\.(\d+)\.(\d+)(?::(\d+)){0,1}$/g;
+ const IPV6_DOUBLE_COL_PAT = /^\[{0,1}([0-9a-f:]*)::([0-9a-f:]*)(?:\]:(\d+)){0,1}$/g;
+ const ipv4Matcher = IPV4_PAT.exec(ip);
+ let hex = "";
+ let port = undefined;
+ let ipOnly = [];
+ try {
+
+ if (ipv4Matcher && ipv4Matcher.length) {
+ for (let i = 1; i <= 4; i++) {
+ ipOnly.push(ipv4Matcher[i]);
+ hex += toHex4(ipv4Matcher[i]);
+ }
+ if (ipv4Matcher[5]) {
+ port = parseInt(ipv4Matcher[5]);
+ }
+ return { ip: ipOnly.join("."), hex, port, version: 4 };
+ }
+
+ // IPV6 Must be colons format (a:b:c:d:e:A.B.C.D not currently supported)
+ let ipv6Pattern = "^\\[{0,1}";
+ for (let i = 1; i <= 7; i++) {
+ ipv6Pattern += "([0-9a-f]+):";
+ }
+ ipv6Pattern += "([0-9a-f]+)(?:\\]:(\\d+)){0,1}$";
+ const IPV6_PAT = new RegExp(ipv6Pattern);
+
+
+ // IPV6, double colon
+ const ipv6DoubleColonMatcher = IPV6_DOUBLE_COL_PAT.exec(ip);
+ if (ipv6DoubleColonMatcher && ipv6DoubleColonMatcher.length) {
+ let p1 = ipv6DoubleColonMatcher[1];
+ if (!p1) {
+ p1 = "0";
+ }
+ let p2 = ipv6DoubleColonMatcher[2];
+ if (!p2) {
+ p2 = "0";
+ }
+ p1 = p1.padStart(4, "0");
+ p2 = p2.padStart(4, "0");
+ ip = p1 + getZeros(8 - numCount(p1) - numCount(p2)) + p2;
+ if (ipv6DoubleColonMatcher[3]) {
+ ip = "[" + ip + "]:" + ipv6DoubleColonMatcher[3];
+ }
+ }
+
+ // IPV6
+ const ipv6Matcher = IPV6_PAT.exec(ip);
+ if (ipv6Matcher && ipv6Matcher.length) {
+ for (let i = 1; i <= 8; i++) {
+ const p = toHex6(ipv6Matcher[i]).padStart(4, "0");
+ ipOnly.push(p);
+ hex += p;
+ }
+ if (ipv6Matcher[9]) {
+ port = parseInt(ipv6Matcher[9]);
+ }
+ return { ip: ipOnly.join(":"), hex, port, version: 6 };
+ }
+
+ throw new Error("Unknown address: " + ip);
+ } catch (error) {
+ return { ip, hex, port, version: null, error: error };
+ }
+
+ function numCount(/** @type {string} */s) {
+ return s.split(":").length;
+ }
+ function getZeros(/** @type {number} */ count) {
+ const sb = [":"];
+ while (count > 0) {
+ sb.push("0000:");
+ count--;
+ }
+ return sb.join("");
+ }
+ function toHex4(/** @type {string} */ s) {
+ const val = parseInt(s);
+ if (val < 0 || val > 255) {
+ throw new Error("Invalid value : " + s);
+ }
+ return val.toString(16).padStart(2, "0");
+ }
+ function toHex6(/** @type {string} */ s) {
+ const val = parseInt(s, 16);
+ if (val < 0 || val > 65536) {
+ throw new Error("Invalid hex value : " + s);
+ }
+ return s;
+ }
+ }
+ function SnmpNode(n) {
+ const node = this;
+ RED.nodes.createNode(node, n);
+ initSnmpNode(node, n);
+ node.oids = n.oids ? n.oids.replace(/\s/g, "") : "";
+
+ node.on("input", function (msg) {
+ const oids = node.oids || msg.oid;
+ const { host, sessionid, user, options } = prepareSnmpOptions(node, msg);
if (oids) {
- openSession(host, data, options).get(oids.split(","), function (error, varbinds) {
+ let sess = openSession(sessionid, host, user, options);
+ sess.on("error", function (err) {
+ node.error(err, msg);
+ })
+ sess.get(oids.split(","), function (error, varbinds) {
if (error) {
node.error(error.toString(), msg);
- }
- else {
- for (var i = 0; i < varbinds.length; i++) {
- if (snmp.isVarbindError(varbinds[i])) {
- node.error(snmp.varbindError(varbinds[i]), msg);
+ } else {
+ for (let i = 0; i < varbinds.length; i++) {
+ let vb = varbinds[i];
+ if (SNMP.isVarbindError(vb)) {
+ node.error(SNMP.varbindError(vb), msg);
+ vb._error = SNMP.varbindError(vb); //add _error to msg so users can determine the varbind is not valid
}
else {
- if (varbinds[i].type == 4) { varbinds[i].value = varbinds[i].value.toString(); }
- varbinds[i].tstr = snmp.ObjectType[varbinds[i].type];
- // node.log(varbinds[i].oid + "|" + varbinds[i].tstr + "|" + varbinds[i].value);
+ if (vb.type == 4) { vb.value = vb.value.toString(); }
}
+ vb.tstr = SNMP.ObjectType[vb.type];
}
- msg.oid = oids;
msg.payload = varbinds;
+ msg.oid = oids;
node.send(msg);
}
closeSession(sessionid); // Needed to close the session else a bad or good read could affect future readings
});
- }
- else {
+ } else {
node.warn("No oid(s) to search for");
}
});
}
- RED.nodes.registerType("snmp", SnmpNode);
+ RED.nodes.registerType("snmp", SnmpNode, {
+ credentials: {
+ username: { type: "text" },
+ authkey: { type: "password" },
+ privkey: { type: "password" }
+ }
+ });
function SnmpSNode(n) {
- RED.nodes.createNode(this, n);
- this.community = n.community;
- this.host = n.host;
- this.version = n.version;
- this.username = n.username;
- this.auth = n.auth;
- this.authprot = n.authprot;
- this.privprot = n.privprot;
- this.authkey = n.authkey;
- this.privkey = n.privkey;
- this.timeout = Number(n.timeout || 5) * 1000;
- this.varbinds = n.varbinds;
- if (this.varbinds && this.varbinds.trim().length === 0) { delete this.varbinds; }
- var node = this;
- this.on("input", function (msg) {
- var host = node.host || msg.host;
- var version = node.version;
- var community = node.community || msg.community;
- var username = node.username || msg.username;
- var auth = node.auth;
- var authprot = node.authprot;
- var privprot = node.privprot;
- var authkey = node.authkey || msg.authkey;
- var privkey = node.privkey || msg.privkey;
- var sessionid = Date.now();
- var data = {};
- data.community = community;
- data.name = username;
- data.auth = auth;
- data.authprot = authprot;
- data.privprot = privprot;
- data.authkey = authkey;
- data.privkey = privkey;
- data.sessionid = sessionid;
- var options = {};
- options.version = version;
- options.timeout = node.timeout;
- var varbinds = (node.varbinds) ? JSON.parse(node.varbinds) : msg.varbinds;
+ const node = this;
+ RED.nodes.createNode(node, n);
+ initSnmpNode(node, n);
+ node.varbinds = n.varbinds;
+ if (node.varbinds && node.varbinds.trim().length === 0) { delete node.varbinds; }
+ node.on("input", function (msg) {
+ const { host, sessionid, user, options } = prepareSnmpOptions(node, msg);
+ const varbinds = (node.varbinds) ? JSON.parse(node.varbinds) : msg.varbinds;
if (varbinds) {
- for (var i = 0; i < varbinds.length; i++) {
- varbinds[i].type = snmp.ObjectType[varbinds[i].type];
+ for (let i = 0; i < varbinds.length; i++) {
+ varbinds[i].type = SNMP.ObjectType[varbinds[i].type];
}
- openSession(host, data, options).set(varbinds, function (error, varbinds) {
+ let sess = openSession(sessionid, host, user, options);
+ sess.on("error", function (err) {
+ node.error(err, msg);
+ })
+ sess.set(varbinds, function (error, varbinds) {
if (error) {
node.error(error.toString(), msg);
- }
- else {
- for (var i = 0; i < varbinds.length; i++) {
+ } else {
+ for (let i = 0; i < varbinds.length; i++) {
// for version 2c we must check each OID for an error condition
- if (snmp.isVarbindError(varbinds[i])) {
- node.error(snmp.varbindError(varbinds[i]), msg);
+ if (SNMP.isVarbindError(varbinds[i])) {
+ node.error(SNMP.varbindError(varbinds[i]), msg);
}
}
}
closeSession(sessionid);
});
- }
- else {
+ } else {
node.warn("No varbinds to set");
}
});
}
- RED.nodes.registerType("snmp set", SnmpSNode);
+ RED.nodes.registerType("snmp set", SnmpSNode, {
+ credentials: {
+ username: { type: "text" },
+ authkey: { type: "password" },
+ privkey: { type: "password" }
+ }
+ });
function SnmpTNode(n) {
- RED.nodes.createNode(this, n);
- this.community = n.community;
- this.host = n.host;
- this.version = n.version;
- this.username = n.username;
- this.auth = n.auth;
- this.authprot = n.authprot;
- this.privprot = n.privprot;
- this.authkey = n.authkey;
- this.privkey = n.privkey;
- this.oids = n.oids.replace(/\s/g, "");
- this.timeout = Number(n.timeout || 5) * 1000;
- var node = this;
- var maxRepetitions = 20;
+ const node = this;
+ RED.nodes.createNode(node, n);
+ initSnmpNode(node, n);
+ node.oids = n.oids ? n.oids.replace(/\s/g, "") : ""
+ const maxRepetitions = 20;
function sortInt(a, b) {
if (a > b) { return 1; }
- else if (b > a) { return -1; }
- else { return 0; }
+ else if (b > a) { return -1; } else { return 0; }
}
- this.on("input", function (msg) {
- var host = node.host || msg.host;
- var version = node.version;
- var community = node.community || msg.community;
- var username = node.username || msg.username;
- var auth = node.auth;
- var authprot = node.authprot;
- var privprot = node.privprot;
- var authkey = node.authkey || msg.authkey;
- var privkey = node.privkey || msg.privkey;
- var oids = node.oids || msg.oid;
- var sessionid = Date.now();
- var data = {};
- data.community = community;
- data.name = username;
- data.auth = auth;
- data.authprot = authprot;
- data.privprot = privprot;
- data.authkey = authkey;
- data.privkey = privkey;
- data.sessionid = sessionid;
- var options = {};
- options.version = version;
- options.timeout = node.timeout;
- node.log({options});
+ node.on("input", function (msg) {
+ const oids = node.oids || msg.oid;
+ const { host, sessionid, user, options } = prepareSnmpOptions(node, msg);
if (oids) {
msg.oid = oids;
- openSession(host, data, options).table(oids, maxRepetitions, function (error, table) {
+ let sess = openSession(sessionid, host, user, options);
+ sess.on("error", function (err) {
+ node.error(err, msg);
+ })
+ sess.table(oids, maxRepetitions, function (error, table) {
if (error) {
node.error(error.toString(), msg);
- }
- else {
- var indexes = [];
- for (var index in table) {
+ } else {
+ const indexes = [];
+ for (let index in table) {
if (table.hasOwnProperty(index)) {
indexes.push(parseInt(index));
}
}
indexes.sort(sortInt);
- for (var i = 0; i < indexes.length; i++) {
- var columns = [];
- for (var column in table[indexes[i]]) {
+ for (let i = 0; i < indexes.length; i++) {
+ const columns = [];
+ for (let column in table[indexes[i]]) {
if (table[indexes[i]].hasOwnProperty(column)) {
columns.push(parseInt(column));
}
}
columns.sort(sortInt);
- // console.log("row index = " + indexes[i]);
- // for (var j = 0; j < columns.length; j++) {
- // console.log(" column " + columns[j] + " = " + table[indexes[i]][columns[j]]);
- // }
}
msg.payload = table;
node.send(msg);
}
closeSession(sessionid);
});
- }
- else {
+ } else {
node.warn("No oid to search for");
}
});
}
- RED.nodes.registerType("snmp table", SnmpTNode);
+ RED.nodes.registerType("snmp table", SnmpTNode, {
+ credentials: {
+ username: { type: "text" },
+ authkey: { type: "password" },
+ privkey: { type: "password" }
+ }
+ });
function SnmpSubtreeNode(n) {
- RED.nodes.createNode(this, n);
- this.community = n.community;
- this.host = n.host;
- this.version = n.version;
- this.username = n.username;
- this.auth = n.auth;
- this.authprot = n.authprot;
- this.privprot = n.privprot;
- this.authkey = n.authkey;
- this.privkey = n.privkey;
- this.oids = n.oids.replace(/\s/g, "");
- this.timeout = Number(n.timeout || 5) * 1000;
- var node = this;
- var maxRepetitions = 20;
- var response = [];
+ const node = this;
+ RED.nodes.createNode(node, n);
+ initSnmpNode(node, n);
+ node.oids = n.oids ? n.oids.replace(/\s/g, "") : ""
+ const maxRepetitions = 20;
- function feedCb(varbinds) {
- for (var i = 0; i < varbinds.length; i++) {
- if (snmp.isVarbindError(varbinds[i])) {
- node.error(snmp.varbindError(varbinds[i]), msg);
- }
- else {
- //console.log(varbinds[i].oid + "|" + varbinds[i].value);
- response.push({ oid: varbinds[i].oid, value: varbinds[i].value });
- }
- }
- }
-
- this.on("input", function (msg) {
- var host = node.host || msg.host;
- var version = node.version;
- var community = node.community || msg.community;
- var username = node.username || msg.username;
- var auth = node.auth;
- var authprot = node.authprot;
- var privprot = node.privprot;
- var authkey = node.authkey || msg.authkey;
- var privkey = node.privkey || msg.privkey;
- var oids = node.oids || msg.oid;
- var sessionid = Date.now();
- var data = {};
- data.community = community;
- data.name = username;
- data.auth = auth;
- data.authprot = authprot;
- data.privprot = privprot;
- data.authkey = authkey;
- data.privkey = privkey;
- data.sessionid = sessionid;
- var options = {};
- options.version = version;
- options.timeout = node.timeout;
+ node.on("input", function (msg) {
+ const oids = node.oids || msg.oid;
+ const { host, sessionid, user, options } = prepareSnmpOptions(node, msg);
if (oids) {
msg.oid = oids;
- openSession(host, data, options).subtree(msg.oid, maxRepetitions, feedCb, function (error) {
+ let sess = openSession(sessionid, host, user, options);
+ sess.on("error", function (err) {
+ node.error(err, msg);
+ })
+ //move response array & feedCb to inside `node.on("input",` to avoid subsequent
+ // calls overwriting results from previous operations (each call gets own result/response)
+ const response = [];
+ function feedCb(varbinds) {
+ for (let i = 0; i < varbinds.length; i++) {
+ if (SNMP.isVarbindError(varbinds[i])) {
+ node.error(SNMP.varbindError(varbinds[i]), msg);
+ } else {
+ response.push({ oid: varbinds[i].oid, value: varbinds[i].value });
+ }
+ }
+ }
+ sess.subtree(msg.oid, maxRepetitions, feedCb, function (error) {
if (error) {
node.error(error.toString(), msg);
- }
- else {
- // Clone the array
- msg.payload = response.slice(0);
+ } else {
+ msg.payload = response;
node.send(msg);
- //Clears response
- response.length = 0;
}
closeSession(sessionid);
});
- }
- else {
+ } else {
node.warn("No oid to search for");
}
});
}
- RED.nodes.registerType("snmp subtree", SnmpSubtreeNode);
-
+ RED.nodes.registerType("snmp subtree", SnmpSubtreeNode, {
+ credentials: {
+ username: { type: "text" },
+ authkey: { type: "password" },
+ privkey: { type: "password" }
+ }
+ });
function SnmpWalkerNode(n) {
- RED.nodes.createNode(this, n);
- this.community = n.community;
- this.host = n.host;
- this.version = n.version;
- this.username = n.username;
- this.auth = n.auth;
- this.authprot = n.authprot;
- this.privprot = n.privprot;
- this.authkey = n.authkey;
- this.privkey = n.privkey;
- this.oids = n.oids.replace(/\s/g, "");
- this.timeout = Number(n.timeout || 5) * 1000;
- var node = this;
- var maxRepetitions = 20;
- var response = [];
+ const node = this;
+ RED.nodes.createNode(node, n);
+ initSnmpNode(node, n);
+ node.oids = n.oids ? n.oids.replace(/\s/g, "") : ""
+ const maxRepetitions = 20;
- function feedCb(varbinds) {
- for (var i = 0; i < varbinds.length; i++) {
- if (snmp.isVarbindError(varbinds[i])) {
- node.error(snmp.varbindError(varbinds[i]), msg);
- }
- else {
- //console.log(varbinds[i].oid + "|" + varbinds[i].value);
- response.push({ oid: varbinds[i].oid, value: varbinds[i].value });
- }
- }
- }
-
- this.on("input", function (msg) {
- node.msg = msg;
- var host = node.host || msg.host;
- var version = node.version;
- var community = node.community || msg.community;
- var username = node.username || msg.username;
- var auth = node.auth;
- var authprot = node.authprot;
- var privprot = node.privprot;
- var authkey = node.authkey || msg.authkey;
- var privkey = node.privkey || msg.privkey;
- var oids = node.oids || msg.oid;
- var sessionid = Date.now();
- var data = {};
- data.community = community;
- data.name = username;
- data.auth = auth;
- data.authprot = authprot;
- data.privprot = privprot;
- data.authkey = authkey;
- data.privkey = privkey;
- data.sessionid = sessionid;
- var options = {};
- options.version = version;
- options.timeout = node.timeout;
+ node.on("input", function (msg) {
+ const oids = node.oids || msg.oid;
+ const { host, sessionid, user, options } = prepareSnmpOptions(node, msg);
if (oids) {
msg.oid = oids;
- openSession(host, data, options).walk(msg.oid, maxRepetitions, feedCb, function (error) {
+ let sess = openSession(sessionid, host, user, options);
+ sess.on("error", function (err) {
+ node.error(err, msg);
+ })
+ //move response array & feedCb to inside `node.on("input",` to avoid subsequent
+ // calls overwriting results from previous operations (each call gets own result/response)
+ const response = [];
+ function feedCb(varbinds) {
+ for (let i = 0; i < varbinds.length; i++) {
+ if (SNMP.isVarbindError(varbinds[i])) {
+ node.error(SNMP.varbindError(varbinds[i]), msg);
+ } else {
+ response.push({ oid: varbinds[i].oid, value: varbinds[i].value });
+ }
+ }
+ }
+ sess.walk(msg.oid, maxRepetitions, feedCb, function (error) {
if (error) {
node.error(error.toString(), msg);
- }
- else {
- // Clone the array
- msg.payload = response.slice(0);
+ } else {
+ msg.payload = response;
node.send(msg);
- //Clears response
- response.length = 0;
}
closeSession(sessionid);
});
- }
- else {
+ } else {
node.warn("No oid to search for");
}
});
}
- RED.nodes.registerType("snmp walker", SnmpWalkerNode);
+ RED.nodes.registerType("snmp walker", SnmpWalkerNode, {
+ credentials: {
+ username: { type: "text" },
+ authkey: { type: "password" },
+ privkey: { type: "password" }
+ }
+ });
};