对网络协议解析的抽象,并简单介绍netbee库

去年曾经在Windows下用MFC写了一个网络协议解析器,界面和功能模仿Wireshark,但是解析速度比Wireshark这样重量级的软件还慢几分(20MB以上的pcap文件,则慢两三倍)。期间产生了一些关于“抽象”的想法,今天看到NetBee以后,可以简单总结一下了。

对真实网络数据的协议解析是一个逐层递进的过程:解析完链路层,然后是网络层,接下来是传输层……每一层的解析工作需要三个参数:

  • 根据上层的一些属性,判断这一层的协议类型
  • 这一层得数据指针,指向协议头
  • 这一层的数据长度,包括协议头和载荷

因此,每一个协议的解析函数抽象为同一个原型,这是最基本的抽象。

在解析方法上,同样有共性可循。大部分操作是这样的:读取固定偏移的几个字节,得到一些数据(地址、时间、操作类型等)。这类操作的代码写多了以后,自然开始想一个问题:能不能把这种代码也自动化处理了?

困难之处在于,各类网络协议的格式解析方法还是存在很大差异的。比如有的协议头部长度不固定,根据某个域的取值来找到头部。因此,将这类操作简单地做功能和配置的分离还不够。需要用一门特定的微语言来描述解析方法,至少包括以下内容:

  • 这个协议头部的字段描述,包括字段长度(或长度依赖关系)和名称;
  • 协议头部每一字段的含义、其可能取值、数据的格式;
  • 根据某些字段的取值不同,确定下一层协议的类型。

在定义了这个协议描述语言后,我们还需要一个通用的引擎,它一边读取网络数据,一边在描述语言的驱使下逐层地解析数据。这个引擎可以分为两部分:前端解析描述语言,后端为大量简单功能的调用,例如“读取两字节,并翻译为整数”等。

这种描述语言+引擎的设计,优点是很显然的——对特定协议的解析代码被抽象为对解析过程的描述,即控制和配置的分离。在这个架构下,要增加对新协议的支持,不用再写新的代码,而是增加描述语言即可。

这些工作已经有了一个实现,即NetBee(http://www.nbee.org/),作者是原来WinPcap的开发团队。此外,作者还基于NetBee开发了名为Analyzer的抓包解析工具(http://analyzer.polito.it/)。

NetBee由三个主要部分构成:

  1. NetPDL:Network Protocol Description Language,是用XML实现的协议解析描述语言,包含了上述三部分必要的内容,即字段描述、语义描述和下一层协议判定;
  2. NetPFL:F是指Filter,这个语言用于网络数据的过滤或分类(防火墙、网关、IDS等大量网络应用有此需求),它依赖于NetPDL的定义,提供类似于“如果是什么协议,或者某字段等于什么时,做什么事”的描述信息;
  3. NetVM:虚拟机,即上面所说的“通用的引擎”。整个系统运行时,会将NetPDL数据库(没错,大量常用协议的描述已经形成知识库)和特定需求的NetPFL一起,编译成中间语言,然后投入NetVM执行。当然,如果只是做协议解析,NetPFL不是必须的。

用图可以更清晰地描述NetBee的结构:

经过了代码转译和虚拟机执行以后,NetBee的解析速度显然是要慢于Wireshark的(后者将不常见协议的解析代码写成动态链接库,根据需要调用执行)。但作者在论文中偷换了一个概念,在将解析结果输出为一种名为PDML的数据包描述格式时,NetBee速度快于ethereal(Wireshark前身),这个结果很欠抽——这个架构本来就是基于XML的,不用像wireshark那样去重新组织数据。

除了速度问题,NetBee还有一些缺点:

  1. 不开源,只提供动态链接库文件;
  2. 不提供Linux下的二进制发行版;
  3. 文档质量一般,示例代码有错误等。

所以很可惜,这个库只能在特定需求下作为解决方案之一。不过这种设计思路,正好印证了Unix开发的很多风格,值得我们学习借鉴。

对网络协议解析的抽象,并简单介绍netbee库》上有6条评论

    1. Claud 文章作者

      我给作者发了信,当天就把最新的源码发给我了,挺不错的(虽然编译折腾死我,make严重依赖于绝对路径)。你也可以试试。
      源码的分发和使用许可不是自由的,我不能发给你,sorry。

      回复
  1. Jacd li

    请教一下netbee的在linux源码的编译方法,我看这源码里面的也没的makefile,难道要自己编写?如果有文档,发我邮箱,小弟不胜感激。谢谢,大侠!

    回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注