1"""
2Observe SNMP engine operations
3++++++++++++++++++++++++++++++
4
5Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
6the following options:
7
8* SNMPv3
9* with USM user 'usr-md5-des', auth: MD5, priv DES or
10* allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
11* over IPv4/UDP, listening at 127.0.0.1:161
12* registers its own execution observer to snmpEngine
13
14The following Net-SNMP command will walk this Agent:
15
16| $ snmpwalk -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 localhost .1.3.6
17
18This script will report some details on request processing as seen
19by rfc3412.receiveMessage() and rfc3412.returnResponsePdu()
20abstract interfaces.
21
22"""#
23from pysnmp.entity import engine, config
24from pysnmp.entity.rfc3413 import cmdrsp, context
25from pysnmp.carrier.asyncore.dgram import udp
26
27# Create SNMP engine
28snmpEngine = engine.SnmpEngine()
29
30
31# Execution point observer setup
32
33# Register a callback to be invoked at specified execution point of
34# SNMP Engine and passed local variables at code point's local scope
35# noinspection PyUnusedLocal,PyUnusedLocal
36def requestObserver(snmpEngine, execpoint, variables, cbCtx):
37    print('Execution point: %s' % execpoint)
38    print('* transportDomain: %s' % '.'.join([str(x) for x in variables['transportDomain']]))
39    print('* transportAddress: %s (local %s)' % ('@'.join([str(x) for x in variables['transportAddress']]), '@'.join([str(x) for x in variables['transportAddress'].getLocalAddress()])))
40    print('* securityModel: %s' % variables['securityModel'])
41    print('* securityName: %s' % variables['securityName'])
42    print('* securityLevel: %s' % variables['securityLevel'])
43    print('* contextEngineId: %s' % variables['contextEngineId'].prettyPrint())
44    print('* contextName: %s' % variables['contextName'].prettyPrint())
45    print('* PDU: %s' % variables['pdu'].prettyPrint())
46
47
48snmpEngine.observer.registerObserver(
49    requestObserver,
50    'rfc3412.receiveMessage:request',
51    'rfc3412.returnResponsePdu'
52)
53
54# Transport setup
55
56# UDP over IPv4
57config.addTransport(
58    snmpEngine,
59    udp.domainName,
60    udp.UdpTransport().openServerMode(('127.0.0.1', 161))
61)
62
63# SNMPv3/USM setup
64
65# user: usr-md5-des, auth: MD5, priv DES
66config.addV3User(
67    snmpEngine, 'usr-md5-des',
68    config.usmHMACMD5AuthProtocol, 'authkey1',
69    config.usmDESPrivProtocol, 'privkey1'
70)
71
72# Allow full MIB access for each user at VACM
73config.addVacmUser(snmpEngine, 3, 'usr-md5-des', 'authPriv', (1, 3, 6, 1, 2, 1), (1, 3, 6, 1, 2, 1))
74
75# Get default SNMP context this SNMP engine serves
76snmpContext = context.SnmpContext(snmpEngine)
77
78# Register SNMP Applications at the SNMP engine for particular SNMP context
79cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
80cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
81cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
82cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)
83
84# Register an imaginary never-ending job to keep I/O dispatcher running forever
85snmpEngine.transportDispatcher.jobStarted(1)
86
87# Run I/O dispatcher which would receive queries and send responses
88try:
89    snmpEngine.transportDispatcher.runDispatcher()
90except:
91    snmpEngine.observer.unregisterObserver()
92    snmpEngine.transportDispatcher.closeDispatcher()
93    raise
94