summaryrefslogtreecommitdiff
path: root/examples/v3arch/asyncore/proxy/command/v3-to-v2c-conversion.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/v3arch/asyncore/proxy/command/v3-to-v2c-conversion.py')
-rw-r--r--examples/v3arch/asyncore/proxy/command/v3-to-v2c-conversion.py143
1 files changed, 143 insertions, 0 deletions
diff --git a/examples/v3arch/asyncore/proxy/command/v3-to-v2c-conversion.py b/examples/v3arch/asyncore/proxy/command/v3-to-v2c-conversion.py
new file mode 100644
index 0000000..da9aba3
--- /dev/null
+++ b/examples/v3arch/asyncore/proxy/command/v3-to-v2c-conversion.py
@@ -0,0 +1,143 @@
+"""
+SNMPv3-to-SNMPv2c conversion
+++++++++++++++++++++++++++++
+
+Act as a local SNMPv3 Agent, relay messages to distant SNMPv1/v2c Agent:
+* over IPv4/UDP
+* with local SNMPv3 user usr-md5-des, MD5 auth and DES privacy protocols
+* local Agent listening at 127.0.0.1:161
+* remote SNMPv1, community public
+* remote Agent listening at 195.218.195.228:161
+
+This script can be queried with the following Net-SNMP command:
+
+| $ snmpget -v3 -l authPriv -u usr-md5-des -A authkey1 -X privkey1 -ObentU 127.0.0.1:161 1.3.6.1.2.1.1.1.0
+
+due to proxy, it is equivalent to
+
+| $ snmpget -v2c -c public 195.218.195.228:161 1.3.6.1.2.1.1.1.0
+
+Warning: for production operation you would need to modify this script
+so that it will re-map possible duplicate request-ID values, coming in
+initial request PDUs from different Managers, into unique values to
+avoid sending duplicate request-IDs to Agents.
+
+"""#
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity import engine, config
+from pysnmp.entity.rfc3413 import cmdrsp, cmdgen, context
+from pysnmp.proto.api import v2c
+from pysnmp import error
+
+# Create SNMP engine with autogenernated engineID and pre-bound
+# to socket transport dispatcher
+snmpEngine = engine.SnmpEngine()
+
+#
+# Transport setup
+#
+
+# Agent section
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName + (1,),
+ udp.UdpTransport().openServerMode(('127.0.0.1', 161))
+)
+
+# Manager section
+
+# UDP over IPv4
+config.addTransport(
+ snmpEngine,
+ udp.domainName + (2,),
+ udp.UdpTransport().openClientMode()
+)
+
+#
+# SNMPv3/USM setup (Agent role)
+#
+
+# user: usr-md5-des, auth: MD5, priv DES
+config.addV3User(
+ snmpEngine, 'usr-md5-des',
+ config.usmHMACMD5AuthProtocol, 'authkey1',
+ config.usmDESPrivProtocol, 'privkey1'
+)
+
+#
+# SNMPv1/2c setup (Manager role)
+#
+
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+#
+# Transport target used by Manager
+#
+
+# Specify security settings per SecurityName (SNMPv1 - 0, SNMPv2c - 1)
+config.addTargetParams(snmpEngine, 'distant-agent-auth', 'my-area',
+ 'noAuthNoPriv', 0)
+
+config.addTargetAddr(
+ snmpEngine, 'distant-agent',
+ udp.domainName + (2,), ('195.218.195.228', 161),
+ 'distant-agent-auth', retryCount=0
+)
+
+# Default SNMP context
+config.addContext(snmpEngine, '')
+
+class CommandResponder(cmdrsp.CommandResponderBase):
+ cmdGenMap = {
+ v2c.GetRequestPDU.tagSet: cmdgen.GetCommandGenerator(),
+ v2c.SetRequestPDU.tagSet: cmdgen.SetCommandGenerator(),
+ v2c.GetNextRequestPDU.tagSet: cmdgen.NextCommandGeneratorSingleRun(),
+ v2c.GetBulkRequestPDU.tagSet: cmdgen.BulkCommandGeneratorSingleRun()
+ }
+ pduTypes = cmdGenMap.keys() # This app will handle these PDUs
+
+ # SNMP request relay
+ def handleMgmtOperation(self, snmpEngine, stateReference, contextName,
+ PDU, acInfo):
+ cbCtx = stateReference, PDU
+ contextEngineId = None # address authoritative SNMP Engine
+ try:
+ self.cmdGenMap[PDU.tagSet].sendPdu(
+ snmpEngine, 'distant-agent',
+ contextEngineId, contextName,
+ PDU,
+ self.handleResponsePdu, cbCtx
+ )
+ except error.PySnmpError:
+ self.handleResponsePdu(
+ stateReference, 'error', None, cbCtx
+ )
+
+ # SNMP response relay
+ def handleResponsePdu(self, snmpEngine, sendRequestHandle,
+ errorIndication, PDU, cbCtx):
+ stateReference, reqPDU = cbCtx
+
+ if errorIndication:
+ PDU = v2c.apiPDU.getResponse(reqPDU)
+ PDU.setErrorStatus(PDU, 5)
+
+ self.sendPdu(
+ snmpEngine, stateReference, PDU
+ )
+
+ self.releaseStateInformation(stateReference)
+
+CommandResponder(snmpEngine, context.SnmpContext(snmpEngine))
+
+snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
+
+# Run I/O dispatcher which would receive queries and send responses
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise