【问题标题】:PySNMP 4.4 with Python 2.7 bulkCmd output not including child OID'sPySNMP 4.4 和 Python 2.7 bulkCmd 输出不包括子 OID
【发布时间】:2017-11-12 00:46:16
【问题描述】:

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

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

向单个网络设备发送单个 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'

【问题讨论】:

    标签: python networking pysnmp


    【解决方案1】:

    bulkSNMP 返回一个迭代器,而您在其上使用了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 相关的问题时,请注意缩进,因为它很重要。

    【讨论】:

    • 感谢soundstripe,这非常有效!下次发帖时我也会检查我的缩进。
    【解决方案2】:

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

    附注 1:如果您想获取位于 MIB 表列下方的托管对象(例如 IF-MIB::ifDescr 等),您可能不需要 lexicographicMode=True

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

    【讨论】:

    • 谢谢 IIya。我会考虑你的建议!
    猜你喜欢
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-29
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    • 2012-02-21
    相关资源
    最近更新 更多