简介
snort中配置文件的处理是一个很重要的部分,因为其不仅是数据的读取过程更是snort初始结构的搭建过程
前面已经对snort解析单个文件做了代码分析.
链接:http://my.oschina.net/u/572632/blog/289256
这里从配置文件读取的总入口开始结合前面的分析做更多的记录,目地是整理出现在snort的整理框架图。以2.9.6.0 Ver 为例
代码分析
/****************************************************************************
* Function: ParseSnortConf()
*
* Read the rules file a line at a time and send each rule to the rule parser
* This is the first pass of the configuration file. It parses everything
* except the rules.
*
* Arguments: None
*
* Returns:
* SnortConfig *
* An initialized and configured snort configuration struct.
* This struct should be passed on the second pass of the
* configuration file to parse the rules.
*
***************************************************************************/
typedef struct _SnortConfig
{
RunMode run_mode;
int run_mode_flags;
int run_flags;
int output_flags;
int logging_flags;
int log_tcpdump;
int no_log;
int no_alert;
int dirty_pig;
//used for processing command line arguments, checksum configuration
//in conf files is maintained at policy level
int checksum_flags; /* -k */
int checksum_flags_modified;
int checksum_drop_flags;
int checksum_drop_flags_modified;
uint32_t event_log_id; /* -G */
int pkt_snaplen;
uint64_t pkt_cnt; /* -n */
#ifdef REG_TEST
uint64_t pkt_skip;
#endif
char *dynamic_rules_path; /* --dump-dynamic-rules */
/* --dynamic-engine-lib
* --dynamic-engine-lib-dir
* --dynamic-detection-lib
* --dynamic-detection-lib-dir
* --dynamic-preprocessor-lib
* --dynamic-preprocessor-lib-dir
*
* See below for struct type
*/
DynamicLibInfo *dyn_engines;
DynamicLibInfo *dyn_rules;
DynamicLibInfo *dyn_preprocs;
#ifdef SIDE_CHANNEL
DynamicLibInfo *dyn_side_channels;
#endif
char pid_path[STD_BUF]; /* --pid-path or config pidpath */
#ifdef EXIT_CHECK
uint64_t exit_check; /* --exit-check */
#endif
/* -h and -B */
sfip_t homenet;
sfip_t obfuscation_net;
uint32_t ipv6_frag_timeout;
uint32_t ipv6_max_frag_sessions;
uint16_t flowbit_size;
char pid_filename[STD_BUF]; /* used with pid_path */
char pidfile_suffix[MAX_PIDFILE_SUFFIX + 1]; /* -R */
char *log_dir; /* -l or config log_dir */
char *orig_log_dir; /* set in case of chroot */
char *interface; /* -i or config interface */
char *bpf_file; /* -F or config bpf_file */
char *pcap_log_file; /* -L */
char *chroot_dir; /* -t or config chroot */
char *alert_file;
char *perf_file; /* -Z */
char *bpf_filter; /* last command line arguments */
char* daq_type; /* --daq or config daq */
char* daq_mode; /* --daq-mode or config daq_mode */
void* daq_vars; /* --daq-var or config daq_var */
void* daq_dirs; /* --daq-dir or config daq_dir */
char* event_trace_file;
uint16_t event_trace_max;
int thiszone;
uint8_t ignore_ports[UINT16_MAX]; /* config ignore_ports */
long int tagged_packet_limit; /* config tagged_packet_limit */
long int pcre_match_limit; /* config pcre_match_limit */
long int pcre_match_limit_recursion; /* config pcre_match_limit_recursion */
int *pcre_ovector;
int pcre_ovector_size;
#ifdef PERF_PROFILING
ProfileConfig profile_rules; /* config profile_rules */
ProfileConfig profile_preprocs; /* config profile_preprocs */
#endif
int user_id;
int group_id;
mode_t file_mask;
#ifdef MPLS
uint8_t mpls_payload_type; /* --mpls_payload_type */
long int mpls_stack_depth; /* --max_mpls_labelchain_len */
#endif
int default_rule_state; /* config default_rule_state */
char* react_page; /* config react */
#ifdef ACTIVE_RESPONSE
uint8_t respond_attempts; /* config respond */
char* respond_device;
uint8_t *eth_dst; /* config destination MAC address */
#endif
#ifdef TARGET_BASED
uint32_t max_attribute_hosts; /* config max_attribute_hosts */
uint32_t max_attribute_services_per_host; /* config max_attribute_services_per_host */
uint32_t max_metadata_services; /* config max_metadata_services */
#endif
OutputConfig *output_configs;
OutputConfig *rule_type_output_configs;
SFGHASH *config_table; /* table of config keywords and arguments */
int asn1_mem;
int active_dynamic_nodes;
RuleState *rule_state_list;
ClassType *classifications;
ReferenceSystemNode *references;
SFGHASH *so_rule_otn_map;
SFGHASH *otn_map;
FastPatternConfig *fast_pattern_config;
EventQueueConfig *event_queue_config;
PreprocPostConfigFuncNode *preproc_post_config_funcs;
PreprocCheckConfigFuncNode *preproc_config_check_funcs;
/* XXX XXX policy specific? */
ThresholdConfig *threshold_config;
RateFilterConfig *rate_filter_config;
DetectionFilterConfig *detection_filter_config;
SF_EVENTQ *event_queue[NUM_EVENT_QUEUES];
SF_LIST **ip_proto_only_lists;
uint8_t ip_proto_array[NUM_IP_PROTOS];
int num_rule_types;
RuleListNode *rule_lists;
int evalOrder[RULE_TYPE__MAX + 1];
ListHead Alert; /* Alert Block Header */
ListHead Log; /* Log Block Header */
ListHead Pass; /* Pass Block Header */
ListHead Activation; /* Activation Block Header */
ListHead Dynamic; /* Dynamic Block Header */
ListHead Drop;
ListHead SDrop;
ListHead Reject;
PostConfigFuncNode *plugin_post_config_funcs;
OTNX_MATCH_DATA *omd;
/* Pattern matcher queue statistics */
unsigned int max_inq;
uint64_t tot_inq_flush;
uint64_t tot_inq_inserts;
uint64_t tot_inq_uinserts;
/* master port list table */
rule_port_tables_t *port_tables;
#ifdef PPM_MGR
ppm_cfg_t ppm_cfg;
#endif
/* The port-rule-maps map the src-dst ports to rules for
* udp and tcp, for Ip we map the dst port as the protocol,
* and for Icmp we map the dst port to the Icmp type. This
* allows us to use the decode packet information to in O(1)
* select a group of rules to apply to the packet. These
* rules may have uricontent, content, or they may be no content
* rules, or any combination. We process the uricontent 1st,
* then the content, and then the no content rules for udp/tcp
* and icmp, than we process the ip rules. */
PORT_RULE_MAP *prmIpRTNX;
PORT_RULE_MAP *prmTcpRTNX;
PORT_RULE_MAP *prmUdpRTNX;
PORT_RULE_MAP *prmIcmpRTNX;
#ifdef TARGET_BASED
srmm_table_t *srmmTable; /* srvc rule map master table */
srmm_table_t *spgmmTable; /* srvc port_group map master table */
sopg_table_t *sopgTable; /* service-oridnal to port_group table */
#endif
SFXHASH *detection_option_hash_table;
SFXHASH *detection_option_tree_hash_table;
tSfPolicyConfig *policy_config;
SnortPolicy **targeted_policies;
unsigned int num_policies_allocated;
char *base_version;
uint8_t enable_teredo; /* config enable_deep_teredo_inspection */
uint8_t enable_gtp; /* config enable_gtp */
char *gtp_ports;
uint8_t enable_esp;
uint8_t vlan_agnostic; /* config vlan_agnostic */
uint8_t addressspace_agnostic; /* config addressspace_agnostic */
uint8_t log_ipv6_extra; /* config log_ipv6_extra_data */
uint8_t tunnel_mask;
uint32_t so_rule_memcap;
uint32_t paf_max; /* config paf_max */
char *cs_dir;
bool ha_peer;
char *ha_out;
char *ha_in;
char *output_dir;
void *file_config;
int disable_all_policies;
uint32_t reenabled_preprocessor_bits; /* flags for preprocessors to check, if all policies are disabled */
#ifdef SIDE_CHANNEL
SideChannelConfig side_channel_config;
#endif
#ifdef SNORT_RELOAD
int reloadPolicyFlag;
PreprocessorSwapData *preprocSwapData;
void *streamReloadConfig;
#endif
tSfPolicyId parserPolicyId;
/* Used when a user defines a new rule type (ruletype keyword)
* It points to the new rule type's ListHead and is used for accessing the
* rule type's AlertList and LogList.
* The output plugins used for the rule type need to be attached to the new
* rule type's list head's AlertList or LogList. It's set before calling
* the output plugin's initialization routine, because in that routine,
* AddFuncToOutputList is called (plugbase.c) and there, the output function
* is attached to the new rule type's appropriate list.
* NOTE: This variable MUST NOT be used during runtime */
ListHead *head_tmp;
} SnortConfig;
typedef struct _VarNode
{
char *name;
char *value;
char *line;
struct _VarNode *next;
} VarNode;
/** 这是snort配置文件读取的总入口 */
SnortConfig * ParseSnortConf(void)
{
SnortConfig *sc = SnortConfNew(); /** 创建snortConfig结构*/
VarNode *tmp = cmd_line_var_list; /** 全局结构*/
tSfPolicyId policy_id; /** 无符号整形作为ID 值*/
file_line = 0; /** 记录当前的行数*/
/** 记录当前解析的文件*/
file_name = snort_conf_file ? snort_conf_file : NULL_CONF;
InitParser();
/**
* 初始化部分全局数据其中最重要的是初始化了rulemap
*
* typedef struct {
* unsigned gid;
* unsigned sid;
* }rule_number_t;
*
* typedef struct {
* int max_rules;
* int num_rules;
* rule_number_t * map;
* }rule_index_map_t;
*
* 1. rule_index_map_t 是管理规则id的,
* 2 每个规则映射一个rule_number_t对象 保存gid和 sid
* 3. 所有rule_number_t 以数组的形式放在rule_index_map_t 中
* 4. 空间时与预分配的大小为 #define MAX_RULE_COUNT (65535 * 2)
*
*
**/
/* Setup the default rule action anchor points
* Need to do this now in case we get a user defined rule type */
/**
* 1.这部分逻辑比较简单但却很重要,主要是搭建规则管理框架的
* 2.规则信息的管理采用的是三成链表
* 3.这里是第一层
* 4具体见后面该部分的代码片段注释
**/
CreateDefaultRules(sc);
/**
* 初始化端口规则表,属于数据管理的辅助结构,不是重点
*
*/
sc->port_tables = PortTablesNew();
/**
* 用于匹配查找的结构初始化
*/
mpseInitSummary();
/**
* 为rule和 option管理初始化了两个hash表
* 使用得是sfghash
* 需要说明的是snort中有多个hash结构,而sfghash是带内存管理功能的
*
*
**/
OtnInit(sc);
/** config table 也使用sfghash*/
/* Used to store "config" configurations */
sc->config_table = sfghash_new(20, 0, 0, free);
if (sc->config_table == NULL)
{
ParseError("%s(%d) No memory to create config table.\n",
__FILE__, __LINE__);
}
sc->fast_pattern_config = FastPatternConfigNew(); /** 建立快速匹配配置结构,保存基础配置信息*/
sc->event_queue_config = EventQueueConfigNew(); /** 建立事务队列的配置结构*/
sc->threshold_config = ThresholdConfigNew(); /** 建立阀值数据的配置结构*/
sc->rate_filter_config = RateFilter_ConfigNew(); /** 建立频率过滤配置结构*/
sc->detection_filter_config = DetectionFilterConfigNew(); /** 建立探测配置结构*/
/**协议数组,其中每个单元的索引为协议号,其中存放了一个链表头*/
sc->ip_proto_only_lists = (SF_LIST **)SnortAlloc(NUM_IP_PROTOS * sizeof(SF_LIST *));
/* We're not going to parse rules on the first pass */
parse_rules = 0;
/** 初始化策略管理结构*/
sc->policy_config = sfPolicyInit();
if (sc->policy_config == NULL)
{
ParseError("No memory to create policy configuration.\n");
}
/* Add the default policy */
/**这里获得策略ID的方式是使用文件名获得的*/
policy_id = sfPolicyAdd(sc->policy_config, file_name);
/**赋值,策略默认ID是第一个读取到的文件的ID*/
sfSetDefaultPolicy(sc->policy_config, policy_id);
/**targeted_policies 是一个空指针数组这里是确保其长度大于default policy id*/
sfDynArrayCheckBounds((void **)&sc->targeted_policies, policy_id, &sc->num_policies_allocated);
/**分配一个snort policy 放入 targeted_policies数组中 policy id 的位置*/
sc->targeted_policies[policy_id] = SnortPolicyNew();
/**初始化snort policy中的部分辅助结构*/
InitVarTables(sc->targeted_policies[policy_id]);
/**根据snort运行模式设置标志,是嗅探模式还是在线模式?*/
InitPolicyMode(sc->targeted_policies[policy_id]);
/**
* 下面是将正在使用的策略id放入指向的parsePolicyId中
* if (sc)
* sc->parserPolicyId = id;
* else
* snort_conf->parserPolicyId = id;
* }
*/
setParserPolicy(sc, policy_id);
#ifndef SOURCEFIRE
/* If snort is not run with root privileges, no interfaces will be defined,
* so user beware if an iface_ADDRESS variable is used in snort.conf and
* snort is not run as root (even if just in read mode) */
DefineAllIfaceVars(sc);
#endif
/* Add command line defined variables - duplicates will already
* have been resolved */
/**
* 提取获得的追加变量
*/
while (tmp != NULL)
{
AddVarToTable(sc, tmp->name, tmp->value);
tmp = tmp->next;
}
/* Initialize storage space for preprocessor defined rule options */
/** 也是使用sfghash*/
sc->targeted_policies[policy_id]->preproc_rule_options = PreprocessorRuleOptionsNew();
if (sc->targeted_policies[policy_id]->preproc_rule_options == NULL)
{
ParseError("Could not allocate storage for preprocessor rule "
"options.\n");
}
/**解析该文件*/
if ( strcmp(file_name, NULL_CONF) )
ParseConfigFile(sc, sc->targeted_policies[policy_id], file_name);
/* We've picked up any targeted policy configs at this point so
* it's probably okay to parse them here */
/**遍历所有snort policy 每一个ID标识一个文件**/
for (policy_id = 0;
policy_id < sfPolicyNumAllocated(sc->policy_config);
policy_id++)
{
char *fname = sfPolicyGet(sc->policy_config, policy_id);
/**如果该id对应首个被解析的文件则忽略*/
/* Already configured default policy */
if (policy_id == sfGetDefaultPolicy(sc->policy_config))
continue;
if (fname != NULL)
{
/**再次确保targed_policies的大小足够*/
sfDynArrayCheckBounds(\
(void **)&sc->targeted_policies, policy_id, &sc->num_policies_allocated);
/**为该文件的解析申请一个snort policy 结构并完成初始化工作*/
sc->targeted_policies[policy_id] = SnortPolicyNew();
InitVarTables(sc->targeted_policies[policy_id]);
InitPolicyMode(sc->targeted_policies[policy_id]);
setParserPolicy(sc, policy_id);
/* Need to reset this for each targeted policy */
memset(config_opt_configured, 0, sizeof(config_opt_configured));
/* Add command line defined variables - duplicates will already
* have been resolved */
tmp = cmd_line_var_list;
while (tmp != NULL)
{
AddVarToTable(sc, tmp->name, tmp->value);
tmp = tmp->next;
}
/* Initialize storage space for preprocessor defined rule options */
sc->targeted_policies[policy_id]->preproc_rule_options = PreprocessorRuleOptionsNew();
if (sc->targeted_policies[policy_id]->preproc_rule_options == NULL)
{
ParseError("Could not allocate storage for preprocessor rule "
"options.\n");
}
/* Parse as include file so if the file is specified relative to
* the snort conf directory we'll pick it up */
ParseInclude(sc, sc->targeted_policies[policy_id], fname);
}
}
/* This can be initialized now since we've picked up any user
* defined rules */
sc->omd = OtnXMatchDataNew(sc->num_rule_types);
/* Reset these. The only issue in not reseting would be if we were
* parsing a command line again, but do it anyway */
file_name = NULL;
file_line = 0;
return sc;
}
/***************************************************************************************/
/** 规则链第一层*/
typedef struct _RuleListNode
{
ListHead *RuleList; /* The rule list associated with this node */
RuleType mode; /* the rule mode */
int rval; /* 0 == no detection, 1 == detection event */
int evalIndex; /* 其实是记录该条目是第几个插入底层链表 */
char *name; /* name of this rule list (for debugging) */
struct _RuleListNode *next; /* the next RuleListNode */
} RuleListNode;
/** 规则链第二层*/
typedef struct _ListHead
{
struct _OutputFuncNode *LogList;
struct _OutputFuncNode *AlertList;
struct _RuleListNode *ruleListNode;
} ListHead;
/* function pointer list for rule head nodes */
typedef struct _RuleFpList
{
/* context data for this test */
void *context;
/* rule check function pointer */
int (*RuleHeadFunc)(Packet *, struct _RuleTreeNode *, struct _RuleFpList *, int);
/* pointer to the next rule function node */
struct _RuleFpList *next;
} RuleFpList;
/**规则链第三层*/
typedef struct _RuleTreeNode
{
RuleFpList *rule_func; /* match functions.. (Bidirectional etc.. ) */
int head_node_number;
RuleType type;
IpAddrSet *sip;
IpAddrSet *dip;
int proto;
PortObject * src_portobject;
PortObject * dst_portobject;
uint32_t flags; /* control flags */
/* stuff for dynamic rules activation/deactivation */
int active_flag;
int activation_counter;
int countdown;
ActivateListNode *activate_list;
/**points to global parent RTN list (Drop/Alert) which contains this
* RTN.
*/
struct _ListHead *listhead;
/**reference count from otn. Multiple OTNs can reference this RTN with the same
* policy.
*/
unsigned int otnRefCount;
} RuleTreeNode;
static void CreateDefaultRules(SnortConfig *sc)
{
if (sc == NULL)
return;
/**构建顶层规则链表
* 1. 每个单元代表一个动作
* 2.所有单元以链式存放,且动作的默认优先级在链中的位置决定
* 3.因为是链式存放,因而能靠改变顶层链中的单元顺序来改变顶层规则的优先级
*/
CreateRuleType(sc, RULE_LIST_TYPE__ACTIVATION, RULE_TYPE__ACTIVATE, 1, &sc->Activation);
CreateRuleType(sc, RULE_LIST_TYPE__DYNAMIC, RULE_TYPE__DYNAMIC, 1, &sc->Dynamic);
CreateRuleType(sc, RULE_LIST_TYPE__PASS, RULE_TYPE__PASS, 0, &sc->Pass); /* changed on Jan 06 */
CreateRuleType(sc, RULE_LIST_TYPE__DROP, RULE_TYPE__DROP, 1, &sc->Drop);
CreateRuleType(sc, RULE_LIST_TYPE__SDROP, RULE_TYPE__SDROP, 0, &sc->SDrop);
CreateRuleType(sc, RULE_LIST_TYPE__REJECT, RULE_TYPE__REJECT, 1, &sc->Reject);
CreateRuleType(sc, RULE_LIST_TYPE__ALERT, RULE_TYPE__ALERT, 1, &sc->Alert);
CreateRuleType(sc, RULE_LIST_TYPE__LOG, RULE_TYPE__LOG, 1, &sc->Log);
}
/****************************************************************************
*
* Function: CreateRuleType
*
* Purpose: Creates a new type of rule and adds it to the end of the rule list
*
* Arguments: name = name of this rule type
* mode = the mode for this rule type
* rval = return value for this rule type (for detect events)
* head = list head to use (or NULL to create a new one)
*
* Returns: the ListHead for the rule type
*
***************************************************************************/
static ListHead * CreateRuleType(SnortConfig *sc, char *name,
RuleType mode, int rval, ListHead *head)
{
RuleListNode *node;
int evalIndex = 0;
if (sc == NULL)
return NULL;
node = (RuleListNode *)SnortAlloc(sizeof(RuleListNode));
/* If this is the first rule list node, then we need to
* create a new list. */
if (sc->rule_lists == NULL)
{
sc->rule_lists = node;
}
else
{
RuleListNode *tmp = sc->rule_lists;
RuleListNode *last;
do
{
/**从这里可以看出snortconfig 中的ruleList 是一个单链表,尾部插入的管理方式*/
/* We do not allow multiple rules types with the same name. */
if (strcasecmp(tmp->name, name) == 0)
{
free(node);
return NULL;
}
/**这里可以看出RuleListNode单元中 evalIndex数值的来源,即按照插入顺序,递增获取*/
evalIndex++;
last = tmp;
tmp = tmp->next;
} while (tmp != NULL);
last->next = node;
}
/* User defined rule type so we need to create a list head for it */
/** 将顶层链表的RuleList指针指向二层链表, 此时二层链表只有一个单元*/
if (head == NULL)
{
node->RuleList = (ListHead *)SnortAlloc(sizeof(ListHead));
}
else
{
/* Our default rules already have list heads */
node->RuleList = head;
}
/** 二层链表头部的ruleListNode指针指向其所属的node*/
node->RuleList->ruleListNode = node;
node->mode = mode;
node->rval = rval;
node->name = SnortStrdup(name);
node->evalIndex = evalIndex;
/**这里是建立type与ruleListnode在第一层规则链表中的位置序号,方便查找*/
sc->evalOrder[node->mode] = evalIndex;
sc->num_rule_types++;
return node->RuleList;
}
static void OtnInit(SnortConfig *sc)
{
if (sc == NULL)
return;
/* Don't initialize this more than once */
if ((sc->so_rule_otn_map != NULL) || (sc->otn_map != NULL))
return;
/* Init sid-gid -> otn map */
sc->so_rule_otn_map = SoRuleOtnLookupNew(); /**分配初始化sfghash*/
if (sc->so_rule_otn_map == NULL)
ParseError("ParseRulesFile so_otn_map sfghash_new failed.\n");
/* Init sid-gid -> otn map */
sc->otn_map = OtnLookupNew(); /**分配初始化sfghash*/
if (sc->otn_map == NULL)
ParseError("ParseRulesFile otn_map sfghash_new failed.\n");
}
/***********************************************************************************/
typedef struct
{
/** 这句是重点*/
/**group id assigned to each file name. The groupId is an abstract concept
* to tie multiple vlans into one group. */
tSfPolicy **ppPolicies;
tSfPolicyId defaultPolicyId;
/**policy id of configuration file or packet being processed. */
tSfPolicyId numAllocatedPolicies;
unsigned int numActivePolicies;
/**vlan to policyId bindings. */
tSfPolicyId vlanBindings[SF_VLAN_BINDING_MAX];
/**policyId to policyId bindings. */
tSfPolicyId policyIdBindings[SF_POLICY_ID_BINDING_MAX];
/**Network to policyId bindings. */
table_t *netBindTable;
} tSfPolicyConfig;
tSfPolicyConfig * sfPolicyInit(void)
{
int i;
tSfPolicyConfig *new = (tSfPolicyConfig *)calloc(1, sizeof(tSfPolicyConfig));
if (new == NULL)
return NULL;
//initialize vlan bindings
for (i = 0; i < SF_VLAN_BINDING_MAX; i++)
{
new->vlanBindings[i] = SF_POLICY_UNBOUND;
}
for (i = 0; i < SF_POLICY_ID_BINDING_MAX; i++)
{
new->policyIdBindings[i] = SF_POLICY_UNBOUND;
}
//initialize net bindings
/** 初始化查找结构*/
new->netBindTable = sfrt_new(DIR_16x7_4x4, IPv6, SF_NETWORK_BINDING_MAX, 20);
return new;
}
/**********************************************************************************/
SnortPolicy * SnortPolicyNew(void)
{
SnortPolicy *pPolicy = (SnortPolicy *)SnortAlloc(sizeof(SnortPolicy));
if (pPolicy)
{
// minimum possible (allows all but errors to pass by default)
pPolicy->min_ttl = 1;
#ifdef NORMALIZER
pPolicy->new_ttl = 5;
#endif
/* Turn on all decoder alerts by default except for oversized alert.
* Useful for bug reports ... */
pPolicy->decoder_alert_flags |= DECODE_EVENT_FLAG__DEFAULT;
pPolicy->decoder_alert_flags |= DECODE_EVENT_FLAG__TCP_EXP_OPT;
pPolicy->decoder_alert_flags |= DECODE_EVENT_FLAG__TCP_OBS_OPT;
pPolicy->decoder_alert_flags |= DECODE_EVENT_FLAG__TCP_TTCP_OPT;
pPolicy->decoder_alert_flags |= DECODE_EVENT_FLAG__TCP_OPT_ANOMALY;
pPolicy->decoder_alert_flags |= DECODE_EVENT_FLAG__IP_OPT_ANOMALY;
pPolicy->decoder_alert_flags |= DECODE_EVENT_FLAG__IPV6_BAD_FRAG;
pPolicy->decoder_alert_flags |= DECODE_EVENT_FLAG__IPV6_BSD_ICMP_FRAG;
pPolicy->decoder_drop_flags |= DECODE_EVENT_FLAG__IPV6_BAD_FRAG;
pPolicy->checksum_flags = CHECKSUM_FLAG__ALL;
}
return pPolicy;
}
#########################################################################################
/**当 ParseConfigFile在配置文件中发现include 规则时会调用下面的回调函数*/
static void ParseInclude(SnortConfig *sc, SnortPolicy *p, char *arg)
{
struct stat file_stat; /* for include path testing */
/* Save place in previous file */
char *stored_file_name = file_name;
int stored_file_line = file_line;
/**任何配置文件不能包含顶层文件,避免出现include回路*/
/* Including top level snort conf file */
if (strcmp(arg, snort_conf_file) == 0)
{
ParseError("Cannot include \"%s\" in an include directive.",
snort_conf_file);
}
/* XXX Maybe not allow an include in an included file to avoid
* potential recursion issues */
file_line = 0;
file_name = SnortStrdup(arg);
/* Stat the file. If that fails, stat it relative to the directory
* that the top level snort configuration file was in */
if (stat(file_name, &file_stat) == -1)
{
int path_len = strlen(snort_conf_dir) + strlen(arg) + 1;
DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"ParseConfigFile: stat "
"on %s failed - going to config_dir\n", file_name););
free(file_name);
file_name = (char *)SnortAlloc(path_len);
snprintf(file_name, path_len, "%s%s", snort_conf_dir, arg);
DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"ParseConfigFile: Opening "
"and parsing %s\n", file_name););
}
/**调用parseConfigFile*/
ParseConfigFile(sc, p, file_name);
free(file_name);
file_name = stored_file_name;
file_line = stored_file_line;
}
总结
作为配置文件读取的顶层接口,实际主要是在解析文件前对必要数据做了初始化工作
include的回调操作是在解析到include命令时作为插件触发的
来源:oschina
链接:https://my.oschina.net/u/572632/blog/289421