对于suricata UT用例来说,很多时候需要构造报文作为输入,有的时候还要构造流作为输入,获取报文匹配结果。为此在suricata中使用util-unittest-helper.c文件来组织这些用于构造UT用例的辅助函数。

unittest-helper.c文件是由编译宏控制编译的,即#ifdef UNITTESTS,在正式的发布版本中不会被编进入执行程序中,但是在运行UT的时候只要定义UNITTESTS,即可以运行,如图1:

图1

util-unittest-helper.c文件主要分为两大类,即辅助的构造函数以及针对这次构造函数的测试用例。辅助构造函数又分为如下几类:

1,构造报文相关
构造报文最基本的是UTHBuildPacketReal函数,该函数的作用是构造特定IP以及特定端口的TCP,UDP和ICMP报文,该函数的入参就是报文payload数据及其长度,以及五元组。该函数内部的实现也是很明确,即申请Packet这样干一个内存空间,将入参的值赋上后即完成了报文的创建。因为在外部传递到引擎的报文最终都会转化为Packet结构体进行处理。可以看到很多的测试用例都会使用该函数进行报文的创建,例如DetectDnsQueryTest04。当然此函数针构造的是IPV4报文,如果想要构造IPV6报文,则可以使用UTHBuildPacketIPV6Real函数,由此可见suricata内置是支持IPV6的。

在一条用例执行完毕之后,需要对于申请的报文空间进行释放,就需要使用UTHFreePacket进行内存的释放。

UTHBuildPacketReal为最原始的构造报文函数,还有一些函数封装了此函数提供了更多差异化的函数构造功能,如下:

UTHBuildPacket使用默认的IP和端口进行报文构造,使用者只需要传输payload内容,长度和协议三个参数即可。

UTHBuildPacketSrcDst使用了默认端口,需要payload内容,长度,协议以及目的源IP五个参数即可。

UTHBuildPacketSrcDstPorts使用了默认IP,需要payload内容,长度,协议以及目的源端口五个参数即可。因为对于有的用例来说需要关注端口而不关注IP,则使用UTHBuildPacketSrcDstPorts即可,其他同理。

上述的函数是构造单个报文,如果想要构造多个报文的话使用一组循环即可。上述构造报文的函数还有一个问题在于,其入参关注的是五元组,那么除了五元组之外的,比如TCP的ACK字段是没有构造的,对于这种情况该怎么办呢?可以使用UTHBuildPacketFromEth,对于构造单个报文来说,比较简洁的办法是使用一些真实的报文数据进行导入。可以看到函数的入参便是原始的报文数据,以及数据大小还有报文个数。其本质是通过引擎的解码函数DecodeEthernet来填充Packet结构体的内容。正常来说引擎的工作模式也是对于接收到的数据,送入DecodeEthernet进行解码,然后填充Packet结构体各个字段的内容,对于IP,TCP的各个字段在Packet结构体中就会有所体现。由此你也可以看出引擎是从DecodeEthernet开始处理的,当然该函数还是要被wrapper的,因为外层还有一些逻辑。对于构造多个详细报文来说,使用UTHBuildPacketArrayFromEth函数即可。释放多个报文的函数为UTHFreePackets。

2,构造流相关

引擎中使用流表来管理流,如果想要创建单条流,使用UTHBuildFlow函数。同报文创建相同,该函数为单条流申请内存,空间并将四元组以及IPV4或者IPV6对应的标志位赋值即生成流。

由于特定的报文属于某一个流,因此实用 UTHAssignFlow函数指定报文的归属,其实内容很简单就是将报文结构体中的flow和标志位关联即可。其实可以想象当引擎收到一个报文的时候,会通过四元组去查找流表,如果流表中流已经存在,将报文进行关联,如果不存在,新建流在关联。

释放流内存的函数为UTHFreeFlow。

另外还发现存在UTHAddStreamToFlow,UTHAddSessionToFlow等函数。首先flow,session,stream这几个概念如下:

