【转】【翻译】Wireshark:添加一个基础的解析器(2)

2015-02-26  本文已影响86人  natsumi

标签: Wireshark


版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://www.blogbus.com/shujiantang-logs/35858037.html
本文是Wireshark官方开发文档9.2节《添加一个基础的解析器》的翻译

9.2.2. 解析协议细节

现在我们已经有了一个可以运用的简单解析器,让我们再为它添点儿什么吧。首先想到的应该就是标示数据包的有效信息了。解析器在这方面给我们提供了支持。

首先要做的事情是创建一个子树以容纳我们的解析结果。这会使协议的细节显示得井井有条。现在解析器在两种情况下被调用:其一,用于获得数据包的概要信息;其二,用于获得数据包的详细信息。这两种情况可以通过树指针参数tree来进行区分。如果树指针为NULL,我们只需要提供概要信息;反之,我们就需要拆解协议完成细节的显示了。基于此,让我们来增强这个解析器吧。

例 9.4. 插入数据包解析.

static void dissect_foo(tvbuff_t *tvb,packet_info *pinfo,proto_tree *tree)
{
    if(check_col(pinfo->cinfo,COL_PROTOCOL))
    {
        col_set_str(pinfo->cinfo,COL_PROTOCOL,"FOO");
    }
    /* Clear out stuff in the info column */
    if(check_col(pinfo->cinfo,COL_INFO))
    {
        col_clear(pinfo->cinfo,COL_INFO);
    }
 
    if(tree)
    {
        /* we are being asked for details */
        proto_item *ti=NULL;
        ti=proto_tree_add_item(tree,proto_foo,tvb,0,-1,FALSE);
    }
}

现在进入下一步,添加一些协议解析功能。在这一步我们需要构建一组帮助解析的表结构。这需要对proto_register_foo函数做些修改。首先定义一组静态数组。
例 9.5. 定义数据结构.

static hf_register_info hf[]=
{
    {
        &hf_foo_pdu_type,
        {"FOO PDU Type","foo.type",FT_UINT8,BASE_DEC,NULL, 0x0,NULL,HFILL}
    }
};
 
/* Setup protocol subtree array */
static gint *ett[]=
{
    &ett_foo
};

接下来,在协议注册代码之后,我们对这些数组进行注册。
例 9.6. 注册数据结构.

proto_register_field_array(proto_foo,hf,array_length(hf));
proto_register_subtree_array(ett,array_length(ett));

变量hf_foo_pdu_typeett_foo依然需要在文件顶部的某处予以声明。
例 9.7. 解析器全局数据结构.

static int hf_foo_pdu_type=-1;
static gint ett_foo=-1;

现在我们就可以对协议细节的显示做一番改善了。
例 9.8. 解析器开始数据包解析.

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,FALSE);
    foo_tree=proto_item_add_subtree(ti,ett_foo);
    proto_tree_add_item(foo_tree,hf_foo_pdu_type,tvb,0,1,FALSE);
}

协议的解析变得愈发有趣了。我们提取出协议的第一部分。数据包的首字节定义了foo协议的包类型。

  • hf_foo_pdu_type:节点索引。
  • FOO PDU Type:项标示。
  • foo.type:过滤字符串。我们可以在过滤框中输入诸如foo.type=1的结构。
  • FT_UNIT8:指定该项数据是一个8比特位的无符号整型。这和我们之前调用函数时设置的一字节有效数据是相一致的。
  • BASE_DEC:针对整型数据,指定将其作为十进制数显示。当然视具体情况也可以设置为“BASE_HEX”(十六进制)和“BASE_OCT”(八进制),以使数据更易辨识。
  • 至于结构中余下的部分我们暂且忽略。

如果您现在安装并试用这个插件,就会发现一些有用的东西了。

接下来让我们完成这个简单协议的解析工作吧。我们需要再添加一些hf数组成员和程序调用。
例 9.9. 完成数据包解析.

//添加到文件开始的某个地方,作为全局变量
static int hf_foo_flags=-1;
static int hf_foo_sequenceno=-1;
static int hf_foo_initialip=-1;
 
//添加到“proto_register_foo”函数中的“hf”数组中,作为数组的成员
{
    &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}
},
 
//添加到“dissect_foo”函数中,实现数据包的解析
gint offset=0;
ti = proto_tree_add_item(tree,proto_foo,tvb,0,-1,FALSE);
foo_tree=proto_item_add_subtree(ti,ett_foo);
proto_tree_add_item(foo_tree,hf_foo_pdu_type,tvb,offset,1,FALSE);

offset+=1;
proto_tree_add_item(foo_tree,hf_foo_flags,tvb,offset,1,FALSE);

offset+=1;
proto_tree_add_item(foo_tree,hf_foo_sequenceno,tvb,offset,2,FALSE);

offset+=2;
proto_tree_add_item(foo_tree,hf_foo_initialip,tvb,offset,4,FALSE);

offset+=4;
上一篇 下一篇

猜你喜欢

热点阅读