Git Product home page Git Product logo

node-snmp-native's Introduction

                                                             __
                                                            /\ \__  __
  ____    ___     ___ ___   _____              ___      __  \ \ ,_\/\_\   __  __     __
 /',__\ /' _ `\ /' __` __`\/\ '__`\  _______ /' _ `\  /'__`\ \ \ \/\/\ \ /\ \/\ \  /'__`\
/\__, `\/\ \/\ \/\ \/\ \/\ \ \ \L\ \/\______\/\ \/\ \/\ \L\.\_\ \ \_\ \ \\ \ \_/ |/\  __/
\/\____/\ \_\ \_\ \_\ \_\ \_\ \ ,__/\/______/\ \_\ \_\ \__/.\_\\ \__\\ \_\\ \___/ \ \____\
 \/___/  \/_/\/_/\/_/\/_/\/_/\ \ \/           \/_/\/_/\/__/\/_/ \/__/ \/_/ \/__/   \/____/
                              \ \_\
                               \/_/

snmp-native Build Status

This is a native SNMP library for Node.js. The purpose is to provide enough functionality to perform large scale monitoring of network equipment. Current features towards this end are:

  • Full implementation of SNMPv2c, including 64 bit data types.
  • Support for Get, GetNext and Set requests, with optimizations such as GetAll and GetSubtree.
  • No unusual external dependencies, no non-JavaScript code.
  • Very high performance, unlimited parallellism. (There are always limits. However, there are no arbitrary such imposed by this code and you at least won't run out of file descriptors.)
  • De facto standards compliance. Generated packets are compared against Net-SNMP and should be identical in all relevant aspects.
  • Well tested. Test coverage should be at or close to 100% for all important code paths.

It specifically does not include:

  • Compatibility with SNMPv1, SNMPv2u or SNMPv3. These are (in order) deprecated, weird, and too complicated. Yes, it's an opinionated library.
  • MIB parsing. Do this in your client app if it's necessary.

It's optimized for polling tens of thousands of counters on hundreds or thousands of hosts in a parallell manner. This is known to work (although performance might be limited by less than optimal SNMP agent implementations in random network gear).

Documentation

Installation

$ npm install snmp-native

Usage

Import

var snmp = require('snmp-native');

new Session(options)

Create a Session. The Session constructor, like most of the other functions, take an options object. The options passed to the Session will be the defaults for any subsequent function calls on that session, but can be overridden as needed. Useful parameters here are host, port and family.

// Create a Session with default settings.
var session = new snmp.Session();

// Create a Session with explicit default host, port, and community.
var session = new snmp.Session({ host: 'device.example.com', port: 161, community: 'special' });

// Create an IPv6 Session.
var session = new snmp.Session({ host: '2001:db8::42', family: 'udp6', community: 'private' });

The following options are recognized as properties in the options object. All can be specified in the Session constructor and optionally overridden at a later time by setting them in the option object to a method call.

For optimum performance when polling many hosts, create a session without specifying the host. Reuse this session for all hosts and specify the host on each get, getAll, etc.

  • host: The host to send the request to. An resolvable name is allowed in addition to IP addresses. Default: 'localhost'.
  • port: The UDP port number to send the request to. Default: 161.
  • community: The SNMP community name. Default: 'public'.
  • family: Address family to bind to. This is only used by the Session constructor since that is when the bind is done. It cannot be changed or overridden after construction. Default: 'udp4'. Valid values: 'udp4' or 'udp6'.
  • timeouts: An array of timeout values. Values are times in milliseconds, the length of the array is the total number of transmissions that will occur. Default: [5000, 5000, 5000, 5000] (four attempts, with five seconds between each). A backoff can be implemented by timeouts along the lines of [ 1000, 2000, 4000, 8000 ]. Retransmissions can be disabled by using only a single timeout value: [ 5000 ].
  • bindPort: UDP port used to bind the socket locally. Default: 0 (random port)
  • msgReceived: A (message, rinfo) => {} function responsible to handle incoming messages and sending UDP responses back. If nothing is given here, the default implementation is used. This is useful if you want to implement custom logic in your application

VarBind objects

All of the get* functions return arrays of VarBind as the result to the callback. The VarBind objects have the following properties:

  • oid: The OID they represent (in array form).
  • type: The integer type code for the returned value.
  • value: The value, in decoded form. This will be an integer for integer, gauge, counter and timetick types, a string for an octet string value, an array for array or IP number types.
  • valueRaw: For octet string values, this is a raw Buffer representing the string.
  • valueHex: For octet string values, this is a hex string representation of the value.
  • sendStamp: The timestamp (in milliseconds) when the request was transmitted.
  • receiveStamp: The timestamp (in milliseconds) when the response was received.

get(options, callback)

Perform a simple GetRequest. Options (in addition to the ones defined above for Session):

  • oid: The OID to get. Example: [1, 3, 6, 1, 4, 1, 1, 2, 3, 4] or '.1.3.6.1.4.1.1.2.3.4'. Both forms are accepted, but the string form will need to be parsed to an array, slightly increasing CPU usage.

Will call the specified callback with an error object (null on success) and the varbind that was received.

session.get({ oid: [1, 3, 6, 1, 4, 1, 42, 1, 0] }, function (error, varbinds) {
    if (error) {
        console.log('Fail :(');
    } else {
        console.log(varbinds[0].oid + ' = ' + varbinds[0].value + ' (' + varbinds[0].type + ')');
    }
});

You can also specify host, community, etc explicitly.

session.get({ oid: [1, 3, 6, 1, 4, 1, 42, 1, 0], host: 'localhost', community: 'test' }, ...);

getNext(options, callback)

Perform a simple GetNextRequest. Options:

  • oid: The OID to get. Example: [1, 3, 6, 1, 4, 1, 1, 2, 3, 4] or '.1.3.6.1.4.1.1.2.3.4'.

Will call the specified callback with an error object (null on success) and the varbind that was received.

session.getNext({ oid: [1, 3, 6, 1, 4, 1, 42, 1, 0] }, function (error, varbinds) {
    if (error) {
        console.log('Fail :(');
    } else {
        console.log(varbinds[0].oid + ' = ' + varbinds[0].value + ' (' + varbinds[0].type + ')');
    }
});

getAll(options, callback)

Perform repeated GetRequests to fetch all the required values. Multiple OIDs will get packed into as few GetRequest packets as possible to minimize roundtrip delays. Gets will be issued serially (not in parallell) to avoid flooding hosts. Options:

  • oids: An array of OIDs to get. Example: [[1, 3, 6, 1, 4, 1, 1, 2, 3], [1, 3, 6, 1, 4, 1, 1, 2, 4]] or ['.1.3.6.1.4.1.1.2.3.4', '.1.3.6.1.4.1.2.3.4.5'].
  • abortOnError: Whether to stop or continue when an error is encountered. Default: false.
  • combinedTimeout: Timeout in milliseconds that the getAll() may take. Default: no timeout.

The callback will be called with an error object or a list of varbinds. If the options property abortOnError is false (default) any variables that couldn't be fetched will simply be omitted from the results. If it is true, the callback will be called with an error object on any failure. If the combinedTimeout is triggered, the callback is called with an error and the partial results.

var oids = [ [1, 3, 6, 1, 4, 1, 42, 1, 0], [1, 3, 6, 1, 4, 1, 42, 2, 0], ... ];
session.getAll({ oids: oids }, function (error, varbinds) {
    varbinds.forEach(function (vb) {
        console.log(vb.oid + ' = ' + vb.value + ' (' + vb.type + ')');
    });
});

getSubtree(options, callback)

Perform repeated GetNextRequests to fetch all values in the specified tree. Options:

  • oid: The OID to get. Example: [1, 3, 6, 1, 4, 1, 1, 2, 3, 4] or '.1.3.6.1.4.1.1.2.3.4'.
  • combinedTimeout: Timeout in milliseconds that the getSubtree() may take. Default: no timeout.

Will call the specified callback with an error object (null on success) and the list of varbinds that was fetched. If the combinedTimeout is triggered, the callback is called with an error and the partial results.

session.getSubtree({ oid: [1, 3, 6, 1, 4, 1, 42] }, function (error, varbinds) {
    if (error) {
        console.log('Fail :(');
    } else {
        varbinds.forEach(function (vb) {
            console.log(vb.oid + ' = ' + vb.value + ' (' + vb.type + ')');
        });
    }
});

set(options, callback)

Perform a simple SetRequest. Options:

  • oid: The OID to perform the set on. Example: [1, 3, 6, 1, 4, 1, 1, 2, 3, 4] or '.1.3.6.1.4.1.1.2.3.4'.
  • value: The value to set. Example: 42.
  • type: The type of the value. Currently supports asn1ber.T.Integer (2), asn1ber.T.Gauge (66), asn1ber.T.IpAddress (64), asn1ber.T.OctetString (4) and asn1ber.T.Null (5). Example: 2.

Example:

session.set({ oid: [1, 3, 6, 1, 4, 1, 42, 1, 0], value: 42, type: 2 }, function (error, varbind) {
    if (error) {
        console.log('Fail :(');
    } else {
        console.log('The set is done.');
    }
});

If you're not really interested in the outcome of the set (and if you are, why aren't you using scripted telnet or ssh instead to begin with?), you can call it without a callback:

session.set({ oid: [1, 3, 6, 1, 4, 1, 42, 1, 0], value: 42, type: 2 });

close()

Cancels all outstanding requests and frees used OS resources. Outstanding requests will call their callback with the "Cancelled" error set.

Example:

session.close();

License

MIT

node-snmp-native's People

Contributors

bangert avatar calmh avatar ddolcimascolo avatar eden-sun avatar fmgdias avatar gregmac avatar lqmanh avatar rsolomo avatar xuannnaux avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-snmp-native's Issues

Build fails on Windows because of node-waf

Does this package is intended to run on Windows?
Looks like node team has decided to switch from waf to gyp for building native modules (cf. http://botsikas.blogspot.fr/2011/12/nodejs-modules-cross-platform.html).

Any chance you would update this very promising plugin so that it can be built on windows?

Edit: Looks like you are indeed using gyp & it's just a dependency that fails to build (dtrace-provider). So this issue is probably irrelevant.

Edit2: Maybe you could do some npm tweaking to consider dtrace as optional (check : restify/node-restify#100 (comment))

Regards!

asn1ber: OID values starting larger than .2.39 are interpreted incorrectly

OID values are encoded a bit strangely in asn1, in that the first two octets are encoded using a single byte:

BER encoding. Primitive. Contents octets are as follows, where value1, …, valuen denote the integer values of the components in the complete object identifier:

  1. The first octet has value 40 × value1 + value2. (This is unambiguous, since value1
    is limited to values 0, 1, and 2; value2 is limited to the range 0 to 39 when value1 is 0 or 1; and, according to X.208, n is always at least 2.)
  2. The following octets, if any, encode value3, …, valuen. Each value is encoded base 128, most significant digit first, with as few digits as possible, and the most significant bit of each octet except the last in the value's encoding set to "1."

The result of this is that the first two octets of an OID can only be within the ranges:

  • 0.0.x to 0.39.x
  • 1.0.x to 1.39.x
  • 2.0.x to 2.79.x

The OID value .2.46 encodes to the byte 0x7E. The problem is this is incorrectly decoded as .3.6.

I came across this with a device with a hrDeviceId value. Interestingly, this is actually a fairly common problem across a few different libraries and applications, and took a while to isolate because many other libraries/tools have the same bug

Implementing SNMP Trap-PDU

First of all, thanks for the effort in implementing SNMP in JavaScript. I have done the same in PHP to get rid of the PHP snmp extension.

Could it be possible to implement all PDU types, especially Trap-PDU types, so that the server could handle alerts sent from devices (socket listening on udp/162).

0xa0 (160)  SNMP GetRequest-PDU
0xa1 (161)  SNMP GetNextRequest-PDU
0xa2 (162)  SNMP GetResponse-PDU
0xa3 (163)  SNMP SetRequest-PDU
0xa4 (164)  SNMPv1 Trap-PDU (replaced by 0xa7 in SNMPv2)
0xa5 (165)  SNMPv2 GetBulkRequest-PDU
0xa6 (166)  SNMPv2 InformRequest-PDU
0xa7 (167)  SNMPv2 SNMPv2-Trap-PDU

Incorrect oid validation

The module incorrectly marks the OID .1.0.8802.1.1.2.1.4.1.1.9 as invalid since it doesn't begin with .1.3. While most OIDs begin with .1.3, there are quite a few that don't. The link below includes some information on this particular OID if you're interested:

http://www.mibdepot.com/cgi-bin/getmib3.cgi?win=mib_a&i=1&n=LLDP-MIB&r=rittal&f=LLDP-MIB&v=v2&t=tab&o=lldpRemSysName

I've also narrowed down the issue to lines 132 to 134 of asn1ber.js:

} else if (!skipValidation && (oid[0] !== 1 || oid[1] !== 3)) {
throw new Error("SNMP OIDs always start with .1.3.");
}

I might be misunderstanding the code, but it looks like we only need to replace (oid[0] !== 1 || oid[1] !== 3) with oid[0] !== 1 to appropriately mark the OID as valid.

What steps can I take to resolve this issue? Thanks for your help. I really appreciate it.

Unable to install the package

Guys,

When I run the npm command i.e. npm install snmp-native it gives the following error -

"Unable to resolve module assert from /Users/tushar-pant/Documents/WWW-ReactNative/node_modules/snmp-native/lib/snmp.js: Module does not exist in the module map

This might be related to facebook/react-native#4968

To resolve try the following:

  1. Clear watchman watches: watchman watch-del-all.
  2. Delete the node_modules folder: rm -rf node_modules && npm install.
  3. Reset packager cache: rm -fr $TMPDIR/react-* or npm start -- --reset-cache."

What should be the issue?

getAll not working in version 1.1.1

Hi guys,

I can't seem to get the 'getAll' method to work no matter what OIDs I try. However if I query them with getSubtree it works. Can someone please inform me of what I am missing.

Doesn't work:

var snmp = require('snmp-native');
var session = new snmp.Session({ host: 'localhost', port: 161, community: 'public' });
var oids = [[1,3,6,1,2,1,1,1],[1,3,6,1,2,1,1,3]];
session.getAll({ oids: oids }, function (error, varbinds) {
    if (error) {
        console.log(error);
    } else {
        varbinds.forEach(function(vb) {
            console.log(vb.oid + " " + vb.value + " " + vb.type);
        });
    }
});

Using getSubtree works:

var snmp = require('snmp-native');
var session = new snmp.Session({ host: 'localhost', port: 161, community: 'public' });
var oids = [[1,3,6,1,2,1,1,1],[1,3,6,1,2,1,1,3]];
session.getSubtree({ oid: oids[0] }, function (error, varbinds) {
    if (error) {
        console.log(error);
    } else {
        varbinds.forEach(function(vb) {
            console.log(vb.oid + " " + vb.value + " " + vb.type);
        });
    }
});

Thanks.

Slow getSubtree

Hello, first of all thanks for sharing this excellent piece of code.
In most cases, I see that the get or getAll requests are fast, a lot, comparable with net-snmp from bash.
However, now I start to try getSubtree and it works extremely slow. To compare, a particular request takes 1.8 seconds with net-snmp from bash and snmp-native takes 27 seconds. The two tests are done on the same server, against the same host and the same OID.
Is it normal for getSubtree to take so long?

Getting always a timeout

I've just try to test snmp-native, but I always got a timeout executing a simple "get" (SNMP agent running on 173 under 127.0.0.1 with community "public"). Do you have any hints?

Error on debug log

I found this error and it seems that I should publish it here:

`Woops! An error occurred while parsing an SNMP message. :(
To have this problem corrected, please report the information below verbatim
via email to [email protected] or by creating a GitHub issue at
https://github.com/calmh/node-snmp-native/issues

Thanks!

AssertionError: 48 == 10
at parse (/var/wwww/wampServer/node_modules/snmp-native/lib/snmp.js:223:12)
at EventEmitter.msgReceived (/var/wwww/wampServer/node_modules/snmp-native/lib/snmp.js:405:15)
at emitTwo (events.js:106:13)
at Socket.emit (events.js:191:7)
at UDP.onMessage (dgram.js:549:8)

Message data:
0a

events.js:160
throw er; // Unhandled 'error' event
^
AssertionError: 48 == 10
at parse (/var/wwww/wampServer/node_modules/snmp-native/lib/snmp.js:223:12)
at EventEmitter.msgReceived (/var/wwww/wampServer/node_modules/snmp-native/lib/snmp.js:405:15)
at emitTwo (events.js:106:13)
at Socket.emit (events.js:191:7)
at UDP.onMessage (dgram.js:549:8)`

Suppress Logging to Console

The following line, is the bane of my existence.

https://github.com/calmh/node-snmp-native/blob/master/lib/snmp.js#L432

        console.warn('Response with unknown request ID from ' + rinfo.address + '. Consider increasing timeouts (' + age + ' ms old?).');

I'm not sure what's going wrong, but I'll increase the timeout to eternity and I'll still get this line.

Regardless, as a required module, I suggest that nothing is printed to the console, all errors should emit up to the calling function; let the application decide if it should care.

Trap listener

Hi, your module is great and easy to use. I want to mount a trap listener but you don't have this functionality. Is it going to be on this project? or can you point me on how to implement it?

Thanks in advance

Héctor Fernando

AssertionError 48=83?

Have a long running app that polls over time and graphs but i'm getting a random crash not sure whats causing it

AssertionError: 48 == 83
at parse (C:\Users\C\Desktop\NODE Projects\Dash\node_modules\snmp-native\lib\snmp.js:223:12)
at EventEmitter.msgReceived (C:\Users\C\Desktop\NODE Projects\Dash\node_modules\snmp-native\lib\snmp.js:404:15)
at emitTwo (events.js:106:13)
at Socket.emit (events.js:191:7)
at UDP.onMessage (dgram.js:540:8)

Message data:
53 46 4a 00 1c 00 00 00 00 00 00 00 00 00 00 00
41 09 f8 50 00 01 01 00 00 00 d9 76

events.js:160
throw er; // Unhandled 'error' event
^
AssertionError: 48 == 83
at parse (C:\Users\C\Desktop\NODE Projects\Dash\node_modules\snmp-native\lib\snmp.js:223:12)
at EventEmitter.msgReceived (C:\Users\C\Desktop\NODE Projects\Dash\node_modules\snmp-native\lib\snmp.js:404:15)
at emitTwo (events.js:106:13)
at Socket.emit (events.js:191:7)
at UDP.onMessage (dgram.js:540:8)

Avoid exit on AssertionError

I have an a problem with errors caused with malformated packets. We are using autobahn and native-snmp as service or module running on it.
In these cases, when an AssertionError is raised, the module exits as if an exception was ocurred, stopping it all.

2018-05-21T12:20:58-0300 [Guest       25380] Woops! An error occurred while parsing an SNMP message. :(
2018-05-21T12:20:58-0300 [Guest       25380] To have this problem corrected, please report the information below verbatim
2018-05-21T12:20:58-0300 [Guest       25380] via email to [email protected] or by creating a GitHub issue at
2018-05-21T12:20:58-0300 [Guest       25380] https://github.com/calmh/node-snmp-native/issues
2018-05-21T12:20:58-0300 [Guest       25380] Thanks!
2018-05-21T12:20:58-0300 [Guest       25380] AssertionError: false == true
2018-05-21T12:20:58-0300 [Guest       25380] at parse (/var/www/project/wampServer/node_modules/snmp-native/lib/snmp.js:236:12)
2018-05-21T12:20:58-0300 [Guest       25380] at EventEmitter.msgReceived (/var/www/project/wampServer/node_modules/snmp-native/lib/snmp.js:416:15)
2018-05-21T12:20:58-0300 [Guest       25380] at emitTwo (events.js:106:13)
2018-05-21T12:20:58-0300 [Guest       25380] at Socket.emit (events.js:191:7)
2018-05-21T12:20:58-0300 [Guest       25380] at UDP.onMessage (dgram.js:549:8)
2018-05-21T12:20:58-0300 [Guest       25380] Message data:
2018-05-21T12:20:58-0300 [Guest       25380] 30 82 00 38 02 01 01 04 81 06 70 75 62 6c 69 63
2018-05-21T12:20:58-0300 [Guest       25380] a2 82 00 28 02 04 28 32 78 01 02 01 00 02 01 00
2018-05-21T12:20:58-0300 [Guest       25380] 30 82 00 18 30 82 00 14 06 82 00 08 2b 06 01 02
2018-05-21T12:20:58-0300 [Guest       25380] 01 01 03 00 43 82 00 04 01 4d ce af
2018-05-21T12:20:58-0300 [Guest       25380] events.js:160
2018-05-21T12:20:58-0300 [Guest       25380] throw er; // Unhandled 'error' event
2018-05-21T12:20:58-0300 [Guest       25380] ^
2018-05-21T12:20:58-0300 [Guest       25380] AssertionError: false == true
2018-05-21T12:20:58-0300 [Guest       25380] at parse (/var/www/project/wampServer/node_modules/snmp-native/lib/snmp.js:236:12)
2018-05-21T12:20:58-0300 [Guest       25380] at EventEmitter.msgReceived (/var/www/project/wampServer/node_modules/snmp-native/lib/snmp.js:416:15)
2018-05-21T12:20:58-0300 [Guest       25380] at emitTwo (events.js:106:13)
2018-05-21T12:20:58-0300 [Guest       25380] at Socket.emit (events.js:191:7)
2018-05-21T12:20:58-0300 [Guest       25380] at UDP.onMessage (dgram.js:549:8)
2018-05-21T12:20:58-0300 [Controller  25341] Guest worker-005 exited with error A process has ended with a probable error condition: process ended with exit code 1.

I could fix it if, instead stop with an AssertionError, the module would continue its execution and only returning an error in the response.

sessionSnmp.get({ oid: getIdOid }, function(error, varbinds){
	if(error) {				// <--- I would like see the error here
		logger.error("error!");
		logger.error(error.toString());
		result.errorDescription = error.toString();
		d.resolve(result);
	} else {     
		try{
			result.uptime = varbinds[0].value;
			result.error = 'false';
			d.resolve(result);        
		}
		catch(e){			// <--- ...or here
			logger.error(e);
			result.errorDescription = e;
			d.resolve(result);
		}
	}
});

How I could do this?

Can't set Octet String

In linux snmpset i can do this to set octet string information :

snmpset -c mycomm -v2c MyHost 1.3.6.1.4.1.20858.10.12.1.5.2.0 x "00 19 5E E1 36 B0"

To set such a string. I do this in the library:

Session.set( {
oid: [1,3,6,1,4,1,20858,10,12,1,5,2,0],
value: "00 19 5E E1 36 B0",
type: 4
}, ...............

And all i get is a TImeout! Can you help, or point me to where i should go to debug this?

vb.valueHex and vb.valueRaw length problem

Retrieving multiple values with getAll will return vb.valueHex and vb.valueRaw much longer than the SNMP response justifies. The first values includes header and value of the remaining ones in same packet.

I have tried my luck with a patch here. Somebody experienced with SNMP and javascript should at least review and conduct own tests before we roll it into anything others might eventually run!

*** snmp-native/lib/snmp.js 2015-04-06 21:22:58.000000000 +0200
--- snmp-native-MOGUL/lib/snmp.js   2015-11-12 19:49:58.004650751 +0100
*************** function parse(buf) {
*** 272,280 ****
          // routine. For the SNMPv2c error types, we simply set the
          // value to a text representation of the error and leave handling
          // up to the user.
!         vbhdr = asn1ber.typeAndLength(bvb)
!         bvb = bvb.slice(vbhdr.header + vbhdr.len)
!         vb.type = bvb[0];
          if (vb.type === asn1ber.types.Null) {
              // Null type.
              vb.value = null;
--- 272,281 ----
          // routine. For the SNMPv2c error types, we simply set the
          // value to a text representation of the error and leave handling
          // up to the user.
!         var vb_name_hdr = asn1ber.typeAndLength(bvb)
!         bvb = bvb.slice(vb_name_hdr.header + vb_name_hdr.len)
!         var vb_value_hdr = asn1ber.typeAndLength(bvb);
!         vb.type = vb_value_hdr.type;
          if (vb.type === asn1ber.types.Null) {
              // Null type.
              vb.value = null;
*************** function parse(buf) {
*** 317,323 ****
          }

          // Take the raw octet string value and preseve it as a buffer and hex string.
!         vb.valueRaw = bvb.slice(vbhdr.header);
          vb.valueHex = vb.valueRaw.toString('hex');

          // Add the request id to the varbind (even though it doesn't really belong)
--- 318,324 ----
          }

          // Take the raw octet string value and preseve it as a buffer and hex string.
!         vb.valueRaw = bvb.slice(vb_value_hdr.header, vb_value_hdr.header + vb_value_hdr.len);
          vb.valueHex = vb.valueRaw.toString('hex');

          // Add the request id to the varbind (even though it doesn't really belong)

Pushing up to 16 VarBinds in packet can cause some devices to drop packet.

// Push up to 16 varbinds in the same message.
// The number 16 isn't really that magical, it's just a nice round
// number that usually seems to fit withing a single packet and gets
// accepted by the switches I've tested it on.
for (m = 0; m < 16 && c < options.oids.length; m++) {

I have run into a few networked devices (mostly resource-constrained, such as UPS network cards), which will just drop a packet which has has tried to shove up to 16 Var Binds in it, due to it being too large. By changing this value to 5 or 6, the device will accept it.

Excerpt from the SNMP Protocol Specification RFC1157 Page 16, Chapter 4:

An implementation of this protocol need not accept messages whose length exceeds 484 octets.

I will look into a way to determine the real-time size as the packet gets constructed to see if we can limit the size of the packet to 484 bytes.

Assertion failure on reading UDP response

Sometimes I get assertion errors when fetching sysdescr.0 from 4000+ switches with 30 concurrent fetches (limited by queue).

AssertionError: 48 == 60
at parse (/usr/home/kanavis/nms/tools/node_modules/snmp-native/lib/snmp.js:207:12)
at EventEmitter.msgReceived (/usr/home/kanavis/nms/tools/node_modules/snmp-native/lib/snmp.js:387:15)
at Socket.emit (events.js:110:17)
at UDP.onMessage (dgram.js:472:8)

Message data:
3c 31 33 34 3e 4d 61 72 20 32 31 20 31 38 3a 32
34 3a 34 34 20 46 6f 72 77 61 72 64 65 64 20 66
72 6f 6d 20 64 65 73 33 35 32 36 2d 73 68 75 68
31 36 6b 35 2d 32 2e 73 77 2e 72 69 6e 65 74 2e
72 75 3a 20 31 39 32 2e 31 36 38 2e 32 33 31 2e
35 37 20 49 4e 46 4f 3a 20 50 6f 72 74 20 38 20
6c 69 6e 6b 20 64 6f 77 6e

events.js:85
throw er; // Unhandled 'error' event
^
AssertionError: 48 == 60
at parse (/usr/home/kanavis/nms/tools/node_modules/snmp-native/lib/snmp.js:207:12)
at EventEmitter.msgReceived (/usr/home/kanavis/nms/tools/node_modules/snmp-native/lib/snmp.js:387:15)
at Socket.emit (events.js:110:17)
at UDP.onMessage (dgram.js:472:8)

Broken buffer for ".1.3.6.1.2.1.2.2.1.6" (if address)

Expected: c8:60:0:df:8:61
Got:

{ 
  type: 4,
  value: '�`\u0000�\ba',
  oid: [ 1, 3, 6, 1, 2, 1, 2, 2, 1, 6, 2 ],
  valueRaw: <Buffer c8 60 00 df 08 61>,
  valueHex: 'c86000df0861', // Decoded HEX is 졠ßࡡ
  requestId: 502795267,
  receiveStamp: 1458171248188,
  sendStamp: 1458171248131
}