flow:通常所说的流,包括TCP流以及UDP流,由五元组唯一确定的通信双方的虚拟链接。
stream:这个就不像flow是一个比较通用的概念,stream是suricata中特指TCP的一条流的上行链接或者下行链接。通常来说flow包含了双向的报文,而一条stream特指TCP的上行报文或者下行报文内容。
session:session也是suricata中为了处理TCP的内容而设置的概念,可以说session和tcp 的flow总体上是指的一回事,当然两个结构体并不相同。由于flow除了表示TCP流之外,还能够表示UDP流,因此flow一个比较通用的结构体。由CP流的处理远比UDP复杂,包括各种报文重组等等,因此使用了session来表示独立于flow之外的一些功能,比如报文重组,因此可以简单的理解session就是一个TCP流的处理结构。

由于TCP的处理比之UDP要复杂许多,为此suricata提供了stream 表示单向的流内容,使用session来进行额外的流处理。

UTHAddSessionToFlow即申请一个session的结构空间,和flow进行关联。由于在session结构中存在了client以及server的stream,因此在UTHAddStreamToFlow的主要工作就是将接受到的数据加入到上下行stream的buffer中。详细使用可以参考DetectUriSigTest06用例。UTHRemoveSessionFromFlow表示从flow中去除session。

3,构造匹配规则相关
UTHAppendSigs向引擎上下文加入规则。通常来说规则文件是以.rules文件提供的,文件中每一行就是一条规则,通过文件加载形式赋值给引擎。但是在UT测试的时候,需要时用UTHAppendSigs函数给引擎上下文添加规则,其中入参包括引擎上下文结构,规则数组,即一行行规则的字符串数组,还有规则个数。其本质也是调用引擎的DetectEngineAppendSig函数完成具体任务,这个函数也是规则加载过程中非常重要的函数。可以参考SCSigOrderingTest12用例中的使用方式。

UTHMatchPackets的入参是引擎上下文,以及若干个报文,目的是让报文去匹配规则。在函数中封装了引擎最为重要的一些函数,包括SigGroupBuild将解析的规则转换为内部的结构;DetectEngineThreadCtxInit初始化引擎上下文;SigMatchSignatures->DetectRun规则检测等等。构造UTHMatchPackets的目的在于作为用例使用的公共部分(但是实际使用的并不多),更多的用例会单独的使用SigGroupBuild以及DetectEngineThreadCtxInit等函数构造测试逻辑。但是通过UTHMatchPackets可以了解到报文匹配规则前后的一些设置,执行的逻辑,这是很重要的。

UTHCheckPacketMatchResults检查报文匹配的结果是否正确,调用PacketAlertCheck进行检查。通过PacketAlertCheck也可以得知,匹配的结果存储在p->alerts.alerts[i].s->id中。

用例SCSigOrderingTest12中正是体现了上述的内容,先是示给引擎上下文添加规则UTHAppendSigs;然后通过报文进行规则的匹配UTHMatchPackets;最后检查匹配结果UTHCheckPacketMatchResults。

UTHPacketMatchSig中使用报文去匹配引擎上下文中的规则,UTHPacketMatchSig的入参为报文和规则,其目的是直接使用报文匹配指定的规则。对比UTHMatchPackets函数,他们用到的执行逻辑都是一致的,即SigGroupBuild将解析的规则转换为内部的结构;DetectEngineThreadCtxInit初始化引擎上下文;SigMatchSignatures->DetectRun规则检测等等。UTHPacketMatchSigMpm比之UTHPacketMatchSig更近一步,增加了多模匹配算法的类型这个入参。

UTHParseSignature测试规则解析是否正确。

UTHGenericTest对前面介绍的函数又进行了封装,即直接扔进去报文,规则,预期结果,然后给出检测结果是否符合预期。

明白了上述几类辅助函数,相信对于该文件中剩下的用例也是很容易理解的。

本文为CSDN村中少年原创文章,未经允许不得转载,博主链接这里。

