コード例 #1
0
ファイル: multiplex.py プロジェクト: woodyle/snmpsim
def init(**context):
    if context['options']:
        for k,v in [split(x, ':') for x in split(context['options'], ',')]:
            if k == 'addon':
                if k in moduleContext:
                    moduleContext[k].append(v)
                else:
                    moduleContext[k] = [v]
            else:
                moduleContext[k] = v
    if context['mode'] == 'variating':
        moduleContext['booted'] = time.time()
    elif context['mode'] == 'recording':
        if 'dir' not in moduleContext:
            raise error.SnmpsimError('SNMP snapshots directory not specified')
        if not os.path.exists(moduleContext['dir']):
            log.msg('multiplex: creating %s...' % moduleContext['dir'])
            os.makedirs(moduleContext['dir'])
        if 'iterations' in moduleContext:
            moduleContext['iterations'] = max(0, int(moduleContext['iterations'])-1)
        if 'period' in moduleContext:
            moduleContext['period'] = float(moduleContext['period'])
        else:
            moduleContext['period'] = 10.0

    moduleContext['ready'] = True
コード例 #2
0
ファイル: multiplex.py プロジェクト: Kryndex/snmpsim
def init(**context):
    if context['options']:
        for k, v in [split(x, ':') for x in split(context['options'], ',')]:
            if k == 'addon':
                if k in moduleContext:
                    moduleContext[k].append(v)
                else:
                    moduleContext[k] = [v]
            else:
                moduleContext[k] = v
    if context['mode'] == 'variating':
        moduleContext['booted'] = time.time()
    elif context['mode'] == 'recording':
        if 'dir' not in moduleContext:
            raise error.SnmpsimError('SNMP snapshots directory not specified')
        if not os.path.exists(moduleContext['dir']):
            log.msg('multiplex: creating %s...' % moduleContext['dir'])
            os.makedirs(moduleContext['dir'])
        if 'iterations' in moduleContext:
            moduleContext['iterations'] = max(
                0,
                int(moduleContext['iterations']) - 1)
        if 'period' in moduleContext:
            moduleContext['period'] = float(moduleContext['period'])
        else:
            moduleContext['period'] = 10.0

    moduleContext['ready'] = True
コード例 #3
0
    def create_snmp_record(self, oid, stop_oid=None, get_subtree=True, get_single_value=False):
        self._get_bulk_flag = self.snmp_parameters.get_bulk_flag
        if get_single_value and self._get_bulk_flag:
            self._get_bulk_flag = False
        self._output_list = list()
        self._oid = univ.ObjectIdentifier(oid)
        if stop_oid:
            self._stop_oid = univ.ObjectIdentifier(stop_oid)
        elif get_subtree:

            _stop_oid = "{}{}".format(oid[:-1], int(oid[-1:]) + 1)
            self._stop_oid = univ.ObjectIdentifier(_stop_oid)

        cb_ctx = {
            'total': 0,
            'count': 0,
            'errors': 0,
            'is_snmp_timeout': False,
            'iteration': 0,
            'reqTime': time.time(),
            '': True,
            'retries': self.snmp_parameters.retry_count,
            'lastOID': oid
        }

        if self._get_bulk_flag:
            self.send_bulk_var_binds(self._oid, cb_ctx)
        else:
            self.send_walk_var_binds(self._oid, cb_ctx)

        log.msg('Sending initial %s request for %s ....' % (
            self.snmp_parameters.get_bulk_flag and 'GETBULK' or 'GETNEXT', self._oid))

        # t = time.time()

        # exc_info = None

        try:
            self.snmp_parameters.snmp_engine.transportDispatcher.runDispatcher()
        except KeyboardInterrupt:
            raise
            # log.msg('Shutting down process...')
        except Exception:
            exc_info = sys.exc_info()
            pass

        if cb_ctx.get("is_snmp_timeout") and not self._output_list:
            raise requestTimedOut

        # t = time.time() - t

        cb_ctx['total'] += cb_ctx['count']

        # log.msg('OIDs dumped: %s, elapsed: %.2f sec, rate: %.2f OIDs/sec, errors: %d' % (
        #     cb_ctx['total'], t, t and cb_ctx['count'] // t or 0, cb_ctx['errors']))
        # if exc_info:
        #     for line in traceback.format_exception(*exc_info):
        #         log.msg(line.replace('\n', ';'))

        return self._output_list
コード例 #4
0
ファイル: notification.py プロジェクト: fixpoint/snmpsim
def _cbFun(sendRequestHandle, errorIndication, errorStatus, errorIndex,
           varBinds, cbCtx):
    oid, value = cbCtx
    if errorIndication or errorStatus:
        log.msg(
            'notification: for %s=%r failed with errorIndication %s, errorStatus %s'
            % (oid, value, errorIndication, errorStatus))
コード例 #5
0
ファイル: redis.py プロジェクト: woodyle/snmpsim
def record(oid, tag, value, **context):
    if 'ready' not in moduleContext:
        raise error.SnmpsimError('module not initialized')

    if 'dbConn' in moduleContext:
        dbConn = moduleContext['dbConn']
    else:
        raise error.SnmpsimError('variation module not initialized')

    if 'started' not in moduleContext:
        moduleContext['started'] = time.time()

    redisScript = moduleContext.get('evalsha')

    keySpace = '%.10d' % (moduleContext['key-spaces-id'] + moduleContext.get('iterations', 0))

    if context['stopFlag']:
        dbConn.sort(keySpace + '-' + 'temp_oids_ordering', store=keySpace + '-' + 'oids_ordering', alpha=True)

        dbConn.delete(keySpace + '-' + 'temp_oids_ordering')
        dbConn.rpush(moduleContext['key-spaces-id'], keySpace)
        log.msg('redis: done with key-space %s' % keySpace)
        if 'iterations' in moduleContext and moduleContext['iterations']:
            log.msg('redis: %s iterations remaining' % moduleContext['iterations'])
            moduleContext['started'] = time.time()
            moduleContext['iterations'] -= 1
            wait = max(0, moduleContext['period'] - (time.time() - moduleContext['started']))

            raise error.MoreDataNotification(period=wait)
        else:
            raise error.NoDataNotification()

    dbOid = '.'.join(['%10s' % x for x in oid.split('.')])
    if 'hexvalue' in context:
        textTag = context['hextag']
        textValue = context['hexvalue']
    else:
        textTag = SnmprecGrammar().getTagByType(context['origValue'])
        textValue = str(context['origValue'])

    dbConn.lpush(keySpace + '-temp_oids_ordering', keySpace + '-' + dbOid)
    if redisScript:
        dbConn.evalsha(redisScript, 1, keySpace + '-' + dbOid, textTag + '|' + textValue)
    else:
        dbConn.set(keySpace + '-' + dbOid, textTag + '|' + textValue)

    if not context['count']:
        settings = {
            'key-spaces-id': moduleContext['key-spaces-id']
        }
        if 'period' in moduleContext:
            settings['period'] = '%.2f' % float(moduleContext['period'])
        if 'addon' in moduleContext:
            settings.update(
                dict([split(x, '=') for x in moduleContext['addon']])
            )
        value = ','.join([ '%s=%s' % (k,v) for k,v in settings.items() ])
        return str(context['startOID']), ':redis', value
    else:
        raise error.NoDataNotification()
コード例 #6
0
ファイル: notification.py プロジェクト: woodyle/snmpsim
def _cbFun(sendRequestHandle,
          errorIndication,
          errorStatus, errorIndex,
          varBinds,
          cbCtx):
    oid, value = cbCtx
    if errorIndication or errorStatus:
        log.msg('notification: for %s=%r failed with errorIndication %s, errorStatus %s' % (oid, value, errorIndication, errorStatus))
コード例 #7
0
ファイル: database.py プロジェクト: woodyle/snmpsim
 def getHandles(self):
     if self.isOpen():
         if self.__textFileTime != os.stat(self.__textFile)[8]:
             log.msg('Text file %s modified, closing' % self.__textFile)
             self.close()
     if not self.isOpen():
         self.create()
         self.open()
     return self.__text, self.__db
コード例 #8
0
 def getHandles(self):
     if self.isOpen():
         if self.__textFileTime != os.stat(self.__textFile)[8]:
             log.msg('Text file %s modified, closing' % self.__textFile)
             self.close()
     if not self.isOpen():
         self.create()
         self.open()
     return self.__text, self.__db
コード例 #9
0
ファイル: redis.py プロジェクト: qnox81/snmpsim
def init(**context):
    options = {}

    if context['options']:
        options.update(
            dict([split(x, ':') for x in split(context['options'], ',')]))

    connectOpts = 'host', 'port', 'password', 'db', 'unix_socket'

    connectParams = dict([(k, options[k]) for k in options
                          if k in connectOpts])

    for k in 'port', 'db':
        if k in connectParams:
            connectParams[k] = int(connectParams[k])

    if not connectParams:
        raise error.SnmpsimError('Redis connect parameters not specified')

    if StrictRedis is None:
        raise error.SnmpsimError('redis-py Python package must be installed!')

    moduleContext['dbConn'] = StrictRedis(**connectParams)

    if context['mode'] == 'recording':
        if 'key-spaces-id' in options:
            moduleContext['key-spaces-id'] = int(options['key-spaces-id'])

        else:
            moduleContext['key-spaces-id'] = random.randrange(0, 0xffffffff)

        log.msg('redis: using key-spaces-id %s' %
                moduleContext['key-spaces-id'])

        if 'iterations' in options:
            moduleContext['iterations'] = max(0,
                                              int(options['iterations']) - 1)

        if 'period' in options:
            moduleContext['period'] = float(options['period'])

        else:
            moduleContext['period'] = 60.0

        redisScript = options.get('evalsha')
        if redisScript:
            log.msg('redis: using server-side script %s' % redisScript)

    elif context['mode'] == 'variating':
        moduleContext['booted'] = time.time()

    moduleContext['ready'] = True
コード例 #10
0
ファイル: redis.py プロジェクト: etingof/snmpsim
def init(**context):
    options = {}

    if context['options']:
        options.update(
            dict([split(x, ':')
                  for x in split(context['options'], ',')]))

    connectOpts = 'host', 'port', 'password', 'db', 'unix_socket'

    connectParams = dict(
        [(k, options[k]) for k in options if k in connectOpts])

    for k in 'port', 'db':
        if k in connectParams:
            connectParams[k] = int(connectParams[k])

    if not connectParams:
        raise error.SnmpsimError('Redis connect parameters not specified')

    if StrictRedis is None:
        raise error.SnmpsimError('redis-py Python package must be installed!')

    moduleContext['dbConn'] = StrictRedis(**connectParams)

    if context['mode'] == 'recording':
        if 'key-spaces-id' in options:
            moduleContext['key-spaces-id'] = int(options['key-spaces-id'])

        else:
            moduleContext['key-spaces-id'] = random.randrange(0, 0xffffffff)

        log.msg('redis: using key-spaces-id %s' % moduleContext['key-spaces-id'])

        if 'iterations' in options:
            moduleContext['iterations'] = max(0, int(options['iterations']) - 1)

        if 'period' in options:
            moduleContext['period'] = float(options['period'])

        else:
            moduleContext['period'] = 60.0

        redisScript = options.get('evalsha')
        if redisScript:
            log.msg('redis: using server-side script %s' % redisScript)

    elif context['mode'] == 'variating':
        moduleContext['booted'] = time.time()

    moduleContext['ready'] = True
コード例 #11
0
ファイル: multiplex.py プロジェクト: woodyle/snmpsim
def record(oid, tag, value, **context):
    if 'ready' not in moduleContext:
        raise error.SnmpsimError('module not initialized')
    if 'started' not in moduleContext:
        moduleContext['started'] = time.time()
    if context['stopFlag']:
        if 'file' in moduleContext:
            moduleContext['file'].close()
            del moduleContext['file']
        else:
            moduleContext['filenum'] = 0
        if 'iterations' in moduleContext and moduleContext['iterations']:
            log.msg('multiplex: %s iterations remaining' % moduleContext['iterations'])
            moduleContext['started'] = time.time()
            moduleContext['iterations'] -= 1
            moduleContext['filenum'] += 1
            wait = max(0, moduleContext['period'] - (time.time() - moduleContext['started']))
            raise error.MoreDataNotification(period=wait)
        else:
            raise error.NoDataNotification()

    if 'file' not in moduleContext:
        if 'filenum' not in moduleContext:
            moduleContext['filenum'] = 0
        snmprecfile = os.path.join(moduleContext['dir'],
                                   '%.5d%ssnmprec' % (moduleContext['filenum'],
                                                      os.path.extsep))
        moduleContext['file'] = open(snmprecfile, 'wb')
        log.msg('multiplex: writing into %s file...' % snmprecfile)

    moduleContext['file'].write(
        SnmprecRecord().format(context['origOid'], context['origValue'])
    )

    if not context['total']:
        settings = {
            'dir': moduleContext['dir'].replace(os.path.sep, '/')
        }
        if 'period' in moduleContext:
            settings['period'] = '%.2f' % float(moduleContext['period'])
        if 'addon' in moduleContext:
            settings.update(
                dict([split(x, '=') for x in moduleContext['addon']])
            )
        value = ','.join([ '%s=%s' % (k,v) for k,v in settings.items() ])
        return str(context['startOID']), ':multiplex', value
    else:
        raise error.NoDataNotification()
コード例 #12
0
def record(oid, tag, value, **context):
    if 'ready' not in moduleContext:
        raise error.SnmpsimError('module not initialized')
    if 'started' not in moduleContext:
        moduleContext['started'] = time.time()
    if context['stopFlag']:
        if 'file' in moduleContext:
            moduleContext['file'].close()
            del moduleContext['file']
        else:
            moduleContext['filenum'] = 0
        if 'iterations' in moduleContext and moduleContext['iterations']:
            log.msg('multiplex: %s iterations remaining' % moduleContext['iterations'])
            moduleContext['started'] = time.time()
            moduleContext['iterations'] -= 1
            moduleContext['filenum'] += 1
            wait = max(0, moduleContext['period'] - (time.time() - moduleContext['started']))
            raise error.MoreDataNotification(period=wait)
        else:
            raise error.NoDataNotification()

    if 'file' not in moduleContext:
        if 'filenum' not in moduleContext:
            moduleContext['filenum'] = 0
        snmprecfile = os.path.join(moduleContext['dir'],
                                   '%.5d%ssnmprec' % (moduleContext['filenum'],
                                                      os.path.extsep))
        moduleContext['file'] = open(snmprecfile, 'wb')
        log.msg('multiplex: writing into %s file...' % snmprecfile)

    moduleContext['file'].write(
        SnmprecRecord().format(context['origOid'], context['origValue'])
    )

    if not context['total']:
        settings = {
            'dir': moduleContext['dir'].replace(os.path.sep, '/')
        }
        if 'period' in moduleContext:
            settings['period'] = '%.2f' % float(moduleContext['period'])
        if 'addon' in moduleContext:
            settings.update(
                dict([split(x, '=') for x in moduleContext['addon']])
            )
        value = ','.join(['%s=%s' % (k, v) for k, v in settings.items()])
        return str(context['startOID']), ':multiplex', value
    else:
        raise error.NoDataNotification()
コード例 #13
0
ファイル: subprocess.py プロジェクト: Kryndex/snmpsim
def variate(oid, tag, value, **context):
    # in --v2c-arch some of the items are not defined
    transportDomain = transportAddress = securityModel = securityName = \
        securityLevel = contextName = '<undefined>'
    if 'transportDomain' in context:
        transportDomain = rfc1902.ObjectName(
            context['transportDomain']).prettyPrint()
    if 'transportAddress' in context:
        transportAddress = ':'.join(
            [str(x) for x in context['transportAddress']])
    if 'securityModel' in context:
        securityModel = str(context['securityModel'])
    if 'securityName' in context:
        securityName = str(context['securityName'])
    if 'securityLevel' in context:
        securityLevel = str(context['securityLevel'])
    if 'contextName' in context:
        contextName = str(context['contextName'])

    args = [(x.replace('@TRANSPORTDOMAIN@', transportDomain).replace(
        '@TRANSPORTADDRESS@', transportAddress).replace(
            '@SECURITYMODEL@',
            securityModel).replace('@SECURITYNAME@', securityName).replace(
                '@SECURITYLEVEL@',
                securityLevel).replace('@CONTEXTNAME@', contextName).replace(
                    '@DATAFILE@',
                    context['dataFile']).replace('@OID@', str(oid)).replace(
                        '@TAG@', tag).replace('@ORIGOID@',
                                              str(context['origOid'])).
             replace('@ORIGTAG@',
                     str(sum(
                         [x
                          for x in context['origValue'].tagSet[0]]))).replace(
                              '@ORIGVALUE@',
                              str(context['origValue'])).replace(
                                  '@SETFLAG@',
                                  str(int(context['setFlag']))).replace(
                                      '@NEXTFLAG@',
                                      str(int(context['nextFlag']))).replace(
                                          '@SUBTREEFLAG@',
                                          str(int(context['subtreeFlag']))))
            for x in split(value, ' ')]

    log.msg('subprocess: executing external process "%s"' % ' '.join(args))

    call = (hasattr(subprocess, 'check_output') and subprocess.check_output
            or hasattr(subprocess, 'check_call') and subprocess.check_call
            or subprocess.call)
    if not hasattr(subprocess, 'check_output'):
        log.msg('subprocess: old Python, expect no output!')

    try:
        return oid, tag, call(args, shell=moduleContext['settings']['shell'])
    except (hasattr(subprocess, 'CalledProcessError')
            and subprocess.CalledProcessError or Exception):
        log.msg('subprocess: external program execution failed')
        return context['origOid'], tag, context['errorStatus']
コード例 #14
0
ファイル: subprocess.py プロジェクト: woodyle/snmpsim
def variate(oid, tag, value, **context):
    # in --v2c-arch some of the items are not defined
    transportDomain = transportAddress = securityModel = securityName = \
                      securityLevel = contextName = '<undefined>'
    if 'transportDomain' in context:
        transportDomain = rfc1902.ObjectName(context['transportDomain']).prettyPrint()
    if 'transportAddress' in context:
        transportAddress = ':'.join([str(x) for x in context['transportAddress']])
    if 'securityModel' in context:
        securityModel = str(context['securityModel'])
    if 'securityName' in context:
        securityName = str(context['securityName'])
    if 'securityLevel' in context:
        securityLevel = str(context['securityLevel'])
    if 'contextName' in context:
        contextName = str(context['contextName'])

    args = [ x\
             .replace('@TRANSPORTDOMAIN@', transportDomain)\
             .replace('@TRANSPORTADDRESS@', transportAddress)\
             .replace('@SECURITYMODEL@', securityModel)\
             .replace('@SECURITYNAME@', securityName)\
             .replace('@SECURITYLEVEL@', securityLevel)\
             .replace('@CONTEXTNAME@', contextName)\
             .replace('@DATAFILE@', context['dataFile'])\
             .replace('@OID@', str(oid))\
             .replace('@TAG@', tag)\
             .replace('@ORIGOID@', str(context['origOid']))\
             .replace('@ORIGTAG@', str(sum([ x for x in context['origValue'].tagSet[0]])))\
             .replace('@ORIGVALUE@', str(context['origValue']))\
             .replace('@SETFLAG@', str(int(context['setFlag'])))\
             .replace('@NEXTFLAG@', str(int(context['nextFlag'])))\
             .replace('@SUBTREEFLAG@', str(int(context['subtreeFlag'])))\
             for x in split(value, ' ') ]

    log.msg('subprocess: executing external process "%s"' % ' '.join(args))

    call = hasattr(subprocess, 'check_output') and subprocess.check_output or \
               hasattr(subprocess, 'check_call') and subprocess.check_call or \
               subprocess.call
    if not hasattr(subprocess, 'check_output'):
        log.msg('subprocess: old Python, expect no output!')

    try:
        return oid, tag, call(
            args, shell=moduleContext['settings']['shell']
        )
    except hasattr(subprocess, 'CalledProcessError') and \
               subprocess.CalledProcessError or Exception:
        log.msg('subprocess: external program execution failed')
        return context['origOid'], tag, context['errorStatus']
コード例 #15
0
ファイル: error.py プロジェクト: woodyle/snmpsim
def variate(oid, tag, value, **context):
    if not context['nextFlag'] and not context['exactMatch']:
        return context['origOid'], tag, context['errorStatus']

    if 'settings' not in recordContext:
        recordContext['settings'] = dict([split(x, '=') for x in split(value, ',')])

        if 'hexvalue' in recordContext['settings']:
            recordContext['settings']['value'] = [int(recordContext['settings']['hexvalue'][x:x+2], 16) for x in range(0, len(recordContext['settings']['hexvalue']), 2)]

        if 'status' in recordContext['settings']:
            recordContext['settings']['status'] = recordContext['settings']['status'].lower()

        if 'op' not in recordContext['settings']:
            recordContext['settings']['op'] = 'any'

        if 'vlist' in recordContext['settings']:
            vlist = {}
            recordContext['settings']['vlist'] = split(recordContext['settings']['vlist'], ':')
            while recordContext['settings']['vlist']:
                o,v,e = recordContext['settings']['vlist'][:3]
                recordContext['settings']['vlist'] = recordContext['settings']['vlist'][3:]
                v = SnmprecGrammar.tagMap[tag](v)
                if o not in vlist:
                    vlist[o] = {}
                if o == 'eq':
                    vlist[o][v] = e
                elif o in ('lt', 'gt'):
                    vlist[o] = v, e
                else:
                    log.msg('error: bad vlist syntax: %s' % recordContext['settings']['vlist'])
            recordContext['settings']['vlist'] = vlist

    e = None

    if context['setFlag']:
        if 'vlist' in recordContext['settings']:
            if 'eq' in recordContext['settings']['vlist'] and  \
                  context['origValue'] in recordContext['settings']['vlist']['eq']:
                e = recordContext['settings']['vlist']['eq'][context['origValue']]
            elif 'lt' in recordContext['settings']['vlist'] and  \
                  context['origValue'] < recordContext['settings']['vlist']['lt'][0]:
                e = recordContext['settings']['vlist']['lt'][1]
            elif 'gt' in recordContext['settings']['vlist'] and  \
                  context['origValue'] > recordContext['settings']['vlist']['gt'][0]:
                e = recordContext['settings']['vlist']['gt'][1]
        elif recordContext['settings']['op'] in ('set', 'any'):
            if 'status' in recordContext['settings']:
                e = recordContext['settings']['status']
    else:        
        if recordContext['settings']['op'] in ('get', 'any'):
            if 'status' in recordContext['settings']:
                e = recordContext['settings']['status']

    if e and e in errorTypes:
        log.msg('error: reporting %s for %s' % (e, oid))
        raise errorTypes[e](
            name=oid, idx=max(0, context['varsTotal']-context['varsRemaining']-1)
        )

    if context['setFlag']:
        recordContext['settings']['value'] = context['origValue']

    return oid, tag, recordContext['settings'].get('value', context['errorStatus'])
コード例 #16
0
ファイル: notification.py プロジェクト: woodyle/snmpsim
def variate(oid, tag, value, **context):
    if 'snmpEngine' in context and context['snmpEngine']:
        snmpEngine = context['snmpEngine']
        if snmpEngine not in moduleContext:
            moduleContext[snmpEngine] = {}
        if context['transportDomain'] not in moduleContext[snmpEngine]:
            # register this SNMP Engine to handle our transports'
            # receiver IDs (which we build by outbound and simulator
            # transportDomains concatenation)
            snmpEngine.registerTransportDispatcher(
                snmpEngine.transportDispatcher,
                UdpTransportTarget.transportDomain + \
                    context['transportDomain']
            )
            snmpEngine.registerTransportDispatcher(
                snmpEngine.transportDispatcher,
                Udp6TransportTarget.transportDomain + \
                    context['transportDomain']
            )
            moduleContext[snmpEngine][context['transportDomain']] = 1
    else:
        raise error.SnmpsimError('variation module not given snmpEngine')

    if not context['nextFlag'] and not context['exactMatch']:
        return context['origOid'], tag, context['errorStatus']

    if 'settings' not in recordContext:
        recordContext['settings'] = dict([split(x, '=') for x in split(value, ',')])
        for k,v in ( ('op', 'set'),
                     ('community', 'public'),
                     ('authkey', None),
                     ('authproto', 'md5'),
                     ('privkey', None),
                     ('privproto', 'des'),
                     ('proto', 'udp'),
                     ('port', '162'),
                     ('ntftype', 'trap'),
                     ('trapoid', '1.3.6.1.6.3.1.1.5.1') ):
            recordContext['settings'].setdefault(k, v)

        if 'hexvalue' in recordContext['settings']:
            recordContext['settings']['value'] = [int(recordContext['settings']['hexvalue'][x:x+2], 16) for x in range(0, len(recordContext['settings']['hexvalue']), 2)]

        if 'vlist' in recordContext['settings']:
            vlist = {}
            recordContext['settings']['vlist'] = split(recordContext['settings']['vlist'], ':')
            while recordContext['settings']['vlist']:
                o,v = recordContext['settings']['vlist'][:2]
                recordContext['settings']['vlist'] = recordContext['settings']['vlist'][2:]
                v = SnmprecGrammar.tagMap[tag](v)
                if o not in vlist:
                    vlist[o] = set()
                if o == 'eq':
                    vlist[o].add(v)
                elif o in ('lt', 'gt'):
                    vlist[o] = v
                else:
                    log.msg('notification: bad vlist syntax: %s' % recordContext['settings']['vlist'])
            recordContext['settings']['vlist'] = vlist

    args = recordContext['settings']
   
    if context['setFlag'] and 'vlist' in args:
        if 'eq' in args['vlist'] and  \
                 context['origValue'] in args['vlist']['eq']:
            pass
        elif 'lt' in args['vlist'] and  \
                 context['origValue'] < args['vlist']['lt']:
            pass
        elif 'gt' in args['vlist'] and  \
                 context['origValue'] > args['vlist']['gt']:
            pass
        else:
            return oid, tag, context['origValue']

    if args['op'] not in ('get', 'set', 'any', '*'):
        log.msg('notification: unknown SNMP request type configured: %s' % args['op'])
        return context['origOid'], tag, context['errorStatus']

    if args['op'] == 'get' and not context['setFlag'] or \
       args['op'] == 'set' and context['setFlag'] or \
       args['op'] in ('any', '*'):
        if args['version'] in ('1', '2c'):
            authData = CommunityData(args['community'], mpModel=args['version'] == '2c' and 1 or 0)
        elif args['version'] == '3':
            if args['authproto'] == 'md5':
                authProtocol = usmHMACMD5AuthProtocol
            elif args['authproto'] == 'sha':
                authProtocol = usmHMACSHAAuthProtocol
            elif args['authproto'] == 'none':
                authProtocol = usmNoAuthProtocol
            else:
                log.msg('notification: unknown auth proto %s' % args['authproto'])
                return context['origOid'], tag, context['errorStatus']
            if args['privproto'] == 'des':
                privProtocol = usmDESPrivProtocol
            elif args['privproto'] == 'aes':
                privProtocol = usmAesCfb128Protocol
            elif args['privproto'] == 'none':
                privProtocol = usmNoPrivProtocol
            else:
                log.msg('notification: unknown privacy proto %s' % args['privproto'])
                return context['origOid'], tag, context['errorStatus']
            authData = UsmUserData(args['user'], args['authkey'], args['privkey'], authProtocol=authProtocol, privProtocol=privProtocol)
        else:
            log.msg('notification: unknown SNMP version %s' % args['version'])
            return context['origOid'], tag, context['errorStatus']

        if 'host' not in args:
            log.msg('notification: target hostname not configured for OID' % (oid,))
            return context['origOid'], tag, context['errorStatus']
        
        if args['proto'] == 'udp':
            target = UdpTransportTarget((args['host'], int(args['port'])))
        elif args['proto'] == 'udp6':
            target = Udp6TransportTarget((args['host'], int(args['port'])))
        else:
            log.msg('notification: unknown transport %s' % args['proto'])
            return context['origOid'], tag, context['errorStatus']
       
        localAddress = None

        if 'bindaddr' in args:
            localAddress = args['bindaddr']
        else:
            if context['transportDomain'][:len(target.transportDomain)] == \
                        target.transportDomain:
                localAddress = snmpEngine.transportDispatcher.getTransport(context['transportDomain']).getLocalAddress()[0]
            else:
                log.msg('notification: incompatible network transport types used by CommandResponder vs NotificationOriginator')
                if 'bindaddr' in args:
                    localAddress = args['bindaddr']

        if localAddress:
            log.msg('notification: binding to local address %s' % localAddress)
            target.setLocalAddress((localAddress, 0))

        # this will make target objects different based on their bind address 
        target.transportDomain = target.transportDomain + \
                                 context['transportDomain']

        varBinds = []

        if 'uptime' in args:
            varBinds.append(
                ( ObjectIdentifier('1.3.6.1.2.1.1.3.0'),
                  TimeTicks(args['uptime']) )
            )

        if args['version'] == '1':
            if 'agentaddress' in args:
                varBinds.append(
                    ( ObjectIdentifier('1.3.6.1.6.3.18.1.3.0'),
                      IpAddress(args['agentaddress']) )
                )
            if 'enterprise' in args:
                varBinds.append(
                    ( ObjectIdentifier('1.3.6.1.6.3.1.1.4.3.0'),
                      ObjectIdentifier(args['enterprise']) )
                )

        if 'varbinds' in args:
            vbs = split(args['varbinds'], ':') 
            while vbs:
                varBinds.append(
                    (ObjectIdentifier(vbs[0]), typeMap[vbs[1]](vbs[2]))
                )
                vbs = vbs[3:]

        sendNotification(
            snmpEngine, authData, target, ContextData(), args['ntftype'],
            NotificationType(ObjectIdentity(args['trapoid'])).addVarBinds(*varBinds),
            cbFun=_cbFun, cbCtx=(oid, value)
        )

        log.msg('notification: sending Notification to %s with credentials %s' % (authData, target))

    if context['setFlag'] or 'value' not in args:
        return oid, tag, context['origValue']
    else:
        return oid, tag, args['value']
