質問

Hello my first ever question on here, in need of bit of guidance.

I'm working on a packet sniffer mainly to decode SNMP PDUs, however I am not entirely sure where to go with it.

Simply put my packet sniffer can extract information from packets however I am interested in the data payload field. It is written in C++ and I am using winsock.

What way should I go about this? Are the SNMP fields encoded in basic encoding rules or will I have to delve into ASN.1?

I am only looking to decode those SNMP fields within the data payload field into human readable form. They are going to be dumped into a text file. So I will be looking at decoding OIDs also. I am verifying everything as I go along with Wireshark and using GETIF to query my SNMP node.

Any guidance is appreciated.

EDIT:

Thanks user1793963 very well explained. Sorry to all who have marked this as too broad.

To elaborate on my original question could anyone explain the initial part of the PDU itself.

Example: My program outputs these hex values 30 82 00 A3 02 01 00, which is SEQUENCE (30), LENGTH (82) and two other values. This is from a GetRequest PDU.

The GetResponse PDU shows these values 30 81 B7 02 01 00, SEQUENCE, 81 in LENGTH and another value.

Could someone explain the values marked in bold. If it uses the simple TLV structure what are the values representing? What I know is the start of the sequence (30) and the total PDU length (which is 82 and 81) and I know 02 01 00 are INTEGER 1 in LENGTH and VERSION 0 however I do not understand 00 A3 (GetRequest) and B7 (GetResponse). What do these values represent? Many thanks.

I am also using Wireshark to check values, however they do not state the start of the PDU sequence


Update, 9 years later :-)

30 82 00 A3 and 30 81 B7 02 the 30 is data type = sequence. Following that are (long) length fields (> 127 bytes).

The rule for large numbers is that only the lower 7 bits in the byte are used for holding the value (0-127). The highest order bit is used as a flag to let the recipient know that this number spans more than one byte. If more than two bytes are required to encode the number, all will have the top bit set apart from the last byte. Any number over 127 must be encoded using more than one byte.

役に立ちましたか?

解決

SNMP packets are encoded in ASN.1, but it's a very simple protocol (at least for SNMP v1 and v2.c, I do not have a lot of experience with v3). It uses a simple TLV structure: type, length, value. For example the bytes 0x4 0x6 0x70 0x75 0x62 0x6c 0x63 are a string (type 4) with length 6 and value "public". You can find a list of types here.

I find it useful to write out packages like this:

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

This is a response on a get request where I requested the OID 1.3.6.1.2.1.1.2.0 (sysObjectID).

  1. A list (type 0x30) with a length of 52 bytes
  2. The version: SNMPv2.c (0=v1, 1=v2.c)
  3. The community string: "public". (note how this is send in cleartext)
  4. A SNMP get-response with length 39
  5. The request ID, a 32 bit integer.
  6. The error code, 0 means no error.
  7. The error index.
  8. A list with length 25
  9. A list with length 23
  10. An OID with length 8: 1.3.6.1.2.1.1.2.0
  11. An OID with length 11: 1.3.6.1.4.1.674.10895.3028

As you can see integers and strings are easy, but OIDs are a bit trickier. First of all the first two parts ("1.3") are represented as a single byte (0x2b). They did this to make each message a few bytes shorter.

The second problem is representing numbers larger than 255. To do this SNMP uses only the 7 least significant bits to store data, the most significant bit is a flag to signal that the data continues in the next byte. Numbers lower than 128 are stored in a single byte.

  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

This method is also used if the length of a TLV field is larger than 127.

RFC1592 describes the structure of the messages, take a look at page 11 for a similar example.

I can also recommend using Wireshark to analyze packets, it does an excellent job of translating them to something readable.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top