Add SNMPv3 support and update to latest deps

closes #705
This commit is contained in:
Steve-Mcl 2022-04-21 16:49:03 +01:00
parent 4b99a5f4d1
commit a7762ea91b
3 changed files with 572 additions and 445 deletions

View File

@ -1,9 +1,9 @@
{
"name" : "node-red-node-snmp",
"version" : "0.0.26",
"version" : "0.1.0",
"description" : "A Node-RED node that looks for SNMP oids.",
"dependencies" : {
"net-snmp" : "2.9.6"
"net-snmp" : "3.6.2"
},
"repository" : {
"type":"git",
@ -24,6 +24,7 @@
"contributors": [
{ "name": "Mika Karaila" },
{ "name": "Bryan Malyn" },
{ "name": "Steve-Mcl" },
{ "name": "Andres" }
]
}

View File

@ -1,3 +1,47 @@
<style id="node-red-node-snmp-common-style">
.form-row.form-row-snmpv1v2.hidden {
display: none !important;
}
.form-row.form-row-snmpv3.hidden {
display: none !important;
}
.form-row.form-row-snmpv3-auth.hidden {
display: none;
}
</style>
<script type="text/javascript" id="node-red-node-snmp-common-script">
const node_snmp_common = {
oneditprepare: function (node) {
$("#node-input-version").on("change", function(evt) {
const isV3 = $("#node-input-version").val() === "v3";
$(".form-row-snmpv1v2").toggleClass("hidden", isV3);
$(".form-row-snmpv3").toggleClass("hidden", !isV3);
$("#node-input-auth").trigger("change");
});
$("#node-input-auth").on("change", function(evt) {
const isV3 = $("#node-input-version").val() === "v3";
const auth = $("#node-input-auth").val();
if(isV3) {
switch (auth) {
case "authNoPriv":
$(".form-row-snmpv3-auth").toggleClass("hidden", false);
$(".form-row-snmpv3-priv").toggleClass("hidden", true);
break;
case "authPriv":
$(".form-row-snmpv3-auth").toggleClass("hidden", false);
$(".form-row-snmpv3-priv").toggleClass("hidden", false);
break;
default: //"noAuthNoPriv":
$(".form-row-snmpv3-auth").toggleClass("hidden", true);
$(".form-row-snmpv3-priv").toggleClass("hidden", true);
break;
}
}
});
$("#node-input-version").trigger("change");
}
}
</script>
<script type="text/html" data-template-name="snmp">
<div class="form-row">
<label for="node-input-host"><i class="fa fa-globe"></i> Host</label>
@ -13,43 +57,43 @@
<span style="margin-left:50px;">Timeout</span>
<input type="text" id="node-input-timeout" placeholder="secs" style="width:50px; direction:rtl; vertical-align:baseline;">&nbsp;S
</div>
<div class="form-row">
<div class="form-row form-row-snmpv1v2">
<label for="node-input-community"><i class="fa fa-user"></i> Community</label>
<input type="text" id="node-input-community" placeholder="public">
</div>
<!-- Following Data is used for V3 Only -->
<div class="form-row">
<div class="form-row form-row-snmpv3">
<label for="node-input-username"><i class="fa fa-user"></i> Username</label>
<input type="text" id="node-input-username" placeholder="username">
</div>
<div class="form-row">
<label for="node-input-auth"><i class="fa fa-user-secret"></i> Auth. </label>
<div class="form-row form-row-snmpv3">
<label for="node-input-auth"><i class="fa fa-user-secret"></i> Auth.</label>
<select type="text" id="node-input-auth" style="width:150px;">
<option value="noAuthNoPriv">noAuthNoPriv</option>
<option value="authNoPriv">authNoPriv</option>
<option value="authPriv">authPriv</option>
</select>
</div>
<div class="form-row">
<label for="node-input-authprot"><i class="fa fa-user-secret"></i> Auth.Prot. </label>
<div class="form-row form-row-snmpv3 form-row-snmpv3-auth">
<label for="node-input-authprot"><i class="fa fa-shield"></i> Auth.Prot.</label>
<select type="text" id="node-input-authprot" style="width:150px;">
<option value="None">None</option>
<option value="MD5">MD5</option>
<option value="SHA">SHA</option>
</select>
<span style="margin-left:50px;">Priv.Prot.</span>
</div>
<div class="form-row form-row-snmpv3 form-row-snmpv3-auth">
<label for="node-input-authkey"><i class="fa fa-key"></i> Auth.Key</label>
<input type="password" id="node-input-authkey" placeholder="Authentication key">
</div>
<div class="form-row form-row-snmpv3 form-row-snmpv3-priv">
<label for="node-input-privprot"><i class="fa fa-shield"></i> Priv.Prot.</label>
<select type="text" id="node-input-privprot" style="width:150px;">
<option value="None">None</option>
<option value="DES">DES</option>
<option value="AES">AES</option>
</select>
</div>
<div class="form-row">
<label for="node-input-authkey"><i class="fa fa-user"></i> Auth.Key</label>
<input type="password" id="node-input-authkey" placeholder="Authentication key">
</div>
<div class="form-row">
<label for="node-input-privkey"><i class="fa fa-user"></i> Priv.Key</label>
<div class="form-row form-row-snmpv3 form-row-snmpv3-priv">
<label for="node-input-privkey"><i class="fa fa-key"></i> Priv.Key</label>
<input type="password" id="node-input-privkey" placeholder="Encryption key">
</div>
<!-- End of unique data for V3 -->
@ -68,9 +112,9 @@
<p>Simple SNMP oid or oid list fetcher. Triggered by any input.</p>
<p><code>msg.host</code> may contain the host.</p>
<p><code>msg.community</code> may contain the community.</p>
<p><code>msg.username</code> may contain the username.</p>
<p><code>msg.authkey</code> may contain the digest security key.</p>
<p><code>msg.privkey</code> may contain the encryption security key.</p>
<p><code>msg.username</code> may contain the username. (V3 only)</p>
<p><code>msg.authkey</code> may contain the digest security key. (V3 only)</p>
<p><code>msg.privkey</code> may contain the encryption security key. (V3 only)</p>
<p><code>msg.oid</code> may contain a comma separated list of oids to request. (no spaces)</p>
<p>OIDs must be numeric. iso. is the same a 1. </p>
<p>The node will output <code>msg.payload</code> and <code>msg.oid</code>.</p>
@ -85,14 +129,16 @@
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: "" }
name: { value: "" },
},
credentials: {
username: { type: "text" },
authkey: { type: "password" },
privkey: { type: "password" }
},
inputs: 1,
outputs: 1,
@ -102,6 +148,9 @@
},
labelStyle: function () {
return this.name ? "node_label_italic" : "";
},
oneditprepare: function () {
node_snmp_common.oneditprepare(this);
}
});
</script>
@ -123,49 +172,49 @@
<span style="margin-left:50px;">Timeout</span>
<input type="text" id="node-input-timeout" placeholder="secs" style="width:50px; direction:rtl; vertical-align:baseline;">&nbsp;S
</div>
<div class="form-row">
<div class="form-row form-row-snmpv1v2">
<label for="node-input-community"><i class="fa fa-user"></i> Community</label>
<input type="text" id="node-input-community" placeholder="public">
</div>
<!-- Following Data is used for V3 Only -->
<div class="form-row">
<div class="form-row form-row-snmpv3">
<label for="node-input-username"><i class="fa fa-user"></i> Username</label>
<input type="text" id="node-input-username" placeholder="username">
</div>
<div class="form-row">
<label for="node-input-auth"><i class="fa fa-user-secret"></i> Auth. </label>
<div class="form-row form-row-snmpv3">
<label for="node-input-auth"><i class="fa fa-user-secret"></i> Auth.</label>
<select type="text" id="node-input-auth" style="width:150px;">
<option value="noAuthNoPriv">noAuthNoPriv</option>
<option value="authNoPriv">authNoPriv</option>
<option value="authPriv">authPriv</option>
</select>
</div>
<div class="form-row">
<label for="node-input-authprot"><i class="fa fa-user-secret"></i> Auth.Prot. </label>
<div class="form-row form-row-snmpv3 form-row-snmpv3-auth">
<label for="node-input-authprot"><i class="fa fa-shield"></i> Auth.Prot.</label>
<select type="text" id="node-input-authprot" style="width:150px;">
<option value="None">None</option>
<option value="MD5">MD5</option>
<option value="SHA">SHA</option>
</select>
<span style="margin-left:50px;">Priv.Prot.</span>
</div>
<div class="form-row form-row-snmpv3 form-row-snmpv3-auth">
<label for="node-input-authkey"><i class="fa fa-key"></i> Auth.Key</label>
<input type="password" id="node-input-authkey" placeholder="Authentication key">
</div>
<div class="form-row form-row-snmpv3 form-row-snmpv3-priv">
<label for="node-input-privprot"><i class="fa fa-shield"></i> Priv.Prot.</label>
<select type="text" id="node-input-privprot" style="width:150px;">
<option value="None">None</option>
<option value="DES">DES</option>
<option value="AES">AES</option>
</select>
</div>
<div class="form-row">
<label for="node-input-authkey"><i class="fa fa-user"></i> Auth.Key</label>
<input type="password" id="node-input-authkey" placeholder="Authentication key">
</div>
<div class="form-row">
<label for="node-input-privkey"><i class="fa fa-user"></i> Priv.Key</label>
<div class="form-row form-row-snmpv3 form-row-snmpv3-priv">
<label for="node-input-privkey"><i class="fa fa-key"></i> Priv.Key</label>
<input type="password" id="node-input-privkey" placeholder="Encryption key">
</div>
<!-- End of unique data for V3 -->
<div class="form-row">
<label for="node-input-varbinds"><i class="fa fa-tags"></i> Varbinds</label>
<textarea rows="10" cols="60" id="node-input-varbinds" placeholder="e.g. [ { &quot;oid&quot;: &quot;1.3.6.1.2.1.1.5.0&quot;,&quot;type&quot;: &quot;OctetString&quot;,&quot;value&quot;: &quot;host1&quot;},{&quot;oid&quot;: &quot;1.3.6.1.2.1.1.6.0&quot;,&quot;type&quot;: &quot;OctetString&quot;,value: &quot;somewhere&quot;}]"
<textarea rows="10" cols="60" id="node-input-varbinds" placeholder="e.g. [ { &quot;oid&quot;: &quot;1.3.6.1.2.1.1.5.0&quot;, &quot;type&quot;: &quot;OctetString&quot;, &quot;value&quot;: &quot;host1&quot;}, { &quot;oid&quot;: &quot;1.3.6.1.2.1.1.6.0&quot;, &quot;type&quot;: &quot;OctetString&quot;, value: &quot;somewhere&quot; } ]"
style="width:70%;"></textarea>
</div>
<div class="form-row">
@ -179,18 +228,18 @@
<p>Simple snmp Set node. Trigger by any input</p>
<p><code>msg.host</code> may contain the host.</p>
<p><code>msg.community</code> may contain the community.</p>
<p><code>msg.username</code> may contain the username.</p>
<p><code>msg.authkey</code> may contain the digest security key.</p>
<p><code>msg.privkey</code> may contain the encryption security key.</p>
<p><code>msg.username</code> may contain the username. (V3 only)</p>
<p><code>msg.authkey</code> may contain the digest security key. (V3 only)</p>
<p><code>msg.privkey</code> may contain the encryption security key. (V3 only)</p>
<p><code>msg.varbinds</code> may contain varbinds as an array of json objects containing multiple oids, types and values.
<pre>[
{
"oid": "1.3.6.1.2.1.1.5.0",
"type": "OctetString",
"value": "host1"
},
{ "oid": ... }
]</pre>
<code style="font-size: smaller;"><pre style="white-space: pre;">[
{
"oid": "1.3.6.1.2.1.1.5.0",
"type": "OctetString",
"value": "host1"
},
{ "oid": ... }
]</pre></code>
<p>Any numeric inputs must be numbers, not strings, e.g. 1 not "1".</p>
<p>OIDs must be numeric. iso. is the same a 1.</p>
</p>
@ -205,15 +254,24 @@
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: "" },
varbinds: { value: "" },
authprot: { value: "MD5", required: true },
privprot: { value: "DES", required: true },
oids: { value: "" },
varbinds: { value: "", validate:function(v) {
try {
return !v || !!JSON.parse(v);
} catch(e) {
return false;
}
}},
name: { value: "" }
},
credentials: {
username: { type: "text" },
authkey: { type: "password" },
privkey: { type: "password" }
},
inputs: 1,
outputs: 0,
icon: "snmp.png",
@ -222,6 +280,9 @@
},
labelStyle: function () {
return this.name ? "node_label_italic" : "";
},
oneditprepare: function () {
node_snmp_common.oneditprepare(this);
}
});
</script>
@ -243,43 +304,43 @@
<span style="margin-left:50px;">Timeout</span>
<input type="text" id="node-input-timeout" placeholder="secs" style="width:50px; direction:rtl; vertical-align:baseline;">&nbsp;S
</div>
<div class="form-row">
<div class="form-row form-row-snmpv1v2">
<label for="node-input-community"><i class="fa fa-user"></i> Community</label>
<input type="text" id="node-input-community" placeholder="public">
</div>
<!-- Following Data is used for V3 Only -->
<div class="form-row">
<div class="form-row form-row-snmpv3">
<label for="node-input-username"><i class="fa fa-user"></i> Username</label>
<input type="text" id="node-input-username" placeholder="username">
</div>
<div class="form-row">
<label for="node-input-auth"><i class="fa fa-user-secret"></i> Auth. </label>
<div class="form-row form-row-snmpv3">
<label for="node-input-auth"><i class="fa fa-user-secret"></i> Auth.</label>
<select type="text" id="node-input-auth" style="width:150px;">
<option value="noAuthNoPriv">noAuthNoPriv</option>
<option value="authNoPriv">authNoPriv</option>
<option value="authPriv">authPriv</option>
</select>
</div>
<div class="form-row">
<label for="node-input-authprot"><i class="fa fa-user-secret"></i> Auth.Prot. </label>
<div class="form-row form-row-snmpv3 form-row-snmpv3-auth">
<label for="node-input-authprot"><i class="fa fa-shield"></i> Auth.Prot.</label>
<select type="text" id="node-input-authprot" style="width:150px;">
<option value="None">None</option>
<option value="MD5">MD5</option>
<option value="SHA">SHA</option>
</select>
<span style="margin-left:50px;">Priv.Prot.</span>
</div>
<div class="form-row form-row-snmpv3 form-row-snmpv3-auth">
<label for="node-input-authkey"><i class="fa fa-key"></i> Auth.Key</label>
<input type="password" id="node-input-authkey" placeholder="Authentication key">
</div>
<div class="form-row form-row-snmpv3 form-row-snmpv3-priv">
<label for="node-input-privprot"><i class="fa fa-shield"></i> Priv.Prot.</label>
<select type="text" id="node-input-privprot" style="width:150px;">
<option value="None">None</option>
<option value="DES">DES</option>
<option value="AES">AES</option>
</select>
</div>
<div class="form-row">
<label for="node-input-authkey"><i class="fa fa-user"></i> Auth.Key</label>
<input type="password" id="node-input-authkey" placeholder="Authentication key">
</div>
<div class="form-row">
<label for="node-input-privkey"><i class="fa fa-user"></i> Priv.Key</label>
<div class="form-row form-row-snmpv3 form-row-snmpv3-priv">
<label for="node-input-privkey"><i class="fa fa-key"></i> Priv.Key</label>
<input type="password" id="node-input-privkey" placeholder="Encryption key">
</div>
<!-- End of unique data for V3 -->
@ -298,9 +359,9 @@
<p>Simple SNMP oid table fetcher. Triggered by any input.</p>
<p><code>msg.host</code> may contain the host.</p>
<p><code>msg.community</code> may contain the community.</p>
<p><code>msg.username</code> may contain the username.</p>
<p><code>msg.authkey</code> may contain the digest security key.</p>
<p><code>msg.privkey</code> may contain the encryption security key.</p>
<p><code>msg.username</code> may contain the username. (V3 only)</p>
<p><code>msg.authkey</code> may contain the digest security key. (V3 only)</p>
<p><code>msg.privkey</code> may contain the encryption security key. (V3 only)</p>
<p><code>msg.oid</code> may contain the oid of a table to request.</p>
<p>OID must be numeric. iso. is the same a 1.</p>
<p>The node will output <code>msg.payload</code> and <code>msg.oid</code>.</p>
@ -315,15 +376,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",
@ -332,6 +395,9 @@
},
labelStyle: function () {
return this.name ? "node_label_italic" : "";
},
oneditprepare: function () {
node_snmp_common.oneditprepare(this);
}
});
</script>
@ -353,43 +419,43 @@
<span style="margin-left:50px;">Timeout</span>
<input type="text" id="node-input-timeout" placeholder="secs" style="width:50px; direction:rtl; vertical-align:baseline;">&nbsp;S
</div>
<div class="form-row">
<div class="form-row form-row-snmpv1v2">
<label for="node-input-community"><i class="fa fa-user"></i> Community</label>
<input type="text" id="node-input-community" placeholder="public">
</div>
<!-- Following Data is used for V3 Only -->
<div class="form-row">
<div class="form-row form-row-snmpv3">
<label for="node-input-username"><i class="fa fa-user"></i> Username</label>
<input type="text" id="node-input-username" placeholder="username">
</div>
<div class="form-row">
<label for="node-input-auth"><i class="fa fa-user-secret"></i> Auth. </label>
<div class="form-row form-row-snmpv3">
<label for="node-input-auth"><i class="fa fa-user-secret"></i> Auth.</label>
<select type="text" id="node-input-auth" style="width:150px;">
<option value="noAuthNoPriv">noAuthNoPriv</option>
<option value="authNoPriv">authNoPriv</option>
<option value="authPriv">authPriv</option>
</select>
</div>
<div class="form-row">
<label for="node-input-authprot"><i class="fa fa-user-secret"></i> Auth.Prot. </label>
<div class="form-row form-row-snmpv3 form-row-snmpv3-auth">
<label for="node-input-authprot"><i class="fa fa-shield"></i> Auth.Prot.</label>
<select type="text" id="node-input-authprot" style="width:150px;">
<option value="None">None</option>
<option value="MD5">MD5</option>
<option value="SHA">SHA</option>
</select>
<span style="margin-left:50px;">Priv.Prot.</span>
</div>
<div class="form-row form-row-snmpv3 form-row-snmpv3-auth">
<label for="node-input-authkey"><i class="fa fa-key"></i> Auth.Key</label>
<input type="password" id="node-input-authkey" placeholder="Authentication key">
</div>
<div class="form-row form-row-snmpv3 form-row-snmpv3-priv">
<label for="node-input-privprot"><i class="fa fa-shield"></i> Priv.Prot.</label>
<select type="text" id="node-input-privprot" style="width:150px;">
<option value="None">None</option>
<option value="DES">DES</option>
<option value="AES">AES</option>
</select>
</div>
<div class="form-row">
<label for="node-input-authkey"><i class="fa fa-user"></i> Auth.Key</label>
<input type="password" id="node-input-authkey" placeholder="Authentication key">
</div>
<div class="form-row">
<label for="node-input-privkey"><i class="fa fa-user"></i> Priv.Key</label>
<div class="form-row form-row-snmpv3 form-row-snmpv3-priv">
<label for="node-input-privkey"><i class="fa fa-key"></i> Priv.Key</label>
<input type="password" id="node-input-privkey" placeholder="Encryption key">
</div>
<!-- End of unique data for V3 -->
@ -408,9 +474,9 @@
<p>Simple SNMP oid subtree fetcher. Triggered by any input. Reads all OIDS at and below the current base OID.</p>
<p><code>msg.host</code> may contain the host.</p>
<p><code>msg.community</code> may contain the community.</p>
<p><code>msg.username</code> may contain the username.</p>
<p><code>msg.authkey</code> may contain the digest security key.</p>
<p><code>msg.privkey</code> may contain the encryption security key.</p>
<p><code>msg.username</code> may contain the username. (V3 only)</p>
<p><code>msg.authkey</code> may contain the digest security key. (V3 only)</p>
<p><code>msg.privkey</code> may contain the encryption security key. (V3 only)</p>
<p><code>msg.oid</code> may contain the oid of a table to request.</p>
<p>OID must be numeric. iso. is the same a 1. </p>
<p>The node will output <code>msg.payload</code> and <code>msg.oid</code>.</p>
@ -425,15 +491,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",
@ -442,6 +510,9 @@
},
labelStyle: function () {
return this.name ? "node_label_italic" : "";
},
oneditprepare: function () {
node_snmp_common.oneditprepare(this);
}
});
</script>
@ -464,43 +535,43 @@
<span style="margin-left:50px;">Timeout</span>
<input type="text" id="node-input-timeout" placeholder="secs" style="width:50px; direction:rtl; vertical-align:baseline;">&nbsp;S
</div>
<div class="form-row">
<div class="form-row form-row-snmpv1v2">
<label for="node-input-community"><i class="fa fa-user"></i> Community</label>
<input type="text" id="node-input-community" placeholder="public">
</div>
<!-- Following Data is used for V3 Only -->
<div class="form-row">
<div class="form-row form-row-snmpv3">
<label for="node-input-username"><i class="fa fa-user"></i> Username</label>
<input type="text" id="node-input-username" placeholder="username">
</div>
<div class="form-row">
<label for="node-input-auth"><i class="fa fa-user-secret"></i> Auth. </label>
<div class="form-row form-row-snmpv3">
<label for="node-input-auth"><i class="fa fa-user-secret"></i> Auth.</label>
<select type="text" id="node-input-auth" style="width:150px;">
<option value="noAuthNoPriv">noAuthNoPriv</option>
<option value="authNoPriv">authNoPriv</option>
<option value="authPriv">authPriv</option>
</select>
</div>
<div class="form-row">
<label for="node-input-authprot"><i class="fa fa-user-secret"></i> Auth.Prot. </label>
<div class="form-row form-row-snmpv3 form-row-snmpv3-auth">
<label for="node-input-authprot"><i class="fa fa-shield"></i> Auth.Prot.</label>
<select type="text" id="node-input-authprot" style="width:150px;">
<option value="None">None</option>
<option value="MD5">MD5</option>
<option value="SHA">SHA</option>
</select>
<span style="margin-left:50px;">Priv.Prot.</span>
</div>
<div class="form-row form-row-snmpv3 form-row-snmpv3-auth">
<label for="node-input-authkey"><i class="fa fa-key"></i> Auth.Key</label>
<input type="password" id="node-input-authkey" placeholder="Authentication key">
</div>
<div class="form-row form-row-snmpv3 form-row-snmpv3-priv">
<label for="node-input-privprot"><i class="fa fa-shield"></i> Priv.Prot.</label>
<select type="text" id="node-input-privprot" style="width:150px;">
<option value="None">None</option>
<option value="DES">DES</option>
<option value="AES">AES</option>
</select>
</div>
<div class="form-row">
<label for="node-input-authkey"><i class="fa fa-user"></i> Auth.Key</label>
<input type="password" id="node-input-authkey" placeholder="Authentication key">
</div>
<div class="form-row">
<label for="node-input-privkey"><i class="fa fa-user"></i> Priv.Key</label>
<div class="form-row form-row-snmpv3 form-row-snmpv3-priv">
<label for="node-input-privkey"><i class="fa fa-key"></i> Priv.Key</label>
<input type="password" id="node-input-privkey" placeholder="Encryption key">
</div>
<!-- End of unique data for V3 -->
@ -520,9 +591,9 @@
Fetches all nodes from this OID to the end of the table.</p>
<p><code>msg.host</code> may contain the host.</p>
<p><code>msg.community</code> may contain the community.</p>
<p><code>msg.username</code> may contain the username.</p>
<p><code>msg.authkey</code> may contain the digest security key.</p>
<p><code>msg.privkey</code> may contain the encryption security key.</p>
<p><code>msg.username</code> may contain the username. (V3 only)</p>
<p><code>msg.authkey</code> may contain the digest security key. (V3 only)</p>
<p><code>msg.privkey</code> may contain the encryption security key. (V3 only)</p>
<p><code>msg.oid</code> may contain the oid of a table to request.</p>
<p>OID must be numeric. iso. is the same a 1. </p>
<p>The node will output <code>msg.payload</code> and <code>msg.oid</code>.</p>
@ -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);
}
});
</script>

View File

@ -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" }
}
});
};