《使用wincap编制一个简单的网络数据包监听与捕获程序》由会员分享,可在线阅读,更多相关《使用wincap编制一个简单的网络数据包监听与捕获程序(7页珍藏版)》请在金锄头文库上搜索。
1、一、 实验目的复习计算机网络课程相关知识,采用合适的程序开发语言完成网络程序开发。二、实验环境微机一台操作系统:WinXP / Linux编程软件:C+二、实验内容要求使用Wincap编制一个简单的网络数据包监听与捕获程序,同时,将捕获的数据包进行分析并将分析结果显示在屏幕上。三、 实验步骤、记录和结果代码如下:#include pcap.htypedef structint number;char name10;Protocol;Protocol protocol10;/* 4字节的IP地址 */typedef struct ip_addressu_char byte1;u_char byt
2、e2;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) + 段偏移量(Fragment offset) (
3、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, const struct pc
4、ap_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; strcpy(protocol0.name, ICMP);protoc
5、ol1.number = 2; strcpy(protocol1.name, IGMP);protocol2.number = 4; strcpy(protocol2.name, IP);protocol3.number = 6; strcpy(protocol3.name, TCP);protocol4.number = 8; strcpy(protocol4.name, EGP);protocol5.number = 9; strcpy(protocol5.name, IGP);protocol6.number = 17; strcpy(protocol6.name, UDP);proto
6、col7.number = 41; strcpy(protocol7.name, IPv6);protocol8.number = 50; strcpy(protocol8.name, ESP);protocol9.number = 89; strcpy(protocol9.name, OSPF);/* 获得设备列表 */if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) = -1)fprintf(stderr,Error in pcap_findalldevs: %sn, errbuf);exit(1);/*
7、 打印列表 */for(d=alldevs; d; d=d-next)printf(%d. %s, +i, d-name);if (d-description)printf( (%s)n, 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
8、 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_PROMISCUOUS, / 混杂模式1000, / 读取超时时间NULL, / 远程机器验证e
9、rrbuf / 错误缓冲池) ) = 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 Ethernet networks.n);/* 释放设备列表 */pcap_fr
10、eealldevs(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, packet_filter, 1, netmask) 0 )fprintf(stderr,nUnable to compile th
11、e 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, NULL);return 0;/* 回调函数,当收到每一个数据包时会被libpcap所调用 */void packet_handler(u_cha
12、r *param, const struct pcap_pkthdr *header, const u_char *pkt_data)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:%4d , timestr, header-ts.tv_usec, header-len);/* 获得IP数据包头部的位置 */ih = (ip_header *) (pkt_data +14); /以太网头部长度/*打印协议类型*/int i;for(i = 0; i proto)break;if(i = 9)printf(%5s , protocoli.name);elseprintf(%5s , Other);/* 打印