From e8fa401677432e4e48d1a9c36b996ef94b043d90 Mon Sep 17 00:00:00 2001 From: Ilya Etingof Date: Tue, 30 Jul 2019 20:29:22 +0200 Subject: [PATCH] Make received MIB objects resolution more forgiving Previously, MIB resolution errors were ignored (whenever possible) for objects we were sending and receiving. This change tightens outgoing objects MIB compliance (send will fail), but tolerate non quite compliant objects we receive. Also, extend the same policy onto `NotificationOriginator`. --- CHANGES.txt | 6 +++--- pysnmp/hlapi/varbinds.py | 14 +++++++++----- pysnmp/smi/rfc1902.py | 16 +++++++++++----- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 3fc262cda..c3a9ad2c0 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -16,9 +16,9 @@ Revision 4.4.10, released 2019-07-29 - Rebased MIB importing code onto `importlib` because `imp` is long deprecated -- MIB objects resolution made more forgiving to errors, added optional - `ignoreErrors` parameter to `ObjectType.resolveWithMib()` to control - that behaviour. +- Received MIB objects resolution made more forgiving to errors, added + optional `ignoreErrors` parameter to `ObjectType.resolveWithMib()` to + control that behaviour. - Fixed asyncore main loop to respect non-default timer resolution - Fixed `.setTimerResolution()` behaviour of abstract main loop dispatcher to update call intervals of the existing periodic dispatcher jobs diff --git a/pysnmp/hlapi/varbinds.py b/pysnmp/hlapi/varbinds.py index ece7b92b9..fdffc1b33 100644 --- a/pysnmp/hlapi/varbinds.py +++ b/pysnmp/hlapi/varbinds.py @@ -36,14 +36,15 @@ def makeVarBinds(self, snmpEngine, varBinds): else: varBind = ObjectType(ObjectIdentity(varBind[0]), varBind[1]) - __varBinds.append(varBind.resolveWithMib(mibViewController)) + __varBinds.append(varBind.resolveWithMib(mibViewController, ignoreErrors=False)) return __varBinds def unmakeVarBinds(self, snmpEngine, varBinds, lookupMib=True): if lookupMib: mibViewController = self.getMibViewController(snmpEngine) - varBinds = [ObjectType(ObjectIdentity(x[0]), x[1]).resolveWithMib(mibViewController) for x in varBinds] + varBinds = [ObjectType(ObjectIdentity(x[0]), x[1]).resolveWithMib( + mibViewController) for x in varBinds] return varBinds @@ -52,7 +53,8 @@ class NotificationOriginatorVarBinds(AbstractVarBinds): def makeVarBinds(self, snmpEngine, varBinds): mibViewController = self.getMibViewController(snmpEngine) if isinstance(varBinds, NotificationType): - varBinds.resolveWithMib(mibViewController) + varBinds.resolveWithMib( + mibViewController, ignoreErrors=False) __varBinds = [] for varBind in varBinds: if isinstance(varBind, ObjectType): @@ -61,11 +63,13 @@ def makeVarBinds(self, snmpEngine, varBinds): varBind = ObjectType(*varBind) else: varBind = ObjectType(ObjectIdentity(varBind[0]), varBind[1]) - __varBinds.append(varBind.resolveWithMib(mibViewController)) + __varBinds.append(varBind.resolveWithMib( + mibViewController, ignoreErrors=False)) return __varBinds def unmakeVarBinds(self, snmpEngine, varBinds, lookupMib=False): if lookupMib: mibViewController = self.getMibViewController(snmpEngine) - varBinds = [ObjectType(ObjectIdentity(x[0]), x[1]).resolveWithMib(mibViewController) for x in varBinds] + varBinds = [ObjectType(ObjectIdentity(x[0]), x[1]).resolveWithMib( + mibViewController) for x in varBinds] return varBinds diff --git a/pysnmp/smi/rfc1902.py b/pysnmp/smi/rfc1902.py index 9c0a50bbd..ad115e7ad 100644 --- a/pysnmp/smi/rfc1902.py +++ b/pysnmp/smi/rfc1902.py @@ -1113,7 +1113,7 @@ def loadMibs(self, *modNames): def isFullyResolved(self): return self.__state & self.stClean - def resolveWithMib(self, mibViewController): + def resolveWithMib(self, mibViewController, ignoreErrors=True): """Perform MIB variable ID conversion and notification objects expansion. Parameters @@ -1121,6 +1121,12 @@ def resolveWithMib(self, mibViewController): mibViewController : :py:class:`~pysnmp.smi.view.MibViewController` class instance representing MIB browsing functionality. + Other Parameters + ---------------- + ignoreErrors: :py:class:`bool` + If `True` (default), ignore MIB object name or value casting + failures if possible. + Returns ------- : :py:class:`~pysnmp.smi.rfc1902.NotificationType` @@ -1158,7 +1164,7 @@ class instance representing MIB browsing functionality. self.__varBinds.append( ObjectType(ObjectIdentity(v2c.apiTrapPDU.snmpTrapOID), - self.__objectIdentity).resolveWithMib(mibViewController) + self.__objectIdentity).resolveWithMib(mibViewController, ignoreErrors) ) SmiNotificationType, = mibViewController.mibBuilder.importSymbols('SNMPv2-SMI', 'NotificationType') @@ -1170,11 +1176,11 @@ class instance representing MIB browsing functionality. if isinstance(mibNode, SmiNotificationType): for notificationObject in mibNode.getObjects(): objectIdentity = ObjectIdentity(*notificationObject + self.__instanceIndex).resolveWithMib( - mibViewController) + mibViewController, ignoreErrors) self.__varBinds.append( ObjectType(objectIdentity, self.__objects.get(notificationObject, rfc1905.unSpecified)).resolveWithMib( - mibViewController) + mibViewController, ignoreErrors) ) varBindsLocation[objectIdentity] = len(self.__varBinds) - 1 else: @@ -1184,7 +1190,7 @@ class instance representing MIB browsing functionality. for varBinds in self.__additionalVarBinds: if not isinstance(varBinds, ObjectType): varBinds = ObjectType(ObjectIdentity(varBinds[0]), varBinds[1]) - varBinds.resolveWithMib(mibViewController) + varBinds.resolveWithMib(mibViewController, ignoreErrors) if varBinds[0] in varBindsLocation: self.__varBinds[varBindsLocation[varBinds[0]]] = varBinds else: