将 OctetString 数据解包到变量中以进行进一步处理
Posted
技术标签:
【中文标题】将 OctetString 数据解包到变量中以进行进一步处理【英文标题】:Unpacking OctetString data into a variable for further processing 【发布时间】:2018-08-11 13:54:11 【问题描述】:全部 - 我正在使用 python 和 pysnmp 通过 snmp 收集 Cisco 发现协议数据。由于我正在使用 CDP,因此我使用的是CISCO-CDP-MIB.my,而我面临的问题是解压缩 cdpCacheCapabilities 和 cdpCacheAddressType 的内容。我看过很多示例并在我的代码中尝试过,但它们对我的特定场景没有帮助。请帮助我了解解包背后的原理,以便我不仅可以将它们应用于我正在工作的两个 MIB,而且还可以应用于其他也可能以打包格式返回数据的 MIB。 cdpCacheCapabilities 的结果应该类似于“00000040”,我已经能够打印结果,但是“0x”总是在我的值之前,我只需要这个值,没有符号。 cdpCacheAddress 的结果应该是一个十六进制的 IP 地址。对于 cdpCacheAddress,我需要先解压缩内容,从而留下一个十六进制字符串,然后将其转换为 IP 地址,即“192.168.1.10”。请解释您的答案背后的逻辑,以便我可以在其他情况下进行调整。谢谢
from pysnmp.hlapi import *
from pysnmp import debug
import binascii
import struct
#use specific flags or 'all' for full debugging
#debug.setLogger(debug.Debug('dsp', 'msgproc'))
for (errorIndication,
errorStatus,
errorIndex,
varBinds) in nextCmd(SnmpEngine(),
CommunityData('public'),
UdpTransportTarget(('10.1.1.1', 161)),
ContextData(),
ObjectType(ObjectIdentity('CISCO-CDP-MIB', 'cdpCacheCapabilities')),
lookupNames=True,
lookupValues=True,
lexicographicMode=False):
if errorIndication:
print(errorIndication)
break
elif errorStatus:
print('%s at %s' % (errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
break
else:
for varBind in varBinds:
value = varBind[-1]
arg = value.prettyPrint()
print(arg)
#dec = format(value,'x')
#dec = repr(value)
dec = struct.unpack('c',value)
print(dec)
【问题讨论】:
【参考方案1】:通过启用 MIB 查找,您要求 pysnmp 使用 MIB 将 SNMP 变量绑定对(OID 和值)转换为对人类友好的东西。
如果您只需要裸露的、未格式化的值,并假设这两个托管对象的类型是 OCTET STRING
,您可以在该值上调用 .asOctets()
或 .asNumbers()
方法来获取原始序列str|bytes
或 int
:
for oid, value in varBinds:
raw_string = value.asOctets()
raw_ints = value.asNumbers()
编辑:
一旦你有了原始值,你就可以把它们变成任何东西:
>>> ''.join(['%.2x' % x for x in b'\x00\x00\x04\x90'])
'00000490'
>>>
>>> '.'.join(['%d' % x for x in (10,0,1,202)])
'10.0.1.202'
【讨论】:
感谢您的意见,伊利亚!拳头,你在哪里建议我删除 MIB 查找?为了回答您的问题,我对 cdpCacheCapabilities 的最终目标是最终得到 8 个十六进制数字,而无需任何其他字符。当我使用建议的 .asOctets() 方法时,我的结果之一是b'\x00\x00\x04\x90'
在这种情况下,我只想要一个包含“00000490”的字符串变量。在 cdpCacheCapabilities 的情况下,我最终得到 (10,0,1,202)。在这种情况下,我需要一个包含 IP 地址的变量,即 =“10.0.1.202”。以上是关于将 OctetString 数据解包到变量中以进行进一步处理的主要内容,如果未能解决你的问题,请参考以下文章