<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>老的工作</title><link>http://blog.vckbase.com/xtdwnuisea/category/168.html</link><description>这些是以前使用VC开发工具时收集的东东......</description><managingEditor>xtdwnuisea</managingEditor><dc:language>kk-KZ</dc:language><generator>.Text Version 0.958.2004.214</generator><item><dc:creator>xtdwnuisea</dc:creator><title>截数据包</title><link>http://blog.vckbase.com/xtdwnuisea/articles/875.html</link><pubDate>Thu, 23 Sep 2004 13:35:00 GMT</pubDate><guid>http://blog.vckbase.com/xtdwnuisea/articles/875.html</guid><wfw:comment>http://blog.vckbase.com/xtdwnuisea/comments/875.html</wfw:comment><comments>http://blog.vckbase.com/xtdwnuisea/articles/875.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blog.vckbase.com/xtdwnuisea/comments/commentRss/875.html</wfw:commentRss><trackback:ping>http://blog.vckbase.com/xtdwnuisea/services/trackbacks/875.html</trackback:ping><description>&lt;P&gt;提交文章： maigan&lt;/P&gt;
&lt;P&gt;提交日期： 2003-10-22 &lt;/P&gt;
&lt;P&gt;文章属性： 原创&lt;/P&gt;
&lt;P&gt;文档类别： 编程技术 &lt;/P&gt;
&lt;P&gt;浏览次数： 今14次/总9053次&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;初探数据包分析程序设计&lt;BR&gt;Author ：maigan&lt;BR&gt;From : 第八军团－信息安全小组（&lt;A href="http://www.cnhacking.com"&gt;www.cnhacking.com&lt;/A&gt; &lt;A href="http://www.juntuan.org"&gt;www.juntuan.org&lt;/A&gt;)&lt;BR&gt;Mail : &lt;A href="mailto:maigan@maigan.com"&gt;maigan@maigan.com&lt;/A&gt;&lt;BR&gt;Warning: 转载本文请注明作者及出处&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;整天在网上转，也看到许多不错的文章，但我发现大多文章要么只停留在理论上，要么就是太高深。对问题详细分析介绍的很少。今天，我就想以数据包分析程序为主题和大家讨论一下网络编程的的相关问题，我也是新手，有不到之处，还望大家不吝指正。&lt;BR&gt;通过对数据包的分析，我们可以判断通信双方的操作系统、网络信息流量、经过的路由、数据包的大小，以及数据包的内容等等。对于喜欢网络安全的人来说，掌握这方面的知识是相当重要的。现在的网络通信中，大部分数据都没有加密，我们可以轻易地从数据包中提取账号、密码之类我们关心的数据.大家在看本文时如有困难，可先读一读计算机网络及C程序设计还有协议分析方面的书。下面我将分TCP/IP族协议结构、程序部分函数及数据结构说明、案例程序剖析三个部分与大家共同学习数据包分析程序的设计方法。&lt;/P&gt;
&lt;P&gt;一、TCP/IP族协议结构&lt;BR&gt;在说TCP/IP之前，先让我们来认识一下以太网，因为我们现在接触最多的就是以太网，并且研究数据包又是离不开以太网的帧的。在以太网中，数据是以被称为帧的数据结构本为单位进行交换的。以太网中常用的协议是CSMA/CD(carrier sense multiple access with collision detection)即载波监听多点接入/碰撞检测，在这里，我们关注的是帧的格式。常用的以太网帧的格式有两种标准，一种是DIX Ethernet V2标准，另一种是IEEE的802.3标准。现在最常用的MAC帧是V2格式，这也是我们所要研究的格式，至于802.3帧我们不再讨论。以太网V2帧的格式如下：&lt;BR&gt;(插入8字节）目的地址（6字节）-&amp;gt;源地址(6字节)-&amp;gt;类型(2字节)-&amp;gt;数据(46-1500)-&amp;gt;FCS(4字节)&lt;BR&gt;以太网的地址由48位的二进制来表示,也就是我们常说的MAC地址及硬件地址。在MAC帧前还有8字节的前同步码和帧的开始定界符，之后才是地址等报头信息。接收端和发送端的地址之后是2字节的类型字段，存放帧中传送数据的上层协议类型，RFC1700号文档规定了这些，如下：&lt;BR&gt;ETHER TYPES(十六进制) PROTOCOlS&lt;BR&gt;800 IP&lt;BR&gt;806 ARP&lt;BR&gt;8035 Revese ARP&lt;BR&gt;809B Apple Talk&lt;BR&gt;8137/8138 Novel&lt;BR&gt;814c SNMP&lt;BR&gt;帧的数据部分长度为46－1500字节，当小于46时，会在后面加入一个整数字节的填充字段。FCS(Frame Check Sequence)在以太网常用循环冗佘校检(CRC:cyclic redandancy check)。&lt;BR&gt;IP协议为网络层协议，网络层的数据结构体被称为IP数据报。IP地址及域名这两个概念我们就不说了，下面我们来看一看IP数据报的结构：&lt;BR&gt;成员名 字节数 说明&lt;BR&gt;version 1/2 IP的版本，现在为IPV4&lt;BR&gt;IHL(报送长度) 1/2 最常用为20，取5－15之前的值，最大60字节&lt;BR&gt;Type Of Service 1 优先和可靠性服务要求的数值&lt;BR&gt;Total Lenth 2 IP数据报的全长&lt;BR&gt;Identification 2 识别IP数据报的编号&lt;BR&gt;Flags 3/8 1位为0表示有碎块，2位为0表示是最后的碎块，为1表示接收中。&lt;BR&gt;Fragment Offset 13/8 分片在原分组中的位置&lt;BR&gt;TTL 1 数据报寿命，建议值为32秒&lt;BR&gt;Protocol 1 上层协议&lt;BR&gt;Headerchecksum 2 报头检验码&lt;BR&gt;Source Address 4 发送端IP地址&lt;BR&gt;Destination Address 4 接收端IP地址&lt;BR&gt;Options And Padding 4 选项及填充位&lt;BR&gt;其中协议字段的值对我们分析数据包是很重要的，下面列出来给大家看看：&lt;BR&gt;值 协议 意义&lt;BR&gt;1 ICMP Internet Control Message Protocol&lt;BR&gt;6 TCP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Tranfer Control Protocol&lt;BR&gt;8 EGP Exterior Gateway Protocol&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 9 IGP Interior Gateway Protocol&lt;BR&gt;17 UDP User Datagram Protocol&lt;BR&gt;下面这些协议的值在后面的程序中我们可以见到，请大家留心记一下。接着我们介绍地址解析协议(ARP/RARP):&lt;BR&gt;成员名 字节数 说明&lt;BR&gt;Hardware address 2 硬件类型，以太网为1&lt;BR&gt;Protocol address 2 上层协议类型，IP为800&lt;BR&gt;Byte length of each hardware 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 查询物理地址的字节长度，以太网为6&lt;BR&gt;Byte length of each protocol address 1 查询上层协议的字节长度，IPv4时为4&lt;BR&gt;Opcode 2 1为ARP请求，2为响应；3为RARP请求，4为响应&lt;BR&gt;Hardware address of sender of this packet 6 发送端硬件地址&lt;BR&gt;protocol address of sender of this packet 4 发送端IP地址&lt;BR&gt;Hardware address of target of this packet 6 查询对象硬件地址&lt;BR&gt;Protocol address of target of this packet 4 查询对象IP地址&lt;BR&gt;ARP/RARP协议用来查询IP对应的硬件地址或反过来查询IP地址，这在我们分析数据包时也会见到。下面介绍ICMP协议。我们常用的PING命令就是用的这个协议，这个协议比较简单，由类型(1字节)、代码(1字节)、检验和(2字节)、还有四个字节的与类型相关的可变部分及数据构成。&lt;BR&gt;数据包在运输层还有两个重要的协议，即TCP/UDP，TCP/UDP中使用端口的概念，以区别计算机上不同的程序。下面我们先来看看TCP数据报的首部构成：&lt;BR&gt;成员名 字节数 说明&lt;BR&gt;Source Port 2 发送端端口号&lt;BR&gt;Destination Port 2 接收端端口号&lt;BR&gt;Sequence NO 4 本报文段所发送的第一个字节的序号&lt;BR&gt;ACk Number 4 期望收到的下一个报文段的序号&lt;BR&gt;DAta Offset 1/2 首部的长度&lt;BR&gt;Reserved 3/4 保留今后用&lt;BR&gt;Contol Bits 3/4 控制位&lt;BR&gt;Window 2 滑动窗口的大小&lt;BR&gt;Checksum 2 检验和&lt;BR&gt;Urgent Pointer 2 紧急指针&lt;BR&gt;Options And Padding 4 可选，真充项&lt;BR&gt;Tcp被使用在跨越路由器进行网络服务的网络应用程序中，如WWW、电子邮件、新闻、FTP等。UDP则是在IP的基础上加入了端口的概念，其结构很简单，只有八个字节首部如下：&lt;BR&gt;源端口(2字节)-&amp;gt;目的端口(2字节)-&amp;gt;长度(2字节)-&amp;gt;检验和(2字节)&lt;/P&gt;
&lt;P&gt;二、程序部分函数及数据结构说明&lt;BR&gt;在此部分我们将介绍后面程序中用到的部分函数及数据结构。在程序中我们使用了PCAP程序库，大家可以从&lt;BR&gt;&lt;A href="ftp://ftp.ee.lbl.gov/libpcap.tar.z"&gt;ftp://ftp.ee.lbl.gov/libpcap.tar.z&lt;/A&gt;下载。我们主要在Redhat Linux下测试程序，这里简单介绍一下程序库的安装方法，其它环境请大家自行解决。我的目的是给大家编写数据包分析程序提供思路，至于实用程序的实现这里不做介绍，第三部分给出的程序也不具实用性，为了演示，程序中实现的功能较多而有些地方又不够详细，编写实用程序时请适当取舍并加入你所需要的功能实现部分。PCAP程序库的安装方法如下：&lt;BR&gt;1、解压文件&lt;BR&gt;2、进入文件目录执行./configure 及make&lt;BR&gt;3、使用Make命令，设定手册和Include文件(要有Root权限)，执行以下命令：&lt;BR&gt;make install -man&lt;BR&gt;make install -incl&lt;BR&gt;4、如出现不存在Include及Include/net目录，则建立此目录并重新执行 make install -incl&lt;BR&gt;5、检查/usr/include/netinet/目录是否存在Protocols.h文件，不存在则拷贝过去。至此程序库安装完毕。&lt;BR&gt;下面介绍程序中出现的部分函数及数据结构：&lt;BR&gt;1、PCAP_t *pd;&lt;BR&gt;此型数据结构称为数据包捕捉描述符。&lt;BR&gt;2、Pcap_Open_Live(argv[1],DEFAUT_SNALEN,1,1000,ebuf)&lt;BR&gt;此函数对Pcap程序库进行初始化并返回指向Pcap_t型数据的指针，其参数列表如下：&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char * 指定网络接口 &lt;BR&gt;int 取得数据的最大字节数 &lt;BR&gt;int 指定网络接口卡，一般用1&lt;BR&gt;int 读出暂停时间&lt;BR&gt;char * 错误消息用缓冲区&lt;BR&gt;3、Pcap_loop(pd,-1,packet_proce,NUll)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 此函数程序的核心，反复执行，利用Pcap取得数据包，返回的是读入数据包的个数，错误时返回－1，其参数列表如下：&lt;BR&gt;Pcap_t * 指定取得数据包的数据包捕捉描述符&lt;BR&gt;int 取得数据包的个数，－1为无限&lt;BR&gt;返回指向函数的指针 指定数据包处理的函数&lt;BR&gt;U_char * 指向赋给数据包处理函数字符串的指针&lt;BR&gt;4、struct ether_header * eth&lt;BR&gt;此结构体存储以太网报头信息，其成员如下：&lt;BR&gt;ether_dhost[6] 接收端的MAC地址&lt;BR&gt;ether_shost[6] 发送端的MAC地址&lt;BR&gt;ether_type 上层协议的种类&lt;BR&gt;5、fflush(stdout)&lt;BR&gt;此函数完成的是强制输出，参数Stdout，强制进行标准输出。&lt;BR&gt;6、noths(((struct ether_header *P)-&amp;gt;ether_type))&lt;BR&gt;此函数将短整型网络字节顺序转换成主机字节顺序。此类函数还有：&lt;BR&gt;ntohl 长整型 功能同上&lt;BR&gt;htons 短整型 将主机字节顺序转换成网络字节顺序&lt;BR&gt;htons 长整型 同上&lt;BR&gt;7、struct IP *iph&lt;BR&gt;ip型结构体在IPh文件中定义，其成员和第一部分讲到的IP数据报结构对应，如下：&lt;BR&gt;成员名 类型 说明&lt;BR&gt;ip_hl 4位无符号整数 报头长度&lt;BR&gt;ip_v 同上 版本，现为4&lt;BR&gt;ip_tos 8位无符号整数 Type of service&lt;BR&gt;ip_len 16位无符号整数 数据报长度&lt;BR&gt;ip_id 同上 标识 &lt;BR&gt;ip_off 同上 数据块偏移和标志&lt;BR&gt;ip_ttl 8位无符号整数 TTL值&lt;BR&gt;ip_p 同上 上层协议&lt;BR&gt;ip_sum 16位无符号整数 检验和&lt;BR&gt;ip_src in_addr结构体 发送端IP&lt;BR&gt;ip_dst 同上 接收端IP&lt;BR&gt;8、struct ether_arp *arph&lt;BR&gt;ether_arp型结构体成员如下：&lt;BR&gt;成员名 类型 说明&lt;BR&gt;ea_hdr arphdr型结构体 报头中地址以外的部分&lt;BR&gt;arp_sha 8位无符号整数数组 发送端MAC地址&lt;BR&gt;arp_spa 同上 发送端IP地址&lt;BR&gt;arp_tha 同上 目标MAC地址&lt;BR&gt;arp_tpa 同上 目标IP地址&lt;BR&gt;9、struct icmphdr * icmp&lt;BR&gt;icmphdr型结构体中包含共用体根据数据报类型的不同而表现不同性质，这里不再列出，只列能通用的三个成员&lt;BR&gt;成员名 说明&lt;BR&gt;type 类型字段&lt;BR&gt;code 代码&lt;BR&gt;checksum 检验和&lt;/P&gt;
&lt;P&gt;三、案例程序剖析&lt;BR&gt;//example.c&lt;BR&gt;//使用方法：example〈网络接口名〉 &amp;gt; 〈输出文件名〉&lt;BR&gt;//例如：example etho &amp;gt; temp.txe&lt;BR&gt;//结束方法：ctrl+c&lt;BR&gt;//程序开始，读入头文件&lt;BR&gt;#include&amp;lt;stdio.h&amp;gt;&lt;BR&gt;#include&amp;lt;sys/types.h&amp;gt;&lt;BR&gt;#include&amp;lt;sys/socket.h&amp;gt;&lt;BR&gt;#include&amp;lt;netinet/in.h&amp;gt;&lt;BR&gt;#include&amp;lt;netinet/in_systm.h&amp;gt;&lt;BR&gt;#include&amp;lt;netinet/ip.h&amp;gt;&lt;BR&gt;#include&amp;lt;netinet/if_ether.h&amp;gt;&lt;BR&gt;#include&amp;lt;pcap.h&amp;gt; //pcap程序库&lt;BR&gt;#include&amp;lt;netdb.h&amp;gt; //DNS检索使用 &lt;BR&gt;#define MAXSTRINGSIZE 256 //字符串长度&lt;BR&gt;#define MAXSIZE 1024 //主机高速缓存中的最大记录条数&lt;BR&gt;#fefine DEFAULT_SNAPLEN 68 /数据包数据的长度&lt;BR&gt;typedef struct&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; unsigned long int ipaddr; //IP地址&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; char hostname[MAXSTRINGSIZE]; //主机名&lt;BR&gt;}dnstable; //高速缓存数据结构&lt;BR&gt;typedef struct &lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dnstable table[MAXSIZE];&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int front;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int rear;&lt;BR&gt;}sequeue; &lt;BR&gt;sequeue *sq; //定义缓存队列&lt;BR&gt;sq-&amp;gt;rear=sq-&amp;gt;front=0; //初始化队列&lt;BR&gt;//输出MAC地址函数&lt;BR&gt;void print_hwadd(u_char * hwadd)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for(int i=0,i&amp;lt;5;++i)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("%2x:",hwadd[i]);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("%2x",hwadd[i]);&lt;BR&gt;}&lt;BR&gt;//输出IP地址的函数&lt;BR&gt;void print_ipadd(u_char *ipadd)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for(int i=0;i&amp;lt;3;++i)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("%d.",ipadd[i]);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("%d",ipadd[i]);&lt;BR&gt;}&lt;BR&gt;//查询端口函数&lt;BR&gt;void getportname(int portno,char portna[],char* proto)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(getservbyport(htons(portno),proto)!=NULL)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strcpy(portna,getservbyport(htons(portno),proto)-&amp;gt;s_name);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sprintf(portna,"%d",portno);&lt;BR&gt;}&lt;BR&gt;//将IP转化为DNS名&lt;BR&gt;void iptohost(unsigned long int ipad,char* hostn)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; struct hostent * shostname;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int m,n,i;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; m=sq-&amp;gt;rear;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; n=sq-&amp;gt;front;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for(i=n%MAXSIZE;i=m%MAXSIZE;i=(++n)%MAXSIZE)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //检查IP是否第一次出现&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(sq-&amp;gt;table[i].ipaddr==ipad)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strcpy(hostn,sq-&amp;gt;table[i].hostname);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(i=m%MAXSIZE)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {//不存在则从域名服务器查询并把结果放入高速缓存&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if((sq-&amp;gt;rear+1)%MAXSIZE=sq-&amp;gt;front) //判队满&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sq-&amp;gt;front=(sq-&amp;gt;front+1)%MAXSIZE; //出队列&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sq-&amp;gt;table[i].ipaddr=ipad;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; shostname=gethostbyaddr((char*)&amp;amp;ipad,sizeof(ipad),AF_INET);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(shostname!=NULL)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strcpy(sq-&amp;gt;table[i].hostname,shostname-&amp;gt;h_name);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strcpy(sq-&amp;gt;table[i].hostname,"");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sq-&amp;gt;rear=(sq-&amp;gt;rear+1)%MAXSIZE;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;BR&gt;void print_hostname(u_char* ipadd)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; unsigned long int ipad;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; char hostn[MAXSTRINTSIZE];&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ipad=*((unsigned long int *)ipadd);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; iptohost(ipad,hostn)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(strlen(hostn)&amp;gt;0)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("%s",hostn);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print_ipadd(ipadd);&lt;BR&gt;}&lt;BR&gt;//处理数据包的函数&lt;BR&gt;void packet_proce(u_char* packets,const struct pcap_pkthdr * header,const u_char *pp)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; struct ether_header * eth; //以太网帧报头指针&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; struct ether_arp * arth; //ARP报头&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; struct ip * iph; //IP报头&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; struct tcphdr * tcph;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; struct udphdr * udph;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; u_short srcport,dstport; //端口号&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; char protocol[MAXSTRINGSIZE]; //协议类型名&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; char srcp[MAXSTRINGSIZE],dstp[MAXSTRINGSIZE]; //端口名&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; unsigned int ptype; //协议类型变量&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; u_char * data; //数据包数据指针&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; u_char tcpudpdata[MAXSTRINGSIZE]; //数据包数据&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int i;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; eth=(struct ether_header *)pp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ptype=ntohs(((struct ether_header *)pp)-&amp;gt;ether_type);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if((ptype==ETHERTYPE_ARP)||(ptype==ETHERTYPE_RARP))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; arph=(struct ether_arp *)(pp+sizeof(struct ether_header));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(ptype==ETHERTYPE_ARP)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("arp ");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("rarp "); //输出协议类型&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print_hwadd((u_char *)&amp;amp;(arph-&amp;gt;arp_sha));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("(");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print_hostname((u_char *)&amp;amp;(arph-&amp;gt;arp_spa));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf(")-&amp;gt;");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print_hwadd((u_char *)&amp;amp;(arph-&amp;gt;arp_tha));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("(");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print_hostname((u_char *)&amp;amp;(arph-&amp;gt;arp_tpa));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf(")\tpacketlen:%d",header-&amp;gt;len);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if(ptype==ETHERTYPE_IP) //IP数据报&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; iph=(struct ip *)(pp+sizeof(struct ether_header));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(iph-&amp;gt;ip_p==1) //ICMP报文&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strcpy(protocol,"icmp");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; srcport=dstport=0;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if(iph-&amp;gt;ip_p==6) //TCP报文&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strcpy(protocol,"tcp");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tcph=(struct tcphdr *)(pp+sizeof(struct ether_header)+4*iph-&amp;gt;ip_hl);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; srcport=ntohs(tcph-&amp;gt;source);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dstport=ntohs(tcph-&amp;gt;dest);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; data=(u_char *)(pp+sizeof(struct ether_header)+4*iph-&amp;gt;ip_hl+4*tcph-&amp;gt;doff);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for(i=0;i&amp;lt;MAXSTRINGSIZE-1;++i)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(i&amp;gt;=header-&amp;gt;len-sizeof(struct ether_header)-4*iph-&amp;gt;ip_hl-4*tcph-&amp;gt;doff);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tcpudpdata[i]=data[i];&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } //TCP数据处理完毕&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if(iph-&amp;gt;ip_p=17) //UDP报文&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strcpy(protocol,"udp");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; udph=(struct udphdr *)(pp+sizeof(struct ether_header)+4*iph-&amp;gt;ip_hl);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; srcport=ntohs(udph-&amp;gt;source);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dstport=ntohs(udph-&amp;gt;dest);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; data=(u_char *)(pp+sizeof(struct ether_header)+4*iph-&amp;gt;ip_hl+8);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for(i=0;i&amp;lt;MAXSTRINGSIZE-1;++i)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(i&amp;gt;=header-&amp;gt;len-sizeof(struct ether_header)-4*iph-&amp;gt;ip_hl-8);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tcpudpdata[i]=data[i];&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tcpudpdata[i]='\0';&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; getportname(srcport,srcp,protocol);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; getportname(dstport,dstp,protocol);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("ip ");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print_hwadd(eth-&amp;gt;ether_shost);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("(");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print_hostname((u_char *)&amp;amp;(iph-&amp;gt;ip_src));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf(")[%s:%s]-&amp;gt;",protocol,srcp);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print_hwadd(eth-&amp;gt;ether_dhost);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("(");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print_hostname((u_char *)&amp;amp;(iph-&amp;gt;ip_dst));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf(")[%s:%s]",protocol,dstp);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("\tttl:%d packetlen:%d,iph-&amp;gt;ttl,header-&amp;gt;len);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("\n");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("%s",tcpudpdata);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("==endpacket==");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("\n");&lt;BR&gt;}&lt;BR&gt;//Main函数取数据包并初始化程序环境&lt;BR&gt;int main(int argc,char ** argv)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; char ebuf[pcap_ERRBUF_SIZE];&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pcap * pd;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(argc&amp;lt;=1) //参数检查&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf("usage:%s&amp;lt;network interface&amp;gt;\n",argv[0]);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit(0);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //设置PCAP程序库&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if((pd=pcap_open_live(argv[1],DEFAULT_SNAPLEN,1,1000,ebuf))=NULL)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (void)fprintf(stderr,"%s",ebuf);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit(1);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //循环取数据包&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //改变参数－1为其它值，可确定取数据包的个数，这里为无限个&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(pcap_loop(pd,-1,packet_proce,NULL)&amp;lt;0)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (void)fprintf(stderr,"pcap_loop:%s\n",pcap_geterr(pd));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit(1);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pcap_colse(pd);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit(0);&lt;BR&gt;}&lt;BR&gt;//程序结束&lt;BR&gt;到此为止，我的这篇文章就写完了，希望能给大家以启发和帮助。平时和网友交流中发现大多数朋友在网上见到长的文章往往都没有信心看下去，其实以前我也是这样，但在这里我想告诉大家，不踏踏实实的深入进去学习，是得不到收获的。一分耕耘，一分收获。&lt;BR&gt;&lt;/P&gt;&lt;img src ="http://blog.vckbase.com/xtdwnuisea/aggbug/875.html" width = "1" height = "1" /&gt;</description></item><item><dc:creator>xtdwnuisea</dc:creator><title>线程结束</title><link>http://blog.vckbase.com/xtdwnuisea/articles/874.html</link><pubDate>Thu, 23 Sep 2004 13:34:00 GMT</pubDate><guid>http://blog.vckbase.com/xtdwnuisea/articles/874.html</guid><wfw:comment>http://blog.vckbase.com/xtdwnuisea/comments/874.html</wfw:comment><comments>http://blog.vckbase.com/xtdwnuisea/articles/874.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blog.vckbase.com/xtdwnuisea/comments/commentRss/874.html</wfw:commentRss><trackback:ping>http://blog.vckbase.com/xtdwnuisea/services/trackbacks/874.html</trackback:ping><description>&lt;P&gt;多线程编程：终止线程&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;导致线程终止的两种正常情况是：控制函数退出或不允许线程完成运行。如果字处理器使用后台打印线程，若成功完成打印，则控制函数将正常终止。但是，如果用户要取消打印，则必须过早终止后台打印线程。此文章解释了如何实现每种情况以及在终止后如何获取退出代码。 &lt;/P&gt;
&lt;P&gt;正常线程终止 &lt;BR&gt;过早的线程终止 &lt;BR&gt;检索线程的退出代码 &lt;BR&gt;正常线程终止&lt;BR&gt;对于辅助线程，正常线程终止很简单：退出控制函数并返回表示终止原因的值。可以使用 AfxEndThread 函数或 return 语句。一般情况下，0 表示成功完成，但这取决于您自己。 &lt;/P&gt;
&lt;P&gt;对于用户界面线程，该过程也很简单：从用户界面线程内调用 Platform SDK 中的 PostQuitMessage。PostQuitMessage 采用的唯一参数是线程的退出代码。对于辅助线程，0 通常表示成功完成。&lt;/P&gt;
&lt;P&gt;过早的线程终止&lt;BR&gt;过早终止线程几乎一样简单：从线程内调用 AfxEndThread。将所需的退出代码作为唯一参数传递。这将停止执行线程、解除对线程堆栈的分配、分离附加到线程的所有 DLL 并从内存中删除线程对象。&lt;/P&gt;
&lt;P&gt;必须从要终止的线程内调用 AfxEndThread。如果要从其他线程终止线程，必须设置两个线程间的通讯方法。&lt;/P&gt;
&lt;P&gt;检索线程的退出代码&lt;BR&gt;若要获取辅助线程或用户界面线程的退出代码，请调用 GetExitCodeThread 函数。有关此函数的信息，请参阅 Platform SDK。此函数获取线程（存储在 CWinThread 对象的 m_hThread 数据成员中）的句柄和 DWORD 的地址。&lt;/P&gt;
&lt;P&gt;如果线程仍然是活动的，GetExitCodeThread 会将 STILL_ACTIVE 放在提供的 DWORD 地址中；否则将退出代码放在此地址中。&lt;/P&gt;
&lt;P&gt;检索 CWinThread 对象的退出代码还需要一步。默认情况下，当 CWinThread 线程终止时，删除该线程对象。这意味着不能访问 m_hThread 数据成员，因为 CWinThread 对象不再存在。若要避免此情况，请执行以下两个操作之一： &lt;/P&gt;
&lt;P&gt;将 m_bAutoDelete 数据成员设置为 FALSE。这使 CWinThread 对象在线程终止后仍可以继续存在。然后可以在线程终止后，访问 m_hThread 数据成员。但是如果使用此技术，您有责任销毁 CWinThread 对象，因为框架不会自动为您删除该对象。这是首选方法。 &lt;BR&gt;&amp;#8212;或&amp;#8212; &lt;/P&gt;
&lt;P&gt;单独存储线程的句柄。创建线程后，（使用 ::DuplicateHandle）将其 m_hThread 数据成员复制到其他变量，并通过该变量访问该成员。这样，终止后即可以自动删除对象，并且仍然可以查出线程终止的原因。请注意：在可以复制句柄之前，线程不终止。执行此操作的最安全的方式是将 CREATE_SUSPENDED 传递到 AfxBeginThread，存储句柄，然后通过调用 ResumeThread 继续执行线程。 &lt;BR&gt;任一方法都可以使您确定 CWinThread 对象终止的原因。&lt;/P&gt;&lt;img src ="http://blog.vckbase.com/xtdwnuisea/aggbug/874.html" width = "1" height = "1" /&gt;</description></item><item><dc:creator>xtdwnuisea</dc:creator><title>打开网页中的HTML</title><link>http://blog.vckbase.com/xtdwnuisea/articles/873.html</link><pubDate>Thu, 23 Sep 2004 13:33:00 GMT</pubDate><guid>http://blog.vckbase.com/xtdwnuisea/articles/873.html</guid><wfw:comment>http://blog.vckbase.com/xtdwnuisea/comments/873.html</wfw:comment><comments>http://blog.vckbase.com/xtdwnuisea/articles/873.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blog.vckbase.com/xtdwnuisea/comments/commentRss/873.html</wfw:commentRss><trackback:ping>http://blog.vckbase.com/xtdwnuisea/services/trackbacks/873.html</trackback:ping><description>&lt;P&gt;BOOL COpenSourceHTMLDlg::OpenSourceHTML()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;UpdateData(TRUE);&lt;BR&gt;&amp;nbsp;CInternetSession session;&lt;BR&gt;&amp;nbsp;CInternetFile* file = NULL;&lt;BR&gt;&amp;nbsp;try&lt;BR&gt;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;// 试着连接到指定URL&lt;BR&gt;&amp;nbsp;&amp;nbsp;file = (CInternetFile*) session.OpenURL(m_strNetAddr); &lt;BR&gt;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;catch (CInternetException* m_pException)&lt;BR&gt;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;// 如果有错误的话，置文件为空&lt;BR&gt;&amp;nbsp;&amp;nbsp;file = NULL; &lt;BR&gt;&amp;nbsp;&amp;nbsp;m_pException-&amp;gt;Delete();&lt;BR&gt;&amp;nbsp;&amp;nbsp;return FALSE;&lt;BR&gt;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;CString strTempLineInf;&lt;BR&gt;&amp;nbsp;m_strSourceHtml = "";&lt;BR&gt;&amp;nbsp;if (file)&lt;BR&gt;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;// 读写网页文件，直到为空&lt;BR&gt;&amp;nbsp;&amp;nbsp;while (file-&amp;gt;ReadString(strTempLineInf) != NULL) //如果采用LPTSTR类型，读取最大个数nMax置0，使它遇空字符时结束&lt;BR&gt;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_strSourceHtml += strTempLineInf;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_strSourceHtml += "\r\n";&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;file-&amp;gt;Close();&lt;BR&gt;&amp;nbsp;&amp;nbsp;delete file;&lt;BR&gt;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;else&lt;BR&gt;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;m_strSourceHtml += _T("到指定服务器的连接建立失败...");&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;return FALSE;&lt;BR&gt;&amp;nbsp;}&lt;/P&gt;
&lt;P&gt;&amp;nbsp;UpdateData(FALSE);&lt;BR&gt;&amp;nbsp;return TRUE;&lt;BR&gt;}&lt;BR&gt;&lt;/P&gt;&lt;img src ="http://blog.vckbase.com/xtdwnuisea/aggbug/873.html" width = "1" height = "1" /&gt;</description></item><item><dc:creator>xtdwnuisea</dc:creator><title>猫的语言</title><link>http://blog.vckbase.com/xtdwnuisea/articles/872.html</link><pubDate>Thu, 23 Sep 2004 13:29:00 GMT</pubDate><guid>http://blog.vckbase.com/xtdwnuisea/articles/872.html</guid><wfw:comment>http://blog.vckbase.com/xtdwnuisea/comments/872.html</wfw:comment><comments>http://blog.vckbase.com/xtdwnuisea/articles/872.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blog.vckbase.com/xtdwnuisea/comments/commentRss/872.html</wfw:commentRss><trackback:ping>http://blog.vckbase.com/xtdwnuisea/services/trackbacks/872.html</trackback:ping><description>&lt;P&gt;猫的语言－AT标准指令&amp;nbsp; &lt;/P&gt;
&lt;P&gt;猫的语言－AT标准指令&amp;nbsp; &lt;BR&gt;〖文章转载或出处〗≡中国电子技术信息网≡ 网址：&lt;A href="http://www.CETINet.com"&gt;www.CETINet.com&lt;/A&gt; &lt;BR&gt;猫的语言－AT标准指令&lt;/P&gt;
&lt;P&gt;众所周知，由Hayes公司创建的Modem AT指令对于Modem的优化设置起着很重要的作用。随着我国信息网络事业的发展，如今购买Modem上Internet和BBS的人越来越多，但烦琐的AT指令使许多用户不能有效的优化自己的Modem，从而导致上网速度慢和不稳定的情况发生，那么如何使用AT命令而优化自己的小猫呢？下面将通过列表方式简单的介绍Modem的AT语言。 &lt;/P&gt;
&lt;P&gt;标准指令： &lt;BR&gt;指令 功 能 &lt;BR&gt;A 送出ANSWER TONE &lt;BR&gt;A/ 重新执行上一个指令。次指令不加前置码 &lt;BR&gt;AT 每个指令之前置码 &lt;BR&gt;B B0＝自动扫描速度，及CCITT低速 &lt;BR&gt;B1＝自动扫描速度，及BELL低速 &lt;BR&gt;D 拨号指令 &lt;BR&gt;DS 选择拨出 内存四组号码 &lt;BR&gt;E E0＝不回应输入字节 &lt;BR&gt;E1＝回应输入字节 &lt;BR&gt;+++ 由资料模式跳回指令模式 &lt;BR&gt;H H0＝MODEM 执行 ON HOOK（一般状态） &lt;BR&gt;H1＝MODEM 执行 OFF HOOK &lt;BR&gt;（举起电话动作） &lt;BR&gt;I I0＝显示产品号码 &lt;BR&gt;I1＝显示CHECKSUM &lt;BR&gt;I2＝内部MEMORY测试 &lt;BR&gt;I3＝显示DEVICE ID &lt;BR&gt;I4＝显示INTERNAL ID &lt;BR&gt;L L1＝小音量 &lt;BR&gt;L2＝中音量 &lt;BR&gt;L3＝大音量 &lt;BR&gt;M M0＝喇叭静音 &lt;BR&gt;M1＝喇叭发声至连线 &lt;BR&gt;M2＝喇叭持续发声 &lt;BR&gt;M3＝条件同M1，但拨号时为静音 &lt;BR&gt;Sr? 读出暂存器r之值（r=0~28） &lt;BR&gt;Sr=n 设定暂存器r之值为n。（r=0~28,n=0~255） &lt;BR&gt;P 脉冲拨号 &lt;BR&gt;T 音频拨号 &lt;BR&gt;Q Q0＝执行指令。回应信息 &lt;BR&gt;Q1＝执行指令。不回应信息 &lt;BR&gt;V V0＝以数字形式。回应信息 &lt;BR&gt;V1＝以文字形式。回应信息 &lt;BR&gt;X X0＝和SMART MODEM 300 相容。连线仅出现 &lt;BR&gt;CONNECT &lt;BR&gt;X1＝连线后会出现连线速率。 &lt;BR&gt;X2＝连线后会出现连线速率。 &lt;BR&gt;并监测DIAL TONE。 &lt;BR&gt;X3＝连线后会出现连线速率。 &lt;BR&gt;并监测BUSY TONE。 &lt;BR&gt;X4＝连线后会出现连线速率。 &lt;BR&gt;并监测DIAL TONE和BUSY TONE。 &lt;BR&gt;Y Y0＝断线前。不送出BREAK信号 &lt;BR&gt;Y1＝断线前。送出4秒BREAK信号 &lt;BR&gt;Z Z0＝RESET 并重新使用第零组参数表。 &lt;BR&gt;Z1＝RESET 并重新使用第壹组参数表。 &lt;/P&gt;
&lt;P&gt;MODEM 延伸指令： &lt;BR&gt;指令 功 能 &lt;BR&gt;&amp;amp;C &amp;amp;C0＝将DCD信号。一直认定为HIGH &lt;BR&gt;&amp;amp;C1＝依据远端送来CARRY信号。实际回应 &lt;BR&gt;&amp;amp;D &amp;amp;D0＝MODEM忽略DTR信号。 &lt;BR&gt;&amp;amp;D1＝当DTR信号变化。MODEM跳至指令模式。 &lt;BR&gt;&amp;amp;D2＝当DTR信号变化。MODEM跳至指令模式。 &lt;BR&gt;并挂线。 &lt;BR&gt;&amp;amp;D3＝当DTR信号变化。MODEM做RESET动作。 &lt;BR&gt;&amp;amp;F &amp;amp;F＝设置V.42BIS模式的出厂设定值。并使用 &lt;BR&gt;RTS／CTS的流程控制。 &lt;BR&gt;&amp;amp;G &amp;amp;G0＝不同GUARD TONE &lt;BR&gt;&amp;amp;G1＝550Hz GUARD TONE &lt;BR&gt;&amp;amp;G2＝1800Hz GUARD TONE　 &lt;BR&gt;&amp;amp;M &amp;amp;M0＝非同步工作模式。 &lt;BR&gt;&amp;amp;O &amp;amp;O0＝关闭Originate-only mode &lt;BR&gt;&amp;amp;O1＝设置Originate-only mode &lt;BR&gt;&amp;amp;P &amp;amp;P0＝OFF-HOOK/ON-HOOK比例 &lt;BR&gt;为39／61。（美制） &lt;BR&gt;&amp;amp;P1＝OFF-HOOK/ON-HOOK比例 &lt;BR&gt;为33／67。（英制，港制） &lt;BR&gt;&amp;amp;S &amp;amp;S0＝DSR信号，设置为ON。 &lt;BR&gt;&amp;amp;S1＝DSR信号，依据RS－232规格。 &lt;BR&gt;&amp;amp;V 显示MODEM参数状态表 &lt;BR&gt;&amp;amp;W &amp;amp;W0＝将目前所用参数，存放在参数表0。 &lt;BR&gt;&amp;amp;W1＝将目前所用参数，存放在参数表1。 &lt;BR&gt;&amp;amp;Y &amp;amp;Y0＝当POWER ON 时，取用参数表0的参数 &lt;BR&gt;&amp;amp;Y1＝当POWER ON 时，取用参数表1的参数 &lt;BR&gt;&amp;amp;Z &amp;amp;Zn＝设置各组电话号码 &lt;BR&gt;%C %C0＝关闭MNP5，V.42BIS的资料压缩模式 &lt;BR&gt;%C1＝启动MNP5，V.42BIS的资料压缩模式 &lt;BR&gt;%D %D0＝关闭CLEAR－DOWN信号 &lt;BR&gt;%D1＝开启CLEAR－DOWN信号 &lt;BR&gt;%E %E0＝关闭V.22BIS AUTO-RETRAIN &lt;BR&gt;%E1＝开启V.22BIS AUTO-RETRAIN &lt;BR&gt;\A \A0＝MNP BLOCK容量。最大 64字节。 &lt;BR&gt;\A1＝MNP BLOCK容量。最大128字节。 &lt;BR&gt;\A2＝MNP BLOCK容量。最大192字节。 &lt;BR&gt;\A3＝MNP BLOCK容量。最大512字节。 &lt;BR&gt;%C %C0＝关闭MNP CLASS5 资料压缩 &lt;BR&gt;%C1＝开启MNP CLASS5 资料压缩 &lt;BR&gt;\G \G0＝关闭DCE流程控制 &lt;BR&gt;\G1＝开启DCE流程控制 &lt;BR&gt;\J \J0＝关闭串口至MODEM之间速率调整 &lt;BR&gt;\J1＝开启串口至MODEM之间速率调整 &lt;BR&gt;\N \N0＝只能联结在普通模式。 &lt;BR&gt;\N1＝只能联结在直接模式。 &lt;BR&gt;\N2＝只能联结在MNP模式。 &lt;BR&gt;\N3＝自动联结在普通 MNP ／V.42模式。 &lt;BR&gt;\N4＝只能联结在V.42模式。 &lt;BR&gt;\Q \Q0＝关闭流程控制 &lt;BR&gt;\Q1＝使用Xon/Xoff流程控制 &lt;BR&gt;\Q2＝使用CTS单向硬件流程控制 &lt;BR&gt;\Q3＝使用CTS／RTS双向硬件流程控制 &lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&lt;BR&gt;郑重声明&lt;BR&gt;&amp;nbsp;&amp;nbsp; 近年来我站数百篇&amp;#8220;原创文章&amp;#8221;被一些媒体肆意转载，不但不标明出自&amp;#8220;中国电子技术信息网&amp;#8221;，而且把相关字眼删除！这是无视技术价值的盗窃行为，是对技术人员辛勤劳动的蔑视，我对此种行为表示强烈的谴责。&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;#8220;本是同根生，相煎何太急&amp;#8221;，考虑到我们做技术的都是同门兄弟，对以前的盗窃行为不再追究，今后再有此类事件，最低处理限度是&amp;#8220;明示于天下&amp;#8221;。在这里向转载过又标注了出处的兄弟媒体表示崇高的敬意！&lt;BR&gt;&amp;nbsp;&amp;nbsp; 兄弟网站如果引用本站&amp;#8220;原创文章&amp;#8221;，请首先经本人许可，并标注&amp;#8220;www.cetinet.com&amp;#8221;或&amp;#8220;中国电子技术信息网&amp;#8221;字样。&lt;BR&gt;&amp;nbsp;&amp;nbsp; 欢迎个人下载使用！ &lt;BR&gt;&lt;/P&gt;&lt;img src ="http://blog.vckbase.com/xtdwnuisea/aggbug/872.html" width = "1" height = "1" /&gt;</description></item></channel></rss>