精华内容
下载资源
问答
  • wireshark插件开发

    2014-09-16 15:45:12
    wireshark插件开发,version_info
  • Wireshark插件开发

    2015-06-24 10:57:00
    原文地址:... 以下是针对Windows平台的插件开发,其它平台非常类似。   1.开发环境准备  1).下载Source code  使用TortoiseSVN,checkout代码(http://anonsvn.wireshark.org/wireshar

    原文地址:http://blog.csdn.net/qgw_2000/article/details/5327519

    以下是针对Windows平台的插件开发,其它平台非常类似。

     

    1.开发环境准备
        1).下载Source code
          使用TortoiseSVN,checkout代码(http://anonsvn.wireshark.org/wireshark/trunk)
          TortoiseSVN还是相当好用的,直接和windows exploer集成,操作对象就是exploer中的文件和文件夹,
          右键文件或文件夹就可进行管理。
        2).编辑src/config.nmake
          修改跟系统相关的变量,包括MSVC的安装路径,Python(2.x)路径等等
        3).安装Cygwin,选择安装编译过程中需要的所有工具,包括bash、perl、sed等等。
        4).检查编译过程中所需工具是否完备
            >nmake -f Makefile.nmake verify_tools
        5).安装Wireshark依赖的所有Library
            >nmake -f Makefile.nmake
        6).删除其他平台的代码
            >nmake -f Makefile.nmake distclean
        7).编译Wireshark
            >nmake -f Makefile.nmake all
        以上过程可以参考Wireshark的developer guide(http://www.wireshark.org/docs/wsdg_html_chunked/)。

     

    2.插件开发
        项目中使用了自己的私有协议。调试时会经常用tcpdump抓包然后在Windows上用Wireshark分析,为了方便就写个简单的插件。
    关于插件开发Wireshark的developer guide有一些描述,但都比较有限,并且关于Wireshark中的各种API也没有文档描述。

    还好Wireshark有很多插件,可以参考其中的插件代码进行分析调试。
    项目里使用的是L2协议,所以参考WiMax的2层协议的dissector实现(src/plugins/m2m)。

     

    3.开发步骤
        这里说的插件(dissector)就是单独的dll,将dll放到特定位置,Wireshark启动时会加载每个dll完成注册。
    这里简单记录一下大概的步骤。


        1).插件入口函数

    1. G_MODULE_EXPORT void plugin_register (void);  
    2. G_MODULE_EXPORT void plugin_reg_handoff(void);  
     
        Wireshark启动时会加载所有$installdir/plugins/$buildversion/*.dll,并且调用每个dll导出的这两个函数。
        插件在这两个函数里完成dissector的注册和初始化工作,其中plugin_register注册插件,plugin_reg_handoff注册协议。

        插件注册:
        i.注册协议名称

    1. int proto_register_protocol(const char *name, const char *short_name, const char *filter_name)  

        参数:
            name:协议名称
            short_name:协议名称简称
            filter_name:filter中使用的协议名称
        返回值:
            协议ID,后续注册相关的函数都会用到它
        工作流程:
            a.将名称插入存放协议名称的Hash表中,避免相同名称的协议
            b.创建protocol_t对象并将其加入全局表(一个维护所有协议的全局链表)
            c.创建header_field_info对象并调用proto_register_field_init注册并返回注册ID

        Sample code:

    1. proto_myprotocol = proto_register_protocol (  
    2.     "MyProtocol Packet",        /* name       */  
    3.     "MyProcotol (myprotocol)",  /* short name */  
    4.     "myprotocol"                /* abbrev     */  
    5.     );  

        简单描述一下header_field_info注册函数:

    1. static int proto_register_field_init(header_field_info *hfinfo, int parent)  
     
        参数:
            hfinfo:header field对象
            parent:header field对象注册后返回的ID,parent为-1时为注册父对象
        返回值:
            注册ID
        工作流程:
            a.将header field对象添加到一个全局数组中
            b.将协议注册时的filter_name和header field对象指针添加到一个全局平衡树中,方便通过filter_name查找
            c.返回当前的header field对象在全局数据中的索引

        现在说说protocol_t和header_field_info结构,以下是它们两的定义。

    1. /* Structure for information about a protocol */  
    2. struct _protocol {  
    3.     const char *name;      /* long description */  
    4.     const char *short_name;  /* short description */  
    5.     const char *filter_name; /* name of this protocol in filters */  
    6.     int proto_id;          /* field ID for this protocol */  
    7.     GList *fields;          /* fields for this protocol */  
    8.     GList *last_field;      /* pointer to end of list of fields */  
    9.     gboolean is_enabled;  /* TRUE if protocol is enabled */  
    10.     gboolean can_toggle;  /* TRUE if is_enabled can be changed */  
    11.     gboolean is_private;  /* TRUE is protocol is private */  
    12. };  
     
            前三个成员分别对应注册时提供的三个name,proto_id为注册时返回的ID,fields和last_field指向header_field_info链表的头和尾。后面会看到header_field_info的注册过程。

    1. /** information describing a header field */  
    2. struct _header_field_info {  
    3.     /* ---------- set by dissector --------- */  
    4.     const char  *name;           /**< full name of this field */  
    5.     const char  *abbrev;         /**< abbreviated name of this field */  
    6.     enum ftenum   type;           /**< field type, one of FT_ (from ftypes.h) */  
    7.     int              display;        /**< one of BASE_, or number of field bits for FT_BOOLEAN */  
    8.     const void  *strings;        /**< value_string, range_string or true_false_string, 
    9.                                           typically converted by VALS(), RVALS() or TFS(). 
    10.                                           If this is an FT_PROTOCOL then it points to the 
    11.                                           associated protocol_t structure */  
    12.     guint32    bitmask;        /**< bitmask of interesting bits */  
    13.     const char  *blurb;          /**< Brief description of field */  
    14.   
    15.     /* ------- set by proto routines (prefilled by HFILL macro, see below) ------ */  
    16.     int        id;             /**< Field ID */  
    17.     int        parent;         /**< parent protocol tree */  
    18.     hf_ref_type   ref_type;       /**< is this field referenced by a filter */  
    19.     int        bitshift;       /**< bits to shift */  
    20.     header_field_info *same_name_next; /**< Link to next hfinfo with same abbrev */  
    21.     header_field_info *same_name_prev; /**< Link to previous hfinfo with same abbrev */  
    22. };  

        _header_field_info结构比较重要,后续如何显示协议中的各个field会用到它。
        下面代码会看到,对协议中的每个域都会注册一个header_field_info对象,它描述了此协议域的显示名称,filer中的使用的名称,数据类型以及显示格式等等。

        这里首次用到它是注册协议,此时_header_field_info.type为FT_PROTOCOL,string指向protocol_t对象并且parent为-1。

     

        其它显示相关的header fields的注册:

    1. static hf_register_info hf[] =  
    2. {  
    3.     {  
    4.         &hf_myprotocol_type,  
    5.         {  
    6.             "Packet Type""myprotocol.type",  
    7.             FT_UINT16, BASE_HEX,  
    8.             VALS(packettypenames), 0x0,  
    9.             NULL, HFILL  
    10.         }  
    11.     },  
    12.     {  
    13.         &hf_myprotocol_checksum,  
    14.         {  
    15.             "Checksum""myprotocol.checksum",  
    16.             FT_UINT16, BASE_HEX, NULL, 0x0,  
    17.             NULL, HFILL  
    18.         }  
    19.     },  
    20.     {  
    21.         &hf_myprotocol_owner,  
    22.         {  
    23.             "Owner""myprotocol.owner",  
    24.             FT_ETHER, BASE_NONE, NULL, 0x0,  
    25.             NULL, HFILL  
    26.         }  
    27.     },  
    28.     ...  
    29. };  
    30.   
    31. proto_register_field_array(proto_myprotocol, hf, array_length(hf));  
    32. proto_register_field_array(proto_myprotocol, hf_tuple, array_length(hf_tuple));  

        这里proto_register_field_array首先将header field对象插入到protocol_t.fields和last_fields所指向的链表中,然后调用proto_register_field_init进行真正的注册。

        ii.协议注册
            

    1. dissector_handle_t create_dissector_handle(dissector_t dissector, int proto)  
     
        参数:
            dissector:函数指针,负责处理数据包解析和显示,原型 typedef void (*dissector_t)(tvbuff_t *, packet_info *, proto_tree *);
            proto:协议ID,注册时返回
        返回值:
            dissector_handle_t对象用于真正的注册

            

    1. void dissector_add(const char *name, guint32 pattern, dissector_handle_t handle)  

        添加dissector_handle_t对象到系统的dissector table中,其中name为对于二层协议为ethertype,pattern为协议ID。

        Sample Code:

    1. dissector_handle_t myprotocol_handle;  
    2.   
    3. myprotocol_handle = create_dissector_handle(dissect_myprotocol, proto_myprotocol);  
    4. dissector_add("ethertype", ETHERTYPE_MyProtocol, myprotocol_handle);  
     
            其中ETHERTYPT_MyProtocol是以太网帧中协议ID。

     

        2).dissector入口函数
            

    1. static void dissect_myprotocol(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)  
     
        参数:
            tvb:数据包buffer指针,可以通过以下这些函数读取内容,注意字节序。
    1. guint8 tvb_get_guint8(tvbuff_t *tvb, gint offset);  
    2. guint16 tvb_get_ntohs(tvbuff_t *tvb, gint offset);  
    3. guint32 tvb_get_ntoh24(tvbuff_t *tvb, gint offset);  
    4. guint32 tvb_get_ntohl(tvbuff_t *tvb, gint offset);  
    5. guint64 tvb_get_ntoh64(tvbuff_t *tvb, gint offset);  

            pinfo:包括各种关于数据包和协议显示的相关信息,我们关注的是显示相关的信息如Wireshark界面上的protocol和info两个栏位。
                可以使用下面的函数对protocol和info栏位进行操作:

    1. col_set_str(pinfo->cinfo, COL_PROTOCOL, "MyProtocol");  
    2. col_clear(pinfo->cinfo, COL_INFO);  
    3. col_add_fstr(pinfo->cinfo, COL_INFO, "Type %s",  
    4.              val_to_str(packet_type, packettypenames, "Unknow (0x%04x)"));  
     
            tree:在Wireshark界面上点击某个数据包,在界面下方会以树状结构显示数据包的详细信息。tree就是描述这个树状结构的数据结构。
                  当tree不为NULL时,我们就必须按照具体的协议添加相应的节点。这也是整个插件的主要工作。

            首先为协议添加一个subtree节点:

    1. myprotocol_item = proto_tree_add_item(tree, proto_myprotocol, tvb, 0, -1, FALSE);  
    2. protocol_tree = proto_item_add_subtree(myprotocol_item, ett_myprotocol);  
     
                其中proto_myprotocol是注册的协议ID,ett_myprotocol是在注册阶段注册的ID,如下所示:
    1. static gint *ett[] =  
    2. {  
    3.     &ett_ctsp,  
    4. };   
    5. proto_register_subtree_array(ett, array_length(ett));  

            往此subtree节点上添加子节点:

    1. /* display the type */  
    2. proto_tree_add_item(myprotocol_tree, hf_myprotocol_type, tvb, offset, 2, TRUE);  
    3. offset += 2;  
    4. /* display the checksum */  
    5. proto_tree_add_item(myprotocol_tree, hf_myprotocol_checksum, tvb, offset, 2, FALSE);  
    6. offset += 2;  
    7. /* display the owner */  
    8. proto_tree_add_item(myprotocol_tree, hf_myprotocol_owner, tvb, offset, 6, FALSE);  
     
            其中hf_myprotocol_*是在注册的header_field_info的ID,proto_tree_add_item会根据对应的header_field_info显示相应的协议域。

        3).其它问题
        Wireshark的developer guide中有一个UDP协议dissector的例子。另外还提到分片和协议解压解密等问题的解决方法。
        开发中还碰到对于tunnel协议的处理等都可以参考现有的dissector例子进行解决。

    展开全文
  • wireshark 插件开发

    2013-08-19 16:23:44
    根据英文介绍的插件开发,写的一个小的demo.

    gtk  libgtk2.0-dev

    根据英文介绍的插件开发,写的一个 小的demo. 暂时整理,不保证正确性,还需进一步验证。如果您有什么指教,请不吝赐教 ,谢谢!

    #include "config.h"
    
    #include <epan/packet.h>
    
    #define FOO_PORT 1234
    
    static int proto_foo = -1;
    
    static int hf_foo_pdu_type = -1;
    static int hf_foo_flags = -1;
    static int hf_foo_sequenceno = -1;
    static int hf_foo_initialip = -1;
    
    static gint ett_foo = -1;
    
    static void  dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
    {
        guint8 packet_type = tvb_get_guint8(tvb, 0);
    
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "FOO");
        /* Clear out stuff in the info column */
        col_clear(pinfo->cinfo,COL_INFO);
        col_add_fstr(pinfo->cinfo, COL_INFO, "Type %s",
                 val_to_str(packet_type, packettypenames, "Unknown (0x%02x)"));
    
        if (tree) { /* we are being asked for details */
            proto_item *ti = NULL;
            proto_tree *foo_tree = NULL;
            gint offset = 0;
    
            ti = proto_tree_add_item(tree, proto_foo, tvb, 0, -1, ENC_NA);
            proto_item_append_text(ti, ", Type %s",
                val_to_str(packet_type, packettypenames, "Unknown (0x%02x)"));
            foo_tree = proto_item_add_subtree(ti, ett_foo);
            proto_tree_add_item(foo_tree, hf_foo_pdu_type, tvb, offset, 1, ENC_BIG_ENDIAN);
            offset += 1;
        }
    #if 0
    	gint offset = 0;
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "FOO");
        /* Clear out stuff in the info column */
        col_clear(pinfo->cinfo,COL_INFO);
    	
    		
       if (tree) { /* we are being asked for details */
            proto_item *ti = NULL;
            proto_tree *foo_tree = NULL;
    
            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_pdu_type, tvb, offset, 1, ENC_BIG_ENDIAN);
            offset += 1;
            proto_tree_add_item(foo_tree, hf_foo_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
            offset += 1;
            proto_tree_add_item(foo_tree, hf_foo_sequenceno, tvb, offset, 2, ENC_BIG_ENDIAN);
            offset += 2;
            proto_tree_add_item(foo_tree, hf_foo_initialip, tvb, offset, 4, ENC_BIG_ENDIAN);
            offset += 4;
    		proto_tree_add_item(foo_tree, hf_foo_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(foo_tree, hf_foo_startflag, tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(foo_tree, hf_foo_endflag, tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(foo_tree, hf_foo_priorityflag, tvb, offset, 1, ENC_BIG_ENDIAN);
            offset += 1;
        }
    #endif
    	
    }
      
    static const value_string packettypenames[] = {
        { 1, "Initialise" },
        { 2, "Terminate" },
        { 3, "Data" },
        { 0, NULL }
    };
    void  proto_register_foo(void)
    {
        static hf_register_info hf[] = {
            { &hf_foo_pdu_type,
                { "FOO PDU Type", "foo.type",
                FT_UINT8, BASE_DEC,
                VALS(packettypenames), 0x0,
                NULL, HFILL }
            }
    		{ &hf_foo_flags,
                { "FOO PDU Flags", "foo.flags",
                FT_UINT8, BASE_HEX,
                NULL, 0x0,
                NULL, HFILL }
            },
            { &hf_foo_sequenceno,
                { "FOO PDU Sequence Number", "foo.seqn",
                FT_UINT16, BASE_DEC,
                NULL, 0x0,
                NULL, HFILL }
            },
            { &hf_foo_initialip,
                { "FOO PDU Initial IP", "foo.initialip",
                FT_IPv4, BASE_NONE,
                NULL, 0x0,
                NULL, HFILL }
            },
    	    { &hf_foo_startflag,
                { "FOO PDU Start Flags", "foo.flags.start",
                FT_BOOLEAN, 8,
                NULL, FOO_START_FLAG,
                NULL, HFILL }
            },
            { &hf_foo_endflag,
                { "FOO PDU End Flags", "foo.flags.end",
                FT_BOOLEAN, 8,
                NULL, FOO_END_FLAG,
                NULL, HFILL }
            },
            { &hf_foo_priorityflag,
                { "FOO PDU Priority Flags", "foo.flags.priority",
                FT_BOOLEAN, 8,
                NULL, FOO_PRIORITY_FLAG,
                NULL, HFILL }
            },
        };
        proto_foo = proto_register_protocol (
            "FOO Protocol", /* name       */
            "FOO",      /* short name */
            "foo"       /* abbrev     */
            );
    	    /* Setup protocol subtree array */
        static gint *ett[] = {
            &ett_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 dissector_handle_t foo_handle;
    
        foo_handle = create_dissector_handle(dissect_foo, proto_foo);
        dissector_add_uint("udp.port", FOO_PORT, foo_handle);
    }


    展开全文
  • wireshark插件开发 - 自定义协议 wireshark插件开发 - Lua插件解析 wireshark插件开发 - C插件解析 wireshark插件开发 -更多 转载于:https://www.cnblogs.com/99code/p/7531265.html...
    展开全文
  • wireshark插件开发 - 自定义协议     wireshark插件开发 - Lua插件解析     wireshark插件开发 - C插件解析     wireshark插件开发 - 更多
    展开全文
  • Wireshark 插件开发整体解决方案 前段时间自己开发了一个 wireshark 的插件,网上介绍插件开发的资料实在是少得可怜 现在整个项目结束了自己决定写一个文档介绍下自己整个项目的开发过程这个文档我 是整合了很多网上...
  • wireshark插件开发完整解决方案(搭建环境+源代码编写)
  • Wireshark插件开发实例

    2011-05-22 22:40:18
    该范例帮助wireshark使用者根据所需要的协议编写插件进行网络数据分析
  • wireshark支持C语言和Lua语言开发插件,本部分内先介绍Lua插件部分开发。Lua语言相对C语言开发有一个巨大的优势,就是不需要编译代码,因为Lua语言是脚本语言,只需要编写相关协议解析的脚本内容,然后由wireshark...
  • 该博主针对wireshark下LUA脚本的开发做了一系列的笔记,实测详细并且有效,故转载。 1. 骨架 首先新建一个文件,命名为foo.lua,注意此文件的编码方式不能是带BOM的UTF8,否则wireshark加载它时会出错(不识别BOM...
  • dissector_add_uint("tcp.port", TCP_PORT_PGCP, csgpgcp_handle); dissector_add_uint_range()//这个函数只能设置几个连续的端口,多了就崩溃...我想问下,插件中解析的端口号只能写死吗,能否全部监听或者从外部获取
  • wireshark插件开发 - C插件解析

    千次阅读 2017-09-20 17:28:26
    相比较而言,C语言就比较麻烦,需要准备一堆开发环境和第三方库,不够简洁,不过C语言的一个优点就是快。然而,Lua语言在脚本语言也是出了名的快,除非报文的流量非常大。   C语言这部分内容相对多些, 主要涉及...
  • wireshark插件开发 - 自定义协议

    千次阅读 2017-09-20 17:28:21
    虽然wireshark自带了很多知名协议的解析插件,譬如HTTP、DHCP等等,然而在实际应用环境中,有不少软件之间的通信协议都是私有的,如游戏客户端和服务器之间的交互协议通常都是私有的,wireshark无法具体解析出各种...
  • 搭建环境时,出现 “bash 不是内部或外部命令,也不是可运行的程序”。新人,求教。
  • wireshark插件开发小结

    千次阅读 2015-10-31 09:07:21
    关键字:wireshark, plugin, lua,protocol 概述 wireshark是非常流行的网络封包分析软件,功能十分强大。可以抓取各种网络包,并显示网络包的详细信息。 为什么使用wireshark Troubleshoot network...
  • 公司的业务在标准的PDCP协议前面加了44个字节的自定义数据,现在想做个wireshark插件用于数据包解析。 要求是自定义的44个字节不解析,只解析44个字节后的标准的PDCP协议。 但是遇到一个问题:插件跳过了...
  • wireshark插件开发资料

    2015-07-13 15:23:34
    You should probably start by reading (or possibly re-reading) README.plugins very ...And don't forget about README.developer, as well as the Wireshark developer's guide. 前两个能在发布的源码的doc
  • 保存为MC_A1E.lua,放到wireshark目录下,比如D:\program files\Wireshark\plugins\3.0,默认解析6000端口,若非6000端口,可右键解码为 MC_A1E协议 -- @brief MC_A1E Protocol dissector plugin -- @author ...
  • 作为一个新的协议,wireshark并没有支持openflow,为了提高调试效率,更好的分析协议报文,一个openflow的wireshark插件是必不可少的。同时作为一个开源项目,openflow除了斯坦福大学在发布之初提供的1.0版本的开源...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,197
精华内容 1,278
关键字:

wireshark插件开发