⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 376.htm

📁 unix高级编程原吗
💻 HTM
📖 第 1 页 / 共 2 页
字号:
  <br>

      垆边人似月,皓腕凝霜雪 <br>

  <br>

  <br>

※ 来源:·BBS 水木清华站 smth.org·[FROM: 166.111.69.59] <br>

发信人: shuke (莫失莫忘), 信区: Security <br>

标  题: snort源码分析(5) <br>

发信站: BBS 水木清华站 (Fri Oct 13 11:20:55 2000) <br>

  <br>

  <br>

  <br>

    Proprocess函数很短,首先调用预处理规则处理数据包p,然后调用检测 <br>

函数Detect进行规则匹配实现检测,如果实现匹配,那么调用函数CallOutput <br>

Plugins根据输出规则进行报警或日志。函数如下: <br>

  <br>

void Preprocess(Packet *p) <br>

{ <br>

   PreprocessFuncNode *idx; <br>

  <br>

   do_detect = 1; <br>

   idx = PreprocessList;  //指向预处理规则链表头 <br>

  <br>

   while(idx != NULL)  //调用预处理函数处理包p <br>

   { <br>

      idx->func(p); <br>

      idx = idx->next; <br>

   } <br>

  <br>

   if(!p->frag_flag && do_detect) <br>

   { <br>

      if(Detect(p))  //调用检测函数 <br>

      { <br>

         CallOutputPlugins(p);  //如果匹配,根据规则输出 <br>



      } <br>

   } <br>

} <br>

  <br>

    尽管这个函数很简洁,但是在第1行我们看到定义了ProprocessFuncNode <br>

结构类型的指针,所以下面,我们不得不开始涉及到snort的各种复杂 <br>

的数据结构。前面的分析,我一直按照程序运行的调用顺序,忽略了许多函 <br>

数(其实有不少非常重要),以期描述出snort执行的主线,避免因为程序中 <br>

大量的调用关系而产生混乱。到现在,我们还没有接触到snort核心的数据结构 <br>

和算法。有不少关键的问题需要解决:规则是如何静态描述的?运行时这些 <br>

规则按照什么结构动态存储?每条规则的处理函数如何被调用?snort给了 <br>

我们提供了非常好的方法。 <br>

  <br>

    snort一个非常成功的思想是利用了plugin机制,规则处理函数并非固定在 <br>

源程序中,而是根据每次运行时的参数设定,从规则文件中读入规则,再把每个 <br>

规则所需要的处理函数挂接到链表上。实际检测时,遍历这些链表,调用链表上 <br>

相应的函数来分析。 <br>

  <br>

    snort主要的数据结构是链表,几乎都是链表来链表去。我们下面做个总的 <br>

介绍。 <br>

  <br>

    我们有必要先回过头来,看一看main函数中对规则初始化时涉及到的一些 <br>



数据结构。 <br>

  <br>

    在main函数初始化规则的时候,先建立了几个链表,全局变量定义如下 <br>

(plugbase.c中): <br>

  <br>

KeywordXlateList *KeywordList; <br>

PreprocessKeywordList *PreprocessKeywords; <br>

PreprocessFuncNode *PreprocessList; <br>

OutputKeywordList *OutputKeywords; <br>

OutputFuncNode *OutputList; <br>

  <br>

    这几种结构的具体定义省略。这一初始化的过程把snort中预定义的关键 <br>

字和处理函数按类别连接在不同的链表上。然后,在解析规则文件的时候, <br>

如果一条规则的选项中包含了某个关键字,就会从上边初始化好的对应的链表 <br>

中查找,把必要的信息和处理函数添加到表示这条规则的节点(用RuleTreeNode <br>

类型来表示,下面详述)的特定域(OptTreeNode类型)中。 <br>

  <br>

    同时,main函数中初始化规则的最后,对指定的规则文件进行解析。在最 <br>

高的层次上,有3个全局变量保存规则(rules.c): <br>

  <br>

