以下程序代码是 基于 WinPcap 的 , 实现 对网络中 UDP 数据的捕获与分析 。 #include "stdafx.h" #include "..\..\..\Include\pcap.h" 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; pcap_if_t *d; int inum; int i=0; pcap_t *adhandle; char errbuf[PCAP_ERRBUF_SIZE]; u_int netmask; char packet_filter[] = "ip and udp"; struct bpf_program fcode; /* 获取设备列表 */ if( ________ 1 __________ (&alldevs, errbuf) == -1) { fprintf(stderr,"pcap_findalldevs 函数调用错误 : %s\n", errbuf); return 1;; } for(d=alldevs; d; d=d->next) { printf("%d. %s", ++i, d->name); if (d->description) printf(" (%s)\n", d->description); else printf(" ( 没有可用的描述符 )\n"); } if(i==0) { printf("\n 无法找到网络接口 ! 请确认 WinPcap 已正确安装 .\n"); return -1; } printf(" 请待捕获数据的输入网卡编号 (1-%d):",i); scanf("%d", &inum); if(inum < 1 || inum > i) { printf("\nAdapter number out of range.\n"); pcap_freealldevs(alldevs); return -1; } for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); /* 打开网卡 */ adhandle= ________ 2 __________ (d->name, 65536, 1, 1000, errbuf ); if ( adhandle == NULL) { fprintf(stderr,"\n 无法打开网络适配器 . WinPcap 不支持 %s \n", d->name); // 释放设备列表 ________ 3 __________ (alldevs); return -1; } if(pcap_datalink(adhandle) != DLT_EN10MB) { fprintf(stderr,"\n 本在以太网环境下可用 .\n"); pcap_freealldevs(alldevs); return -1; } if(d->addresses != NULL) netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr; else netmask=0xffffff; // 编译过滤器 if ( ________ 4 __________ (adhandle, &fcode, packet_filter, 1, netmask) <0 ) { fprintf(stderr,"\n 无法编译过滤规则,请检查语法的正确性 .\n"); pcap_freealldevs(alldevs); return -1; } // 设置过滤器 if ( ________ 5 __________ (adhandle, &fcode)<0) { fprintf(stderr,"\n 设置过滤器错误 .\n"); pcap_freealldevs(alldevs); return -1; } printf("\nlistening on %s...\n", d->description); pcap_freealldevs(alldevs); /* 开始流量捕获 */ ________ 6 __________ (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 timestr[16]; ip_header *ih; udp_header *uh; 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:%d ", timestr, header->ts.tv_usec, header->len); ih = (ip_header *) (pkt_data + 14); // 以太网头部长度 ip_len = (ih->ver_ihl & 0xf) * 4; uh = (udp_header *) ((u_char*)ih + ip_len); sport = ntohs( uh->sport ); dport = ntohs( uh->dport ); 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); }