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

📄 375.htm

📁 unix高级编程原吗
💻 HTM
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://apue.dhs.org"><font face="黑体"><big><big>apue</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center">               ● UNIX网络编程                       (BM: clown)                </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p   align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="index.htm">回到开始</a>][<a href="370.htm">上一层</a>][<a href="376.htm">下一篇</a>]
<hr><p align="left"><small>发信人: shuke (莫失莫忘), 信区: Security <br>

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

发信站: BBS 水木清华站 (Tue Oct 10 11:42:22 2000) <br>

  <br>

  <br>

    现在看看snort如何实现对数据包的分析和检测入侵的。 <br>

  <br>

    在main函数的最后部分有如下语句,比较重要: <br>

  <br>

/* Read all packets on the device.  Continue until cnt packets read */ <br>

if(pcap_loop(pd, pv.pkt_cnt, (pcap_handler)ProcessPacket, NULL) < 0) <br>

{ <br>

...... <br>

} <br>

  <br>

    这里pcap_loop函数有4个参数,分别解释: <br>

  <br>

    pd是一个全局变量,表示文件描述符,在前面OpenPcap的调用中已经被正确地 <br>

赋值。前面说过,snort可以实时采集网络数据,也可以从文件读取数据进行分析。 <br>

在不同情况打开文件(或设备)时,pd分别用来处理文件,或者网卡设备接口。 <br>

  <br>

    pd是struct pcap类型的指针,该结构包括实际的文件描述符,缓冲区,等等 <br>

域,用来处理从相应的文件获取信息。 <br>



  <br>

    OpenPcap函数中对pd赋值的语句分别为: <br>

  <br>

      /* get the device file descriptor,打开网卡接口 */ <br>

      pd = pcap_open_live(pv.interface, snaplen, <br>

                   pv.promisc_flag ? PROMISC : 0, READ_TIMEOUT, errorbuf); <br>

  <br>

      或者 <br>

  <br>

      /* open the file,打开文件 */ <br>

      pd = pcap_open_offline(intf, errorbuf); <br>

  <br>

    于是,这个参数表明从哪里取得待分析的数据。 <br>

  <br>

    第2个参数是pv.pkt_cnt,表示总共要捕捉的包的数量。在main函数初始化时, <br>

缺省设置为-1,成为永真循环,一直捕捉直到程序退出: <br>

  <br>

   /* initialize the packet counter to loop forever */ <br>

   pv.pkt_cnt = -1; <br>

  <br>

    或者在命令行中设置要捕捉的包的数量。前面ParseCmdLine(解析命令行)函数 <br>

的调用中,遇到参数n,重新设定pv.pkt_cnt的值。ParseCmdLine中相关语句如下: <br>



  <br>

         case 'n': /* grab x packets and exit */ <br>

                 pv.pkt_cnt = atoi(optarg); <br>

  <br>

    第3个参数是回调函数,该回调函数处理捕捉到的数据包。这里为函数 <br>

ProcessPacket,下面将详细解释该函数。 <br>

  <br>

    第4个参数是字符串指针,表示用户,这里设置为空。 <br>

  <br>

    在说明处理包的函数ProcessPacket之前,有必要解释一下pcap_loop的实现。 <br>

我们看到main函数只在if条件判断中调用了一次pacp_loop,那么循环一定是在 <br>

pcap_loop中做的了。察看pcap.c文件中pcap_loop的实现部分,我们发现的确如此: <br>

  <br>

int <br>

pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) <br>

{ <br>

        register int n; <br>

  <br>

        for (;;) {  //for循环 <br>

                if (p->sf.rfile != NULL) <br>

                        n = pcap_offline_read(p, cnt, callback, user); <br>

                else { <br>



                        /* <br>

                         * XXX keep reading until we get something <br>

                         * (or an error occurs) <br>

                         */ <br>

                        do {  //do循环 <br>

                                n = pcap_read(p, cnt, callback, user); <br>

                        } while (n == 0); <br>

                } <br>

                if (n <= 0) <br>

                        return (n);  //遇到错误,返回 <br>

                if (cnt > 0) { <br>

                        cnt -= n; <br>

                        if (cnt <= 0) <br>

                                return (0);  //到达指定数量,返回 <br>

                } <br>

                //只有以上两种返回情况 <br>

        } <br>

} <br>

  <br>

  <br>

    现在看看ProcessPacket的实现了,这个回调函数用来处理数据包。该函数是 <br>

是pcap_handler类型的,pcap.h中类型的定义如下: <br>



  <br>

typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, <br>

                             const u_char *); <br>

  <br>

    第1个参数这里没有什么用; <br>

  <br>

    第2个参数为pcap_pkthdr结构指针,记录时间戳、包长、捕捉的长度; <br>

  <br>

    第3个参数字符串指针为数据包。 <br>

  <br>

    函数如下: <br>

void ProcessPacket(char *user, struct pcap_pkthdr *pkthdr, u_char *pkt) <br>

{ <br>

   Packet p;  //Packet结构在decode.h中定义,用来记录数据包的各种信息 <br>

  <br>

   /* call the packet decoder,调用拆包函数,这里grinder是一个全局 <br>

   函数指针,已经在main的SetPktProcessor调用中设置为正确的拆包函数 */ <br>

   (*grinder)(&p, pkthdr, pkt); <br>

  <br>

   /* print the packet to the screen,如果选择了详细显示方式, <br>

   那么把包的数据,显示到标准输出 */ <br>

   if(pv.verbose_flag) <br>



   { <br>

      ......  //省略 <br>

   } <br>

  <br>

   /* check or log the packet as necessary <br>

   如果工作在使用检测规则的方式,就调用Preprocess进行检测, <br>

   否则,仅仅进行日志,记录该包的信息*/ <br>

   if(!pv.use_rules) <br>

   { <br>

      ...   //进行日志,省略 <br>

   } <br>

   else <br>

   { <br>

      Preprocess(&p); <br>

   } <br>

  <br>

   //清除缓冲区 <br>

   ClearDumpBuf(); <br>

  <br>

} <br>

  <br>

    这里Preprocess函数进行实际检测。 <br>



-- <br>

  <br>

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

  <br>

  <br>

※ 修改:·shuke 於 Oct 10 11:47:15 修改本文·[FROM:   166.111.69.59] <br>

</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="370.htm">上一层</a>][<a href="376.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 + -