Esempio n. 1
0
 def setFromName(self, obj, value, impliedFlag=None):
     if not value:
         raise error.SmiError('Short OID for index %s' % repr(obj))
     if self.__intValue.isSuperTypeOf(obj) or \
            self.__uint32Value.isSuperTypeOf(obj) or \
            self.__timeticksValue.isSuperTypeOf(obj) or \
            self.__counter32Value.isSuperTypeOf(obj) or \
            self.__counter64Value.isSuperTypeOf(obj):
         return obj.clone(value[0]), value[1:]
     elif self.__ipaddrValue.isSuperTypeOf(obj):
         return obj.clone(string.join(map(str, value[:4]), '.')), value[4:]
     elif self.__strValue.isSuperTypeOf(obj):
         # rfc1902, 7.7
         if impliedFlag:
             s = reduce(lambda x, y: x + y, map(lambda x: chr(x), value))
             return obj.clone(s), ()
         elif obj.isFixedLength():
             len = obj.getFixedLength()
             s = reduce(lambda x, y: x + y,
                        map(lambda x: chr(x), value[:len]))
             return obj.clone(s), value[len:]
         else:
             s = reduce(lambda x, y: x + y,
                        map(lambda x: chr(x), value[1:value[0] + 1]), '')
             return obj.clone(s), value[value[0] + 1:]
     elif self.__oidValue.isSuperTypeOf(obj):
         if impliedFlag:
             return obj.clone(value), ()
         else:
             return obj.clone(value[1:value[0] + 1]), value[value[0] + 1:]
     # rfc2578, 7.1
     elif self.__bitsValue.isSuperTypeOf(obj):
         s = reduce(lambda x, y: x + y,
                    map(lambda x: chr(x), value[1:value[0] + 1]), '')
         return obj.clone(s), value[value[0] + 1:]
     else:
         raise error.SmiError('Unknown value type for index %s' % repr(obj))
Esempio n. 2
0
 def unloadModules(self, *modNames):
     if not modNames:
         modNames = list(self.mibSymbols.keys())
     for modName in modNames:
         if modName not in self.mibSymbols:
             raise error.SmiError(
                 'No module %s at %s' % (modName, self)
                 )
         self.unexportSymbols(modName)
         del self.__modPathsSeen[self.__modSeen[modName]]
         del self.__modSeen[modName]
         
         debug.logger & debug.flagBld and debug.logger('unloadModules: ' % (modName))
         
     return self
Esempio n. 3
0
 def getTypeName(self, typeName, modName=''):
     self.indexMib()
     if modName in self.__mibSymbolsIdx:
         mibMod = self.__mibSymbolsIdx[modName]
     else:
         raise error.SmiError(
             'No module %s at %s' % (modName, self)
         )
     if typeName in mibMod['typeToModIdx']:
         m = mibMod['typeToModIdx'][typeName]
     else:
         raise error.NoSuchObjectError(
             str='No such type %s::%s at %s' % (modName, typeName, self)
         )
     return m, typeName
Esempio n. 4
0
 def getNodeNameByDesc(self, nodeName, modName=''):
     self.indexMib()
     if modName in self.__mibSymbolsIdx:
         mibMod = self.__mibSymbolsIdx[modName]
     else:
         raise error.SmiError('No module %s at %s' % (modName, self))
     if nodeName in mibMod['varToNameIdx']:
         oid = mibMod['varToNameIdx'][nodeName]
     else:
         raise error.NoSuchObjectError(str='No such symbol %s::%s at %s' %
                                       (modName, nodeName, self))
     debug.logger & debug.flagMIB and debug.logger(
         'getNodeNameByDesc: resolved %s:%s -> %s' %
         (modName, nodeName, oid))
     return self.getNodeNameByOid(oid, modName)
Esempio n. 5
0
    def cloneAsName(self, impliedFlag, parentRow, parentIndices):
        for parentIndex in reversed(parentIndices):
            if isinstance(parentIndex, InetAddressType):
                try:
                    # TODO: newer pyasn1 should ensure .prettyPrint() returns unicode
                    prettyValue = self.asOctets().decode()
                    return parentRow.getAsName(
                        self.typeMap[parentIndex].clone(prettyValue),
                        impliedFlag, parentIndices)
                except KeyError:
                    pass

        raise error.SmiError(
            '%s object encountered without preceding InetAddressType-like index: %r'
            % (self.__class__.__name__, self))
Esempio n. 6
0
 def getOrderedNodeName(self, index, modName=''):
     self.indexMib()
     if modName in self.__mibSymbolsIdx:
         mibMod = self.__mibSymbolsIdx[modName]
     else:
         raise error.SmiError('No module %s at %s' % (modName, self))
     if not mibMod['oidToLabelIdx']:
         raise error.NoSuchObjectError(
             str='No variables at MIB module %s at %s' % (modName, self))
     try:
         oid, label = mibMod['oidToLabelIdx'].items()[index]
     except KeyError:
         raise error.NoSuchObjectError(
             str='No symbol at position %s in MIB module %s at %s' %
             (index, modName, self))
     return oid, label, ()
Esempio n. 7
0
    def getOrderedTypeName(self, index, modName=''):
        self.indexMib()

        if modName in self._mibSymbolsIdx:
            mibMod = self._mibSymbolsIdx[modName]

        else:
            raise error.SmiError('No module %s at %s' % (modName, self))

        if not mibMod['typeToModIdx']:
            raise error.NoSuchObjectError(str='No types at MIB module %s at '
                                          '%s' % (modName, self))

        t = list(mibMod['typeToModIdx'])[index]

        return mibMod['typeToModIdx'][t], t
Esempio n. 8
0
 def getNodeNameByOid(self, nodeName, modName=''):
     self.indexMib()
     mibMod = self.__mibSymbolsIdx.get(modName)
     if mibMod is None:
         raise error.SmiError('No module %s at %s' % (modName, self))
     oid, label, suffix = self.__getOidLabel(nodeName,
                                             mibMod['oidToLabelIdx'],
                                             mibMod['labelToOidIdx'])
     if oid == label:
         raise error.NoSuchObjectError(
             str='Can\'t resolve node name %s::%s at %s' %
             (modName, nodeName, self))
     debug.logger & debug.flagMIB and debug.logger(
         'getNodeNameByOid: resolved %s:%s -> %s' %
         (modName, nodeName, label + suffix))
     return oid, label, suffix
Esempio n. 9
0
 def getIndicesFromInstId(self, instId):
     """Return index values for instance identification"""
     if instId in self.__idToIdxCache:
         return self.__idToIdxCache[instId]
     indices = []
     for impliedFlag, modName, symName in self.indexNames:
         mibObj, = mibBuilder.importSymbols(modName, symName)
         syntax, instId = self.setFromName(mibObj.syntax, instId,
                                           impliedFlag)
         indices.append(syntax)  # to avoid cyclic refs
     if instId:
         raise error.SmiError(
             'Excessive instance identifier sub-OIDs left at %s: %s' %
             (self, instId))
     indices = tuple(indices)
     self.__idToIdxCache[instId] = indices
     return indices
Esempio n. 10
0
 def getAsName(self, obj, impliedFlag=None):
     baseTag = obj.getTagSet().getBaseTag()
     if baseTag == self.__intBaseTag:
         return (int(obj), )
     elif self.__ipaddrTagSet.isSuperTagSetOf(obj.getTagSet()):
         return obj.asNumbers()
     elif baseTag == self.__strBaseTag:
         if impliedFlag or obj.isFixedLength():
             initial = ()
         else:
             initial = (len(obj), )
         return initial + obj.asNumbers()
     elif baseTag == self.__oidBaseTag:
         if impliedFlag:
             return tuple(obj)
         else:
             return (len(self.name), ) + tuple(obj)
     # rfc2578, 7.1
     elif baseTag == self.__bitsBaseTag:
         return (len(obj), ) + obj.asNumbers()
     else:
         raise error.SmiError('Unknown value type for index %r' % (obj, ))
