版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 网络编程论文学 号:姓 名:雷诺提交日期:2011.12.10成 绩:东北大学秦皇岛分校目录1、 WinPcap概述12、 Winpcap驱动各项功能13、 Winpcap的主要功能14、 Winpcap网络编程21) WinPcap获取与网络配置器绑定的设备列表2 2) 获取网络适配器的高级属性信息33) 打开网络适配器并实现抓包功能64) 不使用事件处理器进行抓包95) 过滤数据包12五、NIC驱动器和NDIS17 注:与韩雪同学合作完成 基于WinPcap技术的网络 数据包捕获,过滤和分析技术摘要:在当今的互联网时代里,网络中丰富多彩的各种应用已经彻底改变了人们的工作和生活方式,Int
2、ernet在给人们带来方便的同时,也给网络管理员带了一些困扰。比如,一些单位的员工在工作期间炒股,玩网络游戏等,面对这些问题,基于WinPcap技术的网络数据包捕获,过滤和分析技术。如果在网络的出口位置对网络中的数据包进行捕获和分析,就可以统计出流量是基于哪些应用的,有了流量便可以成功的进行管理。1、 WinPcap概述:winpcap(windows packet capture)是windows平台下一个免费,公共的网络访问系统。开发winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力。它提供了以下的各项功能:1 捕获原始数据报,包括在共享网络上各主机发送/接收的以及
3、相互之间交换的数据报;2 在数据报发往应用程序之前,按照自定义的规则将某些特殊的数据报过滤掉;3 在网络上发送原始的数据报;4 收集网络通信过程中的统计信息。 2、 Winpcap驱动各项功能1 捕获原始数据包:包括在共享网络上各主机发送/接收的以及相互之间交换的数据包; 2 在数据包发往应用程序之前,按照自定义的规则将某些特殊的数据包过滤掉; 3 在网络上发送原始的数据包; 4 收集网络通信过程中的统计信息。 3、 winpcap的主要功能 在于独立于主机协议(如TCP-IP)而发送和接收原始数据包。也就是说,winpcap不能阻塞,过滤或控制其他应用程序数据包的发收,它仅仅只是监听共享网络
4、上传送的数据包。因此,它不能用于QoS调度程序或个人防火墙。目前,winpcap开发的主要对象是windows NT/2000/XP,这主要是因为在使用winpcap的用户中只有一小部分是仅使用windows 95/98/Me,并且MS也已经放弃了对win9x的开发。因此本文相关的程序T-ARP也是面向NT/2000/XP用户的。其实winpcap中的面向9x系统的概念和NT系统的非常相似,只是在某些实现上有点差异,比如说9x只支持ANSI编码,而NT系统则提倡使用Unicode编码。有个软件叫sniffer pro.可以作网管软件用,有很多功能,可监视网络运行情况,每台网内机器的数据流量,实
5、时反映每台机器所访问IP以及它们之间的数据流通情况,可以抓包,可对过滤器进行设置,以便只抓取想要的包,比如POP3包,smtp包,ftp包等,并可从中找到邮箱用户名和密码,还有ftp用户名和密码。它还可以在使用交换机的网络上监听,不过要在交换机上装它的一个软件。还有一个简单的监听软件叫Passwordsniffer,可截获邮箱用户名和密码,还有ftp用户名和密码,它只能用在HUB网络上。著名软件tcpdump及ids snort都是基于libpcap编写的,此外Nmap扫描器也是基于libpcap来捕获目标主机返回的数据包的。 winpcap提供给用户两个不同级别的编程接口:一个基于libpc
6、ap的wpcap.dll,另一个是较底层的packet.dll。对于一般的要与unix平台上libpcap兼容的开发来说,使用wpcap.dll是当然的选择。4、 winpcap网络编程1. WinPcap获取与网络配置器绑定的设备列表在开始捕获数据包之前,通常需要获取与网络适配器绑定的设备列表。通俗的说,就是获取当前计算机中安装的网卡列表,这样用户就可以选择在哪块网块上捕获数据包了。代码:/ FindAllDevs.cpp : 定义控制台应用程序的入口点。/#include stdafx.h#include pcap.h#include remote-ext.h#include stdlib
7、.hint _tmain(int argc, _TCHAR* argv) pcap_if_t *alldevs; pcap_if_t *d; int i=0; char errbufPCAP_ERRBUF_SIZE; /* 获取本地机器设备列表*/ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL /* auth is not needed */, &alldevs, errbuf) = -1) fprintf(stderr,Error in pcap_findalldevs_ex: %sn, errbuf); exit(1); /* 打印列表*
8、/ for(d= alldevs; d != NULL; d= d-next) printf(n%d. %sn, +i, d-name); if (d-description) printf( (%s)n, d-description); else printf( (No description available)n); if (i = 0) printf(nNo interfaces found! Make sure WinPcap is installed.n); return 1; /* 不再需要设备列表了,释放它*/ pcap_freealldevs(alldevs);system(
9、pause);return 0;2. 获取网络适配器的高级属性信息除了网络适配的名称和描述信息外,pcap_if_t结构体中还应包含网络适配器上定义的地址列表,子网掩码列表,广播地址列表和目的地址列表。代码:/ FindAllDevs.cpp : 定义控制台应用程序的入口点。/#include stdafx.h#include pcap.h#include remote-ext.h#include stdlib.h/ 将数字IP地址转换为字符串#define IPTOSBUFFERS12char *iptos(u_long in)static char outputIPTOSBUFFERS3*
10、4+3+1;static short which;u_char *p;p = (u_char *)∈which = (which + 1 = IPTOSBUFFERS ? 0 : which + 1);sprintf(outputwhich, %d.%d.%d.%d, p0, p1, p2, p3);return outputwhich;#ifndef _MINGW32_ /* Cygnus doesnt have IPv6 */char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen)socklen_t soc
11、kaddrlen;#ifdef WIN32sockaddrlen = sizeof(struct sockaddr_in6);#elsesockaddrlen = sizeof(struct sockaddr_storage);#endifif(getnameinfo(sockaddr, sockaddrlen, address, addrlen, NULL, 0, NI_NUMERICHOST) != 0) address = NULL;return address;#endif /* _MINGW32_ */ 打印指定接口的信息,参数d指定要打印的接口void ifprint(pcap_i
12、f_t *d) pcap_addr_t *a; char ip6str128; / 打印名称 printf(%sn,d-name); / 打印描述信息 if (d-description) printf(tDescription: %sn,d-description); / 打印环回信息 printf(tLoopback: %sn,(d-flags & PCAP_IF_LOOPBACK)?yes:no); / 打印地址信息 for(a=d-addresses;a;a=a-next) printf(tAddress Family: #%dn,a-addr-sa_family); switch(a
13、-addr-sa_family) case AF_INET: printf(tAddress Family Name: AF_INETn); if (a-addr) printf(tAddress: %sn,iptos(struct sockaddr_in *)a-addr)-sin_addr.s_addr); if (a-netmask) printf(tNetmask: %sn,iptos(struct sockaddr_in *)a-netmask)-sin_addr.s_addr); if (a-broadaddr) printf(tBroadcast Address: %sn,ipt
14、os(struct sockaddr_in *)a-broadaddr)-sin_addr.s_addr); if (a-dstaddr) printf(tDestination Address: %sn,iptos(struct sockaddr_in *)a-dstaddr)-sin_addr.s_addr); break; case AF_INET6:/ IPv6 printf(tAddress Family Name: AF_INET6n);#ifndef _MINGW32_ /* Cygnus doesnt have IPv6 */ if (a-addr) printf(tAddre
15、ss: %sn, ip6tos(a-addr, ip6str, sizeof(ip6str);#endifbreak; default: printf(tAddress Family Name: Unknownn); break; printf(n);int _tmain(int argc, _TCHAR* argv)pcap_if_t *alldevs;/ 获取的所有网络设备链表pcap_if_t *d;/ 指向一个网络设备char errbufPCAP_ERRBUF_SIZE+1;/ 错误缓冲区/ 获取网络设备列表if(pcap_findalldevs_ex(PCAP_SRC_IF_STR
16、ING, NULL, &alldevs, errbuf) = -1)fprintf(stderr,Error in pcap_findalldevs: %sn, errbuf);exit(1);/ 打印每个网络设备的信息for(d=alldevs;d;d=d-next)ifprint(d);/ 释放网络设备链表pcap_freealldevs(alldevs);system(pause);return 0;3. 打开网络适配器并实现抓包功能 要获得网络适配器绑定的设备列表后,可以要求用户选择一个设备用于捕获数据包。在捕获数据包之前,还需要打开设备。代码:/ pcap_loop.cpp : 定义
17、控制台应用程序的入口点。/#include stdafx.h#include pcap.h#include remote-ext.h#include stdlib.h/* packet handler 函数原型*/void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);int _tmain(int argc, _TCHAR* argv)pcap_if_t *alldevs;/ 获取到的设备列表int inum;int i=0;pcap_t *adhandle;cha
18、r errbufPCAP_ERRBUF_SIZE; /* 获取本机设备列表*/ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) = -1) fprintf(stderr,Error in pcap_findalldevs: %sn, 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-desc
19、ription); else printf( (没有有效的描述信息)n); / 如果没有找到网络适配器 if(i=0) printf(n未发现网络接口!请确定WinPcap被正确安装。n); return -1; printf(请输入要捕获数据包的网络接口编号(1-%d):,i); scanf(%d, &inum); if(inum i) printf(n接口编号越界.n); /* 释放设备列表*/ pcap_freealldevs(alldevs); return -1; /* 跳转到选中的适配器*/ for(d=alldevs, i=0; inext, i+); /* 打开设备*/ if
20、( (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);
21、/* 释放设备列表*/ pcap_freealldevs(alldevs); /* 开始捕获*/ pcap_loop(adhandle, 0, packet_handler, NULL); return 0;/* 每次捕获到数据包时,WinPcap都会自动调用这个回调函数*/void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) struct tm *ltime; char timestr16; time_t local_tv_sec; /* 将时间戳转换成可识别的
22、格式*/ local_tv_sec = header-ts.tv_sec; ltime=localtime(&local_tv_sec); strftime( timestr, sizeof timestr, %H:%M:%S, ltime); / 打印接收到的数据 printf(%s,%.6d len:%dn, timestr, header-ts.tv_usec, header-len); 4. 不使用事件处理器进行抓包Pacp_next_ex()函数是基于回调技术来捕获数据的,当数据到达时,系统会自动调用指定的回调函数,处理捕获的数据。但使用回调方式编写的程序可读性不够好,不理解这种编程
23、思想的人很难解程序的运行轨迹。代码:/ pcap_next_ex.cpp : 定义控制台应用程序的入口点。/#include stdafx.h#include pcap.h#include remote-ext.h#include stdlib.hint _tmain(int argc, _TCHAR* argv)pcap_if_t *alldevs;/ 获取的设备列表pcap_if_t *d;/ 用于遍历设备列表int inum;/ 用户选择的用于监听的int i=0;pcap_t *adhandle;/ 打开设备后返回的WinPcap会话句柄char errbufPCAP_ERRBUF_S
24、IZE;struct tm *ltime;/ 读取数据包的时间char timestr16;struct pcap_pkthdr *header;/ 数据包头const u_char *pkt_data;/ 数据包内容 /* 获取本机设备列表*/ 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)
25、 printf(%d. %s, +i, d-name); if (d-description) printf( (%s)n, d-description); else printf( (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 i) printf(nInterface nu
26、mber out of range.n); /* 释放设备列表*/ pcap_freealldevs(alldevs); return -1; /* 跳转到已选中的适配器*/ for(d=alldevs, i=0; inext, i+); /* 打开设备*/ if ( (adhandle= pcap_open(d-name, / 设备名 65536, / 要捕捉的数据包的部分 / 65535保证能捕获到不同数据链路层上的每个数据包的全部内容 PCAP_OPENFLAG_PROMISCUOUS, / 混杂模式 1000, / 读取超时时间 NULL, / 远程机器验证 errbuf / 错误缓冲
27、池 ) ) = NULL) fprintf(stderr,nUnable to open the adapter. %s is not supported by WinPcapn, d-name); /* 释放设列表*/ pcap_freealldevs(alldevs); return -1; printf(nlistening on %s.n, d-description); /* 释放设备列表*/ pcap_freealldevs(alldevs); /* 获取数据包*/int res; while(res = pcap_next_ex( adhandle, &header, &pkt_
28、data) = 0) if(res = 0) /* 超时时间到*/ continue; /* 将时间戳转换成可识别的格式*/ time_t local_tv_sec = header-ts.tv_sec; ltime=localtime(&local_tv_sec); strftime( timestr, sizeof timestr, %H:%M:%S, ltime); printf(%s,%.6d len:%dn, timestr, header-ts.tv_usec, header-len); if(res = -1) printf(Error reading the packets:
29、%sn, pcap_geterr(adhandle); return -1; return 0;5. 过滤数据包NFS模块中德数据包过滤引擎是WinPcap最强大的功能之一,它可以提供有效的方法获取网络中具有特性的数据包,这也是WinPcap数据包捕获机制的一个组成部分。可以通过调用Pcap_compile()和pcap_setfilter函数来实现过滤数据包的功能。代码:/ UDPdump.cpp : 定义控制台应用程序的入口点。/#include stdafx.h#include pcap.h#include remote-ext.h/* 4字节的IP地址*/typedef struct
30、ip_address u_char byte1; u_char byte2; u_char byte3; u_char byte4;ip_address;/* IPv4 首部*/typedef struct ip_header u_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; / 标志位(Flag
31、s) (3 bits) + 段偏移量(Fragment 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;/* UDP 首部*/typedef
32、struct udp_header u_short sport; / 源端口(Source port) u_short dport; / 目的端口(Destination port) u_short len; / UDP数据包长度(Datagram length) u_short crc; / 校验和(Checksum)udp_header;/* 回调函数原型*/void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);int _tmain(int argc, _TC
33、HAR* argv)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;struct bpf_program fcode; /* 获得设备列表*/ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) = -1) fprintf(stderr,Error in pcap_findallde
34、vs: %sn, errbuf); exit(1); /* 打印列表*/ for(d=alldevs; d; d=d-next) printf(%d. %s, +i, d-name); if (d-description) printf( (%s)n, d-description); else printf( (No description available)n); if(i=0) printf(nNo interfaces found! Make sure WinPcap is installed.n); return -1; printf(Enter the interface numb
35、er (1-%d):,i); scanf(%d, &inum); if(inum i) printf(nInterface number out of range.n); /* 释放设备列表*/ pcap_freealldevs(alldevs); return -1; /* 跳转到已选设备*/ for(d=alldevs, i=0; inext, i+); /* 打开适配器*/ if ( (adhandle= pcap_open(d-name, / 设备名 65536, / 要捕捉的数据包的部分 / 65535保证能捕获到不同数据链路层上的每个数据包的全部内容 PCAP_OPENFLAG_P
36、ROMISCUOUS, / 混杂模式 1000, / 读取超时时间 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 progra
37、m works only on Ethernet 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, pac
38、ket_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)description); /* 释放设备列表*/ pcap_freealldevs(alldevs); /* 开始捕捉*/ pcap_loop(adhandle, 0, packet_handler, NUL
39、L); return 0;/* 回调函数,当收到每一个数据包时会被libpcap所调用*/void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) struct tm *ltime; char timestr16; ip_header *ih; udp_header *uh; u_int ip_len; u_short sport,dport; time_t local_tv_sec; /* 将时间戳转换成可识别的格式*/ local_tv_sec = header-
40、ts.tv_sec; ltime=localtime(&local_tv_sec); strftime( timestr, sizeof timestr, %H:%M:%S, ltime); /* 打印数据包的时间戳和长度*/ printf(%s.%.6d len:%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
41、_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.%dn, ih-saddr.byte1, ih-saddr.byte2, ih-saddr.byte3, ih-saddr.byte4, sport, ih-daddr.byte1, ih-daddr.byte2, ih-daddr.byte3, ih-daddr.byt
42、e4, dport);五、NIC驱动器和NDIS1) NPF和NDISNDIS(Network Driver Interface Specification)是一个定义网络适配器(或者说成是管理网络适配器的驱动程序)与协议驱动(例如TCP/IP的实现)之间通信的规范。NDIS最主要的目的是作为一个允许协议驱动发送和接收网络(LAN或WAN)上的数据包而不必关心特定的适配器或特定的Win32操作系统的封装。 2) NDIS支持三种类型的网络驱动: a. 网络接口卡或NIC驱动(Network interface card or NIC drivers)。NIC驱动直接管理着网络接口卡(NIC)。NIC驱动接下边与硬件连接,从上边表现为一个接口,该接口允许高层发送数据包到网络上,处理中断,重置NIC,停止NIC,查询和设置驱动的运行特征。NIC驱动可以是小端口(miniport)或完全的NI
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 都市人生规划分析
- 逻辑学课件南邮王青
- 咳嗽病护理查房
- 太阳能光伏板的电池性能
- 事业单位工作人员退休(职)登记表
- 个人职业规划书短款
- 混凝土缺陷的修补方案
- 2020-2021学年人教部编版语文二年级下册-《当世界年级还小的时候》教案
- 2024幼儿园假期安全
- 颈椎病科普课件
- 文本数据可视化
- 发生盗窃应急处理预案
- 前庭性偏头痛课件
- 贺州市钟山县2024年事业单位考试A类《职业能力倾向测验》统考试题含解析
- 沪教版五年级下册简易方程练习100题及答案
- 2024综合知识贵州事业单位刷题
- 《国库集中支付制度》课件
- 装配式混凝土预制构件项目市场研究报告
- 医院智能排班系统的设计与实施
- PDCA降低护士针刺伤发生率
- 劳动标准培训课件
评论
0/150
提交评论