[关闭]
@natsumi 2015-02-25T15:41:00.000000Z 字数 2793 阅读 1509

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

Wireshark


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

9.2.3. 改善解析信息

我们可以添加一些数据来改善协议的显示。第一步是添加一些文本标签。我们先来标示数据包类型。对于这类情况,添加一些额外的数据是有好处的。首先我们添加一个简单的类型名表。
例 9.10. 命名数据包类型.

  1. static const value_string packettypenames[]=
  2. {
  3. {1,"Initialise"},
  4. {2,"Terminate"},
  5. {3,"Data"},
  6. {0,NULL}
  7. };

该数据结构可以方便地查询到值所对应的名称。有对其直接操作的函数,不过我们不需调用它们,因为这已经由相关的支持代码实现了。

我们仅需使用VALS宏在数据的适当部分指定细节即可。
例 9.11. 为协议添加名称.

  1. {
  2. &hf_foo_pdu_type,
  3. {"FOO PDU Type","foo.type",FT_UINT8,BASE_DEC,VALS(packettypenames),0x0,NULL,HFILL}
  4. }

这有助于数据包的辨认,我们可以对标志结构做类似的处理。
不过实现这个还需向表中添加更多的数据。
例 9.12. 为协议添加标志.

  1. //添加到文件头部
  2. #define FOO_START_FLAG 0x01
  3. #define FOO_END_FLAG 0x02
  4. #define FOO_PRIORITY_FLAG 0x04
  5. static int hf_foo_startflag=-1;
  6. static int hf_foo_endflag=-1;
  7. static int hf_foo_priorityflag=-1;
  8. //添加到“proto_register_foo”函数中的“hf”数组中,作为数组的成员
  9. {
  10. &hf_foo_startflag,
  11. {"FOO PDU Start Flags","foo.flags.start",FT_BOOLEAN,8,NULL,FOO_START_FLAG,NULL,HFILL}
  12. },
  13. {
  14. &hf_foo_endflag,
  15. {"FOO PDU End Flags","foo.flags.end",FT_BOOLEAN,8,NULL,FOO_END_FLAG,NULL,HFILL}
  16. },
  17. {
  18. &hf_foo_priorityflag,
  19. {"FOO PDU Priority Flags","foo.flags.priority",FT_BOOLEAN,8,NULL,FOO_PRIORITY_FLAG,NULL,HFILL}
  20. },
  21. //添加到“dissect_foo”函数中的合适位置
  22. proto_tree_add_item(foo_tree,hf_foo_flags,tvb,offset,1,FALSE);
  23. proto_tree_add_item(foo_tree,hf_foo_startflag,tvb,offset,1,FALSE);
  24. proto_tree_add_item(foo_tree,hf_foo_endflag,tvb,offset,1,FALSE);
  25. proto_tree_add_item(foo_tree,hf_foo_priorityflag,tvb,offset,1,FALSE);
  26. offset+=1;

这里需要解释一下:

现在,该解析器的功能已显得相当完整了,但我们仍可实施一套方案使其趋于完美。目前我们的解析仅用“Foo Protocol”来标示数据包,这虽然正确但实用价值不大。

我们能够添加一些细节来对其增强。首先我们需要获得协议类型的实际值,这可以通过函数tvb_get_guint8方便地做到。获得该值后我们就可以开展工作了。首先我们可以在包列表面板区的“信息(INFO)”列显示PDU的类别信息——当查看协议踪迹时这是非常有用的。其次,我们也可以在包明细面板区中显示这些信息。
例 9.13. 增强显示.

  1. static void dissect_foo(tvbuff_t *tvb,packet_info *pinfo,proto_tree *tree)
  2. {
  3. guint8 packet_type=tvb_get_guint8(tvb,0);
  4. if(check_col(pinfo->cinfo,COL_PROTOCOL))
  5. {
  6. col_set_str(pinfo->cinfo,COL_PROTOCOL,"FOO");
  7. }
  8. /* Clear out stuff in the info column */
  9. if(check_col(pinfo->cinfo,COL_INFO))
  10. {
  11. col_clear(pinfo->cinfo,COL_INFO);
  12. }
  13. if(check_col(pinfo->cinfo,COL_INFO))
  14. {
  15. col_add_fstr(pinfo->cinfo,COL_INFO,"Type %s",val_to_str(packet_type,packettypenames,"Unknown (0x%02x)"));
  16. }
  17. if(tree)
  18. {
  19. /* we are being asked for details */
  20. proto_item *ti=NULL;
  21. proto_tree *foo_tree=NULL;
  22. gint offset=0;
  23. ti=proto_tree_add_item(tree,proto_foo,tvb,0,-1,FALSE);
  24. proto_item_append_text(ti,", Type %s",val_to_str(packet_type,packettypenames,"Unknown (0x%02x)"));
  25. foo_tree=proto_item_add_subtree(ti,ett_foo);
  26. proto_tree_add_item(foo_tree,hf_foo_pdu_type,tvb,offset,1,FALSE);
  27. offset+=1;
  28. }
  29. }

这里,在获得前8比特位的值后,我们使用内置的应用函数val_to_str获得该值对应的数据。如果值不存在,我们会直接以16进制形式显示该值。我们使用该数据两次,一次用于列表的“信息(INFO)”字段,当然是在它显示的情况下,同样,我们也会将该数据添加到解析树的基部。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注