为何IPAddress的MIB编码与Wireshark显示结果不一致?
SNMP中IP地址VLQ编码的疑问解析
背景与问题
根据RFC1155的3.2.3.2及第6节定义,IpAddress是代表32位互联网地址的应用层类型,以4字节网络字节序(大端序)的OCTET STRING表示;RFC1156的5.4.1则定义ipAddrEntry为包含IpAddress类型的ipAdEntAddr在内的SEQUENCE。
按此规范,IPAddress应是4字节大端序格式,但在Wireshark中查看OID请求时,IP地址192.168.1.21的编码为81 40 81 28 01 15,既非4字节,也不是TLV编码,而是一种用第8位标识"非最后字节"的7位编码(疑似VLQ),例如:
1000 0001 0100 0000 => 1100 0000 1000 0001 0010 1000 => 1010 1000
疑问点:
- 若该编码为VLQ,其文档依据是什么?
- 为何Wireshark显示的内容与RFC中的定义不符?
核心解答
你看到的编码是SNMP OID子标识符的VLQ编码,而非IpAddress类型本身的编码——核心是混淆了「MIB对象值的编码」和「OID索引部分的编码」两个场景。
1. 文档依据:ASN.1 BER的子标识符编码
SNMP基于ASN.1 BER编码,RFC1157(SNMP v1规范)的附录B明确了OID的编码规则:每个子标识符采用可变长度7位编码(VLQ),字节最高位为1表示后续还有字节,为0表示当前是最后一个字节。
以你提供的编码81 40 81 28 01 15解析:
81 40→ 二进制10000001 01000000,去掉每个字节的最高位后合并为0000001 01000000=0xC0(即192)81 28→ 二进制10000001 00101000,合并后为0xA8(即168)01→ 最高位为0,直接取0x01(即1)15→ 最高位为0,直接取0x15(即21)
这正好对应IP地址192.168.1.21:IP的每个字节作为OID的子标识符,数值大于127的(192、168)需要多字节VLQ编码,小于127的(1、21)用单字节编码。
2. 与RFC定义的差异原因
你混淆了两个完全不同的编码场景:
- IpAddress类型的值:比如
ipAdEntAddr对象返回的结果,确实是4字节大端序OCTET STRING,完全符合RFC1155的定义。 - OID中的索引部分:当查询MIB表(如
ipAddrEntry)的特定行时,需要将IP地址作为索引附加到OID末尾,这部分索引是作为OID的子标识符存在,遵循ASN.1 BER对整数的VLQ编码规则,而非IpAddress类型的编码规则。
内容的提问来源于stack exchange,提问作者SpacemanScott
相关产品推荐
相关产品推荐

