Added support for V3

Added support for version 3.
All the existing issues with v1 and v2c are also with v3 e.g.
https://github.com/node-red/node-red-nodes/issues/679
snmp walker will not return more than 1000 objects, all following objects cannot be accessed
Incorrect encryption (privacy) passphrase gives a timeout and not an error (protocol limitation?)
Incorrect community string gives a timeout and not an error (protocol limitation?)
Changes to the node are made with following details:
Node-red v1.2.2
Node.js v12.6.0
Windows_NT 10.0.19841 x64 LE
This commit is contained in:
andres 2020-10-24 11:07:16 +10:00
parent 8f2c631410
commit 4b99a5f4d1
4 changed files with 545 additions and 79 deletions

View File

@ -18,9 +18,15 @@ Usage
SNMP oids fetcher. Can fetch a single or comma separated list of oids. Triggered by any input. SNMP oids fetcher. Can fetch a single or comma separated list of oids. Triggered by any input.
`msg.host` may contain the host. `msg.host` may contain the host including the port.
`msg.community` may contain the community. `msg.community` may contain the community. (v1 and v2c only)
`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 a comma separated list of oids to search for. (no spaces) `msg.oid` may contain a comma separated list of oids to search for. (no spaces)
@ -28,6 +34,12 @@ The host configured in the edit config will override `msg.host`. Leave blank if
The community configured in the edit config will override `msg.community`. Leave blank if you want to use `msg.community` to provide input. The community configured in the edit config will override `msg.community`. Leave blank if you want to use `msg.community` to provide input.
The username configured in the edit config will override `msg.username`. Leave blank if you want to use `msg.username` to provide input.
The digest security key configured in the edit config will override `msg.authkey`. Leave blank if you want to use `msg.authkey` to provide input.
The encryption security key configured in the edit config will override `msg.privkey`. Leave blank if you want to use `msg.privkey` to provide input.
The oids configured in the edit config will override `msg.oid`. Leave blank if you The oids configured in the edit config will override `msg.oid`. Leave blank if you
want to use `msg.oid` to provide input. want to use `msg.oid` to provide input.
@ -38,9 +50,15 @@ Values depends on the oids being requested.
SNMP sets the value of one or more OIDs. SNMP sets the value of one or more OIDs.
`msg.host` may contain the host. `msg.host` may contain the host including the port.
`msg.community` may contain the community. `msg.community` may contain the community. (v1 and v2c only)
`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.varbinds` may contain an array of varbind JSON objects e.g.: `msg.varbinds` may contain an array of varbind JSON objects e.g.:
``` ```
@ -81,6 +99,12 @@ The host configured in the edit config will override `msg.host`. Leave blank if
The community configured in the edit config will override `msg.community`. Leave blank if you want to use `msg.community` to provide input. The community configured in the edit config will override `msg.community`. Leave blank if you want to use `msg.community` to provide input.
The username configured in the edit config will override `msg.username`. Leave blank if you want to use `msg.username` to provide input.
The digest security key configured in the edit config will override `msg.authkey`. Leave blank if you want to use `msg.authkey` to provide input.
The encryption security key configured in the edit config will override `msg.privkey`. Leave blank if you want to use `msg.privkey` to provide input.
The varbinds configured in the edit config will override `msg.varbinds`. Leave blank if you want to use `msg.varbinds` to provide input. The varbinds configured in the edit config will override `msg.varbinds`. Leave blank if you want to use `msg.varbinds` to provide input.
@ -89,16 +113,28 @@ The varbinds configured in the edit config will override `msg.varbinds`. Leave b
Simple SNMP table oid fetcher. Triggered by any input. Simple SNMP table oid fetcher. Triggered by any input.
`msg.host` may contain the host. `msg.host` may contain the host including the port.
`msg.community` may contain the community. `msg.community` may contain the community. (v1 and v2c only)
`msg.oid` may contain the oid of a single table to search for. `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 a comma separated list of oids to search for. (no spaces)
The host configured in the edit config will override `msg.host`. Leave blank if you want to use `msg.host` to provide input. The host configured in the edit config will override `msg.host`. Leave blank if you want to use `msg.host` to provide input.
The community configured in the edit config will override `msg.community`. Leave blank if you want to use `msg.community` to provide input. The community configured in the edit config will override `msg.community`. Leave blank if you want to use `msg.community` to provide input.
The username configured in the edit config will override `msg.username`. Leave blank if you want to use `msg.username` to provide input.
The digest security key configured in the edit config will override `msg.authkey`. Leave blank if you want to use `msg.authkey` to provide input.
The encryption security key configured in the edit config will override `msg.privkey`. Leave blank if you want to use `msg.privkey` to provide input.
The oid configured in the edit config will override `msg.oid`. Leave blank if you The oid configured in the edit config will override `msg.oid`. Leave blank if you
want to use `msg.oid` to provide input. want to use `msg.oid` to provide input.
@ -109,9 +145,15 @@ Values depends on the oids being requested.
Simple SNMP oid subtree fetcher. Triggered by any input. Reads from OID specified and any below it. Simple SNMP oid subtree fetcher. Triggered by any input. Reads from OID specified and any below it.
`msg.host` may contain the host. `msg.host` may contain the host including the port.
`msg.community` may contain the community. `msg.community` may contain the community. (v1 and v2c only)
`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 single table to search for. `msg.oid` may contain the oid of a single table to search for.
@ -119,6 +161,12 @@ The host configured in the edit config will override `msg.host`. Leave blank if
The community configured in the edit config will override `msg.community`. Leave blank if you want to use `msg.community` to provide input. The community configured in the edit config will override `msg.community`. Leave blank if you want to use `msg.community` to provide input.
The username configured in the edit config will override `msg.username`. Leave blank if you want to use `msg.username` to provide input.
The digest security key configured in the edit config will override `msg.authkey`. Leave blank if you want to use `msg.authkey` to provide input.
The encryption security key configured in the edit config will override `msg.privkey`. Leave blank if you want to use `msg.privkey` to provide input.
The oid configured in the edit config will override `msg.oid`. Leave blank if you The oid configured in the edit config will override `msg.oid`. Leave blank if you
want to use `msg.oid` to provide input. want to use `msg.oid` to provide input.
@ -129,9 +177,15 @@ Values depends on the oids being requested.
Simple SNMP oid walker fetcher. Triggered by any input. Reads from OID specified to the end of the table. Simple SNMP oid walker fetcher. Triggered by any input. Reads from OID specified to the end of the table.
`msg.host` may contain the host. `msg.host` may contain the host including the port.
`msg.community` may contain the community. `msg.community` may contain the community. (v1 and v2c only)
`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 single table to search for. `msg.oid` may contain the oid of a single table to search for.
@ -139,6 +193,12 @@ The host configured in the edit config will override `msg.host`. Leave blank if
The community configured in the edit config will override `msg.community`. Leave blank if you want to use `msg.community` to provide input. The community configured in the edit config will override `msg.community`. Leave blank if you want to use `msg.community` to provide input.
The username configured in the edit config will override `msg.username`. Leave blank if you want to use `msg.username` to provide input.
The digest security key configured in the edit config will override `msg.authkey`. Leave blank if you want to use `msg.authkey` to provide input.
The encryption security key configured in the edit config will override `msg.privkey`. Leave blank if you want to use `msg.privkey` to provide input.
The oid configured in the edit config will override `msg.oid`. Leave blank if you The oid configured in the edit config will override `msg.oid`. Leave blank if you
want to use `msg.oid` to provide input. want to use `msg.oid` to provide input.

