Wireshark-bugs: [Wireshark-bugs] [Bug 5110] New: Dissector of TFT - Traffic Flow Template(10.5.6

Date: Thu, 12 Aug 2010 23:32:56 -0700 (PDT)
https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5110

           Summary: Dissector of TFT - Traffic Flow Template(10.5.6.12)
                    incorrectly dissects Packet filter Components
           Product: Wireshark
           Version: 1.2.7
          Platform: x86
        OS/Version: Linux (other)
            Status: NEW
          Severity: Major
          Priority: Low
         Component: Wireshark
        AssignedTo: wireshark-bugs@xxxxxxxxxxxxx
        ReportedBy: jindalprateek87@xxxxxxxxx


Created an attachment (id=5048)
 --> (https://bugs.wireshark.org/bugzilla/attachment.cgi?id=5048)
packet-gsm_a_gm.c file with fixes - fixed_packet-gsm_a_gm.c in function
de_sm_tflow_temp

Build Information:
wireshark 0.99.3a

Copyright 1998-2006 Gerald Combs <gerald@xxxxxxxxxxxxx> and contributors.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Compiled with GTK+ 2.10.2, with GLib 2.12.2, with libpcap 0.9.4,
with libz 1.2.3, with libpcre 6.6, with Net-SNMP 5.3.1, without ADNS,
without Lua.

Running with libpcap version 0.9.4 on Linux 2.6.18-1.2798.fc6.
--
BUGS Found-

1. While dissecting Packet filter Contents of a Packet filter identifier in
Packet Filter List when the TFT operation is "delete packet filters from
existing TFT", in function de_sm_tflow_temp <while> loop for identifying
different packet filter component type identifiers is missing(line no: 4470).
The dissector checks only for the first packet filter component type identifier
present in the Packet filter Content and incorrectly interprets the remaining
data in the Packet filter Content as a new Packet filter identifier whereas it
is actually a part of Packet filter Contents of the previous Packet filter
identifier.

2. Break statement for case 0x40 is missing.

3. current_offset and current_len are not being incremented/decremented
properly in different case blocks.


Old Code - 
static guint16
de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len,
gchar *add_string _U_, int string_len _U_)
{
    guint32          curr_offset;
    guint          curr_len;
    proto_item   *tf = NULL;
    proto_tree   *tf_tree = NULL;
    proto_tree   *comp_tree = NULL;
    guchar        op_code;
    guchar        pkt_fil_count;
    guchar        e_bit;
    const gchar  *str;
    guchar        count;
    guchar        oct;
    gint          pf_length;
    gint          pf_identifier;
    gint          pack_component_type;

    curr_len = len;
    curr_offset = offset;

    /*
     * parse first octet. It contain TFT operation code, E bit and Number of
packet filters
     */
    oct = tvb_get_guint8(tvb, curr_offset);

    op_code = oct>>5;
    pkt_fil_count = oct&0x0f;
    e_bit = (oct>>4)&1;

    proto_tree_add_item(tree,hf_gsm_a_tft_op_code,tvb,curr_offset,1,FALSE);
    proto_tree_add_item(tree,hf_gsm_a_tft_e_bit,tvb,curr_offset,1,FALSE);
    proto_tree_add_item(tree,hf_gsm_a_tft_pkt_flt,tvb,curr_offset,1,FALSE);

    curr_offset++;
    curr_len--;

    /* Packet filter list dissect */

    count = 0;
    if ( op_code == 2 )            /* delete TFT contains no packet filters. so
we will jump over it */
        count = pkt_fil_count;
    while ( count < pkt_fil_count )
    {
        tf = proto_tree_add_text(tree,
            tvb, curr_offset, 1,
            "Packet filter %d",count);   /* 0-> 7 */

        tf_tree = proto_item_add_subtree(tf, ett_sm_tft );

        if ( op_code == 5 )  /* Delete packet filters from existing TFT - just
a list of identifiers */
        {
            if ((curr_offset-offset)<1) {
                proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough
data");
                return(curr_offset-offset);
            }
            oct = tvb_get_guint8(tvb, curr_offset);
            curr_offset++;
            curr_len--;

            proto_tree_add_text(tf_tree,
                tvb, curr_offset-1, 1,
                "Packet filter identifier: 0x%02x (%u)",oct,oct );    
        }
        else                /* create new, Add packet filters or Replace packet
filters */
        {

            if ((curr_offset-offset)<1) {
                proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough
data");
                return(curr_offset-offset);
            }
            pf_identifier = tvb_get_guint8(tvb, curr_offset);
            curr_offset++;
            curr_len--;

            proto_tree_add_text(tf_tree,
                tvb, curr_offset-1, 1,
                "Packet filter identifier: %u (%u)",pf_identifier,
pf_identifier);    

            if ((curr_offset-offset)<1) {
                proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough
data");
                return(curr_offset-offset);
            }
            oct = tvb_get_guint8(tvb, curr_offset);
            curr_offset++;
            curr_len--;

            proto_tree_add_text(tf_tree,
                tvb, curr_offset-1, 1,
                "Packet evaluation precedence: 0x%02x (%u)",oct,oct );    

            if ((curr_offset-offset)<1) { proto_tree_add_text(tf_tree,tvb,
curr_offset, 1,"Not enough data"); return(curr_offset-offset);}
            pf_length = tvb_get_guint8(tvb, curr_offset);
            curr_offset++;
            curr_len--;

            proto_tree_add_text(tf_tree,
                tvb, curr_offset-1, 1,
                "Packet filter length: 0x%02x (%u)",pf_length,pf_length );    
            /* New tree for component */

            /* Dissect Packet filter Component */
            /* while ( filter_len > 1 ) */
            /* packet filter component type identifier: */

            if (pf_length > 0 ){
                if ((curr_offset-offset)<1) {
                    proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough
data");
                    return(curr_offset-offset);
                }
                pack_component_type = tvb_get_guint8(tvb, curr_offset);
                curr_offset++;
                curr_len--;

                tf=proto_tree_add_text(tf_tree,tvb, curr_offset-1, 1,"Packet
filter component type identifier: ");
                comp_tree = proto_item_add_subtree(tf, ett_sm_tft );

                switch ( pack_component_type ){

                case 0x10:
                    str="IPv4 source address type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_ip4_address,tvb,curr_offset,4,FALSE);
                    curr_offset+=4;
                    curr_len-=4;
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_ip4_mask,tvb,curr_offset,4,FALSE);
                    curr_offset+=4;
                    curr_len-=4;
                    break;

                case 0x20:
                    str="IPv6 source address type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_ip6_address,tvb,curr_offset,16,FALSE);
                    curr_offset+=16;
                    curr_len-=16;
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_ip6_mask,tvb,curr_offset,16,FALSE);
                    curr_offset+=16;
                    curr_len-=16;
                    break;

                case 0x30:
                    str="Protocol identifier/Next header type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_protocol_header,tvb,curr_offset,1,FALSE);
                    curr_offset+=1;
                    curr_len-=1;
                    break;

                case 0x40:
                    str="Single destination port type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_port,tvb,curr_offset,2,FALSE);
                    curr_offset+=2;
                    curr_len-=2;

                case 0x41:
                    str="Destination port range type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_port_low,tvb,curr_offset,2,FALSE);
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_port_high,tvb,curr_offset,2,FALSE);
                    curr_offset+=4;
                    curr_len-=4;
                    break;

                case 0x50:
                    str="Single source port type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_port,tvb,curr_offset,2,FALSE);
                    curr_offset+=2;
                    curr_len-=2;
                    break;

                case 0x51:
                    str="Source port range type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_port_low,tvb,curr_offset,2,FALSE);
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_port_high,tvb,curr_offset,2,FALSE);
                    curr_offset+=4;
                    curr_len-=4;
                    break;

                case 0x60:
                    str="Security parameter index type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_security,tvb,curr_offset,4,FALSE);
                    curr_offset+=4;
                    curr_len-=4;
                    break;


                case 0x70:
                    str="Type of service/Traffic class type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_qos_traffic_cls,tvb,curr_offset,1,FALSE);
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_traffic_mask,tvb,curr_offset,1,FALSE);
                    curr_offset+=2;
                    curr_len-=2;
                    break;

                case 0x80:
                    str="Flow label type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_traffic_mask,tvb,curr_offset,1,FALSE);
                    curr_offset+=3;
                    curr_len-=3;
                    break;

                default:
                    str="not specified";
                }
                proto_item_append_text(tf, "(%u) %s", pack_component_type, str
);
                count++;
            }
        }
    }

    /* The parameters list contains a variable number of parameters that might
need to be
     * transferred in addition to the packet filters. If the parameters list is
included, the E
     * bit is set to 1; otherwise, the E bit is set to 0.
     */
    if (e_bit == 1){
         proto_tree_add_text(tf_tree, tvb, curr_offset, 1, "Note: Possible
Authorization Token/Flow Identifier not decoded yet");
    }
    return(curr_offset - offset);
}




