Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Proprietary CAN dissector - dissector is never called

Dear Sharks!

Im able to build wireshark from source and register a proprietary CAN dissector which are supposed to disect the payload from SocketCAN. Here is a code snippet from the SocketCAN source;

next_tvb = tvb_new_subset_length(tvb, CAN_DATA_OFFSET, frame_len);

/* Functionality for choosing subdissector is controlled through Decode As as CAN doesn't
   have a unique identifier to determine subdissector */
if (!dissector_try_uint_new(subdissector_table, 0, next_tvb, pinfo, tree, TRUE, &can_id))
{
    call_data_dissector(next_tvb, pinfo, tree);
}

At the if statement in the call to "dissector_try_uint_new" im expecting wireshark to somehow call my proprietary disector based on me having made the correct register/handoff calls. However, this is not the case and using the debugger I can se that it allways runs in to the if statement and calls "call_data_dissector" instead.

Bellow I've posted the proprietary CAN dissector code, and I'm hoping you would give me clues to why my dissector is not called when wireshark is dissecting SocketCAN frames. I'm new to wireshark and all help are much appreciated, thank you.

Other info: Windows 64, branched from "wireshark-2.4.3"/"v2.4.3"/#368ba1e

/* Wireshark - Network traffic analyzer
* By Gerald Combs <[email protected]>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0+
*/

#include <config.h>

#if 0
/* "System" includes used only as needed */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
...
#endif

#include <epan/packet.h>   /* Should be first Wireshark include (other than config.h) */
#include <epan/expert.h>   /* Include only as needed */
#include <epan/prefs.h>    /* Include only as needed */
#include <epan/dissectors/packet-socketcan.h>
//#include <epan/range.h>    /* Include only as needed */

#if 0
/* IF AND ONLY IF your protocol dissector exposes code to other dissectors
* (which most dissectors don't need to do) then the 'public' prototypes and
* data structures can go in the header file packet-fooo_can.h. If not, then
* a header file is not needed at all and this #include statement can be
* removed. */
#include "packet-fooo_can.h"
#endif

/* Prototypes */
/* (Required to prevent [-Wmissing-prototypes] warnings */
void proto_reg_handoff_fooo_can(void);
void proto_register_fooo_can(void);

/* Initialize the protocol and registered fields */
static int proto_fooo_can = -1;
static int hf_fooo_can_fooo_can_field = -1;
static expert_field ei_fooo_can_EXPERTABBREV = EI_INIT;

/* Global sample preference ("controls" display of numbers) */
static gboolean pref_hex = FALSE;

/* Initialize the subtree pointers */
static gint ett_fooo_can = -1;

#define MAX_NEEDED_FOR_HEURISTICS 8
#define TEST_HEURISTICS_FAIL 1

/* Code to actually dissect the packets */
static int
dissect_fooo_can(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
    void *data _U_)
{//<----- This breakpoint is never hit
    g_debug("Here is my fooo can bus\n"); //Never printed

    struct can_identifier can_id;

    DISSECTOR_ASSERT(data);
    can_id = *((struct can_identifier*)data);

    return 0;
}

