This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

Can I extract data from the tvb using a header field?

0

Can I use a header field to extract data from a tvb?

In an earlier question I was trying to extract data from a processed proto_item, which I was only able to solve with a hack. After looking through the latest tvbuff.h, proto.h, etc, I didn't see any functions that looked like they performed this function. I've drilled down through proto_tree_add_item to see how it is normally accomplished, and there appears to be a lot of machinery involved in picking a few bits out of the supplied tvbuff_t. I would rather avoid using the tvb_get_bits family of functions if possible to reduce the number of offset calculations performed within each dissector.

Is there a way to use the hfindex populated by proto_register_field_array with a given offset and tvbuff_t to extract the data for use in dissector logic? You can assume that I don't need data wider than 32 bits, although a general solution is obviously welcome.

As an example, say a dissector has the following:

static int hf_myBits = -1;
static hf_register_info hf[] = {
    {&hf_myBits, {"Some bits",
        "my_proto.my_bits", FT_UINT16, BASE_HEX, NULL, 0xFFF0, "Some important bits", HFILL}}
}

hf is then registered in proto_register_my_proto, and at some point in dissect_my_proto:

static void dissect_my_proto(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    //...
    proto_tree_add_item(pMyTree, hf_myBits, tvb, some_offset, 2, ENC_LITTLE_ENDIAN);
my_bits_value = tvb_get_something(tvb, some_offset, hf_myBits); // !
if(my_bits_value == SOME_IMPORTANT_VALUE)
{
    //dissect the rest of the data as ABC
} else {
    //dissect the rest of the data as XYZ
}
//...

}

What function would I call on the line marked with // !?

asked 23 Jan ‘15, 10:04

multipleinterfaces's gravatar image

multipleinte…
1.3k152340
accept rate: 12%


2 Answers:

0

Is there a way to use the hfindex populated by proto_register_field_array with a given offset and tvbuff_t to extract the data for use in dissector logic?

Generally no, not easily. There are a couple of functions in proto.h that both set the tree item and retrieve the value: proto_tree_add_bytes_item() and proto_tree_add_time_item(). But most proto.h functions just set the tree item, and it's up to you to get the value separately if you need the value for dissector logic. In theory you could get the field's value, after setting the tree item for it, by looking up the hfindex in the tree and getting its type and calling fvalue_get_uinteger or whatever. But really it's faster, easier, and clearer to just get the value you need by using tvb_get_guint16() or tvb_get_bits16() or whatever.

So for your example code it could be something like this:

my_bits_value = tvb_get_ntohs(tvb, some_offset);
if ((my_bits_value & SOME_VALUE_MASK) == SOME_IMPORTANT_VALUE)
{
    //dissect the rest of the data as ABC
} else {
    //dissect the rest of the data as XYZ
}

answered 24 Jan '15, 10:32

Hadriel's gravatar image

Hadriel
2.7k2939
accept rate: 18%

0

What might be best would be a family of proto_tree_add_ routines that take a pointer to a value as an argument, and return the value through that pointer regardless of whether anything was added to the protocol tree or not, e.g.

proto_item *proto_tree_add_uint_get_value(proto_tree *tree, int hfindex, tvbuff_t *tvb, const gint start, gint length, const guint encoding, guint *value);

However, those functions don't currently exist, so you'd have to fetch the value yourself, separately from putting it into the protocol tree.

answered 24 Jan '15, 16:50

Guy%20Harris's gravatar image

Guy Harris ♦♦
17.4k335196
accept rate: 19%

edited 24 Jan '15, 17:04