使用Wincap编制一个简单的网络数据包监听与捕获程序_第1页
使用Wincap编制一个简单的网络数据包监听与捕获程序_第2页
使用Wincap编制一个简单的网络数据包监听与捕获程序_第3页
使用Wincap编制一个简单的网络数据包监听与捕获程序_第4页
使用Wincap编制一个简单的网络数据包监听与捕获程序_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、一、 实验目的复习计算机网络课程相关知识,采用合适的程序开发语言完成网络程序开发。二、实验环境微机一台操作系统:WinXP / Linux编程软件:C+二、实验内容要求使用Wincap编制一个简单的网络数据包监听与捕获程序,同时,将捕获的数据包进行分析并将分析结果显示在屏幕上。三、 实验步骤、记录和结果代码如下:#include "pcap.h"typedef structint number;char name10;Protocol;Protocol protocol10;/* 4字节的IP地址 */typedef struct ip_addressu_char byte

2、1;u_char byte2;u_char byte3;u_char byte4;ip_address;/* IPv4 首部 */typedef struct ip_headeru_char ver_ihl; / 版本 (4 bits) + 首部长度 (4 bits)u_char tos; / 服务类型(Type of service) u_short tlen; / 总长(Total length) u_short identification; / 标识(Identification)u_short flags_fo; / 标志位(Flags) (3 bits) + 段偏移量(Fragme

3、nt offset) (13 bits)u_char ttl; / 存活时间(Time to live)u_char proto; / 协议(Protocol)u_short crc; / 首部校验和(Header checksum)ip_address saddr; / 源地址(Source address)ip_address daddr; / 目的地址(Destination address)u_int op_pad; / 选项与填充(Option + Padding)ip_header;/* 回调函数原型 */void packet_handler(u_char *param, con

4、st struct pcap_pkthdr *header, const u_char *pkt_data);int main()pcap_if_t *alldevs;pcap_if_t *d;int inum;int i=0;pcap_t *adhandle;char errbufPCAP_ERRBUF_SIZE;u_int netmask;/char packet_filter = "ip and udp"char packet_filter = "ip"struct bpf_program fcode;protocol0.number = 1; s

5、trcpy(, "ICMP");protocol1.number = 2; strcpy(, "IGMP");protocol2.number = 4; strcpy(, "IP");protocol3.number = 6; strcpy(, "TCP");protocol4.number = 8; strcpy(, "EGP");protocol5.nu

6、mber = 9; strcpy(, "IGP");protocol6.number = 17; strcpy(, "UDP");protocol7.number = 41; strcpy(, "IPv6");protocol8.number = 50; strcpy(, "ESP");protocol9.number = 89; strcpy(, "OSPF&quo

7、t;);/* 获得设备列表 */if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) = -1)fprintf(stderr,"Error in pcap_findalldevs: %sn", errbuf);exit(1);/* 打印列表 */for(d=alldevs; d; d=d->next)printf("%d. %s", +i, d->name);if (d->description)printf(" (%s)n",

8、 d->description);elseprintf(" (No description available)n");if(i=0)printf("nNo interfaces found! Make sure WinPcap is installed.n");return -1;printf("Enter the interface number (1-%d):",i);scanf("%d", &inum);if(inum < 1 | inum > i)printf("nIn

9、terface number out of range.n");/* 释放设备列表 */pcap_freealldevs(alldevs);return -1;/* 跳转到已选设备 */for(d=alldevs, i=0; i< inum-1 ;d=d->next, i+);/* 打开适配器 */if ( (adhandle= pcap_open(d->name, / 设备名65536, / 要捕捉的数据包的部分 / 65535保证能捕获到不同数据链路层上的每个数据包的全部内容PCAP_OPENFLAG_PROMISCUOUS, / 混杂模式1000, / 读取超

10、时时间NULL, / 远程机器验证errbuf / 错误缓冲池) ) = NULL)fprintf(stderr,"nUnable to open the adapter. %s is not supported by WinPcapn");/* 释放设备列表 */pcap_freealldevs(alldevs);return -1;/* 检查数据链路层,为了简单,我们只考虑以太网 */if(pcap_datalink(adhandle) != DLT_EN10MB)fprintf(stderr,"nThis program works only on Ethe

11、rnet networks.n");/* 释放设备列表 */pcap_freealldevs(alldevs);return -1;if(d->addresses != NULL)/* 获得接口第一个地址的掩码 */netmask=(struct sockaddr_in *)(d->addresses->netmask)->sin_addr.S_un.S_addr;else/* 如果接口没有地址,那么我们假设一个C类的掩码 */netmask=0xffffff; /编译过滤器if (pcap_compile(adhandle, &fcode, pack

12、et_filter, 1, netmask) <0 )fprintf(stderr,"nUnable to compile the packet filter. Check the syntax.n");/* 释放设备列表 */pcap_freealldevs(alldevs);return -1;/设置过滤器if (pcap_setfilter(adhandle, &fcode)<0)fprintf(stderr,"nError setting the filter.n");/* 释放设备列表 */pcap_freealldevs(

13、alldevs);return -1;printf("nlistening on %s.n", d->description);/* 释放设备列表 */pcap_freealldevs(alldevs);/* 开始捕捉 */pcap_loop(adhandle, 0, packet_handler, NULL);return 0;/* 回调函数,当收到每一个数据包时会被libpcap所调用 */void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_d

14、ata)struct tm *ltime;char timestr16;ip_header *ih;u_int ip_len;u_short sport,dport;time_t local_tv_sec;/* 将时间戳转换成可识别的格式 */local_tv_sec = header->ts.tv_sec;ltime=localtime(&local_tv_sec);strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);/* 打印数据包的时间戳和长度 */printf("%s.%.6d len:

15、%4d ", timestr, header->ts.tv_usec, header->len);/* 获得IP数据包头部的位置 */ih = (ip_header *) (pkt_data +14); /以太网头部长度/*打印协议类型*/int i;for(i = 0; i < 10; i+)if(protocoli.number = ih->proto)break;if(i <= 9)printf("%5s ", );elseprintf("%5s ", "Other&qu

16、ot;);/* 打印IP地址 */printf("%d.%d.%d.%d -> %d.%d.%d.%dn",ih->saddr.byte1,ih->saddr.byte2,ih->saddr.byte3,ih->saddr.byte4,ih->daddr.byte1,ih->daddr.byte2,ih->daddr.byte3,ih->daddr.byte4);程序执行结果如下:上面三张图是程序运行的截图,第一列是数据包的时间戳,第二列是数据包的长度,第三列是数据包的协议类型,第四列是数据包的源IP地址和目的IP地址。

17、四、 实验分析 程序执行过程:使用pcap_findalldevs_ex函数获取已连接的网络适配器列表。这个函数返回一个 pcap_if 结构的链表, 每个这样的结构都包含了一个适配器的详细信息。其中数据域name表示适配器名称,但难以理解,如rpcap:/DeviceNPF_7CD080C7-2B67-4839-B6F6-1D90273D960A,另一个数据域description表示一个可以让人们理解的描述,如(Network adapter 'Realtek PCIe FE Family Controller' on local host)。使用pcap_open()函数打开适配器,将这个函数的snaplen参数设为65535,这比能遇到的最大的MTU还要大,以保证能收到完整的数据包。另一个参数flag设为PCAP_OPENFLAG_PROMISCUOUS,意为混杂模式,不管这个数据包是不是发给本机的,都会去捕获。参数to_ms 指定读取数据的超时时间,这里设置为1000ms,在适配器上进行读取操作都会在 to_ms 毫秒时间内响应。使用pcap_compile

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论