コード例 #17
0
    def cb_fun(self, snmp_engine, send_request_handle, error_indication,
              error_status, error_index, var_bind_table, cb_ctx):

        if cb_ctx['is_snmp_timeout'] and self.snmp_parameters.get_bulk_flag:
            self._get_bulk_flag = True
            cb_ctx['is_snmp_timeout'] = False

        if isinstance(error_indication, RequestTimedOut):
            cb_ctx['is_snmp_timeout'] = True
            self._get_bulk_flag = False

        if error_indication and not cb_ctx['retries']:
            cb_ctx['errors'] += 1
            # log.msg('SNMP Engine error: %s' % error_indication)
            return
        # SNMPv1 response may contain noSuchName error *and* SNMPv2c exception,
        # so we ignore noSuchName error here
        if error_status and error_status != 2 or error_indication:
            log.msg('Remote SNMP error %s' % (error_indication or error_status.prettyPrint()))
            if cb_ctx['retries']:
                try:
                    next_oid = var_bind_table[-1][0][0]
                except IndexError:
                    next_oid = cb_ctx['lastOID']
                else:
                    log.msg('Failed OID: %s' % next_oid)
                # fuzzy logic of walking a broken OID
                if len(next_oid) < 4:
                    pass
                elif (self.snmp_parameters.retry_count - cb_ctx[
                    'retries']) * 10 / self.snmp_parameters.retry_count > 5:
                    next_oid = next_oid[:-2] + (next_oid[-2] + 1,)
                elif next_oid[-1]:
                    next_oid = next_oid[:-1] + (next_oid[-1] + 1,)
                else:
                    next_oid = next_oid[:-2] + (next_oid[-2] + 1, 0)

                cb_ctx['retries'] -= 1
                cb_ctx['lastOID'] = next_oid

                log.msg('Retrying with OID %s (%s retries left)...' % (next_oid, cb_ctx['retries']))

                # initiate another SNMP walk iteration
                if self._get_bulk_flag:
                    self.send_bulk_var_binds(next_oid, cb_ctx)
                else:
                    self.send_walk_var_binds(next_oid, cb_ctx)

            cb_ctx['errors'] += 1

            return

        if self.snmp_parameters.retry_count != cb_ctx['retries']:
            cb_ctx['retries'] += 1

        if var_bind_table and var_bind_table[-1] and var_bind_table[-1][0]:
            cb_ctx['lastOID'] = var_bind_table[-1][0][0]

        stop_flag = False
        time.sleep(0.2)

        # Walk var-binds
        for varBindRow in var_bind_table:
            for oid, value in varBindRow:
                # EOM
                _add_line = True
                if self._stop_oid and oid >= self._stop_oid:
                    stop_flag = True
                    _add_line = False
                if (value is None or
                        value.tagSet in (rfc1905.NoSuchObject.tagSet,
                                         rfc1905.NoSuchInstance.tagSet,
                                         rfc1905.EndOfMibView.tagSet)):
                    stop_flag = True

                # remove value enumeration
                if value.tagSet == rfc1902.Integer32.tagSet:
                    value = rfc1902.Integer32(value)

                if value.tagSet == rfc1902.Unsigned32.tagSet:
                    value = rfc1902.Unsigned32(value)

                if value.tagSet == rfc1902.Bits.tagSet:
                    value = rfc1902.OctetString(value)

                # Build .snmprec record

                context = {
                    'origOid': oid,
                    'origValue': value,
                    'count': cb_ctx['count'],
                    'total': cb_ctx['total'],
                    'iteration': cb_ctx['iteration'],
                    'reqTime': cb_ctx['reqTime'],
                    'startOID': self._oid,
                    'stop_flag': stop_flag,
                }

                try:
                    line = ""
                    if _add_line:
                        line = self.data_file_handler.format(oid, value, **context).replace("|", ", ")
                except error.MoreDataNotification:
                    cb_ctx['count'] = 0
                    cb_ctx['iteration'] += 1

                    more_data_notification = sys.exc_info()[1]
                    if 'period' in more_data_notification:
                        log.msg(
                            '%s OIDs dumped, waiting %.2f sec(s)...' % (
                                cb_ctx['total'], more_data_notification['period']))
                        time.sleep(more_data_notification['period'])

                    # initiate another SNMP walk iteration
                    if self._get_bulk_flag:
                        self.send_bulk_var_binds(self._oid, cb_ctx)
                    else:
                        self.send_walk_var_binds(self._oid, cb_ctx)

                    stop_flag = True  # stop current iteration

                except error.NoDataNotification:
                    pass
                except error.SnmpsimError:
                    log.msg('ERROR: %s' % (sys.exc_info()[1],))
                    continue
                else:
                    if _add_line and line and line not in self._output_list:
                        self._output_list.append(line)

                    cb_ctx['count'] += 1
                    cb_ctx['total'] += 1

                    if cb_ctx['count'] % 100 == 0:
                        log.msg('OIDs dumped: %s/%s' % (
                            cb_ctx['iteration'], cb_ctx['count']))

        # Next request time
        cb_ctx['reqTime'] = time.time()
        # Continue walking
        return not stop_flag
コード例 #18
0
ファイル: pcap2dev.py プロジェクト: Kryndex/snmpsim
    mibBuilder = builder.MibBuilder()

    mibViewController = view.MibViewController(mibBuilder)

    compiler.addMibCompiler(mibBuilder,
                            sources=mibSources or defaultMibSources)
    if isinstance(startOID, rfc1902.ObjectIdentity):
        startOID.resolveWithMib(mibViewController)
    if isinstance(stopOID, rfc1902.ObjectIdentity):
        stopOID.resolveWithMib(mibViewController)

# Load variation module

if variationModuleName:
    for variationModulesDir in confdir.variation:
        log.msg('Scanning "%s" directory for variation modules...' %
                variationModulesDir)
        if not os.path.exists(variationModulesDir):
            log.msg('Directory "%s" does not exist' % variationModulesDir)
            continue

        mod = os.path.join(variationModulesDir, variationModuleName + '.py')
        if not os.path.exists(mod):
            log.msg('Variation module "%s" not found' % mod)
            continue

        ctx = {'path': mod, 'moduleContext': {}}

        try:
            if sys.version_info[0] > 2:
                exec(compile(open(mod).read(), mod, 'exec'), ctx)
            else:
コード例 #19
0
ファイル: multiplex.py プロジェクト: etingof/snmpsim
def variate(oid, tag, value, **context):

    if 'settings' not in recordContext:
        recordContext['settings'] = dict(
            [split(x, '=') for x in split(value, ',')])

        if 'dir' not in recordContext['settings']:
            log.msg('multiplex: snapshot directory not specified')
            return context['origOid'], tag, context['errorStatus']

        recordContext['settings']['dir'] = recordContext[
            'settings']['dir'].replace('/', os.path.sep)

        if recordContext['settings']['dir'][0] != os.path.sep:
            for x in confdir.data:
                d = os.path.join(x, recordContext['settings']['dir'])
                if os.path.exists(d):
                    break

            else:
                log.msg('multiplex: directory %s not '
                        'found' % recordContext['settings']['dir'])
                return context['origOid'], tag, context['errorStatus']

        else:
            d = recordContext['settings']['dir']

        recordContext['dirmap'] = dict(
            [(int(os.path.basename(x).split(os.path.extsep)[0]),
              os.path.join(d, x))
             for x in os.listdir(d)
             if x[-7:] == 'snmprec']
        )

        recordContext['keys'] = list(recordContext['dirmap'])

        recordContext['bounds'] = (
            min(recordContext['keys']), max(recordContext['keys']))

        if 'period' in recordContext['settings']:
            recordContext['settings']['period'] = float(
                recordContext['settings']['period'])

        else:
            recordContext['settings']['period'] = 60.0

        if 'wrap' in recordContext['settings']:
            recordContext['settings']['wrap'] = bool(
                recordContext['settings']['wrap'])

        else:
            recordContext['settings']['wrap'] = False

        if 'control' in recordContext['settings']:
            recordContext['settings']['control'] = rfc1902.ObjectName(
                recordContext['settings']['control'])

            log.msg(
                'multiplex: using control OID %s for subtree %s, '
                'time-based multiplexing '
                'disabled' % (recordContext['settings']['control'], oid))

        recordContext['ready'] = True

    if 'ready' not in recordContext:
        return context['origOid'], tag, context['errorStatus']

    if oid not in moduleContext:
        moduleContext[oid] = {}

    if context['setFlag']:
        if 'control' in (
                recordContext['settings'] and
                recordContext['settings']['control'] == context['origOid']):

            fileno = int(context['origValue'])
            if fileno >= len(recordContext['keys']):
                log.msg('multiplex: .snmprec file number %s over limit of'
                        ' %s' % (fileno, len(recordContext['keys'])))

                return context['origOid'], tag, context['errorStatus']

            moduleContext[oid]['fileno'] = fileno

            log.msg(
                'multiplex: switched to file #%s '
                '(%s)' % (recordContext['keys'][fileno],
                          recordContext['dirmap'][recordContext['keys'][fileno]]))

            return context['origOid'], tag, context['origValue']

        else:
            return context['origOid'], tag, context['errorStatus']

    if 'control' in recordContext['settings']:
        if 'fileno' not in moduleContext[oid]:
            moduleContext[oid]['fileno'] = 0

        if (not context['nextFlag'] and
                recordContext['settings']['control'] == context['origOid']):

            val = rfc1902.Integer32(moduleContext[oid]['fileno'])

            return context['origOid'], tag, val

    else:
        period = recordContext['settings']['period']

        uptime = time.time() - moduleContext['booted']
        timeslot = uptime % (period * len(recordContext['dirmap']))

        fileslot = int(timeslot / period) + recordContext['bounds'][0]

        fileno = bisect.bisect(recordContext['keys'], fileslot) - 1

        if ('fileno' not in moduleContext[oid] or
                moduleContext[oid]['fileno'] < fileno or
                recordContext['settings']['wrap']):
            moduleContext[oid]['fileno'] = fileno

    datafile = recordContext['dirmap'][
        recordContext['keys'][moduleContext[oid]['fileno']]]

    if ('datafile' not in moduleContext[oid] or
            moduleContext[oid]['datafile'] != datafile):

        if 'datafileobj' in moduleContext[oid]:
            moduleContext[oid]['datafileobj'].close()

        recordIndex = RecordIndex(datafile, SnmprecRecord()).create()

        moduleContext[oid]['datafileobj'] = recordIndex

        moduleContext[oid]['datafile'] = datafile

        log.msg(
            'multiplex: switching to data file %s for '
            '%s' % (datafile, context['origOid']))

    text, db = moduleContext[oid]['datafileobj'].getHandles()

    textOid = str(rfc1902.OctetString(
        '.'.join(['%s' % x for x in context['origOid']])))

    try:
        line = moduleContext[oid]['datafileobj'].lookup(textOid)

    except KeyError:
        offset = searchRecordByOid(context['origOid'], text, SnmprecRecord())
        exactMatch = False

    else:
        offset, subtreeFlag, prevOffset = line.split(str2octs(','))
        exactMatch = True

    text.seek(int(offset))

    line, _, _ = getRecord(text)  # matched line

    if context['nextFlag']:
        if exactMatch:
            line, _, _ = getRecord(text)

    else:
        if not exactMatch:
            return context['origOid'], tag, context['errorStatus']

    if not line:
        return context['origOid'], tag, context['errorStatus']

    try:
        oid, value = SnmprecRecord().evaluate(line)

    except error.SnmpsimError:
        oid, value = context['origOid'], context['errorStatus']

    return oid, tag, value
コード例 #20
0
ファイル: sql.py プロジェクト: xiar/vpduserv
def variate(oid, tag, value, **context):
    if 'dbConn' in moduleContext:
        dbConn = moduleContext['dbConn']
    else:
        raise error.SnmpsimError('variation module not initialized')

    cursor = dbConn.cursor()

    try:
        cursor.execute('set session transaction isolation level %s' %
                       moduleContext['isolationLevel'])
        cursor.fetchall()
    except:  # non-MySQL/Postgres
        pass

    if value:
        dbTable = value.split(',').pop(0)
    elif 'dbTable' in moduleContext:
        dbTable = moduleContext['dbTable']
    else:
        log.msg('SQL table not specified for OID %s' % (context['origOid'], ))
        return context['origOid'], tag, context['errorStatus']

    origOid = context['origOid']
    sqlOid = '.'.join(['%10s' % x for x in str(origOid).split('.')])
    if context['setFlag']:
        if 'hexvalue' in context:
            textTag = context['hextag']
            textValue = context['hexvalue']
        else:
            textTag = SnmprecGrammar().getTagByType(context['origValue'])
            textValue = str(context['origValue'])
        cursor.execute(
            'select maxaccess,tag,value from %s where oid=\'%s\' limit 1' %
            (dbTable, sqlOid))
        resultset = cursor.fetchone()
        if resultset:
            maxaccess = resultset[0]
            if maxaccess != 'read-write':
                return origOid, tag, context['errorStatus']

            value_written = textValue
            try:
                value_settings = {}
                value_settings = dict(
                    [split(x, '=') for x in split(resultset[2], ',')])
                print value_settings
                # if detected error mode, raise an error
                if 'mode' in value_settings and \
                        value_settings['mode'] == 'error':
                    raise Error.WrongValueError(
                        name=origOid,
                        idx=max(
                            0, context['varsTotal'] -
                            context['varsRemaining'] - 1))
                elif 'mode' in value_settings and \
                    value_settings['mode'] == 'normal':
                    value_written = "mode=" + value_settings['mode'] + \
                        ",value=" + textValue
                else:
                    return origOid, tag, context['errorStatus']
            except Error.WrongValueError:
                cursor.close()
                raise Error.WrongValueError(name=origOid,
                                            idx=max(
                                                0, context['varsTotal'] -
                                                context['varsRemaining'] - 1))
            except:
                pass

            cursor.execute(
                'update %s set tag=\'%s\',value=\'%s\' where oid=\'%s\'' %
                (dbTable, textTag, value_written, sqlOid))

            inform = moduleContext.get('inform')
            try:
                value = str(origOid) + " " + textValue
                written_len = os.write(inform, value)
                if written_len != len(value):
                    log.msg(
                        "--->Infrasim: Expected length %d, actual length %d\n"
                        % (len(str(origOid)), written_len))
                    cursor.close()
                    return origOid, tag, context['errorStatus']
            except Exception, ex:
                log.msg("--->Infrasim: {0}".format(ex))
                cursor.close()
                return origOid, tag, context['errorStatus']

        else:
            cursor.close()
            raise Error.NoSuchInstanceError(
                name=origOid,
                idx=max(0,
                        context['varsTotal'] - context['varsRemaining'] - 1))

        if context['varsRemaining'] == 0:  # last OID in PDU
            dbConn.commit()
        cursor.close()
        return origOid, textTag, context['origValue']