Response from snmpwalk:

IF-MIB::ifPhysAddress.2 = STRING: c8:60:0:df:8:61

Code:

session.getSubtree({
  oid: '.1.3.6.1.2.1.2.2.1.6'
}, function(error, varbinds) {
  if (!error && varbinds.length) {
    varbinds.forEach(function(vb) {
      console.log(vb);
    });
  }
});

Or am I doing something wrong?

Responses truncated at/around 129 characters

I'm seeing an issue where long snmp responses are being truncated (to 129 characters). For example a really long sysDescr.

I re-produced the issue using a few lines of sample code on the git page so I'm pretty sure it's something within the node-snmp-native library that's truncating it.

BH

Incorrect handling of last timeout (causes retransmit; should not)

I've noticed that I get timeouts sometimes:

Response with unknown request ID from x.x.x.x. Consider increasing timeouts (30112 ms old?).

Looking at the traffic using tcpdump I can see that the original packet did timeout, and there is a re-transmit carried out after 30s. The answer, however, is discarded with the above error message.

Looking at the code it seems that the request id containing the timestamp of the original packet is not updated for the re-transmit, which means that the packet is in effect timed out before it is even re-transmitted.

SNMP-community starting with #

Using a community that start with # gives timeout, changing community to something not starting with a # works just fine.

I've seen similar issues on Cisco-APIs, might % in the beginning be affected as well?

infinite getNext() in getSubtree()

I've one switch with some problem. When I use the getSubtree() api to fetch the switch's ifOperStatus, it cannot stop. Then I look into the code, found that it called getNext() infinitely, cause of the varbinds[0].value is null which has not been considered.

Here is the response of the switch when I call it use the snmpgetnext command:

$>snmpgetnext -v 2c -c xxx xx.xx.xx.xx ifOperStatus.60
Error in packet.
Reason: (genError) A general failure occured
Failed object: IF-MIB::ifOperStatus.60

Is it good at Scaling

If I have millions of network devices.
How can I scale this snmp manager service ?

Several OIDs in the request

Hello!

There is bash script:

#!/bin/sh

HOST=$1
SERIAL=$2
CHANNEL=$3
PORT=$4
VLAN=$5
COMMUNITY=$6

snmpset -v2c -c $COMMUNITY $HOST \
1.3.6.1.4.1.35265.1.22.3.4.1.20.1.8.$SERIAL i 4 \
1.3.6.1.4.1.35265.1.22.3.4.1.3.1.8.$SERIAL u $CHANNEL \
1.3.6.1.4.1.35265.1.22.3.4.1.4.1.8.$SERIAL u $PORT

