suricata的模块和插槽

作者: goto2091

参考资料

suricata官方文档https://suricata.readthedocs.io/en/latest/performance/runmodes.htmldifferent-runmodes suricata的源代码https://blog.csdn.net/shenwansangz/article/details/37900875?utm_medium=distribute.pc_relevant.none-task-blog-utm_term-3\&spm=1001.2101.3001.4242 suricata的总体架构https://www.cnblogs.com/zlslch/p/7382176.html suricata数据结构https://blog.csdn.net/gengzhikui1992/article/details/103031874?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param\&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param

原理

suricata是基于模块(TMmoudle)的,所谓模块是suricata中的数据结构:

typedef struct TmModule_ {
    char *name;          // 模块名称
    TmEcode (*ThreadInit)(ThreadVars *, void *, void **);
    void (*ThreadExitPrintStats)(ThreadVars *, void *);
    TmEcode (*ThreadDeinit)(ThreadVars *, void *);
    TmEcode (*Func)(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *);
    TmEcode (*PktAcqLoop)(ThreadVars *, void *, void *);
    TmEcode (*Init)(void);
    TmEcode (*DeInit)(void);
    void (*RegisterTests)(void);
    uint8_t cap_flags;  
    uint8_t flags;
} TmModule;

每个模块代表一个特定的功能。

例如获取报文、解码报文、检测报文、记录日志这四个模块。

前一个模块的输出是后一个模块的输入,它们各自拥有一个线程。多线程是suricata具有较高性能的保证。
在这里插入图片描述

模块和模块之间的联系通过suricata中的插槽(slot)这一数据结构相连。

typedef struct TmSlot_ {
    ThreadVars *tv;                       // 拥有该slot的线程
    SC_ATOMIC_DECLARE(TmSlotFunc, SlotFunc);// 函数指针
    TmEcode (*PktAcqLoop)(ThreadVars *, void *, void *);      // 模块数据包获取函数
    TmEcode (*SlotThreadInit)(ThreadVars *, void *, void **); // 模块初始化执行函数
    void (*SlotThreadExitPrintStats)(ThreadVars *, void *);   // 模块退出打印函数
    TmEcode (*SlotThreadDeinit)(ThreadVars *, void *);        // 模块清理执行函数
    void *slot_initdata;  // 数据存储
    SC_ATOMIC_DECLARE(void *, slot_data);
    PacketQueue slot_pre_pq;
    PacketQueue slot_post_pq;
    int tm_id;  // tm ID
    int id;     // slot ID
    struct TmSlot_ *slot_next;
} TmSlot;

每个线程运行一个slot对象,slot负责管理其上的模块。包括该模块的初始化,以及对模块数据包的获取和模块的退出和清理。

数据从一个模块到另一个模块是通过slot结构体中的 struct TmSlot_* 指针指向下一个slot,并将数据包输入至下一个slot管理的TmModule上。
在这里插入图片描述

图中有3个插槽,每个插槽各有一个模块,3个插槽各自启动了一个线程。类似生产者和消费者原理,模块i是模块i-1的消费者,模块i-1是模块i的生产者。使用模块-插槽结构的好处是便于添加中间组件对数据包进行处理。同时模块化也便于利用多线程。 suricata的模块需要被注册,注册函数名为 TmModuleXXXRegister(void),模块被注册后便被存入全局数组 TmModule tmm_modules[TMM_SIZE]中。该数组使用了枚举-索引方式。用枚举的方式对数组每个位命名。

typedef enum{
TMM_DECODEDFQ,
TMM_XXXX
};

枚举数正好对应TMM数组的index。 运行模式(run-mode)

在suricata中,线程,模块和队列排列在一起的方式称作运行方式。 suricata如何封包捕获? suricata中的AF_PACKET和PF_RING方法可以捕获数据包。

原文创作:goto2091

原文链接:https://www.cnblogs.com/goto2091/p/13705685.html

更多推荐

更多
  • Pharo敏捷人工智能-第一部分:神经网络
    Apache CN

  • Pharo敏捷人工智能-第二部分:遗传算法
    Apache CN

  • Pharo敏捷人工智能-# 第三部分:神经进化 第三部分:神经进化
    Apache CN

  • Go编程秘籍-三、数据转换与组合 本章将展示一些在数据类型之间转换、使用非常大的数字、使用货币、使用不同类型的编码和解码(包括 Base64 和gob)以及使用闭包创建自定义集合的示例。转换数据类型和接口转换,使用 math 和 math/big ...
  • Go编程秘籍-一、I/O 和文件系统 Go 为基本和复杂 I/O 提供了极好的支持。本章中的方法将探索用于处理 I/O 的常见 Go 接口,并向您展示如何使用它们。Go 标准库经常使用这些接口,本书中的食谱都将使用这些接口。本章将介绍以下配方:使用公共 I/O ...
  • Go编程秘籍-二、命令行工具 命令行应用是处理用户输入和输出的最简单方法之一。本章将重点介绍基于命令行的交互,如命令行参数、配置和环境变量。最后,我们将介绍一个在 Unix 和 Bash for Windows 中为文本输出着色的库。
  • Go编程秘籍-零、前言 要使用本书,您需要以下内容:Unix 编程环境。Go 1.x 系列的最新版本。互联网连接。如各章所述,允许安装其他软件包。各章节的技术要求部分中提到了各配方的先决条件和其他安装要求。
  • Go编程秘籍-十一、分布式系统 本章将探讨管理分布式数据、编排、容器化、度量和监视的方法。这些将成为编写和维护微服务和大型分布式应用工具箱的一部分。在本章中,我们将介绍以下配方:与 concur 一起使用服务发现,利用 Raft 实现基本共识,与 Docker ...
  • Go编程秘籍-十、并行与并发 Go 提供了使并行应用成为可能的原语。Goroutines 允许任何函数变成异步和并发的。通道允许应用设置与 Goroutines 的通信。在本章中,我们将介绍以下配方:使用通道和 select 语句,使用 sync.WaitGroup ...
  • Go编程秘籍-十二、反应式编程和数据流 本章还将探讨与卡夫卡联系的各种方式,并使用它来处理信息。最后,本章将演示如何在 Go 中创建一个基本的graphql服务器。在本章中,我们将介绍以下配方:使用 Goflow 进行数据流编程,与 Kafka 一起使用异步生产者,将卡夫卡连接到...
  • 近期文章

    更多
    文章目录

      推荐作者

      更多