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

标签: 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_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协议的包类型。

  • 函数proto_item_add_subtree的调用在协议树中添加了一个子树,我们就在这里进行细节解析。子树的展开受控于变量ett_foo。当您在协议间切换时,由它记录子树是否展开。正像您从下面的函数调用中看到的那样,随后的所有解析都会添加到该子树中。

  • 函数proto_tree_add_item用于为子树foo_tree添加项,这次调用使用变量hf_foo_pdu_type控制项格式。PDU(协议数据单元)类型是一个单字节数据,位于数据包的首字节,我们将有效数据范围的起点设为0,长度设为1。我们假设它依照网络字节顺序,所以将最后一个参数设为FALSETRUE表示"little endian",FALSE表示"big endian")。尽管对于单字节数据无所谓字节顺序,但我们最好还是保持指定字节顺序的良好习惯。

  • 如果详细查看静态数组中hf_foo_pdu_type的声明,我们能够获悉定义的明细:

  • 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;
  • 这段代码解析了这个简单的虚构协议的全部内容。我们引入了一个新的变量offset以记录数据包解析的位置。将这些额外的代码块放入合适的位置,整个协议就可以得到全面的解析。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,494评论 18 139
  • 简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者...
    保川阅读 5,933评论 1 13
  • 标签: Wireshark 版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明http://www....
    natsumi阅读 1,288评论 0 1
  • tcpdump抓包命令 tcpdump是一个用于截取网络分组,并输出分组内容的工具。tcpdump凭借强大的功能和...
    Yihulee阅读 13,968评论 0 3
  • ———————————————回答好下面的足够了---------------------------------...
    恒爱DE问候阅读 1,705评论 0 4