3

您好,我在这里的第一个问题,需要一些指导。

我正在开发一个数据包嗅探器,主要用于解码 SNMP PDU,但是我不完全确定该去哪里。

简单地说,我的数据包嗅探器可以从数据包中提取信息,但是我对数据有效负载字段感兴趣。它是用 C++ 编写的,我使用的是winsock。

我应该怎么做?SNMP 字段是否在基本编码规则中编码,还是我必须深入研究 ASN.1?

我只是希望将数据有效负载字段中的那些 SNMP 字段解码为人类可读的形式。它们将被转储到文本文件中。所以我也会考虑解码 OID。我在使用 Wireshark 并使用 GETIF 查询我的 SNMP 节点时验证所有内容。

任何指导表示赞赏。

编辑:

感谢 user1793963 很好的解释。对所有将其标记为过于宽泛的人感到抱歉。

为了详细说明我最初的问题,任何人都可以解释 PDU 本身的初始部分。

示例:我的程序输出这些十六进制值 30 82 00 A3 02 01 00,即 SEQUENCE (30)、LENGTH (82) 和其他两个值。这是来自 GetRequest PDU。

GetResponse PDU 显示这些值 30 81 B7 02 01 00, SEQUENCE, 81 in LENGTH 和另一个值。

有人可以解释以粗体标记的值。如果它使用简单的 TLV 结构,代表什么值?我所知道的是序列的开始 (30) 和 PDU 总长度 (即 82 和 81),我知道 02 01 00 在 LENGTH 和 VERSION 0 中是 INTEGER 1 但是我不明白 00 A3 (GetRequest) 和 B7 (获取响应)。这些值代表什么?非常感谢。

我也在使用 Wireshark 来检查值,但是它们没有说明 PDU 序列的开始

4

1 回答 1

10

SNMP 数据包在 ASN.1 中编码,但它是一个非常简单的协议(至少对于 SNMP v1 和 v2.c,我对 v3 没有太多经验)。它使用简单的 TLV 结构:类型、长度、值。例如,字节0x4 0x6 0x70 0x75 0x62 0x6c 0x63是长度为 6 且值为“public”的字符串(类型 4)。您可以在此处找到类型列表。

我发现写出这样的包很有用:

1.  0x30 0x34
2.    0x2 0x1 0x1
3.    0x4 0x6 0x70 0x75 0x62 0x6c 0x63
4.    0xa2 0x27
5.      0x2 0x4 0x1 0x2 0x3 0x4 
6.      0x2 0x1 0x0
7.      0x2 0x1 0x0
8.      0x30 0x19
9.        0x30 0x17
10.         0x6 0x8 0x2b 0x6 0x1 0x2 0x1 0x1 0x2 0x0
11.         0x6 0xb 0x2b 0x6 0x1 0x4 0x1 0x85 0x22 0xd5 0xf 0x97 0x54

这是对我请求 OID 1.3.6.1.2.1.1.2.0 (sysObjectID) 的 get 请求的响应。

  1. 一个长度为 52 字节的列表(类型 0x30)
  2. 版本:SNMPv2.c (0=v1, 1=v2.c)
  3. 社区字符串:“public”。(注意这是如何以明文形式发送的)
  4. 长度为 39 的 SNMP 获取响应
  5. 请求 ID,一个 32 位整数。
  6. 错误代码,0 表示没有错误。
  7. 错误索引。
  8. 长度为 25 的列表
  9. 长度为 23 的列表
  10. 长度为 8 的 OID:1.3.6.1.2.1.1.2.0
  11. 长度为 11 的 OID:1.3.6.1.4.1.674.10895.3028

如您所见,整数和字符串很容易,但 OID 有点棘手。首先,前两部分(“1.3”)表示为单个字节(0x2b)。他们这样做是为了使每条消息缩短几个字节。

第二个问题是表示大于 255 的数字。为此,SNMP 仅使用 7 个最低有效位来存储数据,最高有效位是一个标志,表示数据在下一个字节中继续。小于 128 的数字存储在单个字节中。

  0x7f
= 0 111 1111
= 127

  0x85 0x22
= 1 000 0101, 0 010 0010
=   000 0101    010 0010
= 674

  0xc0 0x80 0x80 0x80
= 1 100 0000, 1 000 0000, 1 000 0000, 0 000 0000
=   100 0000    000 0000    000 0000    000 0000
= 0x8000000

如果 TLV 字段的长度大于 127,也可以使用此方法。

RFC1592描述了消息的结构,请查看第 11 页的类似示例。

我还可以推荐使用 Wireshark 来分析数据包,它在将它们转换为可读的东西方面做得很好。

于 2014-04-11T08:59:45.320 回答