ObjectIdentity.resolveWithMib() 无法解析 InetAddressIPv4 类型的实例索引

ObjectIdentity.resolveWithMib() fails to resolve instance indices with InetAddressIPv4 type

在行走 TCP-MIB::tcpConnectionTable 时,我注意到它们的 table 索引在调用 resolveWithMib() 后仍未解决;打开 MIB 仪器调试显示大小约束检查应用于文本 IP 地址值,而不是原始(4 字节)值。非 IP 地址 table 索引不会出现此问题,例如 IF-MIB::ifIndex.

重现:

from pysnmp.smi.rfc1902 import ObjectIdentity
from pysnmp.smi.builder import MibBuilder
from pysnmp.smi.compiler import addMibCompiler
from pysnmp.smi.view import MibViewController
from pysnmp.debug import Debug, setLogger

builder = MibBuilder()
addMibCompiler(builder)
builder.loadModules('IF-MIB')
builder.loadModules('TCP-MIB')
view = MibViewController(builder)

def doit(*poargs):
    print(ObjectIdentity(*poargs).resolveWithMib(view).getMibSymbol())

setLogger(Debug('all'))
doit('.1.3.6.1.2.1.2.2.1.2.1')
doit('.1.3.6.1.2.1.6.19.1.7.1.9.49.48.46.48.46.48.46.49.49.22.1.14.49.57.50.46.49.54.57.46.50.48.46.49.53.52.2629')

Returns:

2017-09-28 19:14:35,045 pysnmp: running pysnmp version 4.3.9
2017-09-28 19:14:35,045 pysnmp: debug category 'all' enabled
2017-09-28 19:14:35,045 pysnmp: resolving .1.3.6.1.2.1.2.2.1.2.1 as OID or label
2017-09-28 19:14:35,046 pysnmp: indexMib: re-indexing MIB view
2017-09-28 19:14:35,049 pysnmp: getNodeNameByOid: resolved :1.3.6.1.2.1.2.2.1.2.1 -> ('iso', 'org', 'dod', 'internet', 'mgmt', 'mib-2', 'interfaces', 'ifTable', 'ifEntry', 'ifDescr').1
2017-09-28 19:14:35,049 pysnmp: resolved ('.1.3.6.1.2.1.2.2.1.2.1',) into prefix ObjectName('1.3.6.1.2.1.2.2.1.2') and suffix ObjectName('1')
2017-09-28 19:14:35,049 pysnmp: getNodeNameByOid: resolved :1.3.6.1.2.1.2.2.1.2 -> ('iso', 'org', 'dod', 'internet', 'mgmt', 'mib-2', 'interfaces', 'ifTable', 'ifEntry', 'ifDescr').()
2017-09-28 19:14:35,049 pysnmp: resolved prefix ObjectName('1.3.6.1.2.1.2.2.1.2') into MIB node MibTableColumn((1, 3, 6, 1, 2, 1, 2, 2, 1, 2), DisplayString(subtypeSpec=ConstraintsIntersection(ValueSizeConstraint(0, 65535), ValueSizeConstraint(0, 255), ValueSizeConstraint(0, 255))))
2017-09-28 19:14:35,049 pysnmp: getNodeNameByOid: resolved :(1, 3, 6, 1, 2, 1, 2, 2, 1) -> ('iso', 'org', 'dod', 'internet', 'mgmt', 'mib-2', 'interfaces', 'ifTable', 'ifEntry').()
2017-09-28 19:14:35,049 pysnmp: resolved indices are (InterfaceIndex(1),)
('IF-MIB', 'ifDescr', (InterfaceIndex(1),))
2017-09-28 19:14:35,050 pysnmp: resolving .1.3.6.1.2.1.6.19.1.7.1.9.49.48.46.48.46.48.46.49.49.22.1.14.49.57.50.46.49.54.57.46.50.48.46.49.53.52.2629 as OID or label
2017-09-28 19:14:35,051 pysnmp: getNodeNameByOid: resolved :1.3.6.1.2.1.6.19.1.7.1.9.49.48.46.48.46.48.46.49.49.22.1.14.49.57.50.46.49.54.57.46.50.48.46.49.53.52.2629 -> ('iso', 'org', 'dod', 'internet', 'mgmt', 'mib-2', 'tcp', 'tcpConnectionTable', 'tcpConnectionEntry', 'tcpConnectionState').1.9.49.48.46.48.46.48.46.49.49.22.1.14.49.57.50.46.49.54.57.46.50.48.46.49.53.52.2629
2017-09-28 19:14:35,051 pysnmp: resolved ('.1.3.6.1.2.1.6.19.1.7.1.9.49.48.46.48.46.48.46.49.49.22.1.14.49.57.50.46.49.54.57.46.50.48.46.49.53.52.2629',) into prefix ObjectName('1.3.6.1.2.1.6.19.1.7') and suffix ObjectName('1.9.49.48.46.48.46.48.46.49.49.22.1.14.49.57.50.46.49.54.57.46.50.48.46.49.53.52.2629')
2017-09-28 19:14:35,051 pysnmp: getNodeNameByOid: resolved :1.3.6.1.2.1.6.19.1.7 -> ('iso', 'org', 'dod', 'internet', 'mgmt', 'mib-2', 'tcp', 'tcpConnectionTable', 'tcpConnectionEntry', 'tcpConnectionState').()
2017-09-28 19:14:35,051 pysnmp: resolved prefix ObjectName('1.3.6.1.2.1.6.19.1.7') into MIB node MibTableColumn((1, 3, 6, 1, 2, 1, 6, 19, 1, 7), Integer32(subtypeSpec=ConstraintsIntersection(ValueRangeConstraint(-2147483648, 2147483647), ConstraintsUnion(SingleValueConstraint(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))), NamedValues((('synReceived', 4), ('established', 5), ('finWait2', 7), ('timeWait', 11), ('finWait1', 6), ('lastAck', 9), ('closeWait', 8), ('deleteTCB', 12), ('closed', 1), ('closing', 10), ('listen', 2), ('synSent', 3)))))
2017-09-28 19:14:35,051 pysnmp: getNodeNameByOid: resolved :(1, 3, 6, 1, 2, 1, 6, 19, 1) -> ('iso', 'org', 'dod', 'internet', 'mgmt', 'mib-2', 'tcp', 'tcpConnectionTable', 'tcpConnectionEntry').()
2017-09-28 19:14:35,052 pysnmp: error resolving table indices at MibTableRow, (9, 49, 48, 46, 48, 46, 48, 46, 49, 49, 22, 1, 14, 49, 57, 50, 46, 49, 54, 57, 46, 50, 48, 46, 49, 53, 52, 2629): ConstraintsIntersection(ValueSizeConstraint(0, 65535), ValueSizeConstraint(4, 4)) failed at: ValueConstraintError("ValueSizeConstraint(4, 4) failed at: ValueConstraintError('10.0.0.11',)",) at InetAddressIPv4
2017-09-28 19:14:35,052 pysnmp: resolved indices are ((9, 49, 48, 46, 48, 46, 48, 46, 49, 49, 22, 1, 14, 49, 57, 50, 46, 49, 54, 57, 46, 50, 48, 46, 49, 53, 52, 2629),)
('TCP-MIB', 'tcpConnectionState', ((9, 49, 48, 46, 48, 46, 48, 46, 49, 49, 22, 1, 14, 49, 57, 50, 46, 49, 54, 57, 46, 50, 48, 46, 49, 53, 52, 2629),))