ListHead Alert;      /* Alert Block Header */ <br>

ListHead Log;        /* Log Block Header */ <br>



ListHead Pass;       /* Pass Block Header */ <br>

  <br>

    这几个变量是ListHead类型的,正如名称所说,指示链表头。Alert中登记 <br>

了需要报警的规则,Log中登记了需要进行日志的规则,Pass中登记的规则在处 <br>

理过程忽略(不进行任何处理)。ListHead定义如下: <br>

  <br>

typedef struct _ListHead <br>

{ <br>

   RuleTreeNode *TcpList; <br>

   RuleTreeNode *UdpList; <br>

   RuleTreeNode *IcmpList; <br>

} ListHead; <br>

  <br>

    可以看到,每个ListHead结构中有三个指针,分别指向处理Tcp/Udp/Icmp包 <br>

规则的链表头。这里又出现了新的结构RuleTreeNode,为了说明链表的层次关系, <br>

下面列出RuleTreeNode的定义,但是忽略了大部分域: <br>

  <br>

typedef struct _RuleTreeNode <br>

{ <br>

   RuleFpList *rule_func; <br>

  <br>

   ...... //忽略 <br>



  <br>

   struct _RuleTreeNode *right; <br>

  <br>

   OptTreeNode *down;   /* list of rule options to associate with this <br>

                           rule node */ <br>

  <br>

} RuleTreeNode; <br>

  <br>

    RuleTreeNode中包含上述3个指针域,分别又能形成3个链表。RuleTreeNode* <br>

类型的right指向下一个RuleTreeNode,相当于普通链表中的next域,只不过这里 <br>

用right来命名。这样就形成了规则链表。 <br>

  <br>

    RuleFpList类的指针rule_func记录的是该规则的处理函数的链表。一条规则 <br>

有时候需要调用多个处理函数来分析。所以,有必要做成链表。我们看看下面的 <br>

定义,除了next域,还有一个函数指针: <br>

  <br>

typedef struct _RuleFpList <br>

{ <br>

   /* rule check function pointer */ <br>

   int (*RuleHeadFunc)(Packet *, struct _RuleTreeNode *, struct _RuleFpList *); <br>

  <br>

   /* pointer to the next rule function node */ <br>



   struct _RuleFpList *next; <br>

  <br>

} RuleFpList; <br>

  <br>

    第3个指针域是OptTreeNode类的指针down,该行后面的注释说的很清楚,这是 <br>

与这个规则节点相联系的规则选项的链表。很不幸,OptTreeNode的结构也相当复 <br>

杂,而且又引出了几个新的链表。忽略一些域,OptTreeNode定义如下: <br>

  <br>

typedef struct _OptTreeNode <br>

{ <br>

   /* plugin/detection functions go here */ <br>

   OptFpList *opt_func; <br>

  <br>

   /* the ds_list is absolutely essential for the plugin system to work, <br>

      it allows the plugin authors to associate "dynamic" data structures <br>

      with the rule system, letting them link anything they can come up <br>

      with to the rules list */ <br>

   void *ds_list[512];   /* list of plugin data struct pointers */ <br>

  <br>

   .......//省略了一些域 <br>

  <br>

   struct _OptTreeNode *next; <br>



  <br>

} OptTreeNode; <br>

  <br>

    next指向链表的下一个节点,无需多说。OptFpList类型的指针opt_func指向 <br>

选项函数链表,同前面说的RuleFpList没什么大差别。值得注意的是指针数组 <br>

ds_list,用来记录该条规则中涉及到的预定义处理过程。每个元素的类型是void*。 <br>

在实际表示规则的时候,ds_list被强制转换成不同的预定义类型。 <br>

-- <br>

  <br>

      垆边人似月,皓腕凝霜雪 <br>

</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="370.htm">上一层</a>][<a href="377.htm">下一篇</a>]
<p align="center"><a href="http://cterm.163.net">欢迎访问Cterm主页</a></p>
</table>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -