etingof / pysnmp

Python SNMP library
http://snmplabs.com/pysnmp/
BSD 2-Clause "Simplified" License
568 stars 188 forks source link

Incomplete OID Retrieval: SNMP Walk (nextCmd/bulkCmd) Fails to Capture All OIDs #453

Closed Christo-Deyzel closed 7 months ago

Christo-Deyzel commented 7 months ago

Hi everyone,

I'm encountering an issue with PySNMP where the SNMP walk is not retrieving all the expected OIDs.

The last few OIDs that PySNMP manages to retrieve are as follows: 1.3.6.1.2.1.43.8.2.1.14.1.2 = Samsung Electronics 1.3.6.1.2.1.43.8.2.1.15.1.1 = Samsung Internal Input Tray 1.3.6.1.2.1.43.8.2.1.15.1.2 = Samsung External Media Handler 1.3.6.1.2.1.43.8.2.1.15.1.2 = No more variables left in this MIB View ...only 515 results

When I use a standard SNMP utility, it successfully retrieves 4700 results, and the point where PySNMP stops corresponds to a null value: .1.3.6.1.2.1.43.8.2.1.14.1.1 = String: "Samsung Electronics" .1.3.6.1.2.1.43.8.2.1.14.1.2 = String: "Samsung Electronics" .1.3.6.1.2.1.43.8.2.1.15.1.1 = String: "Samsung Internal Input Tray" .1.3.6.1.2.1.43.8.2.1.15.1.2 = String: "Samsung External Media Handler" .1.3.6.1.2.1.43.8.2.1.16.1.1 = Null: .1.3.6.1.2.1.43.8.2.1.16.1.2 = Null: .1.3.6.1.2.1.43.8.2.1.17.1.1 = String: "0001" ...continues to rest 4700 results

At the precise moment when the SNMP Utility returns null, PySNMP prematurely stops, suggesting a potential error handling issue.

Is there a setting I am missing?

Steps to Reproduce:

#error_indication, error_status, error_index, var_binds = cmd_gen.bulkCmd(
    cmdgen.CommunityData('public', mpModel=0),
    cmdgen.UdpTransportTarget(([device_ip], 161), timeout=20, retries=2),
    0, 50,
    '1.3',  # Starting OID for the walk
    maxRows=0,
    maxCalls=0,
    lookupMib = True,
    lexicographicMode = True,
    ignoreNonIncreasingOid = False,
)
if error_indication:
    print(f"Error: {error_indication}")
    return 'Error Indication'

if error_status:
    print(f"Error: {error_status}")
    return 'Error Status'

if error_index:
    print(f"Error: {error_index}")
    return 'Error Index'