/* Register the protocol with Wireshark.
*
* This format is require because a script is used to build the C function that
* calls all the protocol registration.
*/
void
proto_register_fooo_can(void)
{//<----- First Breakpoint to be hit, happens once
    module_t        *fooo_can_module;
    expert_module_t *expert_fooo_can;

    /* Setup list of header fields  See Section 1.5 of README.dissector for
    * details. */
    static hf_register_info hf[] = {
        { &hf_fooo_can_fooo_can_field,
        { "BAR_FOOO_CAN_FIELD", "fooo_can.fooo_can_field",
        FT_BOOLEAN, BASE_HEX, NULL, 0,
        "FIELDDESCR", HFILL }
        }
    };

    /* Setup protocol subtree array */
    static gint *ett[] = {
        &ett_fooo_can
    };

    /* Setup protocol expert items */
    static ei_register_info ei[] = {
        { &ei_fooo_can_EXPERTABBREV,
        { "fooo_can.EXPERTABBREV", PI_COMMENT, PI_WARN,
        "EXPERTDESCR", EXPFILL }
        }
    };

    /* Register the protocol name and description */
    proto_fooo_can = proto_register_protocol("My proprietary protocol over CAN",
        "BAR_FOOO_CAN", "fooo_can");

    /* Required function calls to register the header fields and subtrees */
    proto_register_field_array(proto_fooo_can, hf, array_length(hf));
    proto_register_subtree_array(ett, array_length(ett));

    /* Required function calls to register expert items */
    expert_fooo_can = expert_register_protocol(proto_fooo_can);
    expert_register_field_array(expert_fooo_can, ei, array_length(ei));

    /* Register a preferences module (see section 2.6 of README.dissector
    * for more details). Registration of a prefs callback is not required
    * if there are no preferences that affect protocol registration (an example
    * of a preference that would affect registration is a port preference).
    * If the prefs callback is not needed, use NULL instead of
    * proto_reg_handoff_fooo_can in the following.
    */
    fooo_can_module = prefs_register_protocol(proto_fooo_can,
        proto_reg_handoff_fooo_can);

    /* Register a preferences module under the preferences subtree.
    * Only use this function instead of prefs_register_protocol (above) if you
    * want to group preferences of several protocols under one preferences
    * subtree.
    *
    * Argument subtree identifies grouping tree node name, several subnodes can
    * be specified using slash '/' (e.g. "OSI/X.500" - protocol preferences
    * will be accessible under Protocols->OSI->X.500-><BAR_FOOO_CAN>
    * preferences node.
    */
    //    fooo_can_module = prefs_register_protocol_subtree(const char *subtree,
    //            proto_fooo_can, proto_reg_handoff_fooo_can);

    /* Register a simple example preference */
    prefs_register_bool_preference(fooo_can_module, "show_hex",
        "Display numbers in Hex",
        "Enable to display numerical values in hexadecimal.",
        &pref_hex);
}

/* If this dissector uses sub-dissector registration add a registration routine.
* This exact format is required because a script is used to find these
* routines and create the code that calls these routines.
*
* If this function is registered as a prefs callback (see
* prefs_register_protocol above) this function is also called by Wireshark's
* preferences manager whenever "Apply" or "OK" are pressed. In that case, it
* should accommodate being called more than once by use of the static
* 'initialized' variable included below.

*
* This form of the reg_handoff function is used if if you perform registration
* functions which are dependent upon prefs. See below this function for a
* simpler form which can be used if there are no prefs-dependent registration
* functions.
*/
void
proto_reg_handoff_fooo_can(void)
{//<----- Second Breakpoint to be hit, happens once
    static gboolean inited = FALSE;
    dissector_handle_t fooo_can_handle;

    if (inited)
    {
        return;
    }
    inited = TRUE;
    fooo_can_handle = create_dissector_handle(dissect_fooo_can, proto_fooo_can);
    dissector_add_for_decode_as("can.subdissector", fooo_can_handle);
}


/*
* Editor modelines  -  https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/
click to hide/show revision 2
None

Proprietary CAN dissector - dissector is never called

Dear Sharks!

Im able to build wireshark from source and register a proprietary CAN dissector which are supposed to disect the payload from SocketCAN. Here is a code snippet from the SocketCAN source;

next_tvb = tvb_new_subset_length(tvb, CAN_DATA_OFFSET, frame_len);

/* Functionality for choosing subdissector is controlled through Decode As as CAN doesn't
   have a unique identifier to determine subdissector */
if (!dissector_try_uint_new(subdissector_table, 0, next_tvb, pinfo, tree, TRUE, &can_id))
{
    call_data_dissector(next_tvb, pinfo, tree);
}

At the if statement in the call to "dissector_try_uint_new" dissector_try_uint_new im expecting wireshark to somehow call my proprietary disector based on me having made the correct register/handoff calls. However, this is not the case and using the debugger I can se that it allways runs in to the if statement and calls "call_data_dissector" instead.

Bellow I've posted the proprietary CAN dissector code, and I'm hoping you would give me clues to why my dissector is not called when wireshark is dissecting SocketCAN frames. I'm new to wireshark and all help are much appreciated, thank you.

Other info: Windows 64, branched from "wireshark-2.4.3"/"v2.4.3"/#368ba1e

/* Wireshark - Network traffic analyzer
* By Gerald Combs <[email protected]>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0+
*/

#include <config.h>

#if 0
/* "System" includes used only as needed */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
...
#endif