请注意 IF-MIB::ifDescr 的实例索引如何正确解析为 (InterfaceIndex(1),)TCP-MIB::tcpConnectionState 的实例索引未解析为 ((9, 49, 48, 46, ...),)

我该如何解决或解决这个问题?

在我看来,您正在传递格式错误的索引。例如,46 ASCII 序号表示 IPv4 点分表示法中的十进制点。这个点永远不应该被编码到 OID 中。

这是 tcpConnectionTable 的索引结构:

INDEX   { tcpConnectionLocalAddressType,
          tcpConnectionLocalAddress,
          tcpConnectionLocalPort,
          tcpConnectionRemAddressType,
          tcpConnectionRemAddress,
          tcpConnectionRemPort }

所有这些组件都应该在任何有效索引中结束。如果我拿着你的复制器并尝试反向转换,例如从符号索引(很容易手工构建)到 OID 并返回:

oid = ObjectIdentity('TCP-MIB', 'tcpConnectionState', 
                     'ipv4', '10.0.0.11', 22,
                     'ipv4', '10.0.0.11', 1024).resolveWithMib(view)
print(oid)
mib_obj = ObjectIdentity(oid).resolveWithMib(view)
print(mib_obj.getMibSymbol())

我可以看到索引是如何编码到 OID 中的,并证明 pysnmp 可以将它们解码回来:

1.3.6.1.2.1.6.19.1.7.1.4.10.0.0.11.22.1.4.10.0.0.11.1024
('TCP-MIB', 'tcpConnectionState', 
 (InetAddressType('ipv4'), InetAddressIPv4(hexValue='0a00000b'), InetPortNumber(22),
  InetAddressType('ipv4'), InetAddressIPv4(hexValue='0a00000b'), InetPortNumber(1024)))