Wireshark-dev: Re: [Wireshark-dev] How can I re-use definition of hf[]?

From: "Tamazov, Artem" <artem.tamazov@xxxxxxxxxxx>
Date: Wed, 8 Apr 2009 06:56:14 -0500
This will work, or course, but let's consider the drawbacks.
 
I have evaluated this approach for the case of ATM PW dissection (4 protocols, n:1 and 1:1,
with and without Control Word). It looks that it leads to:
- total 9 protocol dissectors
- 3 of them are "wrappers" in the sense that they do not have data for the tree
- 6 of them are "helpers" in the sense that thay do not have worth by themselves
     - for example one of them may be described as "MPLS PW ATM 1:1 CW without ATM-specific byte"; it
       should dissect 3 first bytes of the 4-byte Control Word.
- protocol tree will be too flat (more like list, not tree)
 
Perhaps I will use your idea, but with some trick: I will tell what I want to decode by means of
specifying tvb size. This way I can reduce number of "helper" dissectors.
For example, I can make "MPLS PW ATM 1:1 CW" dissector so it will decode:
- ATM-specific byte only if tvb size is 1
- Full CW if tvb size is 4.
 
I do not like this approach mostly because things like "MPLS PW ATM 1:1 CW" are just pieces of data,
not protocols. But it looks that I do not have other options (except copy-paste technology ;).
 
I will appreciate any other ideas.
 
Anyway thank you very much for help!
artem//
 


From: wireshark-dev-bounces@xxxxxxxxxxxxx [mailto:wireshark-dev-bounces@xxxxxxxxxxxxx] On Behalf Of Abhik Sarkar
Sent: Wednesday, April 08, 2009 10:10 AM
To: Developer support list for Wireshark
Subject: Re: [Wireshark-dev] How can I re-use definition of hf[]?

How about registering a third common protocol PROTO, putting the common fields in that and then calling dissect methods in the common dissector from the variant dissectors? Would that work?

On Tue, Apr 7, 2009 at 8:06 PM, Tamazov, Artem <artem.tamazov@xxxxxxxxxxx> wrote:

Hello,

I would like to implement two dissectors which are very similar.
How can I re-use definition of hf[]?

See sample code below (question is in comments):

==================
...
static int proto_PROTOABBREV_VARIATION_A = -1;
static int proto_PROTOABBREV_VARIATION_B = -1;
static int hf_PROTOABBREV_FIELDABBREV = -1;
static gint ett_PROTOABBREV = -1;

static int dissect_PROTOABBREV_VARIATION_A(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
...
}

static int dissect_PROTOABBREV_VARIATION_B(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
...
}

void proto_register_PROTOABBREV(void)
{
       static hf_register_info hf[] = {
               { &hf_PROTOABBREV_FIELDABBREV,
                       { "FIELDNAME",           "PROTOABBREV.FIELDABBREV",
                       FIELDTYPE, FIELDBASE, FIELDCONVERT, BITMASK,
                       "FIELDDESCR", HFILL }
               }
       };

       static gint *ett[] = {
               &ett_PROTOABBREV
       };

       proto_PROTOABBREV_VARIATION_A = proto_register_protocol("PROTONAME VARIATION A",
           "PROTOSHORTNAME A", "PROTOABBREVA");
       proto_PROTOABBREV_VARIATION_B = proto_register_protocol("PROTONAME VARIATION B",
           "PROTOSHORTNAME B", "PROTOABBREVB");

       proto_register_field_array(proto_PROTOABBREV_VARIATION_A, hf, array_length(hf));
       /*
        * *QUESTION*:
        *      AFAIK double registration of hf[] is wrong, although currently Wireshark
        *      tolerates this. How to _properly_ re-use hf[] in variation B?
      */
       proto_register_field_array(proto_PROTOABBREV_VARIATION_B, hf, array_length(hf));
       proto_register_subtree_array(ett, array_length(ett));
}

void
proto_reg_handoff_PROTOABBREV(void)
{
       dissector_handle_t PROTOABBREV_handle;
       PROTOABBREV_handle = new_create_dissector_handle(dissect_PROTOABBREV_VARIATION_A, proto_PROTOABBREV_VARIATION_A);
       dissector_add("PARENT_SUBFIELD", ID_VALUE, PROTOABBREV_handle);
       PROTOABBREV_handle = new_create_dissector_handle(dissect_PROTOABBREV_VARIATION_B, proto_PROTOABBREV_VARIATION_B);
       dissector_add("PARENT_SUBFIELD", ID_VALUE, PROTOABBREV_handle);
}
==================

I see one possible way -- using of C preprocessor capabilities:

==================
...
static int hf_PROTOABBREV_FIELDABBREV_for_A = -1;
static int hf_PROTOABBREV_FIELDABBREV_for_B = -1;
...
#define HF_INITIALIZER_FIELDABBREV(hf_handle)\
               { &(hf_handle),\
                       { "FIELDNAME",           "PROTOABBREV.FIELDABBREV",\
                       FIELDTYPE, FIELDBASE, FIELDCONVERT, BITMASK,\
                       "FIELDDESCR", HFILL }\
               }\
       }
...
       static hf_register_info hf_a[] = HF_INITIALIZER_FIELDABBREV(hf_PROTOABBREV_FIELDABBREV_for_A);
       static hf_register_info hf_b[] = HF_INITIALIZER_FIELDABBREV(hf_PROTOABBREV_FIELDABBREV_for_B);
...
       proto_register_field_array(proto_PROTOABBREV_VARIATION_A, hf_a, array_length(hf_a));
       proto_register_field_array(proto_PROTOABBREV_VARIATION_B, hf_b, array_length(hf_b));
...
==================

But this solution is not elegant, I guess.
Any ideas?

Thank you in advance,
artem//

============================================================
The information contained in this message may be privileged
and confidential and protected from disclosure. If the reader
of this message is not the intended recipient, or an employee
or agent responsible for delivering this message to the
intended recipient, you are hereby notified that any reproduction,
dissemination or distribution of this communication is strictly
prohibited. If you have received this communication in error,
please notify us immediately by replying to the message and
deleting it from your computer. Thank you. Tellabs
============================================================