#include <epan/packet.h>   /* Should be first Wireshark include (other than config.h) */
#include <epan/expert.h>   /* Include only as needed */
#include <epan/prefs.h>    /* Include only as needed */
#include <epan/dissectors/packet-socketcan.h>
//#include <epan/range.h>    /* Include only as needed */

#if 0
/* IF AND ONLY IF your protocol dissector exposes code to other dissectors
* (which most dissectors don't need to do) then the 'public' prototypes and
* data structures can go in the header file packet-fooo_can.h. If not, then
* a header file is not needed at all and this #include statement can be
* removed. */
#include "packet-fooo_can.h"
#endif

/* Prototypes */
/* (Required to prevent [-Wmissing-prototypes] warnings */
void proto_reg_handoff_fooo_can(void);
void proto_register_fooo_can(void);

/* Initialize the protocol and registered fields */
static int proto_fooo_can = -1;
static int hf_fooo_can_fooo_can_field = -1;
static expert_field ei_fooo_can_EXPERTABBREV = EI_INIT;

/* Global sample preference ("controls" display of numbers) */
static gboolean pref_hex = FALSE;

/* Initialize the subtree pointers */
static gint ett_fooo_can = -1;

#define MAX_NEEDED_FOR_HEURISTICS 8
#define TEST_HEURISTICS_FAIL 1

/* Code to actually dissect the packets */
static int
dissect_fooo_can(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
    void *data _U_)
{//<----- This breakpoint is never hit
    g_debug("Here is my fooo can bus\n"); //Never printed

    struct can_identifier can_id;

    DISSECTOR_ASSERT(data);
    can_id = *((struct can_identifier*)data);

    return 0;
}

/* Register the protocol with Wireshark.
*
* This format is require because a script is used to build the C function that
* calls all the protocol registration.
*/
void
proto_register_fooo_can(void)
{//<----- First Breakpoint to be hit, happens once
    module_t        *fooo_can_module;
    expert_module_t *expert_fooo_can;

    /* Setup list of header fields  See Section 1.5 of README.dissector for
    * details. */
    static hf_register_info hf[] = {
        { &hf_fooo_can_fooo_can_field,
        { "BAR_FOOO_CAN_FIELD", "fooo_can.fooo_can_field",
        FT_BOOLEAN, BASE_HEX, NULL, 0,
        "FIELDDESCR", HFILL }
        }
    };

    /* Setup protocol subtree array */
    static gint *ett[] = {
        &ett_fooo_can
    };

    /* Setup protocol expert items */
    static ei_register_info ei[] = {
        { &ei_fooo_can_EXPERTABBREV,
        { "fooo_can.EXPERTABBREV", PI_COMMENT, PI_WARN,
        "EXPERTDESCR", EXPFILL }
        }
    };

    /* Register the protocol name and description */
    proto_fooo_can = proto_register_protocol("My proprietary protocol over CAN",
        "BAR_FOOO_CAN", "fooo_can");

    /* Required function calls to register the header fields and subtrees */
    proto_register_field_array(proto_fooo_can, hf, array_length(hf));
    proto_register_subtree_array(ett, array_length(ett));

    /* Required function calls to register expert items */
    expert_fooo_can = expert_register_protocol(proto_fooo_can);
    expert_register_field_array(expert_fooo_can, ei, array_length(ei));

    /* Register a preferences module (see section 2.6 of README.dissector
    * for more details). Registration of a prefs callback is not required
    * if there are no preferences that affect protocol registration (an example
    * of a preference that would affect registration is a port preference).
    * If the prefs callback is not needed, use NULL instead of
    * proto_reg_handoff_fooo_can in the following.
    */
    fooo_can_module = prefs_register_protocol(proto_fooo_can,
        proto_reg_handoff_fooo_can);

    /* Register a preferences module under the preferences subtree.
    * Only use this function instead of prefs_register_protocol (above) if you
    * want to group preferences of several protocols under one preferences
    * subtree.
    *
    * Argument subtree identifies grouping tree node name, several subnodes can
    * be specified using slash '/' (e.g. "OSI/X.500" - protocol preferences
    * will be accessible under Protocols->OSI->X.500-><BAR_FOOO_CAN>
    * preferences node.
    */
    //    fooo_can_module = prefs_register_protocol_subtree(const char *subtree,
    //            proto_fooo_can, proto_reg_handoff_fooo_can);

    /* Register a simple example preference */
    prefs_register_bool_preference(fooo_can_module, "show_hex",
        "Display numbers in Hex",
        "Enable to display numerical values in hexadecimal.",
        &pref_hex);
}

