当前位置: 动力学知识库 > 问答 > 编程问答 >

snmp - Implementing a custom MIB in a PySNMP agent

问题描述:

I'm having difficulty implementing a custom MIB in a PySNMP agent.

I've started with:

http://pysnmp.sourceforge.net/examples/4.x/v3arch/agent/cmdrsp.html

created my own MIB file, used build-pysnmp-mib to make a Python module and successfully imported the symbol.

I can't see where to go next. I need to somehow mount the imported symbol on the list of served MIBs and provide an implementation. (It's currently a MIB with one read-only INTEGER property.)

The MIB file passes smilint without warnings, but I've had to manually add a missing MibScalar import to the generated module.

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

Code:

#!/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()

Generated and amended 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)

Update:

I now have one error left:

$ 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

The debug is:

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'

网友答案:

As for implementing a Managed Object Instance, you have two choices:

  1. Load and subclass the MibScalarInstance class, then override its readGet() method to make it returning your live value. Then instantiate your new class (make sure to pass it appropriate OID that identifies it) and pass it to exportSymbols(), so its OID will get registered at pysnmp Agent.

  2. Load the Integer32 class, subclass it and override its "clone()" method to make it returning your live value. Then load the MibScalarInstance class, instantiate it passing appropriate OID and the instance of your Integer32 subclass, then pass MibScalarInstance object to exportSymbols(), so its OID will get registered at pysnmp Agent.

It may make sense to keep all your code in your own MIB module. Take a look at pysnmp/smi/mibs/instances/*.py to get an idea.

From within your Agent app, invoke mibBuilder.loadModules('TRC-MIB') to load your MIB module into Agent.

In your code you seem to somehow combine the above two approaches: MyDeliveryTime.readGet() will not work, however MyDeliveryTime.clone() or deliveryTimeInstance.readGet() will.

分享给朋友:
您可能感兴趣的文章:
随机阅读: