我正在寻求标准化在PySNMP中检索OID索引的方式。无论OID和数据类型如何,我都需要“完全解析”所有索引。当索引由多个部分和不同的数据类型组成时,它会变得有些复杂。
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
我的最终目标是以dictionary(default dict)
的格式嵌套mib_dict[node][index] = value
,其中mib_dict
是我的默认字典的名称。
如您所知,我上面的代码不适用于所有OID。因为forLLDP-MIB::lldpLocManAddrIfId
的值index
是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中有一个快捷方式,使其更简单...
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句