/* If this dissector uses sub-dissector registration add a registration routine.
* This exact format is required because a script is used to find these
* routines and create the code that calls these routines.
*
* If this function is registered as a prefs callback (see
* prefs_register_protocol above) this function is also called by Wireshark's
* preferences manager whenever "Apply" or "OK" are pressed. In that case, it
* should accommodate being called more than once by use of the static
* 'initialized' variable included below.

*
* This form of the reg_handoff function is used if if you perform registration
* functions which are dependent upon prefs. See below this function for a
* simpler form which can be used if there are no prefs-dependent registration
* functions.
*/
void
proto_reg_handoff_fooo_can(void)
{//<----- Second Breakpoint to be hit, happens once
    static gboolean inited = FALSE;
    dissector_handle_t fooo_can_handle;

    if (inited)
    {
        return;
    }
    inited = TRUE;
    fooo_can_handle = create_dissector_handle(dissect_fooo_can, proto_fooo_can);
    dissector_add_for_decode_as("can.subdissector", fooo_can_handle);
}


/*
* Editor modelines  -  https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/
click to hide/show revision 3
None

Proprietary CAN dissector - dissector is never called

Dear Sharks!

Im able to build wireshark from source and register a proprietary CAN dissector which are supposed to disect the payload from SocketCAN. Here is a code snippet from the SocketCAN source;

next_tvb = tvb_new_subset_length(tvb, CAN_DATA_OFFSET, frame_len);

/* Functionality for choosing subdissector is controlled through Decode As as CAN doesn't
   have a unique identifier to determine subdissector */
if (!dissector_try_uint_new(subdissector_table, 0, next_tvb, pinfo, tree, TRUE, &can_id))
{
    call_data_dissector(next_tvb, pinfo, tree);
}

At the if statement in the call to dissector_try_uint_new im expecting wireshark to somehow call my proprietary disector based on me having made the correct register/handoff calls. However, this is not the case and using the debugger I can se that it allways runs in to the if statement and calls "call_data_dissector" call_data_dissector instead.

Bellow I've posted the proprietary CAN dissector code, and I'm hoping you would give me clues to why my dissector is not called when wireshark is dissecting SocketCAN frames. I'm new to wireshark and all help are much appreciated, thank you.

Other info: Windows 64, branched from "wireshark-2.4.3"/"v2.4.3"/#368ba1e

/* Wireshark - Network traffic analyzer
* By Gerald Combs <[email protected]>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0+
*/

#include <config.h>

#if 0
/* "System" includes used only as needed */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
...
#endif

#include <epan/packet.h>   /* Should be first Wireshark include (other than config.h) */
#include <epan/expert.h>   /* Include only as needed */
#include <epan/prefs.h>    /* Include only as needed */
#include <epan/dissectors/packet-socketcan.h>
//#include <epan/range.h>    /* Include only as needed */

#if 0
/* IF AND ONLY IF your protocol dissector exposes code to other dissectors
* (which most dissectors don't need to do) then the 'public' prototypes and
* data structures can go in the header file packet-fooo_can.h. If not, then
* a header file is not needed at all and this #include statement can be
* removed. */
#include "packet-fooo_can.h"
#endif

/* Prototypes */
/* (Required to prevent [-Wmissing-prototypes] warnings */
void proto_reg_handoff_fooo_can(void);
void proto_register_fooo_can(void);

/* Initialize the protocol and registered fields */
static int proto_fooo_can = -1;
static int hf_fooo_can_fooo_can_field = -1;
static expert_field ei_fooo_can_EXPERTABBREV = EI_INIT;

/* Global sample preference ("controls" display of numbers) */
static gboolean pref_hex = FALSE;

/* Initialize the subtree pointers */
static gint ett_fooo_can = -1;

#define MAX_NEEDED_FOR_HEURISTICS 8
#define TEST_HEURISTICS_FAIL 1

