首页 > 解决方案 > 如何修复“此 OID 中当前不存在此类实例”

问题描述

我只是新来的 pysnmp 并且无法通过 snmp 从某些 cisco mibs 获取值。我怀疑问题在于将 MIB 加载到 pysnmp 中。如何告诉 pysnmp 将其查询定向到特定的 MIB?

我遵循了 pysnmp 网站上的示例,并且可以检索提供的示例中使用的 OID。

我在 Windows 2012 服务器上使用 python3。

这是 pysnmp 网站上用于 SNMPv2-MIB 的示例,并且有效。

def snmp_get(ip, community):
    errorIndication, errorStatus, errorIndex, varBinds = next(
    getCmd(SnmpEngine(),
           CommunityData(community),
           UdpTransportTarget((ip, 161), timeout=1.0, retries=0),
           ContextData(),
           ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0'))
           )
    )

    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]))

    return

运行时返回以下内容:

SNMPv2-MIB::sysDescr.0 = Cisco IOS 软件、C800 软件 (C800-UNIVERSALK9-M)、版本 15.4(3)M3、发布软件 (fc2) 技术支持:http ://www.cisco.com/techsupport版权所有(c) Cisco Systems, Inc. 1986-2015 由 prod_rel_team 于 2015 年 6 月 5 日星期五 16:04 编译

我正在尝试使用 CISCO-WAN-3G-MIB 检索一堆 OID,其中一个用于 c3gGsmLac,即 .1.3.6.1.4.1.9.9.661.1.3.2.1.1

当我用这个 OID 替换 ObjectIdentity 时,我收到以下错误:

SNMPv2-SMI::enterprises.9.9.661.1.3.2.1.1 = 此 OID 当前不存在此类实例。

这是我迷路的地方,因为我知道该实例存在。我可以通过 net-snmp 手动对同一 OID 的设备进行 snmpwalk:

c:\sanitised>snmpwalk -v 2c -c snmpcommunity 1.1.1.1 .1.3.6.1.4.1.9.9.661 .1.3.2.1.1 CISCO-WAN-3G-MIB::c3gGsmLac.13 = Gauge32: 12374

pysnmp 脚本错误表明它正在尝试在 SNMPv2-SMI 下找到该 oid,但它不在那个下,它在 CISCO-WAN-3G-MIB 下。

如何告诉 pysnmp 在不同的 MIB 下查看?

我已经尝试根据我在文档中找到的一些代码来指定:

ObjectType(ObjectIdentity('CISCO-WAN-3G-MIB', 'c3gGsmLac', 13))

这也有效,返回以下输出:

思科-WAN-3G-MIB::c3gGsmLac.13 = 12374

但这并不是真正的解决方案,因为数字 13 并不总是数字 13。它可能因设备而异,我不会提前知道它的数字是多少。

我已经尝试将 MIB 编译成 .py 文件并将它们存储在我的 C:\Program Files\Python37\Lib\site-packages\pysnmp_mibs\ 目录中,但这并没有做任何事情。我也尝试将它们复制到我的 MIBDIRS 环境变量路径中,但这也没有显示任何变化,我仍然收到错误消息。

谁能告诉我如何告诉 pysnmp 在 CISCO-WAN-3G-MIB 中查找 c3gGsmLac?或者如何让它只响应“.1.3.6.1.4.1.9.9.661.1.3.2.1.1”表示?

谢谢

编辑:以下似乎有效:

def snmp_get(ip, community):      
    for (errorIndication,
     errorStatus,
     errorIndex,
     varBinds) in bulkCmd(SnmpEngine(),
                          CommunityData(community),
                          UdpTransportTarget((ip, 161)),
                          ContextData(),
                          0, 50,
                          ObjectType(ObjectIdentity('CISCO-WAN-3G-MIB', 'c3gGsmLac')),
                          ObjectType(ObjectIdentity('CISCO-WAN-3G-MIB', 'c3gGsmCurrentCellId')),
                          lexicographicMode=False):

        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]))

    return

标签: pythonpysnmp

解决方案


要回答您的问题:

SNMPv2-SMI::enterprises.9.9.661.1.3.2.1.1 = 此 OID 当前不存在此类实例。

此错误应该来自您的代理。可能是您缺少标识托管对象实例的 OID 的尾部。

如何告诉 pysnmp 在不同的 MIB 下查看?

您需要预加载包含您的代理将响应的对象的 MIB。

我已经尝试按照我在文档中找到的一些代码指定:

这有效地加载了 MIB。

但这并不是真正的解决方案,因为数字 13 并不总是数字 13。它可能因设备而异,我不会提前知道它的数字是多少。

好吧,看来您正在获取 MIB 表对象。根据该表的性质,索引(例如 13)可能会来来去去,也可能会有所不同。确切的行为通常在 MIB 本身(DESCRIPTION 子句)中描述。

我认为 SNMP 本身没有任何东西可以让您可靠地枚举这些对象。问题是它们只是对底层系统资源的看法。例如,它可以是磁盘驱动器或网络接口。随着时间的推移,他们的存在和他们的名字可能会非常不稳定。

为了缓解这种情况,SNMP 具有 GETNEXT/GETBULK 命令,可让您发现此时实际存在的内容。

如果它们完全可用,我建议阅读 MIB 以获取更多提示,并将其反映在您的应用程序代码中。


推荐阅读