一 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调用。