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).
- A list (type 0x30) with a length of 52 bytes
- The version: SNMPv2.c (0=v1, 1=v2.c)
- The community string: "public". (note how this is send in cleartext)
- A SNMP get-response with length 39
- The request ID, a 32 bit integer.
- The error code, 0 means no error.
- The error index.
- A list with length 25
- A list with length 23
- An OID with length 8: 1.3.6.1.2.1.1.2.0
- 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.