/* Code to actually dissect the packets */
static int
dissect_fooo_can(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
    void *data _U_)
{//<----- This breakpoint is never hit
    g_debug("Here is my fooo can bus\n"); //Never printed

    struct can_identifier can_id;

    DISSECTOR_ASSERT(data);
    can_id = *((struct can_identifier*)data);

    return 0;
}

/* Register the protocol with Wireshark.
*
* This format is require because a script is used to build the C function that
* calls all the protocol registration.
*/
void
proto_register_fooo_can(void)
{//<----- First Breakpoint to be hit, happens once
    module_t        *fooo_can_module;
    expert_module_t *expert_fooo_can;

    /* Setup list of header fields  See Section 1.5 of README.dissector for
    * details. */
    static hf_register_info hf[] = {
        { &hf_fooo_can_fooo_can_field,
        { "BAR_FOOO_CAN_FIELD", "fooo_can.fooo_can_field",
        FT_BOOLEAN, BASE_HEX, NULL, 0,
        "FIELDDESCR", HFILL }
        }
    };

    /* Setup protocol subtree array */
    static gint *ett[] = {
        &ett_fooo_can
    };

    /* Setup protocol expert items */
    static ei_register_info ei[] = {
        { &ei_fooo_can_EXPERTABBREV,
        { "fooo_can.EXPERTABBREV", PI_COMMENT, PI_WARN,
        "EXPERTDESCR", EXPFILL }
        }
    };

    /* Register the protocol name and description */
    proto_fooo_can = proto_register_protocol("My proprietary protocol over CAN",
        "BAR_FOOO_CAN", "fooo_can");

    /* Required function calls to register the header fields and subtrees */
    proto_register_field_array(proto_fooo_can, hf, array_length(hf));
    proto_register_subtree_array(ett, array_length(ett));

    /* Required function calls to register expert items */
    expert_fooo_can = expert_register_protocol(proto_fooo_can);
    expert_register_field_array(expert_fooo_can, ei, array_length(ei));

    /* Register a preferences module (see section 2.6 of README.dissector
    * for more details). Registration of a prefs callback is not required
    * if there are no preferences that affect protocol registration (an example
    * of a preference that would affect registration is a port preference).
    * If the prefs callback is not needed, use NULL instead of
    * proto_reg_handoff_fooo_can in the following.
    */
    fooo_can_module = prefs_register_protocol(proto_fooo_can,
        proto_reg_handoff_fooo_can);

    /* Register a preferences module under the preferences subtree.
    * Only use this function instead of prefs_register_protocol (above) if you
    * want to group preferences of several protocols under one preferences
    * subtree.
    *
    * Argument subtree identifies grouping tree node name, several subnodes can
    * be specified using slash '/' (e.g. "OSI/X.500" - protocol preferences
    * will be accessible under Protocols->OSI->X.500-><BAR_FOOO_CAN>
    * preferences node.
    */
    //    fooo_can_module = prefs_register_protocol_subtree(const char *subtree,
    //            proto_fooo_can, proto_reg_handoff_fooo_can);

    /* Register a simple example preference */
    prefs_register_bool_preference(fooo_can_module, "show_hex",
        "Display numbers in Hex",
        "Enable to display numerical values in hexadecimal.",
        &pref_hex);
}

/* If this dissector uses sub-dissector registration add a registration routine.
* This exact format is required because a script is used to find these
* routines and create the code that calls these routines.
*
* If this function is registered as a prefs callback (see
* prefs_register_protocol above) this function is also called by Wireshark's
* preferences manager whenever "Apply" or "OK" are pressed. In that case, it
* should accommodate being called more than once by use of the static
* 'initialized' variable included below.

*
* This form of the reg_handoff function is used if if you perform registration
* functions which are dependent upon prefs. See below this function for a
* simpler form which can be used if there are no prefs-dependent registration
* functions.
*/
void
proto_reg_handoff_fooo_can(void)
{//<----- Second Breakpoint to be hit, happens once
    static gboolean inited = FALSE;
    dissector_handle_t fooo_can_handle;

    if (inited)
    {
        return;
    }
    inited = TRUE;
    fooo_can_handle = create_dissector_handle(dissect_fooo_can, proto_fooo_can);
    dissector_add_for_decode_as("can.subdissector", fooo_can_handle);
}


/*
* Editor modelines  -  https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/