前面的分析已经知道了读取规则时如何处理动做,协议,地址和端口串。所以对于解析像:node
log tcp any any-> any any
这样的规则头部已经能够完成,这里就对完整规则头部解析后整理规则头部信息的流程进行分析,从该段代码也可看出规则节点是如何与规则选项节点相关联的.
shell
snort-2.9.6.0中取出的代码片断
tcp
static RuleTreeNode * ProcessHeadNode(SnortConfig *sc, RuleTreeNode *test_node, ListHead *list) { /**查找全部规则选项节点关联的规则头节点是否与在处理的头节点相同该节点*/ RuleTreeNode *rtn = findHeadNode(sc, test_node, getParserPolicy(sc)); /* if it doesn't match any of the existing nodes, make a new node and * stick it at the end of the list */ if (rtn == NULL) /**检查是否已有相同的规则节点*/ { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Building New Chain head node\n");); /**若是没有申请一个新的rtn节点*/ rtn = (RuleTreeNode *)SnortAlloc(sizeof(RuleTreeNode)); /**将该规则对象的被动做节点引用计数加一*/ rtn->otnRefCount++; /**将test_node的内容拷贝到rtn中*/ /* copy the prototype header info into the new header block */ XferHeader(test_node, rtn); /* number of header blocks (chain heads?) */ /**这是个全局递增计数,实际是为节点提供ID的*/ head_count++; /**为该节点设置ID*/ rtn->head_node_number = head_count; /**这个过程很简单但却很重要,见后面的代码片断*/ /* initialize the function list for the new RTN */ SetupRTNFuncList(rtn); /**该规则节点的listHead指向对应的动做链*/ /* add link to parent listhead */ rtn->listhead = list; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "New Chain head flags = 0x%X\n", rtn->flags);); } else { /**代表该规则有两个动做节点引用*/ /**注意没有设置listhead指针*/ rtn->otnRefCount++; FreeRuleTreeNode(test_node); } return rtn; } /**returns matched header node. */ static RuleTreeNode * findHeadNode(SnortConfig *sc, RuleTreeNode *testNode, tSfPolicyId policyId) { RuleTreeNode *rtn; OptTreeNode *otn; SFGHASH_NODE *hashNode; for (hashNode = sfghash_findfirst(sc->otn_map); hashNode; hashNode = sfghash_findnext(sc->otn_map)) { /**遍历其中的全部规则选项节点,获取其关联的规则节点*/ otn = (OptTreeNode *)hashNode->data; rtn = getRtnFromOtn(otn, policyId); /**检查该规则选项节点关联的规则节点是不是咱们将要添加的节点*/ if (TestHeader(rtn, testNode)) return rtn; } return NULL; } /**************************************************************************** * * Function: SetupRTNFuncList(RuleTreeNode *) * * Purpose: Configures the function list for the rule header detection * functions (addrs and ports) * * Arguments: rtn => the pointer to the current rules list entry to attach to * * Returns: void function * ***************************************************************************/ static void SetupRTNFuncList(RuleTreeNode * rtn) { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Initializing RTN function list!\n");); DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Functions: ");); /**这部分实际是根据规则对象的头部属性对rtn->rule_func回调链中加入对报文的源地址等数据处理的回调函数*/ if(rtn->flags & BIDIRECTIONAL) { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"CheckBidirectional->\n");); AddRuleFuncToList(CheckBidirectional, rtn); } else { /* Attach the proper port checking function to the function list */ /* * the in-line "if's" check to see if the "any" or "not" flags have * been set so the PortToFunc call can determine which port testing * function to attach to the list */ PortToFunc(rtn, (rtn->flags & ANY_DST_PORT ? 1 : 0), (rtn->flags & EXCEPT_DST_PORT ? 1 : 0), DST); /* as above */ PortToFunc(rtn, (rtn->flags & ANY_SRC_PORT ? 1 : 0), (rtn->flags & EXCEPT_SRC_PORT ? 1 : 0), SRC); /* link in the proper IP address detection function */ AddrToFunc(rtn, SRC); /* last verse, same as the first (but for dest IP) ;) */ AddrToFunc(rtn, DST); } DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"RuleListEnd\n");); /**这里仅仅是在回调连尾部加入一个空回调作结尾标志*/ /* tack the end (success) function to the list */ AddRuleFuncToList(RuleListEnd, rtn); }
规则头部对象不会出现重复函数
一个规则头能被多个规则选项引用ui
对报文的IP,端口处理的回调函数会在这里加入规则持有的回调链中spa
http://my.oschina.net/u/572632/blog/289803.net
http://my.oschina.net/u/572632/blog/289775prototype
http://my.oschina.net/u/572632/blog/289471指针