网络编程课程设计-基于WinPcap技术的网络-数据包捕获过滤和分析技术_第1页
网络编程课程设计-基于WinPcap技术的网络-数据包捕获过滤和分析技术_第2页
网络编程课程设计-基于WinPcap技术的网络-数据包捕获过滤和分析技术_第3页
网络编程课程设计-基于WinPcap技术的网络-数据包捕获过滤和分析技术_第4页
网络编程课程设计-基于WinPcap技术的网络-数据包捕获过滤和分析技术_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

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

文档简介

网络编程论文学号:4090220姓名:雷诺提交日期:2021.12.10成绩:东北大学秦皇岛分校目录WinPcap概述…………1Winpcap驱动各项功能………………1Winpcap的主要功能……………………1Winpcap网络编程…………2WinPcap获取与网络配置器绑定的设备列表…2获取网络适配器的高级属性信息………………3翻开网络适配器并实现抓包功能………………6不使用事件处理器进行抓包……9过滤数据包………12五、NIC驱动器和NDIS…………17注:与4090225韩雪同学合作完成基于WinPcap技术的网络——数据包捕获,过滤和分析技术[摘要]:在当今的互联网时代里,网络中丰富多彩的各种应用已经彻底改变了人们的工作和生活方式,Internet在给人们带来方便的同时,也给网络管理员带了一些困扰。比方,一些单位的员工在工作期间炒股,玩网络游戏等,面对这些问题,基于WinPcap技术的网络数据包捕获,过滤和分析技术。如果在网络的出口位置对网络中的数据包进行捕获和分析,就可以统计出流量是基于哪些应用的,有了流量便可以成功的进行管理。WinPcap概述:winpcap(windowspacketcapture)是windows平台下一个免费,公共的网络访问系统。

开发winpcap这个工程的目的在于为win32应用程序提供访问网络底层的能力。它提供了以下的各项功能:

1>捕获原始数据报,包括在共享网络上各主机发送/接收的以及相互之间交换的数据报;

2>在数据报发往应用程序之前,按照自定义的规那么将某些特殊的数据报过滤掉;

3>在网络上发送原始的数据报;

