解码SNMP PDU - 从哪里开始?

时间:2014-04-10 20:20:33

标签: decode snmp asn.1 ber

你好我这里的第一个问题,需要一点指导。

我正在研究一个主要用于解码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 (的GetResponse)。这些值代表什么? 非常感谢。

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

1 个答案:

答案 0 :(得分:6)

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

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

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
  5. 的SNMP get-response
  6. 请求ID,32位整数。
  7. 错误代码,0表示没有错误。
  8. 错误索引。
  9. 长度为25的列表
  10. 长度为23的列表
  11. 长度为8的OID:1.3.6.1.2.1.1.2.0
  12. 长度为11的OID:1.3.6.1.4.1.674.10895.3028
  13. 正如您所看到的,整数和字符串很容易,但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来分析数据包,它可以很好地将它们翻译成可读的东西。