FIXED CODE - 

static guint16
de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len,
gchar *add_string _U_, int string_len _U_)
{
    guint32          curr_offset;
    guint          curr_len;
    proto_item   *tf = NULL;
    proto_tree   *tf_tree = NULL;
    proto_tree   *comp_tree = NULL;
    guchar        op_code;
    guchar        pkt_fil_count;
    guchar        e_bit;
    const gchar  *str;
    guchar        count;
    guchar        oct;
    gint          pf_length;
    gint          pf_identifier;
    gint          pack_component_type;

    gint start_offset = 0;
    gint filter_len_read = 0;

    curr_len = len;
    curr_offset = offset;

    /*
     * parse first octet. It contain TFT operation code, E bit and Number of
packet filters
     */
    oct = tvb_get_guint8(tvb, curr_offset);

    op_code = oct>>5;
    pkt_fil_count = oct&0x0f;
    e_bit = (oct>>4)&1;

    proto_tree_add_item(tree,hf_gsm_a_tft_op_code,tvb,curr_offset,1,FALSE);
    proto_tree_add_item(tree,hf_gsm_a_tft_e_bit,tvb,curr_offset,1,FALSE);
    proto_tree_add_item(tree,hf_gsm_a_tft_pkt_flt,tvb,curr_offset,1,FALSE);

    curr_offset++;
    curr_len--;

    /* Packet filter list dissect */

    count = 0;
    if ( op_code == 2 )            /* delete TFT contains no packet filters. so
we will jump over it */
        count = pkt_fil_count;
    while ( count < pkt_fil_count )
    {
        tf = proto_tree_add_text(tree,
            tvb, curr_offset, 1,
            "Packet filter %d",count);   /* 0-> 7 */

        tf_tree = proto_item_add_subtree(tf, ett_sm_tft );

        if ( op_code == 5 )  /* Delete packet filters from existing TFT - just
a list of identifiers */
        {
            if ((curr_offset-offset)<1) {
                proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough
data");
                return(curr_offset-offset);
            }
            oct = tvb_get_guint8(tvb, curr_offset);
            curr_offset++;
            curr_len--;

            proto_tree_add_text(tf_tree,
                tvb, curr_offset-1, 1,
                "Packet filter identifier: 0x%02x (%u)",oct,oct );    
        }
        else                /* create new, Add packet filters or Replace packet
filters */
        {

            if ((curr_offset-offset)<1) {
                proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough
data");
                return(curr_offset-offset);
            }
            pf_identifier = tvb_get_guint8(tvb, curr_offset);
            curr_offset++;
            curr_len--;

            proto_tree_add_text(tf_tree,
                tvb, curr_offset-1, 1,
                "Packet filter identifier: %u (%u)",pf_identifier,
pf_identifier);    

            if ((curr_offset-offset)<1) {
                proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough
data");
                return(curr_offset-offset);
            }
            oct = tvb_get_guint8(tvb, curr_offset);
            curr_offset++;
            curr_len--;

            proto_tree_add_text(tf_tree,
                tvb, curr_offset-1, 1,
                "Packet evaluation precedence: 0x%02x (%u)",oct,oct );    

            if ((curr_offset-offset)<1) { proto_tree_add_text(tf_tree,tvb,
curr_offset, 1,"Not enough data"); return(curr_offset-offset);}
            pf_length = tvb_get_guint8(tvb, curr_offset);
            curr_offset++;
            curr_len--;

            proto_tree_add_text(tf_tree,
                tvb, curr_offset-1, 1,
                "Packet filter length: 0x%02x (%u)",pf_length,pf_length );    
            /* New tree for component */

            /* Dissect Packet filter Component */
            /* while ( pf_length > 1 ) */
            /* packet filter component type identifier: */

            while((pf_length - filter_len_read) > 0)
            {

            start_offset = curr_offset;

            if (pf_length > 0 ){
                if ((curr_offset-offset)<1) {
                    proto_tree_add_text(tf_tree,tvb, curr_offset, 1,"Not enough
data");
                    return(curr_offset-offset);
                }
                pack_component_type = tvb_get_guint8(tvb, curr_offset);
                curr_offset++;
                curr_len--;

                tf=proto_tree_add_text(tf_tree,tvb, curr_offset-1, 1,"Packet
filter component type identifier: ");
                comp_tree = proto_item_add_subtree(tf, ett_sm_tft );

                switch ( pack_component_type ){

                case 0x10:
                    str="IPv4 source address type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_ip4_address,tvb,curr_offset,4,FALSE);
                    curr_offset+=4;
                    curr_len-=4;
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_ip4_mask,tvb,curr_offset,4,FALSE);
                    curr_offset+=4;
                    curr_len-=4;
                    break;

                case 0x20:
                    str="IPv6 source address type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_ip6_address,tvb,curr_offset,16,FALSE);
                    curr_offset+=16;
                    curr_len-=16;
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_ip6_mask,tvb,curr_offset,16,FALSE);
                    curr_offset+=16;
                    curr_len-=16;
                    break;

                case 0x30:
                    str="Protocol identifier/Next header type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_protocol_header,tvb,curr_offset,1,FALSE);
                    curr_offset+=1;
                    curr_len-=1;
                    break;

                case 0x40:
                    str="Single local port type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_port,tvb,curr_offset,2,FALSE);
                    curr_offset+=2;
                    curr_len-=2;
                    break;

                case 0x41:
                    str="Local port range type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_port_low,tvb,curr_offset,2,FALSE);
                    curr_offset+=2;
                    curr_len-=2;
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_port_high,tvb,curr_offset,2,FALSE);
                    curr_offset+=2;
                    curr_len-=2;
                    break;

                case 0x50:
                    str="Single Remote port type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_port,tvb,curr_offset,2,FALSE);
                    curr_offset+=2;
                    curr_len-=2;
                    break;

                case 0x51:
                    str="Remote port range type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_port_low,tvb,curr_offset,2,FALSE);
                    curr_offset+=2;
                    curr_len-=2;
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_port_high,tvb,curr_offset,2,FALSE);
                    curr_offset+=2;
                    curr_len-=2;
                    break;

                case 0x60:
                    str="Security parameter index type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_security,tvb,curr_offset,4,FALSE);
                    curr_offset+=4;
                    curr_len-=4;
                    break;


                case 0x70:
                    str="Type of service/Traffic class type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_qos_traffic_cls,tvb,curr_offset,1,FALSE);
                    curr_offset+=1;
                    curr_len-=1;
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_traffic_mask,tvb,curr_offset,1,FALSE);
                    curr_offset+=1;
                    curr_len-=1;
                    break;

                case 0x80:
                    str="Flow label type";
                   
proto_tree_add_item(comp_tree,hf_gsm_a_tft_traffic_mask,tvb,curr_offset,1,FALSE);
                    curr_offset+=3;
                    curr_len-=3;
                    break;

                default:
                    str="not specified";
                }
                proto_item_append_text(tf, "(%u) %s", pack_component_type, str
);

                }
                filter_len_read += curr_offset - start_offset;
            }
            }
                filter_len_read = 0;
                count++;
        }

    /* The parameters list contains a variable number of parameters that might
need to be
     * transferred in addition to the packet filters. If the parameters list is
included, the E
     * bit is set to 1; otherwise, the E bit is set to 0.
     */
    if (e_bit == 1){
         proto_tree_add_text(tf_tree, tvb, curr_offset, 1, "Note: Possible
Authorization Token/Flow Identifier not decoded yet");
    }
    return(curr_offset - offset);
}

-- 
Configure bugmail: https://bugs.wireshark.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.