markabrahams / node-net-snmp

JavaScript implementation of the Simple Network Management Protocol (SNMP)
211 stars 97 forks source link

Response does not match oid error #177

Closed daniep01 closed 2 years ago

daniep01 commented 3 years ago

Hi,

When issuing the following command from bash I get the correct answer = 1.

snmpget  -v2c -cpublic 192.168.1.22 1.3.6.1.4.1.38218.1.7.1.1.4.1
iso.3.6.1.4.1.38218.1.7.1.1.4.1.0 = INTEGER: 1

Doing the same with node-net-snmp creates an error:

ResponseInvalidError: OID '1.3.6.1.4.1.38218.1.7.1.1.4.1' in request at positiion '0' does not match OID '1.3.6.1.4.1.38218.1.7.1.1.4.1.0' in response at position '0'

I can see that there is an additional '.0' in the response from the device, is there anyway to ignore this and get the value regardless?

markabrahams commented 3 years ago

Hi @daniep01 - what you're getting from your device is an incorrect response to the Net-SNMP GetRequest. There's no variable value at 1.3.6.1.4.1.38218.1.7.1.1.4.1, so the device should be returning a noSuchInstance to the snmpget for that OID, not the value of another OID (1.3.6.1.4.1.38218.1.7.1.1.4.1.0). Additionally, on the client side, you're sending the wrong OID. If you want the value at OID 1.3.6.1.4.1.38218.1.7.1.1.4.1.0, you should request this with a GetRequest, not 1.3.6.1.4.1.38218.1.7.1.1.4.1.

To account for this, you can do one of two things: (1) Correct your error on the calling side by adding the .0 to your original OID. (2) Correct your error on the calling side by using a GetNextRequest with your original OID (1.3.6.1.4.1.38218.1.7.1.1.4.1).

daniep01 commented 3 years ago

Hi @markabrahams Thanks for your quick reply, I think my mistake is that I am reading from a table and so should use a table method.

markabrahams commented 3 years ago

The ".0" on the end of the OID suggests it's very likely that you're reading a scalar variable, not a table; the MIB that contains the OID would be the authority on this if you have it (I don't).

Your mistake here is not adding the ".0" onto the OID of the GetRequest.

daniep01 commented 3 years ago

Hi @markabrahams

Here is the MIB in question pdusnmp

Adding .0 generates an error

snmpget  -v2c -public 81.13.24.14 1.3.6.1.4.1.38218.1.7.1.1.4.1.0
iso.3.6.1.4.1.38218.1.7.1.1.4.1.0.0 = No Such Object available on this agent at this OID
markabrahams commented 3 years ago

OK the MIB confirms it's in a table, not a scalar, so the ".0" is not valid - ignore my comments on that being a scalar.

First, confirm what's in that MIB table: snmpwalk -v2c -public 81.13.24.14 1.3.6.1.4.1.38218.1.7

As mentioned previously, it looks like there's a bug in the agent that's returning an incorrect response to a GetRequest, so you might have to come up with a workaround that gets you what you need (e.g. try the library's session.table or session.getNext)

cynik606 commented 2 years ago

Hi there, I have similar issue. We are trying to get the data from the following OID's: image

As you can see all of them contain some data (19, 25, 19) but we are able to get it only from the first one (.1.5.0). The second one gives us this error message: "ResponseInvalidError: OID '1.3.6.1.4.1.42814.1.3.20.1.5.1' in request at positiion '0' does not match OID '1.3.6.1.4.1.42814.1.3.20.1.5.1.0' in response at position '0'" It isn't clear for us. Could you give us some advise? PS. MIB file from the device manufacturer attached owexpl.zip .

cynik606 commented 2 years ago

One remark. We have just tested another module: https://www.npmjs.com/package/snmp-node and there is no problem with reading the second OID (1.3.6.1.4.1.42814.1.3.20.1.5.1).

markabrahams commented 2 years ago

Hi @cynik606 - if you could follow the guidelines in CONTRIBUTING.md on what to include in a bug report, that would provide the information needed to troubleshoot this. In particular these points:

Also, if you can use Net-SNMP tools to display the entire table, that would be helpful: snmpwalk -v 2c -c 1.3.6.1.4.1.42814.1.3.20

cynik606 commented 2 years ago

Hi Mark, The script is following:

var snmp = require("net-snmp"); var session = snmp.createSession("192.168.1.23", "public"); var oids = ["1.3.6.1.4.1.42814.1.3.20.1.5.1"]; session.get(oids, function (error, varbinds) { if (error) { console.error(error); } else { for (var i = 0; i < varbinds.length; i++) { if (snmp.isVarbindError(varbinds[i])) { console.error(snmp.varbindError(varbinds[i])); } else { console.log(varbinds[i].value.toString()); } } } session.close(); });

In the zip file "Desktop.zip" you will find two captures:

In the zip file "walk.zip" you will find xml file with the complete SNMP table of the device: walk.zip

markabrahams commented 2 years ago

Hi @cynik606 - thanks very much for the additional info - that gives a good indication of what's going on here.

The packet capture in the failure case clearly shows that the agent on this device has a bug in its SNMP agent implementation where it's returning an incorrect OID in the varbind in the Response packet. Although the GetRequest is for OID: 1.3.6.1.4.1.42814.1.3.20.1.5.1

the device is incorrectly appending an extra zero to this OID in the Response varbind: 1.3.6.1.4.1.42814.1.3.20.1.5.1.0

This library currently reports that mismatch as an error. So the question is this: Should the library's behaviour change in handling this particular error condition? If so, how?

In looking for RFC guidance here, it seems RFC 3416 Section 4.2.4 "The Response-PDU" is the place that should weigh in here. In this section, after some mention of specific cases in handling error-status cases (which is not this particular case), it states "Upon receipt of a Response-PDU, the receiving SNMP entity presents its contents to the application". As an error check of Response OID against original Request OID is not specifically mentioned, this would steer towards changing the library's behaviour so that it simply "presents its contents to the application", incorrect OID and all, without reporting it as an error.

It would be interesting to see what the Net-SNMP snmpget command-line tool does in this situation, if you're able to. If you run command: snmpget -v 2c -c 1.3.6.1.4.1.42814.1.3.20.1.5.1

does that succeed OK? I often use Net-SNMP as a yardstick for behaviour when weighing up options!

I'm reasonably convinced that there is no down-side to not reporting this as an error i.e. ignoring the incorrect OID and just returning the varbind as-is instead. After all, you came here for the value, not the correct or incorrect returned OID.

So options for handling this condition are: (a) change the library to ignore this error condition (b) change the library to ignore this error condition, and also introduce an session option "reportIncorrectOids" to change behaviour to report the error condition as the library does at present (c) leave the default library behaviour as is, but introduce an session option "ignoreIncorrectOids" to ignore this error condition (d) leave the library behaviour as is - and hard luck if you hit this condition!

If you - or anyone else for that matter - has an opinion here, let me know. I'm inclined towards (b).

gavinaiken commented 2 years ago

I'd vote for copying whatever the command line snmpget tool does, with the options to be strict - so probably (b) I guess

markabrahams commented 2 years ago

Thanks @gavinaiken - massive consensus of 2!

Implemented option (b) with change of name of the new session option to "reportOidMismatchErrors". It's in master now and published in version 3.6.4 of the npm.

@daniep01 and @cynik606 - if you could let me know if this fixes your issue, that would be great, as I don't have a misbehaving device to test against.

daniep01 commented 2 years ago

Thank you for making this change. In my case the project is now finished and I made it work sufficiently well somehow. I'll probably not get chance to rework it with the updated library but I appreciate that it's done. 👍🏻

mvduin commented 2 years ago

Don't forget to report this as a bug against the SNMP agents that are sending these bogus replies!

And while it's good to have the ability to disable this check, I'm personally strongly opposed to disabling this check by default, since:

  1. It's the lack of such checks (in other libraries) that sweep these implementation bugs under the rug and allow for them to go unnoticed
  2. Any such mismatch indicates a bug somewhere and requires a moment of investigation to determine whether it's in the client libary or in the agent, and to determine an appropriate workaround if the problem can't be easily fixed.

In this case the best workaround is to ignore the response OID, but that may be different in other cases, depending on what exactly the agent is doing wrong. For example, perhaps a buggy agent might (e.g. due to improper locking on a data structure) sporadically return a correct varbind for the wrong instance of an object, with the correct workaround in that case being to check the response oid and retry on mismatch (while ignoring the OID sporadically results in undetected garbage data). Or perhaps the packet is just getting misparsed due to malformed ASN.1 from the agent and/or some parser bug in this library.

I think it's better to strictly check and report OID mismatches by default and make it the user's decision to use reportOidMismatchErrors: false as workaround if this is appropriate in their particular case and whoever is responsible for the agent is unable or unwilling to fix their bug.

mvduin commented 2 years ago

(I think backwardsGetNext should be false by default for the exact same reasons: I can imagine various agent bugs that could result in GetNext/GetBulk returning varbinds in non-lexicographical order, but the appropriate workaround would depend on what the actual bug is as well as the client's needs, hence should be evaluated on a case by case basis, after first attempting to get the agent fixed obviously.)