251 lines
9.0 KiB
Python
251 lines
9.0 KiB
Python
#
|
|
# This file is part of pysnmp software.
|
|
#
|
|
# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
|
|
# License: http://pysnmp.sf.net/license.html
|
|
#
|
|
# This is a Python 2.6- version of the same file at level up
|
|
#
|
|
from pysnmp.hlapi.asyncore import cmdgen
|
|
from pysnmp.hlapi.varbinds import *
|
|
from pysnmp.proto.rfc1905 import endOfMibView
|
|
from pysnmp.proto import errind
|
|
from pyasn1.type.univ import Null
|
|
|
|
__all__ = ['getCmd', 'nextCmd', 'setCmd', 'bulkCmd', 'next']
|
|
|
|
|
|
# noinspection PyShadowingBuiltins
|
|
def next(iter):
|
|
return iter.next()
|
|
|
|
def getCmd(snmpEngine, authData, transportTarget, contextData,
|
|
*varBinds, **options):
|
|
# noinspection PyShadowingNames
|
|
def cbFun(snmpEngine, sendRequestHandle,
|
|
errorIndication, errorStatus, errorIndex,
|
|
varBinds, cbCtx):
|
|
cbCtx['errorIndication'] = errorIndication
|
|
cbCtx['errorStatus'] = errorStatus
|
|
cbCtx['errorIndex'] = errorIndex
|
|
cbCtx['varBinds'] = varBinds
|
|
|
|
cbCtx = {}
|
|
|
|
if varBinds:
|
|
cmdgen.getCmd(snmpEngine, authData, transportTarget,
|
|
contextData, *varBinds,
|
|
**dict(cbFun=cbFun, cbCtx=cbCtx,
|
|
lookupMib=options.get('lookupMib', True)))
|
|
|
|
snmpEngine.transportDispatcher.runDispatcher()
|
|
|
|
errorIndication = cbCtx['errorIndication']
|
|
errorStatus = cbCtx['errorStatus']
|
|
errorIndex = cbCtx['errorIndex']
|
|
varBinds = cbCtx['varBinds']
|
|
else:
|
|
errorIndication = errorStatus = errorIndex = None
|
|
varBinds = []
|
|
|
|
yield errorIndication, errorStatus, errorIndex, varBinds
|
|
|
|
|
|
def setCmd(snmpEngine, authData, transportTarget, contextData,
|
|
*varBinds, **options):
|
|
# noinspection PyShadowingNames
|
|
def cbFun(snmpEngine, sendRequestHandle,
|
|
errorIndication, errorStatus, errorIndex,
|
|
varBinds, cbCtx):
|
|
cbCtx['errorIndication'] = errorIndication
|
|
cbCtx['errorStatus'] = errorStatus
|
|
cbCtx['errorIndex'] = errorIndex
|
|
cbCtx['varBinds'] = varBinds
|
|
|
|
cbCtx = {}
|
|
|
|
while True:
|
|
cmdgen.setCmd(snmpEngine, authData, transportTarget,
|
|
contextData, *varBinds,
|
|
**dict(cbFun=cbFun, cbCtx=cbCtx,
|
|
lookupMib=options.get('lookupMib', True)))
|
|
|
|
snmpEngine.transportDispatcher.runDispatcher()
|
|
|
|
yield (cbCtx['errorIndication'],
|
|
cbCtx['errorStatus'], cbCtx['errorIndex'],
|
|
cbCtx['varBinds'])
|
|
|
|
if cbCtx['errorIndication'] != errind.requestTimedOut:
|
|
break
|
|
|
|
|
|
def nextCmd(snmpEngine, authData, transportTarget, contextData,
|
|
*varBinds, **options):
|
|
# noinspection PyShadowingNames
|
|
def cbFun(snmpEngine, sendRequestHandle,
|
|
errorIndication, errorStatus, errorIndex,
|
|
varBindTable, cbCtx):
|
|
cbCtx['errorIndication'] = errorIndication
|
|
cbCtx['errorStatus'] = errorStatus
|
|
cbCtx['errorIndex'] = errorIndex
|
|
cbCtx['varBindTable'] = varBindTable
|
|
|
|
lexicographicMode = options.get('lexicographicMode', True)
|
|
ignoreNonIncreasingOid = options.get('ignoreNonIncreasingOid', False)
|
|
maxRows = options.get('maxRows', 0)
|
|
maxCalls = options.get('maxCalls', 0)
|
|
|
|
cbCtx = {}
|
|
|
|
vbProcessor = CommandGeneratorVarBinds()
|
|
|
|
initialVars = [x[0] for x in vbProcessor.makeVarBinds(snmpEngine, varBinds)]
|
|
|
|
totalRows = totalCalls = 0
|
|
|
|
while True:
|
|
cmdgen.nextCmd(snmpEngine, authData, transportTarget, contextData,
|
|
*[(x[0], Null()) for x in varBinds],
|
|
**dict(cbFun=cbFun, cbCtx=cbCtx,
|
|
lookupMib=options.get('lookupMib', True)))
|
|
|
|
snmpEngine.transportDispatcher.runDispatcher()
|
|
|
|
errorIndication = cbCtx['errorIndication']
|
|
errorStatus = cbCtx['errorStatus']
|
|
errorIndex = cbCtx['errorIndex']
|
|
|
|
if ignoreNonIncreasingOid and errorIndication and \
|
|
isinstance(errorIndication, errind.OidNotIncreasing):
|
|
errorIndication = None
|
|
|
|
if errorIndication:
|
|
yield errorIndication, errorStatus, errorIndex, varBinds
|
|
if errorIndication != errind.requestTimedOut:
|
|
return
|
|
elif errorStatus:
|
|
if errorStatus == 2:
|
|
# Hide SNMPv1 noSuchName error which leaks in here
|
|
# from SNMPv1 Agent through internal pysnmp proxy.
|
|
errorStatus = errorStatus.clone(0)
|
|
errorIndex = errorIndex.clone(0)
|
|
yield errorIndication, errorStatus, errorIndex, varBinds
|
|
return
|
|
else:
|
|
varBinds = cbCtx['varBindTable'] and cbCtx['varBindTable'][0]
|
|
for idx, varBind in enumerate(varBinds):
|
|
name, val = varBind
|
|
if not isinstance(val, Null):
|
|
if lexicographicMode or initialVars[idx].isPrefixOf(name):
|
|
break
|
|
else:
|
|
return
|
|
|
|
totalRows += 1
|
|
totalCalls += 1
|
|
|
|
yield errorIndication, errorStatus, errorIndex, varBinds
|
|
|
|
if maxRows and totalRows >= maxRows or \
|
|
maxCalls and totalCalls >= maxCalls:
|
|
return
|
|
|
|
|
|
def bulkCmd(snmpEngine, authData, transportTarget, contextData,
|
|
nonRepeaters, maxRepetitions, *varBinds, **options):
|
|
# noinspection PyShadowingNames
|
|
def cbFun(snmpEngine, sendRequestHandle,
|
|
errorIndication, errorStatus, errorIndex,
|
|
varBindTable, cbCtx):
|
|
cbCtx['errorIndication'] = errorIndication
|
|
cbCtx['errorStatus'] = errorStatus
|
|
cbCtx['errorIndex'] = errorIndex
|
|
cbCtx['varBindTable'] = varBindTable
|
|
|
|
lexicographicMode = options.get('lexicographicMode', True)
|
|
ignoreNonIncreasingOid = options.get('ignoreNonIncreasingOid', False)
|
|
maxRows = options.get('maxRows', 0)
|
|
maxCalls = options.get('maxCalls', 0)
|
|
|
|
cbCtx = {}
|
|
|
|
vbProcessor = CommandGeneratorVarBinds()
|
|
|
|
initialVars = [x[0] for x in vbProcessor.makeVarBinds(snmpEngine, varBinds)]
|
|
nullVarBinds = [False] * len(initialVars)
|
|
|
|
totalRows = totalCalls = 0
|
|
stopFlag = False
|
|
|
|
while not stopFlag:
|
|
if maxRows and totalRows < maxRows:
|
|
maxRepetitions = min(maxRepetitions, maxRows - totalRows)
|
|
|
|
cmdgen.bulkCmd(snmpEngine, authData, transportTarget, contextData,
|
|
nonRepeaters, maxRepetitions,
|
|
*[(x[0], Null()) for x in varBinds],
|
|
**dict(cbFun=cbFun, cbCtx=cbCtx,
|
|
lookupMib=options.get('lookupMib', True)))
|
|
|
|
snmpEngine.transportDispatcher.runDispatcher()
|
|
|
|
errorIndication = cbCtx['errorIndication']
|
|
errorStatus = cbCtx['errorStatus']
|
|
errorIndex = cbCtx['errorIndex']
|
|
varBindTable = cbCtx['varBindTable']
|
|
|
|
if ignoreNonIncreasingOid and errorIndication and \
|
|
isinstance(errorIndication, errind.OidNotIncreasing):
|
|
errorIndication = None
|
|
|
|
if errorIndication:
|
|
yield (errorIndication, errorStatus, errorIndex,
|
|
varBindTable and varBindTable[0] or [])
|
|
if errorIndication != errind.requestTimedOut:
|
|
return
|
|
elif errorStatus:
|
|
if errorStatus == 2:
|
|
# Hide SNMPv1 noSuchName error which leaks in here
|
|
# from SNMPv1 Agent through internal pysnmp proxy.
|
|
errorStatus = errorStatus.clone(0)
|
|
errorIndex = errorIndex.clone(0)
|
|
yield (errorIndication, errorStatus, errorIndex,
|
|
varBindTable and varBindTable[0] or [])
|
|
return
|
|
else:
|
|
for i in range(len(varBindTable)):
|
|
stopFlag = True
|
|
if len(varBindTable[i]) != len(initialVars):
|
|
varBindTable = i and varBindTable[:i - 1] or []
|
|
break
|
|
for j in range(len(varBindTable[i])):
|
|
name, val = varBindTable[i][j]
|
|
if nullVarBinds[j]:
|
|
varBindTable[i][j] = name, endOfMibView
|
|
continue
|
|
stopFlag = False
|
|
if isinstance(val, Null):
|
|
nullVarBinds[j] = True
|
|
elif not lexicographicMode and \
|
|
not initialVars[j].isPrefixOf(name):
|
|
varBindTable[i][j] = name, endOfMibView
|
|
nullVarBinds[j] = True
|
|
if stopFlag:
|
|
varBindTable = i and varBindTable[:i - 1] or []
|
|
break
|
|
|
|
totalRows += len(varBindTable)
|
|
totalCalls += 1
|
|
|
|
if maxRows and totalRows >= maxRows:
|
|
if totalRows > maxRows:
|
|
varBindTable = varBindTable[:-(totalRows - maxRows)]
|
|
stopFlag = True
|
|
|
|
if maxCalls and totalCalls >= maxCalls:
|
|
stopFlag = True
|
|
|
|
for varBinds in varBindTable:
|
|
yield errorIndication, errorStatus, errorIndex, varBinds
|