diff options
author | elie <elie> | 2009-07-31 19:55:03 +0000 |
---|---|---|
committer | elie <elie> | 2009-07-31 19:55:03 +0000 |
commit | 35ab3f1b8534b1d99b5163e9f2ea0f9552de21f4 (patch) | |
tree | f631e241745feae906aa4c13839c0e6ce9aa7375 | |
parent | 0d5efc682b4f7b6ce7775d97e3b5f38b83590d60 (diff) | |
download | pysnmp-35ab3f1b8534b1d99b5163e9f2ea0f9552de21f4.tar.gz |
Twisted support implemented
-rw-r--r-- | THANKS | 1 | ||||
-rw-r--r-- | examples/v3arch/twisted/agent/ntforg.py | 88 | ||||
-rw-r--r-- | examples/v3arch/twisted/manager/bulkgen.py | 73 | ||||
-rw-r--r-- | examples/v3arch/twisted/manager/getgen.py | 62 | ||||
-rw-r--r-- | examples/v3arch/twisted/manager/nextgen.py | 73 | ||||
-rw-r--r-- | examples/v3arch/twisted/manager/ntfrcv.py | 48 | ||||
-rw-r--r-- | examples/v3arch/twisted/manager/setgen.py | 64 | ||||
-rw-r--r-- | pysnmp/carrier/twisted/__init__.py | 0 | ||||
-rw-r--r-- | pysnmp/carrier/twisted/base.py | 26 | ||||
-rw-r--r-- | pysnmp/carrier/twisted/dgram/__init__.py | 0 | ||||
-rw-r--r-- | pysnmp/carrier/twisted/dgram/base.py | 44 | ||||
-rw-r--r-- | pysnmp/carrier/twisted/dgram/udp.py | 25 | ||||
-rw-r--r-- | pysnmp/carrier/twisted/dgram/unix.py | 26 | ||||
-rw-r--r-- | pysnmp/carrier/twisted/dispatch.py | 53 | ||||
-rw-r--r-- | pysnmp/entity/rfc3413/twisted/__init__.py | 0 | ||||
-rw-r--r-- | pysnmp/entity/rfc3413/twisted/cmdgen.py | 202 | ||||
-rw-r--r-- | pysnmp/entity/rfc3413/twisted/ntforg.py | 32 | ||||
-rw-r--r-- | setup.py | 3 |
18 files changed, 820 insertions, 0 deletions
@@ -22,6 +22,7 @@ Ivan Zderadicka Randy Couey Brian Kyckelhahn Mark M Evans +Filippo Giunchedi at Truelite Srl Thanks to Python Software Foundation for granting financial support for the project. diff --git a/examples/v3arch/twisted/agent/ntforg.py b/examples/v3arch/twisted/agent/ntforg.py new file mode 100644 index 0000000..77df949 --- /dev/null +++ b/examples/v3arch/twisted/agent/ntforg.py @@ -0,0 +1,88 @@ +# Notification originator +from twisted.internet import reactor +from pysnmp.entity import engine, config +from pysnmp.carrier.twisted import dispatch +from pysnmp.carrier.twisted.dgram import udp +from pysnmp.entity.rfc3413 import context +from pysnmp.entity.rfc3413.twisted import ntforg +from pysnmp.proto.api import v2c + +# Send either Teap or Inform request +doInform = 1 + +snmpEngine = engine.SnmpEngine() + +# Set Twisted dispatcher +snmpEngine.registerTransportDispatcher(dispatch.TwistedDispatcher()) + +# v1/2 setup +config.addV1System(snmpEngine, 'test-agent', 'public') + +# v3 setup +config.addV3User( + snmpEngine, 'test-user', + config.usmHMACMD5AuthProtocol, 'authkey1', + config.usmDESPrivProtocol, 'privkey1' + ) + +# Transport params +config.addTargetParams(snmpEngine, 'myParams', 'test-user', 'authPriv') +#config.addTargetParams(snmpEngine, 'myParams', 'test-agent', 'noAuthNoPriv', 1) + +# Transport addresses +config.addTargetAddr( + snmpEngine, 'myNMS', config.snmpUDPDomain, + ('127.0.0.1', 162), 'myParams', tagList='myManagementStations' + ) + +# Notification targets +if doInform: + config.addNotificationTarget( + snmpEngine, 'myNotifyName', 'myParams','myManagementStations','inform' + ) +else: + config.addNotificationTarget( + snmpEngine, 'myNotifyName', 'myParams', 'myManagementStations', 'trap' + ) + +# Transport +config.addSocketTransport( + snmpEngine, + udp.domainName, + udp.UdpTwistedTransport().openClientMode() + ) + +# Agent-side VACM setup +config.addContext(snmpEngine, '') +config.addVacmUser(snmpEngine, 1, 'test-agent', 'noAuthNoPriv', + (), (), (1,3,6)) # v1 +config.addVacmUser(snmpEngine, 2, 'test-agent', 'noAuthNoPriv', + (), (), (1,3,6)) # v2c +config.addVacmUser(snmpEngine, 3, 'test-user', 'authPriv', + (), (), (1,3,6)) # v3 + +# SNMP context +snmpContext = context.SnmpContext(snmpEngine) + +# Twisted API follows + +def receiveResponse((sendRequestHandle, errorIndication)): + if errorIndication: + print 'Error: ', errorIndication + reactor.stop() + +ntfOrg = ntforg.NotificationOriginator(snmpContext) + +df = ntfOrg.sendNotification( + snmpEngine, + # Notification targets + 'myNotifyName', + # Trap OID (SNMPv2-MIB::coldStart) + (1,3,6,1,6,3,1,1,5,1), + # ((oid, value), ... ) + (((1,3,6,1,2,1,1,5), v2c.OctetString('Example Notificator')),) + ) + +if doInform: + df.addCallback(receiveResponse) + reactor.run() diff --git a/examples/v3arch/twisted/manager/bulkgen.py b/examples/v3arch/twisted/manager/bulkgen.py new file mode 100644 index 0000000..96201ac --- /dev/null +++ b/examples/v3arch/twisted/manager/bulkgen.py @@ -0,0 +1,73 @@ +# BULK Command Generator +from twisted.internet import reactor, defer +from pysnmp.entity import engine, config +from pysnmp.carrier.twisted import dispatch +from pysnmp.carrier.twisted.dgram import udp +from pysnmp.entity.rfc3413.twisted import cmdgen + +snmpEngine = engine.SnmpEngine() + +# Set Twisted dispatcher +snmpEngine.registerTransportDispatcher(dispatch.TwistedDispatcher()) + +# v1/2 setup +config.addV1System(snmpEngine, 'test-agent', 'public') + +# v3 setup +config.addV3User( + snmpEngine, 'test-user', + config.usmHMACMD5AuthProtocol, 'authkey1', + config.usmDESPrivProtocol, 'privkey1' + ) + +# Transport params +config.addTargetParams(snmpEngine, 'myParams', 'test-user', 'authPriv') +#config.addTargetParams(snmpEngine, 'myParams', 'test-agent', 'noAuthNoPriv', 1) + +# Transport addresses +config.addTargetAddr( + snmpEngine, 'myRouter', config.snmpUDPDomain, + ('127.0.0.1', 161), 'myParams' + ) + +# Transport +config.addSocketTransport( + snmpEngine, + udp.domainName, + udp.UdpTwistedTransport().openClientMode() + ) + +# Twisted API follows + +def receiveResponse( + (errorIndication, errorStatus, errorIndex, varBindTable), + bulkCmdGen, snmpEngine): + if errorIndication or errorStatus: + print 'Error: ', errorIndication, errorStatus.prettyPrint(), errorIndex + reactor.stop() + return + for varBindRow in varBindTable: + for oid, val in varBindRow: + if val is None: + print oid.prettyPrint() + else: + print '%s = %s' % (oid.prettyPrint(), val.prettyPrint()) + for oid, val in varBindTable[-1]: + if val is not None: + df = bulkCmdGen.sendReq( + snmpEngine, 'myRouter', 0, 25, varBindTable[-1] + ) + df.addCallback(receiveResponse, bulkCmdGen, snmpEngine) + return + else: + reactor.stop() + +bulkCmdGen = cmdgen.BulkCommandGenerator() + +df = bulkCmdGen.sendReq( + snmpEngine, 'myRouter', 0, 25, (((1,3,6,1,2), None),) + ) + +df.addCallback(receiveResponse, bulkCmdGen, snmpEngine) + +reactor.run() diff --git a/examples/v3arch/twisted/manager/getgen.py b/examples/v3arch/twisted/manager/getgen.py new file mode 100644 index 0000000..a2cb9a4 --- /dev/null +++ b/examples/v3arch/twisted/manager/getgen.py @@ -0,0 +1,62 @@ +# GET Command Generator +from twisted.internet import reactor, defer +from pysnmp.entity import engine, config +from pysnmp.carrier.twisted import dispatch +from pysnmp.carrier.twisted.dgram import udp +from pysnmp.entity.rfc3413.twisted import cmdgen + +snmpEngine = engine.SnmpEngine() + +# Set Twisted dispatcher +snmpEngine.registerTransportDispatcher(dispatch.TwistedDispatcher()) + +# v1/2 setup +config.addV1System(snmpEngine, 'test-agent', 'public') + +# v3 setup +config.addV3User( + snmpEngine, 'test-user', + config.usmHMACMD5AuthProtocol, 'authkey1', + config.usmDESPrivProtocol, 'privkey1' + ) + +# Transport params +config.addTargetParams(snmpEngine, 'myParams', 'test-user', 'authPriv') +#config.addTargetParams(snmpEngine, 'myParams', 'test-agent', 'noAuthNoPriv', 1) + +# Transport addresses +config.addTargetAddr( + snmpEngine, 'myRouter', config.snmpUDPDomain, + ('127.0.0.1', 161), 'myParams' + ) + +# Transport +config.addSocketTransport( + snmpEngine, + udp.domainName, + udp.UdpTwistedTransport().openClientMode() + ) + +# Twisted API follows + +def receiveResponse((errorIndication, errorStatus, errorIndex, varBinds)): + if errorIndication or errorStatus: + print 'Error: ', errorIndication, errorStatus.prettyPrint(), errorIndex + reactor.stop() + return + for oid, val in varBinds: + if val is None: + print oid.prettyPrint() + else: + print '%s = %s' % (oid.prettyPrint(), val.prettyPrint()) + reactor.stop() + +getCmdGen = cmdgen.GetCommandGenerator() + +df = getCmdGen.sendReq( + snmpEngine, 'myRouter', (((1,3,6,1,2,1,1,1,0), None),) + ) + +df.addCallback(receiveResponse) + +reactor.run() diff --git a/examples/v3arch/twisted/manager/nextgen.py b/examples/v3arch/twisted/manager/nextgen.py new file mode 100644 index 0000000..8fdc3a8 --- /dev/null +++ b/examples/v3arch/twisted/manager/nextgen.py @@ -0,0 +1,73 @@ +# GETNEXT Command Generator +from twisted.internet import reactor, defer +from pysnmp.entity import engine, config +from pysnmp.carrier.twisted import dispatch +from pysnmp.carrier.twisted.dgram import udp +from pysnmp.entity.rfc3413.twisted import cmdgen + +snmpEngine = engine.SnmpEngine() + +# Set Twisted dispatcher +snmpEngine.registerTransportDispatcher(dispatch.TwistedDispatcher()) + +# v1/2 setup +config.addV1System(snmpEngine, 'test-agent', 'public') + +# v3 setup +config.addV3User( + snmpEngine, 'test-user', + config.usmHMACMD5AuthProtocol, 'authkey1', + config.usmDESPrivProtocol, 'privkey1' + ) + +# Transport params +config.addTargetParams(snmpEngine, 'myParams', 'test-user', 'authPriv') +#config.addTargetParams(snmpEngine, 'myParams', 'test-agent', 'noAuthNoPriv', 1) + +# Transport addresses +config.addTargetAddr( + snmpEngine, 'myRouter', config.snmpUDPDomain, + ('127.0.0.1', 161), 'myParams' + ) + +# Transport +config.addSocketTransport( + snmpEngine, + udp.domainName, + udp.UdpTwistedTransport().openClientMode() + ) + +# Twisted API follows + +def receiveResponse( + (errorIndication, errorStatus, errorIndex, varBindTable), + nextCmdGen, snmpEngine): + if errorIndication or errorStatus: + print 'Error: ', errorIndication, errorStatus.prettyPrint(), errorIndex + reactor.stop() + return + for varBindRow in varBindTable: + for oid, val in varBindRow: + if val is None: + print oid.prettyPrint() + else: + print '%s = %s' % (oid.prettyPrint(), val.prettyPrint()) + for oid, val in varBindTable[-1]: + if val is not None: + df = nextCmdGen.sendReq( + snmpEngine, 'myRouter', varBindTable[-1] + ) + df.addCallback(receiveResponse, nextCmdGen, snmpEngine) + return + else: + reactor.stop() + +nextCmdGen = cmdgen.NextCommandGenerator() + +df = nextCmdGen.sendReq( + snmpEngine, 'myRouter', (((1,3,6,1,2,1,1), None),) + ) + +df.addCallback(receiveResponse, nextCmdGen, snmpEngine) + +reactor.run() diff --git a/examples/v3arch/twisted/manager/ntfrcv.py b/examples/v3arch/twisted/manager/ntfrcv.py new file mode 100644 index 0000000..61bb5ca --- /dev/null +++ b/examples/v3arch/twisted/manager/ntfrcv.py @@ -0,0 +1,48 @@ +# Notification Receiver (TRAP/INFORM) +from twisted.internet import reactor +from pysnmp.entity import engine, config +from pysnmp.carrier.twisted import dispatch +from pysnmp.carrier.twisted.dgram import udp +from pysnmp.entity.rfc3413 import ntfrcv + +# Create SNMP engine with autogenernated engineID and pre-bound +# to socket transport dispatcher +snmpEngine = engine.SnmpEngine() + +# Set Twisted dispatcher +snmpEngine.registerTransportDispatcher(dispatch.TwistedDispatcher()) + +# v1/2 setup +config.addV1System(snmpEngine, 'test-agent', 'public') + +# v3 setup +config.addV3User( + snmpEngine, 'test-user', + config.usmHMACMD5AuthProtocol, 'authkey1', + config.usmDESPrivProtocol, 'privkey1' + ) + +# Transport +config.addSocketTransport( + snmpEngine, + udp.domainName, + udp.UdpTwistedTransport().openServerMode(('127.0.0.1', 1162)) + ) + +# Callback function for receiving notifications +def cbFun(snmpEngine, + stateReference, + contextEngineId, contextName, + varBinds, + cbCtx): + transportDomain, transportAddress = snmpEngine.msgAndPduDsp.getTransportInfo(stateReference) + print 'Notification from %s, SNMP Engine \"%s\", Context \"%s\"' % ( + transportAddress, contextEngineId, contextName + ) + for name, val in varBinds: + print '%s = %s' % (name.prettyPrint(), val.prettyPrint()) + +# Apps registration +ntfrcv.NotificationReceiver(snmpEngine, cbFun) + +reactor.run() diff --git a/examples/v3arch/twisted/manager/setgen.py b/examples/v3arch/twisted/manager/setgen.py new file mode 100644 index 0000000..4bdac57 --- /dev/null +++ b/examples/v3arch/twisted/manager/setgen.py @@ -0,0 +1,64 @@ +# SET Command Generator +from twisted.internet import reactor, defer +from pysnmp.entity import engine, config +from pysnmp.carrier.twisted import dispatch +from pysnmp.carrier.twisted.dgram import udp +from pysnmp.entity.rfc3413.twisted import cmdgen +from pysnmp.proto import rfc1902 + +snmpEngine = engine.SnmpEngine() + +# Set Twisted dispatcher +snmpEngine.registerTransportDispatcher(dispatch.TwistedDispatcher()) + +# v1/2 setup +config.addV1System(snmpEngine, 'test-agent', 'public') + +# v3 setup +config.addV3User( + snmpEngine, 'test-user', + config.usmHMACMD5AuthProtocol, 'authkey1', + config.usmDESPrivProtocol, 'privkey1' + ) + +# Transport params +config.addTargetParams(snmpEngine, 'myParams', 'test-user', 'authPriv') +#config.addTargetParams(snmpEngine, 'myParams', 'test-agent', 'noAuthNoPriv', 1) + +# Transport addresses +config.addTargetAddr( + snmpEngine, 'myRouter', config.snmpUDPDomain, + ('127.0.0.1', 161), 'myParams' + ) + +# Transport +config.addSocketTransport( + snmpEngine, + udp.domainName, + udp.UdpTwistedTransport().openClientMode() + ) + +# Twisted API follows + +def receiveResponse((errorIndication, errorStatus, errorIndex, varBinds)): + if errorIndication or errorStatus: + print 'Error: ', errorIndication, errorStatus.prettyPrint(), errorIndex + reactor.stop() + return + for oid, val in varBinds: + if val is None: + print oid.prettyPrint() + else: + print '%s = %s' % (oid.prettyPrint(), val.prettyPrint()) + reactor.stop() + +getCmdGen = cmdgen.SetCommandGenerator() + +df = getCmdGen.sendReq( + snmpEngine, 'myRouter', + (((1,3,6,1,2,1,1,1,0), rfc1902.OctetString('Grinch')),) + ) + +df.addCallback(receiveResponse) + +reactor.run() diff --git a/pysnmp/carrier/twisted/__init__.py b/pysnmp/carrier/twisted/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/pysnmp/carrier/twisted/__init__.py diff --git a/pysnmp/carrier/twisted/base.py b/pysnmp/carrier/twisted/base.py new file mode 100644 index 0000000..ecceaca --- /dev/null +++ b/pysnmp/carrier/twisted/base.py @@ -0,0 +1,26 @@ +# +# Copyright (C) 2008 Truelite Srl <info@truelite.it> +# Author: Filippo Giunchedi <filippo@truelite.it> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License Version 2 +# as published by the Free Software Foundation +# +# Description: twisted DatagramProtocol UDP transport +# + +class AbstractTwistedTransport: + """Base Twisted Transport, to be used with TwistedDispatcher""" + def __init__(self): + self._writeQ = [] + + # AbstractTwistedTransport API + + def registerCbFun(self, cbFun): + self._cbFun = cbFun + + def unregisterCbFun(self): + self._cbFun = None + + def closeTransport(self): + self.unregisterCbFun() diff --git a/pysnmp/carrier/twisted/dgram/__init__.py b/pysnmp/carrier/twisted/dgram/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/pysnmp/carrier/twisted/dgram/__init__.py diff --git a/pysnmp/carrier/twisted/dgram/base.py b/pysnmp/carrier/twisted/dgram/base.py new file mode 100644 index 0000000..75dd455 --- /dev/null +++ b/pysnmp/carrier/twisted/dgram/base.py @@ -0,0 +1,44 @@ +"""Implements twisted-based generic DGRAM transport""" +from time import time +from twisted.internet.protocol import DatagramProtocol +from twisted.internet import reactor +from pysnmp.carrier.twisted.base import AbstractTwistedTransport +from pysnmp.carrier import error +from pysnmp import debug + +class DgramTwistedTransport(DatagramProtocol, AbstractTwistedTransport): + """Base Twisted datagram Transport, to be used with TwistedDispatcher""" + + # Twisted Datagram API + + def datagramReceived(self, datagram, address): + if self._cbFun is None: + raise error.CarrierError('Unable to call cbFun') + else: + # Callback fun is called through callLater() in attempt + # to make Twisted timed calls work under high load. + reactor.callLater(0, self._cbFun, self, address, datagram) + + def startProtocol(self): + debug.logger & debug.flagIO and debug.logger('startProtocol: invoked') + while self._writeQ: + outgoingMessage, transportAddress = self._writeQ.pop(0) + debug.logger & debug.flagIO and debug.logger('startProtocol: transportAddress %s outgoingMessage %s' % (transportAddress, repr(outgoingMessage))) + try: + self.transport.write(outgoingMessage, transportAddress) + except Exception, why: + raise error.CarrierError('Twisted exception: %s' % (why,)) + + def stopProtocol(self): + debug.logger & debug.flagIO and debug.logger('stopProtocol: invoked') + self.closeTransport() + + def sendMessage(self, outgoingMessage, transportAddress): + debug.logger & debug.flagIO and debug.logger('startProtocol: %s transportAddress %s outgoingMessage %s' % ((self.transport is None and "queuing" or "sending"), transportAddress, repr(outgoingMessage))) + if self.transport is None: + self._writeQ.append((outgoingMessage, transportAddress)) + else: + try: + self.transport.write(outgoingMessage, transportAddress) + except Exception, why: + raise error.CarrierError('Twisted exception: %s' % (why,)) diff --git a/pysnmp/carrier/twisted/dgram/udp.py b/pysnmp/carrier/twisted/dgram/udp.py new file mode 100644 index 0000000..850ff1b --- /dev/null +++ b/pysnmp/carrier/twisted/dgram/udp.py @@ -0,0 +1,25 @@ +"""Implements twisted-based UDP transport""" +from twisted.internet import reactor +from pysnmp.carrier.twisted.dgram.base import DgramTwistedTransport +from pysnmp.carrier import error + +domainName = snmpUDPDomain = (1, 3, 6, 1, 6, 1, 1) + +class UdpTwistedTransport(DgramTwistedTransport): + # AbstractTwistedTransport API + + def openClientMode(self, iface=''): + try: + self._lport = reactor.listenUDP(0, self, iface) + except Exception, why: + raise error.CarrierError(why) + return self + + def openServerMode(self, iface=None): + try: + self._lport = reactor.listenUDP(iface[1], self, iface[0]) + except Exception, why: + raise error.CarrierError(why) + return self + +UdpTransport = UdpTwistedTransport
\ No newline at end of file diff --git a/pysnmp/carrier/twisted/dgram/unix.py b/pysnmp/carrier/twisted/dgram/unix.py new file mode 100644 index 0000000..75bfe17 --- /dev/null +++ b/pysnmp/carrier/twisted/dgram/unix.py @@ -0,0 +1,26 @@ +"""Implements twisted-based UNIX domain socket transport""" +from twisted.internet import reactor +from pysnmp.carrier.twisted.dgram.base import DgramTwistedTransport +from pysnmp.carrier import error + +domainName = snmpLocalDomain = (1, 3, 6, 1, 2, 1, 100, 1, 13) + +class UnixTwistedTransport(DgramTwistedTransport): + # AbstractTwistedTransport API + + def openClientMode(self, iface=''): + try: + self._lport = reactor.connectUNIXDatagram(iface, self) + except Exception, why: + raise error.CarrierError(why) + return self + + def openServerMode(self, iface=None): + try: + self._lport = reactor.listenUNIXDatagram(iface, self) + except Exception, why: + raise error.CarrierError(why) + + return self + +UnixTransport = UnixTwistedTransport
\ No newline at end of file diff --git a/pysnmp/carrier/twisted/dispatch.py b/pysnmp/carrier/twisted/dispatch.py new file mode 100644 index 0000000..36b4ccc --- /dev/null +++ b/pysnmp/carrier/twisted/dispatch.py @@ -0,0 +1,53 @@ +# +# Copyright (C) 2008 Truelite Srl <info@truelite.it> +# Author: Filippo Giunchedi <filippo@truelite.it> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License Version 2 +# as published by the Free Software Foundation +# +# Description: Transport dispatcher based on twisted.internet.reactor +# +from time import time +from twisted.internet import reactor, task +from pysnmp.carrier.base import AbstractTransportDispatcher +from pysnmp.carrier import error + +class TwistedDispatcher(AbstractTransportDispatcher): + """TransportDispatcher based on twisted.internet.reactor""" + def __init__(self, *args, **kwargs): + AbstractTransportDispatcher.__init__(self) + self.__transportCount = 0 + self.timeout = kwargs.get('timeout', 1.0) + self.loopingcall = task.LoopingCall(self.handleTimeout) + + def handleTimeout(self): + self.handleTimerTick(time()) + + def runDispatcher(self, timeout=0.0): + if not reactor.running: + try: + reactor.run() + except Exception, why: + raise error.CarrierError(why) + + # jobstarted/jobfinished might be okay as-is + + def registerTransport(self, tDomain, transport): + if not self.loopingcall.running and self.timeout > 0: + self.loopingcall.start(self.timeout, now = False) + AbstractTransportDispatcher.registerTransport( + self, tDomain, transport + ) + self.__transportCount = self.__transportCount + 1 + + def unregisterTransport(self, tDomain): + t = AbstractTransportDispatcher.getTransport(self, tDomain) + if t is not None: + AbstractTransportDispatcher.unregisterTransport(self, tDomain) + t.closeTransport() + self.__transportCount = self.__transportCount - 1 + + # The last transport has been removed, stop the timeout + if self.__transportCount > 0 and self.loopingcall.running: + self.loopingcall.stop() diff --git a/pysnmp/entity/rfc3413/twisted/__init__.py b/pysnmp/entity/rfc3413/twisted/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/pysnmp/entity/rfc3413/twisted/__init__.py diff --git a/pysnmp/entity/rfc3413/twisted/cmdgen.py b/pysnmp/entity/rfc3413/twisted/cmdgen.py new file mode 100644 index 0000000..297c49d --- /dev/null +++ b/pysnmp/entity/rfc3413/twisted/cmdgen.py @@ -0,0 +1,202 @@ +from twisted.internet import reactor, defer +from pysnmp.entity.rfc3413 import cmdgen + +class GetCommandGenerator(cmdgen.GetCommandGenerator): + def sendReq( + self, + snmpEngine, + addrName, + varBinds, + contextEngineId=None, + contextName='' + ): + df = defer.Deferred() + cmdgen.GetCommandGenerator.sendReq( + self, + snmpEngine, + addrName, + varBinds, + None, + df, + contextEngineId, + contextName + ) + return df + + def _handleResponse( + self, + snmpEngine, + transportDomain, + transportAddress, + messageProcessingModel, + securityModel, + securityName, + securityLevel, + contextEngineId, + contextName, + pduVersion, + PDU, + timeout, + retryCount, + pMod, + rspPDU, + sendRequestHandle, + (cbFun, cbCtx) + ): + cbCtx.callback( + (None, + pMod.apiPDU.getErrorStatus(rspPDU), + pMod.apiPDU.getErrorIndex(rspPDU), + pMod.apiPDU.getVarBinds(rspPDU)) + ) + +class SetCommandGenerator(cmdgen.SetCommandGenerator): + def sendReq( + self, + snmpEngine, + addrName, + varBinds, + contextEngineId=None, + contextName='' + ): + df = defer.Deferred() + cmdgen.SetCommandGenerator.sendReq( + self, + snmpEngine, + addrName, + varBinds, + None, + df, + contextEngineId, + contextName + ) + return df + + def _handleResponse( + self, + snmpEngine, + transportDomain, + transportAddress, + messageProcessingModel, + securityModel, + securityName, + securityLevel, + contextEngineId, + contextName, + pduVersion, + PDU, + timeout, + retryCount, + pMod, + rspPDU, + sendRequestHandle, + (cbFun, cbCtx) + ): + cbCtx.callback( + (None, + pMod.apiPDU.getErrorStatus(rspPDU), + pMod.apiPDU.getErrorIndex(rspPDU), + pMod.apiPDU.getVarBinds(rspPDU)) + ) + +class NextCommandGenerator(cmdgen.NextCommandGenerator): + def sendReq( + self, + snmpEngine, + addrName, + varBinds, + contextEngineId=None, + contextName='' + ): + df = defer.Deferred() + cmdgen.NextCommandGenerator.sendReq( + self, + snmpEngine, + addrName, + varBinds, + None, + df, + contextEngineId, + contextName + ) + return df + + def _handleResponse( + self, + snmpEngine, + transportDomain, + transportAddress, + messageProcessingModel, + securityModel, + securityName, + securityLevel, + contextEngineId, + contextName, + pduVersion, + PDU, + timeout, + retryCount, + pMod, + rspPDU, + sendRequestHandle, + (cbFun, cbCtx) + ): + cbCtx.callback( + (None, + pMod.apiPDU.getErrorStatus(rspPDU), + pMod.apiPDU.getErrorIndex(rspPDU), + pMod.apiPDU.getVarBindTable(PDU, rspPDU)) + ) + +class BulkCommandGenerator(cmdgen.BulkCommandGenerator): + def sendReq( + self, + snmpEngine, + addrName, + nonRepeaters, + maxRepetitions, + varBinds, + contextEngineId=None, + contextName='' + ): + df = defer.Deferred() + cmdgen.BulkCommandGenerator.sendReq( + self, + snmpEngine, + addrName, + nonRepeaters, + maxRepetitions, + varBinds, + None, + df, + contextEngineId=None, + contextName='' + ) + return df + + def _handleResponse( + self, + snmpEngine, + transportDomain, + transportAddress, + messageProcessingModel, + securityModel, + securityName, + securityLevel, + contextEngineId, + contextName, + pduVersion, + PDU, + timeout, + retryCount, + pMod, + rspPDU, + sendRequestHandle, + (cbFun, cbCtx) + ): + cbCtx.callback( + (None, + pMod.apiBulkPDU.getErrorStatus(rspPDU), + pMod.apiBulkPDU.getErrorIndex(rspPDU), + pMod.apiBulkPDU.getVarBindTable(PDU, rspPDU)) + ) diff --git a/pysnmp/entity/rfc3413/twisted/ntforg.py b/pysnmp/entity/rfc3413/twisted/ntforg.py new file mode 100644 index 0000000..e02f2ab --- /dev/null +++ b/pysnmp/entity/rfc3413/twisted/ntforg.py @@ -0,0 +1,32 @@ +from twisted.internet import reactor, defer +from pysnmp.entity.rfc3413 import ntforg + +class NotificationOriginator(ntforg.NotificationOriginator): + def sendNotification( + self, + snmpEngine, + notificationTarget, + notificationName, + additionalVarBinds=None, + contextName='' + ): + df = defer.Deferred() + ntforg.NotificationOriginator.sendNotification( + self, + snmpEngine, + notificationTarget, + notificationName, + additionalVarBinds, + None, + df, + contextName='' + ) + return df + + def _handleResponse( + self, + sendRequestHandle, + errorIndication, + cbFun, + cbCtx): + cbCtx.callback((sendRequestHandle, errorIndication)) @@ -15,9 +15,12 @@ setup(name="pysnmp", 'pysnmp.v4.carrier', 'pysnmp.v4.carrier.asynsock', 'pysnmp.v4.carrier.asynsock.dgram', + 'pysnmp.v4.carrier.twisted', + 'pysnmp.v4.carrier.twisted.dgram', 'pysnmp.v4.entity', 'pysnmp.v4.entity.rfc3413', 'pysnmp.v4.entity.rfc3413.oneliner', + 'pysnmp.v4.entity.rfc3413.twisted', 'pysnmp.v4.proto', 'pysnmp.v4.proto.mpmod', 'pysnmp.v4.proto.secmod', |