def setCmd(self, authData, transportTarget, varBinds, cbInfo): (cbFun, cbCtx) = cbInfo addrName, paramsName = self.cfgCmdGen( authData, transportTarget ) __varBinds = [] for varName, varVal in varBinds: name, oid = mibvar.mibNameToOid( self.mibViewController, varName ) if not isinstance(varVal, base.AbstractSimpleAsn1Item): ((symName, modName), suffix) = mibvar.oidToMibName( self.mibViewController, name + oid ) syntax = mibvar.cloneFromMibValue( self.mibViewController, modName, symName, varVal ) if syntax is None: raise error.PySnmpError( 'Value type MIB lookup failed for %r' % (varName,) ) varVal = syntax.clone(varVal) __varBinds.append((name + oid, varVal)) return cmdgen.SetCommandGenerator().sendReq( self.snmpEngine, addrName, __varBinds, cbFun, cbCtx, authData.contextEngineId, authData.contextName )
def snmp_getnext_multiple(self, auth_data, transport, *object_names): self.__lock.acquire() try: appReturn = {} varBindHead = map(lambda (x,y): univ.ObjectIdentifier(x+y), map((lambda x,g=self.__generator: mibvar.mibNameToOid(g.mibViewController,x)), object_names)) varBindTotalTable = [] cbCtx = (varBindHead, varBindTotalTable, appReturn) self.__generator.asyncNextCmd(auth_data, transport, object_names, (self.multi_callback, cbCtx)) # Work around Eaton Powerare UPS's incorrect end-of-getnext packet. try: self.__dispatcher() except error.ProtocolError, e: # Some Eaton Powerware UPS SNMP stacks respond with an out # of range error-index (2) for the final getnext response # of NoSuchName. if not varBindTotalTable: msglog.log("SNMP", msglog.types.WARN, "Caught ProtocolError with empty" " varBindTotalTable, re-raising.") msglog.log("SNMP", msglog.types.DB, "cbCtx: %r" % cbCtx) raise msglog.exception() msglog.log("SNMP", msglog.types.WARN, "Ignoring protocol error to allow (partial)" " discovery.") appReturn['errorIndication'] = None appReturn['errorStatus'] = None appReturn['errorIndex'] = 0 appReturn['varBindTable'] = varBindTotalTable return self.multi_varbinds_result(cbCtx)
def makeReadVarBinds(self, varNames): varBinds = [] for varName in varNames: if isinstance(varName[0], self.intTypes): name = varName else: name, oid = mibvar.mibNameToOid( self.mibViewController, varName ) name = name + oid varBinds.append((name, self._null)) return varBinds
def sendNotification( self, authData, transportTarget, notifyType, notificationType, varBinds=None, cbInfo=(None, None) ): (cbFun, cbCtx) = cbInfo tagList = str(transportTarget.transportAddr).replace(' ', '_') notifyName = self.cfgNtfOrg(authData, transportTarget, notifyType, tagList) if notificationType: name, oid = mibvar.mibNameToOid( self.mibViewController, notificationType ) notificationType = name + oid if varBinds: __varBinds = [] for varName, varVal in varBinds: name, oid = mibvar.mibNameToOid( self.mibViewController, varName ) if not isinstance(varVal, base.Asn1ItemBase): ((symName, modName), suffix) = mibvar.oidToMibName( self.mibViewController, name + oid ) syntax = mibvar.cloneFromMibValue( self.mibViewController, modName, symName, varVal ) if syntax is None: raise error.PySnmpError( 'Value type MIB lookup failed for %r' % (varName,) ) varVal = syntax.clone(varVal) __varBinds.append((name + oid, varVal)) else: __varBinds = None return ntforg.NotificationOriginator(self.snmpContext).sendNotification(self.snmpEngine, notifyName, notificationType, __varBinds, cbFun, cbCtx)
def snmp_getbulk_multiple(self, auth_data, transport, non_repeaters, max_repetitions, *object_names): self.__lock.acquire() try: appReturn = {} varBindHead = map( lambda (x, y): univ.ObjectIdentifier(x + y), map((lambda x, g=self.__generator: mibvar.mibNameToOid( g.mibViewController, x)), object_names)) varBindTotalTable = [] cbCtx = (varBindHead, varBindTotalTable, appReturn) self.__generator.asyncBulkCmd(auth_data, transport, non_repeaters, max_repetitions, object_names, (self.multi_callback, cbCtx)) self.__dispatcher() return self.multi_varbinds_result(cbCtx) finally: self.__lock.release() raise EUnreachableCode()
def snmp_getbulk_multiple(self, auth_data, transport, non_repeaters, max_repetitions, *object_names): self.__lock.acquire() try: appReturn = {} varBindHead = map(lambda (x,y): univ.ObjectIdentifier(x+y), map((lambda x,g=self.__generator: mibvar.mibNameToOid(g.mibViewController,x)), object_names)) varBindTotalTable = [] cbCtx = (varBindHead, varBindTotalTable, appReturn) self.__generator.asyncBulkCmd( auth_data, transport, non_repeaters, max_repetitions, object_names, (self.multi_callback, cbCtx) ) self.__dispatcher() return self.multi_varbinds_result(cbCtx) finally: self.__lock.release() raise EUnreachableCode()
def snmp_getnext_multiple(self, auth_data, transport, *object_names): self.__lock.acquire() try: appReturn = {} varBindHead = map( lambda (x, y): univ.ObjectIdentifier(x + y), map((lambda x, g=self.__generator: mibvar.mibNameToOid( g.mibViewController, x)), object_names)) varBindTotalTable = [] cbCtx = (varBindHead, varBindTotalTable, appReturn) self.__generator.asyncNextCmd(auth_data, transport, object_names, (self.multi_callback, cbCtx)) # Work around Eaton Powerare UPS's incorrect end-of-getnext packet. try: self.__dispatcher() except error.ProtocolError, e: # Some Eaton Powerware UPS SNMP stacks respond with an out # of range error-index (2) for the final getnext response # of NoSuchName. if not varBindTotalTable: msglog.log( "SNMP", msglog.types.WARN, "Caught ProtocolError with empty" " varBindTotalTable, re-raising.") msglog.log("SNMP", msglog.types.DB, "cbCtx: %r" % cbCtx) raise msglog.exception() msglog.log( "SNMP", msglog.types.WARN, "Ignoring protocol error to allow (partial)" " discovery.") appReturn['errorIndication'] = None appReturn['errorStatus'] = None appReturn['errorIndex'] = 0 appReturn['varBindTable'] = varBindTotalTable return self.multi_varbinds_result(cbCtx)
class CommandGenerator(AsynCommandGenerator): def getCmd(self, authData, transportTarget, *varNames): def __cbFun(sendRequestHandle, errorIndication, errorStatus, errorIndex, varBinds, appReturn): appReturn['errorIndication'] = errorIndication appReturn['errorStatus'] = errorStatus appReturn['errorIndex'] = errorIndex appReturn['varBinds'] = varBinds appReturn = {} self.asyncGetCmd(authData, transportTarget, varNames, (__cbFun, appReturn)) self.snmpEngine.transportDispatcher.runDispatcher() return (appReturn['errorIndication'], appReturn['errorStatus'], appReturn['errorIndex'], appReturn['varBinds']) def setCmd(self, authData, transportTarget, *varBinds): def __cbFun(sendRequestHandle, errorIndication, errorStatus, errorIndex, varBinds, appReturn): appReturn['errorIndication'] = errorIndication appReturn['errorStatus'] = errorStatus appReturn['errorIndex'] = errorIndex appReturn['varBinds'] = varBinds appReturn = {} self.asyncSetCmd(authData, transportTarget, varBinds, (__cbFun, appReturn)) self.snmpEngine.transportDispatcher.runDispatcher() return (appReturn['errorIndication'], appReturn['errorStatus'], appReturn['errorIndex'], appReturn['varBinds']) def nextCmd(self, authData, transportTarget, *varNames): def __cbFun(sendRequestHandle, errorIndication, errorStatus, errorIndex, varBindTable, (varBindHead, varBindTotalTable, appReturn)): if errorIndication or errorStatus: appReturn['errorIndication'] = errorIndication appReturn['errorStatus'] = errorStatus appReturn['errorIndex'] = errorIndex appReturn['varBindTable'] = varBindTable return else: varBindTableRow = varBindTable[-1] for idx in range(len(varBindTableRow)): name, val = varBindTableRow[idx] # XXX extra rows if val is not None and varBindHead[idx].isPrefixOf(name): break else: appReturn['errorIndication'] = errorIndication appReturn['errorStatus'] = errorStatus appReturn['errorIndex'] = errorIndex appReturn['varBindTable'] = varBindTotalTable return varBindTotalTable.extend(varBindTable) return 1 # continue table retrieval varBindHead = map( lambda (x, y): univ.ObjectIdentifier(x + y), map(lambda x, self=self: mibvar.mibNameToOid( self.mibViewController, x), varNames)) appReturn = {} self.asyncNextCmd(authData, transportTarget, varNames, (__cbFun, (varBindHead, [], appReturn))) self.snmpEngine.transportDispatcher.runDispatcher() return (appReturn['errorIndication'], appReturn['errorStatus'], appReturn['errorIndex'], appReturn['varBindTable'])
class AsynCommandGenerator: _null = univ.Null('') def __init__(self, snmpEngine=None): if snmpEngine is None: self.snmpEngine = engine.SnmpEngine() else: self.snmpEngine = snmpEngine self.mibViewController = view.MibViewController( self.snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder) self.__knownAuths = {} self.__knownTransports = {} self.__knownTransportAddrs = {} def __del__(self): self.uncfgCmdGen() def cfgCmdGen(self, authData, transportTarget, tagList=''): if self.__knownAuths.has_key(authData): paramsName = self.__knownAuths[authData] else: paramsName = 'p%s' % nextID() if isinstance(authData, CommunityData): config.addV1System(self.snmpEngine, authData.securityName, authData.communityName) config.addTargetParams(self.snmpEngine, paramsName, authData.securityName, authData.securityLevel, authData.mpModel) elif isinstance(authData, UsmUserData): config.addV3User(self.snmpEngine, authData.securityName, authData.authProtocol, authData.authKey, authData.privProtocol, authData.privKey) config.addTargetParams(self.snmpEngine, paramsName, authData.securityName, authData.securityLevel) else: raise error.PySnmpError('Unsupported SNMP version') self.__knownAuths[authData] = paramsName if not self.__knownTransports.has_key(transportTarget.transportDomain): transport = transportTarget.openClientMode() config.addSocketTransport(self.snmpEngine, transportTarget.transportDomain, transport) self.__knownTransports[transportTarget.transportDomain] = transport k = transportTarget, tagList if self.__knownTransportAddrs.has_key(k): addrName = self.__knownTransportAddrs[k] else: addrName = 'a%s' % nextID() config.addTargetAddr(self.snmpEngine, addrName, transportTarget.transportDomain, transportTarget.transportAddr, paramsName, transportTarget.timeout * 100, transportTarget.retries, tagList) self.__knownTransportAddrs[k] = addrName return addrName, paramsName def uncfgCmdGen(self): for authData, paramsName in self.__knownAuths.items(): if isinstance(authData, CommunityData): config.delV1System(self.snmpEngine, authData.securityName) config.delTargetParams(self.snmpEngine, paramsName) elif isinstance(authData, UsmUserData): config.delV3User(self.snmpEngine, authData.securityName) config.delTargetParams(self.snmpEngine, paramsName) else: raise error.PySnmpError('Unsupported SNMP version') self.__knownAuths.clear() for transportDomain, transport in self.__knownTransports.items(): config.delSocketTransport(self.snmpEngine, transportDomain) transport.closeTransport() self.__knownTransports.clear() for addrName in self.__knownTransportAddrs.values(): config.delTargetAddr(self.snmpEngine, addrName) self.__knownTransportAddrs.clear() # Async SNMP apps def asyncGetCmd(self, authData, transportTarget, varNames, (cbFun, cbCtx)): addrName, paramsName = self.cfgCmdGen(authData, transportTarget) varBinds = [] for varName in varNames: name, oid = mibvar.mibNameToOid(self.mibViewController, varName) varBinds.append((name + oid, self._null)) return cmdgen.GetCommandGenerator().sendReq(self.snmpEngine, addrName, varBinds, cbFun, cbCtx)
# Async SNMP apps def asyncGetCmd(self, authData, transportTarget, varNames, (cbFun, cbCtx)): addrName, paramsName = self.cfgCmdGen(authData, transportTarget) varBinds = [] for varName in varNames: name, oid = mibvar.mibNameToOid(self.mibViewController, varName) varBinds.append((name + oid, self._null)) return cmdgen.GetCommandGenerator().sendReq(self.snmpEngine, addrName, varBinds, cbFun, cbCtx) def asyncSetCmd(self, authData, transportTarget, varBinds, (cbFun, cbCtx)): addrName, paramsName = self.cfgCmdGen(authData, transportTarget) __varBinds = [] for varName, varVal in varBinds: name, oid = mibvar.mibNameToOid(self.mibViewController, varName) if not type(varVal) == types.InstanceType: ((symName, modName), suffix) = mibvar.oidToMibName(self.mibViewController, name + oid) syntax = mibvar.cloneFromMibValue(self.mibViewController, modName, symName, varVal) if syntax is None: raise error.PySnmpError( 'Value type MIB lookup failed for %s' % repr(varName)) varVal = syntax.clone(varVal) __varBinds.append((name + oid, varVal)) return cmdgen.SetCommandGenerator().sendReq(self.snmpEngine, addrName, __varBinds, cbFun, cbCtx) def asyncNextCmd(self, authData, transportTarget, varNames, (cbFun,
) varBinds.append((name + oid, self._null)) return cmdgen.GetCommandGenerator().sendReq( self.snmpEngine, addrName, varBinds, cbFun, cbCtx ) def asyncSetCmd( self, authData, transportTarget, varBinds, (cbFun, cbCtx) ): addrName, paramsName = self.cfgCmdGen( authData, transportTarget ) __varBinds = [] for varName, varVal in varBinds: name, oid = mibvar.mibNameToOid( self.mibViewController, varName ) if not type(varVal) == types.InstanceType: ((symName, modName), suffix) = mibvar.oidToMibName( self.mibViewController, name + oid ) syntax = mibvar.cloneFromMibValue( self.mibViewController, modName, symName, varVal ) if syntax is None: raise error.PySnmpError( 'Value type MIB lookup failed for %s' % repr(varName) ) varVal = syntax.clone(varVal) __varBinds.append((name + oid, varVal)) return cmdgen.SetCommandGenerator().sendReq(
def bulkCmd(self, authData, transportTarget, nonRepeaters, maxRepetitions, *varNames): def __cbFun(sendRequestHandle, errorIndication, errorStatus, errorIndex, varBindTable, cbCtx): (self, varBindHead, varBindTotalTable, appReturn) = cbCtx if errorStatus or \ errorIndication and not self.ignoreNonIncreasingOid or \ errorIndication and self.ignoreNonIncreasingOid and \ not isinstance(errorIndication, errind.OidNotIncreasing): appReturn['errorIndication'] = errorIndication appReturn['errorStatus'] = errorStatus appReturn['errorIndex'] = errorIndex appReturn['varBindTable'] = varBindTable return else: while varBindTable: if len(varBindTable[-1]) != len(varBindHead): # Fix possibly non-rectangular table del varBindTable[-1] else: break varBindTotalTable.extend(varBindTable) # XXX out of table # rows possible varBindTableRow = varBindTable[-1] for idx in range(len(varBindTableRow)): name, val = varBindTableRow[idx] if not isinstance(val, univ.Null): if self.lexicographicMode: if varBindHead[idx] <= name: break else: if varBindHead[idx].isPrefixOf(name): break else: appReturn['errorIndication'] = errorIndication appReturn['errorStatus'] = errorStatus appReturn['errorIndex'] = errorIndex appReturn['varBindTable'] = varBindTotalTable return return 1 # continue table retrieval varBindHead = [] for varName in varNames: name, suffix = mibvar.mibNameToOid( self.__asynCmdGen.mibViewController, varName ) varBindHead.append(univ.ObjectIdentifier(name + suffix)) appReturn = {} self.__asynCmdGen.bulkCmd( authData, transportTarget, nonRepeaters, maxRepetitions, varNames, (__cbFun, (self, varBindHead, [], appReturn)) ) self.__asynCmdGen.snmpEngine.transportDispatcher.runDispatcher() return ( appReturn['errorIndication'], appReturn['errorStatus'], appReturn['errorIndex'], appReturn['varBindTable'] )
def nextCmd(self, authData, transportTarget, *varNames): def __cbFun(sendRequestHandle, errorIndication, errorStatus, errorIndex, varBindTable, cbCtx): (self, varBindHead, varBindTotalTable, appReturn) = cbCtx if errorStatus or \ errorIndication and not self.ignoreNonIncreasingOid or \ errorIndication and self.ignoreNonIncreasingOid and \ not isinstance(errorIndication, errind.OidNotIncreasing): appReturn['errorIndication'] = errorIndication if errorStatus == 2: # Hide SNMPv1 noSuchName error which leaks in here # from SNMPv1 Agent through internal pysnmp proxy. appReturn['errorStatus'] = errorStatus.clone(0) appReturn['errorIndex'] = errorIndex.clone(0) else: appReturn['errorStatus'] = errorStatus appReturn['errorIndex'] = errorIndex appReturn['varBindTable'] = varBindTotalTable return else: varBindTableRow = varBindTable[-1] for idx in range(len(varBindTableRow)): name, val = varBindTableRow[idx] # XXX extra rows if not isinstance(val, univ.Null): if self.lexicographicMode: if varBindHead[idx] <= name: break else: if varBindHead[idx].isPrefixOf(name): break else: appReturn['errorIndication'] = errorIndication appReturn['errorStatus'] = errorStatus appReturn['errorIndex'] = errorIndex appReturn['varBindTable'] = varBindTotalTable return varBindTotalTable.extend(varBindTable) return 1 # continue table retrieval varBindHead = [] for varName in varNames: name, suffix = mibvar.mibNameToOid( self.__asynCmdGen.mibViewController, varName ) varBindHead.append(univ.ObjectIdentifier(name + suffix)) appReturn = {} self.__asynCmdGen.nextCmd( authData, transportTarget, varNames, (__cbFun, (self, varBindHead,[],appReturn)) ) self.__asynCmdGen.snmpEngine.transportDispatcher.runDispatcher() return ( appReturn['errorIndication'], appReturn['errorStatus'], appReturn['errorIndex'], appReturn['varBindTable'] )
authData.securityName, authData.securityLevel, subTree ) self.uncfgCmdGen() def asyncSendNotification( self, authData, transportTarget, notifyType, notificationType, varBinds=None, (cbFun, cbCtx)=(None, None) ): tagList = string.replace(str(transportTarget.transportAddr), ' ', '_') notifyName = self.cfgNtfOrg(authData, transportTarget, notifyType, tagList) if notificationType: name, oid = mibvar.mibNameToOid( self.mibViewController, notificationType ) notificationType = name + oid if varBinds: __varBinds = [] for varName, varVal in varBinds: name, oid = mibvar.mibNameToOid( self.mibViewController, varName ) if not type(varVal) == types.InstanceType: ((symName, modName), suffix) = mibvar.oidToMibName( self.mibViewController, name + oid ) syntax = mibvar.cloneFromMibValue( self.mibViewController, modName, symName, varVal )