简体   繁体   English

pysnmp:如何使oid可写

[英]pysnmp: how to make an oid writable

I would like to emulate a SNMP device, who i don't have the MIB file from device. 我想模拟一个SNMP设备,但我没有该设备的MIB文件。 I just need to emulate one function, a writable OctectString value. 我只需要模拟一个函数,一个可写的OctectString值。

Here is my code: 这是我的代码:

from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher
from pysnmp.carrier.asynsock.dgram import udp, udp6
from pyasn1.codec.ber import encoder, decoder
from pysnmp.proto import api
import time, bisect
from pysnmp import debug

debug.setLogger(debug.Debug('all'))    

class SysDescr:
    name = (1, 3, 6, 1, 2, 1, 1, 1, 0)
    def __eq__(self, other): return self.name == other
    def __ne__(self, other): return self.name != other
    def __lt__(self, other): return self.name < other
    def __le__(self, other): return self.name <= other
    def __gt__(self, other): return self.name > other
    def __ge__(self, other): return self.name >= other
    def __call__(self, protoVer):
        return api.protoModules[protoVer].OctetString(
            'PySNMP responder'
            )

class Domabox:
    name = (1, 3, 6, 1, 2, 1, 1, 2, 0)
    def __eq__(self, other): return self.name == other
    def __ne__(self, other): return self.name != other
    def __lt__(self, other): return self.name < other
    def __le__(self, other): return self.name <= other
    def __gt__(self, other): return self.name > other
    def __ge__(self, other): return self.name >= other
    def __call__(self, protoVer):
        return api.protoModules[protoVer].OctetString(
            'Domabox responder'
            )


class Uptime:
    name = (1, 3, 6, 1, 2, 1, 1, 3, 0)
    birthday = time.time()
    def __eq__(self, other): return self.name == other
    def __ne__(self, other): return self.name != other
    def __lt__(self, other): return self.name < other
    def __le__(self, other): return self.name <= other
    def __gt__(self, other): return self.name > other
    def __ge__(self, other): return self.name >= other    
    def __call__(self, protoVer):
        return api.protoModules[protoVer].TimeTicks(
            (time.time()-self.birthday)*100
            )


class Remote:
    name = (1, 3, 6, 1, 2, 1, 1, 4, 0)
    def __eq__(self, other): return self.name == other
    def __ne__(self, other): return self.name != other
    def __lt__(self, other): return self.name < other
    def __le__(self, other): return self.name <= other
    def __gt__(self, other): return self.name > other
    def __ge__(self, other): return self.name >= other
    def __call__(self, protoVer):
        return api.protoModules[protoVer].OctetString(
            'Remote'
            )


mibInstr = (
    SysDescr(), Domabox(), Uptime(), Remote(),  # sorted by object name
    )

mibInstrIdx = {}
for mibVar in mibInstr:
    mibInstrIdx[mibVar.name] = mibVar

def cbFun(transportDispatcher, transportDomain, transportAddress, wholeMsg):
    while wholeMsg:
        msgVer = api.decodeMessageVersion(wholeMsg)
        pMod = api.protoModules[api.protoVersion1]
        reqMsg, wholeMsg = decoder.decode(
            wholeMsg, asn1Spec=pMod.Message(),
            )
        rspMsg = pMod.apiMessage.getResponse(reqMsg)
        rspPDU = pMod.apiMessage.getPDU(rspMsg)        
        reqPDU = pMod.apiMessage.getPDU(reqMsg)

        print "reqPDU", reqPDU
        varBinds = []; pendingErrors = []
        errorIndex = 0
        # GETNEXT PDU
        if reqPDU.isSameTypeWith(pMod.GetNextRequestPDU()):
            # Produce response var-binds
            for oid, val in pMod.apiPDU.getVarBinds(reqPDU):
                errorIndex = errorIndex + 1
                # Search next OID to report
                nextIdx = bisect.bisect(mibInstr, oid)
                if nextIdx == len(mibInstr):
                    # Out of MIB
                    varBinds.append((oid, val))
                    pendingErrors.append(
                        (pMod.apiPDU.setEndOfMibError, errorIndex)
                        )
                else:
                    # Report value if OID is found
                    varBinds.append(
                        (mibInstr[nextIdx].name, mibInstr[nextIdx](msgVer))
                        )
        elif reqPDU.isSameTypeWith(pMod.GetRequestPDU()):
            for oid, val in pMod.apiPDU.getVarBinds(reqPDU):
                if oid in mibInstrIdx:
                    varBinds.append((oid, mibInstrIdx[oid](msgVer)))
                else:
                    # No such instance
                    varBinds.append((oid, val))
                    pendingErrors.append(
                        (pMod.apiPDU.setNoSuchInstanceError, errorIndex)
                        )
                    break

        elif reqPDU.isSameTypeWith(pMod.setRequestPDU()):
            print "request ?"
        else:
            print "unsupported..."
            # Report unsupported request type
            pMod.apiPDU.setErrorStatus(rspPDU, 'genErr')
        pMod.apiPDU.setVarBinds(rspPDU, varBinds)
        # Commit possible error indices to response PDU
        for f, i in pendingErrors:
            f(rspPDU, i)
        transportDispatcher.sendMessage(
            encoder.encode(rspMsg), transportDomain, transportAddress
            )

    return wholeMsg

transportDispatcher = AsynsockDispatcher()
transportDispatcher.registerRecvCbFun(cbFun)

# UDP/IPv4
transportDispatcher.registerTransport(
    udp.domainName, udp.UdpSocketTransport().openServerMode(('localhost', 161))
)

# UDP/IPv6
transportDispatcher.registerTransport(
    udp6.domainName, udp6.Udp6SocketTransport().openServerMode(('::1', 161))
)

transportDispatcher.jobStarted(1)

try:
    # Dispatcher will never finish as job#1 never reaches zero
    transportDispatcher.runDispatcher()
except:
    transportDispatcher.closeDispatcher()
    raise

When i send a snmp write value, i got 当我发送snmp写值时,我得到了

;AttributeError: 'module' object has no attribute 'setRequestPDU'

from line 从线

elif reqPDU.isSameTypeWith(pMod.setRequestPDU()):

var reqPDU content: var reqPDU内容:

reqPDU SetRequestPDU().setComponentByPosition(0, Integer(1639861451)).setComponentByPosition(1, Integer('noError')).setComponentByPosition(2, Integer(0)).setComponentByPosition(3, VarBindList().setComponentByPosition(0, VarBind().setComponentByPosition(0, ObjectName(1.3.6.1.2.1.1.4.0)).setComponentByPosition(1, ObjectSyntax().setComponentByPosition(0, SimpleSyntax().setComponentByPosition(1, OctetString('57'))))))

Thanks. 谢谢。

You probably meant pMod.SetRequestPDU() in your code (notice capital 'S'). 您可能在代码中使用了pMod.SetRequestPDU()(注意大写的“ S”)。

However, instead of writing your own emulator, I'd suggest considering a general purpose SNMP simulator which could be configured to emulate a full blown SNMP-capable device. 但是,建议您不要考虑编写自己的模拟器,而应该考虑使用通用SNMP模拟器 ,该模拟器可以配置为模拟功能齐全的SNMP设备。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM