前面的分析已經知道了讀取規則時如何處理動做,協議,地址和端口串。所以對於解析像: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指針