Esempio n. 11
0
 def announceManagementEvent(self, action, name, val, idx, acInfo):
     # Convert OID suffix into index vals
     instId = name[len(self.name) + 1:]
     baseIndices = []
     for impliedFlag, modName, symName in self.indexNames:
         mibObj, = mibBuilder.importSymbols(modName, symName)
         syntax, instId = self.setFromName(mibObj.syntax, instId,
                                           impliedFlag)
         if self.name == mibObj.name[:-1]:
             baseIndices.append((mibObj.name, syntax))
     if instId:
         raise error.SmiError(
             'Excessive instance identifier sub-OIDs left at %s: %s' %
             (self, instId))
     if not baseIndices:
         return
     for modName, mibSym in self.augmentingRows.keys():
         mibObj, = mibBuilder.importSymbols(modName, mibSym)
         debug.logger & debug.flagIns and debug.logger(
             'announceManagementEvent %s to %s' % (action, mibObj))
         mibObj.receiveManagementEvent(action, baseIndices, val, idx,
                                       acInfo)
Esempio n. 12
0
    def getNodeNameByOid(self, nodeName, modName=''):
        self.indexMib()

        if modName in self._mibSymbolsIdx:
            mibMod = self._mibSymbolsIdx[modName]

        else:
            raise error.SmiError('No module %s at %s' % (modName, self))

        oid, label, suffix = self._getOidLabel(nodeName,
                                               mibMod['oidToLabelIdx'],
                                               mibMod['labelToOidIdx'])

        if oid == label:
            raise error.NoSuchObjectError(
                str='Cannot resolve node name %s::%s at '
                '%s' % (modName, nodeName, self))

        debug.logger & debug.FLAG_MIB and debug.logger(
            'getNodeNameByOid: resolved %s:%s -> '
            '%s.%s' % (modName, nodeName, label, suffix))

        return oid, label, suffix
Esempio n. 13
0
    def exportSymbols(self, modName, *anonymousSyms, **namedSyms):
        if modName not in self.mibSymbols:
            self.mibSymbols[modName] = {}

        mibSymbols = self.mibSymbols[modName]

        for symObj in anonymousSyms:
            debug.logger & debug.FLAG_BLD and debug.logger(
                'exportSymbols: anonymous symbol %s::'
                '__pysnmp_%ld' % (modName, self._autoName))

            mibSymbols['__pysnmp_%ld' % self._autoName] = symObj

            self._autoName += 1

        for symName, symObj in namedSyms.items():
            if symName in mibSymbols:
                raise error.SmiError('Symbol %s already exported at %s' %
                                     (symName, modName))

            if (symName != self.moduleID
                    and not isinstance(symObj, classTypes)):

                label = symObj.getLabel()

                if label:
                    symName = label

                else:
                    symObj.setLabel(symName)

            mibSymbols[symName] = symObj

            debug.logger & debug.FLAG_BLD and debug.logger(
                'exportSymbols: symbol %s::%s' % (modName, symName))

        self.lastBuildId += 1
Esempio n. 14
0
    def flipFlopFsm(self, fsmTable, *varBinds, **context):
        """Read, modify, create or remove Managed Objects Instances.

        Given one or more py:class:`~pysnmp.smi.rfc1902.ObjectType`, recursively
        transitions corresponding Managed Objects Instances through the Finite State
        Machine (FSM) states till it reaches its final stop state.

        Parameters
        ----------
        fsmTable: :py:class:`dict`
            A map of (`state`, `status`) -> `state` representing FSM transition matrix.
            See :py:class:`RowStatus` for FSM transition logic.

        varBinds: :py:class:`tuple` of :py:class:`~pysnmp.smi.rfc1902.ObjectType` objects
            representing Managed Objects Instances to work with.

        Other Parameters
        ----------------
        \*\*context:

            Query parameters:

            * `cbFun` (callable) - user-supplied callable that is invoked to
                pass the new value of the Managed Object Instance or an error.

            * `acFun` (callable) - user-supplied callable that is invoked to
                authorize access to the requested Managed Object Instance. If
                not supplied, no access control will be performed.

        Notes
        -----
        The callback functions (e.g. `cbFun`, `acFun`) have the same signature
        as this method where `varBind` contains the new Managed Object Instance
        value.

        In case of errors, the `errors` key in the `context` dict will contain
        a sequence of `dict` objects describing one or more errors that occur.

        Such error `dict` will have the `error`, `idx` and `state` keys providing
        the details concerning the error, for which variable-binding and in what
        state the system has failed.
        """
        count = [0]

        cbFun = context.get('cbFun')

        def _cbFun(varBind, **context):
            idx = context.pop('idx', None)

            err = context.pop('error', None)
            if err:
                # Move other errors into the errors sequence
                errors = context['errors']
                errors.append(
                    {'error': err,
                     'idx': idx,
                     'varbind': varBind,
                     'state': context['state']}
                )

                context['status'] = self.STATUS_ERROR

            if idx is None:
                if cbFun:
                    cbFun((), **context)
                return

            _varBinds = context['varBinds']

            _varBinds[idx] = varBind

            count[0] += 1

            debug.logger & debug.flagIns and debug.logger(
                '_cbFun: var-bind %d, processed %d, expected %d' % (
                idx, count[0], len(varBinds)))

            if count[0] < len(varBinds):
                return

            debug.logger & debug.flagIns and debug.logger(
                '_cbFun: finished, output var-binds %r' % (_varBinds,))

            self.flipFlopFsm(fsmTable, *varBinds, **dict(context, cbFun=cbFun))

        debug.logger & debug.flagIns and debug.logger('flipFlopFsm: input var-binds %r' % (varBinds,))

        mibTree, = self.mibBuilder.importSymbols('SNMPv2-SMI', 'iso')

        try:
            state = context['state']
            status = context['status']
            instances = context['instances']
            errors = context['errors']
            _varBinds = context['varBinds']

        except KeyError:
            state, status = self.STATE_START, self.STATUS_OK
            instances = {}
            errors = []
            _varBinds = list(varBinds)

            self.__indexMib()

        debug.logger & debug.flagIns and debug.logger(
            'flipFlopFsm: current state %s, status %s' % (state, status))

        try:
            newState = fsmTable[(state, status)]

        except KeyError:
            try:
                newState = fsmTable[(self.STATE_ANY, status)]

            except KeyError:
                raise error.SmiError('Unresolved FSM state %s, %s' % (state, status))

        debug.logger & debug.flagIns and debug.logger(
            'flipFlopFsm: state %s status %s -> transitioned into state %s' % (state, status, newState))

        state = newState

        if state == self.STATE_STOP:
            context.pop('state', None)
            context.pop('status', None)
            context.pop('instances', None)
            context.pop('varBinds', None)
            if cbFun:
                cbFun(_varBinds, **context)
            return

        # the case of no var-binds
        if not varBinds:
            _cbFun(None, **context)
            return

        actionFun = getattr(mibTree, state, None)
        if not actionFun:
            raise error.SmiError(
                'Unsupported state handler %s at %s' % (state, self)
            )

        for idx, varBind in enumerate(varBinds):
            actionFun(varBind,
                      **dict(context, cbFun=_cbFun,
                             state=state, status=status,
                             idx=idx, total=len(varBinds),
                             instances=instances, errors=errors,
                             varBinds=_varBinds, nextName=None))

            debug.logger & debug.flagIns and debug.logger(
                'flipFlopFsm: func %s initiated for %r' % (actionFun, varBind))
Esempio n. 15
0
    def indexMib(self):
        if self.lastBuildId == self.mibBuilder.lastBuildId:
            return

        debug.logger & debug.FLAG_MIB and debug.logger(
            'indexMib: re-indexing MIB view')

        MibScalarInstance, = self.mibBuilder.importSymbols(
            'SNMPv2-SMI', 'MibScalarInstance')

        #
        # Create indices
        #

        # Module name -> module-scope indices
        self._mibSymbolsIdx.clear()

        globMibMod = {
            'oidToLabelIdx': OidOrderedDict(),
            'labelToOidIdx': {},
            'varToNameIdx': {},
            'typeToModIdx': OrderedDict(),
            'oidToModIdx': {}
        }

        self._mibSymbolsIdx[''] = globMibMod

        # Oid <-> label indices

        modNames = sorted(self.mibBuilder.mibSymbols, key=self._sortFun)

        # Index modules names
        for modName in modNames:
            mibMod = {
                'oidToLabelIdx': OidOrderedDict(),
                'labelToOidIdx': {},
                'varToNameIdx': {},
                'typeToModIdx': OrderedDict(),
                'oidToModIdx': {}
            }

            self._mibSymbolsIdx[modName] = mibMod

            # Types & MIB vars indices
            for n, v in self.mibBuilder.mibSymbols[modName].items():
                if n == self.mibBuilder.moduleID:  # do not index this
                    continue  # special symbol

                if isinstance(v, classTypes):
                    if n in mibMod['typeToModIdx']:
                        raise error.SmiError(
                            'Duplicate SMI type %s::%s, has '
                            '%s' % (modName, n, mibMod['typeToModIdx'][n]))

                    globMibMod['typeToModIdx'][n] = modName
                    mibMod['typeToModIdx'][n] = modName

                elif isinstance(v, instanceTypes):
                    if isinstance(v, MibScalarInstance):
                        continue

                    if n in mibMod['varToNameIdx']:
                        raise error.SmiError(
                            'Duplicate MIB variable %s::%s has '
                            '%s' % (modName, n, mibMod['varToNameIdx'][n]))

                    globMibMod['varToNameIdx'][n] = v.name
                    mibMod['varToNameIdx'][n] = v.name

                    # Potentially ambiguous mapping ahead
                    globMibMod['oidToModIdx'][v.name] = modName
                    mibMod['oidToModIdx'][v.name] = modName
                    globMibMod['oidToLabelIdx'][v.name] = (n, )
                    mibMod['oidToLabelIdx'][v.name] = (n, )

                else:
                    raise error.SmiError('Unexpected object %s::%s' %
                                         (modName, n))

        # Build oid->long-label index
        oidToLabelIdx = self._mibSymbolsIdx['']['oidToLabelIdx']
        labelToOidIdx = self._mibSymbolsIdx['']['labelToOidIdx']

        prevOid = ()
        baseLabel = ()

        for key in oidToLabelIdx:
            keydiff = len(key) - len(prevOid)

            if keydiff > 0:
                if prevOid:
                    if keydiff == 1:
                        baseLabel = oidToLabelIdx[prevOid]

                    else:
                        baseLabel += key[-keydiff:-1]
                else:
                    baseLabel = ()

            elif keydiff < 0:
                baseLabel = ()
                keyLen = len(key)

                i = keyLen - 1

                while i:
                    k = key[:i]

                    if k in oidToLabelIdx:
                        baseLabel = oidToLabelIdx[k]

                        if i != keyLen - 1:
                            baseLabel += key[i:-1]

                        break

                    i -= 1

            # Build oid->long-label index
            oidToLabelIdx[key] = baseLabel + oidToLabelIdx[key]

            # Build label->oid index
            labelToOidIdx[oidToLabelIdx[key]] = key
            prevOid = key

        # Build module-scope oid->long-label index
        for mibMod in self._mibSymbolsIdx.values():
            for oid in mibMod['oidToLabelIdx']:
                mibMod['oidToLabelIdx'][oid] = oidToLabelIdx[oid]
                mibMod['labelToOidIdx'][oidToLabelIdx[oid]] = oid

        self.lastBuildId = self.mibBuilder.lastBuildId
Esempio n. 16
0
    def indexMib(self):
        if self.lastBuildId == self.mibBuilder.lastBuildId:
            return

        debug.logger & debug.flagMIB and debug.logger(
            'indexMib: re-indexing MIB view')

        MibScalarInstance, = self.mibBuilder.importSymbols(
            'SNMPv2-SMI', 'MibScalarInstance')

        #
        # Create indices
        #

        # Module name -> module-scope indices
        self.__mibSymbolsIdx = OrderedDict()

        # Oid <-> label indices

        # This is potentionally ambiguous mapping. Sort modules in
        # ascending age for resolution
        def __sortFun(x, b=self.mibBuilder):
            if b.moduleID in b.mibSymbols[x]:
                m = b.mibSymbols[x][b.moduleID]
                r = m.getRevisions()
                if r:
                    return r[0]
            else:
                return "1970-01-01 00:00"

        modNames = list(self.mibBuilder.mibSymbols.keys())
        modNames.sort(key=__sortFun)

        # Index modules names
        for modName in [''] + modNames:
            # Modules index
            self.__mibSymbolsIdx[modName] = mibMod = {
                'oidToLabelIdx': OidOrderedDict(),
                'labelToOidIdx': {},
                'varToNameIdx': {},
                'typeToModIdx': OrderedDict(),
                'oidToModIdx': {}
            }

            if not modName:
                globMibMod = mibMod
                continue

            # Types & MIB vars indices
            for n, v in self.mibBuilder.mibSymbols[modName].items():
                if n == self.mibBuilder.moduleID:  # do not index this
                    continue  # special symbol
                if isinstance(v, classTypes):
                    if n in mibMod['typeToModIdx']:
                        raise error.SmiError(
                            'Duplicate SMI type %s::%s, has %s' % \
                            (modName, n, mibMod['typeToModIdx'][n])
                            )
                    globMibMod['typeToModIdx'][n] = modName
                    mibMod['typeToModIdx'][n] = modName
                elif isinstance(v, instanceTypes):
                    if isinstance(v, MibScalarInstance):
                        continue
                    if n in mibMod['varToNameIdx']:
                        raise error.SmiError(
                            'Duplicate MIB variable %s::%s has %s' % \
                            (modName, n, mibMod['varToNameIdx'][n])
                            )
                    globMibMod['varToNameIdx'][n] = v.name
                    mibMod['varToNameIdx'][n] = v.name
                    # Potentionally ambiguous mapping ahead
                    globMibMod['oidToModIdx'][v.name] = modName
                    mibMod['oidToModIdx'][v.name] = modName
                    globMibMod['oidToLabelIdx'][v.name] = (n, )
                    mibMod['oidToLabelIdx'][v.name] = (n, )
                else:
                    raise error.SmiError('Unexpected object %s::%s' %
                                         (modName, n))

        # Build oid->long-label index
        oidToLabelIdx = self.__mibSymbolsIdx['']['oidToLabelIdx']
        labelToOidIdx = self.__mibSymbolsIdx['']['labelToOidIdx']
        if oidToLabelIdx:
            prevOid = oidToLabelIdx.keys()[0]
        else:
            prevOid = ()
        baseLabel = ()
        for key in oidToLabelIdx.keys():
            keydiff = len(key) - len(prevOid)
            if keydiff > 0:
                baseLabel = oidToLabelIdx[prevOid]
                if keydiff > 1:
                    baseLabel = baseLabel + key[-keydiff:-1]
            if keydiff < 0:
                keyLen = len(key)
                i = keyLen - 1
                while i:
                    k = key[:i]
                    if k in oidToLabelIdx:
                        baseLabel = oidToLabelIdx[k]
                        if i != keyLen - 1:
                            baseLabel = baseLabel + key[i:-1]
                        break
                    i = i - 1
            # Build oid->long-label index
            oidToLabelIdx[key] = baseLabel + oidToLabelIdx[key]
            # Build label->oid index
            labelToOidIdx[oidToLabelIdx[key]] = key
            prevOid = key

        # Build module-scope oid->long-label index
        for mibMod in self.__mibSymbolsIdx.values():
            for oid in mibMod['oidToLabelIdx'].keys():
                mibMod['oidToLabelIdx'][oid] = oidToLabelIdx[oid]
                mibMod['labelToOidIdx'][oidToLabelIdx[oid]] = oid

        self.lastBuildId = self.mibBuilder.lastBuildId
Esempio n. 17
0
    def flipFlopFsm(self, fsmTable, *varBinds, **context):

        try:
            fsmContext = context['fsmState']

        except KeyError:
            self.__indexMib()

            fsmContext = context['fsmState'] = dict(varBinds=[], state='start', status='ok')

            debug.logger & debug.flagIns and debug.logger('flipFlopFsm: input var-binds %r' % (varBinds,))

        mibTree, = self.mibBuilder.importSymbols('SNMPv2-SMI', 'iso')

        outputVarBinds = fsmContext['varBinds']
        state = fsmContext['state']
        status = fsmContext['status']

        origExc = origTraceback = None

        while True:
            k = state, status
            if k in fsmTable:
                fsmState = fsmTable[k]
            else:
                k = '*', status
                if k in fsmTable:
                    fsmState = fsmTable[k]
                else:
                    raise error.SmiError(
                        'Unresolved FSM state %s, %s' % (state, status)
                    )
            debug.logger & debug.flagIns and debug.logger(
                'flipFlopFsm: state %s status %s -> fsmState %s' % (state, status, fsmState))
            state = fsmState
            status = 'ok'
            if state == 'stop':
                break

            for idx, (name, val) in enumerate(varBinds):
                mgmtFun = getattr(mibTree, state, None)
                if not mgmtFun:
                    raise error.SmiError(
                        'Unsupported state handler %s at %s' % (state, self)
                    )

                context['idx'] = idx

                try:
                    # Convert to tuple to avoid ObjectName instantiation
                    # on subscription
                    rval = mgmtFun((tuple(name), val), **context)

                except error.SmiError:
                    exc_t, exc_v, exc_tb = sys.exc_info()
                    debug.logger & debug.flagIns and debug.logger(
                        'flipFlopFsm: fun %s exception %s for %s=%r with traceback: %s' % (
                            mgmtFun, exc_t, name, val, traceback.format_exception(exc_t, exc_v, exc_tb)))
                    if origExc is None:  # Take the first exception
                        origExc, origTraceback = exc_v, exc_tb
                    status = 'err'
                    break
                else:
                    debug.logger & debug.flagIns and debug.logger(
                        'flipFlopFsm: fun %s succeeded for %s=%r' % (mgmtFun, name, val))
                    if rval is not None:
                        outputVarBinds.append((rval[0], rval[1]))

        if origExc:
            if sys.version_info[0] <= 2:
                raise origExc
            else:
                try:
                    raise origExc.with_traceback(origTraceback)
                finally:
                    # Break cycle between locals and traceback object
                    # (seems to be irrelevant on Py3 but just in case)
                    del origTraceback

        cbFun = context.get('cbFun')
        if cbFun:
            cbFun(outputVarBinds, **context)
Esempio n. 18
0
 def getFirstModuleName(self):
     self.indexMib()
     modNames = self.__mibSymbolsIdx.keys()
     if modNames:
         return modNames[0]
     raise error.SmiError('No modules loaded at %s' % self)
Esempio n. 19
0
 def flipFlopFsm(self, fsmTable, inputVarBinds, acInfo):
     self.__indexMib()
     debug.logger & debug.flagIns and debug.logger(
         'flipFlopFsm: input var-binds %r' % (inputVarBinds, ))
     mibTree, = self.mibBuilder.importSymbols('SNMPv2-SMI', 'iso')
     outputVarBinds = []
     state, status = 'start', 'ok'
     origExc = None
     while True:
         k = (state, status)
         if k in fsmTable:
             fsmState = fsmTable[k]
         else:
             k = ('*', status)
             if k in fsmTable:
                 fsmState = fsmTable[k]
             else:
                 raise error.SmiError('Unresolved FSM state %s, %s' %
                                      (state, status))
         debug.logger & debug.flagIns and debug.logger(
             'flipFlopFsm: state %s status %s -> fsmState %s' %
             (state, status, fsmState))
         state = fsmState
         status = 'ok'
         if state == 'stop':
             break
         idx = 0
         for name, val in inputVarBinds:
             f = getattr(mibTree, state, None)
             if f is None:
                 raise error.SmiError('Unsupported state handler %s at %s' %
                                      (state, self))
             try:
                 # Convert to tuple to avoid ObjectName instantiation
                 # on subscription
                 rval = f(tuple(name), val, idx, acInfo)
             except error.SmiError:
                 exc_t, exc_v, exc_tb = sys.exc_info()
                 debug.logger & debug.flagIns and debug.logger(
                     'flipFlopFsm: fun %s exception %s for %s=%r with traceback: %s'
                     % (f, exc_t, name, val,
                        traceback.format_exception(exc_t, exc_v, exc_tb)))
                 if origExc is None:  # Take the first exception
                     origExc, origTraceback = exc_v, exc_tb
                 status = 'err'
                 break
             else:
                 debug.logger & debug.flagIns and debug.logger(
                     'flipFlopFsm: fun %s suceeded for %s=%r' %
                     (f, name, val))
                 if rval is not None:
                     outputVarBinds.append((rval[0], rval[1]))
             idx += 1
     if origExc:
         if sys.version_info[0] <= 2:
             raise origExc
         else:
             try:
                 raise origExc.with_traceback(origTraceback)
             finally:
                 # Break cycle between locals and traceback object
                 # (seems to be irrelevant on Py3 but just in case)
                 del origTraceback
     return outputVarBinds
Esempio n. 20
0
 def addMibCompiler(mibBuilder, **kwargs):
     if not kwargs.get('ifAvailable'):
         raise error.SmiError('MIB compiler not available (pysmi not installed)')
Esempio n. 21
0
 def getOrderedModuleName(self, index):
     self.indexMib()
     modNames = self.__mibSymbolsIdx.keys()
     if modNames:
         return modNames[index]
     raise error.SmiError('No modules loaded at %s' % self)
