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

Greetings,

I have two protocols that are encapsulated like so: TCP or UDP -> proto1 -> proto2.

I have created a heuristic dissector for proto1 that is registered to TCP or UDP (my protocols can run over either). This works fine, and in the Wireshark GUI I see proto1 being dissected, with its tree information being populated appropriately. I then created a subdissector proto2, that is registered to proto1. Through the debug window I can see control being passed from proto1 to proto2 for an applicable packet, and furthermore, proto2 is updating the 'Protocol' field in the Wireshark GUI of its abbreviated protocol name. However, proto2's tree information is not showing up in the GUI.

Through debugging I have verified that the tree is being passed correctly from proto1 to proto2, that the applicable tree parameters inside proto2 are not NULL and do not have -1 values. I've even restructured proto2 to be a heuristic dissector for TCP or UDP and in this case, the tree information is present in the Wireshark GUI. My hypothesis is that I am missing something between the call to the subdissector, as in something isnt being saved or passed correctly. One concern I have is that proto2's abbreviated name is in the syntax proto_2 with the underscore, filenames, variable/method declarations all use the underscore for the protocols abbreviation - could this be an issue? (clearly I'm exhausted on ideas)
Any help is appreciated.

Code Snippets:

    PROTO1 CODE:
proto_register_proto1: 
    static hf_register_info hf[] = {
    ...
    { &hf_proto1_prot_id,
        { "Protocol Identifier", "proto1.prot_id", FT_UINT16, BASE_HEX, VALS(0x1022), 0x0, 
        "Protocol Identifier", HFILL } }
    ...
    };
    ...
    subdissector_table = register_dissector_table("proto1.prot_id", 
        "Protocol Identifier", FT_UINT16, BASE_HEX);

dissect_proto1:
...

if (proto2_handoff){
    tvbuff_t *next_tvb;
gint len, reported_len;

len = tvb_length_remaining(tvb, 4);
reported_len = tvb_reported_length_remaining(tvb, PROTO1_HDR_LEN);
next_tvb = tvb_new_subset(tvb, PROTO1_HDR_LEN, len, reported_len);
    dissector_try_uint(subdissector_table, 0x1022, next_tvb, pinfo, tree);
}
...

PROTO2 CODE:
proto_reg_handoff_proto2:
...
ptoto2_handle = find_dissector("proto2");
dissector_add("proto1.prot_id", 0x1022, proto2_handle);
data_handle = find_dissector("data")
...
proto_register_proto2:
proto_proto2 = proto_register_protocol ("PROTO2 Protocol", "PROTO2", "proto2");

proto_register_field_array(proto_proto2, hf_proto2, array_length (hf_proto2));
proto_register_subtree_array (ett_proto2, array_length (ett_proto2));
register_dissector("proto2", dissect_proto2, proto_proto2);
...
dissect_proto2:
if (check_col(pinfo->cinfo, COL_PROTOCOL))
    col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_PROTO2); /* this works... */
if (tree) { /* we are being asked for details */
    guint32 offset = 0;
    guint32 length = 0;
/* through debugs I see control being passed here, tree != NULL and has the same value from when it was in proto1 */
proto2_item = proto_tree_add_item(tree, proto_proto2, tvb, 0, -1, FALSE);
    proto2_tree = proto_item_add_subtree(proto2_item, ett_proto2);
/* this appears to be the break, where these calls do not update the tree structure in the GUI */
}

asked 07 Sep '12, 08:12

iggy114's gravatar image

iggy114
1111
accept rate: 0%


You might try some of the following changes:

dissect_proto1:

if (proto2_handoff) {
    tvbuff_t *next_tvb;
    gint reported_len;

    /* Before calling proto2, verify reported_len > 0.
       Also, be sure call_dissector() is not encapsulated within an if (tree) {...} block. */
    reported_len = tvb_reported_length_remaining(tvb, PROTO1_HDR_LEN);
    if (reported_len > 0) {
        next_tvb = tvb_new_subset(tvb, PROTO1_HDR_LEN, -1, reported_len);
        call_dissector(proto2_handle, next_tvb, pinfo, tree);
    }  
}

proto_register_proto1:

/* Delete this:
subdissector_table = register_dissector_table("proto1.port_id", 
    "Protocol Identifier", FT_UINT16, BASE_HEX);
*/

proto_reg_handoff_proto1:

proto2_handle = find_dissector("proto2");

dissect_proto2:

if (tree) {
    /* Change FALSE to ENC_NA */
    proto2_item = proto_tree_add_item(tree, proto_proto2, tvb, 0, -1, ENC_NA);
    proto2_tree = proto_item_add_subtree(proto2_item, ett_proto2);

    /* 
       Now add stuff to proto2_tree, favoring proto_tree_add_item() and avoiding 
       proto_tree_add_text() for the most part, but don't put stuff in here that isn't
       allowed to be encapsulated within the if (tree) {...} block.
       Refer to doc/README.developer skeleton code for more details ...
     */
}

proto_reg_handoff_proto2:

/* Delete all this:
   ptoto2_handle = find_dissector("proto2");
   dissector_add("proto1.prot_id", 0x1022, proto2_handle);
   data_handle = find_dissector("data")
*/
permanent link

answered 07 Sep '12, 11:32

cmaynard's gravatar image

cmaynard ♦♦
9.4k1038142
accept rate: 20%

Thank you for your quick response.
I've implemented the changes you've suggested but am getting the same results. I've even gone as far to add an item to the proto2 tree thinking that it wont print to screen unless its populated but this has failed to render the tree as well.
Do you know if there is any legitimacy my concern over the naming syntax of proto2?
One thing I've noticed through my debugging is that

proto2_item = proto_tree_add_item(tree, proto_proto2, tvb, 0, -1, ENC_NA);

seems to not always return the same structure for each packet. Sometimes it will, sometimes it won't - any concern here?

(07 Sep '12, 12:56) iggy114

The naming syntax of proto2 should be fine, although on a somewhat related note, you might want to run your dissector through the tools/checkfiltername.pl script. Actually, you should run your dissector through all tools/check*.pl scripts.

How are you determining if (proto2_handoff)? Is it correct?

Does your proto1 happen to be over TCP? If so, look into using dissect_pdus() for TCP reassembly. You'll have to determine TCP vs. UDP, but there are examples for this. Temporarily, you might also want to change any if (tree) to if (1) to be sure call_dissector() isn't in one.

(07 Sep '12, 13:17) cmaynard ♦♦

If you still require further assistance, I'd recommend moving this discussion to the Wireshark developer's mailing list. As the FAQ states, this is a Q&A site, and not a discussion forum. I think the developer's mailing list would work better here.

(07 Sep '12, 13:21) cmaynard ♦♦
Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Question tags:

×23
×20
×19

question asked: 07 Sep '12, 08:12

question was seen: 2,158 times

last updated: 07 Sep '12, 13:21

p​o​w​e​r​e​d by O​S​Q​A