etingof / snmpsim

SNMP Simulator
http://snmplabs.com/snmpsim/
BSD 2-Clause "Simplified" License
389 stars 120 forks source link

Response without variable? #58

Closed Benik3 closed 5 years ago

Benik3 commented 5 years ago

Hello.

Is possible to make respond without any value/OID? E.g. when error is used.
That's what happen to me on one device in real use and I would like to reproduce it.

Thank you

etingof commented 5 years ago

Proper SNMP implementation must always return exactly the same OIDs in response that were found in request. Having said that, the only valid way to receive an empty response would be to send an empty request.

There is currently no way to make snmpsim returning malformed response. May be we should add that feature through a variation module...

Benik3 commented 5 years ago

Yes, it should reply... Just for better info, here is real data from wireshark: snmp_error_1.zip We don't know how this error was made, that's why I'm trying some SNMP simulators (we had problem with driver after this response).

Thanks for reply, we can close this issue if you don't want to leave it into feature :)

etingof commented 5 years ago

Yeah, it seems snmpsim is missing this kind of simulation feature. Perhaps we should have it.

Off the top of my head, may be you could stand up SNMP proxy forwarder in front of snmpsim (or pretty much any SNMP agent) and write a simple plugin for SNMP forwarder which would re-write response PDU in a way you want. That should be doable, I think.

Let me know if you want to proceed this way and need further help.

Benik3 commented 5 years ago

Thanks for tip. I'm novice to Python, but I will try to look on it with my friend :)

Benik3 commented 5 years ago

We tried to get the SNMPproxy working with the rewrite example but without success :/ We got error that there is no route when we try walk.

[2019-01-30 12:59:01,631 INFO TrunkingClient at 127.0.0.1:0, peer 127.0.0.1:30301: client is now connected
2019-01-30 12:59:09,839 ERROR no route configured callflow-id=d84b3e8ebc snmp-engine-id=0x0102030405070809 snmp-transport-domain=1.3.6.1.6.1.1.100 snmp-bind-address=127.0.0.1 snmp-bind-port=1161 snmp-security-model=1 snmp-security-level=1 snmp-security-name=public snmp-credentials-id=<nil> snmp-context-engine-id=0x0102030405070809 snmp-context-name=<nil> snmp-context-id=any-context snmp-pdu=GetNextRequestPDU#1.3.6.1:<nil>, snmp-content-id=any-content snmp-peer-address=127.0.0.1 snmp-peer-port=47107 snmp-peer-id=100
]

P.S. we had to run it on RaspberryPi, because on windows the server even doesn't start

etingof commented 5 years ago

I'd start with example configuration, then modify it to introduce your own plugin.

To troubleshoot the 'no route' problem I'd need to see the entire line saying that.

P.S. we had to run it on RaspberryPi, because on windows the server even doesn't start

If you could share the exact failure, I'd be happy to fix it right away.

p.s. May be we should better move to snmpfwd issue tracker to ease further googling...

etingof commented 5 years ago

Ah, pardon me! I see you've pasted the log line already!

So looking there the snmp-credentials-id=<nil> is the cause of the routing failure. Your incoming SNMP message does not match the configuration. I suspect the problem is with SNMP version - your message uses SNMP v1 (snmp-security-model=1), while in the configuration you might have SNMPv2c (snmp-security-model=2).

Does it make sense?

Benik3 commented 5 years ago

I see :) That's because we copied the snmpwalk example from the wiki where is -v1, and configuration example, where is v2. Too much work today :) We will test tomorrow. On windows it do simply nothing. No error, no output even with debug in console... I will try more tomorrow and eventually I will make issue in the Proxy repository to better further tracking.

Benik3 commented 5 years ago

Hello. We finally got the proxy working and we successfully simulated the response with error 1 (TooBig) and no variables :) Thank you a lot!

etingof commented 5 years ago

Awesome! We should somehow unify the plugins across the whole SNMP tooling... They were conceived at different times, thus they are a bit different.

Benik3 commented 5 years ago

I found one thing, which I don't know if it's correct or not. When I simulate error on one OID, the rest of values in respons is NULL even that they are in the .snmprec. Is that correct? I though that the rest values will be OK. obrazek

obrazek

etingof commented 5 years ago

I think this is how it should be with SNMP. Errors in error-status are "hard errors", they lead to failing the entire operation.

Does it undermine the way how you need to simulate a broken agent?

Benik3 commented 5 years ago

I thought that when there is the error-index, which say that error is on OID 2, the rest will be with good values. But I don't know the SNMP norm, I will try to dig deeper into it :) I was just curious how it will act with request on multiple OIDs and one will be fault :)

