snort会话预处理sessionPacketProcessor派发过程

时间:2022-12-01 16:54:03


一 sessionPacketProcessor原型及功能

1.函数原型:

static void sessionPacketProcessor(Packet *p, void *context);

sessionPacketProcessor是snort预处理函数,snort所有预处理函数接口是:

typedef void (*PreprocEvalFunc)(Packet *p, void *context);

定义在plugbase.h中。

2.函数功能:

(1)判断传入Packet是否合法,不合法则返回错误;

(2)判断Packet的ssnptr是否为空,如果为空,则从scb缓存查找相关scb;

(3)调用SaveSessionFlowStatisticInfo保存网络连接记录;

(4)初始化snort策略等。

二 sessionPacketProcessor装入

sessionPacketProcessor被initializeSessionPreproc函数加载到snort的预处理链表中:

void initializeSessionPreproc(struct _SnortConfig *sc, char *args)
{
...
AddFuncToPreprocList(sc, sessionPacketProcessorm PP_SESSION_PRIORITY, PP_SESSION, PROTO_BIT_ALL);
}

snort预处理链表是包含在SnortPolicy结构体内:

typedef struct _SnortPolicy
{
...
PreprocEvalFuncNode *preproc_eval_funcs; // 预处理链表
}SnortPolicy;

SnortPolicy是定义在snort.h,PreprocEvalFuncNode是预处理链表结点,定义在plugbase.h:

typedef struct _PreprocEvalFuncNode
{
void *context;
uint16_t priority;
...
}PreprocEvalFuncNode;

三 加入预处理链表AddFuncToPreprocList

AddFuncToPreprocList定义在plugbase.c,其功能是将预处理函数加入到snort预处理链表中:

PreprocEvalFuncNode *AddFuncToPreprocList(SnortConfig *sc, ...)
{
...
p = sc->targeted_policies[policy_id]; // 找到snort策略
node = (PreprocEvalFuncNode *)SnortAlloc(sizeof(PreprocEvalFuncNode));
// 如下代码是将node插入到p->preproc_eval_funcs
// 如果参数preproc_id已存在于链表中 则删除node 出错处理 即preproc_id是预处理器唯一id 链表里所有预处理器都是不同的
// 参数priority表示预处理器的优先级,priority值越小,优先级越高,将优先级高的预处理器插入靠近链表头的位置
// 即在预处理器链表中,各结点按优先级次序排序,优先级越高,越靠近链表头
...
}

四 预处理函数派发DispatchPreprocessors

DispatchPreprocessors定义在detect.c,其功能是遍历snort预处理链表,依次调用所有预处理函数

static void DispatchPreprocessors(Packet *p,...)
{
// 对某个Packet包派发所有预处理器
p->cur_pp = policy->preproc_eval_funcs; // 找到链表头
...
ppn->func(p, ppn->context); // 调用预处理函数
...
do {
// 如果不是Ics模式 并且包的payload为0 并且优先级大于0x200 则不做派发 退出循环
// 如果预处理标识开启 则调用预处理函数
} while((p->cur_pp != NULL) && !(p->packet_flags & PKT_PASS_RULE));
}

DispatchPreprocessors由预处理主函数Preprocess调用。