snort规则解析源码分析

 

 

init_policies

遍历sc->policy_map->ips_policy_count()和sc->policy_map->inspection_policy_count(),设置ips_policy->policy_mode和inspection_policy->policy_mode

ParseRules

  1. 遍历sc->policy_map->ips_policy_count()
  2. 通过sc->policy_map->get_ips_policy(idx)获取IpsPolicy
  3. 判断p->includer不为空,则执行push_parse_location,ParseConfigFile,pop_parse_location。push_parse_location函数创建loc对象,并将loc入栈;

ParseConfigFile函数通过状态机解析规则;

pop_parse_location函数将loc出栈。

  1. 判断!p->rules.empty(),并执行3中流程
  2. 判断!idx and !s_aux_rules.empty(),并执行3中流程
  3. 判断!idx and sc->stdin_rules,并执行3中流程
  4. 调用PortTablesFinish。

 

PortTablesFinish

  1. 分别将port_tables->ip.src,port_tables->ip.dst,port_tables->icmp.src,port_tables->icmp.dst,port_tables->tcp.src,port_tables->tcp.dst,port_tables->udp.src,port_tables->udp.dst调用finish_portlist_table函数
  2. 分别将port_tables->ip.any->rule_list,port_tables->icmp.any->rule_list,port_tables->tcp.any->rule_list,port_tables->udp.any->rule_list,port_tables->svc_any->rule_list等调用RuleListSortUniq,该函数将上面的链表按照数据部分进行排序。数据部分为int类型的rule id。

 

finish_portlist_table

  1. 调用函数PortTableSortUniqRules,将pt->pt_polist中的每个PortObject的rule_list按照ruleid进行排序;先遍历p->pt_polist,它的每一个成员是PortObject,然后遍历PortObject po->rule_list按照rule id进行排序
  2. 调用PortTableCompile,其中调用PortTableCompileMergePortObjects函数:

创建p->pt_mpo_hash表,数据成员为PortObject

创建p->pt_mpxo_hash表,数据成员为plx_t

  1. 调用create_port_lists,将p->pt_polist转换成数组,下标为端口号,成员为PortObject组成的链表。先遍历p->pt_polist得到每一个PortObject,然后遍历po->item_list,每个成员为PortObjectItem,取出端口号,并按照端口号作为下标,存放PortObject到数组中。
  2. 按照端口号,遍历3中得到的数组,取出数组中的PortObject对象,将其保存在pol中,调用PortTableCompileMergePortObjectList2函数:

根据PortObject中规则数量的多少,分别存放在polarge或者posmall中,数量多的po放在polarge中,数量少的po放在posmall中

分别对polarge和posmall按照地址进行排序

分别将地址封装在plx_large和plx_small中

分别调用_merge_N_pol对polarge和posmall进行合并,得到ponew和posnew

如果ponew和posnew不为空且不相同,根据posnew->rule_hash复制到ponew->rule_hash中

  1. 释放optimized_pl数组占用的空间
  2. 遍历mhashx hash表,其中每个成员为PortObject2,使用new PortBitSet初始化PortObject2中的port_list
  3. 遍历pt_port_object,取出PortObject2对象,如果port_list不为空,则为port_list->set设置位
  4. 遍历mhashx,取出PortObject2对象po
  5. 将po->port_list中置位状态保存到数组parray
  6. 在函数PortObjectItemListFromBits中根据parray生成一个PortObjectItem链表plist
  7. 释放po->item_list,使用plist赋值给po->item_list

 

OrderRuleLists

  1. 调用mSplit,得到toks和num_toks
  2. 遍历num_toks,内部遍历sc->rule_lists node,如果toks[i]和 node->name相同,将节点node从sc->rule_lists上取下,放入链表ordered_list尾部;否则,就跳过node
  3. 遍历sc->rule_lists,将其上剩余的node节点也放入ordered_list尾部
  4. 修改sc->rule_lists为ordered_list

 

fpCreateFastPacketDetection

  1. 调用fpCreatePortGroups
  2. 调用fpCreateRuleMaps
  3. 调用fpCreateServicePortGroups

 

fpCreatePortGroups

  1. 分别为p->ip.src,p->ip.dst,p->icmp.src,p->icmp.dst,p->tcp.src,p->tcp.dst,p->udp.src,p->udp.dst,调用 fpCreatePortTablePortGroups
  2. 在fpCreatePortObject2PortGroup中:

遍历pt_mpo_hash表,成员为PortObject2 po,调用fpCreatePortObject2PortGroup,为po创建PortGroup

fpCreatePortObject2PortGroup

  1. PortObject2* po,如果po为空,或者po->rule_hash位空,则返回
  2. 创建一个portgroup
  3. 将pox = po
  4. 遍历pox->rule_hash,取出数据prindex,根据prindex调用parser_get_rule_ids获取gid,sid
  5. 调用OtnLookup获取otn
  6. 如果otn->snort_protocol_id为网络协议,调用fpAddPortGroupRule

调用get_fp_content,获取pmv,如果pmv不为空,则

获取offload_search_api,如果offload_search_api与search_api不相同,则

继续调用get_fp_content,获取pmv_ol,如果pmv_ol不为空,设置add_to_offload为true,否则设置cont为false

如果cont为true,初始化agent,初始化pg->mpsegrp[main_pmd->pm_type],调用pg->mpsegrp[main_pmd->pm_type]->create_normal_mpse(sc, &agent)

如果add_to_offload为true,初始化agent_offload,调用pg->mpsegrp[main_pmd->pm_type]->create_offload_mpse

如果pg->mpsegrp[main_pmd->pm_type]->normal_mpse为true,调用fpFinishPortGroupRule,调用fpAddAlternatePatterns

如果ol_pmd and pg->mpsegrp[main_pmd->pm_type]->offload_mpse为true,则调用fpFinishPortGroupRule,调用fpAddAlternatePatterns

  1. 调用fpFinishPortGroup

 

 

fpFinishPortGroup

  1. 如果pg->mpsegrp[i]和pg->mpsegrp[i]->normal_mpse均不为空,调用pg->mpsegrp[i]->normal_mpse->get_pattern_count(),如果返回值不等于0,同时!sc->test_mode() or sc->mem_check()为true,则调用pg->mpsegrp[i]->normal_mpse->prep_patterns(sc);如果返回值等于0,则调用MpseManager::delete_search_engine(pg->mpsegrp[i]->normal_mpse)
  2. 如果pg->mpsegrp[i]->offload_mpse不为空,pg->mpsegrp[i]->offload_mpse->get_pattern_count() != 0且!sc->test_mode() or sc->mem_check(),则调用 pg->mpsegrp[i]->offload_mpse->prep_patterns(sc);否则调用MpseManager::delete_search_engine(pg->mpsegrp[i]->offload_mpse)
  3. 遍历pg->nfp_head,调用otn_create_tree;
  4. 调用finalize_detection_option_tree

 

 

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值