Wireshark-dev: Re: [Wireshark-dev] dissecting bits versus bytes

From: Brian Oleksa <oleksab@xxxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 17 May 2011 23:09:43 -0400
Jakub

I took your advice and am trying to use proto_tree_add_bits_item(). I am making some progress.....but when I come to the next multiple of 8 bits.....wireshark crashes.

Here is my current code base: I am stuck when I get to the URN (which is 24 bits).

Any help is greatly appreciated.

void dissect_vmf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {

    proto_item *vmf_item = NULL;
    proto_item *vmf_sub_item = NULL;
    proto_tree *vmf_tree = NULL;
    proto_tree *vmf_header_tree = NULL;

    guint8 fpi;
    guint8 gpi;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_VMF);
    col_clear(pinfo->cinfo, COL_INFO);

    if (tree) {
        guint8 bit_offset;
        guint32 offset;

        vmf_item = proto_tree_add_item(tree, proto_vmf, tvb, 0, -1, FALSE);
        vmf_tree = proto_item_add_subtree(vmf_item, ett_vmf);
        vmf_header_tree = proto_item_add_subtree(vmf_item, ett_vmf);

        vmf_header_tree = proto_item_add_subtree(vmf_sub_item, ett_vmf);
        {
            #define MAXIUM_BUFFER 1024
            char *buf = (char*)ep_alloc(MAXIUM_BUFFER);
            char * packet_name = "VMF Message Rev C";
            proto_tree *vmf_sub_tree = NULL;

            offset = 0;
            bit_offset = 4;

            g_snprintf(buf, BUFFER, "%s", packet_name);

            vmf_item = proto_tree_add_text(tree, tvb, offset, 0, "%s", buf);
            vmf_sub_tree = proto_item_add_subtree(vmf_item, ett_vmf);

            //Version
            proto_tree_add_bits_item(vmf_sub_tree, hf_vmf_version, tvb, bit_offset, 4, TRUE);

            bit_offset -= 1;

            //FPI
            fpi = tvb_get_bits8(tvb, bit_offset, 1);
            proto_tree_add_bits_item(vmf_sub_tree, hf_vmf_fpi, tvb, bit_offset, 1, TRUE);

            //Field presence indicator (FPI). If FPI = 1 then the next field is presence. If it = 0 than it is absence.
            if(fpi == 1)
            {
            //Data Compression type
                bit_offset -= 2;
                proto_tree_add_bits_item(vmf_sub_tree, hf_vmf_datacompressiontype, tvb, bit_offset, 2, TRUE);
            }

            if(fpi == 0)
            {
                bit_offset -= 1;
            }

            //GPI
            gpi = tvb_get_bits8(tvb, bit_offset, 1);
            proto_tree_add_bits_item(vmf_sub_tree, hf_vmf_gpi, tvb, bit_offset, 1, TRUE);

            //Group presence indicator (GPI). If GPI = 1 then the next field is presence. If it = 0 than it is absence.
            if(gpi == 1)
            {
            bit_offset -= 1;

            //FPI
              fpi = tvb_get_bits8(tvb, bit_offset, 1);
              proto_tree_add_bits_item(vmf_sub_tree, hf_vmf_fpi, tvb, bit_offset, 1, TRUE);

             if(fpi == 1)
                {
               
                //bit_offset -= 24;
                //URN
                proto_tree_add_bits_item(vmf_sub_tree, hf_vmf_urn, tvb, bit_offset, 24, TRUE);

                offset += 1;
                }

            }

        }
    }
}


void proto_register_vmf(void) {
    static hf_register_info hf[] = {
        { &hf_vmf_version,
            { "Version", "vmf.version", FT_UINT8, BASE_DEC, NULL, 0x0,
                NULL, HFILL}},
        { &hf_vmf_fpi,
            { "FPI", "vmf.fpi", FT_UINT8, BASE_DEC, NULL, 0x0,
                NULL, HFILL}},
        { &hf_vmf_fpi2,
            { "FPI", "vmf.fpi", FT_UINT8, BASE_DEC, NULL, 0x01,
                NULL, HFILL}},
        { &hf_vmf_fpi3,
            { "FPI", "vmf.fpi", FT_UINT8, BASE_DEC, NULL, 0x10,
                NULL, HFILL}},
        { &hf_vmf_datacompressiontype,
            { "Data Compression Type", "vmf.dataCompressionType", FT_UINT8, BASE_DEC, NULL, 0x0,
                NULL, HFILL}},
        { &hf_vmf_gpi,
            { "GPI", "vmf.gpi", FT_UINT8, BASE_DEC, NULL, 0x0,
                NULL, HFILL}},
           { &hf_vmf_urn,
            { "URN", "vmf.urn", FT_UINT32, BASE_DEC, NULL, 0x0,
                NULL, HFILL}}
    };

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

    proto_vmf = proto_register_protocol("VMF", "VMF", "vmf");
    proto_register_field_array(proto_vmf, hf, array_length(hf));
    proto_register_subtree_array(ett, array_length(ett));
    register_dissector("vmf", dissect_vmf, proto_vmf);
}



Here is a screen shot that reflects the above code:




How would you dissect this packet...??  Here is the layout of the packet.

bits 5-8 is the version:
bit 4 is the FPI
(if FPI ==1) then bits 3 and 2 is the data compression
(if FPI ==0) then the data compression does not exist...so bit 3 is now the GPI

(If GPI == 1) then the next field is present. So FPI is now bit 2
If GPI == 0 then the whole Group (G1) is not present.

I am currently stuck on the URN. It seams that if I do this:   proto_tree_add_bits_item(vmf_sub_tree, hf_vmf_urn, tvb, bit_offset, 24, TRUE);
Wireshark throws an error.


Here is the spec sheet:



Thanks,
Brian





On Tue, May 17, 2011 at 10:28:23AM -0400, Brian Oleksa wrote:
> I am dissecting bits not bytes. I am running into some problems.
> ... 
> Any help with this is greatly appreciated.
You can try using proto_tree_add_bits_item(), hth.
___________________________________________________________________________
Sent via:    Wireshark-dev mailing list <wireshark-dev@xxxxxxxxxxxxx>
Archives:    http://www.wireshark.org/lists/wireshark-dev
Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev
             mailto:wireshark-dev-request@xxxxxxxxxxxxx?subject=unsubscribe