diff options
Diffstat (limited to 'pysnmp/entity')
-rw-r--r-- | pysnmp/entity/rfc3413/oneliner/auth.py | 126 | ||||
-rw-r--r-- | pysnmp/entity/rfc3413/oneliner/cmdgen.py | 313 | ||||
-rw-r--r-- | pysnmp/entity/rfc3413/oneliner/ctx.py | 35 | ||||
-rw-r--r-- | pysnmp/entity/rfc3413/oneliner/ntforg.py | 91 | ||||
-rw-r--r-- | pysnmp/entity/rfc3413/oneliner/sync/__init__.py | 1 | ||||
-rw-r--r-- | pysnmp/entity/rfc3413/oneliner/sync/cmdgen.py | 602 | ||||
-rw-r--r-- | pysnmp/entity/rfc3413/oneliner/sync/compat/__init__.py | 1 | ||||
-rw-r--r-- | pysnmp/entity/rfc3413/oneliner/sync/compat/cmdgen.py | 256 | ||||
-rw-r--r-- | pysnmp/entity/rfc3413/oneliner/sync/compat/ntforg.py | 48 | ||||
-rw-r--r-- | pysnmp/entity/rfc3413/oneliner/sync/ntforg.py | 126 | ||||
-rw-r--r-- | pysnmp/entity/rfc3413/oneliner/target.py | 81 |
11 files changed, 1338 insertions, 342 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): |