pysnmp - nextCmd - 不检索下一个元素

时间:2017-09-22 08:24:08

标签: python python-3.x pysnmp

我是python的新手。我正在尝试理解pysnmp的用法。

我尝试了以下内容:

import asyncio
from pysnmp.hlapi.asyncio import *
from pysnmp import debug

@asyncio.coroutine
def run():
    snmpEngine = SnmpEngine()
    while True:
        errorIndication, errorStatus, errorIndex, varBinds = yield from nextCmd(
            snmpEngine,
            CommunityData('public', mpModel=1),
            UdpTransportTarget(('giga-int-2', 161)),
            ContextData(),
            ObjectType(ObjectIdentity('1.3.6.1.2.1.31.1.1.1.1')),
            lexicographicMode=False
        )

        if errorIndication:
            print(errorIndication)
            break
        elif errorStatus:
            print('%s at %s' % (
                errorStatus.prettyPrint(),
                errorIndex and varBinds[int(errorIndex) - 1][0] or '?')
            )
        else:
            for varBind in varBinds:
                for v in varBind:
                    print(' = '.join([x.prettyPrint() for x in v]))

    snmpEngine.transportDispatcher.closeDispatcher()

asyncio.get_event_loop().run_until_complete(run())

结果我总是得到相同的界面。怎么了?为什么不检索下一个元素?

SNMPv2-SMI::mib-2.31.1.1.1.1.1 = sc0
SNMPv2-SMI::mib-2.31.1.1.1.1.1 = sc0
SNMPv2-SMI::mib-2.31.1.1.1.1.1 = sc0

4 个答案:

答案 0 :(得分:1)

这是有效的。但我想避免使用明确的next(),它不适合asyncio

from pysnmp.hlapi import *
from pysnmp import debug
g = nextCmd(
    SnmpEngine(),
    CommunityData('public', mpModel=1),
    UdpTransportTarget(('giga-int-2', 161)),
    ContextData(),
    ObjectType(ObjectIdentity('1.3.6.1.2.1.31.1.1.1.1')),
    lexicographicMode=False
)

while True:
    try:
        errorIndication, errorStatus, errorIndex, varBinds = next(g);
        if errorIndication:
            print(errorIndication)
        elif errorStatus:
            print('%s at %s' % (errorStatus.prettyPrint(), errorIndex and     varBinds[int(errorIndex) - 1][0] or '?'))
        else:
            for name, val in varBinds:
                print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
    except StopIteration:
        break

答案 1 :(得分:0)

我希望这段代码对您有用。它是异步的,不包含显式调用。

import asyncio
from pysnmp.hlapi.asyncio import *


@asyncio.coroutine
def getone(snmpEngine, target):
    errorIndication, errorStatus, errorIndex, varBinds = yield from getCmd(
        snmpEngine,
        CommunityData('public', mpModel=1),
        UdpTransportTarget(('giga-int-2', 161)),
        ContextData(),
        target
    )

    if errorIndication:
        print(errorIndication)
    elif errorStatus:
        print('%s at %s' % (
            errorStatus.prettyPrint(),
            errorIndex and varBinds[int(errorIndex) - 1][0] or '?'
        )
              )
    else:
        for varBind in varBinds:
            print(' = '.join([x.prettyPrint() for x in varBind]))


snmpEngine = SnmpEngine()

loop = asyncio.get_event_loop()
loop.run_until_complete(
    asyncio.wait([getone(snmpEngine, ObjectType(ObjectIdentity('1.3.6.1.2.1.31.1.1.1.' + str(n)))) for n in range(1,254)])

答案 2 :(得分:0)

在您循环内部,您将发送 SNMP GETNEXT命令并接收响应。您始终在同一个OID上发送相同的请求,这就解释了为什么您始终会收到相同的答案。 ; - )

要“遍历”SNMP代理,在每次迭代时,您需要发送对刚刚收到的OID的请求,以响应上一次迭代,直到您决定停止(或在代理处用完OID)。 p>

这是我未经测试过的代码,可以给你一个想法:

start_oid = ObjectType(ObjectIdentity('1.3.6.1.2.1.31.1.1.1.1'))
end_oid = ObjectType(ObjectIdentity('1.3.6.1.2.1.31.1.1.1.10'))
oid = start_oid

while oid < end_oid:
    errorIndication, errorStatus, errorIndex, varBinds = yield from nextCmd(
        snmpEngine,
        CommunityData('public', mpModel=1),
        UdpTransportTarget(('giga-int-2', 161)),
        ContextData(),
        oid
    )
    # ...omitted error checking...
    varBind = varBinds[0]
    # here we replacing the `oid` that goes into the next request
    oid, value = varBind

答案 3 :(得分:0)

这是我使用@Ilya Etingof的答案构建的解决方案。函数位于某些主机处理程序类中。

def inc_oid(self, oid):
    _oid = oid.split('.')
    lastint = int(_oid[-1])
    _oid[-1] = str(lastint + 1)
    return '.'.join(_oid)


async def snmp_walk_async(self, oid):
    resultstr = ''
    endoid = self.inc_oid(oid)
    while True:
        (errorIndication, 
        errorStatus, 
        errorIndex, 
        varBinds)  = await nextCmd(
                    self.snmpengine,
                    CommunityData(self.community, mpModel=0),
                    UdpTransportTarget((self.host, 161)),
                    ContextData(),
                    ObjectType(ObjectIdentity(oid)),
                    lexicographicMode=False)

        if errorIndication:
            print(errorIndication)
            break
        elif errorStatus:
            print('%s at %s' % (errorStatus.prettyPrint(),
                                errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
            break

        else:
            varBind = varBinds[0][0]
            oid, value = varBind
            oid = str(oid)

            if oid >= endoid:
                break

            for varBind in varBinds:
                resultstr += ' = '.join([x.prettyPrint() for x in varBind]) + '\n'

    return resultstr