コード例 #21
0
def variate(oid, tag, value, **context):
    if not context['nextFlag'] and not context['exactMatch']:
        return context['origOid'], tag, context['errorStatus']

    if 'settings' not in recordContext:
        recordContext['settings'] = dict([split(x, '=') for x in split(value, ',')])

        if 'hexvalue' in recordContext['settings']:
            recordContext['settings']['value'] = [int(recordContext['settings']['hexvalue'][x:x + 2], 16) for x in
                                                  range(0, len(recordContext['settings']['hexvalue']), 2)]

        if 'wait' in recordContext['settings']:
            recordContext['settings']['wait'] = float(recordContext['settings']['wait'])
        else:
            recordContext['settings']['wait'] = 500.0

        if 'deviation' in recordContext['settings']:
            recordContext['settings']['deviation'] = float(recordContext['settings']['deviation'])
        else:
            recordContext['settings']['deviation'] = 0.0

        if 'vlist' in recordContext['settings']:
            vlist = {}
            recordContext['settings']['vlist'] = split(recordContext['settings']['vlist'], ':')
            while recordContext['settings']['vlist']:
                o, v, d = recordContext['settings']['vlist'][:3]
                recordContext['settings']['vlist'] = recordContext['settings']['vlist'][3:]
                d = int(d)
                v = SnmprecGrammar.tagMap[tag](v)
                if o not in vlist:
                    vlist[o] = {}
                if o == 'eq':
                    vlist[o][v] = d
                elif o in ('lt', 'gt'):
                    vlist[o] = v, d
                else:
                    log.msg('delay: bad vlist syntax: %s' % recordContext['settings']['vlist'])
            recordContext['settings']['vlist'] = vlist

        if 'tlist' in recordContext['settings']:
            tlist = {}
            recordContext['settings']['tlist'] = split(recordContext['settings']['tlist'], ':')
            while recordContext['settings']['tlist']:
                o, v, d = recordContext['settings']['tlist'][:3]
                recordContext['settings']['tlist'] = recordContext['settings']['tlist'][3:]
                v = int(v)
                d = int(d)
                if o not in tlist:
                    tlist[o] = {}
                if o == 'eq':
                    tlist[o][v] = d
                elif o in ('lt', 'gt'):
                    tlist[o] = v, d
                else:
                    log.msg('delay: bad tlist syntax: %s' % recordContext['settings']['tlist'])
            recordContext['settings']['tlist'] = tlist

    if context['setFlag'] and 'vlist' in recordContext['settings']:
        if ('eq' in recordContext['settings']['vlist'] and
                    context['origValue'] in recordContext['settings']['vlist']['eq']):
            delay = recordContext['settings']['vlist']['eq'][context['origValue']]
        elif ('lt' in recordContext['settings']['vlist'] and
                context['origValue'] < recordContext['settings']['vlist']['lt'][0]):
            delay = recordContext['settings']['vlist']['lt'][1]
        elif ('gt' in recordContext['settings']['vlist'] and
                context['origValue'] > recordContext['settings']['vlist']['gt'][0]):
            delay = recordContext['settings']['vlist']['gt'][1]
        else:
            delay = recordContext['settings']['wait']

    elif 'tlist' in recordContext['settings']:
        now = int(time.time())
        if ('eq' in recordContext['settings']['tlist'] and
                now == recordContext['settings']['tlist']['eq']):
            delay = recordContext['settings']['tlist']['eq'][now]
        elif ('lt' in recordContext['settings']['tlist'] and
                now < recordContext['settings']['tlist']['lt'][0]):
            delay = recordContext['settings']['tlist']['lt'][1]
        elif ('gt' in recordContext['settings']['tlist'] and
                now > recordContext['settings']['tlist']['gt'][0]):
            delay = recordContext['settings']['tlist']['gt'][1]
        else:
            delay = recordContext['settings']['wait']
    else:
        delay = recordContext['settings']['wait']

    if recordContext['settings']['deviation']:
        delay += random.randrange(
            -recordContext['settings']['deviation'], recordContext['settings']['deviation']
        )

    if delay < 0:
        delay = 0
    elif delay > 99999:
        log.msg('delay: dropping response for %s' % oid)
        raise error.NoDataNotification()

    log.msg('delay: waiting %d milliseconds for %s' % (delay, oid))

    time.sleep(delay / 1000)  # ms

    if context['setFlag'] or 'value' not in recordContext['settings']:
        return oid, tag, context['origValue']
    else:
        return oid, tag, recordContext['settings']['value']
コード例 #22
0
ファイル: snmprec.py プロジェクト: woodyle/snmpsim
            sys.exit(-1)
    if privProtocols[v3PrivProto] == config.usmNoPrivProtocol:
        if v3PrivKey is not None:
            v3PrivProto = 'DES'
    else:
        if v3PrivKey is None:
            sys.stderr.write('ERROR: --v3-priv-key is missing\r\n%s\r\n' % helpMessage)
            sys.exit(-1)
else:
    v3ContextEngineId = None
    v3ContextName = ''

log.setLogger('snmprec', 'stderr')

if getBulkFlag and not snmpVersion:
    log.msg('WARNING: will be using GETNEXT with SNMPv1!')
    getBulkFlag = False

# Attempt to reopen std output stream in binary mode
if outputFile is sys.stderr:
    if sys.version_info[0] > 2:
        outputFile = outputFile.buffer
    elif sys.platform == "win32":
        import msvcrt
        msvcrt.setmode(outputFile.fileno(), os.O_BINARY)

# Load variation module

if variationModuleName:
    for variationModulesDir in confdir.variation:
        log.msg('Scanning "%s" directory for variation modules...' % variationModulesDir)
コード例 #23
0
ファイル: snmprec.py プロジェクト: woodyle/snmpsim
def cbFun(snmpEngine, sendRequestHandle, errorIndication,
          errorStatus, errorIndex, varBindTable, cbCtx):
    if errorIndication and not cbCtx['retries']:
        cbCtx['errors'] += 1
        log.msg('SNMP Engine error: %s' % errorIndication)
        return
    # SNMPv1 response may contain noSuchName error *and* SNMPv2c exception,
    # so we ignore noSuchName error here
    if errorStatus and errorStatus != 2 or errorIndication:
        log.msg('Remote SNMP error %s' % (errorIndication or errorStatus.prettyPrint()))
        if cbCtx['retries']:
            try:
                nextOID = varBindTable[-1][0][0]
            except IndexError:
                nextOID = cbCtx['lastOID']
            else:
                log.msg('Failed OID: %s' % nextOID)
            # fuzzy logic of walking a broken OID
            if len(nextOID) < 4:
                pass
            elif (continueOnErrors-cbCtx['retries'])*10/continueOnErrors > 5:
                nextOID = nextOID[:-2] + (nextOID[-2]+1,)
            elif nextOID[-1]:
                nextOID = nextOID[:-1] + (nextOID[-1]+1,)
            else:
                nextOID = nextOID[:-2] + (nextOID[-2]+1, 0)

            cbCtx['retries'] -= 1
            cbCtx['lastOID'] = nextOID

            log.msg('Retrying with OID %s (%s retries left)...' % (nextOID, cbCtx['retries']))
            
            # initiate another SNMP walk iteration
            if getBulkFlag:
                cmdGen.sendVarBinds(
                    snmpEngine, 
                    'tgt', 
                    v3ContextEngineId, v3Context,
                    0, getBulkRepetitions,
                    [ (nextOID, None) ], 
                    cbFun, cbCtx
                )
            else:
                cmdGen.sendVarBinds(
                    snmpEngine,
                   'tgt',
                    v3ContextEngineId, v3Context,
                    [ (nextOID, None) ],
                    cbFun, cbCtx
                )

        cbCtx['errors'] += 1

        return

    if continueOnErrors != cbCtx['retries']:
        cbCtx['retries'] += 1

    if varBindTable and varBindTable[-1] and varBindTable[-1][0]:
        cbCtx['lastOID'] = varBindTable[-1][0][0]

    stopFlag = False

    # Walk var-binds
    for varBindRow in varBindTable:
        for oid, val in varBindRow:
            # EOM
            if stopOID and oid >= stopOID:
                stopFlag = True # stop on out of range condition
            elif val is None or \
                val.tagSet in (rfc1905.NoSuchObject.tagSet,
                               rfc1905.NoSuchInstance.tagSet,
                               rfc1905.EndOfMibView.tagSet):
                stopFlag = True

            # Build .snmprec record

            context = {
                'origOid': oid,
                'origValue': val,
                'count': cbCtx['count'],
                'total': cbCtx['total'],
                'iteration': cbCtx['iteration'],
                'reqTime': cbCtx['reqTime'],
                'startOID': startOID,
                'stopOID': stopOID,
                'stopFlag': stopFlag,
                'variationModule': variationModule
            }

            try:
                line = dataFileHandler.format(oid, val, **context)
            except error.MoreDataNotification:
                cbCtx['count'] = 0
                cbCtx['iteration'] += 1

                moreDataNotification = sys.exc_info()[1]
                if 'period' in moreDataNotification:
                    log.msg('%s OIDs dumped, waiting %.2f sec(s)...' % (cbCtx['total'], moreDataNotification['period']))
                    time.sleep(moreDataNotification['period'])
 
                # initiate another SNMP walk iteration
                if getBulkFlag:
                    cmdGen.sendVarBinds(
                        snmpEngine, 
                        'tgt', 
                        v3ContextEngineId, v3Context,
                        0, getBulkRepetitions,
                        [ (startOID, None) ], 
                        cbFun, cbCtx
                    )
                else:
                    cmdGen.sendVarBinds(
                        snmpEngine,
                        'tgt',
                        v3ContextEngineId, v3Context,
                        [ (startOID, None) ],
                        cbFun, cbCtx
                    )

                stopFlag = True  # stop current iteration
 
            except error.NoDataNotification:
                pass
            except error.SnmpsimError:
                log.msg('ERROR: %s' % (sys.exc_info()[1],))
                continue
            else:
                outputFile.write(line)

                cbCtx['count'] += 1
                cbCtx['total'] += 1

                if cbCtx['count'] % 100 == 0:
                    log.msg('OIDs dumped: %s/%s' % (cbCtx['iteration'], cbCtx['count']))

    # Next request time
    cbCtx['reqTime'] = time.time()

    # Continue walking
    return not stopFlag
コード例 #24
0
ファイル: error.py プロジェクト: jiuzhuaxiong/snmpsim
def variate(oid, tag, value, **context):
    if not context['nextFlag'] and not context['exactMatch']:
        return context['origOid'], tag, context['errorStatus']

    if 'settings' not in recordContext:
        recordContext['settings'] = dict(
            [split(x, '=') for x in split(value, ',')])

        if 'hexvalue' in recordContext['settings']:
            recordContext['settings']['value'] = [
                int(recordContext['settings']['hexvalue'][x:x + 2],
                    16) for x in range(
                        0, len(recordContext['settings']['hexvalue']), 2)
            ]

        if 'status' in recordContext['settings']:
            recordContext['settings']['status'] = recordContext['settings'][
                'status'].lower()

        if 'op' not in recordContext['settings']:
            recordContext['settings']['op'] = 'any'

        if 'vlist' in recordContext['settings']:
            vlist = {}
            recordContext['settings']['vlist'] = split(
                recordContext['settings']['vlist'], ':')
            while recordContext['settings']['vlist']:
                o, v, e = recordContext['settings']['vlist'][:3]
                recordContext['settings']['vlist'] = recordContext['settings'][
                    'vlist'][3:]
                typeTag, _ = SnmprecRecord.unpackTag(tag)
                v = SnmprecGrammar.tagMap[typeTag](v)
                if o not in vlist:
                    vlist[o] = {}
                if o == 'eq':
                    vlist[o][v] = e
                elif o in ('lt', 'gt'):
                    vlist[o] = v, e
                else:
                    log.msg('error: bad vlist syntax: %s' %
                            recordContext['settings']['vlist'])
            recordContext['settings']['vlist'] = vlist

    e = None

    if context['setFlag']:
        if 'vlist' in recordContext['settings']:
            if ('eq' in recordContext['settings']['vlist']
                    and context['origValue']
                    in recordContext['settings']['vlist']['eq']):
                e = recordContext['settings']['vlist']['eq'][
                    context['origValue']]
            elif ('lt' in recordContext['settings']['vlist']
                  and context['origValue'] <
                  recordContext['settings']['vlist']['lt'][0]):
                e = recordContext['settings']['vlist']['lt'][1]
            elif ('gt' in recordContext['settings']['vlist']
                  and context['origValue'] >
                  recordContext['settings']['vlist']['gt'][0]):
                e = recordContext['settings']['vlist']['gt'][1]
        elif recordContext['settings']['op'] in ('set', 'any'):
            if 'status' in recordContext['settings']:
                e = recordContext['settings']['status']
    else:
        if recordContext['settings']['op'] in ('get', 'any'):
            if 'status' in recordContext['settings']:
                e = recordContext['settings']['status']

    if e and e in errorTypes:
        log.msg('error: reporting %s for %s' % (e, oid))
        raise errorTypes[e](
            name=oid,
            idx=max(0, context['varsTotal'] - context['varsRemaining'] - 1))

    if context['setFlag']:
        recordContext['settings']['value'] = context['origValue']

    return oid, tag, recordContext['settings'].get('value',
                                                   context['errorStatus'])
コード例 #25
0
ファイル: sql.py プロジェクト: zharkon2/bas_repo
def variate(oid, tag, value, **context):
    if 'dbConn' in moduleContext:
        dbConn = moduleContext['dbConn']
    else:
        raise error.SnmpsimError('variation module not initialized')

    cursor = dbConn.cursor()

    try:
        cursor.execute(
            'set session transaction isolation level %s' % isolationLevels[moduleContext['isolationLevel']]
        )
        cursor.fetchall()
    except:  # non-MySQL/Postgres
        pass

    if value:
        dbTable = value.split(',').pop(0)
    elif 'dbTable' in moduleContext:
        dbTable = moduleContext['dbTable']
    else:
        log.msg('SQL table not specified for OID %s' % (context['origOid'],))
        return context['origOid'], tag, context['errorStatus']

    origOid = context['origOid']
    sqlOid = '.'.join(['%10s' % x for x in str(origOid).split('.')])

    if context['setFlag']:
        if 'hexvalue' in context:
            textTag = context['hextag']
            textValue = context['hexvalue']
        else:
            textTag = SnmprecGrammar().getTagByType(context['origValue'])
            textValue = str(context['origValue'])
        cursor.execute(
            'select maxaccess,tag from %s where oid=\'%s\' limit 1' % (dbTable, sqlOid)
        )
        resultset = cursor.fetchone()
        if resultset:
            maxaccess = resultset[0]
            if maxaccess != 'read-write':
                return origOid, tag, context['errorStatus']
            cursor.execute(
                'update %s set tag=\'%s\',value=\'%s\' where oid=\'%s\'' % (dbTable, textTag, textValue, sqlOid)
            )
        else:
            cursor.execute(
                'insert into %s values (\'%s\', \'%s\', \'%s\', \'read-write\')' % (dbTable, sqlOid, textTag, textValue)
            )
        if context['varsRemaining'] == 0:  # last OID in PDU
            dbConn.commit()
        cursor.close()
        return origOid, textTag, context['origValue']
    else:
        if context['nextFlag']:
            cursor.execute('select oid from %s where oid>\'%s\' order by oid limit 1' % (dbTable, sqlOid))
            resultset = cursor.fetchone()
            if resultset:
                origOid = origOid.clone(
                    '.'.join([x.strip() for x in str(resultset[0]).split('.')])
                )
                sqlOid = '.'.join(['%10s' % x for x in str(origOid).split('.')])
            else:
                cursor.close()
                return origOid, tag, context['errorStatus']

        cursor.execute('select tag, value from %s where oid=\'%s\' limit 1' % (dbTable, sqlOid))
        resultset = cursor.fetchone()
        cursor.close()

        if resultset:
            return origOid, str(resultset[0]), str(resultset[1])
        else:
            return origOid, tag, context['errorStatus']
コード例 #26
0
def record(oid, tag, value, **context):
    if 'started' not in moduleContext:
        moduleContext['started'] = time.time()

    if 'iterations' not in moduleContext:
        moduleContext['iterations'] = min(
            1, moduleContext['settings'].get('iterations', 0))

    # single-run recording

    if 'iterations' not in moduleContext[
            'settings'] or not moduleContext['settings']['iterations']:
        if context['origValue'].tagSet not in (rfc1902.Counter32.tagSet,
                                               rfc1902.Counter64.tagSet,
                                               rfc1902.TimeTicks.tagSet,
                                               rfc1902.Gauge32.tagSet,
                                               rfc1902.Integer.tagSet):
            if 'hextag' in context:
                tag = context['hextag']
            if 'hexvalue' in context:
                value = context['hexvalue']
            return oid, tag, value

        if 'taglist' not in moduleContext['settings'] or \
                        tag not in moduleContext['settings']['taglist']:
            return oid, tag, value

        value = 'initial=%s' % value

        if context['origValue'].tagSet == rfc1902.TimeTicks.tagSet:
            value += ',rate=100'
        elif context['origValue'].tagSet == rfc1902.Integer.tagSet:
            value += ',rate=0'

        return oid, tag + ':numeric', value

    # multiple-iteration recording

    if oid not in moduleContext:
        settings = {'initial': value}
        if context['origValue'].tagSet == rfc1902.TimeTicks.tagSet:
            settings['rate'] = 100
        elif context['origValue'].tagSet == rfc1902.Integer.tagSet:
            settings['rate'] = 0  # may be constants
        if 'addon' in moduleContext['settings']:
            settings.update(
                dict([
                    split(x, '=') for x in moduleContext['settings']['addon']
                ]))

        moduleContext[oid] = {}

        moduleContext[oid]['settings'] = settings

    if moduleContext['iterations']:
        if context['stopFlag']:  # switching to final iteration
            log.msg('numeric: %s iterations remaining' %
                    moduleContext['settings']['iterations'])
            moduleContext['iterations'] -= 1
            moduleContext['started'] = time.time()
            wait = max(
                0,
                float(moduleContext['settings']['period']) -
                (time.time() - moduleContext['started']))
            raise error.MoreDataNotification(period=wait)
        else:  # storing values on first iteration
            moduleContext[oid]['time'] = time.time()
            moduleContext[oid]['value'] = context['origValue']
            if 'hexvalue' in moduleContext[oid]:
                moduleContext[oid]['hexvalue'] = context['hexvalue']
            if 'hextag' in moduleContext[oid]:
                moduleContext[oid]['hextag'] = context['hextag']
            raise error.NoDataNotification()
    else:
        if context['stopFlag']:
            raise error.NoDataNotification()

        if 'value' in moduleContext[oid]:
            if context['origValue'].tagSet not in (rfc1902.Counter32.tagSet,
                                                   rfc1902.Counter64.tagSet,
                                                   rfc1902.TimeTicks.tagSet,
                                                   rfc1902.Gauge32.tagSet,
                                                   rfc1902.Integer.tagSet):
                if 'hextag' in moduleContext[oid]:
                    tag = moduleContext[oid]['hextag']
                if 'hexvalue' in moduleContext[oid]:
                    value = moduleContext[oid]['hexvalue']
                return oid, tag, value

            if tag not in moduleContext['settings']['taglist']:
                return oid, tag, moduleContext[oid]['value']

            moduleContext[oid]['settings']['rate'] = (int(
                context['origValue']) - int(moduleContext[oid]['value'])) / (
                    time.time() - moduleContext[oid]['time'])

            tag += ':numeric'
            value = ','.join([
                '%s=%s' % (k, v)
                for k, v in moduleContext[oid]['settings'].items()
            ])
            return oid, tag, value
        else:
            raise error.NoDataNotification()
コード例 #27
0
ファイル: sql.py プロジェクト: InfraSIM/vpduserv
def variate(oid, tag, value, **context):
    if 'dbConn' in moduleContext:
        dbConn = moduleContext['dbConn']
    else:
        raise error.SnmpsimError('variation module not initialized')

    cursor = dbConn.cursor()

    try:
        cursor.execute(
            'set session transaction isolation level %s' % moduleContext['isolationLevel']
        )
        cursor.fetchall()
    except:  # non-MySQL/Postgres
        pass

    if value:
        dbTable = value.split(',').pop(0)
    elif 'dbTable' in moduleContext:
        dbTable = moduleContext['dbTable']
    else:
        log.msg('SQL table not specified for OID %s' % (context['origOid'],))
        return context['origOid'], tag, context['errorStatus']

    origOid = context['origOid']
    sqlOid = '.'.join(['%10s' % x for x in str(origOid).split('.')])
    if context['setFlag']:
        if 'hexvalue' in context:
            textTag = context['hextag']
            textValue = context['hexvalue']
        else:
            textTag = SnmprecGrammar().getTagByType(context['origValue'])
            textValue = str(context['origValue'])
        cursor.execute(
            'select maxaccess,tag,value from %s where oid=\'%s\' limit 1' % (dbTable, sqlOid)
        )
        resultset = cursor.fetchone()
        if resultset:
            maxaccess = resultset[0]
            if maxaccess != 'read-write':
                return origOid, tag, context['errorStatus']

            value_written = textValue
            try:
                value_settings = {}
                value_settings = dict([split(x, '=') for x in split(resultset[2], ',')])
                print value_settings
                # if detected error mode, raise an error
                if 'mode' in value_settings and \
                        value_settings['mode'] == 'error':
                    raise Error.WrongValueError(name=origOid,
                                                idx=max(0,
                                                        context['varsTotal'] - context['varsRemaining'] - 1))
                elif 'mode' in value_settings and \
                    value_settings['mode'] == 'normal':
                    value_written = "mode=" + value_settings['mode'] + \
                        ",value=" + textValue
                else:
                    return origOid, tag, context['errorStatus']
            except Error.WrongValueError:
                cursor.close()
                raise Error.WrongValueError(name=origOid,
                                           idx=max(0, context['varsTotal'] - context['varsRemaining'] - 1))
            except:
                pass

            cursor.execute(
                'update %s set tag=\'%s\',value=\'%s\' where oid=\'%s\'' %
                (dbTable, textTag, value_written, sqlOid)
            )

            inform = moduleContext.get('inform')
            try:
                value = str(origOid) + " " + textValue
                written_len = os.write(inform, value)
                if written_len != len(value):
                    log.msg("--->Infrasim: Expected length %d, actual length %d\n" % (len(str(origOid)), written_len))
                    cursor.close()
                    return origOid, tag, context['errorStatus']
            except Exception, ex:
                log.msg("--->Infrasim: {0}".format(ex))
                cursor.close()
                return origOid, tag, context['errorStatus']

        else:
            cursor.close()
            raise Error.NoSuchInstanceError(name=origOid,
                   idx=max(0, context['varsTotal'] - context['varsRemaining'] - 1))

        if context['varsRemaining'] == 0:  # last OID in PDU
            dbConn.commit()
        cursor.close()
        return origOid, textTag, context['origValue']
コード例 #28
0
def variate(oid, tag, value, **context):
    if 'snmpEngine' in context and context['snmpEngine']:
        snmpEngine = context['snmpEngine']
        if snmpEngine not in moduleContext:
            moduleContext[snmpEngine] = {}
        if context['transportDomain'] not in moduleContext[snmpEngine]:
            # register this SNMP Engine to handle our transports'
            # receiver IDs (which we build by outbound and simulator
            # transportDomains concatenation)
            snmpEngine.registerTransportDispatcher(
                snmpEngine.transportDispatcher,
                UdpTransportTarget.transportDomain + \
                context['transportDomain']
            )
            snmpEngine.registerTransportDispatcher(
                snmpEngine.transportDispatcher,
                Udp6TransportTarget.transportDomain + \
                context['transportDomain']
            )
            moduleContext[snmpEngine][context['transportDomain']] = 1
    else:
        raise error.SnmpsimError('variation module not given snmpEngine')

    if not context['nextFlag'] and not context['exactMatch']:
        return context['origOid'], tag, context['errorStatus']

    if 'settings' not in recordContext:
        recordContext['settings'] = dict([split(x, '=') for x in split(value, ',')])
        for k, v in (('op', 'set'),
                     ('community', 'public'),
                     ('authkey', None),
                     ('authproto', 'md5'),
                     ('privkey', None),
                     ('privproto', 'des'),
                     ('proto', 'udp'),
                     ('port', '162'),
                     ('ntftype', 'trap'),
                     ('trapoid', '1.3.6.1.6.3.1.1.5.1')):
            recordContext['settings'].setdefault(k, v)

        if 'hexvalue' in recordContext['settings']:
            recordContext['settings']['value'] = [int(recordContext['settings']['hexvalue'][x:x + 2], 16) for x in
                                                  range(0, len(recordContext['settings']['hexvalue']), 2)]

        if 'vlist' in recordContext['settings']:
            vlist = {}
            recordContext['settings']['vlist'] = split(recordContext['settings']['vlist'], ':')
            while recordContext['settings']['vlist']:
                o, v = recordContext['settings']['vlist'][:2]
                recordContext['settings']['vlist'] = recordContext['settings']['vlist'][2:]
                v = SnmprecGrammar.tagMap[tag](v)
                if o not in vlist:
                    vlist[o] = set()
                if o == 'eq':
                    vlist[o].add(v)
                elif o in ('lt', 'gt'):
                    vlist[o] = v
                else:
                    log.msg('notification: bad vlist syntax: %s' % recordContext['settings']['vlist'])
            recordContext['settings']['vlist'] = vlist

    args = recordContext['settings']

    if context['setFlag'] and 'vlist' in args:
        if 'eq' in args['vlist'] and \
                        context['origValue'] in args['vlist']['eq']:
            pass
        elif 'lt' in args['vlist'] and \
                        context['origValue'] < args['vlist']['lt']:
            pass
        elif 'gt' in args['vlist'] and \
                        context['origValue'] > args['vlist']['gt']:
            pass
        else:
            return oid, tag, context['origValue']

    if args['op'] not in ('get', 'set', 'any', '*'):
        log.msg('notification: unknown SNMP request type configured: %s' % args['op'])
        return context['origOid'], tag, context['errorStatus']

    if args['op'] == 'get' and not context['setFlag'] or \
                            args['op'] == 'set' and context['setFlag'] or \
                    args['op'] in ('any', '*'):
        if args['version'] in ('1', '2c'):
            authData = CommunityData(args['community'], mpModel=args['version'] == '2c' and 1 or 0)
        elif args['version'] == '3':
            if args['authproto'] == 'md5':
                authProtocol = usmHMACMD5AuthProtocol
            elif args['authproto'] == 'sha':
                authProtocol = usmHMACSHAAuthProtocol
            elif args['authproto'] == 'none':
                authProtocol = usmNoAuthProtocol
            else:
                log.msg('notification: unknown auth proto %s' % args['authproto'])
                return context['origOid'], tag, context['errorStatus']
            if args['privproto'] == 'des':
                privProtocol = usmDESPrivProtocol
            elif args['privproto'] == 'aes':
                privProtocol = usmAesCfb128Protocol
            elif args['privproto'] == 'none':
                privProtocol = usmNoPrivProtocol
            else:
                log.msg('notification: unknown privacy proto %s' % args['privproto'])
                return context['origOid'], tag, context['errorStatus']
            authData = UsmUserData(args['user'], args['authkey'], args['privkey'], authProtocol=authProtocol,
                                   privProtocol=privProtocol)
        else:
            log.msg('notification: unknown SNMP version %s' % args['version'])
            return context['origOid'], tag, context['errorStatus']

        if 'host' not in args:
            log.msg('notification: target hostname not configured for OID %s' % (oid,))
            return context['origOid'], tag, context['errorStatus']

        if args['proto'] == 'udp':
            target = UdpTransportTarget((args['host'], int(args['port'])))
        elif args['proto'] == 'udp6':
            target = Udp6TransportTarget((args['host'], int(args['port'])))
        else:
            log.msg('notification: unknown transport %s' % args['proto'])
            return context['origOid'], tag, context['errorStatus']

        localAddress = None

        if 'bindaddr' in args:
            localAddress = args['bindaddr']
        else:
            if context['transportDomain'][:len(target.transportDomain)] == \
                    target.transportDomain:
                localAddress = \
                snmpEngine.transportDispatcher.getTransport(context['transportDomain']).getLocalAddress()[0]
            else:
                log.msg(
                    'notification: incompatible network transport types used by CommandResponder vs NotificationOriginator')
                if 'bindaddr' in args:
                    localAddress = args['bindaddr']

        if localAddress:
            log.msg('notification: binding to local address %s' % localAddress)
            target.setLocalAddress((localAddress, 0))

        # this will make target objects different based on their bind address 
        target.transportDomain = target.transportDomain + \
                                 context['transportDomain']

        varBinds = []

        if 'uptime' in args:
            varBinds.append(
                (ObjectIdentifier('1.3.6.1.2.1.1.3.0'),
                 TimeTicks(args['uptime']))
            )

        if args['version'] == '1':
            if 'agentaddress' in args:
                varBinds.append(
                    (ObjectIdentifier('1.3.6.1.6.3.18.1.3.0'),
                     IpAddress(args['agentaddress']))
                )
            if 'enterprise' in args:
                varBinds.append(
                    (ObjectIdentifier('1.3.6.1.6.3.1.1.4.3.0'),
                     ObjectIdentifier(args['enterprise']))
                )

        if 'varbinds' in args:
            vbs = split(args['varbinds'], ':')
            while vbs:
                varBinds.append(
                    (ObjectIdentifier(vbs[0]), typeMap[vbs[1]](vbs[2]))
                )
                vbs = vbs[3:]

        sendNotification(
            snmpEngine, authData, target, ContextData(), args['ntftype'],
            NotificationType(ObjectIdentity(args['trapoid'])).addVarBinds(*varBinds),
            cbFun=_cbFun, cbCtx=(oid, value)
        )

        log.msg('notification: sending Notification to %s with credentials %s' % (authData, target))

    if context['setFlag'] or 'value' not in args:
        return oid, tag, context['origValue']
    else:
        return oid, tag, args['value']
コード例 #29
0
ファイル: numeric.py プロジェクト: etingof/snmpsim
def record(oid, tag, value, **context):
    if 'started' not in moduleContext:
        moduleContext['started'] = time.time()

    if 'iterations' not in moduleContext:
        moduleContext['iterations'] = min(
            1, moduleContext['settings'].get('iterations', 0))

    # single-run recording

    iterations = moduleContext['settings'].get('iterations')
    if not iterations:
        if context['origValue'].tagSet not in INTEGER_TYPES:
            if 'hextag' in context:
                tag = context['hextag']

            if 'hexvalue' in context:
                value = context['hexvalue']

            return oid, tag, value

        if ('taglist' not in moduleContext['settings'] or
                tag not in moduleContext['settings']['taglist']):
            return oid, tag, value

        value = 'initial=%s' % value

        if context['origValue'].tagSet == rfc1902.TimeTicks.tagSet:
            value += ',rate=100'

        elif context['origValue'].tagSet == rfc1902.Integer.tagSet:
            value += ',rate=0'

        return oid, tag + ':numeric', value

    # multiple-iteration recording

    if oid not in moduleContext:
        settings = {
            'initial': value
        }

        if context['origValue'].tagSet == rfc1902.TimeTicks.tagSet:
            settings['rate'] = 100

        elif context['origValue'].tagSet == rfc1902.Integer.tagSet:
            settings['rate'] = 0  # may be constants

        if 'addon' in moduleContext['settings']:
            settings.update(
                dict([split(x, '=')
                      for x in moduleContext['settings']['addon']]))

        moduleContext[oid] = {}

        moduleContext[oid]['settings'] = settings

    if moduleContext['iterations']:
        if context['stopFlag']:  # switching to final iteration
            log.msg('numeric: %s iterations '
                    'remaining' % moduleContext['iterations'])

            moduleContext['iterations'] -= 1
            moduleContext['started'] = time.time()

            running = time.time() - moduleContext['started']
            wait = max(0, float(moduleContext['settings']['period']) - running)

            raise error.MoreDataNotification(period=wait)

        else:  # storing values on first iteration
            moduleContext[oid]['time'] = time.time()
            moduleContext[oid]['value'] = context['origValue']

            if 'hexvalue' in moduleContext[oid]:
                moduleContext[oid]['hexvalue'] = context['hexvalue']

            if 'hextag' in moduleContext[oid]:
                moduleContext[oid]['hextag'] = context['hextag']

            raise error.NoDataNotification()
    else:
        if context['stopFlag']:
            raise error.NoDataNotification()

        if 'value' in moduleContext[oid]:
            if context['origValue'].tagSet not in INTEGER_TYPES:
                if 'hextag' in moduleContext[oid]:
                    tag = moduleContext[oid]['hextag']

                if 'hexvalue' in moduleContext[oid]:
                    value = moduleContext[oid]['hexvalue']

                return oid, tag, value

            if tag not in moduleContext['settings']['taglist']:
                return oid, tag, moduleContext[oid]['value']

            diff = int(context['origValue']) - int(moduleContext[oid]['value'])
            runtime = time.time() - moduleContext[oid]['time']
            moduleContext[oid]['settings']['rate'] = diff / runtime

            tag += ':numeric'
            value = ','.join(
                ['%s=%s' % (k, v)
                 for k, v in moduleContext[oid]['settings'].items()])

            return oid, tag, value

        else:
            raise error.NoDataNotification()