Esempio n. 22
0
class MibBuilder:
    loadTexts = 0
    defaultCoreMibs = 'pysnmp.smi.mibs.instances:pysnmp.smi.mibs'
    defaultMiscMibs = 'pysnmp_mibs'

    def __init__(self):
        self.lastBuildId = self._autoName = 0L
        sources = []
        for m in string.split(
                os.environ.get('PYSNMP_MIB_PKGS', self.defaultCoreMibs), ':'):
            sources.append(ZipMibSource(m).init())
        # Compatibility variable
        if os.environ.has_key('PYSNMP_MIB_DIR'):
            os.environ['PYSNMP_MIB_DIRS'] = os.environ['PYSNMP_MIB_DIR']
        if os.environ.has_key('PYSNMP_MIB_DIRS'):
            for m in string.split(os.environ['PYSNMP_MIB_DIRS'], ':'):
                sources.append(DirMibSource(m).init())
        if self.defaultMiscMibs:
            for m in string.split(self.defaultMiscMibs, ':'):
                try:
                    sources.append(ZipMibSource(m).init())
                except ImportError:
                    pass
        self.mibSymbols = {}
        self.__modSeen = {}
        self.__modPathsSeen = {}
        apply(self.setMibSources, sources)

    # MIB modules management

    def setMibSources(self, *mibSources):
        self.__mibSources = mibSources
        debug.logger & debug.flagBld and debug.logger(
            'setMibPath: new MIB sources %s' % (self.__mibSources, ))

    def getMibSources(self):
        return self.__mibSources

    # Legacy/compatibility methods
    def setMibPath(self, *mibPaths):
        apply(self.setMibSources, map(DirMibSource, mibPaths))

    def getMibPath(self):
        l = []
        for mibSource in self.getMibSources():
            if isinstance(mibSource, DirMibSource):
                l.append(mibSource.fullPath())
        return tuple(l)

    def loadModules(self, *modNames):
        # Build a list of available modules
        if not modNames:
            modNames = {}
            for mibSource in self.__mibSources:
                for modName in mibSource.listdir():
                    modNames[modName] = None
            modNames = modNames.keys()
        if not modNames:
            raise error.SmiError('No MIB module to load at %s' % (self, ))

        for modName in modNames:
            for mibSource in self.__mibSources:
                debug.logger & debug.flagBld and debug.logger(
                    'loadModules: trying %s at %s' % (modName, mibSource))
                try:
                    modData, sfx = mibSource.read(modName)
                except IOError, why:
                    debug.logger & debug.flagBld and debug.logger(
                        'loadModules: read %s from %s failed: %s' %
                        (modName, mibSource, why))
                    continue

                modPath = mibSource.fullPath(modName, sfx)

                if self.__modPathsSeen.has_key(modPath):
                    debug.logger & debug.flagBld and debug.logger(
                        'loadModules: seen %s' % modPath)
                    continue
                else:
                    self.__modPathsSeen[modPath] = 1

                debug.logger & debug.flagBld and debug.logger(
                    'loadModules: evaluating %s' % modPath)

                g = {'mibBuilder': self}

                try:
                    exec(modData, g)
                except StandardError, why:
                    del self.__modPathsSeen[modPath]
                    raise error.SmiError('MIB module \"%s\" load error: %s' %
                                         (modPath, why))

                self.__modSeen[modName] = modPath

                debug.logger & debug.flagBld and debug.logger(
                    'loadModules: loaded %s' % modPath)

                break

            if not self.__modSeen.has_key(modName):
                raise error.SmiError(
                    'MIB file \"%s\" not found in search path' %
                    (modName and modName + ".py[co]"))
Esempio n. 23
0
class TextualConvention:
    displayHint = ''
    status = 'current'
    description = ''
    reference = ''
    bits = ()
    __integer = Integer()
    __counter32 = Counter32()
    __unsigned32 = Unsigned32()
    __timeticks = TimeTicks()
    __counter64 = Counter64()
    __octetString = OctetString()
    __objectIdentifier = ObjectIdentifier()

    def getDisplayHint(self):
        return self.displayHint

    def getStatus(self):
        return self.status

    def getDescription(self):
        return self.description

    def getReference(self):
        return self.reference

    def prettyOut(self, value):  # override asn1 type method
        """Implements DISPLAY-HINT evaluation"""
        if self.displayHint and (self.__integer.isSuperTypeOf(self)
                                 or self.__unsigned32.isSuperTypeOf(self)
                                 or self.__timeticks.isSuperTypeOf(self)
                                 or self.__counter32.isSuperTypeOf(self)
                                 or self.__counter64.isSuperTypeOf(self)):
            t, f = apply(lambda t, f=0: (t, f), split(self.displayHint, '-'))
            if t == 'x':
                return '0x%x' % value
            elif t == 'd':
                try:
                    return '%.*f' % (int(f), float(value) / pow(10, int(f)))
                except StandardError, why:
                    raise error.SmiError('float num evaluation error: %s' %
                                         why)
            elif t == 'o':
                return '0%o' % value
            elif t == 'b':
                v = value
                r = ['B']
                while v:
                    r.insert(0, '%d' % (v & 0x01))
                    v = v >> 1
                return join(r, '')
            else:
                raise error.SmiError('Unsupported numeric type spec: %s' % t)
        elif self.displayHint and self.__octetString.isSuperTypeOf(self):
            r = ''
            v = str(value)
            d = self.displayHint
            while v and d:
                # 1
                if d[0] == '*':
                    repeatIndicator = repeatCount = int(v[0])
                    d = d[1:]
                    v = v[1:]
                else:
                    repeatCount = 1
                    repeatIndicator = None

                # 2
                octetLength = ''
                while d and d[0] in digits:
                    octetLength = octetLength + d[0]
                    d = d[1:]
                try:
                    octetLength = int(octetLength)
                except StandardError, why:
                    raise error.SmiError('Bad octet length: %s' % octetLength)
                if not d:
                    raise error.SmiError('Short octet length: %s' %
                                         self.displayHint)
                # 3
                displayFormat = d[0]
                d = d[1:]

                # 4
                if d and d[0] not in digits and d[0] != '*':
                    displaySep = d[0]
                    d = d[1:]
                else:
                    displaySep = ''

                # 5
                if d and displaySep and repeatIndicator is not None:
                    repeatTerminator = d[0]
                    displaySep = ''
                    d = d[1:]
                else:
                    repeatTerminator = None

                while repeatCount:
                    repeatCount = repeatCount - 1
                    # 't' stands for UTF-8, does it need any special support?
                    if displayFormat == 'a' or displayFormat == 't':
                        r = r + v[:octetLength]
                    elif displayFormat in ('x', 'd', 'o'):
                        n = 0L
                        vv = v[:octetLength]
                        while vv:
                            n = n << 8
                            try:
                                n = n | ord(vv[0])
                                vv = vv[1:]
                            except StandardError, why:
                                raise error.SmiError(
                                    'Display format eval failure: %s: %s' %
                                    (vv, why))
                        if displayFormat == 'x':
                            r = r + '%02x' % n
                        elif displayFormat == 'o':
                            r = r + '%03o' % n
                        else:
                            r = r + '%d' % n
                    else:
                        raise error.SmiError(
                            'Unsupported display format char: %s' % \
                            displayFormat
                            )
                    if v and repeatTerminator:
                        r = r + repeatTerminator
                    v = v[octetLength:]
Esempio n. 24
0
class MibTableRow(MibTree):
    """MIB table row (SMI 'Entry'). Manages a set of table columns.
       Implements row creation/destruction.
    """
    def __init__(self, name):
        MibTree.__init__(self, name)
        self.indexNames = ()
        self.augmentingRows = {}

    # Table indices resolution. Handle almost all possible rfc1902 types
    # explicitly rather than by means of isSuperTypeOf() method because
    # some subtypes may be implicitly tagged what renders base tag
    # unavailable.

    __intValue = Integer()
    __counter32Value = Counter32()
    __uint32Value = Unsigned32()
    __timeticksValue = TimeTicks()
    __counter64Value = Counter64()
    __strValue = OctetString()
    __oidValue = ObjectIdentifier()
    __ipaddrValue = IpAddress()
    __bitsValue = Bits()

    def setFromName(self, obj, value, impliedFlag=None):
        if not value:
            raise error.SmiError('Short OID for index %s' % repr(obj))
        if self.__intValue.isSuperTypeOf(obj) or \
               self.__uint32Value.isSuperTypeOf(obj) or \
               self.__timeticksValue.isSuperTypeOf(obj) or \
               self.__counter32Value.isSuperTypeOf(obj) or \
               self.__counter64Value.isSuperTypeOf(obj):
            return obj.clone(value[0]), value[1:]
        elif self.__ipaddrValue.isSuperTypeOf(obj):
            return obj.clone(string.join(map(str, value[:4]), '.')), value[4:]
        elif self.__strValue.isSuperTypeOf(obj):
            # rfc1902, 7.7
            if impliedFlag:
                s = reduce(lambda x, y: x + y, map(lambda x: chr(x), value))
                return obj.clone(s), ()
            elif obj.isFixedLength():
                len = obj.getFixedLength()
                s = reduce(lambda x, y: x + y,
                           map(lambda x: chr(x), value[:len]))
                return obj.clone(s), value[len:]
            else:
                s = reduce(lambda x, y: x + y,
                           map(lambda x: chr(x), value[1:value[0] + 1]), '')
                return obj.clone(s), value[value[0] + 1:]
        elif self.__oidValue.isSuperTypeOf(obj):
            if impliedFlag:
                return obj.clone(value), ()
            else:
                return obj.clone(value[1:value[0] + 1]), value[value[0] + 1:]
        # rfc2578, 7.1
        elif self.__bitsValue.isSuperTypeOf(obj):
            s = reduce(lambda x, y: x + y,
                       map(lambda x: chr(x), value[1:value[0] + 1]), '')
            return obj.clone(s), value[value[0] + 1:]
        else:
            raise error.SmiError('Unknown value type for index %s' % repr(obj))

    def getAsName(self, obj, impliedFlag=None):
        if self.__intValue.isSuperTypeOf(obj) or \
               self.__uint32Value.isSuperTypeOf(obj) or \
               self.__timeticksValue.isSuperTypeOf(obj) or \
               self.__counter32Value.isSuperTypeOf(obj) or \
               self.__counter64Value.isSuperTypeOf(obj):
            return (int(obj), )
        elif self.__ipaddrValue.isSuperTypeOf(obj):
            return tuple(map(ord, obj))
        elif self.__strValue.isSuperTypeOf(obj):
            if impliedFlag or obj.isFixedLength():
                initial = ()
            else:
                initial = (len(obj), )
            return reduce(lambda x, y: x + (y, ), map(lambda x: ord(x), obj),
                          initial)
        elif self.__oidValue.isSuperTypeOf(obj):
            if impliedFlag:
                return tuple(obj)
            else:
                return (len(self.name), ) + tuple(obj)
        # rfc2578, 7.1
        elif self.__bitsValue.isSuperTypeOf(obj):
            return reduce(lambda x, y: x + (y, ), map(lambda x: ord(x), obj),
                          (len(obj), ))
        else:
            raise error.SmiError('Unknown value type for index %s' % repr(obj))

    # Fate sharing mechanics

    def announceManagementEvent(self, action, name, val, idx, (acFun, acCtx)):
        # Convert OID suffix into index vals
        instId = name[len(self.name) + 1:]
        baseIndices = []
        for impliedFlag, modName, symName in self.indexNames:
            mibObj, = mibBuilder.importSymbols(modName, symName)
            syntax, instId = self.setFromName(mibObj.syntax, instId,
                                              impliedFlag)
            if self.name == mibObj.name[:-1]:
                baseIndices.append((mibObj.name, syntax))
        if instId:
            raise error.SmiError(
                'Excessive instance identifier sub-OIDs left at %s: %s' %
                (self, instId))
        if not baseIndices:
            return
        for modName, mibSym in self.augmentingRows.keys():
            mibObj, = mibBuilder.importSymbols(modName, mibSym)
            debug.logger & debug.flagIns and debug.logger(
                'announceManagementEvent %s to %s' % (action, mibObj))
            mibObj.receiveManagementEvent(action, baseIndices, val, idx,
                                          (acFun, acCtx))
Esempio n. 25
0
    def flipFlopFsm(self, fsmTable, *varBinds, **context):
        try:
            fsmContext = context[self.FSM_CONTEXT]

        except KeyError:
            self.__indexMib()

            fsmContext = context[self.FSM_CONTEXT] = dict(
                sessionId=self.FSM_SESSION_ID(),
                varBinds=list(varBinds[:]),
                fsmCallable=functools.partial(self.flipFlopFsm, fsmTable, *varBinds),
                state=self.STATE_START, status=self.STATUS_OK
            )

            debug.logger & debug.flagIns and debug.logger('flipFlopFsm: input var-binds %r' % (varBinds,))

        mibTree, = self.mibBuilder.importSymbols('SNMPv2-SMI', 'iso')

        state = fsmContext['state']
        status = fsmContext['status']

        debug.logger & debug.flagIns and debug.logger(
            'flipFlopFsm: current state %s, status %s' % (state, status))

        try:
            newState = fsmTable[(state, status)]

        except KeyError:
            try:
                newState = fsmTable[(self.STATE_ANY, status)]

            except KeyError:
                raise error.SmiError('Unresolved FSM state %s, %s' % (state, status))

        debug.logger & debug.flagIns and debug.logger(
            'flipFlopFsm: state %s status %s -> new state %s' % (state, status, newState))

        state = newState

        if state == self.STATE_STOP:
            context.pop(self.FSM_CONTEXT, None)

            cbFun = context.get('cbFun')
            if cbFun:
                varBinds = fsmContext['varBinds']
                cbFun(varBinds, **context)

            return

        fsmContext.update(state=state, count=0)

        # the case of no var-binds
        if not varBinds:
            return self._flipFlopFsmCb(None, idx=-1, **context)

        mgmtFun = getattr(mibTree, state, None)
        if not mgmtFun:
            raise error.SmiError(
                'Unsupported state handler %s at %s' % (state, self)
            )

        for idx, varBind in enumerate(varBinds):
            try:
                # TODO: managed objects to run asynchronously
                #mgmtFun(varBind, idx=idx, **context)
                self._flipFlopFsmCb(mgmtFun(varBind, idx=idx, **context), idx=idx, **context)

            except error.SmiError:
                exc = sys.exc_info()
                debug.logger & debug.flagIns and debug.logger(
                    'flipFlopFsm: fun %s exception %s for %r with traceback: %s' % (
                        mgmtFun, exc[0], varBind, traceback.format_exception(*exc)))

                varBind = varBind[0], exc

                fsmContext['status'] = self.STATUS_ERROR

                self._flipFlopFsmCb(varBind, idx=idx, **context)

                return

            else:
                debug.logger & debug.flagIns and debug.logger(
                    'flipFlopFsm: func %s initiated for %r' % (mgmtFun, varBind))