View File

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

View File

@ -3,19 +3,56 @@
<label for="node-input-host"><i class="fa fa-globe"></i> Host</label> <label for="node-input-host"><i class="fa fa-globe"></i> Host</label>
<input type="text" id="node-input-host" placeholder="ip address(:optional port)"> <input type="text" id="node-input-host" placeholder="ip address(:optional port)">
</div> </div>
<div class="form-row">
<label for="node-input-community"><i class="fa fa-user"></i> Community</label>
<input type="text" id="node-input-community" placeholder="public">
</div>
<div class="form-row"> <div class="form-row">
<label for="node-input-version"><i class="fa fa-bookmark"></i> Version</label> <label for="node-input-version"><i class="fa fa-bookmark"></i> Version</label>
<select type="text" id="node-input-version" style="width:150px;"> <select type="text" id="node-input-version" style="width:150px;">
<option value="1">v1</option> <option value="v1">v1</option>
<option value="2c">v2c</option> <option value="v2c">v2c</option>
<option value="v3">v3</option>
</select> </select>
<span style="margin-left:50px;">Timeout</span> <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 <input type="text" id="node-input-timeout" placeholder="secs" style="width:50px; direction:rtl; vertical-align:baseline;">&nbsp;S
</div> </div>
<div class="form-row">
<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">
<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>
<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>
<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>
<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>
<input type="password" id="node-input-privkey" placeholder="Encryption key">
</div>
<!-- End of unique data for V3 -->
<div class="form-row"> <div class="form-row">
<label for="node-input-oids"><i class="fa fa-tags"></i> OIDs</label> <label for="node-input-oids"><i class="fa fa-tags"></i> OIDs</label>
<textarea rows="4" cols="60" id="node-input-oids" placeholder="e.g. 1.3.6.1.2.1.1.5.0" style="width:70%;"></textarea> <textarea rows="4" cols="60" id="node-input-oids" placeholder="e.g. 1.3.6.1.2.1.1.5.0" style="width:70%;"></textarea>
@ -31,6 +68,9 @@
<p>Simple SNMP oid or oid list fetcher. Triggered by any input.</p> <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.host</code> may contain the host.</p>
<p><code>msg.community</code> may contain the community.</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.oid</code> may contain a comma separated list of oids to request. (no spaces)</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>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> <p>The node will output <code>msg.payload</code> and <code>msg.oid</code>.</p>
@ -42,10 +82,16 @@
color: "YellowGreen", color: "YellowGreen",
defaults: { defaults: {
host: { value: "127.0.0.1" }, host: { value: "127.0.0.1" },
community: { value: "public" }, version: { value: "v1", required: true },
version: { value: "1", required: true },
oids: { value: "" },
timeout: { value: 5 }, 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: "" },
oids: { value: "" },
name: { value: "" } name: { value: "" }
}, },
inputs: 1, inputs: 1,
@ -65,19 +111,58 @@
<label for="node-input-host"><i class="fa fa-globe"></i> Host</label> <label for="node-input-host"><i class="fa fa-globe"></i> Host</label>
<input type="text" id="node-input-host" placeholder="ip address(:optional port)"> <input type="text" id="node-input-host" placeholder="ip address(:optional port)">
</div> </div>
<div class="form-row">
<label for="node-input-community"><i class="fa fa-user"></i> Community</label>
<input type="text" id="node-input-community" placeholder="public">
</div>
<div class="form-row"> <div class="form-row">
<label for="node-input-version"><i class="fa fa-bookmark"></i> Version</label> <label for="node-input-version"><i class="fa fa-bookmark"></i> Version</label>
<select type="text" id="node-input-version" style="width:150px;"> <select type="text" id="node-input-version" style="width:150px;">
<option value="1">v1</option> <option value="v1">v1</option>
<option value="2c">v2c</option> <option value="v2c">v2c</option>
<!-- Following Data is used for V3 Only -->
<option value="v3">v3</option>
<!-- End of unique data for V3 -->
</select> </select>
<span style="margin-left:50px;">Timeout</span> <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 <input type="text" id="node-input-timeout" placeholder="secs" style="width:50px; direction:rtl; vertical-align:baseline;">&nbsp;S
</div> </div>
<div class="form-row">
<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">
<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>
<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>
<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>
<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>
<input type="password" id="node-input-privkey" placeholder="Encryption key">
</div>
<!-- End of unique data for V3 -->
<div class="form-row"> <div class="form-row">
<label for="node-input-varbinds"><i class="fa fa-tags"></i> Varbinds</label> <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;}]"
@ -94,6 +179,9 @@
<p>Simple snmp Set node. Trigger by any input</p> <p>Simple snmp Set node. Trigger by any input</p>
<p><code>msg.host</code> may contain the host.</p> <p><code>msg.host</code> may contain the host.</p>
<p><code>msg.community</code> may contain the community.</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.varbinds</code> may contain varbinds as an array of json objects containing multiple oids, types and values. <p><code>msg.varbinds</code> may contain varbinds as an array of json objects containing multiple oids, types and values.
<pre>[ <pre>[
{ {
@ -114,10 +202,16 @@
color: "YellowGreen", color: "YellowGreen",
defaults: { defaults: {
host: { value: "127.0.0.1" }, host: { value: "127.0.0.1" },
community: { value: "public" }, version: { value: "v1", required: true },
version: { value: "1", required: true },
varbinds: { value: "" },
timeout: { value: 5 }, 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: "" },
name: { value: "" } name: { value: "" }
}, },
inputs: 1, inputs: 1,
@ -137,19 +231,58 @@
<label for="node-input-host"><i class="fa fa-globe"></i> Host</label> <label for="node-input-host"><i class="fa fa-globe"></i> Host</label>
<input type="text" id="node-input-host" placeholder="ip address(:optional port)"> <input type="text" id="node-input-host" placeholder="ip address(:optional port)">
</div> </div>
<div class="form-row">
<label for="node-input-community"><i class="fa fa-user"></i> Community</label>
<input type="text" id="node-input-community" placeholder="public">
</div>
<div class="form-row"> <div class="form-row">
<label for="node-input-version"><i class="fa fa-bookmark"></i> Version</label> <label for="node-input-version"><i class="fa fa-bookmark"></i> Version</label>
<select type="text" id="node-input-version" style="width:150px;"> <select type="text" id="node-input-version" style="width:150px;">
<option value="1">v1</option> <option value="v1">v1</option>
<option value="2c">v2c</option> <option value="v2c">v2c</option>
<!-- Following Data is used for V3 Only -->
<option value="v3">v3</option>
<!-- End of unique data for V3 -->
</select> </select>
<span style="margin-left:50px;">Timeout</span> <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 <input type="text" id="node-input-timeout" placeholder="secs" style="width:50px; direction:rtl; vertical-align:baseline;">&nbsp;S
</div> </div>
<div class="form-row">
<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">
<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>
<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>
<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>
<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>
<input type="password" id="node-input-privkey" placeholder="Encryption key">
</div>
<!-- End of unique data for V3 -->
<div class="form-row"> <div class="form-row">
<label for="node-input-oids"><i class="fa fa-tags"></i> OID</label> <label for="node-input-oids"><i class="fa fa-tags"></i> OID</label>
<input type="text" id="node-input-oids" placeholder="e.g. 1.3.6.1.2.1.1.5.0"> <input type="text" id="node-input-oids" placeholder="e.g. 1.3.6.1.2.1.1.5.0">
@ -165,6 +298,9 @@
<p>Simple SNMP oid table fetcher. Triggered by any input.</p> <p>Simple SNMP oid table fetcher. Triggered by any input.</p>
<p><code>msg.host</code> may contain the host.</p> <p><code>msg.host</code> may contain the host.</p>
<p><code>msg.community</code> may contain the community.</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.oid</code> may contain the oid of a table to request.</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>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> <p>The node will output <code>msg.payload</code> and <code>msg.oid</code>.</p>
@ -176,10 +312,16 @@
color: "YellowGreen", color: "YellowGreen",
defaults: { defaults: {
host: { value: "127.0.0.1" }, host: { value: "127.0.0.1" },
community: { value: "public" }, version: { value: "v1", required: true },
version: { value: "1", required: true },
oids: { value: "" },
timeout: { value: 5 }, 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: "" },
oids: { value: "" },
name: { value: "" } name: { value: "" }
}, },
inputs: 1, inputs: 1,
@ -199,19 +341,58 @@
<label for="node-input-host"><i class="fa fa-globe"></i> Host</label> <label for="node-input-host"><i class="fa fa-globe"></i> Host</label>
<input type="text" id="node-input-host" placeholder="ip address(:optional port)"> <input type="text" id="node-input-host" placeholder="ip address(:optional port)">
</div> </div>
<div class="form-row">
<label for="node-input-community"><i class="fa fa-user"></i> Community</label>
<input type="text" id="node-input-community" placeholder="public">
</div>
<div class="form-row"> <div class="form-row">
<label for="node-input-version"><i class="fa fa-bookmark"></i> Version</label> <label for="node-input-version"><i class="fa fa-bookmark"></i> Version</label>
<select type="text" id="node-input-version" style="width:150px;"> <select type="text" id="node-input-version" style="width:150px;">
<option value="1">v1</option> <option value="v1">v1</option>
<option value="2c">v2c</option> <option value="v2c">v2c</option>
<!-- Following Data is used for V3 Only -->
<option value="v3">v3</option>
<!-- End of unique data for V3 -->
</select> </select>
<span style="margin-left:50px;">Timeout</span> <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 <input type="text" id="node-input-timeout" placeholder="secs" style="width:50px; direction:rtl; vertical-align:baseline;">&nbsp;S
</div> </div>
<div class="form-row">
<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">
<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>
<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>
<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>
<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>
<input type="password" id="node-input-privkey" placeholder="Encryption key">
</div>
<!-- End of unique data for V3 -->
<div class="form-row"> <div class="form-row">
<label for="node-input-oids"><i class="fa fa-tags"></i> OID</label> <label for="node-input-oids"><i class="fa fa-tags"></i> OID</label>
<input type="text" id="node-input-oids" placeholder="e.g. 1.3.6.1.2.1.1.5.0"> <input type="text" id="node-input-oids" placeholder="e.g. 1.3.6.1.2.1.1.5.0">
@ -227,6 +408,9 @@
<p>Simple SNMP oid subtree fetcher. Triggered by any input. Reads all OIDS at and below the current base OID.</p> <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.host</code> may contain the host.</p>
<p><code>msg.community</code> may contain the community.</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.oid</code> may contain the oid of a table to request.</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>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> <p>The node will output <code>msg.payload</code> and <code>msg.oid</code>.</p>
@ -238,10 +422,16 @@
color: "YellowGreen", color: "YellowGreen",
defaults: { defaults: {
host: { value: "127.0.0.1" }, host: { value: "127.0.0.1" },
community: { value: "public" }, version: { value: "v1", required: true },
version: { value: "1", required: true },
oids: { value: "" },
timeout: { value: 5 }, 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: "" },
oids: { value: "" },
name: { value: "" } name: { value: "" }
}, },
inputs: 1, inputs: 1,
@ -262,19 +452,58 @@
<label for="node-input-host"><i class="fa fa-globe"></i> Host</label> <label for="node-input-host"><i class="fa fa-globe"></i> Host</label>
<input type="text" id="node-input-host" placeholder="ip address(:optional port)"> <input type="text" id="node-input-host" placeholder="ip address(:optional port)">
</div> </div>
<div class="form-row">
<label for="node-input-community"><i class="fa fa-user"></i> Community</label>
<input type="text" id="node-input-community" placeholder="public">
</div>
<div class="form-row"> <div class="form-row">
<label for="node-input-version"><i class="fa fa-bookmark"></i> Version</label> <label for="node-input-version"><i class="fa fa-bookmark"></i> Version</label>
<select type="text" id="node-input-version" style="width:150px;"> <select type="text" id="node-input-version" style="width:150px;">
<option value="1">v1</option> <option value="v1">v1</option>
<option value="2c">v2c</option> <option value="v2c">v2c</option>
<!-- Following Data is used for V3 Only -->
<option value="v3">v3</option>
<!-- End of unique data for V3 -->
</select> </select>
<span style="margin-left:50px;">Timeout</span> <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 <input type="text" id="node-input-timeout" placeholder="secs" style="width:50px; direction:rtl; vertical-align:baseline;">&nbsp;S
</div> </div>
<div class="form-row">
<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">
<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>
<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>
<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>
<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>
<input type="password" id="node-input-privkey" placeholder="Encryption key">
</div>
<!-- End of unique data for V3 -->
<div class="form-row"> <div class="form-row">
<label for="node-input-oids"><i class="fa fa-tags"></i> OID</label> <label for="node-input-oids"><i class="fa fa-tags"></i> OID</label>
<input type="text" id="node-input-oids" placeholder="e.g. 1.3.6.1.2.1.1.5.0"> <input type="text" id="node-input-oids" placeholder="e.g. 1.3.6.1.2.1.1.5.0">
@ -291,6 +520,9 @@
Fetches all nodes from this OID to the end of the table.</p> 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.host</code> may contain the host.</p>
<p><code>msg.community</code> may contain the community.</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.oid</code> may contain the oid of a table to request.</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>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> <p>The node will output <code>msg.payload</code> and <code>msg.oid</code>.</p>
@ -304,10 +536,16 @@
color: "YellowGreen", color: "YellowGreen",
defaults: { defaults: {
host: { value: "127.0.0.1" }, host: { value: "127.0.0.1" },
community: { value: "public" }, version: { value: "v1", required: true },
version: { value: "1", required: true },
oids: { value: "" },
timeout: { value: 5 }, 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: "" },
oids: { value: "" },
name: { value: "" } name: { value: "" }
}, },
inputs: 1, inputs: 1,