コード例 #30
0
ファイル: writecache.py プロジェクト: timlegge/snmpsim
def variate(oid, tag, value, **context):
    if not context['nextFlag'] and not context['exactMatch']:
        return context['origOid'], tag, context['errorStatus']

    if 'settings' not in recordContext:
        recordContext['settings'] = dict(
            [split(x, '=') for x in split(value, ',')])

        if 'vlist' in recordContext['settings']:

            vlist = {}

            recordContext['settings']['vlist'] = split(
                recordContext['settings']['vlist'], ':')

            while recordContext['settings']['vlist']:
                o, v, e = recordContext['settings']['vlist'][:3]

                vl = recordContext['settings']['vlist'][3:]
                recordContext['settings']['vlist'] = vl

                typeTag, _ = SnmprecRecord.unpackTag(tag)

                v = SnmprecGrammar.TAG_MAP[typeTag](v)

                if o not in vlist:
                    vlist[o] = {}

                if o == 'eq':
                    vlist[o][v] = e

                elif o in ('lt', 'gt'):
                    vlist[o] = v, e

                else:
                    log.msg('writecache: bad vlist syntax: '
                            '%s' % recordContext['settings']['vlist'])

            recordContext['settings']['vlist'] = vlist

        if 'status' in recordContext['settings']:
            st = recordContext['settings']['status'].lower()
            recordContext['settings']['status'] = st

    if oid not in moduleContext:
        moduleContext[oid] = {}

        typeTag, _ = SnmprecRecord.unpackTag(tag)

        moduleContext[oid]['type'] = SnmprecGrammar.TAG_MAP[typeTag]()

    textOid = str(oid)

    if context['setFlag']:
        if 'vlist' in recordContext['settings']:
            if ('eq' in recordContext['settings']['vlist']
                    and context['origValue']
                    in recordContext['settings']['vlist']['eq']):
                e = recordContext['settings']['vlist']['eq'][
                    context['origValue']]

            elif ('lt' in recordContext['settings']['vlist']
                  and context['origValue'] <
                  recordContext['settings']['vlist']['lt'][0]):
                e = recordContext['settings']['vlist']['lt'][1]

            elif ('gt' in recordContext['settings']['vlist']
                  and context['origValue'] >
                  recordContext['settings']['vlist']['gt'][0]):
                e = recordContext['settings']['vlist']['gt'][1]

            else:
                e = None

            if e in ERROR_TYPES:
                idx = max(0,
                          context['varsTotal'] - context['varsRemaining'] - 1)
                raise ERROR_TYPES[e](name=oid, idx=idx)

        if moduleContext[oid]['type'].isSameTypeWith(context['origValue']):
            moduleContext['cache'][textOid] = context['origValue']

        else:
            return context['origOid'], tag, context['errorStatus']

    if 'status' in recordContext['settings']:

        if ('op' not in recordContext['settings']
                or recordContext['settings']['op'] == 'any' or
                recordContext['settings']['op'] == 'set' and context['setFlag']
                or recordContext['settings']['op'] == 'get'
                and not context['setFlag']):

            e = recordContext['settings']['status']

            if e in ERROR_TYPES:
                idx = max(0,
                          context['varsTotal'] - context['varsRemaining'] - 1)
                raise ERROR_TYPES[e](name=oid, idx=idx)

    if textOid in moduleContext['cache']:
        return oid, tag, moduleContext['cache'][textOid]

    elif 'hexvalue' in recordContext['settings']:
        return oid, tag, moduleContext[oid]['type'].clone(
            hexValue=recordContext['settings']['hexvalue'])

    elif 'value' in recordContext['settings']:
        return oid, tag, moduleContext[oid]['type'].clone(
            recordContext['settings']['value'])

    else:
        return oid, tag, context['errorStatus']
コード例 #31
0
ファイル: pcap2dev.py プロジェクト: woodyle/snmpsim
    mibViewController = view.MibViewController(mibBuilder)

    compiler.addMibCompiler(
        mibBuilder, sources=mibSources or defaultMibSources
    )
    if isinstance(startOID, rfc1902.ObjectIdentity):
        startOID.resolveWithMib(mibViewController)
    if isinstance(stopOID, rfc1902.ObjectIdentity):
        stopOID.resolveWithMib(mibViewController)

# Load variation module

if variationModuleName:
    for variationModulesDir in confdir.variation:
        log.msg('Scanning "%s" directory for variation modules...' % variationModulesDir)
        if not os.path.exists(variationModulesDir):
            log.msg('Directory "%s" does not exist' % variationModulesDir)
            continue

        mod = os.path.join(variationModulesDir, variationModuleName + '.py')
        if not os.path.exists(mod):
            log.msg('Variation module "%s" not found' % mod)
            continue

        ctx = { 'path': mod, 'moduleContext': {} }

        try:
            if sys.version_info[0] > 2:
                exec(compile(open(mod).read(), mod, 'exec'), ctx)
            else:
コード例 #32
0
ファイル: sql.py プロジェクト: woodyle/snmpsim
def variate(oid, tag, value, **context):
    if 'dbConn' in moduleContext:
        dbConn = moduleContext['dbConn']
    else:
        raise error.SnmpsimError('variation module not initialized')

    cursor = dbConn.cursor()

    try:
        cursor.execute(
            'set session transaction isolation level %s' % moduleContext['isolationLevel']
        )
        cursor.fetchall()
    except:  # non-MySQL/Postgres
        pass

    if value:
        dbTable = value.split(',').pop(0)
    elif 'dbTable' in moduleContext:
        dbTable = moduleContext['dbTable']
    else:
        log.msg('SQL table not specified for OID %s' % (context['origOid'],))
        return context['origOid'], tag, context['errorStatus']

    origOid = context['origOid']
    sqlOid = '.'.join(['%10s' % x for x in str(origOid).split('.')])

    if context['setFlag']:
        if 'hexvalue' in context:
            textTag = context['hextag']
            textValue = context['hexvalue']
        else:
            textTag = SnmprecGrammar().getTagByType(context['origValue'])
            textValue = str(context['origValue'])
        cursor.execute(
            'select maxaccess,tag from %s where oid=\'%s\' limit 1' % (dbTable, sqlOid)
        )
        resultset = cursor.fetchone()
        if resultset:
            maxaccess = resultset[0]
            if maxaccess != 'read-write':
                return origOid, tag, context['errorStatus']
            cursor.execute(
                'update %s set tag=\'%s\',value=\'%s\' where oid=\'%s\'' % (dbTable, textTag, textValue, sqlOid)
            )
        else:
            cursor.execute(
                'insert into %s values (\'%s\', \'%s\', \'%s\', \'read-write\')' % (dbTable, sqlOid, textTag, textValue)
            )
        if context['varsRemaining'] == 0:  # last OID in PDU
            dbConn.commit()
        cursor.close()
        return origOid, textTag, context['origValue']
    else:
        if context['nextFlag']:
            cursor.execute('select oid from %s where oid>\'%s\' order by oid limit 1' % (dbTable, sqlOid))
            resultset = cursor.fetchone()
            if resultset:
                origOid = origOid.clone(
                  '.'.join([x.strip() for x in str(resultset[0]).split('.')])
                )
                sqlOid = '.'.join(['%10s' % x for x in str(origOid).split('.')])
            else:
                cursor.close()
                return origOid, tag, context['errorStatus']

        cursor.execute('select tag, value from %s where oid=\'%s\' limit 1' % (dbTable, sqlOid))
        resultset = cursor.fetchone()
        cursor.close()

        if resultset:
            return origOid, str(resultset[0]), str(resultset[1])
        else:
            return origOid, tag, context['errorStatus']
コード例 #33
0
ファイル: redis.py プロジェクト: etingof/snmpsim
def variate(oid, tag, value, **context):
    if 'dbConn' in moduleContext:
        dbConn = moduleContext['dbConn']

    else:
        raise error.SnmpsimError('variation module not initialized')

    if 'settings' not in recordContext:
        settings = recordContext['settings'] = dict(
            [split(x, '=') for x in split(value, ',')])

        if 'key-spaces-id' not in settings:
            log.msg('redis:mandatory key-spaces-id option is missing')
            return context['origOid'], tag, context['errorStatus']

        settings['period'] = float(settings.get('period', 60))

        if 'evalsha' in settings:
            if not dbConn.script_exists(settings['evalsha']):
                log.msg('redis: lua script %s does not exist '
                        'at Redis' % settings['evalsha'])
                return context['origOid'], tag, context['errorStatus']

        recordContext['ready'] = True

    if 'ready' not in recordContext:
        return context['origOid'], tag, context['errorStatus']

    redisScript = recordContext['settings'].get('evalsha')

    keySpacesId = recordContext['settings']['key-spaces-id']

    if recordContext['settings']['period']:
        booted = time.time() - moduleContext['booted']
        slot = int(dbConn.llen(keySpacesId)) // recordContext['settings']['period']
        keySpaceIdx = int(booted) % (recordContext['settings']['period'] * slot)

    else:
        keySpaceIdx = 0

    keySpace = dbConn.lindex(keySpacesId, keySpaceIdx)

    if ('current-keyspace' not in recordContext or
            recordContext['current-keyspace'] != keySpace):
        log.msg('redis: now using keyspace %s (cycling period'
                ' %s)' % (
            keySpace, recordCoentext['settings']['period'] or '<disabled>'))

        recordContext['current-keyspace'] = keySpace

    if keySpace is None:
        return origOid, tag, context['errorStatus']

    origOid = context['origOid']
    dbOid = '.'.join(['%10s' % x for x in str(origOid).split('.')])

    if context['setFlag']:
        if 'hexvalue' in context:
            textTag = context['hextag']
            textValue = context['hexvalue']

        else:
            textTag = SnmprecGrammar().getTagByType(context['origValue'])
            textValue = str(context['origValue'])

        if redisScript:
            prevTagAndValue = dbConn.evalsha(redisScript, 1, keySpace + '-' + dbOid)

        else:
            prevTagAndValue = dbConn.get(keySpace + '-' + dbOid)

        if prevTagAndValue:
            prevTag, prevValue = prevTagAndValue.split('|')

            if unpackTag(prevTag)[0] != unpackTag(textTag)[0]:
                idx = max(0, context['varsTotal'] - context['varsRemaining'] - 1)
                raise WrongValueError(name=origOid, idx=idx)

        else:
            dbConn.linsert(
                keySpace + '-oids_ordering', 'after',
                getNextOid(dbConn, keySpace, dbOid), dbOid)

        if redisScript:
            dbConn.evalsha(redisScript, 1, keySpace + '-' + dbOid,
                           textTag + '|' + textValue)

        else:
            dbConn.set(keySpace + '-' + dbOid, textTag + '|' + textValue)

        return origOid, textTag, context['origValue']

    else:
        if context['nextFlag']:
            textOid = dbConn.lindex(
                keySpace + '-oids_ordering',
                getNextOid(dbConn, keySpace, dbOid, index=True))

        else:
            textOid = keySpace + '-' + dbOid

        if redisScript:
            tagAndValue = dbConn.evalsha(redisScript, 1, textOid)

        else:
            tagAndValue = dbConn.get(textOid)

        if not tagAndValue:
            return origOid, tag, context['errorStatus']

        textOid = '.'.join(
            [x.strip() for x in textOid.split('-', 1)[1].split('.')])
        textTag, textValue = tagAndValue.split('|', 1)

        return textOid, textTag, textValue
コード例 #34
0
ファイル: redis.py プロジェクト: qnox81/snmpsim
def record(oid, tag, value, **context):
    if 'ready' not in moduleContext:
        raise error.SnmpsimError('module not initialized')

    if 'dbConn' in moduleContext:
        dbConn = moduleContext['dbConn']

    else:
        raise error.SnmpsimError('variation module not initialized')

    if 'started' not in moduleContext:
        moduleContext['started'] = time.time()

    redisScript = moduleContext.get('evalsha')

    keySpace = '%.10d' % (moduleContext['key-spaces-id'] +
                          moduleContext.get('iterations', 0))

    if context['stopFlag']:
        dbConn.sort(keySpace + '-' + 'temp_oids_ordering',
                    store=keySpace + '-' + 'oids_ordering',
                    alpha=True)

        dbConn.delete(keySpace + '-' + 'temp_oids_ordering')
        dbConn.rpush(moduleContext['key-spaces-id'], keySpace)

        log.msg('redis: done with key-space %s' % keySpace)

        if 'iterations' in moduleContext and moduleContext['iterations']:
            log.msg('redis: %s iterations remaining' %
                    moduleContext['iterations'])

            moduleContext['started'] = time.time()
            moduleContext['iterations'] -= 1

            runtime = time.time() - moduleContext['started']
            wait = max(0, moduleContext['period'] - runtime)

            raise error.MoreDataNotification(period=wait)

        else:
            raise error.NoDataNotification()

    dbOid = '.'.join(['%10s' % x for x in oid.split('.')])

    if 'hexvalue' in context:
        textTag = context['hextag']
        textValue = context['hexvalue']

    else:
        textTag = SnmprecGrammar().getTagByType(context['origValue'])
        textValue = str(context['origValue'])

    dbConn.lpush(keySpace + '-temp_oids_ordering', keySpace + '-' + dbOid)

    if redisScript:
        dbConn.evalsha(redisScript, 1, keySpace + '-' + dbOid,
                       textTag + '|' + textValue)

    else:
        dbConn.set(keySpace + '-' + dbOid, textTag + '|' + textValue)

    if not context['count']:
        settings = {'key-spaces-id': moduleContext['key-spaces-id']}

        if 'period' in moduleContext:
            settings['period'] = '%.2f' % float(moduleContext['period'])

        if 'addon' in moduleContext:
            settings.update(
                dict([split(x, '=') for x in moduleContext['addon']]))

        value = ','.join(['%s=%s' % (k, v) for k, v in settings.items()])

        return str(context['startOID']), ':redis', value

    else:
        raise error.NoDataNotification()