Esempio n. 26
0
    def prettyOut(self, value):  # override asn1 type method
        """Implements DISPLAY-HINT evaluation"""
        if self.displayHint and (
            self.__integer.isSuperTypeOf(self) or
            self.__unsigned32.isSuperTypeOf(self) or
            self.__timeticks.isSuperTypeOf(self) or
            self.__counter32.isSuperTypeOf(self) or
            self.__counter64.isSuperTypeOf(self)
            ):
            _ = lambda t, f=0: (t, f)
            t, f = _(*self.displayHint.split('-'))
            if t == 'x':
                return '0x%x' % value
            elif t == 'd':
                try:
                    return '%.*f' % (int(f), float(value)/pow(10, int(f)))
                except Exception:
                    raise error.SmiError(
                        'float num evaluation error: %s' % sys.exc_info()[1]
                    )
            elif t == 'o':
                return '0%o' % value
            elif t == 'b':
                v = value; r = ['B']
                while v:
                    r.insert(0, '%d' % (v&0x01))
                    v = v>>1
                return ''.join(r)
            else:
                raise error.SmiError(
                    'Unsupported numeric type spec: %s' % t
                    )
        elif self.displayHint and self.__octetString.isSuperTypeOf(self):
            r = ''
            v = self.__class__(value).asNumbers()
            d = self.displayHint
            while v and d:
                # 1
                if d[0] == '*':
                    repeatIndicator = repeatCount = v[0]
                    d = d[1:]; v = v[1:]
                else:
                    repeatCount = 1; repeatIndicator = None
                    
                # 2
                octetLength = ''
                while d and d[0] in '0123456789':
                    octetLength = octetLength + d[0]
                    d = d[1:]
                try:
                    octetLength = int(octetLength)
                except Exception:
                    raise error.SmiError(
                        'Bad octet length: %s' % octetLength
                        )                    
                if not d:
                    raise error.SmiError(
                        'Short octet length: %s' % self.displayHint
                        )
                # 3
                displayFormat = d[0]
                d = d[1:]

                # 4
                if d and d[0] not in '0123456789' and d[0] != '*':
                    displaySep = d[0]
                    d = d[1:]
                else:
                    displaySep = ''

                # 5
                if d and displaySep and repeatIndicator is not None:
                        repeatTerminator = d[0]
                        displaySep = ''
                        d = d[1:]
                else:
                    repeatTerminator = None

                while repeatCount:
                    repeatCount = repeatCount - 1
                    # 't' stands for UTF-8, does it need any special support?
                    if displayFormat == 'a' or displayFormat == 't':
                        r = r + ''.join([ chr(x) for x in v[:octetLength] ])
                    elif displayFormat in ('x', 'd', 'o'):
                        n = 0; vv = v[:octetLength]
                        while vv:
                            n = n << 8
                            try:
                                n = n | vv[0]
                                vv = vv[1:]
                            except Exception:
                                raise error.SmiError(
                                    'Display format eval failure: %s: %s'
                                    % (vv, sys.exc_info()[1])
                                    )
                        if displayFormat == 'x':
                            r = r + '%02x' % n
                        elif displayFormat == 'o':
                            r = r + '%03o' % n
                        else:
                            r = r + '%d' % n
                    else:
                        raise error.SmiError(
                            'Unsupported display format char: %s' % \
                            displayFormat
                            )
                    if v and repeatTerminator:
                        r = r + repeatTerminator
                    v = v[octetLength:]
                if v and displaySep:
                    r = r + displaySep
                if not d:
                    d = self.displayHint
#             if d:
#                 raise error.SmiError(
#                     'Unparsed display hint left: %s' % d
#                     )
            return r
        elif self.__objectIdentifier.isSuperTypeOf(self):
            return self.__objectIdentifier.prettyOut(value)
        elif self.__octetString.isSuperTypeOf(self):
            return self.__octetString.prettyOut(value)
        else:
            return str(value)
Esempio n. 27
0
    def __indexMib(self):
        # Build a tree from MIB objects found at currently loaded modules
        if self.lastBuildId == self.mibBuilder.lastBuildId:
            return

        (MibScalarInstance, MibScalar, MibTableColumn, MibTableRow,
         MibTable) = self.mibBuilder.importSymbols('SNMPv2-SMI',
                                                   'MibScalarInstance',
                                                   'MibScalar',
                                                   'MibTableColumn',
                                                   'MibTableRow', 'MibTable')

        mibTree, = self.mibBuilder.importSymbols('SNMPv2-SMI', 'iso')

        #
        # Management Instrumentation gets organized as follows:
        #
        # MibTree
        #   |
        #   +----MibScalar
        #   |        |
        #   |        +-----MibScalarInstance
        #   |
        #   +----MibTable
        #   |
        #   +----MibTableRow
        #          |
        #          +-------MibTableColumn
        #                        |
        #                        +------MibScalarInstance(s)
        #
        # Mind you, only Managed Objects get indexed here, various MIB defs and
        # constants can't be SNMP managed so we drop them.
        #
        scalars = {}
        instances = {}
        tables = {}
        rows = {}
        cols = {}

        # Sort by module name to give user a chance to slip-in
        # custom MIB modules (that would be sorted out first)
        mibSymbols = list(self.mibBuilder.mibSymbols.items())
        mibSymbols.sort(key=lambda x: x[0], reverse=True)

        for modName, mibMod in mibSymbols:
            for symObj in mibMod.values():
                if isinstance(symObj, MibTable):
                    tables[symObj.name] = symObj
                elif isinstance(symObj, MibTableRow):
                    rows[symObj.name] = symObj
                elif isinstance(symObj, MibTableColumn):
                    cols[symObj.name] = symObj
                elif isinstance(symObj, MibScalarInstance):
                    instances[symObj.name] = symObj
                elif isinstance(symObj, MibScalar):
                    scalars[symObj.name] = symObj

        # Detach items from each other
        for symName, parentName in self.lastBuildSyms.items():
            if parentName in scalars:
                scalars[parentName].unregisterSubtrees(symName)
            elif parentName in cols:
                cols[parentName].unregisterSubtrees(symName)
            elif parentName in rows:
                rows[parentName].unregisterSubtrees(symName)
            else:
                mibTree.unregisterSubtrees(symName)

        lastBuildSyms = {}

        # Attach Managed Objects Instances to Managed Objects
        for inst in instances.values():
            if inst.typeName in scalars:
                scalars[inst.typeName].registerSubtrees(inst)
            elif inst.typeName in cols:
                cols[inst.typeName].registerSubtrees(inst)
            else:
                raise error.SmiError('Orphan MIB scalar instance %r at %r' %
                                     (inst, self))
            lastBuildSyms[inst.name] = inst.typeName

        # Attach Table Columns to Table Rows
        for col in cols.values():
            rowName = col.name[:-1]  # XXX
            if rowName in rows:
                rows[rowName].registerSubtrees(col)
            else:
                raise error.SmiError('Orphan MIB table column %r at %r' %
                                     (col, self))
            lastBuildSyms[col.name] = rowName

        # Attach Table Rows to MIB tree
        for row in rows.values():
            mibTree.registerSubtrees(row)
            lastBuildSyms[row.name] = mibTree.name

        # Attach Tables to MIB tree
        for table in tables.values():
            mibTree.registerSubtrees(table)
            lastBuildSyms[table.name] = mibTree.name

        # Attach Scalars to MIB tree
        for scalar in scalars.values():
            mibTree.registerSubtrees(scalar)
            lastBuildSyms[scalar.name] = mibTree.name

        self.lastBuildSyms = lastBuildSyms

        self.lastBuildId = self.mibBuilder.lastBuildId

        debug.logger & debug.flagIns and debug.logger('__indexMib: rebuilt')
