用NetPDL解析网络数据

来源:互联网 发布:阿里巴巴网站淘宝网 编辑:程序博客网 时间:2024/04/27 21:02

摘要:

       在目前的网络通讯和诊断中,网络截包的分析是非常重要的一个环节,尤其在调试私有协议的时候,常常会出现要对着屏幕数字节的问题,各个字段的解析也非常麻烦。在本文中给出一个工具Analyzer和一种数据可视化语言netPDL,对于解析私有协议非常有用。

 

关键词: 网络 数据 表示 xml netPDL

 

 

1.  网络数据的常见形式

网络截包数据是二进制编码,并且数据表示方式有多种多样。比如网络序的长字,字,字节,位等。并且协议的一些字段可能有变长成分,字段的解释严重依赖于前面字段的含义。如何解析这些协议通常很费脑筋,因为如果自己写解析器,那么图形化表示将是一个问题,为了实现图形界面所花时间将会远超过写解析器本身。 如果采用软件工具的话,基本上大部分分析网络包的工具不支持私有协议的解析,自己写一个解析器插件通常比较麻烦,我想为ethereal写解析器应该不会简单。那么就剩下一个比较容易的办法,那就是如果分析工具支持用户用一种简单的语言定义规则,然后分析器读入规则并且根据规则将数据截包表示出来,那一定会使得私有协议的调试简单方便的多。

从目前各个软件看来,ethereal是开源工具里支持协议比较多,功能比较强大的,但是开发私有的解析器需要编写插件,需要编译链接过程,并且其本身的一些库在windows下编译并不方便,所以不符合私有协议开发的要求。而Analyzer则提供了一个接口和一个规范语言netPDL,用户可以用netPDL语言写一个xml文件,然后改动一些相关配置,就可以很方便的解析新的协议了。

2.  网络数据的表示

netPDL中,基本上解析一个协议所需要的能力都具备了,从本质上来说,netPDL也是一种语言,analyzer读入netPDL所写的xml文件,然后在虚拟机内解释执行,从而控制网络数据的表示。下面就给出netPDL的一些基本方面:

定义一个协议的通用结构

1)  <proto>标记定义一个协议,在协议里会处理协议格式和协议封装。

一个协议由<fields><block> <presentif> <nextproto>构成,后三个是可选部分。

<field>由如下域组成:

       <fixed> 定义了一个定长域

       <masked> 定义了一个掩码域

       <variable> 定义了一个变长域

       <line> 定义了一个行的变长域

       <pad> 定义了pad以对齐到一定的边界

       <includeblk> 定义了一个必须被包含在当前位置的给定块

       <plugin> 定义了一个外部插件来处理解码过程

       <if> 定义了一个处理分支

       <switch> 定义了当前处理流程的多重选择

       <loop> 定义了一个能被处理几次的域

       <loopctrl> 定义了一个能够修改循环标准处理的事件

 

       <block>类似一个子协议,常用于表达扩展域等,有<field><presentif>域。跟条件解码配合使用可以提高解码显示的可读性,打个比喻,<block>有点类似子程序,可以通过<includeblk>来调用。

      

描述一个协议的域是一个麻烦的事情,通常 域长度和域出现次数以及域偏移可以确定一个域,但是很多情况下,这些域的相关参数需要动态确定,所以<offset>用来确定域偏移,<loop>用来确定出现次数。

 

下面是定长域的一些属性:size,vector,如果是位域,用的属性是masked,bit

对于变长字段,属性为 <variable> <varend> <oper> <size>

 

3.  对于私有网络数据的解析

目前有一个专有软件采用专有协议和另外的实现通讯。通常是在终端的tcp端口5555通讯。一般是

0x55 长度(4字节)命令字(1字节)命令内容(变长) 0xaa

              其中 长度=命令内容长度+7

下面的就是pc控制台数据的xml文件:

<?xml version="1.0" encoding="utf-8"?>

 

<proto name="PCControl" showname="zte PC Control">

 

       <presentif oper="eq">

              <fieldref name="fixheader"/>

              <number value="85"/>

       </presentif>

 

       <fields>

              <fixed name="fixheader" showname="fix header 0x55" showtype="hex" size="Byte"/>

              <fixed name="len" showname="packetlen" showtype="hex" size="word"/>

              <fixed name="commond" showname="commond" showtype="hex" size="byte"/>

           <variable name="payload" showname="payload" varend="size" oper="=">

            <expr oper="-">

                <fieldref name="len"/>

                <number value="7" type="dec"/>

            </expr>

        </variable>

        <fixed name="fixtail" showname="fix tail 0xaa" showtype="hex" size="Byte"/>

 

    </fields>

 

</proto>

为了让analyzer分析我们的协议,假设上面的xml文件叫做PCControl.xml, 那么需要如下处理:

1)在netPDL.xml中加入 <!ENTITY PCControl SYSTEM "PCControl.xml">

   &PCControl;

2)由于是tcp协议,需要在tcp-udp.xml中源端口和目的端口switch中加入:

<case value="9999" protoref="PCControl"/>

然后启动analyzer,打开我们捕获的包,会有如下界面:

 

 

4.  本方法的缺点

虽然本方法写解析器很方便,但是也有其缺点,就是如果私有协议的字段本身解释过于复杂,或者位操作过于复杂,xml解析器写起来也很麻烦,这时候还是类似ethereal的解析器比较方便。