在 PySNMP 代理中实现自定义 MIB

问题描述 投票:0回答:2

我在 PySNMP 代理中实现自定义 MIB 时遇到困难。

我从它的文档网站开始,创建了自己的 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'
snmp pysnmp
2个回答
1
投票

对于实现托管对象实例,您有两种选择:

  1. 加载 MibScalarInstance 类并对其进行子类化,然后重写其 readGet() 方法以使其返回实时值。然后实例化您的新类(确保向其传递标识它的适当 OID)并将其传递给 exportSymbols(),以便其 OID 将在 pysnmp Agent 中注册。

  2. 加载 Integer32 类,将其子类化并重写其“clone()”方法以使其返回实时值。然后加载 MibScalarInstance 类,通过适当的 OID 和 Integer32 子类的实例来实例化它,然后将 MibScalarInstance 对象传递给 exportSymbols(),这样它的 OID 将在 pysnmp Agent 中注册。

将所有代码保存在您自己的 MIB 模块中可能是有意义的。查看 pysnmp/smi/mibs/instances/*.py 以获得一个想法。

在您的 Agent 应用程序中,调用 mibBuilder.loadModules('TRC-MIB') 将 MIB 模块加载到 Agent 中。

在您的代码中,您似乎以某种方式结合了上述两种方法:MyDeliveryTime.readGet() 不起作用,但是 MyDeliveryTime.clone() 或 DeliveryTimeInstance.readGet() 会起作用。


0
投票

我也遇到过类似的问题:

尝试将 MY-MIB.[pyc] 文件放入 ~/.pysnmp/mibs 文件夹中,但我认为真正有效的是将这些文件放入文件夹 /usr/lib/pytho*/site/pysnmp/smi/mibs/ 中.

正在开发 pysnmp-4.3.9

© www.soinside.com 2019 - 2024. All rights reserved.