﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-【永恒的瞬间】  -文章分类-meshwork</title><link>http://www.blogjava.net/19851985lili/category/22482.html</link><description>☜GivE mE HapPy ☞




</description><language>zh-cn</language><lastBuildDate>Wed, 16 May 2007 10:30:10 GMT</lastBuildDate><pubDate>Wed, 16 May 2007 10:30:10 GMT</pubDate><ttl>60</ttl><item><title>网络嗅探软件的设计与分析</title><link>http://www.blogjava.net/19851985lili/articles/117824.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Wed, 16 May 2007 05:53:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/117824.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/117824.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/117824.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/117824.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/117824.html</trackback:ping><description><![CDATA[&nbsp;
<p><strong><span>&nbsp;<span>摘 要</span><span>&nbsp;</span></span></strong><span>本文介绍了网络嗅探器软件的功能，以及网络嗅探软件设计的原理，并以软件设计的模块化思想为主介绍了编写一个网络嗅探软件的总体设计思想以及主要代码设计，同时对涉及到的若干网络编程知识以及一些网络基本知识进行了介绍。本文的最后也指出了此网络嗅探软件设计的另一个发展方向。</span></p>
<p><span><span>&nbsp;&nbsp; </span></span><strong><span><span>&nbsp;&nbsp;&nbsp;</span></span></strong><strong><span>关键词 </span></strong><span>&nbsp;</span><span>网络嗅探器</span><span>&nbsp;</span><span>混杂模式</span><span> &nbsp;</span><span>模块化设计</span></p>
<p><strong><span>1</span></strong><span> <strong>&nbsp;</strong></span><strong><span>引</span></strong><strong><span> </span></strong><strong><span>言</span></strong></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span></span><span>随着网络技术的发展，网络系统对于整个社会的工作和建设发挥着越来越大的作用，网络环境也变得越来越复杂，与此同时网络系统的安全问题也引起了我们的关注。设计数据包嗅探器的目的在于能够使系统管理员运用此类软件分析网络流量以便更好地控制网络。它能够帮助系统管理人员迅速地找到问题症结所在（如网络瓶颈、错误配置等），它们通常被用来在网路上截取</span><span>/</span><span>阅读位于</span><span>OSI </span><span>协议模型中各个协议层次上的数据包。</span><span>&nbsp;</span></p>
<p><strong><span>2 </span></strong><strong><span>网络嗅探软件的设计原理</span></strong><span>&nbsp;</span></p>
<p align=left><span>嗅探器可以理解为一个安装在计算机上的窃听设备，它可以用来窃听计算机在网络上所产生的众多的信息，可以窃听计算机程序在网络上发送和接收到的数据，用来接收在网络上传输的信息。</span></p>
<p><span>很多计算机网络采用的是</span><span>&#8220;</span><span>共享媒体</span><span>"</span><span>。也就是说，不必中断他的通讯，并且配置特别的线路，再安装嗅探器，几乎可以在任何连接着的网络上直接窃听到同一掩码范围内的计算机网络数据。这种窃听方式为</span><span>&#8220;</span><span>基于混杂模式的嗅探</span><span>&#8221;</span><span>（</span><span>promiscuous mode</span><span>）。</span></p>
<p><strong><span>2.1 </span></strong><strong><span>以太网的工作原理</span></strong><strong></strong></p>
<p><span>以太网的数据传输是基于</span><span>&#8220;</span><span>共享</span><span>&#8221;</span><span>原理的：所有的同一本地网范围内的计算机共同接收到相同的数据包。这意味着计算机直接的通讯都是透明可见的。正是因为这样的原因，以太网卡都构造了硬件的</span><span>&#8220;</span><span>过滤器</span><span>&#8221;,</span><span>这个过滤器将忽略掉一切和自己无关的网络信息。事实上是忽略掉了与自身</span><span>MAC</span><span>地址不符合的信息。嗅探程序正是利用了这个特点，它把网卡设置为</span><span>&#8220;</span><span>混杂模式</span><span>&#8221;</span><span>。因此，嗅探程序就能够接收到整个以太网内的网络数据信息了。</span>&nbsp;</p>
<p><span>在以太网中所有的通讯都是广播的，也就是说通常在同一个网段的所有网络接口都可以访问在物理媒体上传输的所有数据，而每一个网络接口都有一个唯一的硬件地址，这个硬件地址也就是网卡的</span><span>MAC</span><span>地址。大多数系统使用</span><span>48</span><span>比特的地址，这个地址用来表示</span></p>
<p><span>网络中的每一个设备。一般来说每一块网卡上的</span><span>MAC</span><span>地址都是不同的，每个网卡厂家得到一段地址，然后用这段地址分配给其生产的每个网卡一个地址。在硬件地址和</span><span>IP</span><span>地址间使用</span><span>ARP</span><span>和</span><span>RARP</span><span>协议进行相互转换。</span></p>
<p><span>在正常的情况下，一个网络接口应该只响应这样的两种数据帧：</span></p>
<p><span>①</span><span> </span><span>与自己硬件地址相匹配的数据帧。</span></p>
<p><span>②</span><span> </span><span>发向所有机器的广播数据帧。</span></p>
<p><strong><span>2.2 </span></strong><strong><span>网卡的工作原理</span></strong><strong></strong></p>
<p><span>在一个实际的系统中，数据的收发是由网卡来完成的。网卡接收到传输来的数据，网卡内的单片程序接收数据帧的目的</span><span>MAC</span><span>地址。根据计算机上的网卡驱动程序设置的接收模式判断该不该接收。认为该接收就接收后产生中断信号通知</span><span>CPU</span><span>；认为不该接收就丢掉不管。所以不该接收的数据，网卡就截断了，计算机根本就不知道。</span><span>CPU</span><span>得到中断信号产生中断，操作系统就根据网卡的驱动程序设置的网卡中断程序地址调用驱动程序接收数据，驱动程序接收数据后放入信号堆栈让操作系统处理。</span></p>
<p><span>对于网卡一般有四种接收模式：</span></p>
<p><span>①</span><span>&nbsp;</span><span>广播方式：该模式下的网卡能够接收网络中的广播信息。</span></p>
<p><span>②</span><span>&nbsp;</span><span>组播方式：设置在该模式下的网卡能够接收组播数据。</span></p>
<p><span>③</span><span>&nbsp;</span><span>直接方式：在这种模式下，只有目的网卡才能接收该数据。</span></p>
<p><span>④</span><span>&nbsp;</span><span>混杂模式：在这种模式下的网卡能够接收一切通过它的数据</span><span>,</span><span>而不管该数据是否是传给它的。</span></p>
<p>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>数据包</span><span>MAC</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>接口配置模式</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>产生中断，通知</span><span>CPU</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>产生中断，通知</span><span>CPU</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span><span>&nbsp;&nbsp;&nbsp; </span></span><span>不处理，丢弃</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>本地接口硬件地址</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>广播地址 </span></p>
            <p>&nbsp;</p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>其他硬件地址</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>混杂模式</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>非混合模式</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>数据包</span><span>MAC</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>接口配置模式</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>产生中断，通知</span><span>CPU</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>产生中断，通知</span><span>CPU</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span><span>&nbsp;&nbsp;&nbsp; </span></span><span>不处理，丢弃</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>数据包</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p><strong><span>2.3 </span></strong><strong><span>网络嗅探软件的工作原理</span></strong><strong></strong></p>
