Wireshark V2 插件信息列在应用过滤器后重置

Wireshark V2 plugin info column resets after applying filter

我有一个基本的 Wireshark 插件,它最初是为 Wireshark V1 编写的,目前我正在尝试将其移植到 V2。

我目前遇到的问题是,当插件在 wireshark-qt-release 中 运行 时,插件可以正常启动并显示所有必要的信息,但是一旦设置了过滤器,其中包含的信息信息栏被清除。信息栏在清除过滤器后也保持为空。

用于设置在信息列中找到的字符串的数据包类型变量也被添加到正在剖析的数据包的 Header 树中。无论是否设置过滤器,此设置都会保持不变。

基于分支 master-2.0 构建,分支为 up-to-date。 使用 MSVC 2013 构建,我没有收到任何错误或警告。

还在 Wireshark 中启用了调试控制台,但没有任何结果,但这可能是因为我无法调整当前设置为 28 的调试级别。

在同一检查中构建的 wireshark-gtk2 构建中工作正常。

感谢任何帮助。

/* packet-trcp.c
* 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.
*/

#include "config.h"

#include <stdio.h>

#include <epan/dissectors/packet-tcp.h>

#define PROTO_TAG_TRCP      "TRCP"
#define MAGIC_NUMBER        0x111111
#define FRAME_HEADER_LEN    8
#define TRCP_PORT           1111

static int proto_trcp = -1;

static dissector_handle_t data_handle = NULL;
static dissector_handle_t trcp_handle = NULL;

static void dissect_trcp(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree);
static int dissect_trcp_message(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void *);

static const value_string packet_type_names[] =
{
    { 0, "Invalid message" },
    { 1, "Connection Request" },
    { 2, "Connection Response" },
    { 3, "Disconnect" },
    { 4, "File Header" },
    { 5, "File Chunk" },
    { 6, "Cancel File Transfer" },
    { 7, "Firmware Imported" },
    { 8, "Alert Message" },
    { 9, "Restore Factory Settings" },
    { 10, "Format Internal Storage" },
    { 11, "Beacon" },
    { 12, "Shutdown" },

    { 0, NULL }
};

static gint hf_trcp_header    = -1;
static gint hf_trcp_magic     = -1;
static gint hf_trcp_length    = -1;
static gint hf_trcp_type      = -1;
static gint hf_trcp_data      = -1;

static gint ett_trcp          = -1;
static gint ett_trcp_header   = -1;
static gint ett_trcp_data     = -1;

//-----------------------------------------------------------------------------------------------------------------------

void proto_reg_handoff_trcp(void)
{
    static gboolean initialized = FALSE;

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

        trcp_handle = create_dissector_handle(dissect_trcp, proto_trcp);
        dissector_add_uint("tcp.port", TRCP_PORT, trcp_handle);

        initialized = TRUE;
    }
}

//-----------------------------------------------------------------------------------------------------------------------

void proto_register_trcp (void)
{
    static hf_register_info hf[] =
    {
        {&hf_trcp_header,
        {"Header", "trcp.header", FT_NONE, BASE_NONE, NULL, 0x0, "TRCP Header", HFILL }},

        {&hf_trcp_magic,
        {"Magic", "trcp.magic", FT_UINT32, BASE_HEX, NULL, 0x0, "Magic Bytes", HFILL }},

        {&hf_trcp_length,
        {"Package Length", "trcp.len", FT_UINT16, BASE_DEC, NULL, 0x0, "Package Length", HFILL }},

        {&hf_trcp_type,
        {"Type", "trcp.type", FT_UINT16, BASE_DEC, VALS(packet_type_names), 0x0, "Package Type", HFILL }},

        {&hf_trcp_data,
        {"Data", "trcp.data", FT_NONE, BASE_NONE, NULL, 0x0, "Data", HFILL }}
    };

    static gint *ett[] =
    {
        &ett_trcp,
        &ett_trcp_header,
        &ett_trcp_data
    };

    proto_trcp = proto_register_protocol ("TRCP Protocol", "TRCP", "trcp");

    proto_register_field_array (proto_trcp, hf, array_length (hf));
    proto_register_subtree_array (ett, array_length (ett));
    register_dissector("trcp", dissect_trcp, proto_trcp);
}

//-----------------------------------------------------------------------------------------------------------------------

static guint get_trcp_message_len(packet_info * pinfo, tvbuff_t * tvb, int offset)
{
    guint plen;
    plen = tvb_get_ntohs(tvb, offset + 6);

    // Add the header length to the data length to get the total packet length
    plen += FRAME_HEADER_LEN;

    return plen;
}

//-----------------------------------------------------------------------------------------------------------------------

static void dissect_trcp(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
{
    // According to - 9.4.2. How to reassemble split TCP Packets
    tcp_dissect_pdus(tvb, pinfo, tree,      // Hand over from above
    TRUE,                                   // Reassemble packet or not
    FRAME_HEADER_LEN,                       // Smallest amount of data required to determine message length (8 bytes)
    get_trcp_message_len,                   // Function pointer to a method that returns message length
    dissect_trcp_message,                   // Function pointer to real message dissector
    NULL);
}

//-----------------------------------------------------------------------------------------------------------------------

static int dissect_trcp_message(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data)
{
    proto_item * trcp_item = NULL;
    proto_item * trcp_sub_item_header = NULL;
    proto_item * trcp_sub_item_data = NULL;
    proto_tree * trcp_tree = NULL;
    proto_tree * trcp_header_tree = NULL;
    proto_tree * trcp_data_tree = NULL;

    guint32 magic = 0;
    guint32 offset = 0;
    guint32 length_tvb = 0;

    guint16 type = 0;
    guint16 length = 0;

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

    if (tree)
    {
        trcp_item = proto_tree_add_item(tree, proto_trcp, tvb, 0, -1, FALSE);
        trcp_tree = proto_item_add_subtree(trcp_item, ett_trcp);

        trcp_sub_item_header = proto_tree_add_item(trcp_tree, hf_trcp_header, tvb, offset, -1, FALSE);
        trcp_header_tree = proto_item_add_subtree(trcp_sub_item_header, ett_trcp_header);

        /*
        4 bytes for magic number
        2 bytes for packet type
        2 bytes for data length
        */

        // Add Magic to header tree
        proto_tree_add_item(trcp_header_tree, hf_trcp_magic, tvb, offset, 4, FALSE);
        offset += 4;

        // Get the type byte
        type = tvb_get_ntohs(tvb, offset);

        // Add Type to header tree
        proto_tree_add_uint(trcp_header_tree, hf_trcp_type, tvb, offset, 2, type);
        offset += 2;

        col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(type, packet_type_names, "Unknown Type:0x%02x"));
        col_set_fence(pinfo->cinfo, COL_INFO);

        // Add Length to header tree
        length = tvb_get_ntohs(tvb, offset);
        proto_tree_add_uint(trcp_header_tree, hf_trcp_length, tvb, offset, 2, length);
        offset += 2;

        if (length)
        {
            // Data
            trcp_sub_item_data = proto_tree_add_item(trcp_tree, hf_trcp_data, tvb, offset, -1, FALSE);
            trcp_data_tree = proto_item_add_subtree(trcp_sub_item_data, ett_trcp_data);
        }
    }

    return tvb_captured_length(tvb);
}

仅当 tree 参数为非 NULL 时才设置列。

不要那样做。

始终设置它,不管 tree是否为空。有 no 保证,如果调用解析器以提供列信息,tree 将是非空的;我们从来没有提供过这样的保证,以后也永远不会提供这样的保证。