コード例 #35
0
ファイル: writecache.py プロジェクト: etingof/snmpsim
def variate(oid, tag, value, **context):
    if not context['nextFlag'] and not context['exactMatch']:
        return context['origOid'], tag, context['errorStatus']

    if 'settings' not in recordContext:
        recordContext['settings'] = dict([split(x, '=') for x in split(value, ',')])

        if 'vlist' in recordContext['settings']:

            vlist = {}

            recordContext['settings']['vlist'] = split(
                recordContext['settings']['vlist'], ':')

            while recordContext['settings']['vlist']:
                o, v, e = recordContext['settings']['vlist'][:3]

                vl = recordContext['settings']['vlist'][3:]
                recordContext['settings']['vlist'] = vl

                typeTag, _ = SnmprecRecord.unpackTag(tag)

                v = SnmprecGrammar.TAG_MAP[typeTag](v)

                if o not in vlist:
                    vlist[o] = {}

                if o == 'eq':
                    vlist[o][v] = e

                elif o in ('lt', 'gt'):
                    vlist[o] = v, e

                else:
                    log.msg('writecache: bad vlist syntax: '
                            '%s' % recordContext['settings']['vlist'])

            recordContext['settings']['vlist'] = vlist

        if 'status' in recordContext['settings']:
            st = recordContext['settings']['status'].lower()
            recordContext['settings']['status'] = st

    if oid not in moduleContext:
        moduleContext[oid] = {}

        typeTag, _ = SnmprecRecord.unpackTag(tag)

        moduleContext[oid]['type'] = SnmprecGrammar.TAG_MAP[typeTag]()

    textOid = str(oid)

    if context['setFlag']:
        if 'vlist' in recordContext['settings']:
            if ('eq' in recordContext['settings']['vlist'] and
                    context['origValue'] in recordContext['settings']['vlist']['eq']):
                e = recordContext['settings']['vlist']['eq'][context['origValue']]

            elif ('lt' in recordContext['settings']['vlist'] and
                    context['origValue'] < recordContext['settings']['vlist']['lt'][0]):
                e = recordContext['settings']['vlist']['lt'][1]

            elif ('gt' in recordContext['settings']['vlist'] and
                    context['origValue'] > recordContext['settings']['vlist']['gt'][0]):
                e = recordContext['settings']['vlist']['gt'][1]

            else:
                e = None

            if e in ERROR_TYPES:
                idx = max(0, context['varsTotal'] - context['varsRemaining'] - 1)
                raise ERROR_TYPES[e](name=oid, idx=idx)

        if moduleContext[oid]['type'].isSameTypeWith(context['origValue']):
            moduleContext['cache'][textOid] = context['origValue']

        else:
            return context['origOid'], tag, context['errorStatus']

    if 'status' in recordContext['settings']:

        if ('op' not in recordContext['settings'] or
                recordContext['settings']['op'] == 'any' or
                recordContext['settings']['op'] == 'set' and context['setFlag'] or
                recordContext['settings']['op'] == 'get' and not context['setFlag']):

            e = recordContext['settings']['status']

            if e in ERROR_TYPES:
                idx = max(0, context['varsTotal'] - context['varsRemaining'] - 1)
                raise ERROR_TYPES[e](name=oid, idx=idx)

    if textOid in moduleContext['cache']:
        return oid, tag, moduleContext['cache'][textOid]

    elif 'hexvalue' in recordContext['settings']:
        return oid, tag, moduleContext[oid]['type'].clone(
            hexValue=recordContext['settings']['hexvalue'])

    elif 'value' in recordContext['settings']:
        return oid, tag, moduleContext[oid]['type'].clone(
            recordContext['settings']['value'])

    else:
        return oid, tag, context['errorStatus']
コード例 #36
0
ファイル: redis.py プロジェクト: qnox81/snmpsim
def variate(oid, tag, value, **context):
    if 'dbConn' in moduleContext:
        dbConn = moduleContext['dbConn']

    else:
        raise error.SnmpsimError('variation module not initialized')

    if 'settings' not in recordContext:
        settings = recordContext['settings'] = dict(
            [split(x, '=') for x in split(value, ',')])

        if 'key-spaces-id' not in settings:
            log.msg('redis:mandatory key-spaces-id option is missing')
            return context['origOid'], tag, context['errorStatus']

        settings['period'] = float(settings.get('period', 60))

        if 'evalsha' in settings:
            if not dbConn.script_exists(settings['evalsha']):
                log.msg('redis: lua script %s does not exist '
                        'at Redis' % settings['evalsha'])
                return context['origOid'], tag, context['errorStatus']

        recordContext['ready'] = True

    if 'ready' not in recordContext:
        return context['origOid'], tag, context['errorStatus']

    redisScript = recordContext['settings'].get('evalsha')

    keySpacesId = recordContext['settings']['key-spaces-id']

    if recordContext['settings']['period']:
        booted = time.time() - moduleContext['booted']
        slot = int(
            dbConn.llen(keySpacesId)) // recordContext['settings']['period']
        keySpaceIdx = int(booted) % (recordContext['settings']['period'] *
                                     slot)

    else:
        keySpaceIdx = 0

    keySpace = dbConn.lindex(keySpacesId, keySpaceIdx)

    if ('current-keyspace' not in recordContext
            or recordContext['current-keyspace'] != keySpace):
        log.msg(
            'redis: now using keyspace %s (cycling period'
            ' %s)' %
            (keySpace, recordCoentext['settings']['period'] or '<disabled>'))

        recordContext['current-keyspace'] = keySpace

    if keySpace is None:
        return origOid, tag, context['errorStatus']

    origOid = context['origOid']
    dbOid = '.'.join(['%10s' % x for x in str(origOid).split('.')])

    if context['setFlag']:
        if 'hexvalue' in context:
            textTag = context['hextag']
            textValue = context['hexvalue']

        else:
            textTag = SnmprecGrammar().getTagByType(context['origValue'])
            textValue = str(context['origValue'])

        if redisScript:
            prevTagAndValue = dbConn.evalsha(redisScript, 1,
                                             keySpace + '-' + dbOid)

        else:
            prevTagAndValue = dbConn.get(keySpace + '-' + dbOid)

        if prevTagAndValue:
            prevTag, prevValue = prevTagAndValue.split('|')

            if unpackTag(prevTag)[0] != unpackTag(textTag)[0]:
                idx = max(0,
                          context['varsTotal'] - context['varsRemaining'] - 1)
                raise WrongValueError(name=origOid, idx=idx)

        else:
            dbConn.linsert(keySpace + '-oids_ordering', 'after',
                           getNextOid(dbConn, keySpace, dbOid), dbOid)

        if redisScript:
            dbConn.evalsha(redisScript, 1, keySpace + '-' + dbOid,
                           textTag + '|' + textValue)

        else:
            dbConn.set(keySpace + '-' + dbOid, textTag + '|' + textValue)

        return origOid, textTag, context['origValue']

    else:
        if context['nextFlag']:
            textOid = dbConn.lindex(
                keySpace + '-oids_ordering',
                getNextOid(dbConn, keySpace, dbOid, index=True))

        else:
            textOid = keySpace + '-' + dbOid

        if redisScript:
            tagAndValue = dbConn.evalsha(redisScript, 1, textOid)

        else:
            tagAndValue = dbConn.get(textOid)

        if not tagAndValue:
            return origOid, tag, context['errorStatus']

        textOid = '.'.join(
            [x.strip() for x in textOid.split('-', 1)[1].split('.')])
        textTag, textValue = tagAndValue.split('|', 1)

        return textOid, textTag, textValue
コード例 #37
0
ファイル: snmprec.py プロジェクト: ntwo1980/snmpsim
    if privProtocols[v3PrivProto] == config.usmNoPrivProtocol:
        if v3PrivKey is not None:
            v3PrivProto = 'DES'
    else:
        if v3PrivKey is None:
            sys.stderr.write('ERROR: --v3-priv-key is missing\r\n%s\r\n' %
                             helpMessage)
            sys.exit(-1)
else:
    v3ContextEngineId = None
    v3ContextName = ''

log.setLogger('snmprec', 'stderr')

if getBulkFlag and not snmpVersion:
    log.msg('WARNING: will be using GETNEXT with SNMPv1!')
    getBulkFlag = False

# Attempt to reopen std output stream in binary mode
if outputFile is sys.stderr:
    if sys.version_info[0] > 2:
        outputFile = outputFile.buffer
    elif sys.platform == "win32":
        import msvcrt

        msvcrt.setmode(outputFile.fileno(), os.O_BINARY)

# Load variation module

if variationModuleName:
    for variationModulesDir in confdir.variation:
コード例 #38
0
ファイル: multiplex.py プロジェクト: Kryndex/snmpsim
def variate(oid, tag, value, **context):
    if 'settings' not in recordContext:
        recordContext['settings'] = dict(
            [split(x, '=') for x in split(value, ',')])
        if 'dir' not in recordContext['settings']:
            log.msg('multiplex: snapshot directory not specified')
            return context['origOid'], tag, context['errorStatus']

        recordContext['settings']['dir'] = recordContext['settings'][
            'dir'].replace('/', os.path.sep)
        if recordContext['settings']['dir'][0] != os.path.sep:
            for x in confdir.data:
                d = os.path.join(x, recordContext['settings']['dir'])
                if os.path.exists(d):
                    break
            else:
                log.msg('multiplex: directory %s not found' %
                        recordContext['settings']['dir'])
                return context['origOid'], tag, context['errorStatus']
        else:
            d = recordContext['settings']['dir']
        recordContext['dirmap'] = dict([
            (int(os.path.basename(x).split(os.path.extsep)[0]),
             os.path.join(d, x)) for x in os.listdir(d) if x[-7:] == 'snmprec'
        ])
        recordContext['keys'] = list(recordContext['dirmap'].keys())
        recordContext['bounds'] = (min(recordContext['keys']),
                                   max(recordContext['keys']))
        if 'period' in recordContext['settings']:
            recordContext['settings']['period'] = float(
                recordContext['settings']['period'])
        else:
            recordContext['settings']['period'] = 60.0
        if 'wrap' in recordContext['settings']:
            recordContext['settings']['wrap'] = bool(
                recordContext['settings']['wrap'])
        else:
            recordContext['settings']['wrap'] = False
        if 'control' in recordContext['settings']:
            recordContext['settings']['control'] = rfc1902.ObjectName(
                recordContext['settings']['control'])
            log.msg(
                'multiplex: using control OID %s for subtree %s, time-based multiplexing disabled'
                % (recordContext['settings']['control'], oid))

        recordContext['ready'] = True

    if 'ready' not in recordContext:
        return context['origOid'], tag, context['errorStatus']

    if oid not in moduleContext:
        moduleContext[oid] = {}

    if context['setFlag']:
        if 'control' in recordContext['settings'] and \
                        recordContext['settings']['control'] == context['origOid']:
            fileno = int(context['origValue'])
            if fileno >= len(recordContext['keys']):
                log.msg('multiplex: .snmprec file number %s over limit of %s' %
                        (fileno, len(recordContext['keys'])))
                return context['origOid'], tag, context['errorStatus']
            moduleContext[oid]['fileno'] = fileno
            log.msg('multiplex: switched to file #%s (%s)' %
                    (recordContext['keys'][fileno],
                     recordContext['dirmap'][recordContext['keys'][fileno]]))
            return context['origOid'], tag, context['origValue']
        else:
            return context['origOid'], tag, context['errorStatus']

    if 'control' in recordContext['settings']:
        if 'fileno' not in moduleContext[oid]:
            moduleContext[oid]['fileno'] = 0
        if (not context['nextFlag'] and recordContext['settings']['control']
                == context['origOid']):
            return context['origOid'], tag, rfc1902.Integer32(
                moduleContext[oid]['fileno'])
    else:
        timeslot = (time.time() - moduleContext['booted']) % (
            recordContext['settings']['period'] * len(recordContext['dirmap']))
        fileslot = int(
            timeslot /
            recordContext['settings']['period']) + recordContext['bounds'][0]

        fileno = bisect.bisect(recordContext['keys'], fileslot) - 1

        if ('fileno' not in moduleContext[oid]
                or moduleContext[oid]['fileno'] < fileno
                or recordContext['settings']['wrap']):
            moduleContext[oid]['fileno'] = fileno

    datafile = recordContext['dirmap'][recordContext['keys'][moduleContext[oid]
                                                             ['fileno']]]

    if ('datafile' not in moduleContext[oid]
            or moduleContext[oid]['datafile'] != datafile):
        if 'datafileobj' in moduleContext[oid]:
            moduleContext[oid]['datafileobj'].close()
        moduleContext[oid]['datafileobj'] = RecordIndex(
            datafile, SnmprecRecord()).create()
        moduleContext[oid]['datafile'] = datafile

        log.msg('multiplex: switching to data file %s for %s' %
                (datafile, context['origOid']))

    text, db = moduleContext[oid]['datafileobj'].getHandles()

    textOid = str(
        rfc1902.OctetString('.'.join(['%s' % x for x in context['origOid']])))

    try:
        line = moduleContext[oid]['datafileobj'].lookup(textOid)
    except KeyError:
        offset = searchRecordByOid(context['origOid'], text, SnmprecRecord())
        exactMatch = False
    else:
        offset, subtreeFlag, prevOffset = line.split(str2octs(','))
        exactMatch = True

    text.seek(int(offset))

    line, _, _ = getRecord(text)  # matched line

    if context['nextFlag']:
        if exactMatch:
            line, _, _ = getRecord(text)
    else:
        if not exactMatch:
            return context['origOid'], tag, context['errorStatus']

    if not line:
        return context['origOid'], tag, context['errorStatus']

    try:
        oid, value = SnmprecRecord().evaluate(line)
    except error.SnmpsimError:
        oid, value = context['origOid'], context['errorStatus']

    return oid, tag, value
コード例 #39
0
ファイル: snmprec.py プロジェクト: ntwo1980/snmpsim
def cbFun(snmpEngine, sendRequestHandle, errorIndication, errorStatus,
          errorIndex, varBindTable, cbCtx):
    if errorIndication and not cbCtx['retries']:
        cbCtx['errors'] += 1
        log.msg('SNMP Engine error: %s' % errorIndication)
        return
    # SNMPv1 response may contain noSuchName error *and* SNMPv2c exception,
    # so we ignore noSuchName error here
    if errorStatus and errorStatus != 2 or errorIndication:
        log.msg('Remote SNMP error %s' %
                (errorIndication or errorStatus.prettyPrint()))
        if cbCtx['retries']:
            try:
                nextOID = varBindTable[-1][0][0]
            except IndexError:
                nextOID = cbCtx['lastOID']
            else:
                log.msg('Failed OID: %s' % nextOID)
            # fuzzy logic of walking a broken OID
            if len(nextOID) < 4:
                pass
            elif (continueOnErrors -
                  cbCtx['retries']) * 10 / continueOnErrors > 5:
                nextOID = nextOID[:-2] + (nextOID[-2] + 1, )
            elif nextOID[-1]:
                nextOID = nextOID[:-1] + (nextOID[-1] + 1, )
            else:
                nextOID = nextOID[:-2] + (nextOID[-2] + 1, 0)

            cbCtx['retries'] -= 1
            cbCtx['lastOID'] = nextOID

            log.msg('Retrying with OID %s (%s retries left)...' %
                    (nextOID, cbCtx['retries']))

            # initiate another SNMP walk iteration
            if getBulkFlag:
                cmdGen.sendVarBinds(snmpEngine, 'tgt', v3ContextEngineId,
                                    v3Context, 0, getBulkRepetitions,
                                    [(nextOID, None)], cbFun, cbCtx)
            else:
                cmdGen.sendVarBinds(snmpEngine, 'tgt', v3ContextEngineId,
                                    v3Context, [(nextOID, None)], cbFun, cbCtx)

        cbCtx['errors'] += 1

        return

    if continueOnErrors != cbCtx['retries']:
        cbCtx['retries'] += 1

    if varBindTable and varBindTable[-1] and varBindTable[-1][0]:
        cbCtx['lastOID'] = varBindTable[-1][0][0]

    stopFlag = False

    # Walk var-binds
    for varBindRow in varBindTable:
        for oid, val in varBindRow:
            # EOM
            if stopOID and oid >= stopOID:
                stopFlag = True  # stop on out of range condition
            elif val is None or \
                            val.tagSet in (rfc1905.NoSuchObject.tagSet,
                                           rfc1905.NoSuchInstance.tagSet,
                                           rfc1905.EndOfMibView.tagSet):
                stopFlag = True

            # Build .snmprec record

            context = {
                'origOid': oid,
                'origValue': val,
                'count': cbCtx['count'],
                'total': cbCtx['total'],
                'iteration': cbCtx['iteration'],
                'reqTime': cbCtx['reqTime'],
                'startOID': startOID,
                'stopOID': stopOID,
                'stopFlag': stopFlag,
                'variationModule': variationModule
            }

            try:
                line = dataFileHandler.format(oid, val, **context)
            except error.MoreDataNotification:
                cbCtx['count'] = 0
                cbCtx['iteration'] += 1

                moreDataNotification = sys.exc_info()[1]
                if 'period' in moreDataNotification:
                    log.msg('%s OIDs dumped, waiting %.2f sec(s)...' %
                            (cbCtx['total'], moreDataNotification['period']))
                    time.sleep(moreDataNotification['period'])

                # initiate another SNMP walk iteration
                if getBulkFlag:
                    cmdGen.sendVarBinds(snmpEngine, 'tgt', v3ContextEngineId,
                                        v3Context, 0, getBulkRepetitions,
                                        [(startOID, None)], cbFun, cbCtx)
                else:
                    cmdGen.sendVarBinds(snmpEngine, 'tgt', v3ContextEngineId,
                                        v3Context, [(startOID, None)], cbFun,
                                        cbCtx)

                stopFlag = True  # stop current iteration

            except error.NoDataNotification:
                pass
            except error.SnmpsimError:
                log.msg('ERROR: %s' % (sys.exc_info()[1], ))
                continue
            else:
                outputFile.write(line)

                cbCtx['count'] += 1
                cbCtx['total'] += 1

                if cbCtx['count'] % 100 == 0:
                    log.msg('OIDs dumped: %s/%s' %
                            (cbCtx['iteration'], cbCtx['count']))

    # Next request time
    cbCtx['reqTime'] = time.time()

    # Continue walking
    return not stopFlag
