A-A+

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

2018年12月06日 suricata 暂无评论

简介
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注册所需的计数器。

标签:

给我留言

Copyright © 九毛的官方博客 保留所有权利.   Theme  Ality

用户登录