4>收集网络通信过程中的统计信息。Winpcap驱动各项功能1>捕获原始数据包:包括在共享网络上各主机发送/接收的以及相互之间交换的数据包;2>在数据包发往应用程序之前,按照自定义的规那么将某些特殊的数据包过滤掉;3>在网络上发送原始的数据包;4>收集网络通信过程中的统计信息。winpcap的主要功能在于独立于主机协议〔如TCP-IP)而发送和接收原始数据包。也就是说,winpcap不能阻塞,过滤或控制其他应用程序数据包的发收,它仅仅只是监听共享网络上传送的数据包。因此,它不能用于QoS调度程序或个人防火墙。目前,winpcap开发的主要对象是windowsNT/2000/XP,这主要是因为在使用winpcap的用户中只有一小局部是仅使用windows95/98/Me,并且MS也已经放弃了对win9x的开发。因此本文相关的程序T-ARP也是面向NT/2000/XP用户的。其实winpcap中的面向9x系统的概念和NT系统的非常相似,只是在某些实现上有点差异,比方说9x只支持ANSI编码,而NT系统那么提倡使用Unicode编码。有个软件叫snifferpro.可以作网管软件用,有很多功能,可监视网络运行情况,每台网内机器的数据流量,实时反映每台机器所访问IP以及它们之间的数据流通情况,可以抓包,可对过滤器进行设置,以便只抓取想要的包,比方POP3包,smtp包,ftp包等,并可从中找到邮箱用户名和密码,还有ftp用户名和密码。它还可以在使用交换机的网络上监听,不过要在交换机上装它的一个软件。还有一个简单的监听软件叫Passwordsniffer,可截获邮箱用户名和密码,还有ftp用户名和密码,它只能用在HUB网络上。著名软件tcpdump及idssnort都是基于libpcap编写的,此外Nmap扫描器也是基于libpcap来捕获目标主机返回的数据包的。winpcap提供应用户两个不同级别的编程接口:一个基于libpcap的wpcap.dll,另一个是较底层的packet.dll。对于一般的要与unix平台上libpcap兼容的开发来说,使用wpcap.dll是当然的选择。winpcap网络编程WinPcap获取与网络配置器绑定的设备列表在开始捕获数据包之前,通常需要获取与网络适配器绑定的设备列表。通俗的说,就是获取当前计算机中安装的网卡列表,这样用户就可以选择在哪块网块上捕获数据包了。代码://FindAllDevs.cpp:定义控制台应用程序的入口点。//#include"stdafx.h"#include"pcap.h"#include"remote-ext.h"#include"stdlib.h"int_tmain(intargc,_TCHAR*argv[]){pcap_if_t*alldevs;pcap_if_t*d;inti=0;charerrbuf[PCAP_ERRBUF_SIZE];/*获取本地机器设备列表*/if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL/*authisnotneeded*/,&alldevs,errbuf)==-1){fprintf(stderr,"Errorinpcap_findalldevs_ex:%s\n",errbuf);exit(1);}/*打印列表*/for(d=alldevs;d!=NULL;d=d->next){printf("\n%d.%s\n",++i,d->name);if(d->description)printf("(%s)\n",d->description);elseprintf("(Nodescriptionavailable)\n");}if(i==0){printf("\nNointerfacesfound!MakesureWinPcapisinstalled.\n");return1;}/*不再需要设备列表了,释放它*/pcap_freealldevs(alldevs); system("pause"); return0;}获取网络适配器的高级属性信息除了网络适配的名称和描述信息外,pcap_if_t结构体中还应包含网络适配器上定义的地址列表,子网掩码列表,播送地址列表和目的地址列表。代码://FindAllDevs.cpp:定义控制台应用程序的入口点。//#include"stdafx.h"#include"pcap.h"#include"remote-ext.h"#include"stdlib.h"//将数字IP地址转换为字符串#defineIPTOSBUFFERS 12char*iptos(u_longin){ staticcharoutput[IPTOSBUFFERS][3*4+3+1]; staticshortwhich; u_char*p; p=(u_char*)∈ which=(which+1==IPTOSBUFFERS?0:which+1); sprintf(output[which],"%d.%d.%d.%d",p[0],p[1],p[2],p[3]); returnoutput[which];}#ifndef__MINGW32__/*Cygnusdoesn'thaveIPv6*/char*ip6tos(structsockaddr*sockaddr,char*address,intaddrlen){ socklen_tsockaddrlen; #ifdefWIN32 sockaddrlen=sizeof(structsockaddr_in6); #else sockaddrlen=sizeof(structsockaddr_storage); #endif if(getnameinfo(sockaddr, sockaddrlen, address, addrlen, NULL, 0, NI_NUMERICHOST)!=0)address=NULL; returnaddress;}#endif/*__MINGW32__*///打印指定接口的信息,参数d指定要打印的接口voidifprint(pcap_if_t*d){pcap_addr_t*a;charip6str[128];//打印名称printf("%s\n",d->name);//打印描述信息if(d->description)printf("\tDescription:%s\n",d->description);//打印环回信息printf("\tLoopback:%s\n",(d->flags&PCAP_IF_LOOPBACK)?"yes":"no");//打印地址信息for(a=d->addresses;a;a=a->next){printf("\tAddressFamily:#%d\n",a->addr->sa_family);switch(a->addr->sa_family){caseAF_INET:printf("\tAddressFamilyName:AF_INET\n");if(a->addr)printf("\tAddress:%s\n",iptos(((structsockaddr_in*)a->addr)->sin_addr.s_addr));if(a->netmask)printf("\tNetmask:%s\n",iptos(((structsockaddr_in*)a->netmask)->sin_addr.s_addr));if(a->broadaddr)printf("\tBroadcastAddress:%s\n",iptos(((structsockaddr_in*)a->broadaddr)->sin_addr.s_addr));if(a->dstaddr)printf("\tDestinationAddress:%s\n",iptos(((structsockaddr_in*)a->dstaddr)->sin_addr.s_addr));break; caseAF_INET6: //IPv6printf("\tAddressFamilyName:AF_INET6\n");#ifndef__MINGW32__/*Cygnusdoesn'thaveIPv6*/if(a->addr)printf("\tAddress:%s\n",ip6tos(a->addr,ip6str,sizeof(ip6str)));#endif break; default:printf("\tAddressFamilyName:Unknown\n");break;}}printf("\n");}int_tmain(intargc,_TCHAR*argv[]){ pcap_if_t*alldevs; //获取的所有网络设备链表 pcap_if_t*d; //指向一个网络设备 charerrbuf[PCAP_ERRBUF_SIZE+1]; //错误缓冲区 //获取网络设备列表 if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&alldevs,errbuf)==-1) { fprintf(stderr,"Errorinpcap_findalldevs:%s\n",errbuf); exit(1); } //打印每个网络设备的信息 for(d=alldevs;d;d=d->next) { ifprint(d); } //释放网络设备链表 pcap_freealldevs(alldevs); system("pause"); return0;}翻开网络适配器并实现抓包功能要获得网络适配器绑定的设备列表后,可以要求用户选择一个设备用于捕获数据包。在捕获数据包之前,还需要翻开设备。代码://pcap_loop.cpp:定义控制台应用程序的入口点。//#include"stdafx.h"#include"pcap.h"#include"remote-ext.h"#include"stdlib.h"/*packethandler函数原型*/voidpacket_handler(u_char*param,conststructpcap_pkthdr*header,constu_char*pkt_data);int_tmain(intargc,_TCHAR*argv[]){ pcap_if_t*alldevs; //获取到的设备列表 intinum; inti=0; pcap_t*adhandle; charerrbuf[PCAP_ERRBUF_SIZE];/*获取本机设备列表*/if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&alldevs,errbuf)==-1){fprintf(stderr,"Errorinpcap_findalldevs:%s\n",errbuf);exit(1);}/*打印设备列表*/ pcap_if_t*d;for(d=alldevs;d;d=d->next){printf("%d.%s",++i,d->name);if(d->description)printf("(%s)\n",d->description);elseprintf("(没有有效的描述信息)\n");} //如果没有找到网络适配器if(i==0){printf("\n未发现网络接口!请确定WinPcap被正确安装。\n");return-1;}printf("请输入要捕获数据包的网络接口编号(1-%d):",i);scanf("%d",&inum);if(inum<1||inum>i){printf("\n接口编号越界.\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, //读取超时时间NULL, //远程机器验证errbuf //错误缓冲池))==NULL){fprintf(stderr,"\n无法翻开网络适配器。WinPcap不支持%s\n",d->name);/*释放设备列表*/pcap_freealldevs(alldevs);return-1;}printf("\n在%s上启动监听...\n",d->description);/*释放设备列表*/pcap_freealldevs(alldevs);/*开始捕获*/pcap_loop(adhandle,0,packet_handler,NULL);return0;}/*每次捕获到数据包时,WinPcap都会自动调用这个回调函数*/voidpacket_handler(u_char*param,conststructpcap_pkthdr*header,constu_char*pkt_data){structtm*ltime;chartimestr[16];time_tlocal_tv_sec;/*将时间戳转换成可识别的格式*/local_tv_sec=header->ts.tv_sec;ltime=localtime(&local_tv_sec);strftime(timestr,sizeoftimestr,"%H:%M:%S",ltime);//打印接收到的数据printf("%s,%.6dlen:%d\n",timestr,header->ts.tv_usec,header->len);}不使用事件处理器进行抓包Pacp_next_ex()函数是基于回调技术来捕获数据的,当数据到达时,系统会自动调用指定的回调函数,处理捕获的数据。但使用回调方式编写的程序可读性不够好,不理解这种编程思想的人很难解程序的运行轨迹。代码://pcap_next_ex.cpp:定义控制台应用程序的入口点。//#include"stdafx.h"#include"pcap.h"#include"remote-ext.h"#include"stdlib.h"int_tmain(intargc,_TCHAR*argv[]){ pcap_if_t*alldevs; //获取的设备列表 pcap_if_t*d; //用于遍历设备列表 intinum; //用户选择的用于监听的 inti=0; pcap_t*adhandle; //翻开设备后返回的WinPcap会话句柄 charerrbuf[PCAP_ERRBUF_SIZE]; structtm*ltime; //读取数据包的时间 chartimestr[16]; structpcap_pkthdr*header; //数据包头 constu_char*pkt_data; //数据包内容/*获取本机设备列表*/if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&alldevs,errbuf)==-1){fprintf(stderr,"Errorinpcap_findalldevs:%s\n",errbuf);exit(1);}/*打印列表*/for(d=alldevs;d;d=d->next){printf("%d.%s",++i,d->name);if(d->description)printf("(%s)\n",d->description);elseprintf("(Nodescriptionavailable)\n");}if(i==0){printf("\nNointerfacesfound!MakesureWinPcapisinstalled.\n");return-1;}printf("Entertheinterfacenumber(1-%d):",i);scanf("%d",&inum);if(inum<1||inum>i){printf("\nInterfacenumberoutofrange.\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,//读取超时时间NULL,//远程机器验证errbuf//错误缓冲池))==NULL){fprintf(stderr,"\nUnabletoopentheadapter.%sisnotsupportedbyWinPcap\n",d->name);/*释放设列表*/pcap_freealldevs(alldevs);return-1;}printf("\nlisteningon%s...\n",d->description);/*释放设备列表*/pcap_freealldevs(alldevs);/*获取数据包*/ intres; while((res=pcap_next_ex(adhandle,&header,&pkt_data))>=0){if(res==0)/*超时时间到*/continue;/*将时间戳转换成可识别的格式*/time_tlocal_tv_sec=header->ts.tv_sec;ltime=localtime(&local_tv_sec);strftime(timestr,sizeoftimestr,"%H:%M:%S",ltime);printf("%s,%.6dlen:%d\n",timestr,header->ts.tv_usec,header->len);}if(res==-1){printf("Errorreadingthepackets:%s\n",pcap_geterr(adhandle));return-1;} return0;}过滤数据包NFS模块中德数据包过滤引擎是WinPcap最强大的功能之一,它可以提供有效的方法获取网络中具有特性的数据包,这也是WinPcap数据包捕获机制的一个组成局部。可以通过调用Pcap_compile()和pcap_setfilter函数来实现过滤数据包的功能。代码://UDPdump.cpp:定义控制台应用程序的入口点。//#include"stdafx.h"#include"pcap.h"#include"remote-ext.h"/*4字节的IP地址*/typedefstructip_address{u_charbyte1;u_charbyte2;u_charbyte3;u_charbyte4;}ip_address;/*IPv4首部*/typedefstructip_header{u_charver_ihl;//版本(4bits)+首部长度(4bits)u_chartos;//效劳类型(Typeofservice)u_shorttlen;//总长(Totallength)u_shortidentification;//标识(Identification)u_shortflags_fo;//标志位(Flags)(3bits)+段偏移量(Fragmentoffset)(13bits)u_charttl;//存活时间(Timetolive)u_charproto;//协议(Protocol)u_shortcrc;//首部校验和(Headerchecksum)ip_addresssaddr;//源地址(Sourceaddress)ip_addressdaddr;//目的地址(Destinationaddress)u_intop_pad;//选项与填充(Option+Padding)}ip_header;/*UDP首部*/typedefstructudp_header{u_shortsport;//源端口(Sourceport)u_shortdport;//目的端口(Destinationport)u_shortlen;//UDP数据包长度(Datagramlength)u_shortcrc;//校验和(Checksum)}udp_header;/*回调函数原型*/voidpacket_handler(u_char*param,conststructpcap_pkthdr*header,constu_char*pkt_data);int_tmain(intargc,_TCHAR*argv[]){ pcap_if_t*alldevs; pcap_if_t*d; intinum; inti=0; pcap_t*adhandle; charerrbuf[PCAP_ERRBUF_SIZE]; u_intnetmask; charpacket_filter[]="ipandudp"; structbpf_programfcode;/*获得设备列表*/if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&alldevs,errbuf)==-1){fprintf(stderr,"Errorinpcap_findalldevs:%s\n",errbuf);exit(1);}/*打印列表*/for(d=alldevs;d;d=d->next){printf("%d.%s",++i,d->name);if(d->description)printf("(%s)\n",d->description);elseprintf("(Nodescriptionavailable)\n");}if(i==0){printf("\nNointerfacesfound!MakesureWinPcapisinstalled.\n");return-1;}printf("Entertheinterfacenumber(1-%d):",i);scanf("%d",&inum);if(inum<1||inum>i){printf("\nInterfacenumberoutofrange.\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,//读取超时时间NULL,//远程机器验证errbuf//错误缓冲池))==NULL){fprintf(stderr,"\nUnabletoopentheadapter.%sisnotsupportedbyWinPcap\n");/*释放设备列表*/pcap_freealldevs(alldevs);return-1;}/*检查数据链路层,为了简单,我们只考虑以太网*/if(pcap_datalink(adhandle)!=DLT_EN10MB){fprintf(stderr,"\nThisprogramworksonlyonEthernetnetworks.\n");/*释放设备列表*/pcap_freealldevs(alldevs);return-1;}if(d->addresses!=NULL)/*获得接口第一个地址的掩码*/netmask=((structsockaddr_in*)(d->addresses->netmask))->sin_addr.S_un.S_addr;else/*如果接口没有地址,那么我们假设一个C类的掩码*/netmask=0xffffff;//编译过滤器if(pcap_compile(adhandle,&fcode,packet_filter,1,netmask)<0){fprintf(stderr,"\nUnabletocompilethepacketfilter.Checkthesyntax.\n");/*释放设备列表*/pcap_freealldevs(alldevs);return-1;}//设置过滤器if(pcap_setfilter(adhandle,&fcode)<0){fprintf(stderr,"\nErrorsettingthefilter.\n");/*释放设备列表*/pcap_freealldevs(alldevs);return-1;}printf("\nlisteningon%s...\n",d->description);/*释放设备列表*/pcap_freealldevs(alldevs);/*开始捕捉*/pcap_loop(adhandle,0,packet_handler,NULL); return0;}/*回调函数,当收到每一个数据包时会被libpcap所调用*/voidpacket_handler(u_char*param,conststructpcap_pkthdr*header,constu_char*pkt_data){structtm*ltime;chartimestr[16];ip_header*ih;udp_header*uh;u_intip_len;u_shortsport,dport;time_tlocal_tv_sec;/*将时间戳转换成可识别的格式*/local_tv_sec=header->ts.tv_sec;ltime=localtime(&local_tv_sec);strftime(timestr,sizeoftimestr,"%H:%M:%S",ltime);/*打印数据包的时间戳和长度*/printf("%s.%.6dlen:%d",timestr,header->ts.tv_usec,header->len);/*获得IP数据包头部的位置*/ih=(ip_header*)(pkt_data+14);//以太网头部长度/*获得UDP首部的位置*/ip_len=(ih->ver_ihl&0xf)*4;uh=(udp_header*)((u_char*)ih+ip_len);/*将网络字节序列转换成主机字节序列*/sport=ntohs(uh->sport);dport=ntohs(uh->dport);/*打印IP地址和UDP端口*/printf("%d.%d.%d.%d.%d->%d.%d.%d.%d.%d\n",ih->saddr.byte1,ih->saddr.byte2,ih->saddr.byte3,ih->saddr.byte4,sport,ih->daddr.byte1,ih->daddr.byte2,ih->daddr.byte3,ih->daddr.byte4,dport);}五、NIC驱动器和NDISNPF和NDISNDIS〔NetworkDriverInterfaceSpecification〕是一个定义网络适配器〔或者说成是管理网络适配器的驱动程序〕与协议驱动〔例如TCP/IP的实现〕之间通信的标准。NDIS最主要的目的是作为一个允许协议驱动发送和接收网络〔LAN或WAN〕上的数据包而不必关心特定的适配器或特定的Win32操作系统的封装。NDIS支持三种类型的网络驱动:网络接口卡或NIC驱动〔NetworkinterfacecardorNICdrivers〕。NIC驱动直接管理着网络接口卡〔NIC〕。NIC驱动接下边与硬件连接,从上边表现为一个接口,该接口允许高层发送数据包到网络上,处理中断,重置NIC,停止NIC,查询和设置驱动的运行特征。NIC驱动可以是小端口〔miniport〕或完全的NIC驱动〔fullNICdriver〕。Miniport驱动仅仅实现了管理NIC的必要操作,包括在NIC上发送和接收数据。对于所有最底层的NIC驱动的操作由NDIS提供,例如同步〔syn

温馨提示

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

评论

0/150

提交评论