在PySNMP代理中实现自定义MIB
我在PySNMP代理中实现自定义MIB时遇到困难。在PySNMP代理中实现自定义MIB
我已经开始与:
http://pysnmp.sourceforge.net/examples/4.x/v3arch/agent/cmdrsp.html
创建了自己的MIB文件,用于build-pysnmp-mib
,使一个Python模块,并成功导入符号。
我看不到下一步该去哪里。我需要以某种方式将导入的符号安装在所提供的MIB列表中并提供一个实现。 (它目前是具有一个只读INTEGER属性的MIB。)
MIB文件通过smilint
,但没有警告,但我必须手动将缺少的MibScalar
导入添加到生成的模块。
MIB:
TRS-MIB DEFINITIONS ::= BEGIN
internet OBJECT IDENTIFIER ::= { iso(1) org(3) dod(6) 1 }
enterprises OBJECT IDENTIFIER ::= { internet private(4) 1 }
thorcom OBJECT IDENTIFIER ::= { enterprises 27817 }
trs OBJECT IDENTIFIER ::= { thorcom 2 }
trsEntry OBJECT IDENTIFIER ::= { trs 1 }
trsDeliveryTime OBJECT-TYPE
SYNTAX Integer32
ACCESS not-accessible
STATUS mandatory
DESCRIPTION "Average message delivery time in milliseconds."
::= { trsEntry 1 }
END
代码:
#!/usr/bin/env python
# Command Responder
from pysnmp.entity import engine, config
from pysnmp.carrier.asynsock.dgram import udp
#from pysnmp.carrier.asynsock.dgram import udp6
from pysnmp.entity.rfc3413 import cmdrsp, context
from pysnmp.proto.rfc1902 import OctetString
from pysnmp.smi import builder
from pysnmp import debug
debug.setLogger(debug.Debug('all'))
# Create SNMP engine with autogenernated engineID and pre-bound
# to socket transport dispatcher
snmpEngine = engine.SnmpEngine()
# Setup UDP over IPv4 transport endpoint
config.addSocketTransport(
snmpEngine,
udp.domainName,
udp.UdpSocketTransport().openServerMode(('127.0.0.1', 161))
)
# Start of new code
mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder
mibSources = mibBuilder.getMibSources() + (
builder.DirMibSource('.'),
)
mibBuilder.setMibSources(*mibSources)
# Create and put on-line my managed object
deliveryTime, = mibBuilder.importSymbols('TRS-MIB', 'trsDeliveryTime')
Integer32, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('SNMPv2-SMI', 'Integer32')
MibScalarInstance, = mibBuilder.importSymbols('SNMPv2-SMI', 'MibScalarInstance')
class MyDeliveryTime(Integer32):
def readGet(self, name, val, idx, (acFun, acCtx)):
return name, self.syntax.clone(42)
deliveryTimeInstance = MibScalarInstance(
deliveryTime.name, (0,), deliveryTime.syntax
)
mibBuilder.exportSymbols('TRS-MIB', deliveryTimeInstance=deliveryTimeInstance) # creating MIB
# End of new code
# v1/2 setup
config.addV1System(snmpEngine, 'test-agent', 'public')
# v3 setup
config.addV3User(
snmpEngine, 'test-user',
config.usmHMACMD5AuthProtocol, 'authkey1',
config.usmDESPrivProtocol, 'privkey1'
)
# VACM setup
config.addContext(snmpEngine, '')
config.addRwUser(snmpEngine, 1, 'test-agent', 'noAuthNoPriv', (1,3,6)) # v1
config.addRwUser(snmpEngine, 2, 'test-agent', 'noAuthNoPriv', (1,3,6)) # v2c
config.addRwUser(snmpEngine, 3, 'test-user', 'authPriv', (1,3,6)) # v3
# SNMP context
snmpContext = context.SnmpContext(snmpEngine)
# Apps registration
cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)
snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
snmpEngine.transportDispatcher.runDispatcher()
生成并修改TRS-MIB.py:
# PySNMP SMI module. Autogenerated from smidump -f python TRS-MIB
# by libsmi2pysnmp-0.1.1 at Fri Aug 31 13:56:45 2012,
# Python version (2, 6, 6, 'final', 0)
# Imported just in case new ASN.1 types would be created
from pyasn1.type import constraint, namedval
# Imports
(Integer, ObjectIdentifier, OctetString,) = mibBuilder.importSymbols("ASN1", "Integer", "ObjectIdentifier", "OctetString")
(Bits, Integer32, MibIdentifier, MibScalar, TimeTicks,) = mibBuilder.importSymbols("SNMPv2-SMI", "Bits", "Integer32", "MibIdentifier", "MibScalar", "TimeTicks")
# Objects
internet = MibIdentifier((1, 3, 6, 1))
enterprises = MibIdentifier((1, 3, 6, 1, 4, 1))
thorcom = MibIdentifier((1, 3, 6, 1, 4, 1, 27817))
trs = MibIdentifier((1, 3, 6, 1, 4, 1, 27817, 2))
trsEntry = MibIdentifier((1, 3, 6, 1, 4, 1, 27817, 2, 1))
trsDeliveryTime = MibScalar((1, 3, 6, 1, 4, 1, 27817, 2, 1, 1), Integer32()).setMaxAccess("noaccess")
if mibBuilder.loadTexts: trsDeliveryTime.setDescription("Average message delivery time in milliseconds.")
# Augmentions
# Exports
# Objects
mibBuilder.exportSymbols("TRS-MIB", internet=internet, enterprises=enterprises, thorcom=thorcom, trs=trs, trsEntry=trsEntry, trsDeliveryTime=trsDeliveryTime)
更新:
我现在有一个错误左:
$ snmpget -v2c -c public localhost .1.3.6.1.4.1.27817.2.1.1
Error in packet
Reason: noAccess
Failed object: iso.3.6.1.4.1.27817.2.1.1
调试是:
DBG: handle_read: transportAddress ('127.0.0.1', 48191) incomingMessage '0,\x02\x01\x01\x04\x06public\xa0\x1f\x02\x04>9\xc4\xa0\x02\x01\x00\x02\x01\x000\x110\x0f\x06\x0b+\x06\x01\x04\x01\x81\xd9)\x02\x01\x01\x05\x00'
DBG: receiveMessage: msgVersion 1, msg decoded
DBG: prepareDataElements: Message:
version='version-2'
community=public
data=PDUs:
get-request=GetRequestPDU:
request-id=1043973280
error-status='noError'
error-index=0
variable-bindings=VarBindList:
VarBind:
name=1.3.6.1.4.1.27817.2.1.1
=_BindValue:
unSpecified=
DBG: value index rebuilt at (1, 3, 6, 1, 6, 3, 18, 1, 1, 1, 2), 1 entries
DBG: processIncomingMsg: looked up securityName MibScalarInstance((1, 3, 6, 1, 6, 3, 18, 1, 1, 1, 3, 116, 101, 115, 116, 45, 97, 103, 101, 110, 116), test-agent) contextEngineId MibScalarInstance((1, 3, 6, 1, 6, 3, 18, 1, 1, 1, 4, 116, 101, 115, 116, 45, 97, 103, 101, 110, 116), �O�c�@��) contextName MibScalarInstance((1, 3, 6, 1, 6, 3, 18, 1, 1, 1, 5, 116, 101, 115, 116, 45, 97, 103, 101, 110, 116),) by communityName MibScalarInstance((1, 3, 6, 1, 6, 3, 18, 1, 1, 1, 2, 116, 101, 115, 116, 45, 97, 103, 101, 110, 116), public)
DBG: processIncomingMsg: generated maxSizeResponseScopedPDU 65379 securityStateReference 12831470
DBG: prepareDataElements: SM returned securityEngineID SnmpEngineID(hexValue='8004fb857f00163de40e2b7') securityName test-agent
DBG: prepareDataElements: cached by new stateReference 2662033
DBG: receiveMessage: MP succeded
DBG: receiveMessage: PDU GetRequestPDU:
request-id=1043973280
error-status='noError'
error-index=0
variable-bindings=VarBindList:
VarBind:
name=1.3.6.1.4.1.27817.2.1.1
=_BindValue:
unSpecified=
DBG: receiveMessage: pduType TagSet(Tag(tagClass=128, tagFormat=32, tagId=0))
DBG: processPdu: stateReference 2662033, varBinds [(ObjectName(1.3.6.1.4.1.27817.2.1.1), Null(''))]
DBG: getMibInstrum: contextName "", mibInstum <pysnmp.smi.instrum.MibInstrumController instance at 0x7fcbfe3d5e60>
DBG: flipFlopFsm: inputNameVals [(ObjectName(1.3.6.1.4.1.27817.2.1.1), Null(''))]
DBG: flipFlopFsm: state start status ok -> fsmState readTest
DBG: flipFlopFsm: fun <bound method MibTree.readTest of MibTree((1,), None)> failed NoAccessError({'name': (1, 3, 6, 1, 4, 1, 27817, 2, 1, 1), 'idx': 0}) for 1.3.6.1.4.1.27817.2.1.1=Null('')
DBG: flipFlopFsm: state readTest status err -> fsmState stop
DBG: sendRsp: stateReference 2662033, errorStatus noAccess, errorIndex 1, varBinds [(ObjectName(1.3.6.1.4.1.27817.2.1.1), Null(''))]
DBG: returnResponsePdu: PDU ResponsePDU:
request-id=1043973280
error-status='noAccess'
error-index=1
variable-bindings=VarBindList:
VarBind:
name=1.3.6.1.4.1.27817.2.1.1
=_BindValue:
unSpecified=
DBG: prepareResponseMessage: cache read msgID 1043973280 transportDomain (1, 3, 6, 1, 6, 1, 1) transportAddress ('127.0.0.1', 48191) by stateReference 2662033
DBG: prepareResponseMessage: using contextEngineId SnmpEngineID(hexValue='8004fb857f00163de40e2b7') contextName
DBG: generateResponseMsg: recovered community public by securityStateReference 12831470
DBG: generateResponseMsg: Message:
version='version-2'
community=public
data=PDUs:
response=ResponsePDU:
request-id=1043973280
error-status='noAccess'
error-index=1
variable-bindings=VarBindList:
VarBind:
name=1.3.6.1.4.1.27817.2.1.1
=_BindValue:
unSpecified=
DBG: returnResponsePdu: MP suceeded
DBG: receiveMessage: processPdu succeeded
DBG: handle_write: transportAddress ('127.0.0.1', 48191) outgoingMessage '0,\x02\x01\x01\x04\x06public\xa2\x1f\x02\x04>9\xc4\xa0\x02\x01\x06\x02\x01\x010\x110\x0f\x06\x0b+\x06\x01\x04\x01\x81\xd9)\x02\x01\x01\x05\x00'
作为实现管理对象的实例,你有两个选择:
加载和子类MibScalarInstance类,然后覆盖其readGet()方法使其返回您的实时价值。然后实例化你的新类(确保传递适当的OID来标识它)并将它传递给exportSymbols(),所以它的OID将在pysnmp Agent中注册。
加载Integer32类,对它进行子类化并覆盖它的“clone()”方法,使其返回实时值。然后加载MibScalarInstance类,实例化它传递适当的OID和Integer32子类的实例,然后将MibScalarInstance对象传递给exportSymbols(),所以它的OID将在pysnmp Agent中注册。
将所有代码保留在您自己的MIB模块中可能有意义。看看pysnmp/smi/mibs/instances/*。py来获得一个想法。
从您的Agent应用程序中,调用mibBuilder.loadModules('TRC-MIB')将您的MIB模块加载到代理中。
在你的代码中,你似乎以某种方式结合了上述两种方法:MyDeliveryTime.readGet()将不起作用,但是MyDeliveryTime.clone()或deliveryTimeInstance.readGet()会。
我也遇到了类似的问题:
试图把MY-MIB [PYC]文件在〜/。pysnmp/mibs文件夹,但我认为真正起作用的是将这些文件放在文件夹/ usr/lib/pytho */site/pysnmp/smi/mibs /中。
我在pysnmp-4.3.9上工作
谢谢,我想我快到了。我只剩下一个错误...(请参阅原始问题)。谢谢你的帮助。 – fadedbee
解决方案是将'.setMaxAccess(“noaccess”)'改为'.setMaxAccess(“readonly”)'。 – fadedbee