Zenith 原创作品,要转载,请注明出处, 并对本文保留出版权。
本文特别使用WildPackets自带的Decoder,对协议的解析的过程进行了详细阐述。
本说明,会选取SMPP的片断作为例子进行说明。
首先,我们在解码时,需要了解整个网络信息的组织方式和消息结构。有必要了解OSI的分层结构,和某一种协议的对应关系,来帮助理解协议的本质。如果解析的是以太网的数据包,则需要了解以太网的消息结构,IP数据包则需要了解IP包的组织方式和消息结构,TCP包的组织方式和消息结构,应用层协议数据的组织方式和消息结构,例如,这里我们要对SMPP进行解析,那么我们就需要了解SMPP消息的内部结构和组织方式。
对SMPP来说,它是一个应用层的协议,那么它就必须依赖一个下层协议进行数据传输。在这里,它下层传输协议就是TCP。TCP是一个传输层协议,它也要依赖下层协议进行数据路由,它的下层就是IP协议。以此类推,IP协议的下层就是以太网协议。当然也可以是其他协议如PPP协议等。
现在我们来看看,如果进来一个SMPP的数据包,DecoderManager是如何从第二层数据解析到TCP以及应用层数据的呢?
首先我们可以从Manager.dcd中可以看到:
解析管理器进程入口:
如果进来的是以太网数据,Decoder Manager会调用Manager.dcd中的void Ether::Main()方法对以太网数据的链路层数据进行解析并将数据显示在WildPackets产品(OmniPeek或EtherPeek)的主窗口中。
其实,这只是一系列的方法调用的结果。根据每一层协议头中的协议标志位进行相应的方法调用,以此类推,层层解包,就能完成我们要达到的目的了。
由此,根据上述原理,我们可以清晰发现,如下的方法调用路径
Ether::Main()-->Ether::Branching()-->Ether::Branching2()-->Ether::Brankching3()
在Branching3中,我们可以看只有一条指令
TST# 0 1 -Ether::Branching_3_Str;
|
这条指令是跳转指令,根据当前g[1]中的值作为索引,装载Ether::Branching_3_Str中和g[1]中对应的解码器并运行之。
而在Ether::Branching_3_Str中,我们可以发现这么一个自定义索引数组的成员
这个0800,就是以太网的上层协议标志位,这里指的是IP,所以在Ether::Brankching3()之后,如果数据包的上层协议标志位是IP的话,DecoderManager会执行IP()这个方法,如果是其他标志的话也会执行其他方法,只要这些方法在这里已经定义,如果要解析其他非IP协议的朋友,就可以在这里申明其他协议标志和该协议解析方法的绑定了。
接下来开始解析IP层的数据了。 IP方法和TCP方法都在IETF_main.dcd这个文件中定义。
类似链路层的解析,我也可以看到 IP层解析的方法调用路径:
IP()-->IP Options g2()-->IP::Common()
在IP::Common中,我们也可以看到这么一句:
类似的,在g[3]中,包含了代表上层协议的数据,这句就是根据索引数组去调用上层协议解析器的入口,如果是TCP的话,就会调用TCP()方法。如果是其他协议的话,同样也可以在这里定义其他上层协议的子解析器。
果然,在IP::Common_Str中有这个成员:
同样在开始TCP()解析后,我们发现存在这样的调用路径:
TCP()-->TCP_Data()-->TCP_ports()
根据TCP_ports()的定义我们可看到这个指令:
根据TCP::Ports_Str,我们得到了根据TCP端口来进行应用层解析的入口:
0x1398的十进制为5016,一般为SMPP协议的默认端口。 SMPP()存放在SMPP-short_message_peer_to_peer.dcd文件中。如果有要解析其他协议的,可以在这个数组中添加端口和要调用的针对该协议的解析器名称。
下面,我们来看看SMPP()方法的内部定义。
LABL( 0, 0, 0, 0xb1, "SMPP - Short Message Peer to Peer Protocol"); g[50]= pl[4]; SMPP::Header(); SMPP::OPLauncher(); //TSB#( 0, l[3], 0, 0, SMPP::Operation_Type)
|
整个程序结构很紧凑,一共才四个指令:
LABL是打标签指令,对数据指针无任何影响。
g[50]...,这句的含义等于 GLNG 4 50; 根据SMPP协议的定义,意义为将SMPP的命令字(CMD_ID)放入全局变量数组索引号为50的成员中,并且不改变数据指针的位置。
接下来,分别调用SMPP::Header()方法和SMPP::OPLauncher()来对SMPP的协议头和消息体作解析处理。
在SMPP::Header()中,命令字的识别和打印,主要是按照SMPP::Command_ID_Str;索引数组进行的。
SMPP::OPLauncher()中,对各个命令字消息的解析,也是通过SMPP::Operation_Type;索引数组进行跳转解析的。
致此,我们已经对WildPackets的解析器的解析过程进行了一系列的分析。
希望对各位有所帮助。
2007/08/25
阅读(3100) | 评论(0) | 转发(0) |