Пример #1
0
 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
         )
Пример #2
0
 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)
Пример #3
0
 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
Пример #4
0
    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)
Пример #5
0
 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()
Пример #6
0
 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()
Пример #7
0
 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)
Пример #8
0
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'])
Пример #9
0
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)
Пример #10
0
    # 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,
Пример #11
0
                )
            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(
Пример #12
0
    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']
            )
Пример #13
0
    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']
            )
Пример #14
0
                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
                        )