下面分享的是OSSIM关联分析的一部分源代码。
/*
** * 我们想知道该指令是否与根节点指令匹配,这里只检查根节点。这里我们不检查指令的子节点**
*/
gboolean
sim_directive_match_by_event (SimDirective *directive,
SimEvent *event)
{
SimRule *rule;
gboolean match;
g_return_val_if_fail (directive, FALSE);
g_return_val_if_fail (SIM_IS_DIRECTIVE (directive), FALSE);
g_return_val_if_fail (!directive->_priv->matched, FALSE);
g_return_val_if_fail (directive->_priv->rule_root, FALSE);
g_return_val_if_fail (directive->_priv->rule_root->data, FALSE);
g_return_val_if_fail (SIM_IS_RULE (directive->_priv->rule_root->data), FALSE);
g_return_val_if_fail (event, FALSE);
g_return_val_if_fail (SIM_IS_EVENT (event), FALSE);
rule = SIM_RULE (directive->_priv->rule_root->data);
match = sim_rule_match_by_event (rule, event);
return match;
}
/*
** *这将检查事件是否可以与backlog中的某些数据匹配。backlog实际上是一个包含事件数据的指令。每个backlog条目都是一个树,其中包含来自一个指令的所有规则(它相当于是一个指令克隆)。其中每个规则(simrule)还包含与规则匹配的事件的数据。**
*
*/
gboolean
sim_directive_backlog_match_by_event (SimDirective *directive,
SimEvent *event)
{
GNode *node = NULL;
g_return_val_if_fail (directive, FALSE);
g_return_val_if_fail (SIM_IS_DIRECTIVE (directive), FALSE);
g_return_val_if_fail (!directive->_priv->matched, FALSE);
g_return_val_if_fail (directive->_priv->rule_curr, FALSE);
g_return_val_if_fail (directive->_priv->rule_curr->data, FALSE);
g_return_val_if_fail (SIM_IS_RULE (directive->_priv->rule_curr->data), FALSE);
g_return_val_if_fail (event, FALSE);
g_return_val_if_fail (SIM_IS_EVENT (event), FALSE);
node = directive->_priv->rule_curr->children;
while (node) //**我们必须对照backlog中的所有规则节点检查事件,除了根节点,因为它签入了sim_directive_match_by_event是从sim_organizer_correlation调用的.**
{
SimRule *rule = (SimRule *) node->data;
if (sim_rule_match_by_event (rule, event))
{
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "sim_directive_backlog_match_by_event; sim_rule_match_by_event: True");
time_t time_last = time (NULL);
directive->_priv->rule_curr = node; // 每次事件匹配时,该指令都下一级到匹配的节点。下次将根据此级别检查事件。
//FIXME: 父节点中可能存在内存泄漏.
directive->_priv->time_last = time_last;
directive->_priv->time_out = sim_directive_get_rule_curr_time_out_max (directive);
sim_rule_set_event_data (rule, event); //这里我们将事件中的各个字段分配到规则中,所以每次我们进入规则时,我们可以看到匹配的事件.
sim_rule_set_time_last (rule, time_last);
if (!G_NODE_IS_LEAF (node))
{
GNode *children = node->children;
while (children)
{
SimRule *rule_child = (SimRule *) children->data;
sim_rule_set_time_last (rule_child, time_last);
sim_directive_set_rule_vars (directive, children);
children = children->next;
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "sim_directive_backlog_match_by_event: There are childrens in %d directive", directive->_priv->id);
}
}
else
{
directive->_priv->matched = TRUE;
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "sim_directive_backlog_match_by_event: The directive %d has matched", directive->_priv->id);
}
return TRUE;
}
else
{
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "sim_directive_backlog_match_by_event: sim_rule_match_by_event: False");
}
node = node->next;
}
return FALSE;
}
/*
* 检查指令中的所有节点规则,以查看.......
*/
gboolean
sim_directive_backlog_match_by_not (SimDirective *directive)
{
GNode *node = NULL;
GNode *children = NULL;
g_return_val_if_fail (directive, FALSE);
g_return_val_if_fail (SIM_IS_DIRECTIVE (directive), FALSE);
g_return_val_if_fail (!directive->_priv->matched, FALSE);
g_return_val_if_fail (directive->_priv->rule_curr, FALSE);
g_return_val_if_fail (directive->_priv->rule_curr->data, FALSE);
g_return_val_if_fail (SIM_IS_RULE (directive->_priv->rule_curr->data), FALSE);
node = directive->_priv->rule_curr->children;
while (node)
{
SimRule *rule = (SimRule *) node->data;
//如果规则已超时 &&
if ((sim_rule_is_time_out (rule)) && (sim_rule_get_not (rule)) && (!sim_rule_is_not_invalid (rule)))
{
time_t time_last = time (NULL);
directive->_priv->rule_curr = node;
directive->_priv->time_last = time_last;
directive->_priv->time_out = sim_directive_get_rule_curr_time_out_max (directive);
sim_rule_set_not_data (rule);
if (!G_NODE_IS_LEAF (node)) //这不是最后的节点,他还有一些子节点.
{
children = node->children;
while (children)
{
SimRule *rule_child = (SimRule *) children->data;
sim_rule_set_time_last (rule_child, time_last);
sim_directive_set_rule_vars (directive, children);
children = children->next;
}
}
else //last node!
{
directive->_priv->matched = TRUE;
}
return TRUE;
}
node = node->next;
}
return FALSE;
}
/*
* backlog&directives几乎是相同的:backlog是存储指令并填充事件数据的地方。
*“node”是子节点函数。我们需要从引用其级别的节点向该节点添加src_ip、port等。如果“node”参数是根节点->子节点1->子节点2中的children2,并且我们在children2中有1:plugin-sid,那么我们必须将根节点中的plugin-sid添加到children2中。
*/
void
sim_directive_set_rule_vars (SimDirective *directive,
GNode *node)
{
SimRule *rule;
SimRule *rule_up;
GNode *node_up;
GList *vars;
GInetAddr *ia;
GInetAddr *sensor;
gint port;
gint sid;
SimProtocolType protocol;
gchar *aux = NULL;
g_return_if_fail (directive);
g_return_if_fail (SIM_IS_DIRECTIVE (directive));
g_return_if_fail (node);
g_return_if_fail (g_node_depth (node) > 1);
rule = (SimRule *) node->data;
vars = sim_rule_get_vars (rule);