# Process the results
for var_bind_table_row in var_binds:
    for name, val in var_bind_table_row:
        print(f"{name.prettyPrint()} = {val.prettyPrint()}")`

Expected Behavior: I expected the SNMP walk using PySNMP to retrieve all the specified OIDs.

Actual Behavior: PySNMP retrieves less than 600 OIDs, and the SNMP walk stops at a point where there is a null value. This behavior is inconsistent with the results obtained from the standard SNMP utility.

Additional Information: The standard SNMP utility used for comparison is SNMP Utility. - Download Utility here No error messages are provided by PySNMP; the walk simply stops prematurely. My environment details: Python Version: 3.8 PySNMP Version: 4.4.12 Operating System: windows 10

lextm commented 7 months ago

There were quite a few reports on walk operations, so you need to enable debugging https://www.pysnmp.com/pysnmp/examples/#using-these-examples and then compare to those.

Christo-Deyzel commented 7 months ago

Hi @lextm,

Thank you for your prompt response. I have utilized the debug command as suggested and have collected the following results from my snmp walk:

When the returned value is null (observed in the standard SNMP walk results) no errors are raised. The error-status is 'noError'. But it stops everytime a null value is introduced in the walk. I conducted the walk from various angles, consistently obtaining the same results. In the alternative SNMP utility, there are over 300 null values from 4700 values, all reacting the same when I change the walk root subtree.

I am eager to contribute to resolving this issue, given that SNMP walking is a critical component of my application. I am willing to assist with development or provide any information needed for debugging. If you prefer, I am open to allowing you to log onto my machine for direct debugging.

Here is a snippet of the response for the OID with a null value:

2023-11-20 09:53:51,897 pysnmp: sendPdu: current time 5 ticks, one tick is 0.5 seconds 2023-11-20 09:53:51,897 pysnmp: sendPdu: new sendPduHandle 727660, timeout 40.0 ticks, cbFun <bound method CommandGenerator.processResponsePdu of <pysnmp.entity.rfc3413.cmdgen.BulkCommandGenerator object at 0x000002B3F98A7DC0>> 2023-11-20 09:53:51,911 pysnmp: sendPdu: MP succeeded 2023-11-20 09:53:51,915 pysnmp: receiveMessage: msgVersion 0, msg decoded 2023-11-20 09:53:51,917 pysnmp: receiveMessage: MP succeded 2023-11-20 09:53:51,917 pysnmp: receiveMessage: PDU GetResponsePDU: request-id=2315122 error-status=noError error-index=0 variable-bindings=VarBindList: VarBind: name=1.3.6.1.2.1.43.8.2.1.16.1.1 value=ObjectSyntax: simple=SimpleSyntax: empty=

2023-11-20 09:53:51,928 pysnmp: sendPdu: current time 5 ticks, one tick is 0.5 seconds 2023-11-20 09:53:51,936 pysnmp: sendPdu: new sendPduHandle 727661, timeout 40.0 ticks, cbFun <bound method CommandGenerator.processResponsePdu of <pysnmp.entity.rfc3413.cmdgen.BulkCommandGenerator object at 0x000002B3F98A7DC0>> 2023-11-20 09:53:51,938 pysnmp: sendPdu: MP succeeded 2023-11-20 09:53:51,940 pysnmp: receiveMessage: msgVersion 0, msg decoded 2023-11-20 09:53:51,942 pysnmp: receiveMessage: MP succeded 2023-11-20 09:53:51,943 pysnmp: receiveMessage: PDU GetResponsePDU: request-id=2315124 error-status=noError error-index=0 variable-bindings=VarBindList: VarBind: name=1.3.6.1.2.1.43.8.2.1.16.1.1 value=ObjectSyntax: simple=SimpleSyntax: empty=

Here is a response from a oid that returns Samsung External Media Handler:

2023-11-20 09:53:51,830 pysnmp: sendPdu: current time 4 ticks, one tick is 0.5 seconds 2023-11-20 09:53:51,843 pysnmp: sendPdu: new sendPduHandle 727659, timeout 40.0 ticks, cbFun <bound method CommandGenerator.processResponsePdu of <pysnmp.entity.rfc3413.cmdgen.BulkCommandGenerator object at 0x000002B3F98A7DC0>> 2023-11-20 09:53:51,879 pysnmp: sendPdu: MP succeeded 2023-11-20 09:53:51,892 pysnmp: receiveMessage: msgVersion 0, msg decoded 2023-11-20 09:53:51,894 pysnmp: receiveMessage: MP succeded 2023-11-20 09:53:51,895 pysnmp: receiveMessage: PDU GetResponsePDU: request-id=2315120 error-status=noError error-index=0 variable-bindings=VarBindList: VarBind: name=1.3.6.1.2.1.43.8.2.1.15.1.2 value=ObjectSyntax: simple=SimpleSyntax: string=Samsung External Media Handler

2023-11-20 09:53:51,897 pysnmp: receiveMessage: cache read by sendPduHandle 727659 2023-11-20 09:53:51,897 pysnmp: receiveMessage: processResponsePdu succeeded 2023-11-20 09:53:51,897 pysnmp: sendPdu: securityName s-5824012256909706693, PDU GetNextRequestPDU: request-id=2315122 error-status=noError error-index=0 variable-bindings=VarBindList: VarBind: name=1.3.6.1.2.1.43.8.2.1.15.1.2 value=ObjectSyntax: simple=SimpleSyntax: empty=

I appreciate your assistance and look forward to your guidance on resolving this matter.

Best regards, Christo

Christo-Deyzel commented 7 months ago

I managed to find a better solution for walking.

https://github.com/lextudio/pysnmp

@lextm thanks for forking the above and improving it :)

Christo-Deyzel commented 7 months ago

https://github.com/lextudio/pysnmp

lextm commented 7 months ago

Then the changes might come from pysnmp community patches (from Splunk or others) that have been integrated into 5.0 releases.

You can read #429 to learn more about the ecosystem changes.

Christo-Deyzel commented 7 months ago

Again appreciate the initiative @lextm!