在PySNMP代理中实现自定义MIB

时间:2012-08-31 13:03:08

标签: snmp pysnmp

我在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'

2 个答案:

答案 0 :(得分:1)

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

  1. 加载并继承MibScalarInstance类,然后覆盖其readGet()方法,使其返回实时值。然后实例化你的新类(确保传递它标识它的相应OID)并将其传递给exportSymbols(),因此它的OID将在pysnmp Agent上注册。

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

  3. 将所有代码保存在自己的MIB模块中可能是有意义的。看看pysnmp / smi / mibs / instances / * .py来了解一下。

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

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

答案 1 :(得分:0)

我也面临类似的问题:

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

正在研究pysnmp-4.3.9