(作者:燕云 出处:http://www.cnblogs.com/SwordTao/ 欢迎转载,但也请保留这段声明,谢谢!)
君不见 黄河之水 天上来 奔流到海不复回
君不见 高堂明镜 悲白发 朝如青丝暮成雪
人生得意须尽欢 莫使金樽空对月
——将进酒
pcap文件格式,为多数的tcpdump、wireshark等重量级的数据包抓取、分析应用程序所直接支持,所以,为我们的程序中嵌入此类文件的解析与生成功能,很是值得。
具体信息请看wireshark wiki:http://wiki.wireshark.org/Development/LibpcapFileFormat
笔者本来想借助开源的tcpreplay与libpcap中的代码片段来快速实现此目的,没想到被两个bug,卡住了几个小时,真是欲速则不达!
第一处:tcpreplay,如果不是因为宏SEEK_SET恰巧等于0 ...... 不要多说,虽不致命,但祸患无穷。
第二处:libpcap,关于packet header的结构定义,struct timeval长度为16字节,而实际上这段区域长度为8字节,所以,这个结构体根本不能正常工作。只会更糟!
无碍,我们继续,最终的pcap文件解析函数原型:
上图是即为解析的核心函数原型,对照着第一个图一起看会很清晰!下面进行测试 :)
1 int main() 2 { 3 struct pcap_file_header phdr; 4 char * filePathPtr="log.pcap"; 5 int fd; 6 int i; 7 int packet_counter; 8 struct packet pkt; 9 10 if ( ( fd=open(filePathPtr,O_RDONLY) )==-1 ) 11 { 12 printf("error: open file error %s \n",filePathPtr); 13 return 1; 14 } 15 if( is_pcap_file_format(fd,&phdr)) 16 { 17 print_pcap_file_header(&phdr); 18 } 19 else 20 { 21 printf("error: file %s format not support \n",filePathPtr); 22 return 1; 23 } 24 packet_counter=0; 25 while(1) 26 { 27 if(pcap_file_get_next_packet(fd,&pkt)) 28 { 29 packet_counter++; 30 printf("snaplen: %d actual_len: %d packet_counter: %d \n",pkt.len,pkt.actual_len,packet_counter); 31 for(i=0; i<pkt.len; ++i) 32 { 33 printf(" %02x", pkt.data[i]); 34 if( (i + 1) % 16 == 0 ) 35 { 36 printf("\n"); 37 } 38 } 39 printf("\n\n"); 40 } 41 else 42 { 43 printf("done\n"); 44 break; 45 } 46 } 47 close(fd); 48 }