原文链接:http://www.9mblog.com/96.html
RunModeDispatch(suri.run_mode, suri.runmode_custom_mode)
初始化运行模式。首先,根据配置文件和程序中的默认值来配置运行模式(single、auto这些),而运行模式类 型(PCAP_DEV、PCAPFILE这些)也在之前已经确定了,因此运行模式已经固定下来,可以从runmodes表中获取到特定的RunMode 了,接着就调用RunMode中的RunModeFunc,进入当前运行模式的初始化函数。以PCAP_DEV类型下的autofp模式为例,该模式的初 始化函数为:RunModeIdsPcapAutoFp。
void RunModeDispatch(int runmode, const char *custom_mode)
{
char *local_custom_mode = NULL;
if (custom_mode == NULL) {
char *val = NULL;
if (ConfGet("runmode", &val) != 1) {
custom_mode = NULL;
} else {
custom_mode = val;
}
}
获取运行模式类型(auto, autofp, worke)
if (custom_mode == NULL || strcmp(custom_mode, "auto") == 0) {
switch (runmode) {
case RUNMODE_PCAP_DEV:
custom_mode = RunModeIdsGetDefaultMode();
break;
case RUNMODE_PCAP_FILE:
custom_mode = RunModeFilePcapGetDefaultMode();
break;
#ifdef HAVE_PFRING
case RUNMODE_PFRING:
custom_mode = RunModeIdsPfringGetDefaultMode();
break;
#endif
case RUNMODE_NFQ:
custom_mode = RunModeIpsNFQGetDefaultMode();
break;
case RUNMODE_IPFW:
custom_mode = RunModeIpsIPFWGetDefaultMode();
break;
case RUNMODE_ERF_FILE:
custom_mode = RunModeErfFileGetDefaultMode();
break;
case RUNMODE_DAG:
custom_mode = RunModeErfDagGetDefaultMode();
break;
case RUNMODE_TILERA_MPIPE:
custom_mode = RunModeTileMpipeGetDefaultMode();
break;
case RUNMODE_NAPATECH:
custom_mode = RunModeNapatechGetDefaultMode();
break;
case RUNMODE_AFP_DEV:
custom_mode = RunModeAFPGetDefaultMode();
break;
case RUNMODE_NETMAP:
custom_mode = RunModeNetmapGetDefaultMode();
break;
case RUNMODE_UNIX_SOCKET:
custom_mode = RunModeUnixSocketGetDefaultMode();
break;
case RUNMODE_NFLOG:
custom_mode = RunModeIdsNflogGetDefaultMode();
break;
default:
SCLogError(SC_ERR_UNKNOWN_RUN_MODE, "Unknown runtime mode. Aborting");
exit(EXIT_FAILURE);
}
获取各个模式中预定义的运行模式类型(auto, autofp, worke),大部分都是auto和autofp,只有netmap是worker。原因是3.0.1的版本sutofp存在内存泄漏。
} else { /* if (custom_mode == NULL) */
/* Add compability with old 'worker' name */
if (!strcmp("worker", custom_mode)) {
SCLogWarning(SC_ERR_RUNMODE, "'worker' mode have been renamed "
"to 'workers', please modify your setup.");
local_custom_mode = SCStrdup("workers");
if (unlikely(local_custom_mode == NULL)) {
SCLogError(SC_ERR_MEM_ALLOC, "Unable to dup custom mode");
exit(EXIT_FAILURE);
}
custom_mode = local_custom_mode;
}
如果指定或配置中是worker则使用worker
}
RunMode *mode = RunModeGetCustomMode(runmode, custom_mode);
找runmode(pcap, pcapfile, pfring, netmap等)下对应custom_mode(auto, autofp, worker)对应的mode
if (mode == NULL) {
SCLogError(SC_ERR_RUNMODE, "The custom type \"%s\" doesn't exist "
"for this runmode type \"%s\". Please use --list-runmodes to "
"see available custom types for this runmode",
custom_mode, RunModeTranslateModeToName(runmode));
exit(EXIT_FAILURE);
}
/* Export the custom mode */
if (active_runmode) {
SCFree(active_runmode);
}
active_runmode = SCStrdup(custom_mode);
if (unlikely(active_runmode == NULL)) {
SCLogError(SC_ERR_MEM_ALLOC, "Unable to dup active mode");
exit(EXIT_FAILURE);
}
if (strcasecmp(active_runmode, "autofp") == 0) {
TmqhFlowPrintAutofpHandler();
}
mode->RunModeFunc();
运行指向的模块初始化函数,该函数在各个模式的runmode*.c中通过RunModeRegisterNewRunMode注册。以pcapfile为例,此处为RunModeFilePcapAutoFp函数,在runmode-pcap-file.c中注册。
if (local_custom_mode != NULL)
SCFree(local_custom_mode);
/* Check if the alloted queues have at least 1 reader and writer */
TmValidateQueueState();
检查queue的状态,我在这里遇到过大问题,增加了接收和处理线程,但没有增加相应的queue的数量,导致此处报错。
return;
}