snort作为一个网络入侵检测工具,与同类工具拥有相似的处理流程,如下所示:
基本数据初始化
回调函数注册
读取规则建立临时结构
使用临时结构建立最终便于匹配的结构,该过程也可称为编译过程。
进入循环获取报文进行处理
而报文的处理又经历如下流程
拆包
预处理
匹配
动作
前面文章已经分析了规则的读取:
http://my.oschina.net/u/572632/blog/290351
这里就将继续分析如何建立匹配结构,建立匹配结构的过程又可称为编译过程,目地是将读取规则后建立的便于收集数据的结构转换为专门用于匹配的结构。
如下图所示,当端口初次解析的过程中snort使用如下的方式存放解析出的端口对象。
按照端口所属规则的协议类型将其分为tcp, udp等几类
每一类协议包含anyany_object, src_table, dst_table
如果这条规则的源和目地端口都为any则直接将该规则的规则索引加入anyany_object持有的规则链表中。
如果该规则的源端口非any,则将该规则的源端口对象入src_table中,并将该规则对应的索引加入源端口对象持有的规则链中。如果该规则的数据流是双向的则还需要将源端口对象加入dst_table中。
如果该规则的目地端口非any,则将该规则的目地端口对象入dst_table中,并将该规则对应的索引加入目地端口对象持有的规则链中。如果该规则的数据流是双向的则还需要将源端口对象加入dst_table中。
存在必有其理由,代码也一样,作者的处理必然有其原因,因此这里先分析下目前的状况。
现在我们的anyany_object表现的很良好,但在src_table或者dst_table中会有多个port_object,当读取规则完成后在src_table或dst_table中的portObject目前如下图。这会带来下面几个问题。
port item在前面的文章做过分析,他可能是一个端口,也可能是端口范围,甚至可能是其包含的端口取反,更糟糕的是port Object是他持有的端口条目综合得出的。
即使我们为port object处理了port item集合后,在port object之间也可能出现重复的问题,极端情况可能6000个端口指向同一个port object而我们却保留了6000个副本,这是相当糟糕的。
因此在这里的匹配结构我们希望是下面这样的,每个端口下面是匹配上该端口的规则集合。
所以这里的代码所需的工作就是从上面的结构转换为下面的结构。
fpCreatePortGroups
IN BUILDING
snort 快速匹配引擎的构建,布布扣,bubuko.com
原文:http://my.oschina.net/u/572632/blog/292514