您的位置:首页 > 其它

suricata 3.1 源码分析23 (数据包解码模块注册及初始化)

2016-09-28 09:37 260 查看
简介

Suricata的解码模块与数据包获取模块是一一对应的,例如DecodePcap对应ReceivePcap,DecodeAFP对应ReceiveAFP。

然而,我们知道数据包格式都是协议规定的,因此核心的数据包解码流程一定会是固定的。例如,对于常规的以太网包IPV4包TCP包,无非是DecodeEthernet->DecodeIPV4->DecodeTCP->…

那么,这里为什么需要设置不同的解码模块呢?主要原因是因为,各种数据源对协议的支持可能不同,并且也需要相应对Packet进行些不同设置。为了避免把这些差异处理代码集中放在一个诸如DecodePacket这样的通用函数中,因此Suricata干脆就做了划分,不同数据源对应不同解码模块。其实随着后面分析可以看到,每个解码模块函数都大同小异,在做完针对各自数据源的特殊处理后,都会调用DecodeEthernet、DecodePPP、DecodeSll等通用解码函数进行进一步处理。

例如,据我用肉眼做diff,DecodePcap和DecodeAFP的内容完全一样,而DecodePfring却相对更简单,只有对Ethernet的解码,因此可以猜测pfring数据源大概只支持以太网。另一方面,DecodePcapFile又完全不同了,其中有些针对Flow的特殊处理,并且解码也是通过回调函数来调用的,具体不知道是调的什么函数。

与前面数据源的类似,下面我只记录常用的实时pcap模式下的解码模块的实现,也就是DecodePcap模块。若遇到与前面可能重复的内容,这里可能就只简单提一下,避免冗余。

模块注册

模块注册是跟ReceivePcap模块紧挨着的,与后者不同的是:

1. 模块flags为TM_FLAG_DECODE_TM,表示这是一个解码模块。

2. 这次模块执行函数不再是PktAcqLoop了,而是Func,设置为DecodePcap。

模块初始化

初始化函数为DecodePcapThreadInit。这个模块并没有初始化数据,因此initdata没有使用。函数内部会新建一个DecodeThreadVars结构体,用于保存该线程模块的上下文。该结构的重要字段如下:

字段含义
udp_dp_ctx用于UDP包的应用层协议检测,通过AlpProtoFinalize2Thread初始化。
counter_*解码模块所注册的性能计数器ID,例如counter_ipv4计数器用于统计IPV4数据包个数。
函数中首先通过DecodeThreadVarsAlloc新建一个DecodeThreadVars,然后调用DecodeRegisterPerfCounters注册所需的计数器。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据