コード例 #40
0
ファイル: database.py プロジェクト: woodyle/snmpsim
    def create(self, forceIndexBuild=False, validateData=False):
        textFileTime = os.stat(self.__textFile)[8]

        # gdbm on OS X seems to voluntarily append .db, trying to catch that
        
        indexNeeded = forceIndexBuild
        
        for dbFile in (
            self.__dbFile + os.path.extsep + 'db',
            self.__dbFile
            ):
            if os.path.exists(dbFile):
                if textFileTime < os.stat(dbFile)[8]:
                    if indexNeeded:
                        log.msg('Forced index rebuild %s' % dbFile)
                    elif not whichdb(dbFile):
                        indexNeeded = True
                        log.msg('Unsupported index format, rebuilding index %s' % dbFile)
                else:
                    indexNeeded = True
                    log.msg('Index %s out of date' % dbFile)
                break
        else:
            indexNeeded = True
            log.msg('Index %s does not exist for data file %s' % (self.__dbFile, self.__textFile))
            
        if indexNeeded:
            # these might speed-up indexing
            open_flags = 'nfu' 
            while open_flags:
                try:
                    db = dbm.open(self.__dbFile, open_flags)
                except Exception:
                    open_flags = open_flags[:-1]
                    continue
                else:
                    break
            else:
                raise error.SnmpsimError('Failed to create %s for data file %s: %s' % (self.__dbFile, self.__textFile, sys.exc_info()[1]))

            try:
                text = open(self.__textFile, 'rb')
            except:
                raise error.SnmpsimError('Failed to open data file %s: %s' % (self.__dbFile, sys.exc_info()[0]))

            log.msg('Building index %s for data file %s (open flags \"%s\")...' % (self.__dbFile, self.__textFile, open_flags))
            sys.stdout.flush()
        
            lineNo = 0
            offset = 0
            prevOffset = -1
            while 1:
                line, lineNo, offset = getRecord(text, lineNo, offset)
                if not line:
                    # reference to last OID in data file
                    db['last'] = '%d,%d,%d' % (offset, 0, prevOffset)
                    break
             
                try:
                    oid, tag, val = self.__textParser.grammar.parse(line)
                except Exception:
                    db.close()
                    exc = sys.exc_info()[1]
                    try:
                        os.remove(self.__dbFile)
                    except OSError:
                        pass
                    raise error.SnmpsimError('Data error at %s:%d: %s' % (self.__textFile, lineNo, exc))

                if validateData:
                    try:
                        self.__textParser.evaluateOid(oid)
                    except Exception:
                        db.close()
                        exc = sys.exc_info()[1]
                        try:
                            os.remove(self.__dbFile)
                        except OSError:
                            pass
                        raise error.SnmpsimError('OID error at %s:%d: %s' % (self.__textFile, lineNo, exc))
                    try:
                        self.__textParser.evaluateValue(
                            oid, tag, val, dataValidation=True
                        )
                    except Exception:
                        log.msg(
                            'ERROR at line %s, value %r: %s' % \
                            (lineNo, val, sys.exc_info()[1])
                        )

                # for lines serving subtrees, type is empty in tag field
                db[oid] = '%d,%d,%d' % (offset, tag[0] == ':', prevOffset)

                if tag[0] == ':':
                    prevOffset = offset
                else:
                    prevOffset = -1   # not a subtree - no backreference

                offset += len(line)

            text.close()
            db.close()
       
            log.msg('...%d entries indexed' % lineNo)

        self.__textFileTime = os.stat(self.__textFile)[8]

        self.__dbType = whichdb(self.__dbFile)

        return self
コード例 #41
0
ファイル: delay.py プロジェクト: etingof/snmpsim
def variate(oid, tag, value, **context):
    if not context['nextFlag'] and not context['exactMatch']:
        return context['origOid'], tag, context['errorStatus']

    if 'settings' not in recordContext:
        recordContext['settings'] = dict(
            [split(x, '=') for x in split(value, ',')])

        if 'hexvalue' in recordContext['settings']:
            recordContext['settings']['value'] = [
                int(recordContext['settings']['hexvalue'][x:x + 2], 16)
                for x in range(0, len(recordContext['settings']['hexvalue']), 2)]

        if 'wait' in recordContext['settings']:
            recordContext['settings']['wait'] = float(
                recordContext['settings']['wait'])

        else:
            recordContext['settings']['wait'] = 500.0

        if 'deviation' in recordContext['settings']:
            recordContext['settings']['deviation'] = float(
                recordContext['settings']['deviation'])

        else:
            recordContext['settings']['deviation'] = 0.0

        if 'vlist' in recordContext['settings']:

            vlist = {}

            recordContext['settings']['vlist'] = split(
                recordContext['settings']['vlist'], ':')

            while recordContext['settings']['vlist']:
                o, v, d = recordContext['settings']['vlist'][:3]

                recordContext['settings']['vlist'] = recordContext['settings']['vlist'][3:]

                d = int(d)

                typeTag, _ = SnmprecRecord.unpackTag(tag)

                v = SnmprecGrammar.TAG_MAP[typeTag](v)

                if o not in vlist:
                    vlist[o] = {}

                if o == 'eq':
                    vlist[o][v] = d

                elif o in ('lt', 'gt'):
                    vlist[o] = v, d

                else:
                    log.msg('delay: bad vlist syntax: '
                            '%s' % recordContext['settings']['vlist'])

            recordContext['settings']['vlist'] = vlist

        if 'tlist' in recordContext['settings']:
            tlist = {}

            recordContext['settings']['tlist'] = split(
                recordContext['settings']['tlist'], ':')

            while recordContext['settings']['tlist']:
                o, v, d = recordContext['settings']['tlist'][:3]

                recordContext['settings']['tlist'] = recordContext['settings']['tlist'][3:]

                v = int(v)
                d = int(d)

                if o not in tlist:
                    tlist[o] = {}

                if o == 'eq':
                    tlist[o][v] = d

                elif o in ('lt', 'gt'):
                    tlist[o] = v, d

                else:
                    log.msg('delay: bad tlist syntax: '
                            '%s' % recordContext['settings']['tlist'])

            recordContext['settings']['tlist'] = tlist

    if context['setFlag'] and 'vlist' in recordContext['settings']:
        if ('eq' in recordContext['settings']['vlist'] and
                    context['origValue'] in recordContext['settings']['vlist']['eq']):
            delay = recordContext['settings']['vlist']['eq'][context['origValue']]

        elif ('lt' in recordContext['settings']['vlist'] and
                context['origValue'] < recordContext['settings']['vlist']['lt'][0]):
            delay = recordContext['settings']['vlist']['lt'][1]

        elif ('gt' in recordContext['settings']['vlist'] and
                context['origValue'] > recordContext['settings']['vlist']['gt'][0]):
            delay = recordContext['settings']['vlist']['gt'][1]

        else:
            delay = recordContext['settings']['wait']

    elif 'tlist' in recordContext['settings']:
        now = int(time.time())
        if ('eq' in recordContext['settings']['tlist'] and
                now == recordContext['settings']['tlist']['eq']):
            delay = recordContext['settings']['tlist']['eq'][now]

        elif ('lt' in recordContext['settings']['tlist'] and
                now < recordContext['settings']['tlist']['lt'][0]):
            delay = recordContext['settings']['tlist']['lt'][1]

        elif ('gt' in recordContext['settings']['tlist'] and
                now > recordContext['settings']['tlist']['gt'][0]):
            delay = recordContext['settings']['tlist']['gt'][1]

        else:
            delay = recordContext['settings']['wait']

    else:
        delay = recordContext['settings']['wait']

    if recordContext['settings']['deviation']:
        delay += random.randrange(
            -recordContext['settings']['deviation'],
            recordContext['settings']['deviation'])

    if delay < 0:
        delay = 0

    elif delay > 99999:
        log.msg('delay: dropping response for %s' % oid)
        raise error.NoDataNotification()

    log.msg('delay: waiting %d milliseconds for %s' % (delay, oid))

    time.sleep(delay / 1000)  # ms

    if context['setFlag'] or 'value' not in recordContext['settings']:
        return oid, tag, context['origValue']

    else:
        return oid, tag, recordContext['settings']['value']
コード例 #42
0
    def create(self, forceIndexBuild=False, validateData=False):
        textFileTime = os.stat(self.__textFile)[8]

        # gdbm on OS X seems to voluntarily append .db, trying to catch that

        indexNeeded = forceIndexBuild

        for dbFile in (
            self.__dbFile + os.path.extsep + 'db',
            self.__dbFile
            ):
            if os.path.exists(dbFile):
                if textFileTime < os.stat(dbFile)[8]:
                    if indexNeeded:
                        log.msg('Forced index rebuild %s' % dbFile)
                    elif not whichdb(dbFile):
                        indexNeeded = True
                        log.msg('Unsupported index format, rebuilding index %s' % dbFile)
                else:
                    indexNeeded = True
                    log.msg('Index %s out of date' % dbFile)
                break
        else:
            indexNeeded = True
            log.msg('Index %s does not exist for data file %s' % (self.__dbFile, self.__textFile))

        if indexNeeded:
            # these might speed-up indexing
            open_flags = 'nfu'
            while open_flags:
                try:
                    db = dbm.open(self.__dbFile, open_flags)
                except Exception:
                    open_flags = open_flags[:-1]
                    continue
                else:
                    break
            else:
                raise error.SnmpsimError('Failed to create %s for data file %s: %s' % (self.__dbFile, self.__textFile, sys.exc_info()[1]))

            try:
                text = open(self.__textFile, 'rb')
            except:
                raise error.SnmpsimError('Failed to open data file %s: %s' % (self.__dbFile, sys.exc_info()[0]))

            log.msg('Building index %s for data file %s (open flags \"%s\")...' % (self.__dbFile, self.__textFile, open_flags))
            sys.stdout.flush()

            lineNo = 0
            offset = 0
            prevOffset = -1
            while True:
                line, lineNo, offset = getRecord(text, lineNo, offset)
                if not line:
                    # reference to last OID in data file
                    db['last'] = '%d,%d,%d' % (offset, 0, prevOffset)
                    break

                try:
                    oid, tag, val = self.__textParser.grammar.parse(line)
                except Exception:
                    db.close()
                    exc = sys.exc_info()[1]
                    try:
                        os.remove(self.__dbFile)
                    except OSError:
                        pass
                    raise error.SnmpsimError('Data error at %s:%d: %s' % (self.__textFile, lineNo, exc))

                if validateData:
                    try:
                        self.__textParser.evaluateOid(oid)
                    except Exception:
                        db.close()
                        exc = sys.exc_info()[1]
                        try:
                            os.remove(self.__dbFile)
                        except OSError:
                            pass
                        raise error.SnmpsimError('OID error at %s:%d: %s' % (self.__textFile, lineNo, exc))
                    try:
                        self.__textParser.evaluateValue(
                            oid, tag, val, dataValidation=True
                        )
                    except Exception:
                        log.msg(
                            'ERROR at line %s, value %r: %s' % \
                            (lineNo, val, sys.exc_info()[1])
                        )

                # for lines serving subtrees, type is empty in tag field
                db[oid] = '%d,%d,%d' % (offset, tag[0] == ':', prevOffset)

                if tag[0] == ':':
                    prevOffset = offset
                else:
                    prevOffset = -1   # not a subtree - no backreference

                offset += len(line)

            text.close()
            db.close()

            log.msg('...%d entries indexed' % lineNo)

        self.__textFileTime = os.stat(self.__textFile)[8]

        self.__dbType = whichdb(self.__dbFile)

        return self
コード例 #43
0
ファイル: writecache.py プロジェクト: woodyle/snmpsim
def variate(oid, tag, value, **context):
    if not context['nextFlag'] and not context['exactMatch']:
        return context['origOid'], tag, context['errorStatus']

    if 'settings' not in recordContext:
        recordContext['settings'] = dict([split(x, '=') for x in split(value, ',')])

        if 'vlist' in recordContext['settings']:
            vlist = {}
            recordContext['settings']['vlist'] = split(recordContext['settings']['vlist'], ':')
            while recordContext['settings']['vlist']:
                o,v,e = recordContext['settings']['vlist'][:3]
                recordContext['settings']['vlist'] = recordContext['settings']['vlist'][3:]
                v = SnmprecGrammar.tagMap[tag](v)
                if o not in vlist:
                    vlist[o] = {}
                if o == 'eq':
                    vlist[o][v] = e
                elif o in ('lt', 'gt'):
                    vlist[o] = v, e
                else:
                    log.msg('writecache: bad vlist syntax: %s' % recordContext['settings']['vlist'])
            recordContext['settings']['vlist'] = vlist

    if oid not in moduleContext:
        moduleContext[oid] = {}
        moduleContext[oid]['type'] = SnmprecGrammar().tagMap[tag]()

    textOid = str(oid)

    if context['setFlag']:
        if 'vlist' in recordContext['settings']:
            if 'eq' in recordContext['settings']['vlist'] and  \
                     context['origValue'] in recordContext['settings']['vlist']['eq']:
                e = recordContext['settings']['vlist']['eq'][context['origValue']]
            elif 'lt' in recordContext['settings']['vlist'] and  \
                     context['origValue']<recordContext['settings']['vlist']['lt'][0]:
                e = recordContext['settings']['vlist']['lt'][1]
            elif 'gt' in recordContext['settings']['vlist'] and  \
                     context['origValue']>recordContext['settings']['vlist']['gt'][0]:
                e = recordContext['settings']['vlist']['gt'][1]
            else:
                e = None

            if e in errorTypes:
                raise errorTypes[e](
                    name=oid, idx=max(0, context['varsTotal']-context['varsRemaining']-1)
                )

        if moduleContext[oid]['type'].isSameTypeWith(context['origValue']):
            moduleContext['cache'][textOid] = context['origValue']
        else:
            return context['origOid'], tag, context['errorStatus']

    if textOid in moduleContext['cache']:
        return oid, tag, moduleContext['cache'][textOid]
    elif 'hexvalue' in recordContext['settings']:
        return oid, tag, moduleContext[oid]['type'].clone(hexValue=recordContext['settings']['hexvalue'])
    elif 'value' in recordContext['settings']:
        return oid, tag, moduleContext[oid]['type'].clone(recordContext['settings']['value'])
    else:
        return oid, tag, context['errorStatus']