结合前面对snort中解析IP的细节处理,从总体上分析snort读取规则是如何管理解析到的IP,以及是如何经过直接复制副原本提升效率的.
node
前面对处理细节的分析 http://my.oschina.net/u/572632/blog/289745
ide
snort 规则中的IP介绍
源码分析
部分代码片断结合流程图说明
ui
/* Used by the "list" mode. A doubly linked list of sfip_t objects. */ typedef struct _ip_node { /*构成一个链表明一个IP集合,存放在sfip_var_t中的head或neg_head中*/ sfip_t *ip; #define ip_addr ip; /* To ease porting Snort */ struct _ip_node *next; int flags; // XXX int addr_flags; /* Flags used exlusively by Snort */ /* Keeping these variables seperate keeps * this from stepping on Snort's toes. */ /* Should merge them later */ } sfip_node_t; /* An IP variable onkect */ typedef struct _var_t { /**每个被解析的IP串对应该结构*/ /* Selects whether or not to use the list, the table, * or any other method added later */ MODES mode; /* Linked lists. Switch to something faster later */ sfip_node_t *head; /**解析出的通常IP*/ sfip_node_t *neg_head; /**被 !取反的IP*/ /* The mode above will select whether to use the sfip_node_t linked list * or the IP routing table */ // sfrt rt; /* Linked list of IP variables for the variable table */ struct _var_t *next; /**构成链表*/ uint32_t id; /**IP串的ID*/ char *name; /**IP串的名字*/ char *value; } sfip_var_t; /* A variable table for storing and looking up variables */ /* Expand later to use a faster data structure */ typedef struct _vartable_t { /**管理全部被解析出的IP串*/ sfip_var_t *head; uint32_t id; } vartable_t;
当从配置文件中得到一个IP串时就交给解析器解析器this
解析器首先查看是否已解析过相同的串,若是有直接拷贝一个副本做为该次解析结果spa
若是该串没有解析过,则解析器开始解析该串.net
解析完成后将该串解析后的集合放入管理器中,向用户返回该次解析结果code
代码取自snort-2.9.6.0对象
static int ProcessIP(SnortConfig *sc, char *addr, RuleTreeNode *rtn, int mode, int neg_list) { /**获取存放全部IP信息的表*/ vartable_t *ip_vartable = sc->targeted_policies[getParserPolicy(sc)]->ip_vartable; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Got address string: %s\n", addr);); assert(rtn); /* If a rule has a variable in it, we want to copy that variable's * contents to the IP variable (IP list) stored with the rtn. * This code tries to look up the variable, and if found, will copy it * to the rtn->{sip,dip} */ if(mode == SRC) /**区分解析对象是源IP仍是目地IP*/ { int ret; if (rtn->sip == NULL) /**源IP是否已解析*/ { /**查看是否解析过相同的IP结合*/ sfip_var_t *tmp = sfvt_lookup_var(ip_vartable, addr); if (tmp != NULL) { /**若是出现过相同的集合直接拷贝上次解析后的数据*/ rtn->sip = sfvar_create_alias(tmp, tmp->name); if (rtn->sip == NULL) ret = SFIP_FAILURE; else ret = SFIP_SUCCESS; } else { /**不然建立解析该串并放入ip_varTable中*/ rtn->sip = (sfip_var_t *)SnortAlloc(sizeof(sfip_var_t)); ret = sfvt_add_to_var(ip_vartable, rtn->sip, addr); } } else { /** 解析串,并将解析出的IP集合添加到rtn->sip中, 并放入ip_vartable中*/ ret = sfvt_add_to_var(ip_vartable, rtn->sip, addr); } /* The function sfvt_add_to_var adds 'addr' to the variable 'rtn->sip' */ if (ret != SFIP_SUCCESS) { if(ret == SFIP_LOOKUP_FAILURE) { ParseError("Undefined variable in the string: %s.", addr); } else if(ret == SFIP_CONFLICT) { ParseError("Negated IP ranges that are more general than " "non-negated ranges are not allowed. Consider " "inverting the logic: %s.", addr); } else if(ret == SFIP_NOT_ANY) { ParseError("!any is not allowed: %s.", addr); } else { ParseError("Unable to process the IP address: %s.", addr); } } /**该节点中出现一个any 标记,则将rtn中标注ANY*/ if(rtn->sip->head && rtn->sip->head->flags & SFIP_ANY) { rtn->flags |= ANY_SRC_IP; } } /* mode == DST */ /**与源IP相对*/ else { int ret; if (rtn->dip == NULL) { sfip_var_t *tmp = sfvt_lookup_var(ip_vartable, addr); if (tmp != NULL) { rtn->dip = sfvar_create_alias(tmp, tmp->name); if (rtn->dip == NULL) ret = SFIP_FAILURE; else ret = SFIP_SUCCESS; } else { rtn->dip = (sfip_var_t *)SnortAlloc(sizeof(sfip_var_t)); ret = sfvt_add_to_var(ip_vartable, rtn->dip, addr); } } else { ret = sfvt_add_to_var(ip_vartable, rtn->dip, addr); } if (ret != SFIP_SUCCESS) { if(ret == SFIP_LOOKUP_FAILURE) { ParseError("Undefined variable in the string: %s.", addr); } else if(ret == SFIP_CONFLICT) { ParseError("Negated IP ranges that are more general than " "non-negated ranges are not allowed. Consider " "inverting the logic: %s.", addr); } else if(ret == SFIP_NOT_ANY) { ParseError("!any is not allowed: %s.", addr); } else { ParseError("Unable to process the IP address: %s.", addr); } } if(rtn->dip->head && rtn->dip->head->flags & SFIP_ANY) { rtn->flags |= ANY_DST_IP; } } /* Make sure the IP lists provided by the user are valid */ if (mode == SRC) ValidateIPList(rtn->sip, addr); else ValidateIPList(rtn->dip, addr); return 0; }
该部分代码的对括号以及取反的方式有很大的参考价值blog
每次解析前先尝试查找被解析过的相同的串得到副原本减小解析的思路减小了不少开销
独孤九剑的<snort入侵检测系统源码分析>