<p><span>根据以上的介绍，我们可以得出结论如下：</span></p>
<p><span>首先，在以太网中是基于广播方式传送数据的，也就是说，所有的物理信号都要经过我的机器。再次，网卡可以置于一种模式叫混杂模式（</span><span>promiscuous mode</span><span>），在这种模式下工作的网卡能够接收到一切通过它的数据，而不管实际上数据的目的地址是不是它。这就是以下将要介绍的网络嗅探软件的工作的基本原理：让网卡接收一切它所能接收的数据。</span></p>
<p><span>计算机直接所传送的数据，事实上是大量的二进制数据。因此</span><span>, </span><span>一个网络窃听程序还必须也使用特定的网络协议来分解嗅探到的数据，嗅探器也就必须能够识别出哪个协议对应于这个数据片断，只有这样才能够进行正确的解码。</span><span>&nbsp;</span><span><span>&nbsp;&nbsp;</span></span></p>
<p><strong><span>3 </span></strong><strong><span>网络嗅探软件的设计实现</span></strong><strong></strong></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span></span><span>该网络嗅探软件能够从网络上读取数据包并且解析数据包报文头中各字段的意义。能够分析数据帧以及所使用的协议的类型。</span></p>
<p><span>3.1 </span><span>网络嗅探软件的模块结构</span></p>
<p><span>设计该网络嗅探软件可分为以下几个步骤：</span></p>
<p><span>①</span><span>&nbsp;</span><span>创建套接字</span></p>
<p><span>②</span><span>&nbsp;</span><span>把网卡设置为混杂模式</span></p>
<p><span>③</span><span>&nbsp;</span><span>捕获数据包</span></p>
<p><span>④</span><span>&nbsp;</span><span>分析数据包</span></p>
<p><span>3.2 </span><span>模块说明</span></p>
<p><span>⑴　</span><span> </span><span>该网络嗅探软件主要是运用</span><span>LINUX</span><span>环境下的</span><span>SOCKET</span><span>编程。网络的</span><span>SOCKET</span><span>数据传输是一种特殊的</span><span>I/O, SOCKET</span><span>也是一种文件描述符。该网络嗅探软件设计的目的是截获所有的数据包，即包括所有的协议。</span></p>
<p><span>Socket</span><span>（）函数的定义式如下：</span></p>
<p><span>Sockfd = socket ( int family, int type, int protocol ) </span><span>；</span></p>
<p><span>第一个参数是地址类型，如果选用</span><span>AF UNIX, </span><span>是用于本机上不同进程之间进行通信，而设为</span><span>AF INET </span><span>则是用于不同主机之间的通信；第二个参数即</span><span>socket</span><span>的类型参数，主要有</span><span>4</span><span>种参数类型如下：</span></p>
<p><span>①　</span><span>SOCK DRAM</span><span>：</span><span>used for udp datagrams.</span></p>
<p><span>②　</span><span>SOCK STREAM</span><span>：</span><span>used for tcp packets.</span></p>
<p><span>③　</span><span>SOCK RAW</span><span>：</span><span>used to bypass the transport layer and directly access the IP layer.</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>　④　</span><span>SOCK PACKET</span><span>：</span><span>this is linux specific, it is similuar to sock raw except it accesses the DATA LINK layer.</span></p>
<p><span>第三个参数是协议参数，指定程序使用具体的协议。</span></p>
<p><span>在此程序中为截获包含所有协议的数据包，故在程序的开始就写语句：</span></p>
<p><span>＃</span><span>define&nbsp;PROTO<span>&nbsp;&nbsp; </span>htons </span><span>（</span><span>0x0003</span><span>）</span><span>/ *Ethernet code for all protol */</span></p>
<p><span>且在本程序中</span><span>socket</span><span>（）函数的第二个参数选用</span><span>sock packet</span><span>。</span></p>
<p><span>⑵　套接字创建成功之后，就可以选择网络接口并加以参数控制了。进入第二个模块：设置网卡于混杂模式。</span></p>
<p><span>在程序中有一个单独的自定义函数是用来将网卡设置为混杂模式的。在这个模块中主要是调用了</span><span>ioctl </span><span>函数，</span><span>ioctl </span><span>函数是用来控制特殊文件的底层设备参数的，这些特殊文件通常是终端、套接字和接口。</span><span>ioctl </span><span>函数的定义如下：</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>ioctl</span><span>（</span><span>sock</span><span>，</span><span> SIOCGIFFLAGS, &amp;ifr </span><span>）</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>ioctl</span><span>（）函数中第一个参数是一个打开的原始套接字描述符&#8220;</span><span>sock</span><span>&#8221;，第二个参数是所要执行的请求操作。这里，请求操作是&#8220;</span><span>SIOCGIFFLAGS</span><span>&#8221;，意思是获取接口&#8220;</span><span>etho</span><span>&#8221;的标记符。第三个参数是接口请求数据结构的地址指针，该结构中包含了所要进行请求操作的接口名称值。</span></p>
<p><span>⑶　网络接口设置为混杂模式以后，接着就可以接收数据包了</span><span>, </span><span>进入捕获数据包的模块。</span></p>
<p><span><span>&nbsp;&nbsp; </span>recvfrom&nbsp;( if_eth_fd, &amp;ep, sizeof (ep), 0, &amp;dest, &amp;dlen );</span></p>
<p><span>这个函数要做的就是接收数据，并把接收到的数据放入</span><span>buffer</span><span>中。</span></p>
<p><span>⑷　在成功的接收到数据包后，程序将进入下一个模块：分析数据包。</span></p>
<p><span>这里要介绍一下有关的网络基本知识，首先介绍一下</span><span>TCP/IP</span><span>的分层：</span></p>
<p><span>在</span><span>TCP/IP</span><span>协议族中，有很多种协议。可用图一简单概括</span><span>TCP/IP</span><span>协议族中不同层次的协议。如图所示，由于</span><span>TCP</span><span>、</span><span>UDP</span><span>、</span><span>ICMP</span><span>和</span><span>IGMP</span><span>都要向</span><span>IP</span><span>传送数据，因此</span><span>IP</span><span>必须在生成的</span><span>IP</span><span>首部中加入某种标识，以表明数据属于哪一层。为此，</span><span>IP</span><span>在首部中存入一个长度为</span><span>8 bit</span><span>的数据，称作协议域。</span><span>1</span><span>表示为</span><span>ICMP</span><span>协议，</span><span>2</span><span>表示为</span><span>IGMP</span><span>协议，</span><span>6</span><span>表示为</span><span>TCP</span><span>协议，</span><span>17</span><span>表示为</span><span>UDP</span><span>协议。类似地，许多应用程序都可以使用</span><span>TCP</span><span>或</span><span>UDP</span><span>来传送数据。运输层协议在生成报文首部时要存入一个应用程序的标识符。</span><span>TCP</span><span>和</span><span>UDP</span><span>都用一个</span><span>16 bit</span><span>的端口号来表示不同的应用程序。</span><span>TCP</span><span>和</span><span>UDP</span><span>把源端口号和目的端口号分别存入报文首部中。网络接口分别要发送和接收</span><span>IP</span><span>、</span><span>ARP</span><span>和</span><span>RARP</span><span>数据，因此也必须在以太网的帧首部中加入某种形式的标识，以指明生成数据的网络层协议。为此，以太网的帧首部也有一个</span><span>16 bit</span><span>的帧类型域。</span></p>
<p>&nbsp;</p>
<p>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p>&nbsp;</p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>TCP<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>UDP</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>ICMP</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>IP</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>IGMP</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>ARP</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>硬件接口</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%">
    <tbody>
        <tr>
            <td>
            <div>
            <p><span>RARP</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p><span>用户进程</span><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>用户进程</span><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>用户进程</span><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>用户进程</span><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>应用层</span><span><span>&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span>运输层 </span><span>网络层</span>&nbsp;<span><span>&nbsp;&nbsp;</span></span><span>链路层</span></p>
<p><span><span>&nbsp;&nbsp;</span></span><span><span>&nbsp; </span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>媒体</span></p>
<p><span>（图一）</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span></span><span>网络嗅探程序在分析数据包这一阶段正是根据了网络的工作原理：在收到一个以太网数据帧时，数据就开始从协议栈中由底向上升，同时去掉各层协议加上的报文首部。每层协议盒都要去检查报文首部中的协议标识，以确定接收数据的上层协议。这个过程即是分用。</span></p>
<p><strong><span>4 </span></strong><strong><span>进一步的发展方向</span></strong><strong></strong></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>还有很多的功能可以加入到本文所设计的软件中，使其变得更加完整。它的另一个发展的方向就是进一步更好的分析数据包中的数据部分，并能够把分析出来的数据从</span><span>ASCII</span><span>码转换为自然语言，这就能够给用户带来很大的方便。</span></p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/19851985lili/aggbug/117824.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-05-16 13:53 <a href="http://www.blogjava.net/19851985lili/articles/117824.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>