sleep 1

snmpset -v2c -c ${COMMUNITY} ${HOST} \
1.3.6.1.4.1.35265.1.22.3.4.1.43.1.8.${SERIAL} u 1 \
1.3.6.1.4.1.35265.1.22.3.14.1.4.1.8.${SERIAL}.1 i 1 \
1.3.6.1.4.1.35265.1.22.3.14.1.5.1.8.${SERIAL}.1 i ${VLAN}

These OIDs must be a single request. Can I make such a request using snmp-native?

AssertionError: 48 == 83

Got the following error:

AssertionError: 48 == 83
    at parse (/srv/httpd/dashboard/node_modules/snmp-native/lib/snmp.js:183:12)
    at EventEmitter.msgReceived (/srv/httpd/dashboard/node_modules/snmp-native/lib/snmp.js:362:15)
    at Socket.EventEmitter.emit (events.js:96:17)
    at UDP.onMessage (dgram.js:350:8)

Message data:
    53 70 6f 74 55 64 70 30 52 37 d8 75 89 71 3d 0e 
    00 01 00 04 48 95 c2 03 a2 b8 ae 7f d6 2e 5a b1 
    45 1e c7 7c e1 54 21 ec 55 61 18 a1 

events.js:68
        throw arguments[1]; // Unhandled 'error' event
                       ^