Benik3 commented 5 years ago

probably only thing which I found at least saying something more about response is this from RFC 1905.

A GetRequest-PDU is generated and transmitted at the request of a
   SNMPv2 application.

   Upon receipt of a GetRequest-PDU, the receiving SNMPv2 entity
   processes each variable binding in the variable-binding list to
   produce a Response-PDU.  All fields of the Response-PDU have the same
   values as the corresponding fields of the received request except as
   indicated below.  Each variable binding is processed as follows:

(1)  If the variable binding's name exactly matches the name of a
     variable accessible by this request, then the variable binding's
     value field is set to the value of the named variable.

(2)  Otherwise, if the variable binding's name does not have an OBJECT
     IDENTIFIER prefix which exactly matches the OBJECT IDENTIFIER
     prefix of any (potential) variable accessible by this request, then
     its value field is set to `noSuchObject'.

(3)  Otherwise, the variable binding's value field is set to
     `noSuchInstance'.

   If the processing of any variable binding fails for a reason other
   than listed above, then the Response-PDU is re-formatted with the
   same values in its request-id and variable-bindings fields as the
   received GetRequest-PDU, with the value of its error-status field set
   to `genErr', and the value of its error-index field is set to the
   index of the failed variable binding.

   Otherwise, the value of the Response-PDU's error-status field is set
   to `noError', and the value of its error-index field is zero.

   The generated Response-PDU is then encapsulated into a message.  If
   the size of the resultant message is less than or equal to both a
   local constraint and the maximum message size of the originator, it
   is transmitted to the originator of the GetRequest-PDU.

There is that Each variable binding is processed as follows: so in theory variables are processed in loop until error, which set the error status and index. But there is nothing more if the first OK values should be transmitted, if it should stop on the error (so the rest will be NULL) or if it continue ( but then the error-index could be rewritten by another error)... So it looks like this behaviour is not precisely described by RFC and can be implemented in more way...

But it's true that then there is:

4.2.4.  The Response-PDU

   The Response-PDU is generated by a SNMPv2 entity only upon receipt of
   a GetRequest-PDU, GetNextRequest-PDU, GetBulkRequest-PDU,
   SetRequest-PDU, or InformRequest-PDU, as described elsewhere in this
   document.

   If the error-status field of the Response-PDU is non-zero, the value
   fields of the variable bindings in the variable binding list are
   ignored.

Which says that manager should ignore data in response if error status is non zero. So it doesn't care if there are valid or not values :)

BTW there is also that with error "TooBig" the variable list is really empty:

If the size of the resultant message is less than or equal to both a
   local constraint and the maximum message size of the originator, it
   is transmitted to the originator of the GetRequest-PDU.

   Otherwise, an alternate Response-PDU is generated.  This alternate
   Response-PDU is formatted with the same value in its request-id field
   as the received GetRequest-PDU, with the value of its error-status
   field set to "tooBig", the value of its error-index field set to
   zero, and an empty variable-bindings field.
etingof commented 5 years ago

Thanks for digging into the RFC!

But there is nothing more if the first OK values should be transmitted, if it should stop on the error (so the rest will be NULL) or if it continue ( but then the error-index could be rewritten by another error)...

Well, yes. But trouble is that RFC-suggested way how SNMP agent should process request var-bindings is that even reads are done in phases (first test all var-bindings, the get all var-bindings). That implies that get phase might never be reached should test phase fails...

BTW there is also that with error "TooBig" the variable list is really empty:

Indeed... Let me see if I could fix that.

etingof commented 5 years ago

BTW there is also that with error "TooBig" the variable list is really empty:

So #59 and unreleased pysnmp should have the rest of PDU errors implemented and var-bindings reset to empty on tooBig error.

etingof commented 5 years ago

JFYI: just released both pysnmp and snmpsim.

Benik3 commented 5 years ago

Great! I will test it on Monday ;)

Benik3 commented 5 years ago

I don't know if I made something wrong, but I got an error.
I installed it this way (on ubuntu minimal):
1.) sudo pip uninstall snmpsim and sudo pip uninstall pysnmp (to uninstall the old version) 2.)git clone snmpsim and pysnmp 3.)sudo python setup.py install for pysnmp 4.)sudo python setup.py install for snmpsim

When I try to run snmpsimd I got: obrazek

etingof commented 5 years ago

You've pulled pysnmp 5 from master. Either just pip install pysnmp or pull it from the release-4.4.9 branch.

Benik3 commented 5 years ago

I got it :) And I successfully tested the toobig error! It really returned error 1 and empty var-binds filed :)

Benik3 commented 5 years ago

I think that we can close this as solved :)