summaryrefslogtreecommitdiff
path: root/pysnmp
diff options
context:
space:
mode:
authorelie <elie>2015-09-14 05:20:24 +0000
committerelie <elie>2015-09-14 05:20:24 +0000
commit2f24177c361ba4d9deba2d7378f84aa96111db80 (patch)
tree383c282bfe661bef3eaf16077946124c0039d9ab /pysnmp
parent4397ac4bd10b626aa9355cf04ee0cdb410fe6030 (diff)
downloadpysnmp-2f24177c361ba4d9deba2d7378f84aa96111db80.tar.gz
* synchronous oneliner apps redesigned to offer Python generator-based
API along with a more comprehensive set of accepted parameters. * massively documented (in Sphinx, NumPy style)
Diffstat (limited to 'pysnmp')
-rw-r--r--pysnmp/entity/rfc3413/oneliner/auth.py126
-rw-r--r--pysnmp/entity/rfc3413/oneliner/cmdgen.py313
-rw-r--r--pysnmp/entity/rfc3413/oneliner/ctx.py35
-rw-r--r--pysnmp/entity/rfc3413/oneliner/ntforg.py91
-rw-r--r--pysnmp/entity/rfc3413/oneliner/sync/__init__.py1
-rw-r--r--pysnmp/entity/rfc3413/oneliner/sync/cmdgen.py602
-rw-r--r--pysnmp/entity/rfc3413/oneliner/sync/compat/__init__.py1
-rw-r--r--pysnmp/entity/rfc3413/oneliner/sync/compat/cmdgen.py256
-rw-r--r--pysnmp/entity/rfc3413/oneliner/sync/compat/ntforg.py48
-rw-r--r--pysnmp/entity/rfc3413/oneliner/sync/ntforg.py126
-rw-r--r--pysnmp/entity/rfc3413/oneliner/target.py81
-rw-r--r--pysnmp/smi/rfc1902.py457
12 files changed, 1781 insertions, 356 deletions
diff --git a/pysnmp/entity/rfc3413/oneliner/auth.py b/pysnmp/entity/rfc3413/oneliner/auth.py
index 8c7e5f6..df1eafe 100644
--- a/pysnmp/entity/rfc3413/oneliner/auth.py
+++ b/pysnmp/entity/rfc3413/oneliner/auth.py
@@ -3,6 +3,49 @@ from pysnmp import error
from pyasn1.compat.octets import null
class CommunityData:
+ """Creates SNMP v1/v2c configuration entry.
+
+ This object can be used by
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.cmdgen.AsyncCommandGenerator` or
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.ntforg.AsyncNotificationOriginator`
+ and their derivatives for adding new entries to Local Configuration
+ Datastore (LCD) managed by :py:class:`~pysnmp.entity.engine.SnmpEngine`
+ class instance.
+
+ See :RFC:`2576#section-5.3` for more information on the
+ *SNMP-COMMUNITY-MIB::snmpCommunityTable*.
+
+ Parameters
+ ----------
+ communityIndex : str
+ Unique index value of a row in snmpCommunityTable. If it is the
+ only positional parameter, it is taken as *communityName*.
+ communityName : str
+ SNMP v1/v2c community string.
+ mpModel : int
+ SNMP version - 0 for SNMPv1 and 1 for SNMPv2c.
+ contextEngineId : str
+ Indicates the location of the context in which management
+ information is accessed when using the community string
+ specified by the above communityName.
+ contextName : str
+ The context in which management information is accessed when
+ using the above communityName.
+ tag : str
+ Arbitrary string that specifies a set of transport endpoints
+ to which a notification may be sent using communityName above
+ (see also :RFC:`3413#section-4.1.4`).
+
+ Examples
+ --------
+ >>> from pysnmp.entity.rfc3413.oneliner.auth import CommunityData
+ >>> CommunityData('public')
+ CommunityData(communityIndex='s1410706889', communityName=<COMMUNITY>, mpModel=1, contextEngineId=None, contextName='', tag='')
+ >>> CommunityData('public', 'public')
+ CommunityData(communityIndex='public', communityName=<COMMUNITY>, mpModel=1, contextEngineId=None, contextName='', tag='')
+ >>>
+
+ """
mpModel = 1 # Default is SMIv2
securityModel = mpModel + 1
securityLevel = 'noAuthNoPriv'
@@ -65,8 +108,89 @@ class CommunityData:
tag is None and self.tag or tag,
securityName is None and self.securityName or securityName
)
-
+
+#: No Authentication Protocol.
+usmNoAuthProtocol = config.usmNoAuthProtocol
+#: The HMAC-MD5-96 Digest Authentication Protocol (:RFC:`3414#section-6`)
+usmHMACMD5AuthProtocol = config.usmHMACMD5AuthProtocol
+#: The HMAC-SHA-96 Digest Authentication Protocol (:RFC:`3414#section-7`)
+usmHMACSHAAuthProtocol = config.usmHMACSHAAuthProtocol
+
+#: No Privacy Protocol.
+usmNoPrivProtocol = config.usmNoPrivProtocol
+#: The CBC-DES Symmetric Encryption Protocol (:RFC:`3414#section-8`)
+usmDESPrivProtocol = config.usmDESPrivProtocol
+#: The 3DES-EDE Symmetric Encryption Protocol (`draft-reeder-snmpv3-usm-3desede-00 <https://tools.ietf.org/html/draft-reeder-snmpv3-usm-3desede-00#section-5>`_)
+usm3DESEDEPrivProtocol = config.usm3DESEDEPrivProtocol
+#: The CFB128-AES-128 Symmetric Encryption Protocol (:RFC:`3826#section-3`)
+usmAesCfb128Protocol = config.usmAesCfb128Protocol
+#: The CFB128-AES-192 Symmetric Encryption Protocol (`draft-blumenthal-aes-usm-04 <https://tools.ietf.org/html/draft-blumenthal-aes-usm-04#section-3>`_)
+usmAesCfb192Protocol = config.usmAesCfb192Protocol
+#: The CFB128-AES-256 Symmetric Encryption Protocol (`draft-blumenthal-aes-usm-04 <https://tools.ietf.org/html/draft-blumenthal-aes-usm-04#section-3>`_)
+usmAesCfb256Protocol = config.usmAesCfb256Protocol
+
class UsmUserData:
+ """Creates SNMP v3 User Security Model (USM) configuration entry.
+
+ This object can be used by
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.cmdgen.AsyncCommandGenerator` or
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.ntforg.AsyncNotificationOriginator`
+ and their derivatives for adding new entries to Local Configuration
+ Datastore (LCD) managed by :py:class:`~pysnmp.entity.engine.SnmpEngine`
+ class instance.
+
+ See :RFC:`3414#section-5` for more information on the
+ *SNMP-USER-BASED-SM-MIB::usmUserTable*.
+
+ Parameters
+ ----------
+ userName : str
+ A human readable string representing the name of the SNMP USM user.
+ authKey : str
+ Initial value of the secret authentication key. If not set,
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmNoAuthProtocol`
+ is implied. If set and no *authProtocol* is specified,
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmHMACMD5AuthProtocol`
+ takes effect.
+ privKey : str
+ Initial value of the secret encryption key. If not set,
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmNoPrivProtocol`
+ is implied. If set and no *privProtocol* is specified,
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmDESPrivProtocol`
+ takes effect.
+ authProtocol : tuple
+ An indication of whether messages sent on behalf of this USM user
+ can be authenticated, and if so, the type of authentication protocol
+ which is used.
+
+ Supported authentication protocol identifiers are:
+
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmNoAuthProtocol` (default is *authKey* not given)
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmHMACMD5AuthProtocol` (default if *authKey* is given)
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmHMACSHAAuthProtocol`
+ privProtocol : tuple
+ An indication of whether messages sent on behalf of this USM user
+ be encrypted, and if so, the type of encryption protocol which is used.
+
+ Supported encryption protocol identifiers are:
+
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmNoPrivProtocol` (default is *authKey* not given)
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmDESPrivProtocol` (default if *authKey* is given)
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usm3DESEDEPrivProtocol`
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmAesCfb128Protocol`
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmAesCfb192Protocol`
+ * :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.usmAesCfb256Protocol`
+
+ Examples
+ --------
+ >>> from pysnmp.entity.rfc3413.oneliner.auth import UsmUserData
+ >>> UsmUserData('testuser', authKey='authenticationkey')
+ UsmUserData(userName='testuser', authKey=<AUTHKEY>, privKey=<PRIVKEY>, authProtocol=(1,3,6,1,6,3,10,1,1,2), privProtocol=(1,3,6,1,6,3,10,1,2,1))
+ >>> UsmUserData('testuser', authKey='authenticationkey', privKey='encryptionkey')
+ UsmUserData(userName='testuser', authKey=<AUTHKEY>, privKey=<PRIVKEY>, authProtocol=(1,3,6,1,6,3,10,1,1,2), privProtocol=(1,3,6,1,6,3,10,1,2,2))
+ >>>
+
+ """
authKey = privKey = None
authProtocol = config.usmNoAuthProtocol
privProtocol = config.usmNoPrivProtocol
diff --git a/pysnmp/entity/rfc3413/oneliner/cmdgen.py b/pysnmp/entity/rfc3413/oneliner/cmdgen.py
index d646cf6..4f38d51 100644
--- a/pysnmp/entity/rfc3413/oneliner/cmdgen.py
+++ b/pysnmp/entity/rfc3413/oneliner/cmdgen.py
@@ -1,31 +1,19 @@
+from sys import version_info
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413 import cmdgen
-from pysnmp.smi.rfc1902 import ObjectIdentity, ObjectType
-from pysnmp.entity.rfc3413.oneliner.auth import CommunityData, UsmUserData
-from pysnmp.entity.rfc3413.oneliner.target import UdpTransportTarget, \
- Udp6TransportTarget, UnixTransportTarget
-from pysnmp.entity.rfc3413.oneliner.ctx import ContextData
+from pysnmp.smi.rfc1902 import *
+from pysnmp.entity.rfc3413.oneliner.auth import *
+from pysnmp.entity.rfc3413.oneliner.target import *
+from pysnmp.entity.rfc3413.oneliner.ctx import *
from pysnmp.proto import rfc1905, errind
from pysnmp.smi import view
from pysnmp import nextid, error
from pyasn1.type import univ, base
from pyasn1.compat.octets import null
+
# obsolete, compatibility symbols
from pysnmp.entity.rfc3413.oneliner.mibvar import MibVariable
-# Auth protocol
-usmHMACMD5AuthProtocol = config.usmHMACMD5AuthProtocol
-usmHMACSHAAuthProtocol = config.usmHMACSHAAuthProtocol
-usmNoAuthProtocol = config.usmNoAuthProtocol
-
-# Privacy protocol
-usmDESPrivProtocol = config.usmDESPrivProtocol
-usm3DESEDEPrivProtocol = config.usm3DESEDEPrivProtocol
-usmAesCfb128Protocol = config.usmAesCfb128Protocol
-usmAesCfb192Protocol = config.usmAesCfb192Protocol
-usmAesCfb256Protocol = config.usmAesCfb256Protocol
-usmNoPrivProtocol = config.usmNoPrivProtocol
-
# SNMP engine
SnmpEngine = engine.SnmpEngine
@@ -226,29 +214,21 @@ class AsyncCommandGenerator:
return __varBinds
- def unmakeVarBinds(self, snmpEngine, varBinds, lookupNames, lookupValues):
- if lookupNames or lookupValues:
+ def unmakeVarBinds(self, snmpEngine, varBinds, lookupMib=False):
+ if lookupMib:
mibViewController = self.getMibViewController(snmpEngine)
varBinds = [ ObjectType(ObjectIdentity(x[0]), x[1]).resolveWithMib(mibViewController) for x in varBinds ]
return varBinds
- def makeVarBindsHead(self, snmpEngine, varNames):
- return [
- x[0] for x in self.makeVarBinds(
- snmpEngine,
- [ (x, univ.Null('')) for x in varNames ]
- )
- ]
-
# Async SNMP apps
def getCmd(self, snmpEngine, authData, transportTarget, contextData,
- varBinds, cbInfo, lookupNames=False, lookupValues=False):
+ varBinds, cbInfo, lookupMib=False):
def __cbFun(snmpEngine, sendRequestHandle,
errorIndication, errorStatus, errorIndex,
varBinds, cbCtx):
- lookupNames, lookupValues, cbFun, cbCtx = cbCtx
+ lookupMib, cbFun, cbCtx = cbCtx
return cbFun(
snmpEngine,
sendRequestHandle,
@@ -256,7 +236,7 @@ class AsyncCommandGenerator:
errorStatus,
errorIndex,
self.unmakeVarBinds(
- snmpEngine, varBinds, lookupNames, lookupValues
+ snmpEngine, varBinds, lookupMib
),
cbCtx
)
@@ -273,15 +253,15 @@ class AsyncCommandGenerator:
contextData.contextName,
self.makeVarBinds(snmpEngine, varBinds),
__cbFun,
- (lookupNames, lookupValues, cbFun, cbCtx)
+ (lookupMib, cbFun, cbCtx)
)
def setCmd(self, snmpEngine, authData, transportTarget, contextData,
- varBinds, cbInfo, lookupNames=False, lookupValues=False):
+ varBinds, cbInfo, lookupMib=False):
def __cbFun(snmpEngine, sendRequestHandle,
errorIndication, errorStatus, errorIndex,
varBinds, cbCtx):
- lookupNames, lookupValues, cbFun, cbCtx = cbCtx
+ lookupMib, cbFun, cbCtx = cbCtx
return cbFun(
snmpEngine,
sendRequestHandle,
@@ -289,7 +269,7 @@ class AsyncCommandGenerator:
errorStatus,
errorIndex,
self.unmakeVarBinds(
- snmpEngine, varBinds, lookupNames, lookupValues
+ snmpEngine, varBinds, lookupMib
),
cbCtx
)
@@ -306,22 +286,22 @@ class AsyncCommandGenerator:
contextData.contextName,
self.makeVarBinds(snmpEngine, varBinds),
__cbFun,
- (lookupNames, lookupValues, cbFun, cbCtx)
+ (lookupMib, cbFun, cbCtx)
)
def nextCmd(self, snmpEngine, authData, transportTarget, contextData,
- varBinds, cbInfo, lookupNames=False, lookupValues=False):
+ varBinds, cbInfo, lookupMib=False):
def __cbFun(snmpEngine, sendRequestHandle,
errorIndication, errorStatus, errorIndex,
varBindTable, cbCtx):
- lookupNames, lookupValues, cbFun, cbCtx = cbCtx
+ lookupMib, cbFun, cbCtx = cbCtx
return cbFun(
snmpEngine,
sendRequestHandle,
errorIndication,
errorStatus,
errorIndex,
- [ self.unmakeVarBinds(snmpEngine, varBindTableRow, lookupNames, lookupValues) for varBindTableRow in varBindTable ],
+ [ self.unmakeVarBinds(snmpEngine, varBindTableRow, lookupMib) for varBindTableRow in varBindTable ],
cbCtx
)
@@ -335,23 +315,23 @@ class AsyncCommandGenerator:
contextData.contextEngineId, contextData.contextName,
self.makeVarBinds(snmpEngine, varBinds),
__cbFun,
- (lookupNames, lookupValues, cbFun, cbCtx)
+ (lookupMib, cbFun, cbCtx)
)
def bulkCmd(self, snmpEngine, authData, transportTarget, contextData,
nonRepeaters, maxRepetitions, varBinds, cbInfo,
- lookupNames=False, lookupValues=False):
+ lookupMib=False):
def __cbFun(snmpEngine, sendRequestHandle,
errorIndication, errorStatus, errorIndex,
varBindTable, cbCtx):
- lookupNames, lookupValues, cbFun, cbCtx = cbCtx
+ lookupMib, cbFun, cbCtx = cbCtx
return cbFun(
snmpEngine,
sendRequestHandle,
errorIndication,
errorStatus,
errorIndex,
- [ self.unmakeVarBinds(snmpEngine, varBindTableRow, lookupNames, lookupValues) for varBindTableRow in varBindTable ],
+ [ self.unmakeVarBinds(snmpEngine, varBindTableRow, lookupMib) for varBindTableRow in varBindTable ],
cbCtx
)
@@ -367,239 +347,9 @@ class AsyncCommandGenerator:
nonRepeaters, maxRepetitions,
self.makeVarBinds(snmpEngine, varBinds),
__cbFun,
- (lookupNames, lookupValues, cbFun, cbCtx)
+ (lookupMib, cbFun, cbCtx)
)
-# Synchronous one-liner SNMP apps
-
-def getCmd(snmpEngine, authData, transportTarget, contextData,
- *varBinds, **kwargs):
-
- def cbFun(snmpEngine, sendRequestHandle,
- errorIndication, errorStatus, errorIndex,
- varBinds, cbCtx):
- cbCtx['errorIndication'] = errorIndication
- cbCtx['errorStatus'] = errorStatus
- cbCtx['errorIndex'] = errorIndex
- cbCtx['varBinds'] = varBinds
-
- cbCtx = {}
-
- AsyncCommandGenerator().getCmd(
- snmpEngine,
- authData,
- transportTarget,
- contextData,
- varBinds,
- (cbFun, cbCtx),
- kwargs.get('lookupNames'),
- kwargs.get('lookupValues')
- )
-
- snmpEngine.transportDispatcher.runDispatcher()
-
- yield cbCtx['errorIndication'], \
- cbCtx['errorStatus'], cbCtx['errorIndex'], \
- cbCtx['varBinds']
-
-def setCmd(snmpEngine, authData, transportTarget, contextData,
- *varBinds, **kwargs):
-
- def cbFun(snmpEngine, sendRequestHandle,
- errorIndication, errorStatus, errorIndex,
- varBinds, cbCtx):
- cbCtx['errorIndication'] = errorIndication
- cbCtx['errorStatus'] = errorStatus
- cbCtx['errorIndex'] = errorIndex
- cbCtx['varBinds'] = varBinds
-
- cbCtx = {}
-
- AsyncCommandGenerator().setCmd(
- snmpEngine,
- authData,
- transportTarget,
- contextData,
- varBinds,
- (cbFun, cbCtx),
- kwargs.get('lookupNames'),
- kwargs.get('lookupValues')
- )
-
- snmpEngine.transportDispatcher.runDispatcher()
-
- yield cbCtx['errorIndication'], \
- cbCtx['errorStatus'], cbCtx['errorIndex'], \
- cbCtx['varBinds']
-
-def nextCmd(snmpEngine, authData, transportTarget, contextData,
- *varBinds, **kwargs):
-
- def cbFun(snmpEngine, sendRequestHandle,
- errorIndication, errorStatus, errorIndex,
- varBindTable, cbCtx):
- cbCtx['errorIndication'] = errorIndication
- cbCtx['errorStatus'] = errorStatus
- cbCtx['errorIndex'] = errorIndex
- cbCtx['varBindTable'] = varBindTable
-
- lookupNames = kwargs.get('lookupNames', False)
- lookupValues = kwargs.get('lookupValues', False)
- lexicographicMode = kwargs.get('lexicographicMode', False)
- ignoreNonIncreasingOid = kwargs.get('ignoreNonIncreasingOid', False)
- maxRows = kwargs.get('maxRows', 0)
- maxCalls = kwargs.get('maxCalls', 0)
-
- cbCtx = {}
-
- cmdGen = AsyncCommandGenerator()
-
- initialVars = [ x[0] for x in cmdGen.makeVarBinds(snmpEngine, varBinds) ]
-
- totalRows = totalCalls = 0
-
- while True:
- cmdGen.nextCmd(snmpEngine,
- authData,
- transportTarget,
- contextData,
- [ (x[0], univ.Null()) for x in varBinds ],
- (cbFun, cbCtx),
- kwargs.get('lookupNames'),
- kwargs.get('lookupValues'))
-
- snmpEngine.transportDispatcher.runDispatcher()
-
- errorIndication = cbCtx['errorIndication']
- errorStatus = cbCtx['errorStatus']
- errorIndex = cbCtx['errorIndex']
-
- if ignoreNonIncreasingOid and errorIndication and \
- isinstance(errorIndication, errind.OidNotIncreasing):
- errorIndication = None
- if errorStatus or errorIndication:
- 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
- continue
- else:
- varBinds = cbCtx['varBindTable'] and cbCtx['varBindTable'][0]
- for idx, varBind in enumerate(varBinds):
- name, val = varBind
- if not isinstance(val, univ.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, **kwargs):
-
- def cbFun(snmpEngine, sendRequestHandle,
- errorIndication, errorStatus, errorIndex,
- varBindTable, cbCtx):
- cbCtx['errorIndication'] = errorIndication
- cbCtx['errorStatus'] = errorStatus
- cbCtx['errorIndex'] = errorIndex
- cbCtx['varBindTable'] = varBindTable
-
- lookupNames = kwargs.get('lookupNames', False)
- lookupValues = kwargs.get('lookupValues', False)
- lexicographicMode = kwargs.get('lexicographicMode', False)
- ignoreNonIncreasingOid = kwargs.get('ignoreNonIncreasingOid', False)
- maxRows = kwargs.get('maxRows', 0)
- maxCalls = kwargs.get('maxCalls', 0)
-
- cbCtx = {}
-
- cmdGen = AsyncCommandGenerator()
-
- initialVars = [ x[0] for x in cmdGen.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], univ.Null()) for x in varBinds ],
- (cbFun, cbCtx),
- kwargs.get('lookupNames'),
- kwargs.get('lookupValues'))
-
- 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 errorStatus or errorIndication:
- 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 []
- continue
- 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, rfc1905.endOfMibView
- continue
- stopFlag = False
- if isinstance(val, univ.Null):
- nullVarBinds[j] = True
- elif not lexicographicMode and \
- not initialVars[j].isPrefixOf(name):
- varBindTable[i][j] = name, rfc1905.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
-
#
# The rest of code in this file belongs to obsolete, compatibility wrappers.
# Never use interfaces below for new applications!
@@ -641,7 +391,7 @@ class AsynCommandGenerator:
def unmakeVarBinds(self, varBinds, lookupNames, lookupValues):
return self.__asyncCmdGen.unmakeVarBinds(
- self.snmpEngine, varBinds, lookupNames, lookupValues
+ self.snmpEngine, varBinds, lookupNames or lookupValues
)
def getCmd(self, authData, transportTarget, varNames, cbInfo,
@@ -668,7 +418,7 @@ class AsynCommandGenerator:
ContextData(contextEngineId, contextName),
[(x, self._null) for x in varNames],
cbInfo,
- lookupNames, lookupValues
+ lookupNames or lookupValues
)
asyncGetCmd = getCmd
@@ -695,7 +445,7 @@ class AsynCommandGenerator:
self.snmpEngine,
authData, transportTarget,
ContextData(contextEngineId, contextName), varBinds, cbInfo,
- lookupNames, lookupValues
+ lookupNames or lookupValues
)
asyncSetCmd = setCmd
@@ -724,7 +474,7 @@ class AsynCommandGenerator:
ContextData(contextEngineId, contextName),
[(x, self._null) for x in varNames],
cbInfo,
- lookupNames, lookupValues
+ lookupNames or lookupValues
)
asyncNextCmd = nextCmd
@@ -755,7 +505,7 @@ class AsynCommandGenerator:
nonRepeaters, maxRepetitions,
[(x, self._null) for x in varNames],
cbInfo,
- lookupNames, lookupValues
+ lookupNames or lookupValues
)
asyncBulkCmd = bulkCmd
@@ -816,3 +566,8 @@ class CommandGenerator:
return errorIndication, errorStatus, errorIndex, varBindTable
+# circular module import dependency
+if version_info[:2] < (2, 6):
+ from pysnmp.entity.rfc3413.oneliner.sync.compat.cmdgen import *
+else:
+ from pysnmp.entity.rfc3413.oneliner.sync.cmdgen import *
diff --git a/pysnmp/entity/rfc3413/oneliner/ctx.py b/pysnmp/entity/rfc3413/oneliner/ctx.py
index 3449912..528a2b0 100644
--- a/pysnmp/entity/rfc3413/oneliner/ctx.py
+++ b/pysnmp/entity/rfc3413/oneliner/ctx.py
@@ -1,6 +1,41 @@
from pyasn1.compat.octets import null
class ContextData:
+ """Creates UDP/IPv6 configuration entry and initialize socket API if needed.
+
+ This object can be used by
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.cmdgen.AsyncCommandGenerator` or
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.ntforg.AsyncNotificationOriginator`
+ and their derevatives for forming SNMP PDU and also adding new entries to
+ Local Configuration Datastore (LCD) in order to support SNMPv1/v2c with
+ SNMPv3 interoperability.
+
+ See :RFC:`3411#section-4.1` for SNMP Context details.
+
+ Parameters
+ ----------
+ contextEngineId : str
+ Uniquely identifies an SNMP entity that may realize an instance of
+ a MIB with a particular contextName (:RFC:`3411#section-3.3.2`).
+ More frequently than not, ContextEngineID is the same as
+ authoritative SnmpEngineID, however if SNMP Engine serves multiple
+ SNMP Entities, their ContextEngineIDs would be distinct.
+ Default is authoritative SNMP Engine ID.
+ contextName : str
+ Used to name an instance of MIB (:RFC:`3411#section-3.3.3`).
+ Default is empty string.
+
+ Examples
+ --------
+ >>> from pysnmp.entity.rfc3413.oneliner.ctx import ContextData
+ >>> ContextData()
+ ContextData(contextEngineId=None, contextName='')
+ >>> ContextData(OctetString(hexValue='01020ABBA0'))
+ ContextData(contextEngineId=OctetString(hexValue='01020abba0'), contextName='')
+ >>> ContextData(contextName='mycontext')
+ ContextData(contextEngineId=None, contextName='mycontext')
+
+ """
def __init__(self, contextEngineId=None, contextName=null):
self.contextEngineId = contextEngineId
self.contextName = contextName
diff --git a/pysnmp/entity/rfc3413/oneliner/ntforg.py b/pysnmp/entity/rfc3413/oneliner/ntforg.py
index 6ff9215..96a8456 100644
--- a/pysnmp/entity/rfc3413/oneliner/ntforg.py
+++ b/pysnmp/entity/rfc3413/oneliner/ntforg.py
@@ -1,30 +1,16 @@
from pyasn1.compat.octets import null
from pysnmp import nextid, error
from pysnmp.entity import engine, config
-from pysnmp.smi.rfc1902 import ObjectIdentity, ObjectType, NotificationType
+from pysnmp.smi.rfc1902 import *
from pysnmp.entity.rfc3413 import ntforg, context
-from pysnmp.entity.rfc3413.oneliner.auth import CommunityData, UsmUserData
-from pysnmp.entity.rfc3413.oneliner.target import UdpTransportTarget, \
- Udp6TransportTarget, UnixTransportTarget
+from pysnmp.entity.rfc3413.oneliner.auth import *
+from pysnmp.entity.rfc3413.oneliner.target import *
+from pysnmp.entity.rfc3413.oneliner.ctx import *
from pysnmp.entity.rfc3413.oneliner import cmdgen
# obsolete, compatibility symbols
from pysnmp.entity.rfc3413.oneliner.mibvar import MibVariable
-# Auth protocol
-usmHMACMD5AuthProtocol = config.usmHMACMD5AuthProtocol
-usmHMACSHAAuthProtocol = config.usmHMACSHAAuthProtocol
-usmNoAuthProtocol = config.usmNoAuthProtocol
-
-# Privacy protocol
-usmDESPrivProtocol = config.usmDESPrivProtocol
-usm3DESEDEPrivProtocol = config.usm3DESEDEPrivProtocol
-usmAesCfb128Protocol = config.usmAesCfb128Protocol
-usmAesCfb192Protocol = config.usmAesCfb192Protocol
-usmAesCfb256Protocol = config.usmAesCfb256Protocol
-usmNoPrivProtocol = config.usmNoPrivProtocol
-
SnmpEngine = engine.SnmpEngine
-ContextData = cmdgen.ContextData
nextID = nextid.Integer(0xffffffff)
@@ -135,8 +121,8 @@ class AsyncNotificationOriginator:
__varBinds.append(varBind.resolveWithMib(mibViewController))
return __varBinds
- def unmakeVarBinds(self, snmpEngine, varBinds, lookupNames, lookupValues):
- if lookupNames or lookupValues:
+ def unmakeVarBinds(self, snmpEngine, varBinds, lookupMib=False):
+ if lookupMib:
mibViewController = self.getMibViewController(snmpEngine)
varBinds = [ ObjectType(ObjectIdentity(x[0]), x[1]).resolveWithMib(mibViewController) for x in varBinds ]
return varBinds
@@ -144,20 +130,20 @@ class AsyncNotificationOriginator:
def sendNotification(self, snmpEngine,
authData, transportTarget, contextData,
notifyType,
- varBinds=(),
+ varBinds,
cbInfo=(None, None),
- lookupNames=False, lookupValues=False):
+ lookupMib=False):
def __cbFun(snmpEngine, sendRequestHandle, errorIndication,
errorStatus, errorIndex, varBinds, cbCtx):
- lookupNames, lookupValues, cbFun, cbCtx = cbCtx
+ lookupMib, cbFun, cbCtx = cbCtx
return cbFun and cbFun(
snmpEngine,
sendRequestHandle,
errorIndication,
errorStatus, errorIndex,
self.unmakeVarBinds(
- snmpEngine, varBinds, lookupNames, lookupValues
+ snmpEngine, varBinds, lookupMib
),
cbCtx
)
@@ -176,43 +162,7 @@ class AsyncNotificationOriginator:
snmpEngine, authData, transportTarget, notifyType
)
- return ntforg.NotificationOriginator().sendVarBinds(snmpEngine, notifyName, contextData.contextEngineId, contextData.contextName, self.makeVarBinds(snmpEngine, varBinds), __cbFun, (lookupNames, lookupValues, cbFun, cbCtx))
-
-#
-# Synchronous one-liner Notification Originator application
-#
-
-def sendNotification(snmpEngine, authData, transportTarget, contextData,
- notifyType, notificationType, **kwargs):
-
- def cbFun(snmpEngine, sendRequestHandle,
- errorIndication, errorStatus, errorIndex,
- varBinds, cbCtx):
- cbCtx['errorIndication'] = errorIndication
- cbCtx['errorStatus'] = errorStatus
- cbCtx['errorIndex'] = errorIndex
- cbCtx['varBinds'] = varBinds
-
- cbCtx = {}
-
- AsyncNotificationOriginator().sendNotification(
- snmpEngine,
- authData,
- transportTarget,
- contextData,
- notifyType,
- notificationType,
- (cbFun, cbCtx),
- kwargs.get('lookupNames'),
- kwargs.get('lookupValues')
- )
-
- snmpEngine.transportDispatcher.runDispatcher()
-
- if cbCtx:
- yield cbCtx['errorIndication'], \
- cbCtx['errorStatus'], cbCtx['errorIndex'], \
- cbCtx['varBinds']
+ return ntforg.NotificationOriginator().sendVarBinds(snmpEngine, notifyName, contextData.contextEngineId, contextData.contextName, self.makeVarBinds(snmpEngine, varBinds), __cbFun, (lookupMib, cbFun, cbCtx))
#
# The rest of code in this file belongs to obsolete, compatibility wrappers.
@@ -256,6 +206,16 @@ class AsynNotificationOriginator:
def uncfgNtfOrg(self, authData=None):
return self.__asyncNtfOrg.uncfgNtfOrg(self.snmpEngine, authData)
+ def makeVarBinds(self, varBinds):
+ return self.__asyncNtfOrg.makeVarBinds(
+ self.snmpEngine, varBinds
+ )
+
+ def unmakeVarBinds(self, varBinds, lookupNames, lookupValues):
+ return self.__asyncNtfOrg.unmakeVarBinds(
+ self.snmpEngine, varBinds, lookupNames or lookupValues
+ )
+
def sendNotification(self, authData, transportTarget,
notifyType, notificationType,
varBinds=(), # legacy, use NotificationType instead
@@ -306,7 +266,7 @@ class AsynNotificationOriginator:
contextName),
notifyType, notificationType.addVarBinds(*varBinds),
(__cbFun, cbInfo),
- lookupNames, lookupValues
+ lookupNames or lookupValues
)
asyncSendNotification = sendNotification
@@ -328,3 +288,10 @@ class NotificationOriginator:
notificationType.addVarBinds(*varBinds),
**kwargs):
return x
+
+# circular module import dependency
+from sys import version_info
+if version_info[:2] < (2, 6):
+ from pysnmp.entity.rfc3413.oneliner.sync.compat.ntforg import *
+else:
+ from pysnmp.entity.rfc3413.oneliner.sync.ntforg import *
diff --git a/pysnmp/entity/rfc3413/oneliner/sync/__init__.py b/pysnmp/entity/rfc3413/oneliner/sync/__init__.py
new file mode 100644
index 0000000..8c3066b
--- /dev/null
+++ b/pysnmp/entity/rfc3413/oneliner/sync/__init__.py
@@ -0,0 +1 @@
+# This file is necessary to make this directory a package.
diff --git a/pysnmp/entity/rfc3413/oneliner/sync/cmdgen.py b/pysnmp/entity/rfc3413/oneliner/sync/cmdgen.py
new file mode 100644
index 0000000..b3a42d7
--- /dev/null
+++ b/pysnmp/entity/rfc3413/oneliner/sync/cmdgen.py
@@ -0,0 +1,602 @@
+from pysnmp.entity.rfc3413.oneliner.cmdgen import *
+
+if version_info[:2] < (2, 6):
+ def next(iter):
+ return iter.next()
+
+def getCmd(snmpEngine, authData, transportTarget, contextData,
+ *varBinds, **options):
+ """Creates a generator to perform one or more SNMP GET queries.
+
+ On each iteration, new SNMP GET request is send (:RFC:`1905#section-4.2.1`).
+ The iterator blocks waiting for response to arrive or error to occur.
+
+ Parameters
+ ----------
+ snmpEngine : :py:class:`~pysnmp.entity.engine.SnmpEngine`
+ Class instance representing SNMP engine.
+
+ authData : :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.CommunityData` or :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.UsmUserData`
+ Class instance representing SNMP credentials.
+
+ transportTarget : :py:class:`~pysnmp.entity.rfc3413.oneliner.target.UdpTransportTarget` or :py:class:`~pysnmp.entity.rfc3413.oneliner.target.Udp6TransportTarget`
+ Class instance representing transport type along with SNMP peer address.
+
+ contextData : :py:class:`~pysnmp.entity.rfc3413.oneliner.ctx.ContextData`
+ Class instance representing SNMP ContextEngineId and ContextName values.
+
+ *varBinds : :py:class:`~pysnmp.smi.rfc1902.ObjectType`
+ One or more class instances representing MIB variables to place
+ into SNMP request.
+
+ Other Parameters
+ ----------------
+ **options :
+ Request options:
+
+ * `lookupMib` - load MIB and resolve response MIB variables at
+ the cost of slightly reduced performance. Default is `True`.
+
+ Yields
+ ------
+ errorIndication : str
+ True value indicates SNMP engine error.
+ errorStatus : str
+ Non-zero value indicates SNMP PDU error.
+ errorIndex : int
+ Non-zero value refers to *varBinds[errorIndex-1]
+ varBinds : tuple
+ A sequence of :py:class:`~pysnmp.smi.rfc1902.ObjectType` class
+ instances representing MIB variables returned in SNMP response.
+
+ Raises
+ ------
+ PySnmpError
+ Or its derivative indicating that an error occurred while
+ performing SNMP operation.
+
+ Notes
+ -----
+ The `getCmd` generator will be exhausted immidiately unless
+ a new sequence of `varBinds` are send back into running generator
+ (supported since Python 2.6).
+
+ Examples
+ --------
+ >>> from pysnmp.entity.rfc3413.oneliner.cmdgen import *
+ >>> g = getCmd(SnmpEngine(),
+ ... CommunityData('public'),
+ ... UdpTransportTarget(('demo.snmplabs.com', 161)),
+ ... ContextData(),
+ ... ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)))
+ >>> next(g)
+ (None, 0, 0, [ObjectType(ObjectIdentity(ObjectName('1.3.6.1.2.1.1.1.0')), DisplayString('SunOS zeus.snmplabs.com 4.1.3_U1 1 sun4m'))])
+ >>>
+
+ """
+ def cbFun(snmpEngine, sendRequestHandle,
+ errorIndication, errorStatus, errorIndex,
+ varBinds, cbCtx):
+ cbCtx['errorIndication'] = errorIndication
+ cbCtx['errorStatus'] = errorStatus
+ cbCtx['errorIndex'] = errorIndex
+ cbCtx['varBinds'] = varBinds
+
+ cbCtx = {}
+
+ cmdGen = AsyncCommandGenerator()
+
+ while True:
+ if varBinds:
+ cmdGen.getCmd(
+ snmpEngine,
+ authData,
+ transportTarget,
+ contextData,
+ varBinds,
+ (cbFun, cbCtx),
+ 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 = []
+
+ varBinds = ( yield errorIndication, errorStatus, errorIndex, varBinds )
+
+ if not varBinds:
+ break
+
+def setCmd(snmpEngine, authData, transportTarget, contextData,
+ *varBinds, **options):
+ """Creates a generator to perform one or more SNMP SET queries.
+
+ On each iteration, new SNMP SET request is send (:RFC:`1905#section-4.2.5`).
+ The iterator blocks waiting for response to arrive or error to occur.
+
+ Parameters
+ ----------
+ snmpEngine : :py:class:`~pysnmp.entity.engine.SnmpEngine`
+ Class instance representing SNMP engine.
+
+ authData : :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.CommunityData` or :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.UsmUserData`
+ Class instance representing SNMP credentials.
+
+ transportTarget : :py:class:`~pysnmp.entity.rfc3413.oneliner.target.UdpTransportTarget` or :py:class:`~pysnmp.entity.rfc3413.oneliner.target.Udp6TransportTarget`
+ Class instance representing transport type along with SNMP peer address.
+
+ contextData : :py:class:`~pysnmp.entity.rfc3413.oneliner.ctx.ContextData`
+ Class instance representing SNMP ContextEngineId and ContextName values.
+
+ *varBinds : :py:class:`~pysnmp.smi.rfc1902.ObjectType`
+ One or more class instances representing MIB variables to place
+ into SNMP request.
+
+ Other Parameters
+ ----------------
+ **options :
+ Request options:
+
+ * `lookupMib` - load MIB and resolve response MIB variables at
+ the cost of slightly reduced performance. Default is `True`.
+ Default is `True`.
+
+ Yields
+ ------
+ errorIndication : str
+ True value indicates SNMP engine error.
+ errorStatus : str
+ Non-zero value indicates SNMP PDU error.
+ errorIndex : int
+ Non-zero value refers to *varBinds[errorIndex-1]
+ varBinds : tuple
+ A sequence of :py:class:`~pysnmp.smi.rfc1902.ObjectType` class
+ instances representing MIB variables returned in SNMP response.
+
+ Raises
+ ------
+ PySnmpError
+ Or its derivative indicating that an error occurred while
+ performing SNMP operation.
+
+ Notes
+ -----
+ The `setCmd` generator will be exhausted immidiately unless
+ a new sequence of `varBinds` are send back into running generator
+ (supported since Python 2.6).
+
+ Examples
+ --------
+ >>> from pysnmp.entity.rfc3413.oneliner.cmdgen import *
+ >>> g = setCmd(SnmpEngine(),
+ ... CommunityData('public'),
+ ... UdpTransportTarget(('demo.snmplabs.com', 161)),
+ ... ContextData(),
+ ... ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0), 'Linux i386'))
+ >>> next(g)
+ (None, 0, 0, [ObjectType(ObjectIdentity(ObjectName('1.3.6.1.2.1.1.1.0')), DisplayString('Linux i386'))])
+ >>>
+
+ """
+ def cbFun(snmpEngine, sendRequestHandle,
+ errorIndication, errorStatus, errorIndex,
+ varBinds, cbCtx):
+ cbCtx['errorIndication'] = errorIndication
+ cbCtx['errorStatus'] = errorStatus
+ cbCtx['errorIndex'] = errorIndex
+ cbCtx['varBinds'] = varBinds
+
+ cbCtx = {}
+
+ cmdGen = AsyncCommandGenerator()
+
+ while True:
+ if varBinds:
+ cmdGen.setCmd(
+ snmpEngine,
+ authData,
+ transportTarget,
+ contextData,
+ varBinds,
+ (cbFun, cbCtx),
+ 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 = []
+
+ varBinds = ( yield errorIndication, errorStatus, errorIndex, varBinds )
+
+ if not varBinds:
+ break
+
+def nextCmd(snmpEngine, authData, transportTarget, contextData,
+ *varBinds, **options):
+ """Creates a generator to perform one or more SNMP GETNEXT queries.
+
+ On each iteration, new SNMP GETNEXT request is send
+ (:RFC:`1905#section-4.2.2`). The iterator blocks waiting for response
+ to arrive or error to occur.
+
+ Parameters
+ ----------
+ snmpEngine : :py:class:`~pysnmp.entity.engine.SnmpEngine`
+ Class instance representing SNMP engine.
+
+ authData : :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.CommunityData` or :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.UsmUserData`
+ Class instance representing SNMP credentials.
+
+ transportTarget : :py:class:`~pysnmp.entity.rfc3413.oneliner.target.UdpTransportTarget` or :py:class:`~pysnmp.entity.rfc3413.oneliner.target.Udp6TransportTarget`
+ Class instance representing transport type along with SNMP peer address.
+
+ contextData : :py:class:`~pysnmp.entity.rfc3413.oneliner.ctx.ContextData`
+ Class instance representing SNMP ContextEngineId and ContextName values.
+
+ *varBinds : :py:class:`~pysnmp.smi.rfc1902.ObjectType`
+ One or more class instances representing MIB variables to place
+ into SNMP request.
+
+ Other Parameters
+ ----------------
+ **options :
+ Request options:
+
+ * `lookupMib` - load MIB and resolve response MIB variables at
+ the cost of slightly reduced performance. Default is `True`.
+ Default is `True`.
+ * `lexicographicMode` - stop iteration when all response MIB
+ variables leave the scope of initial MIB variables in
+ `varBinds`. Default is `True`.
+ * `ignoreNonIncreasingOid` - continue iteration even if response
+ MIB variables (OIDs) are not greater then request MIB variables.
+ Default is `False`.
+ * `maxRows` - stop iteration once this generator instance processed
+ `maxRows` of SNMP conceptual table. Default is `0` (no limit).
+ * `maxCalls` - stop iteration once this generator instance processed
+ `maxCalls` responses. Default is 0 (no limit).
+
+ Yields
+ ------
+ errorIndication : str
+ True value indicates SNMP engine error.
+ errorStatus : str
+ Non-zero value indicates SNMP PDU error.
+ errorIndex : int
+ Non-zero value refers to *varBinds[errorIndex-1]
+ varBinds : tuple
+ A sequence of :py:class:`~pysnmp.smi.rfc1902.ObjectType` class
+ instances representing MIB variables returned in SNMP response.
+
+ Raises
+ ------
+ PySnmpError
+ Or its derivative indicating that an error occurred while
+ performing SNMP operation.
+
+ Notes
+ -----
+ The `nextCmd` generator will be exhausted on any of the following
+ conditions:
+
+ * SNMP engine error occurs thus `errorIndication` is `True`
+ * SNMP PDU `errorStatus` is reported as `True`
+ * SNMP :py:class:`~pysnmp.proto.rfc1905.EndOfMibView` values
+ (also known as *SNMP exception values*) are reported for all
+ MIB variables in `varBinds`
+ * *lexicographicMode* option is set to `False` and all
+ response MIB variables leave the scope of `varBinds`
+
+ At any moment a new sequence of `varBinds` could be send back into
+ running generator (supported since Python 2.6).
+
+ Examples
+ --------
+ >>> from pysnmp.entity.rfc3413.oneliner.cmdgen import *
+ >>> g = nextCmd(SnmpEngine(),
+ ... CommunityData('public'),
+ ... UdpTransportTarget(('demo.snmplabs.com', 161)),
+ ... ContextData(),
+ ... ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr')))
+ >>> next(g)
+ (None, 0, 0, [ObjectType(ObjectIdentity(ObjectName('1.3.6.1.2.1.1.1.0')), DisplayString('SunOS zeus.snmplabs.com 4.1.3_U1 1 sun4m'))])
+ >>> g.send( [ ObjectType(ObjectIdentity('IF-MIB', 'ifInOctets')) ] )
+ (None, 0, 0, [(ObjectName('1.3.6.1.2.1.2.2.1.10.1'), Counter32(284817787))])
+ """
+ def cbFun(snmpEngine, sendRequestHandle,
+ errorIndication, errorStatus, errorIndex,
+ varBindTable, cbCtx):
+ cbCtx['errorIndication'] = errorIndication
+ cbCtx['errorStatus'] = errorStatus
+ cbCtx['errorIndex'] = errorIndex
+ cbCtx['varBindTable'] = varBindTable
+
+ lookupMib = options.get('lookupMib', True)
+ lexicographicMode = options.get('lexicographicMode', True)
+ ignoreNonIncreasingOid = options.get('ignoreNonIncreasingOid', False)
+ maxRows = options.get('maxRows', 0)
+ maxCalls = options.get('maxCalls', 0)
+
+ cbCtx = {}
+
+ cmdGen = AsyncCommandGenerator()
+
+ initialVars = [ x[0] for x in cmdGen.makeVarBinds(snmpEngine, varBinds) ]
+
+ totalRows = totalCalls = 0
+
+ while True:
+ if varBinds:
+ cmdGen.nextCmd(snmpEngine,
+ authData,
+ transportTarget,
+ contextData,
+ [ (x[0], univ.Null()) for x in varBinds ],
+ (cbFun, cbCtx),
+ lookupMib)
+
+ 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
+ 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, univ.Null):
+ if lexicographicMode or initialVars[idx].isPrefixOf(name):
+ break
+ else:
+ return
+
+ totalRows += 1
+ totalCalls += 1
+ else:
+ errorIndication = errorStatus = errorIndex = None
+ varBinds = []
+
+ initialVarBinds = ( yield errorIndication, errorStatus,
+ errorIndex, varBinds )
+
+ if initialVarBinds:
+ varBinds = initialVarBinds
+ initialVars = [ x[0] for x in cmdGen.makeVarBinds(snmpEngine,
+ varBinds) ]
+
+ if maxRows and totalRows >= maxRows or \
+ maxCalls and totalCalls >= maxCalls:
+ return
+
+def bulkCmd(snmpEngine, authData, transportTarget, contextData,
+ nonRepeaters, maxRepetitions, *varBinds, **options):
+ """Creates a generator to perform one or more SNMP GETBULK queries.
+
+ On each iteration, new SNMP GETBULK request is send
+ (:RFC:`1905#section-4.2.3`). The iterator blocks waiting for response
+ to arrive or error to occur.
+
+ Parameters
+ ----------
+ snmpEngine : :py:class:`~pysnmp.entity.engine.SnmpEngine`
+ Class instance representing SNMP engine.
+
+ authData : :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.CommunityData` or :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.UsmUserData`
+ Class instance representing SNMP credentials.
+
+ transportTarget : :py:class:`~pysnmp.entity.rfc3413.oneliner.target.UdpTransportTarget` or :py:class:`~pysnmp.entity.rfc3413.oneliner.target.Udp6TransportTarget`
+ Class instance representing transport type along with SNMP peer address.
+
+ contextData : :py:class:`~pysnmp.entity.rfc3413.oneliner.ctx.ContextData`
+ Class instance representing SNMP ContextEngineId and ContextName values.
+
+ nonRepeaters : int
+ One MIB variable is requested in response for the first
+ `nonRepeaters` MIB variables in request.
+
+ maxRepetitions : int
+ `maxRepetitions` MIB variables are requested in response for each
+ of the remaining MIB variables in the request (e.g. excluding
+ `nonRepeaters`). Remote SNMP engine may choose lesser value than
+ requested.
+
+ *varBinds : :py:class:`~pysnmp.smi.rfc1902.ObjectType`
+ One or more class instances representing MIB variables to place
+ into SNMP request.
+
+ Other Parameters
+ ----------------
+ **options :
+ Request options:
+
+ * `lookupMib` - load MIB and resolve response MIB variables at
+ the cost of slightly reduced performance. Default is `True`.
+ Default is `True`.
+ * `lexicographicMode` - stop iteration when all response MIB
+ variables leave the scope of initial MIB variables in
+ `varBinds`. Default is `True`.
+ * `ignoreNonIncreasingOid` - continue iteration even if response
+ MIB variables (OIDs) are not greater then request MIB variables.
+ Default is `False`.
+ * `maxRows` - stop iteration once this generator instance processed
+ `maxRows` of SNMP conceptual table. Default is `0` (no limit).
+ * `maxCalls` - stop iteration once this generator instance processed
+ `maxCalls` responses. Default is 0 (no limit).
+
+ Yields
+ ------
+ errorIndication : str
+ True value indicates SNMP engine error.
+ errorStatus : str
+ Non-zero value indicates SNMP PDU error.
+ errorIndex : int
+ Non-zero value refers to *varBinds[errorIndex-1]
+ varBinds : tuple
+ A sequence of :py:class:`~pysnmp.smi.rfc1902.ObjectType` class
+ instances representing MIB variables returned in SNMP response.
+
+ Raises
+ ------
+ PySnmpError
+ Or its derivative indicating that an error occurred while
+ performing SNMP operation.
+
+ Notes
+ -----
+ The `bulkCmd` generator will be exhausted on any of the following
+ conditions:
+
+ * SNMP engine error occurs thus `errorIndication` is `True`
+ * SNMP PDU `errorStatus` is reported as `True`
+ * SNMP :py:class:`~pysnmp.proto.rfc1905.EndOfMibView` values
+ (also known as *SNMP exception values*) are reported for all
+ MIB variables in `varBinds`
+ * *lexicographicMode* option is set to `False` and all
+ response MIB variables leave the scope of `varBinds`
+
+ At any moment a new sequence of `varBinds` could be send back into
+ running generator (supported since Python 2.6).
+
+ Setting `maxRepetitions` value to 15..50 might significantly improve
+ system performance, as many MIB variables get packed into a single
+ response message at once.
+
+ Examples
+ --------
+ >>> from pysnmp.entity.rfc3413.oneliner.cmdgen import *
+ >>> g = bulkCmd(SnmpEngine(),
+ ... CommunityData('public'),
+ ... UdpTransportTarget(('demo.snmplabs.com', 161)),
+ ... ContextData(),
+ ... 0, 25,
+ ... ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr')))
+ >>> next(g)
+ (None, 0, 0, [ObjectType(ObjectIdentity(ObjectName('1.3.6.1.2.1.1.1.0')), DisplayString('SunOS zeus.snmplabs.com 4.1.3_U1 1 sun4m'))])
+ >>> g.send( [ ObjectType(ObjectIdentity('IF-MIB', 'ifInOctets')) ] )
+ (None, 0, 0, [(ObjectName('1.3.6.1.2.1.2.2.1.10.1'), Counter32(284817787))])
+ """
+ def cbFun(snmpEngine, sendRequestHandle,
+ errorIndication, errorStatus, errorIndex,
+ varBindTable, cbCtx):
+ cbCtx['errorIndication'] = errorIndication
+ cbCtx['errorStatus'] = errorStatus
+ cbCtx['errorIndex'] = errorIndex
+ cbCtx['varBindTable'] = varBindTable
+
+ lookupMib = options.get('lookupMib', True)
+ lexicographicMode = options.get('lexicographicMode', True)
+ ignoreNonIncreasingOid = options.get('ignoreNonIncreasingOid', False)
+ maxRows = options.get('maxRows', 0)
+ maxCalls = options.get('maxCalls', 0)
+
+ cbCtx = {}
+
+ cmdGen = AsyncCommandGenerator()
+
+ initialVars = [ x[0] for x in cmdGen.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], univ.Null()) for x in varBinds ],
+ (cbFun, cbCtx),
+ lookupMib)
+
+ 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, rfc1905.endOfMibView
+ continue
+ stopFlag = False
+ if isinstance(val, univ.Null):
+ nullVarBinds[j] = True
+ elif not lexicographicMode and \
+ not initialVars[j].isPrefixOf(name):
+ varBindTable[i][j] = name, rfc1905.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
diff --git a/pysnmp/entity/rfc3413/oneliner/sync/compat/__init__.py b/pysnmp/entity/rfc3413/oneliner/sync/compat/__init__.py
new file mode 100644
index 0000000..8c3066b
--- /dev/null
+++ b/pysnmp/entity/rfc3413/oneliner/sync/compat/__init__.py
@@ -0,0 +1 @@
+# This file is necessary to make this directory a package.
diff --git a/pysnmp/entity/rfc3413/oneliner/sync/compat/cmdgen.py b/pysnmp/entity/rfc3413/oneliner/sync/compat/cmdgen.py
new file mode 100644
index 0000000..ebe3296
--- /dev/null
+++ b/pysnmp/entity/rfc3413/oneliner/sync/compat/cmdgen.py
@@ -0,0 +1,256 @@
+from pysnmp.entity.rfc3413.oneliner.cmdgen import *
+
+# Synchronous one-liner SNMP Command Generator apps
+
+if version_info[:2] < (2, 6):
+ def next(iter):
+ return iter.next()
+
+def getCmd(snmpEngine, authData, transportTarget, contextData,
+ *varBinds, **options):
+
+ def cbFun(snmpEngine, sendRequestHandle,
+ errorIndication, errorStatus, errorIndex,
+ varBinds, cbCtx):
+ cbCtx['errorIndication'] = errorIndication
+ cbCtx['errorStatus'] = errorStatus
+ cbCtx['errorIndex'] = errorIndex
+ cbCtx['varBinds'] = varBinds
+
+ cbCtx = {}
+
+ cmdGen = AsyncCommandGenerator()
+
+ if varBinds:
+ cmdGen.getCmd(
+ snmpEngine,
+ authData,
+ transportTarget,
+ contextData,
+ varBinds,
+ (cbFun, cbCtx),
+ 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):
+
+ def cbFun(snmpEngine, sendRequestHandle,
+ errorIndication, errorStatus, errorIndex,
+ varBinds, cbCtx):
+ cbCtx['errorIndication'] = errorIndication
+ cbCtx['errorStatus'] = errorStatus
+ cbCtx['errorIndex'] = errorIndex
+ cbCtx['varBinds'] = varBinds
+
+ cbCtx = {}
+
+ cmdGen = AsyncCommandGenerator()
+
+ while True:
+ cmdGen.setCmd(
+ snmpEngine,
+ authData,
+ transportTarget,
+ contextData,
+ varBinds,
+ (cbFun, cbCtx),
+ 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):
+
+ def cbFun(snmpEngine, sendRequestHandle,
+ errorIndication, errorStatus, errorIndex,
+ varBindTable, cbCtx):
+ cbCtx['errorIndication'] = errorIndication
+ cbCtx['errorStatus'] = errorStatus
+ cbCtx['errorIndex'] = errorIndex
+ cbCtx['varBindTable'] = varBindTable
+
+ lookupMib = options.get('lookupMib', True)
+ lexicographicMode = options.get('lexicographicMode', True)
+ ignoreNonIncreasingOid = options.get('ignoreNonIncreasingOid', False)
+ maxRows = options.get('maxRows', 0)
+ maxCalls = options.get('maxCalls', 0)
+
+ cbCtx = {}
+
+ cmdGen = AsyncCommandGenerator()
+
+ initialVars = [ x[0] for x in cmdGen.makeVarBinds(snmpEngine, varBinds) ]
+
+ totalRows = totalCalls = 0
+
+ while True:
+ cmdGen.nextCmd(snmpEngine,
+ authData,
+ transportTarget,
+ contextData,
+ [ (x[0], univ.Null()) for x in varBinds ],
+ (cbFun, cbCtx),
+ lookupMib)
+
+ 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, univ.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):
+
+ def cbFun(snmpEngine, sendRequestHandle,
+ errorIndication, errorStatus, errorIndex,
+ varBindTable, cbCtx):
+ cbCtx['errorIndication'] = errorIndication
+ cbCtx['errorStatus'] = errorStatus
+ cbCtx['errorIndex'] = errorIndex
+ cbCtx['varBindTable'] = varBindTable
+
+ lookupMib = options.get('lookupMib', True)
+ lexicographicMode = options.get('lexicographicMode', True)
+ ignoreNonIncreasingOid = options.get('ignoreNonIncreasingOid', False)
+ maxRows = options.get('maxRows', 0)
+ maxCalls = options.get('maxCalls', 0)
+
+ cbCtx = {}
+
+ cmdGen = AsyncCommandGenerator()
+
+ initialVars = [ x[0] for x in cmdGen.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], univ.Null()) for x in varBinds ],
+ (cbFun, cbCtx),
+ lookupMib)
+
+ 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, rfc1905.endOfMibView
+ continue
+ stopFlag = False
+ if isinstance(val, univ.Null):
+ nullVarBinds[j] = True
+ elif not lexicographicMode and \
+ not initialVars[j].isPrefixOf(name):
+ varBindTable[i][j] = name, rfc1905.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
diff --git a/pysnmp/entity/rfc3413/oneliner/sync/compat/ntforg.py b/pysnmp/entity/rfc3413/oneliner/sync/compat/ntforg.py
new file mode 100644
index 0000000..7a9291c
--- /dev/null
+++ b/pysnmp/entity/rfc3413/oneliner/sync/compat/ntforg.py
@@ -0,0 +1,48 @@
+from pysnmp.entity.rfc3413.oneliner.ntforg import *
+
+if version_info[:2] < (2, 6):
+ def next(iter):
+ return iter.next()
+
+#
+# Synchronous one-liner SNMP Notification Originator application
+#
+
+def sendNotification(snmpEngine, authData, transportTarget, contextData,
+ notifyType, varBinds, **options):
+
+ def cbFun(snmpEngine, sendRequestHandle,
+ errorIndication, errorStatus, errorIndex,
+ varBinds, cbCtx):
+ cbCtx['errorIndication'] = errorIndication
+ cbCtx['errorStatus'] = errorStatus
+ cbCtx['errorIndex'] = errorIndex
+ cbCtx['varBinds'] = varBinds
+
+ cbCtx = {}
+
+ ntfOrg = AsyncNotificationOriginator()
+
+ if varBinds:
+ ntfOrg.sendNotification(
+ snmpEngine,
+ authData,
+ transportTarget,
+ contextData,
+ notifyType,
+ varBinds,
+ (cbFun, cbCtx),
+ options.get('lookupMib', True)
+ )
+
+ snmpEngine.transportDispatcher.runDispatcher()
+
+ errorIndication = cbCtx.get('errorIndication')
+ errorStatus = cbCtx.get('errorStatus')
+ errorIndex = cbCtx.get('errorIndex')
+ varBinds = cbCtx.get('varBinds', [])
+ else:
+ errorIndication = errorStatus = errorIndex = None
+ varBinds = []
+
+ yield errorIndication, errorStatus, errorIndex, varBinds
diff --git a/pysnmp/entity/rfc3413/oneliner/sync/ntforg.py b/pysnmp/entity/rfc3413/oneliner/sync/ntforg.py
new file mode 100644
index 0000000..16f3930
--- /dev/null
+++ b/pysnmp/entity/rfc3413/oneliner/sync/ntforg.py
@@ -0,0 +1,126 @@
+from pysnmp.entity.rfc3413.oneliner.ntforg import *
+
+if version_info[:2] < (2, 6):
+ def next(iter):
+ return iter.next()
+
+def sendNotification(snmpEngine, authData, transportTarget, contextData,
+ notifyType, varBinds, **options):
+ """Creates a generator to send one or more SNMP notifications.
+
+ On each iteration, new SNMP TRAP or INFORM notification is send
+ (:RFC:`3413#section-3.3`). The iterator blocks waiting for
+ INFORM acknowlegement to arrive or error to occur.
+
+ Parameters
+ ----------
+ snmpEngine : :py:class:`~pysnmp.entity.engine.SnmpEngine`
+ Class instance representing SNMP engine.
+
+ authData : :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.CommunityData` or :py:class:`~pysnmp.entity.rfc3413.oneliner.auth.UsmUserData`
+ Class instance representing SNMP credentials.
+
+ transportTarget : :py:class:`~pysnmp.entity.rfc3413.oneliner.target.UdpTransportTarget` or :py:class:`~pysnmp.entity.rfc3413.oneliner.target.Udp6TransportTarget`
+ Class instance representing transport type along with SNMP peer address.
+
+ contextData : :py:class:`~pysnmp.entity.rfc3413.oneliner.ctx.ContextData`
+ Class instance representing SNMP ContextEngineId and ContextName values.
+
+ notifyType : str
+ Indicates type of notification to be sent. Recognized literal
+ values are *trap* or *inform*.
+
+ varBinds: tuple
+ Single :py:class:`~pysnmp.smi.rfc1902.NotificationType` class instance
+ representing a minimum sequence of MIB variables required for
+ particular notification type.
+ Alternatively, a sequence of :py:class:`~pysnmp.smi.rfc1902.ObjectType`
+ objects could be passed instead. In the latter case it is up to
+ the user to ensure proper Notification PDU contents.
+
+ Other Parameters
+ ----------------
+ **options :
+ Request options:
+
+ * `lookupMib` - load MIB and resolve response MIB variables at
+ the cost of slightly reduced performance. Default is `True`.
+
+ Yields
+ ------
+ errorIndication : str
+ True value indicates SNMP engine error.
+ errorStatus : str
+ Non-zero value indicates SNMP PDU error.
+ errorIndex : int
+ Non-zero value refers to *varBinds[errorIndex-1]
+ varBinds : tuple
+ A sequence of :py:class:`~pysnmp.smi.rfc1902.ObjectType` class
+ instances representing MIB variables returned in SNMP response.
+
+ Raises
+ ------
+ PySnmpError
+ Or its derivative indicating that an error occurred while
+ performing SNMP operation.
+
+ Notes
+ -----
+ The `sendNotification` generator will be exhausted immidiately unless
+ an instance of :py:class:`~pysnmp.smi.rfc1902.NotificationType` class
+ or a sequence of :py:class:`~pysnmp.smi.rfc1902.ObjectType` `varBinds`
+ are send back into running generator (supported since Python 2.6).
+
+ Examples
+ --------
+ >>> from pysnmp.entity.rfc3413.oneliner.ntforg import *
+ >>> g = sendNotification(SnmpEngine(),
+ ... CommunityData('public'),
+ ... UdpTransportTarget(('demo.snmplabs.com', 162)),
+ ... ContextData(),
+ ... 'trap',
+ ... NotificationType(ObjectIdentity('IF-MIB', 'linkDown')))
+ >>> next(g)
+ (None, 0, 0, [])
+ >>>
+
+ """
+ def cbFun(snmpEngine, sendRequestHandle,
+ errorIndication, errorStatus, errorIndex,
+ varBinds, cbCtx):
+ cbCtx['errorIndication'] = errorIndication
+ cbCtx['errorStatus'] = errorStatus
+ cbCtx['errorIndex'] = errorIndex
+ cbCtx['varBinds'] = varBinds
+
+ cbCtx = {}
+
+ ntfOrg = AsyncNotificationOriginator()
+
+ while True:
+ if varBinds:
+ ntfOrg.sendNotification(
+ snmpEngine,
+ authData,
+ transportTarget,
+ contextData,
+ notifyType,
+ varBinds,
+ cbInfo=(cbFun, cbCtx),
+ lookupMib=options.get('lookupMib', True)
+ )
+
+ snmpEngine.transportDispatcher.runDispatcher()
+
+ errorIndication = cbCtx.get('errorIndication')
+ errorStatus = cbCtx.get('errorStatus')
+ errorIndex = cbCtx.get('errorIndex')
+ varBinds = cbCtx.get('varBinds', [])
+ else:
+ errorIndication = errorStatus = errorIndex = None
+ varBinds = []
+
+ varBinds = ( yield errorIndication, errorStatus, errorIndex, varBinds )
+
+ if not varBinds:
+ break
diff --git a/pysnmp/entity/rfc3413/oneliner/target.py b/pysnmp/entity/rfc3413/oneliner/target.py
index 04ecb5f..ecb7882 100644
--- a/pysnmp/entity/rfc3413/oneliner/target.py
+++ b/pysnmp/entity/rfc3413/oneliner/target.py
@@ -37,6 +37,42 @@ class _AbstractTransportTarget:
def _resolveAddr(self, transportAddr): raise NotImplementedError()
class UdpTransportTarget(_AbstractTransportTarget):
+ """Creates UDP/IPv4 configuration entry and initialize socket API if needed.
+
+ This object can be used by
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.cmdgen.AsyncCommandGenerator` or
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.ntforg.AsyncNotificationOriginator`
+ and their derevatives for adding new entries to Local Configuration
+ Datastore (LCD) managed by :py:class:`~pysnmp.entity.engine.SnmpEngine`
+ class instance.
+
+ See :RFC:`1906#section-3` for more information on the UDP transport mapping.
+
+ Parameters
+ ----------
+ transportAddr : tuple
+ Indicates remote address in Python :py:mod:`socket` module format
+ which is a tuple of FQDN, port where FQDN is a string representing
+ either hostname or IPv4 address in quad-dotted form, port is an
+ integer.
+ timeout : int
+ Response timeout in seconds.
+ retries : int
+ Maximum number of request retries, 0 retries means just a single
+ request.
+ tagList : str
+ Arbitrary string that contains a list of tag values which are used
+ to select target addresses for a particular operation
+ (:RFC:`3413#section-4.1.4`).
+
+ Examples
+ --------
+ >>> from pysnmp.entity.rfc3413.oneliner.target import UdpTransportTarget
+ >>> UdpTransportTarget(('demo.snmplabs.com', 161))
+ UdpTransportTarget(('195.218.195.228', 161), timeout=1, retries=5, tagList='')
+ >>>
+
+ """
transportDomain = udp.domainName
protoTransport = udp.UdpSocketTransport
def _resolveAddr(self, transportAddr):
@@ -50,6 +86,51 @@ class UdpTransportTarget(_AbstractTransportTarget):
raise error.PySnmpError('Bad IPv4/UDP transport address %s: %s' % ('@'.join([ str(x) for x in transportAddr ]), sys.exc_info()[1]))
class Udp6TransportTarget(_AbstractTransportTarget):
+ """Creates UDP/IPv6 configuration entry and initialize socket API if needed.
+
+ This object can be used by
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.cmdgen.AsyncCommandGenerator` or
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.ntforg.AsyncNotificationOriginator`
+ and their derevatives for adding new entries to Local Configuration
+ Datastore (LCD) managed by :py:class:`~pysnmp.entity.engine.SnmpEngine`
+ class instance.
+
+ See :RFC:`1906#section-3`, :RFC:`2851#section-4` for more information
+ on the UDP and IPv6 transport mapping.
+
+ Parameters
+ ----------
+ transportAddr : tuple
+ Indicates remote address in Python :py:mod:`socket` module format
+ which is a tuple of FQDN, port where FQDN is a string representing
+ either hostname or IPv6 address in one of three conventional forms
+ (:RFC:`1924#section-3`), port is an integer.
+ timeout : int
+ Response timeout in seconds.
+ retries : int
+ Maximum number of request retries, 0 retries means just a single
+ request.
+ tagList : str
+ Arbitrary string that contains a list of tag values which are used
+ to select target addresses for a particular operation
+ (:RFC:`3413#section-4.1.4`).
+
+ Examples
+ --------
+ >>> from pysnmp.entity.rfc3413.oneliner.target import Udp6TransportTarget
+ >>> Udp6TransportTarget(('google.com', 161))
+ Udp6TransportTarget(('2a00:1450:4014:80a::100e', 161), timeout=1, retries=5, tagList='')
+ >>> Udp6TransportTarget(('FEDC:BA98:7654:3210:FEDC:BA98:7654:3210', 161))
+ Udp6TransportTarget(('fedc:ba98:7654:3210:fedc:ba98:7654:3210', 161), timeout=1, retries=5, tagList='')
+ >>> Udp6TransportTarget(('1080:0:0:0:8:800:200C:417A', 161))
+ Udp6TransportTarget(('1080::8:800:200c:417a', 161), timeout=1, retries=5, tagList='')
+ >>> Udp6TransportTarget(('::0', 161))
+ Udp6TransportTarget(('::', 161), timeout=1, retries=5, tagList='')
+ >>> Udp6TransportTarget(('::', 161))
+ Udp6TransportTarget(('::', 161), timeout=1, retries=5, tagList='')
+ >>>
+
+ """
transportDomain = udp6.domainName
protoTransport = udp6.Udp6SocketTransport
def _resolveAddr(self, transportAddr):
diff --git a/pysnmp/smi/rfc1902.py b/pysnmp/smi/rfc1902.py
index 8d66f25..b61f5a0 100644
--- a/pysnmp/smi/rfc1902.py
+++ b/pysnmp/smi/rfc1902.py
@@ -8,17 +8,83 @@ from pyasn1.type.base import AbstractSimpleAsn1Item
from pyasn1.error import PyAsn1Error
from pysnmp import debug
-#
-# An OID-like object that embeds MIB resolution.
-#
-# Valid initializers include:
-# ObjectIdentity('1.3.6.1.2.1.1.1.0')
-# ObjectIdentity('iso.org.dod.internet.mgmt.mib-2.system.sysDescr.0')
-# ObjectIdentity('SNMPv2-MIB', 'system')
-# ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)
-# ObjectIdentity('IP-MIB', 'ipAdEntAddr', '127.0.0.1', 123)
-#
+# expose SNMP types in this namespace for convenience
+Integer = rfc1902.Integer
+Integer32 = rfc1902.Integer32
+OctetString = rfc1902.OctetString
+ObjectIdentifier = rfc1902.ObjectIdentifier
+IpAddress = rfc1902.IpAddress
+Counter32 = rfc1902.Counter32
+Gauge32 = rfc1902.Gauge32
+Unsigned32 = rfc1902.Unsigned32
+TimeTicks = rfc1902.TimeTicks
+Opaque = rfc1902.Opaque
+Counter64 = rfc1902.Counter64
+Bits = rfc1902.Bits
+ObjectName = rfc1902.ObjectName
+
class ObjectIdentity:
+ """Create an object representing MIB variable ID.
+
+ At the protocol level, MIB variable is only identified by an OID.
+ However, when interacting with humans, MIB variable can also be referred
+ to by its MIB name. The *ObjectIdentity* class supports various forms
+ of MIB variable identification, providing automatic conversion from
+ one to others. At the same time *ObjectIdentity* objects behave like
+ :py:obj:`tuples` of py:obj:`int` sub-OIDs.
+
+ See :RFC:`1902#section-2` for more information on OBJECT-IDENTITY
+ SMI definitions.
+
+ Parameters
+ ----------
+ args
+ initial MIB variable identity. Recognized variants:
+
+ * single :py:obj:`tuple` or integers representing OID
+ * single :py:obj:`str` representing OID in dot-separated
+ integers form
+ * single :py:obj:`str` representing MIB variable in
+ dot-separated labels form
+ * single :py:obj:`str` representing MIB name. First variable
+ defined in MIB is assumed.
+ * pair of :py:obj:`str` representing MIB name and variable name
+ * pair of :py:obj:`str` representing MIB name and variable name
+ followed by an arbitrary number of :py:obj:`str` and/or
+ :py:obj:`int` values representing MIB variable instance
+ identification.
+
+ Other parameters
+ ----------------
+ kwargs
+ MIB resolution options:
+
+ * whenever only MIB name is given, resolve into last variable defined
+ in MIB if last=True. Otherwise resolves to first variable (default).
+
+ Notes
+ -----
+ Actual conversion between MIB variable representation formats occurs
+ upon :py:meth:`~pysnmp.smi.rfc1902.ObjectIdentity.resolveWithMib`
+ invocation.
+
+ Examples
+ --------
+ >>> from pysnmp.smi.rfc1902 import ObjectIdentity
+ >>> ObjectIdentity((1, 3, 6, 1, 2, 1, 1, 1, 0))
+ ObjectIdentity((1, 3, 6, 1, 2, 1, 1, 1, 0))
+ >>> ObjectIdentity('1.3.6.1.2.1.1.1.0')
+ ObjectIdentity('1.3.6.1.2.1.1.1.0')
+ >>> ObjectIdentity('iso.org.dod.internet.mgmt.mib-2.system.sysDescr.0')
+ ObjectIdentity('iso.org.dod.internet.mgmt.mib-2.system.sysDescr.0')
+ >>> ObjectIdentity('SNMPv2-MIB', 'system')
+ ObjectIdentity('SNMPv2-MIB', 'system')
+ >>> ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)
+ ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)
+ >>> ObjectIdentity('IP-MIB', 'ipAdEntAddr', '127.0.0.1', 123)
+ ObjectIdentity('IP-MIB', 'ipAdEntAddr', '127.0.0.1', 123)
+
+ """
stDirty, stClean = 1, 2
def __init__(self, *args, **kwargs):
@@ -28,22 +94,95 @@ class ObjectIdentity:
self.__asn1SourcesToAdd = self.__asn1SourcesOptions = None
self.__state = self.stDirty
- #
- # public API
- #
def getMibSymbol(self):
+ """Returns MIB variable symbolic identification.
+
+ Returns
+ -------
+ str
+ MIB module name
+ str
+ MIB variable symbolic name
+ : :py:class:`~pysnmp.proto.rfc1902.ObjectName`
+ class instance representing MIB variable instance index.
+
+ Raises
+ ------
+ SmiError
+ If MIB variable conversion has not been performed.
+
+ Examples
+ --------
+ >>> objectIdentity = ObjectIdentity('1.3.6.1.2.1.1.1.0')
+ >>> objectIdentity.resolveWithMib(mibViewController)
+ >>> objectIdentity.getMibSymbol()
+ ('SNMPv2-MIB', 'sysDescr', (0,))
+ >>>
+
+ """
if self.__state & self.stClean:
return self.__modName, self.__symName, self.__indices
else:
raise SmiError('%s object not fully initialized' % self.__class__.__name__)
def getOid(self):
+ """Returns OID identifying MIB variable.
+
+ Returns
+ -------
+ : :py:class:`~pysnmp.proto.rfc1902.ObjectName`
+ full OID identifying MIB variable including possible index part.
+
+ Raises
+ ------
+ SmiError
+ If MIB variable conversion has not been performed.
+
+ Examples
+ --------
+ >>> objectIdentity = ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)
+ >>> objectIdentity.resolveWithMib(mibViewController)
+ >>> objectIdentity.getOid()
+ ObjectName('1.3.6.1.2.1.1.1.0')
+ >>>
+
+ """
if self.__state & self.stClean:
return self.__oid
else:
raise SmiError('%s object not fully initialized' % self.__class__.__name__)
def getLabel(self):
+ """Returns symbolic path to this MIB variable.
+
+ Meaning a sequence of symbolic identifications for each of parent
+ MIB objects in MIB tree.
+
+ Returns
+ -------
+ tuple
+ sequence of names of nodes in a MIB tree from the top of the tree
+ towards this MIB variable.
+
+ Raises
+ ------
+ SmiError
+ If MIB variable conversion has not been performed.
+
+ Notes
+ -----
+ Returned sequence may not contain full path to this MIB variable
+ if some symbols are now known at the moment of MIB look up.
+
+ Examples
+ --------
+ >>> objectIdentity = ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)
+ >>> objectIdentity.resolveWithMib(mibViewController)
+ >>> objectIdentity.getOid()
+ ('iso', 'org', 'dod', 'internet', 'mgmt', 'mib-2', 'system', 'sysDescr')
+ >>>
+
+ """
if self.__state & self.stClean:
return self.__label
else:
@@ -63,6 +202,35 @@ class ObjectIdentity:
#
def addAsn1MibSource(self, *asn1Sources, **kwargs):
+ """Adds path to a repository to search ASN.1 MIB files.
+
+ Parameters
+ ----------
+ *asn1Sources :
+ one or more URL in form of :py:obj:`str` identifying local or
+ remote ASN.1 MIB repositories. Path must include the *@mib@*
+ component which will be replaced with MIB module name at the
+ time of search.
+
+ Returns
+ -------
+ : :py:class:`~pysnmp.smi.rfc1902.ObjectIdentity`
+ reference to itself
+
+ Notes
+ -----
+ Please refer to :py:class:`~pysmi.reader.localfile.FileReader`,
+ :py:class:`~pysmi.reader.httpclient.HttpReader` and
+ :py:class:`~pysmi.reader.ftpclient.FtpReader` classes for
+ in-depth information on ASN.1 MIB lookup.
+
+ Examples
+ --------
+ >>> ObjectIdentity('SNMPv2-MIB', 'sysDescr').addAsn1Source('http://mibs.snmplabs.com/asn1/@mib@')
+ ObjectIdentity('SNMPv2-MIB', 'sysDescr')
+ >>>
+
+ """
if self.__asn1SourcesToAdd is None:
self.__asn1SourcesToAdd = asn1Sources
else:
@@ -91,6 +259,47 @@ class ObjectIdentity:
# this would eventually be called by an entity which posses a
# reference to MibViewController
def resolveWithMib(self, mibViewController):
+ """Perform MIB variable ID conversion.
+
+ Parameters
+ ----------
+ mibViewController : :py:class:`~pysnmp.smi.view.MibViewController`
+ class instance representing MIB browsing functionality.
+
+ Returns
+ -------
+ : :py:class:`~pysnmp.smi.rfc1902.ObjectIdentity`
+ reference to itself
+
+ Raises
+ ------
+ SmiError
+ In case of fatal MIB hanling errora
+
+ Notes
+ -----
+ Calling this method might cause the following sequence of
+ events (exact details depends on many factors):
+
+ * ASN.1 MIB file downloaded and handed over to
+ :py:class:`~pysmi.compiler.MibCompiler` for conversion into
+ Python MIB module (based on pysnmp classes)
+ * Python MIB module is imported by SNMP engine, internal indices
+ created
+ * :py:class:`~pysnmp.smi.view.MibViewController` looks up the
+ rest of MIB identification information based on whatever information
+ is already available, :py:class:`~pysnmp.smi.rfc1902.ObjectIdentity`
+ class instance
+ gets updated and ready for further use.
+
+ Examples
+ --------
+ >>> objectIdentity = ObjectIdentity('SNMPv2-MIB', 'sysDescr')
+ >>> objectIdentity.resolveWithMib(mibViewController)
+ ObjectIdentity('SNMPv2-MIB', 'sysDescr')
+ >>>
+
+ """
if self.__mibSourcesToAdd is not None:
debug.logger & debug.flagMIB and debug.logger('adding MIB sources %s' % ', '.join(self.__mibSourcesToAdd))
mibViewController.mibBuilder.addMibSources(
@@ -374,6 +583,63 @@ class ObjectIdentity:
# A two-element sequence of ObjectIdentity and SNMP data type object
class ObjectType:
+ """Create an object representing MIB variable.
+
+ Instances of :py:class:`~pysnmp.smi.rfc1902.ObjectType` class are
+ containters incorporating :py:class:`~pysnmp.smi.rfc1902.ObjectIdentity`
+ class instance (identifying MIB variable) and optional value belonging
+ to one of SNMP types (:RFC:`1902`).
+
+ Typical MIB variable is defined like this (from *SNMPv2-MIB.txt*):
+
+ .. code-block:: bash
+
+ sysDescr OBJECT-TYPE
+ SYNTAX DisplayString (SIZE (0..255))
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "A textual description of the entity. This value should..."
+ ::= { system 1 }
+
+ Corresponding ObjectType instantiation would look like this:
+
+ .. code-block:: python
+
+ ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr'), 'Linux i386 box')
+
+ In order to behave like SNMP variable-binding (:RFC:`1157#section-4.1.1`),
+ :py:class:`~pysnmp.smi.rfc1902.ObjectType` objects also support
+ sequence protocol addressing `objectIdentity` as its 0-th element
+ and `objectSyntax` as 1-st.
+
+ See :RFC:`1902#section-2` for more information on OBJECT-TYPE SMI
+ definitions.
+
+ Parameters
+ ----------
+ objectIdentity : :py:class:`~pysnmp.smi.rfc1902.ObjectIdentity`
+ Class instance representing MIB variable identification.
+ objectSyntax :
+ Represents a value associated with this MIB variable. Values of
+ built-in Python types will be automatically converted into SNMP
+ object as specified in OBJECT-TYPE->SYNTAX field.
+
+ Notes
+ -----
+ Actual conversion between MIB variable representation formats occurs
+ upon :py:meth:`~pysnmp.smi.rfc1902.ObjectType.resolveWithMib`
+ invocation.
+
+ Examples
+ --------
+ >>> from pysnmp.smi.rfc1902 import *
+ >>> ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0'))
+ ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0'), Null())
+ >>> ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0), 'Linux i386')
+ ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0), 'Linux i386')
+
+ """
stDirty, stClean = 1, 2
def __init__(self, objectIdentity, objectSyntax=rfc1905.unSpecified):
if not isinstance(objectIdentity, ObjectIdentity):
@@ -387,6 +653,9 @@ class ObjectType:
else:
raise SmiError('%s object not fully initialized' % self.__class__.__name__)
+ def __str__(self):
+ return self.prettyPrint()
+
def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, ', '.join([ repr(x) for x in self.__args]))
@@ -394,6 +663,39 @@ class ObjectType:
return self.__state & self.stClean
def resolveWithMib(self, mibViewController):
+ """Perform MIB variable ID and associated value conversion.
+
+ Parameters
+ ----------
+ mibViewController : :py:class:`~pysnmp.smi.view.MibViewController`
+ class instance representing MIB browsing functionality.
+
+ Returns
+ -------
+ : :py:class:`~pysnmp.smi.rfc1902.ObjectType`
+ reference to itself
+
+ Raises
+ ------
+ SmiError
+ In case of fatal MIB hanling errora
+
+ Notes
+ -----
+ Calling this method involves
+ :py:meth:`~pysnmp.smi.rfc1902.ObjectIdentity.resolveWithMib`
+ method invocation.
+
+ Examples
+ --------
+ >>> objectType = ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr'), 'Linux i386')
+ >>> objectType.resolveWithMib(mibViewController)
+ ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr'), DisplayString('Linux i386'))
+ >>> str(objectType)
+ 'SNMPv2-MIB::sysDescr."0" = Linux i386'
+ >>>
+
+ """
if self.__state & self.stClean:
return self
@@ -433,8 +735,71 @@ class ObjectType:
else:
raise SmiError('%s object not fully initialized' % self.__class__.__name__)
-# A sequence of ObjectType's
class NotificationType:
+ """Create an object representing SNMP Notification.
+
+ Instances of :py:class:`~pysnmp.smi.rfc1902.NotificationType` class are
+ containters incorporating :py:class:`~pysnmp.smi.rfc1902.ObjectIdentity`
+ class instance (identifying particular notification) and a collection
+ of MIB variables IDs that
+ :py:class:`~pysnmp.entity.rfc3413.oneliner.cmdgen.NotificationOriginator`
+ should gather and put into notification message.
+
+ Typical notification is defined like this (from *IF-MIB.txt*):
+
+ .. code-block:: bash
+
+ linkDown NOTIFICATION-TYPE
+ OBJECTS { ifIndex, ifAdminStatus, ifOperStatus }
+ STATUS current
+ DESCRIPTION
+ "A linkDown trap signifies that the SNMP entity..."
+ ::= { snmpTraps 3 }
+
+ Corresponding NotificationType instantiation would look like this:
+
+ .. code-block:: python
+
+ NotificationType(ObjectIdentity('IF-MIB', 'linkDown'))
+
+ To retain similarity with SNMP variable-bindings,
+ :py:class:`~pysnmp.smi.rfc1902.NotificationType` objects behave like
+ a sequence of :py:class:`~pysnmp.smi.rfc1902.ObjectType` class
+ instances.
+
+ See :RFC:`1902#section-2` for more information on NOTIFICATION-TYPE SMI
+ definitions.
+
+ Parameters
+ ----------
+ objectIdentity : :py:class:`~pysnmp.smi.rfc1902.ObjectIdentity`
+ Class instance representing MIB notification type identification.
+ instanceIndex : :py:class:`~pysnmp.proto.rfc1902.ObjectName`
+ Trailing part of MIB variables OID identification that represents
+ concrete instance of a MIB variable. When notification is prepared,
+ `instanceIndex` is appended to each MIB variable identification
+ listed in NOTIFICATION-TYPE->OBJECTS clause.
+ objects : dict
+ Dictionary-like object that may return values by OID key. The
+ `objects` dictionary is consulted when notification is being
+ prepared. OIDs are taken from MIB variables listed in
+ NOTIFICATION-TYPE->OBJECTS with `instanceIndex` part appended.
+
+ Notes
+ -----
+ Actual notification type and MIB variables look up occurs
+ upon :py:meth:`~pysnmp.smi.rfc1902.NotificationType.resolveWithMib`
+ invocation.
+
+ Examples
+ --------
+ >>> from pysnmp.smi.rfc1902 import *
+ >>> NotificationType(ObjectIdentity('1.3.6.1.6.3.1.1.5.3'))
+ NotificationType(ObjectIdentity('1.3.6.1.6.3.1.1.5.3'), (), {})
+ >>> NotificationType(ObjectIdentity('IP-MIB', 'linkDown'), ObjectName('3.5))
+ NotificationType(ObjectIdentity('1.3.6.1.6.3.1.1.5.3'), ObjectName('3.5'), {})
+
+ """
stDirty, stClean = 1, 2
def __init__(self, objectIdentity, instanceIndex=(), objects={}):
if not isinstance(objectIdentity, ObjectIdentity):
@@ -456,6 +821,33 @@ class NotificationType:
return '%s(%r, %r, %r)' % (self.__class__.__name__, self.__objectIdentity, self.__instanceIndex, self.__objects)
def addVarBinds(self, *varBinds):
+ """Appends variable-binding to notification.
+
+ Parameters
+ ----------
+ *varBinds : :py:class:`~pysnmp.smi.rfc1902.ObjectType`
+ One or more :py:class:`~pysnmp.smi.rfc1902.ObjectType` class
+ instances.
+
+ Returns
+ -------
+ : :py:class:`~pysnmp.smi.rfc1902.NotificationType`
+ reference to itself
+
+ Notes
+ -----
+ This method can be used to add custom variable-bindings to
+ notification message in addition to MIB variables specified
+ in NOTIFICATION-TYPE->OBJECTS clause.
+
+ Examples
+ --------
+ >>> nt = NotificationType(ObjectIdentity('IP-MIB', 'linkDown'))
+ >>> nt.addVarBinds(ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)))
+ NotificationType(ObjectIdentity('IP-MIB', 'linkDown'), (), {})
+ >>>
+
+ """
debug.logger & debug.flagMIB and debug.logger('additional var-binds: %r' % (varBinds,))
if self.__state & self.stClean:
self.__varBinds.extend(varBinds)
@@ -467,6 +859,43 @@ class NotificationType:
return self.__state & self.stClean
def resolveWithMib(self, mibViewController):
+ """Perform MIB variable ID conversion and notification objects expansion.
+
+ Parameters
+ ----------
+ mibViewController : :py:class:`~pysnmp.smi.view.MibViewController`
+ class instance representing MIB browsing functionality.
+
+ Returns
+ -------
+ : :py:class:`~pysnmp.smi.rfc1902.NotificationType`
+ reference to itself
+
+ Raises
+ ------
+ SmiError
+ In case of fatal MIB hanling errora
+
+ Notes
+ -----
+ Calling this method might cause the following sequence of
+ events (exact details depends on many factors):
+
+ * :py:meth:`pysnmp.smi.rfc1902.ObjectIdentity.resolveWithMib` is called
+ * MIB variables names are read from NOTIFICATION-TYPE->OBJECTS clause,
+ :py:class:`~pysnmp.smi.rfc1902.ObjectType` instances are created
+ from MIB variable OID and `indexInstance` suffix.
+ * `objects` dictionary is queried for each MIB variable OID,
+ acquired values are added to corresponding MIB variable
+
+ Examples
+ --------
+ >>> notificationType = NotificationType(ObjectIdentity('IF-MIB', 'linkDown'))
+ >>> notificationType.resolveWithMib(mibViewController)
+ NotificationType(ObjectIdentity('IF-MIB', 'linkDown'), (), {})
+ >>>
+
+ """
if self.__state & self.stClean:
return self