suricata UT测试用例中使用的几个重要的辅助函数相关推荐

  1. 对linux的mv命令设计测试用例,测试用例中的细节 - 八音弦的个人空间 - OSCHINA - 中文开源技术交流社区...

    编写测试用例是在实际测试执行开始之前进行的软件测试活动的重要组成部分.因此,在编写测试用例时必须头脑清晰地理解需求.测试执行阶段的顺利程度主要取决于测试用例的编写质量,还取决于对需求的理解程度.理论上 ...

  2. 根据接口文档中的入参,生成自动化测试用例中的异常测试用例,包含用例描述,用例数据

    根据接口文档中的入参,生成自动化测试用例中的异常测试用例,包含用例描述,用例数据 参考文章: (1)根据接口文档中的入参,生成自动化测试用例中的异常测试用例,包含用例描述,用例数据 (2)https: ...

  3. gtest 学习之五 测试用例中定义类

    上一个例子中被测试的类是作为测试类的一个成员变量,在本例中没有测试类,被测试类只能在一个测试用例中定义使用 头文件sample4.h #ifndef GTEST_SAMPLES_SAMPLE4_H_ ...

  4. 软件测试报告na是什么意思,软件测试用例中报告结果的N\/A是什么意思

    CMCC测试用例中的N/A,是指没有条件或者环境去测这一条CASE,比如某一条case需要某种辅助工具去测试,而这种辅助工具没有,那就是N/A.总之是不用测或者是没有测的意思 测试用例的执行结果怎么区 ...

  5. python 测试用例中设置执行时间_Python基于unittest实现测试用例执行

    利用python进行测试时,测试用例的加载方式有2种: 一种是通过unittest.main()来启动所需测试的测试模块: 一种是添加到testsuite集合中再加载所有的被测试对象,而testsui ...

  6. 根据接口文档中的入参,生成自动化测试用例中的异常测试用例,包含用例描述,用例数据...

     不想当将军的小兵,不是好的小兵:不想做开发的测试,不是好的测试: 不管你信不信,我是信了... 一直以来,内心总有些迷茫的时候,迷茫的是作为测试既然要学那么多编程,为什么不直接去干开发呢? 看了这句 ...

  7. SAP Spartacus单元测试用例中Component构造函数的调用上下文

    我有一个Angular Component,构造函数的两个参数通过依赖注入指定. 在单元测试时候,观察这两个参数如何被注入的.在构造函数被调用之前,先执行实例的初始化逻辑: 观察此时的this: 最后 ...

  8. junit 参数化测试用例_JUnit:在参数化测试中命名单个测试用例

    junit 参数化测试用例 几年前,我写了有关JUnit参数化测试的文章 . 我不喜欢它们的一件事是JUnit使用数字命名了单个测试用例,因此,如果它们失败,您将不知道是哪个测试参数导致了失败. 以下 ...

  9. JUnit:在参数化测试中命名单个测试用例

    几年前,我写了有关JUnit参数化测试的文章 . 我不喜欢它们的一件事是JUnit使用数字命名了单个测试用例,因此,如果它们失败,您将不知道是哪个测试参数导致了失败. 以下Eclipse屏幕快照将向您 ...

最新文章

  1. spring mvc 异常统一处理方式
  2. 洛谷P1003 铺地毯 noip2011提高组day1T1
  3. 《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一导读
  4. 【pyqt5学习】——groupBox显示matplotlib图像
  5. doc无法编译java文件_java编译成jar文件.doc
  6. MySQL 事物隔离级别
  7. 怎么样得到平台相关的换行符?
  8. 查询mysql临时表空间_查看临时表空间使用情况
  9. Python socket 编程理解
  10. 智能优化算法:粒子群算法相关代码
  11. MySQL单元三试题与答案_2016年3月三级MySQL数据库试题及答案
  12. 移动叔叔MTK6589一键ROOT工具v3.0+by+罗微
  13. SD卡 TF卡 引脚定义
  14. 1.1 pug常用命令
  15. H2教程系列(二) 创建数据库
  16. 用计算机计算工资的公式,工资、薪金所得个人所得税Excel计算公式(正算)
  17. 计算机关系差 并 交,计算机三个关系投影 交 并 差是什么意思
  18. 点到平面的距离(最短距离)
  19. ChaosBlade
  20. 外架小横杆外露长度规范要求_浅谈提高悬挑架质量、安全及视觉效果的管理方法...

热门文章

  1. EasyExcel标题加批注和标题字体填充红色
  2. 全球回报最好的 40 个 VC 投资案例,我们可以从中学到什么?
  3. 软件工程网络15结对编程作业(201521123062)
  4. python自制免费代理IP服务
  5. 【重要通知】定了!全国各地的中小商户扶持政策,都在这了!
  6. 微博爬虫及简单数据分析
  7. 多波次导弹发射中的规划问题(二)
  8. Cesium学习教程+笔记(Mars3D) 图层 图层组 矢量数据
  9. win休眠模式+定时休眠
  10. UEFI开发与调试---edk2中的Module