带有 Python 2.7 bulkCmd 输出的 PySNMP 4.4 不包括子 OID

PySNMP 4.4 with Python 2.7 bulkCmd output not including child OID's

首先,我是 Python 和 PySNMP 的新手。我正在尝试将网络设备列表传递给 bulkCmd 以获取有关所有物理接口的信息。

目前它只收集第一个接口,然后移动到列表中的下一个网络设备。我已经对词典和 maxCalls 进行了更改,重复但 none 有任何不同。

在将单个 bulkCmd 发送到单个网络设备时,我已成功轮询所有接口。

代码:

from pysnmp.hlapi import *

routers = ["router1", "router2"]

#adds routers to getCmd and bulkCmd
def snmpquery (hostip):

    errorIndication, errorStatus, errorIndex, varBinds = next (
        bulkCmd(SnmpEngine(),
            CommunityData('communitystring'),
            UdpTransportTarget((hostip, 161)),
            ContextData(),
            0, 50,  
            ObjectType(ObjectIdentity('IF-MIB', 'ifDescr')),
            ObjectType(ObjectIdentity('IF-MIB', 'ifAlias')),
            ObjectType(ObjectIdentity('IF-MIB', 'ifOperStatus')),
            lexicographicMode=True
        )
    )

    # Check for errors and print out results
    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]))


# calls snmpquery for all routers in list
for router in routers:
    snmpquery(router)

输出:

IF-MIB::ifDescr.1 = GigabitEthernet0/0
IF-MIB::ifAlias.1 = InterfaceDesc
IF-MIB::ifOperStatus.1 = 'up'
IF-MIB::ifDescr.1 = GigabitEthernet0/0
IF-MIB::ifAlias.1 = InterfaceDesc
IF-MIB::ifOperStatus.1 = 'up'

bulkSNMP returns 一个迭代器并且您在其上使用 next() 它仅检索第一个迭代。您可能从 PySNMP documentation 那里得到了这个想法,它并没有很好地展示如何检索所有结果。

您应该使用 for 循环遍历所有迭代,如下所示:

from pysnmp.hlapi import *
routers = ["router1", "router2"]

def snmpquery (hostip):
    snmp_iter = bulkCmd(SnmpEngine(),
                        CommunityData('communitystring'),
                        UdpTransportTarget((hostip, 161)),
                        ContextData(),
                        0, 50,  
                        ObjectType(ObjectIdentity('IF-MIB', 'ifDescr')),
                        ObjectType(ObjectIdentity('IF-MIB', 'ifAlias')),
                        ObjectType(ObjectIdentity('IF-MIB', 'ifOperStatus')),
                        lexicographicMode=True)
    for errorIndication, errorStatus, errorIndex, varBinds in snmp_iter:
        # Check for errors and print out results
        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]))

# calls snmpquery for all routers in list
for router in routers:
    snmpquery(router)

此外,在发布 Python 相关问题时请注意缩进,因为它很重要。

您需要迭代由 bulkCmd 函数生成的生成器以重复 SNMP 查询以提取不适合先前响应数据包的 SNMP 管理对象。只需放弃 next() 调用并 运行 for 循环 bulkCmd().

旁注 1:如果您想获取驻留在 MIB table 列下方的托管对象(例如 IF-MIB::ifDescr 等),您可能不需要 lexicographicMode=True

旁注 2:如果您的网络上有许多 SNMP 代理,您可以考虑通过与 in parallel 对话来加快数据检索过程。您将使用相同的 getBulk() 调用,它只是执行并行性的底层网络 I/O。