如何在 PySNMP 中规范 OID 索引检索?

How to standardize OID index retrieval in PySNMP?

我希望标准化我在 PySNMP 中检索 OID 索引的方式。无论 OID 和数据类型如何,我都需要将所有索引设为 "fully resolved"。当索引由多个部分和不同数据类型组成时,它会变得有点复杂。

def execute_snmp(transactions, address, pp=True):
    mib_dict = defaultdict(dict)
    for ei, es, ex, vb in transactions:
        if ei:
            raise SNMPAgentUnreachable(ei)
        elif es:
            err_reason = f"{es.prettyPrint()} {ex and transactions[int(ex) - 1][0] or '?'}"
            raise ValueError(err_reason)
        else:
            for mib, val in vb:
                node, index_tuple = mib.getMibSymbol()[1:]
                # print('.'.join(('%d' % x for x in index_tuple[1].asNumbers())))
                # print(*(type(x) for x in index_tuple))
                index = '.'.join(x.prettyPrint() for x in index_tuple)
                print(mib, mib.prettyPrint(), mib.prettyPrint().split('.', 1)[-1], index, sep=' ====== ')
                value = val.prettyPrint() if pp else val
                mib_dict[node][index] = value

以上代码的示例输出如下所示:

# 1.0.8802.1.1.2.1.3.8.1.5.1.4.10.0.1.200 ====== LLDP-MIB::lldpLocManAddrIfId.ipV4."0x0a0001c8" ====== ipV4."0x0a0001c8" ====== ipV4.0x0a0001c8
# 1.3.6.1.2.1.17.4.3.1.1.228.224.166.29.95.216 ====== BRIDGE-MIB::dot1dTpFdbAddress."e4:e0:a6:1d:5f:d8" ====== "e4:e0:a6:1d:5f:d8" ====== e4:e0:a6:1d:5f:d8
# 1.3.6.1.2.1.4.22.1.4.1.10.0.1.220 ====== IP-MIB::ipNetToMediaType.1.10.0.1.220 ====== 1.10.0.1.220 ====== 1.10.0.1.220

我的最终目标是以 mib_dict[node][index] = value 格式的嵌套 dictionary(default dict) 结束,其中 mib_dict 是我默认词典的名称。

如您所知,我的上述代码不适用于所有 OID。对于 LLDP-MIB::lldpLocManAddrIfIdindex 的值是 ipV4.0x0a0001c8 而不是 1.4.10.0.1.200。我可以通过执行以下操作获取索引的 IP 地址部分:print('.'.join(('%d' % x for x in index_tuple[1].asNumbers()))) 但这不适用于没有 asNumbers() 属性的索引。

我怎样才能编写一段适用于所有 OID 的索引的代码,而不管 OID 的长度和组成(数据类型)?有没有一种方法可以将相同的原理应用于提取值?

我不确定什么是理想的 index 类型...一种可能性是那里只有未解析的 OID,它的索引部分。如果这是可行的方法,也许您可​​以通过从托管对象实例 OID 中删除索引部分来计算它。

要找出切割OID的位置,您可以使用与MIB管理对象关联的OID(例如LLDP-MIB::lldpLocManAddrIfId)-它是OID的静态前缀,不包括任何变量索引部分:

for var_bind in var_binds:
    object_identity, value = var_bind
    mib_node = object_identity.getMibNode()
    object_instance_oid = object_identity.getOid()
    object_oid = mib_node.getName()
    index_part = object_instance_oid[len(object_oid):]

我们应该在 pysnmp 中有一个快捷方式以使其更简单...