AssertionError: 48 == 83
    at parse (/srv/httpd/dashboard/node_modules/snmp-native/lib/snmp.js:183:12)
    at EventEmitter.msgReceived (/srv/httpd/dashboard/node_modules/snmp-native/lib/snmp.js:362:15)
    at Socket.EventEmitter.emit (events.js:96:17)
    at UDP.onMessage (dgram.js:350:8)

Do you need some further information?

Error while getting ip address data.

When I use the "snmpget" command from the shell it's okay, but when I use the library, I encounter such a problem.

$ snmpget -v2c -c administrator 192.168.2.60 1.3.6.1.4.1.21317.1.3.2.2.3.4.2.0

output

SNMPv2-SMI::enterprises.21317.1.3.2.2.3.4.2.0 = IpAddress: 192.168.2.60

but when i use the library
I'm getting an output like...

'0,4,192,168,2,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' }

I also add the wireshark output.
simple.pcapng.zip

NPM out of sync with Github

'npm install snmp-native' installs a different version of the module compared to what is on Github. I don't know how many differences there are, but there is one that causes problems for me:

/lib/snmp.js, line 801/807:

if (options.combinedTimeout) {
var combinedTimeoutEvent = function() {
combinedTimeoutExpired = true;
return callback(new Error('Timeout'), results);
};
combinedTimeoutTimer = setTimeout(combinedTimeoutEvent, options.combinedTimeout);
}

The results parameter in the callback should be vbs. This was fixed back in January, so it makes me wonder how old the NPM code is.

multiple OIDs on set

Multiple OIDs on set is allowed?
For example, like this:

snmpset -v2c -c private HOSTNAME .1.3.6.1.4.1.48.9.1.1.0 i 8 .1.3.6.1.4.1.48.9.1.6.0 i 4 .1.3.6.1.4.1.48.9.1.7.0 i 78 .1.3.6.1.4.1.48.9.1.3.0 u 0

Can't resolve 'dgram'

Hi,
when trying to import snmp-native (using webpack) ...
import snmp from 'snmp-native' or
const snmp = require('snmp-native')
... throws this error:
ModuleNotFoundError: Module not found: Error: Can't resolve 'dgram' in '... node_modules/snmp-native/lib'
Thanks for any help!

No type Hex-STRING?

One of my responses is a hex string ��and should not look like this ���`��M���\D�
�'�Y���3���Z�������������d���w����H��{�������@������2�N7;���h�� (4)

Error on parsing SNMP message

I was working with a TCW241
TCW241-Ethernet-I-O-module-user-manual-R4.2.pdf

If i try to interrogate the states of the sensors using ".getAll" I get the following error:

Woops! An error occurred while parsing an SNMP message. :(
To have this problem corrected, please report the information below verbatim
via email to [email protected] or by creating a GitHub issue at
https://github.com/calmh/node-snmp-native/issues

Thanks!

AssertionError [ERR_ASSERTION]: 48 == undefined
    at parse (C:\Sviluppo\GitLab\Clevermind\Cloud\services\Technology-SNMP\node_modules\snmp-native\lib\snmp.js:260:12)
    at Session.msgReceived (C:\Sviluppo\GitLab\Clevermind\Cloud\services\Technology-SNMP\node_modules\snmp-native\lib\snmp.js:411:15)
    at emitTwo (events.js:126:13)
    at Socket.emit (events.js:214:7)
    at UDP.onMessage [as onmessage] (dgram.js:658:8)

Message data:
    30 82 00 1b 02 01 01 04 06 70 75 62 6c 69 63 a2
    82 00 0c 02 04 5c 2c 8c 01 02 01 01 02 01 00
events.js:183
      throw er; // Unhandled 'error' event
      ^

AssertionError [ERR_ASSERTION]: 48 == undefined
    at parse (C:\Sviluppo\GitLab\Clevermind\Cloud\services\Technology-SNMP\node_modules\snmp-native\lib\snmp.js:260:12)
    at Session.msgReceived (C:\Sviluppo\GitLab\Clevermind\Cloud\services\Technology-SNMP\node_modules\snmp-native\lib\snmp.js:411:15)
    at emitTwo (events.js:126:13)
    at Socket.emit (events.js:214:7)
    at UDP.onMessage [as onmessage] (dgram.js:658:8)

Just followed the instructions and shared the problem.

Sensors are not present and problably this is the reason of such situation (maybe when missing the devide doesn't really handle correctly the SNMP standard )
Everything else works correctly.

I would like to be able to handle the error and ignore the OIDs which trigger it, instead of seeing the entire "getAll" explode ( the "abortOnError" options doesn't seem to work ).
Any help to understand it would be nice!

EDIT:
If I use ".get" instead of ".getAll" the problem doesn't occur.
The only difference is that with ".getAll" I use an array of OIDs; if I use ".get" I need to cycle over the array and do the single call for every entry (it's far from perfection but it works)

Error occurred while parsing an SNMP message

Not sure what is causing this. I am doing a fair few SNMP requests per 5 sec and 60 sec. Let me know if you need more information. I should also add this happens infrequently but enough to be annoying.

Woops! An error occurred while parsing an SNMP message. :(
To have this problem corrected, please report the information below verbatim
via email to [email protected] or by creating a GitHub issue at
https://github.com/calmh/node-snmp-native/issues

Thanks!

AssertionError: 48 == 66
at parse (C:\Users\crb\Desktop\snmp\node_modules\snmp-native\lib\snmp.js:228:12)
at EventEmitter.msgReceived (C:\Users\crb\Desktop\snmp\node_modules\snmp-native\lib\snmp.js:410:15)
at emitTwo (events.js:106:13)
at Socket.emit (events.js:191:7)
at UDP.onMessage (dgram.js:548:8)

Message data:
42 00 00 00 05 33 f0 2c d1 1f c5 41 00 97 b0 32
e2 1d 10 5b a4 c0 a8 40 80 ca 6f 01 00 00 00 0f
00 57 00 49 00 4e 00 2d 00 43 00 4c 00 36 00 35
00 33 00 32 00 47 00 45 00 44 00 42 00 48

events.js:160
throw er; // Unhandled 'error' event
^
AssertionError: 48 == 66
at parse (C:\Users\crb\Desktop\snmp\node_modules\snmp-native\lib\snmp.js:228:12)
at EventEmitter.msgReceived (C:\Users\crb\Desktop\snmp\node_modules\snmp-native\lib\snmp.js:410:15)
at emitTwo (events.js:106:13)
at Socket.emit (events.js:191:7)
at UDP.onMessage (dgram.js:548:8)

getSubtree won't retrieve all oids when not in numeric order

As the title suggests the getSubtree function doesn't return all oids if they are not in order. Example below:

When requesting 1.3.6.1.2.1.17.4.3.1.1 with snmpwalk I get the below output and a lot more. You will see after they are not ordered which is fine as they are returned anyway.

OID=.1.3.6.1.2.1.17.4.3.1.1.0.34.100.181.251.62, Type=OctetString, Value=                             
OID=.1.3.6.1.2.1.17.4.3.1.1.120.165.4.237.241.250, Type=OctetString, Value=                         
OID=.1.3.6.1.2.1.17.4.3.1.1.244.206.70.191.124.155, Type=OctetString, Value=                         
OID=.1.3.6.1.2.1.17.4.3.1.1.244.206.70.191.124.154, Type=OctetString, Value=                        
OID=.1.3.6.1.2.1.17.4.3.1.1.120.227.181.207.79.69, Type=OctetString, Value=                         
OID=.1.3.6.1.2.1.17.4.3.1.1.208.23.194.138.146.72, Type=OctetString, Value=                           
OID=.1.3.6.1.2.1.17.4.3.1.1.2.156.2.161.21.112, Type=OctetString, Value=  
.... (there are alot more after this)

Now if I use snmp-native I get nothing as the result. But looking deeper if I add some logging in the getSubtree method I find it stops at 244.206.70.191.124.155 because the next entry is 244.206.70.191.124.154. Which is less than the original.

[ 1, 3, 6, 1, 2, 1, 17, 4, 3, 1, 1, 0, 34, 100, 181, 251, 62 ]
[ 1, 3, 6, 1, 2, 1, 17, 4, 3, 1, 1, 120, 165, 4, 237, 241, 250 ]
[ 1, 3, 6, 1, 2, 1, 17, 4, 3, 1, 1, 244, 206, 70, 191, 124, 155 ]

So this led me to believe the problem lies in the compareOids function. Specifically this piece of code which checks if each value is greater than the last.

    for (i = 0; i < mlen; i++) {
        if (oidA[i] > oidB[i]) {
            return -1;
        } else if (oidB[i] > oidA[i]) {
            return 1;
        }
    }

Now I changed it to this which is working from what I can tell but the original oid needs to be parsed in.

    if(originalOid.length < mlen) {
        for(var i = 0; i < originalOid.length; i++) {
            // Check the oids contain the root oid if they don't stop
            if(originalOid[i] != oidA[i] || originalOid[i] != oidB[i]) {
                return -1;
            }
        }
        return 1;
    } else {
        return -1;
    }

Is there another way to retrieve a list of oids like this that I am missing? If not would be great if getSubtree would support these.

Add support for OSX

Package works on OSX when added from github, but fails to install from npm.
Can you please add Darwin as a valid OS?

$ npm i snmp-native
npm ERR! code EBADPLATFORM
npm ERR! notsup Unsupported platform for [email protected]: wanted {"os":"linux","arch":"any"} (current: {"os":"darwin","arch":"x64"})
npm ERR! notsup Valid OS: linux
npm ERR! notsup Valid Arch: any
npm ERR! notsup Actual OS: darwin
npm ERR! notsup Actual Arch: x64

Parse OID's on SET requests type 6

Let me first say great work and thanks for this module!!...it's been really useful for me.

Recently needed to send some OID value type(6) on a SET request and found that it didin't worked.
I figured then that the OID string on the VALUE parameter was not being parsed correctly, so manually created the array myself...everything worked ok!!

Looking at the module found that the function 'parseSingleOid' does the same thing i did manually, so it would be great to run the SET requests VALUE with type 6 through this 'parseSingleOid'

SNMPv3 support

I know its listed as future development in the readme, but I didn't see a ticket open for it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.