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

How can I examine the actual value of a proto_item?

1

How can I examine the actual value of a proto_item in my dissector? I thought something like this would work:

...
{&hf_pfield,
    {"ProtoField", "proto.field", FT_UINT32, BASE_HEX,
      VALS(ProtoFieldValueString),
      ProtoFieldBitmask, "Proto Field", HFILL}}
...
void dissect_proto(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
    proto_item *p_item = NULL;
    guint32 guint32_value = 0;
    ...
    if(tree) {
        p_item = ptvcursor_add(cursor, hf_pfield, 4, endianness);
        guint32_value = fvalue_get_uinteger(&(item->finfo->value)); /*Crash*/
        ...
    }
    ...

...but this pretty handily kills Wireshark every time, resulting in an uninformative "The application has requested the Runtime to terminate in an unusual way" dialog. (I think it's tripping an assertion somewhere, but I haven't been able to track it down yet). How can I access the data referenced by a proto_item without extracting it from the tvb again?

Edit: I know the tree is valid since the line in question is inside if(tree) {...}. In this case, is it even possible to examine the fvalue_t inside item->finfo? Alternatively, can I use the header field to extract the field value directly, rather than adding it to the tree first?

Edit: I've managed to track down the assetion that is failing, and it confuses me more. In fvalue_get_uinteger in epan/ftypes/ftypes.c:

guint32
fvalue_get_uinteger(fvalue_t *fv)
{
    g_assert(fv->ftype->get_value_uinteger);
    return fv->ftype->get_value_uinteger(fv);
}

When control reaches this from my dissector, fv->ftype->get_value_uinteger is 0x0, and fv->ftype seems to be a FT_PROTOCOL --except that the field, hf_pfield, indexes a FT_UINT32 field. Can anyone explain why the proto_item does not seem to hold the correct value type?

Edit Again: I have stepped through the entire dissection process for a single packet of my protocol. It turns out that the first time the line is reached (during the second pass, when tree is not NULL), p_item->finfo is correctly a FT_UINT32, and the correct value is, indeed, extracted. However, on the next pass (anyone know where I can find out what each pass is --I thought there were only two?), it is FT_PROTOCOL. It does not appear that I have overstepped any buffers, since all of the interceding canary checks come out just fine. It also does not appear that hf_pfield has been invalidated or corrupted, as it has the same value as during the first two passes. Can anyone shed some light on this for me?

asked 03 Nov '11, 15:57

multipleinterfaces's gravatar image

multipleinte...
1.3k152340
accept rate: 12%

edited 08 Nov '11, 14:08


2 Answers:

1

While I am still a little confused, I have found a fairly reasonable workaround for now.

if(tree)
{
    if(item->finfo->value.ftype->get_value_uinteger)
    {
        guint32_value = fvalue_get_uinteger(&(item->finfo->value));
        /* Do work with value */
    }
}

This appears to work, but I am still confused about why the ftype is different than what it is declared as sometimes. I think it would stand to reason that if a header field is registered as FT_UINT32 that I should be able to safely get a uinteger value from any proto_item for that field.

answered 09 Nov '11, 11:09

multipleinterfaces's gravatar image

multipleinte...
1.3k152340
accept rate: 12%

0

There is no guarantee that there is an item! If the tree argument to dissect_proto() is null, no protocol tree will be constructed, hence no item from the tree.

Unfortunately, there's no good idiom for that other than extracting it from the tvbuff again. Perhaps there should be ptvcursor_add_and_return_uint(), ptvcursor_add_and_return_ipv4(), ptvcursor_add_and_return_string() and so on, which return the item value through a pointer.

answered 03 Nov '11, 18:08

Guy%20Harris's gravatar image

Guy Harris ♦♦
17.4k335196
accept rate: 19%

You are correct, although I should have said that the lines in question are within an if(tree) { ... } block. I'll update my question.

(04 Nov '11, 06:08) multipleinte...