View File

@ -5,34 +5,91 @@ module.exports = function (RED) {
var sessions = {}; var sessions = {};
function getSession(host, community, version, timeout) { function openSession(host, data, options) {
var sessionKey = host + ":" + community + ":" + version; //console.log({data});
var port = 161; //console.log({options});
var sessionid = data.sessionid;
options.port = 161;
if (host.indexOf(":") !== -1) { if (host.indexOf(":") !== -1) {
port = host.split(":")[1]; options.port = host.split(":")[1];
host = host.split(":")[0]; host = host.split(":")[0];
} }
if (!(sessionKey in sessions)) { // SNMPv3 call
sessions[sessionKey] = snmp.createSession(host, community, { port:port, version:version, timeout:(timeout || 5000) }); 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 || "";
} }
return sessions[sessionKey]; }
}
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);
}
return sessions[sessionid];
}
// Any session needs to be closed after completion
function closeSession(sessionid) {
//console.log("closing session");
sessions[sessionid].close();
} }
function SnmpNode(n) { function SnmpNode(n) {
RED.nodes.createNode(this, n); RED.nodes.createNode(this, n);
this.community = n.community; this.community = n.community;
this.host = n.host; this.host = n.host;
this.version = (n.version === "2c") ? snmp.Version2c : snmp.Version1; 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.oids = n.oids.replace(/\s/g, "");
this.timeout = Number(n.timeout || 5) * 1000; this.timeout = Number(n.timeout || 5) * 1000;
var node = this; var node = this;
this.on("input", function (msg) { this.on("input", function (msg) {
var host = node.host || msg.host; var host = node.host || msg.host;
var version = node.version;
var community = node.community || msg.community; 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 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;
if (oids) { if (oids) {
getSession(host, community, node.version, node.timeout).get(oids.split(","), function (error, varbinds) { openSession(host, data, options).get(oids.split(","), function (error, varbinds) {
if (error) { if (error) {
node.error(error.toString(), msg); node.error(error.toString(), msg);
} }
@ -51,6 +108,7 @@ module.exports = function (RED) {
msg.payload = varbinds; msg.payload = varbinds;
node.send(msg); node.send(msg);
} }
closeSession(sessionid); // Needed to close the session else a bad or good read could affect future readings
}); });
} }
else { else {
@ -64,20 +122,46 @@ module.exports = function (RED) {
RED.nodes.createNode(this, n); RED.nodes.createNode(this, n);
this.community = n.community; this.community = n.community;
this.host = n.host; this.host = n.host;
this.version = (n.version === "2c") ? snmp.Version2c : snmp.Version1; this.version = n.version;
this.varbinds = n.varbinds; 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.timeout = Number(n.timeout || 5) * 1000;
this.varbinds = n.varbinds;
if (this.varbinds && this.varbinds.trim().length === 0) { delete this.varbinds; } if (this.varbinds && this.varbinds.trim().length === 0) { delete this.varbinds; }
var node = this; var node = this;
this.on("input", function (msg) { this.on("input", function (msg) {
var host = node.host || msg.host; var host = node.host || msg.host;
var version = node.version;
var community = node.community || msg.community; 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; var varbinds = (node.varbinds) ? JSON.parse(node.varbinds) : msg.varbinds;
if (varbinds) { if (varbinds) {
for (var i = 0; i < varbinds.length; i++) { for (var i = 0; i < varbinds.length; i++) {
varbinds[i].type = snmp.ObjectType[varbinds[i].type]; varbinds[i].type = snmp.ObjectType[varbinds[i].type];
} }
getSession(host, community, node.version, node.timeout).set(varbinds, function (error, varbinds) { openSession(host, data, options).set(varbinds, function (error, varbinds) {
if (error) { if (error) {
node.error(error.toString(), msg); node.error(error.toString(), msg);
} }
@ -89,6 +173,7 @@ module.exports = function (RED) {
} }
} }
} }
closeSession(sessionid);
}); });
} }
else { else {
@ -104,7 +189,13 @@ module.exports = function (RED) {
RED.nodes.createNode(this, n); RED.nodes.createNode(this, n);
this.community = n.community; this.community = n.community;
this.host = n.host; this.host = n.host;
this.version = (n.version === "2c") ? snmp.Version2c : snmp.Version1; 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.oids = n.oids.replace(/\s/g, "");
this.timeout = Number(n.timeout || 5) * 1000; this.timeout = Number(n.timeout || 5) * 1000;
var node = this; var node = this;
@ -118,11 +209,32 @@ module.exports = function (RED) {
this.on("input", function (msg) { this.on("input", function (msg) {
var host = node.host || msg.host; var host = node.host || msg.host;
var version = node.version;
var community = node.community || msg.community; 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 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});
if (oids) { if (oids) {
msg.oid = oids; msg.oid = oids;
getSession(host, community, node.version, node.timeout).table(oids, maxRepetitions, function (error, table) { openSession(host, data, options).table(oids, maxRepetitions, function (error, table) {
if (error) { if (error) {
node.error(error.toString(), msg); node.error(error.toString(), msg);
} }
@ -150,6 +262,7 @@ module.exports = function (RED) {
msg.payload = table; msg.payload = table;
node.send(msg); node.send(msg);
} }
closeSession(sessionid);
}); });
} }
else { else {
@ -164,7 +277,13 @@ module.exports = function (RED) {
RED.nodes.createNode(this, n); RED.nodes.createNode(this, n);
this.community = n.community; this.community = n.community;
this.host = n.host; this.host = n.host;
this.version = (n.version === "2c") ? snmp.Version2c : snmp.Version1; 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.oids = n.oids.replace(/\s/g, "");
this.timeout = Number(n.timeout || 5) * 1000; this.timeout = Number(n.timeout || 5) * 1000;
var node = this; var node = this;
@ -185,11 +304,31 @@ module.exports = function (RED) {
this.on("input", function (msg) { this.on("input", function (msg) {
var host = node.host || msg.host; var host = node.host || msg.host;
var version = node.version;
var community = node.community || msg.community; 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 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;
if (oids) { if (oids) {
msg.oid = oids; msg.oid = oids;
getSession(host, community, node.version, node.timeout).subtree(msg.oid, maxRepetitions, feedCb, function (error) { openSession(host, data, options).subtree(msg.oid, maxRepetitions, feedCb, function (error) {
if (error) { if (error) {
node.error(error.toString(), msg); node.error(error.toString(), msg);
} }
@ -200,6 +339,7 @@ module.exports = function (RED) {
//Clears response //Clears response
response.length = 0; response.length = 0;
} }
closeSession(sessionid);
}); });
} }
else { else {
@ -214,7 +354,13 @@ module.exports = function (RED) {
RED.nodes.createNode(this, n); RED.nodes.createNode(this, n);
this.community = n.community; this.community = n.community;
this.host = n.host; this.host = n.host;
this.version = (n.version === "2c") ? snmp.Version2c : snmp.Version1; 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.oids = n.oids.replace(/\s/g, "");
this.timeout = Number(n.timeout || 5) * 1000; this.timeout = Number(n.timeout || 5) * 1000;
var node = this; var node = this;
@ -235,12 +381,32 @@ module.exports = function (RED) {
this.on("input", function (msg) { this.on("input", function (msg) {
node.msg = msg; node.msg = msg;
var oids = node.oids || msg.oid;
var host = node.host || msg.host; var host = node.host || msg.host;
var version = node.version;
var community = node.community || msg.community; 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;
if (oids) { if (oids) {
msg.oid = oids; msg.oid = oids;
getSession(host, community, node.version, node.timeout).walk(msg.oid, maxRepetitions, feedCb, function (error) { openSession(host, data, options).walk(msg.oid, maxRepetitions, feedCb, function (error) {
if (error) { if (error) {
node.error(error.toString(), msg); node.error(error.toString(), msg);
} }
@ -251,6 +417,7 @@ module.exports = function (RED) {
//Clears response //Clears response
response.length = 0; response.length = 0;
} }
closeSession(sessionid);
}); });
} }
else { else {