diff options
author | Ilya Etingof <etingof@gmail.com> | 2019-11-04 18:50:42 +0100 |
---|---|---|
committer | Ilya Etingof <etingof@gmail.com> | 2019-11-04 18:50:42 +0100 |
commit | eba1b2025b5bb8416c3dc359e91099875787d186 (patch) | |
tree | a6996e8d6c75a29c01a79922622643820c85ae93 | |
parent | a421a36e8498abc0824e81ae96b8e30bc447f2c0 (diff) | |
download | pysnmp-git-eba1b2025b5bb8416c3dc359e91099875787d186.tar.gz |
Command Responder to produce `genErr` SNMP error
Fixes `genErr` handing in Command Responder when mapping MIB
instrumentation exception onto SNMP errors. Prior to this fix,
`genErr` would never be reported back to SNMP manager.
-rw-r--r-- | CHANGES.txt | 6 | ||||
-rw-r--r-- | pysnmp/entity/rfc3413/cmdrsp.py | 121 |
2 files changed, 54 insertions, 73 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 7d8f18ac..61cb0a55 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,8 +1,10 @@ -Revision 4.4.13, released 2019-10-XX +Revision 4.4.13, released 2019-11-XX ------------------------------------ -No changes yet +- Fixed `genErr` handing in Command Responder when mapping MIB instrumentation + exception onto SNMP errors. Prior to this fix, `genErr` would never be + reported back to SNMP manager. Revision 4.4.12, released 2019-09-24 ------------------------------------ diff --git a/pysnmp/entity/rfc3413/cmdrsp.py b/pysnmp/entity/rfc3413/cmdrsp.py index 5cef0a14..80d555ec 100644 --- a/pysnmp/entity/rfc3413/cmdrsp.py +++ b/pysnmp/entity/rfc3413/cmdrsp.py @@ -17,6 +17,27 @@ class CommandResponderBase(object): acmID = 3 # default MIB access control method to use pduTypes = () + smiToSnmpErrorMap = { + pysnmp.smi.error.TooBigError: 'tooBig', + pysnmp.smi.error.NoSuchNameError: 'noSuchName', + pysnmp.smi.error.BadValueError: 'badValue', + pysnmp.smi.error.ReadOnlyError: 'readOnly', + pysnmp.smi.error.GenError: 'genErr', + pysnmp.smi.error.NoAccessError: 'noAccess', + pysnmp.smi.error.WrongTypeError: 'wrongType', + pysnmp.smi.error.WrongLengthError: 'wrongLength', + pysnmp.smi.error.WrongEncodingError: 'wrongEncoding', + pysnmp.smi.error.WrongValueError: 'wrongValue', + pysnmp.smi.error.NoCreationError: 'noCreation', + pysnmp.smi.error.InconsistentValueError: 'inconsistentValue', + pysnmp.smi.error.ResourceUnavailableError: 'resourceUnavailable', + pysnmp.smi.error.CommitFailedError: 'commitFailed', + pysnmp.smi.error.UndoFailedError: 'undoFailed', + pysnmp.smi.error.AuthorizationError: 'authorizationError', + pysnmp.smi.error.NotWritableError: 'notWritable', + pysnmp.smi.error.InconsistentNameError: 'inconsistentName' + } + def __init__(self, snmpEngine, snmpContext): snmpEngine.msgAndPduDsp.registerContextEngineId( snmpContext.contextEngineId, self.pduTypes, self.processPdu @@ -129,97 +150,55 @@ class CommandResponderBase(object): # 3.2.5 varBinds = v2c.apiPDU.getVarBinds(PDU) - errorStatus, errorIndex = 'noError', 0 debug.logger & debug.flagApp and debug.logger( 'processPdu: stateReference %s, varBinds %s' % (stateReference, varBinds)) try: - self.handleMgmtOperation(snmpEngine, stateReference, - contextName, PDU, - (self.__verifyAccess, snmpEngine)) + self.handleMgmtOperation( + snmpEngine, stateReference, contextName, PDU, + (self.__verifyAccess, snmpEngine)) + + return # SNMPv2 SMI exceptions - except pysnmp.smi.error.GenError: + except pysnmp.smi.error.SmiError: errorIndication = sys.exc_info()[1] + debug.logger & debug.flagApp and debug.logger( - 'processPdu: stateReference %s, errorIndication %s' % (stateReference, errorIndication)) + 'processPdu: stateReference %s, errorIndication ' + '%s' % (stateReference, errorIndication)) + if 'oid' in errorIndication: - # Request REPORT generation + # Request MP-model to produce REPORT response statusInformation['oid'] = errorIndication['oid'] statusInformation['val'] = errorIndication['val'] - # Handle PDU-level SMI errors - - except pysnmp.smi.error.TooBigError: - errorStatus, errorIndex = 'tooBig', 0 - # rfc1905: 4.2.1.3 - varBinds = [] - - # this should never bubble up, SNMP exception objects should be passed as values - except pysnmp.smi.error.NoSuchNameError: - errorStatus, errorIndex = 'noSuchName', sys.exc_info()[1]['idx'] + 1 - - except pysnmp.smi.error.BadValueError: - errorStatus, errorIndex = 'badValue', sys.exc_info()[1]['idx'] + 1 - - except pysnmp.smi.error.ReadOnlyError: - errorStatus, errorIndex = 'readOnly', sys.exc_info()[1]['idx'] + 1 - - except pysnmp.smi.error.GenError: - errorStatus, errorIndex = 'genErr', sys.exc_info()[1]['idx'] + 1 - - except pysnmp.smi.error.NoAccessError: - errorStatus, errorIndex = 'noAccess', sys.exc_info()[1]['idx'] + 1 - - except pysnmp.smi.error.WrongTypeError: - errorStatus, errorIndex = 'wrongType', sys.exc_info()[1]['idx'] + 1 - - except pysnmp.smi.error.WrongLengthError: - errorStatus, errorIndex = 'wrongLength', sys.exc_info()[1]['idx'] + 1 + errorStatus = self.smiToSnmpErrorMap.get( + errorIndication.__class__, 'genErr') - except pysnmp.smi.error.WrongEncodingError: - errorStatus, errorIndex = 'wrongEncoding', sys.exc_info()[1]['idx'] + 1 - - except pysnmp.smi.error.WrongValueError: - errorStatus, errorIndex = 'wrongValue', sys.exc_info()[1]['idx'] + 1 - - except pysnmp.smi.error.NoCreationError: - errorStatus, errorIndex = 'noCreation', sys.exc_info()[1]['idx'] + 1 - - except pysnmp.smi.error.InconsistentValueError: - errorStatus, errorIndex = 'inconsistentValue', sys.exc_info()[1]['idx'] + 1 - - except pysnmp.smi.error.ResourceUnavailableError: - errorStatus, errorIndex = 'resourceUnavailable', sys.exc_info()[1]['idx'] + 1 - - except pysnmp.smi.error.CommitFailedError: - errorStatus, errorIndex = 'commitFailed', sys.exc_info()[1]['idx'] + 1 + try: + errorIndex = errorIndication['idx'] + 1 - except pysnmp.smi.error.UndoFailedError: - errorStatus, errorIndex = 'undoFailed', sys.exc_info()[1]['idx'] + 1 + except KeyError: + errorIndex = 1 - except pysnmp.smi.error.AuthorizationError: - errorStatus, errorIndex = 'authorizationError', sys.exc_info()[1]['idx'] + 1 + if len(varBinds) > errorIndex: + errorIndex = 1 - except pysnmp.smi.error.NotWritableError: - errorStatus, errorIndex = 'notWritable', sys.exc_info()[1]['idx'] + 1 + # rfc1905: 4.2.1.3 + if errorStatus == 'tooBig': + errorIndex = 0 + varBinds = [] - except pysnmp.smi.error.InconsistentNameError: - errorStatus, errorIndex = 'inconsistentName', sys.exc_info()[1]['idx'] + 1 - - except pysnmp.smi.error.SmiError: - errorStatus, errorIndex = 'genErr', len(varBinds) and 1 + # Report error + self.sendVarBinds(snmpEngine, stateReference, errorStatus, + errorIndex, varBinds) except pysnmp.error.PySnmpError: - self.releaseStateInformation(stateReference) - return - - else: # successful request processor must release state info - return - - self.sendVarBinds(snmpEngine, stateReference, errorStatus, - errorIndex, varBinds) + debug.logger & debug.flagApp and debug.logger( + 'processPdu: stateReference %s, error ' + '%s' % (stateReference, sys.exc_info()[1])) self.releaseStateInformation(stateReference) |