Wireshark-dev: [Wireshark-dev] Disabling a dissector doesn't seem to quite work.

From: "Maynard, Chris" <Christopher.Maynard@xxxxxxxxx>
Date: Fri, 7 Sep 2012 17:47:43 -0400

Recently another old proprietary protocol (I’ll call it FOO) was brought to my attention, and I was asked to write a dissector for it.  In doing so, I discovered a conflict with another dissector, namely SNA.  Initially I thought that simply disabling SNA when analyzing FOO would be good enough for our purposes; however, even after disabling SNA, the FOO dissector was never called.

 

The conflict arises because both dissectors, SNA and FOO, register as follows:

 

dissector_add_uint("llc.dsap", SAP_SNA2, [sna|foo]_handle);

 

I found that even with SNA disabled, I had to comment out the above line of code from the packet-sna.c source file before LLC would successfully hand off dissection to FOO.

 

To illustrate this, I’ve attached a very stripped down and slightly modified version of packet-foo.c, along with a simple foo24.pcap file in case anyone would care to take a look at it.  I have since found an alternate solution, but I was surprised that disabling a protocol does not seem to have the completely desired effect.  While the packet does not get dissected as SNA, other dissectors are apparently not given the opportunity to dissect the packet even when the SNA dissector is disabled.

 

But beyond LLC and SNA, I was thinking/wondering that maybe this is a general problem affecting all dissectors and that some general solution might be needed?

 

Thanks.

- Chris

 

--

 

CONFIDENTIALITY NOTICE: The information contained in this email message is intended only for use of the intended recipient. If the reader of this message is not the intended recipient, you are hereby notified that any dissemination, distribution or copying of this communication is strictly prohibited. If you have received this communication in error, please immediately delete it from your system and notify the sender by replying to this email.  Thank you.

/* packet-foo.c
 * Routines for FOO dissection
 * Copyright 2012, Chris Maynard <Chris.Maynard@xxxxxxxxx>
 *
 * $Id$
 *
 * Wireshark - Network traffic analyzer
 * By Gerald Combs <gerald@xxxxxxxxxxxxx>
 * Copyright 1998 Gerald Combs
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <string.h>
#include <ctype.h>
#include <epan/packet.h>
#include <epan/strutil.h>

static dissector_handle_t data_handle;

static int proto_foo = -1;
static gint hf_foo_type = -1;
static gint hf_foo_field1 = -1;
static gint hf_foo_field2 = -1;

static gint ett_foo = -1;

#define FOO_TYPE_DATA                    8

static const value_string foo_type_vals[] = {
    {FOO_TYPE_DATA, "DATA"},
    {0, NULL}
};

void proto_register_foo(void);
void proto_reg_handoff_foo(void);

static void
dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item *ti;
    proto_tree *foo_tree;
    tvbuff_t *next_tvb;
    gint rem_len;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "FOO");

    if ( tree ) {
        ti = proto_tree_add_item(tree, proto_foo, tvb, 0, -1, ENC_NA);
        foo_tree = proto_item_add_subtree(ti, ett_foo);

        proto_tree_add_item(foo_tree, hf_foo_type, tvb, 0, 1, ENC_NA);
        proto_tree_add_item(foo_tree, hf_foo_field1, tvb, 1, 1, ENC_NA);
        proto_tree_add_item(foo_tree, hf_foo_field2, tvb, 2, 1, ENC_NA);
    }

    if ( (rem_len = tvb_reported_length_remaining(tvb, 3)) > 0 ) {
        next_tvb = tvb_new_subset(tvb, 3, -1, rem_len);
        call_dissector(data_handle, next_tvb, pinfo, tree);
    }
}

void
proto_register_foo(void)
{
    static hf_register_info hf[] = {
        { &hf_foo_type,
            {"Type", "foo.type", FT_UINT8, BASE_DEC,
            VALS(foo_type_vals), 0, NULL, HFILL}},
        { &hf_foo_field1,
            {"Field1", "foo.field1", FT_UINT8, BASE_DEC,
            NULL, 0, NULL, HFILL}},
        { &hf_foo_field2,
            {"Field2", "foo.field2", FT_UINT8, BASE_DEC,
            NULL, 0, NULL, HFILL}},
    };

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

    proto_foo = proto_register_protocol("FOO Protocol", "FOO", "foo");
    proto_register_field_array(proto_foo, hf, array_length(hf));
    proto_register_subtree_array(ett, array_length(ett));
}

void
proto_reg_handoff_foo(void)
{
    static int foo_initialized = FALSE;
    dissector_handle_t foo_handle;

    if ( !foo_initialized ) {
        data_handle = find_dissector("data");

        foo_handle = create_dissector_handle(dissect_foo, proto_foo);
        dissector_add_uint("llc.dsap", 12, foo_handle);
        dissector_add_uint("llc.dsap", 42, foo_handle);
        dissector_add_uint("llc.dsap", 43, foo_handle);
        foo_initialized = TRUE;
    }
}

/*
 * Editor modelines
 *
 * Local variables:
 * c-basic-offset: 4
 * tab-width: 4
 * indent-tabs-mode: nil
 * End:
 *
 * vi: set shiftwidth=4 tabstop=4 expandtab:
 * :indentSize=4:tabSize=4:noTabs=true:
 *
 */


Attachment: foo24.pcap
Description: foo24.pcap

Attachment: Makefile_common.patch
Description: Makefile_common.patch