赞
踩
从上一篇 “浅谈 Suricata”我们可以了解 Suricata 的安装部署大致框架、以及从配置方面谈及的性能优化。这篇文章则从代码角度带您剖析 Suricata。
通过本篇文章,您将了解以下知识点:
提到Suricata源码分析,我们首先需要了解suricata整体框架设计,只有你了解了整体框架,他才能对阅读源码有更好的促进作用。而提到框架则需要了解它的运行模式,在上一篇文章中说,suricata相对于传统snort引擎,它是由很多单独的线程模块所组成,使用者可以自行配置组合所需要的线程模块既可进行优化、自定义需求。默认的运行模式主要分为workers模式、autofp模式以及单线程模式single。workers模式主要是采用串行流水线的模式,针对单独数据流采取唯一线程 从头至尾处理,而autofp则是将收包和解包放在一个单独线程,而剩下的工作线程则通过队列传递数据包进行处理。 显然workers模式更适用于高效率处理数据包。
其次suricata支持多种抓包引擎,如:pcap、netmap、pfring、socket等。本文就pfring抓包引擎来谈一下数据包的流转以及部分解析引擎。 ##运行模式 涉及文件:runmodes.c 、util-runmodes.c、tm-thread.c、tm-queue ...... ###1. 注册运行模式
- void RunModeIdsPfringRegister(void)
- {
- default_mode_autofp = "autofp";
- RunModeRegisterNewRunMode(RUNMODE_PFRING, "autofp",
- "Multi threaded pfring mode. Packets from "
- "each flow are assigned to a single detect "
- "thread, unlike \\"pfring_auto\\" where packets "
- "from the same flow can be processed by any "
- "detect thread",
- RunModeIdsPfringAutoFp);
- RunModeRegisterNewRunMode(RUNMODE_PFRING, "single",
- "Single threaded pfring mode",
- RunModeIdsPfringSingle);
- RunModeRegisterNewRunMode(RUNMODE_PFRING, "workers",
- "Workers pfring mode, each thread does all"
- " tasks from acquisition to logging",
- RunModeIdsPfringWorkers);
- return;
- }
模块结构
- typedef struct TmModule_ {
- const char *name;
- TmEcode (*ThreadInit)(ThreadVars *, const void *, void **);
- ......
- } TmModule;
- TmModule tmm_modules[TMM_SIZE];
模块注册结构体,主要用于注册各个线程模块,提供全局变量tmm_modules, 便于组装回调。 如pfring模块注册:
- void TmModuleReceivePfringRegister (void)
- {
- tmm_modules[TMM_RECEIVEPFRING].name = "ReceivePfring";
- tmm_modules[TMM_RECEIVEPFRING].ThreadInit = ReceivePfringThreadInit;
- tmm_modules[TMM_RECEIVEPFRING].Func = NULL;
- tmm_modules[TMM_RECEIVEPFRING].PktAcqLoop = ReceivePfringLoop;
- tmm_modules[TMM_RECEIVEPFRING].PktAcqBreakLoop = PfringBreakLoop;
- tmm_modules[TMM_RECEIVEPFRING].RegisterTests = NULL;
- tmm_modules[TMM_RECEIVEPFRING].flags = TM_FLAG_RECEIVE_TM;
- }
线程结构
- typedef struct ThreadVars_ {
- pthread_t t;
- char name[16];
- char *printable_name;
- char *thread_group_name;
- SC_ATOMIC_DECLARE(unsigned int, flags);
- uint8_t tmm_flags;
- Tmq *inq;
- Tmq *outq;
- void *outctx;
- const char *outqh_name;
- struct Packet_ * (*tmqh_in)(struct ThreadVars_ *);
- void (*InShutdownHandler)(struct ThreadVars_ *);
- void (*tmqh_out)(struct ThreadVars_ *, struct Packet_ *);
- void *(*tm_func)(void *);
- struct TmSlot_ *tm_slots;
- ......
- struct ThreadVars_ *next;
- struct ThreadVars_ *prev;
- } ThreadVars;
线程结构,主要用于自由组装模块之后,提供线程队列绑定、线程句柄等。
队列结构
- typedef struct Tmqh_ {
- const char *name;
- Packet *(*InHandler)(ThreadVars *);
- void (*InShutdownHandler)(ThreadVars *);
- void (*OutHandler)(ThreadVars *, Packet *);
- void *(*OutHandlerCtxSetup)(const char *);
- void (*OutHandlerCtxFree)(void *);
- void (*RegisterTests)(void);
- } Tmqh;
- Tmqh tmqh_table[TMQH_SIZE];
队列数据结构,提供队列的注册回调、并提供全局句柄tmqh_table供线程绑定队列用。而队列主要包含 这几种: TMQH_SIMPLE, TMQH_NFQ, TMQH_PACKETPOOL, TMQH_FLOW, 这边我们主要关心TMQH_PACKETPO
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。