1"""
2Specific SNMP Engine ID
3+++++++++++++++++++++++
4
5Listen and respond to SNMP GET/SET/GETNEXT/GETBULK queries with
6the following options:
7
8* SNMPv3
9* with SNMP EngineID: 8000000004030201
10* with USM user 'usr-md5-des', auth: MD5, priv DES
11* allow access to SNMPv2-MIB objects (1.3.6.1.2.1)
12* over IPv4/UDP, listening at 127.0.0.1:161
13
14The following Net-SNMP command will walk this Agent:
15
16| $ snmpwalk -v3 -u usr-md5-des -l authPriv -A authkey1 -X privkey1 -e 8000000004030201 localhost .1.3.6
17
18"""#
19from pysnmp.entity import engine, config
20from pysnmp.entity.rfc3413 import cmdrsp, context
21from pysnmp.carrier.asyncore.dgram import udp
22from pysnmp.proto import rfc1902
23
24# Create SNMP engine
25snmpEngine = engine.SnmpEngine(rfc1902.OctetString(hexValue='8000000004030201'))
26
27# Transport setup
28
29# UDP over IPv4
30config.addTransport(
31    snmpEngine,
32    udp.domainName,
33    udp.UdpTransport().openServerMode(('127.0.0.1', 161))
34)
35
36# SNMPv3/USM setup
37
38# user: usr-md5-des, auth: MD5, priv DES
39config.addV3User(
40    snmpEngine, 'usr-md5-des',
41    config.usmHMACMD5AuthProtocol, 'authkey1',
42    config.usmDESPrivProtocol, 'privkey1'
43)
44
45# Allow full MIB access for each user at VACM
46config.addVacmUser(snmpEngine, 3, 'usr-md5-des', 'authPriv', (1, 3, 6, 1, 2, 1), (1, 3, 6, 1, 2, 1))
47
48# Get default SNMP context this SNMP engine serves
49snmpContext = context.SnmpContext(snmpEngine)
50
51# Register SNMP Applications at the SNMP engine for particular SNMP context
52cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
53cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
54cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
55cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)
56
57# Register an imaginary never-ending job to keep I/O dispatcher running forever
58snmpEngine.transportDispatcher.jobStarted(1)
59
60# Run I/O dispatcher which would receive queries and send responses
61try:
62    snmpEngine.transportDispatcher.runDispatcher()
63except:
64    snmpEngine.transportDispatcher.closeDispatcher()
65    raise
66