Wireshark-dev: [Wireshark-dev] Follow up on SNMP VarBind values

From: Jaap Keuter <jaap.keuter@xxxxxxxxx>
Date: Thu, 20 Jan 2011 17:56:42 +0100
Hi list,

Ref:
[1] RFC 2578 (http://tools.ietf.org/html/rfc2578)
[2] X.690 (http://www.itu.int/rec/T-REC-X.690-200811-I)
[3] epan/oids.c (http://anonsvn.wireshark.org/viewvc/trunk-1.4/epan/oids.c?revision=34416&view=markup)
[4] Bug 2468 (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=2468)
[5] Revision 25148 (http://anonsvn.wireshark.org/viewvc?view=rev&revision=25148)

I was researching a bug relating to value presentations of a Gauge32 [1] and found that it doesn't work for values larger than 2147483647. This value (in base 16) is 7FFFFFFF, which means that any larger value sets the most significant bit of the 32 bit field.

Normally when the most significant bit is set this indicated a negative number, i.c.o. a signed value. The Gauge32 type is defined as IMPLICIT INTEGER (0..4294967295), hence unsigned.

The Basic Encoding Rules [2] state in 8.3 "Encoding of an integer value" that "The contents octets shall be a two's complement binary number equal to the integer value". Therefore it is treated as a signed value.

In order to encode our unsigned 32 bit value with the most significant bit set, we must prefix it with a '00' byte. That allows us to have a 32 bit unsigned value in a variable sized, signed integer type field.

Unfortunately this brings us trouble when using the presentation functions of Wireshark. These encoded(!) integer value types are directly mapped onto Wireshark integer types, see oids.c [3]. That works as long as the positive values are small, but when the limits of the Wireshark integer types are reached, the encoding comes into play.

When encoding these large positive values, the encoded result will become 5 bytes long (leading '0' bytes for positive value, 4 bytes for the value itself, with the most significant bit set). When coding presentation of an FT_UINT32, the field length may not be longer than 4 bytes, which fits the maximum size of an unencoded(!) unsigned integer, but not the encoded(!) unsigned integer. Therefore when a field of size 5 is found, even though it holds a valid value, it's being rejected for presentation.

There are two solutions to this problem.

One is already implemented for a bug report [4], but only for timeticks_type ([APPLICATION 3]), see oids.c [3]. It uses the FT_UINT64 as a container for the 32 bit value.
This solution could be extended to the other types involved:
- Counter32 ([APPLICATION 1])
- Gauge32([APPLICATION 2])
Still it won't help with Counter64 ([APPLICATION 6]), which faces the same problem in the 64 bit field.

Another solution would be to acknowledge the encoding, extracting the value and decode it, before adding it for presentation. This solution would be suitable for both FT_UINT32 and FT_UINT64. Feasibility would have to be researched.

I intend to expand the solution created in r25148 [5] first, then work on the next solution (#include <stddisclaimer>).

Thanks,
Jaap