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

Recursively dissect data fields

0

I'm writing a dissector for what is essentially a Google Protocol Buffers message. The details aren't important; I end up with a number of fields of bytes. All this is working well.

Now, sometimes, and not intrinsically recognizable from the data, a field of bytes may itself be a full message. Is it possible to register the dissector so that I can select just the one data field and say "Decode as..." and interpret the field as another message?

proto_item *i = proto_tree_add_text(tree, tvb, offset, pre_len + data_len,
                                    "Length-prefixed Data");
proto_tree *t = proto_item_add_subtree(i, ett_protobuf);

proto_tree_add_text(t, tvb, offset, pre_len, "Len: %llu", pre_len); proto_tree_add_bytes(t, hf_protobuf_nested_type, tvb, offset + pre_len, data_len, tvb_get_ptr(tvb, offset + pre_len, data_len));

(Background: While Protocol Buffer messages contain enough information to describe how long each field is, there is no information on what the field means. It may be just a string of data, or it may be a nested message. That’s why there cannot be any other sensible default action that treat a field as an opaque byte string. Only the human operator, who can consult the out-of-band schema, can decide whether the byte string is actually supposed to be a nested message.)

asked 22 May ‘13, 06:27

LouisDx's gravatar image

LouisDx
11336
accept rate: 0%

edited 22 May ‘13, 06:47


2 Answers:

1

Is it possible to register the dissector so that I can select just the one data field and say "Decode As..."

Currently, "Decode As..." is not a general mechanism for which arbitrary dissectors can register a table (so that, for a packet containing the protocol the dissector handles, you can choose to decode something carried by that protocol as some other protocol) and arbitrary dissectors can register in that table (so that they can be chosen with "Decode As...".

You could create a preference in your dissector to let you select a protocol to decode the payload as.

answered 22 May '13, 12:45

Guy%20Harris's gravatar image

Guy Harris ♦♦
17.4k335196
accept rate: 19%

I understand. Thanks for clarifying!

(23 May '13, 04:59) LouisDx

1

It might be possible, but that would be really hard to implement.

Why not heuristically look at the data bytes. If you assume it is nested, you can extract the length field from the data bytes and then compare that to the actual length of the data bytes. If it matches, you can assume that it is indeed nested. If not, you must assume it is just a data field.

And maybe there are other constraints in the formatting of the data field that you could use to strengthen the heuristics.

answered 22 May '13, 08:01

SYN-bit's gravatar image

SYN-bit ♦♦
17.1k957245
accept rate: 20%

I don't like heuristics in that case. You can always cook up an actually intended string that just happens to look like a message... and you wouldn't know if it was an actual message until you parsed the whole thing. Can you run a dissector tenatively and see if it succeeds?

(22 May '13, 08:35) LouisDx

You would need a routine that just checks whether the tvb contains a valid "Google Protocol Buffer".

If it returns true, create a new tvb with the string data and recursively call your dissector on it. If not, just display the string data as string. Actually, I would always display the string and use a subtree when the string can be interpreted as an embedded message.

(22 May '13, 09:36) SYN-bit ♦♦

Yeah, I see. I was hoping I could have a UI action such as "decode as" that the user could trigger, without the need for looking ahead and attempting to parse... thanks anyway!

(22 May '13, 12:32) LouisDx