Esempio n. 28
0
class MibInstrumController:
    fsmReadVar = {
        # ( state, status ) -> newState
        ('start', 'ok'): 'readTest',
        ('readTest', 'ok'): 'readGet',
        ('readGet', 'ok'): 'stop',
        ('*', 'err'): 'stop'
    }
    fsmReadNextVar = {
        # ( state, status ) -> newState
        ('start', 'ok'): 'readTestNext',
        ('readTestNext', 'ok'): 'readGetNext',
        ('readGetNext', 'ok'): 'stop',
        ('*', 'err'): 'stop'
    }
    fsmWriteVar = {
        # ( state, status ) -> newState
        ('start', 'ok'): 'writeTest',
        ('writeTest', 'ok'): 'writeCommit',
        ('writeCommit', 'ok'): 'writeCleanup',
        ('writeCleanup', 'ok'): 'readTest',
        # Do read after successful write
        ('readTest', 'ok'): 'readGet',
        ('readGet', 'ok'): 'stop',
        # Error handling
        ('writeTest', 'err'): 'writeCleanup',
        ('writeCommit', 'err'): 'writeUndo',
        ('writeUndo', 'ok'): 'readTest',
        # Ignore read errors (removed columns)
        ('readTest', 'err'): 'stop',
        ('readGet', 'err'): 'stop',
        ('*', 'err'): 'stop'
    }

    def __init__(self, mibBuilder):
        self.mibBuilder = mibBuilder
        self.lastBuildId = -1
        self.lastBuildSyms = {}

    # MIB indexing

    def __indexMib(self):
        # Build a tree from MIB objects found at currently loaded modules
        if self.lastBuildId == self.mibBuilder.lastBuildId:
            return

        (MibScalarInstance, MibScalar, MibTableColumn, MibTableRow,
         MibTable, MibTree) = self.mibBuilder.importSymbols(
             'SNMPv2-SMI', 'MibScalarInstance', 'MibScalar', 'MibTableColumn',
             'MibTableRow', 'MibTable', 'MibTree')

        mibTree, = self.mibBuilder.importSymbols('SNMPv2-SMI', 'iso')

        #
        # Management Instrumentation gets organized as follows:
        #
        # MibTree
        #   |
        #   +----MibScalar
        #   |        |
        #   |        +-----MibScalarInstance
        #   |
        #   +----MibTable
        #   |
        #   +----MibTableRow
        #          |
        #          +-------MibTableColumn
        #                        |
        #                        +------MibScalarInstance(s)
        #
        # Mind you, only Managed Objects get indexed here, various MIB defs and
        # constants can't be SNMP managed so we drop them.
        #
        scalars = {}
        instances = {}
        tables = {}
        rows = {}
        cols = {}

        # Sort by module name to give user a chance to slip-in
        # custom MIB modules (that would be sorted out first)
        mibSymbols = self.mibBuilder.mibSymbols.items()
        mibSymbols.sort(lambda x, y: cmp(y[0], x[0]))

        for modName, mibMod in mibSymbols:
            for symObj in mibMod.values():
                if type(symObj) != InstanceType:
                    continue
                if isinstance(symObj, MibTable):
                    tables[symObj.name] = symObj
                elif isinstance(symObj, MibTableRow):
                    rows[symObj.name] = symObj
                elif isinstance(symObj, MibTableColumn):
                    cols[symObj.name] = symObj
                elif isinstance(symObj, MibScalarInstance):
                    instances[symObj.name] = symObj
                elif isinstance(symObj, MibScalar):
                    scalars[symObj.name] = symObj

        # Detach items from each other
        for symName, parentName in self.lastBuildSyms.items():
            if scalars.has_key(parentName):
                scalars[parentName].unregisterSubtrees(symName)
            elif cols.has_key(parentName):
                cols[parentName].unregisterSubtrees(symName)
            elif rows.has_key(parentName):
                rows[parentName].unregisterSubtrees(symName)
            else:
                mibTree.unregisterSubtrees(symName)

        lastBuildSyms = {}

        # Attach Managed Objects Instances to Managed Objects
        for inst in instances.values():
            if scalars.has_key(inst.typeName):
                scalars[inst.typeName].registerSubtrees(inst)
            elif cols.has_key(inst.typeName):
                cols[inst.typeName].registerSubtrees(inst)
            else:
                raise error.SmiError('Orphan MIB scalar instance %s at %s' %
                                     (inst, self))
            lastBuildSyms[inst.name] = inst.typeName

        # Attach Table Columns to Table Rows
        for col in cols.values():
            rowName = col.name[:-1]  # XXX
            if rows.has_key(rowName):
                rows[rowName].registerSubtrees(col)
            else:
                raise error.SmiError('Orphan MIB table column %s at %s' %
                                     (col, self))
            lastBuildSyms[col.name] = rowName

        # Attach Table Rows to MIB tree
        for row in rows.values():
            mibTree.registerSubtrees(row)
            lastBuildSyms[row.name] = mibTree.name

        # Attach Tables to MIB tree
        for table in tables.values():
            mibTree.registerSubtrees(table)
            lastBuildSyms[table.name] = mibTree.name

        # Attach Scalars to MIB tree
        for scalar in scalars.values():
            mibTree.registerSubtrees(scalar)
            lastBuildSyms[scalar.name] = mibTree.name

        self.lastBuildSyms = lastBuildSyms

        self.lastBuildId = self.mibBuilder.lastBuildId

        debug.logger & debug.flagIns and debug.logger('__indexMib: rebuilt')

    # MIB instrumentation

    def flipFlopFsm(self, fsmTable, inputNameVals, (acFun, acCtx)):
        self.__indexMib()
        debug.logger & debug.flagIns and debug.logger(
            'flipFlopFsm: inputNameVals %s' % (inputNameVals, ))
        mibTree, = self.mibBuilder.importSymbols('SNMPv2-SMI', 'iso')
        outputNameVals = []
        state, status = 'start', 'ok'
        myErr = None
        while 1:
            fsmState = fsmTable.get((state, status))
            if fsmState is None:
                fsmState = fsmTable.get(('*', status))
                if fsmState is None:
                    raise error.SmiError('Unresolved FSM state %s, %s' %
                                         (state, status))
            debug.logger & debug.flagIns and debug.logger(
                'flipFlopFsm: state %s status %s -> fsmState %s' %
                (state, status, fsmState))
            state = fsmState
            status = 'ok'
            if state == 'stop':
                break
            idx = 0
            for name, val in inputNameVals:
                f = getattr(mibTree, state, None)
                if f is None:
                    raise error.SmiError('Unsupported state handler %s at %s' %
                                         (state, self))
                try:
                    # Convert to tuple to avoid ObjectName instantiation
                    # on subscription
                    rval = f(tuple(name), val, idx, (acFun, acCtx))
                except error.SmiError, why:
                    debug.logger & debug.flagIns and debug.logger(
                        'flipFlopFsm: fun %s failed %s for %s=%s' %
                        (f, why, name, val))
                    if myErr is None:  # Take the first exception
                        myErr = why
                    status = 'err'
                    break
                else:
                    debug.logger & debug.flagIns and debug.logger(
                        'flipFlopFsm: fun %s suceeded for %s=%s' %
                        (f, name, val))
                    if rval is not None:
                        outputNameVals.append((rval[0], rval[1]))
                idx = idx + 1
Esempio n. 29
0
 def addMibCompiler(mibBuilder, **kwargs):
     if not kwargs.get('ifAvailable'):
         raise error.SmiError('MIB compiler not available: %s' % errorMsg)
Esempio n. 30
0
 def prettyIn(self, value):
     for v in str(value):
         if v in self._delimiters:
             raise error.SmiError('Delimiters not allowed in tag value')
     return OctetString.prettyIn(self, value)