Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

puresnmp.exc.ErrorResponse: unknown error (status-code: 17) on OID 1.3.6.1.2.1.1.4.0 #62

Open
beruhan opened this issue Jul 1, 2019 · 6 comments
Labels

Comments

@beruhan
Copy link

beruhan commented Jul 1, 2019

I use the example in the doc,but I raise exception:

from puresnmp import set
    from puresnmp.x690.types import OctetString

    IP = "192.168.12.133"
    COMMUNITY = 'private'
    OID = '1.3.6.1.2.1.1.4.0'

    result = set(IP, COMMUNITY, OID, OctetString(b'I am contact'))
    print(repr(result))

the exception as follows:

Traceback (most recent call last):
  File "D:/work/project/iot_exploit/iot_exploit/core/protocols/snmp_client.py", line 74, in <module>
    result = set(IP, COMMUNITY, OID, OctetString(b'I am contact'))
  File "C:\Python36\lib\site-packages\puresnmp\api\pythonic.py", line 136, in set
    result = multiset(ip, community, [(oid, value)], port, timeout=timeout)
  File "C:\Python36\lib\site-packages\puresnmp\api\pythonic.py", line 149, in multiset
    raw_output = raw.multiset(ip, community, mappings, port, timeout)
  File "C:\Python36\lib\site-packages\puresnmp\api\raw.py", line 321, in multiset
    raw_response = Sequence.from_bytes(response)
  File "C:\Python36\lib\site-packages\puresnmp\x690\types.py", line 170, in from_bytes
    return cls.decode(data)
  File "C:\Python36\lib\site-packages\puresnmp\x690\types.py", line 400, in decode
    value, data = pop_tlv(data)
  File "C:\Python36\lib\site-packages\puresnmp\x690\types.py", line 116, in pop_tlv
    value = cls.from_bytes(chunk)
  File "C:\Python36\lib\site-packages\puresnmp\x690\types.py", line 170, in from_bytes
    return cls.decode(data)
  File "C:\Python36\lib\site-packages\puresnmp\pdu.py", line 231, in decode
    return super(GetResponse, cls).decode(data)
  File "C:\Python36\lib\site-packages\puresnmp\pdu.py", line 117, in decode
    raise exception
puresnmp.exc.ErrorResponse: unknown error (status-code: 17) on OID 1.3.6.1.2.1.1.4.0

@exhuma
Copy link
Owner

exhuma commented Jul 2, 2019

This exception means that the device itself returns an error with the code 17. The meaning of this code is non-standard and should be documented by the device manufacturer. Possibly in MIB files.

But to make sure puresnmp is behaving correctly, can you try to run the following two commands on a Linux CLI and attach the output please?

snmpget -v2c -c <your_community> -On <ip-address> 1.3.6.1.2.1.1.4.0

and

snmpget -v2c -c <your_community> -On <ip-address> .1.3.6.1.2.1.1.4.0

In case this works, double-check that it is still broken in puresnmp. I've come accross some devices that only work... sometimed 😄

@alexxxe
Copy link
Contributor

alexxxe commented Jun 4, 2020

I think it could be related to the case when OID does not exist.
In my case the folowing is thrown when code is trying to get one of not exisitng OIDs:

Traceback (most recent call last):

await self.device.snmp_get('1.3.6.1.4.1.32584.1.1.1.12.2.0')
File "/usr/lib/preseem/netpoll/snmp_client.py", line 124, in snmp_get
val = await psnmp.get(self.host, self.comm, oid)
File "/usr/local/lib/python3.7/site-packages/puresnmp/aio/api/raw.py", line 83, in get
ip, community, [oid], port, timeout=timeout)
File "/usr/local/lib/python3.7/site-packages/puresnmp/aio/api/raw.py", line 112, in multiget
Sequence.from_bytes(response)
File "/usr/local/lib/python3.7/site-packages/puresnmp/x690/types.py", line 169, in from_bytes
return cls.decode(data)
File "/usr/local/lib/python3.7/site-packages/puresnmp/x690/types.py", line 382, in decode
value, data = pop_tlv(data)
File "/usr/local/lib/python3.7/site-packages/puresnmp/x690/types.py", line 117, in pop_tlv
value = cls.from_bytes(chunk)
File "/usr/local/lib/python3.7/site-packages/puresnmp/x690/types.py", line 169, in from_bytes
return cls.decode(data)
File "/usr/local/lib/python3.7/site-packages/puresnmp/pdu.py", line 286, in decode
return super(GetResponse, cls).decode(data)
File "/usr/local/lib/python3.7/site-packages/puresnmp/pdu.py", line 145, in decode
raise exception
puresnmp.exc.GenErr: General Error (genErr) (status-code: 5) on OID 1.3.6.1.4.1.32584.1.1.1.12.2.0`

When I try to use Linux CLI based snmpget with the same OID it just return nothing.

@exhuma
Copy link
Owner

exhuma commented Jun 5, 2020

@alexxxe: the last line in the traceback says that the device returned an SNMP packet with an error-code of "5". These error codes are mapped to Python exceptions and are raised if a device returns such a packet.

There is a special error-status (2) for non-existing OIDs. So it's either incorrectly reported as "general-error" by the device, or the OID exists, and something else is wrong on the device.

I see this comes from a multiget call. And I can see that having the whole call crash out with an exception if only one of the OIDs causes issues like this is a problem. It might be worth retuning the exceptions instances in that case, instead of raising them. This would allow for more graceful degradation of client-code without losing details on errors. I'll think about how to integrate this feature.

@exhuma
Copy link
Owner

exhuma commented Jun 5, 2020

... actally, scratch my last comment about adding a more "forgiving" return value. The error-status is a field in the returning PDU, so unfortunately the whole respose packet is tagged as error and raising an Exception is the correct way of handling this.

@alexxxe
Copy link
Contributor

alexxxe commented Jun 8, 2020

@exhuma , thanks for your response. I thinkg in my case device is incorrectly responsed with error-status: 5 on non-existing OID. And yes, this is still a problem in case when the one not exisiting OID fails the whole call.

@exhuma
Copy link
Owner

exhuma commented Jun 9, 2020

I'm actually not sure I can do anything about that. SNMP exchanges messages as "PDU" messages. The error-code is part of the top-level information in that PDU. The requested variables/values are embedded inside that PDU.

The error-status "5" flags the whole PDU as erroneous. So in a way it is correct to raise this as an exception.

Other errors like "NoSuchOID" or "NoSuchInstance" are actually error values which are not written into the PDU error-status field, but rather in the variable value.

I will keep thinking on this. I am currently reading through the SNMPv3 RFCs to get support for that too, but I'm only advancing slowly. But I will need to keep some way in the code to raise errors if something goes wrong on the device. If I will make this more lenient, then devices which correctly return errors might lead to incorrect code/values downstream (in the client code). I prefer to "fail fast".

I understand this is not a solution if you have a device which misbehaves, but which you still want to query via SNMP.

I'm currently using puresnmp on several thousand devices on a daily basis, and I've come across some funky behaviours myself. On those extreme/blocking cases I usually contact the device manufacturer and so far they always agreed that it was a bug in their OS and fixed it.

@exhuma exhuma added the v1.x label May 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants