红联Linux门户
Linux帮助

Ubuntu16.04安装libpcap开发库对pcap文件中的数据包进行过滤

发布时间:2017-10-01 16:21:21来源:linux网站作者:拜乔布斯
Ubuntu16.04下安装了Wireshark的话,应该是已经安装了libpcap0.8的包,如下图:
Ubuntu16.04安装libpcap开发库对pcap文件中的数据包进行过滤
 
使用sudo apt-get install libpcap-dev安装开发包,安装后系统显示如下图:
Ubuntu16.04安装libpcap开发库对pcap文件中的数据包进行过滤
 
多了libpcap0.8-dev和libpcap-dev两个包。
 
工作可能截取的数据包文件(pcap文件)含有一些重要的数据包,这时我们需要把他们提取出来保存到新的数据包文件(pcap文件)中。比如下面图片中只需要dns协议的数据包
Ubuntu16.04安装libpcap开发库对pcap文件中的数据包进行过滤
 
直接贴代码了,如果api不知道怎么用的,直接使用man就行了;注意过滤表达式使用“udp port 53”,不要使用“dns”编译过滤表达式的时候会出错,提示语法错误。
 
#include <stdio.h>  
#include <stdlib.h>  
#include <time.h>  
#include <pcap/pcap.h>
pcap_t *source_pcap_t=NULL;  
pcap_dumper_t *des_pcap_dumper_t=NULL;
int exit_main()  
{  
printf("exit_main() is called.\n");  
if( NULL!=source_pcap_t )  
{  
pcap_close(source_pcap_t);  
}  
if( NULL!=des_pcap_dumper_t )  
{  
pcap_dump_close(des_pcap_dumper_t);  
}  
exit(0);  
}
int main(int argc, char *argv[])  
{
//打开要处理pcap文件  
char errbuf[PCAP_ERRBUF_SIZE]={0};  
if( NULL==(source_pcap_t=pcap_open_offline(argv[1], errbuf)) )  
{  
printf("pcap_open_offline() return NULL.\nerrbuf:%s\n", errbuf);  
exit_main();  
}  
//打开保存的pcap文件 
if( NULL==(des_pcap_dumper_t=pcap_dump_open(source_pcap_t,"./rescult.pcap")) )  
{  
printf("pcap_dump_open() fail.\n");  
exit_main();  
}
//判断链路层类型  
int datalink_offset=0;  
//pcap_datalink() returns the link-layer header type for the live capture or ``savefile'' specified by pcap_t  
int datalink_type=pcap_datalink(source_pcap_t);  
switch (datalink_type)  
{  
case PCAP_ERROR_NOT_ACTIVATED:  
printf("pcap_datalink() return PCAP_ERROR_NOT_ACTIVATED.\n");  
exit_main();  
break;  
case DLT_NULL:  
printf("Data Link Type:BSD loopback.\n");  
datalink_offset=4;  
break;  
case DLT_EN10MB:  
printf("Data Link Type:IEEE 802.3.\n");  
datalink_offset=14;  
break;  
case DLT_PPP:  
printf("Data Link Type:PPP.\n");  
datalink_offset=0;  
break;  
case DLT_FDDI:  
printf("Data Link Type:FDDI.\n");  
datalink_offset=21;  
break;  
case DLT_IEEE802_11:  
printf("Data Link Type:IEEE 802.11.\n");  
datalink_offset=22;  
break;  
case DLT_PPP_ETHER:  
printf("Data Link Type:PPPoE.\n");  
datalink_offset=20;  
break;  
default :  
printf("Data Link Type:UnKnown.\n");  
}  
printf("datalink_offset:%d\n", datalink_offset);
//设置过滤表达式  
struct bpf_program filter;  
if( -1==pcap_compile(source_pcap_t, &filter, "udp port 53", 1, 0) )  
{  
printf("pcap_compile() fail.\n");  
printf("errno:%s\n", pcap_geterr(source_pcap_t));  
exit_main();  
}  
if( -1==pcap_setfilter(source_pcap_t, &filter) )  
{  
printf("pcap_setfilter() fail.\n");  
exit_main();  
}
//网络层  
struct pcap_pkthdr packet;  
const u_char *pktStr;  
while(1)  
{  
pktStr=pcap_next(source_pcap_t, &packet);  
if( NULL==pktStr )  
{  
printf("pcap_next() return NULL.\n");  
break;
}  
else  
{  
printf("Packet length: %d\n", packet.len);
printf("Number of bytes: %d\n", packet.caplen);
printf("Recieved time: %s\n", ctime((const time_t *)&packet.ts.tv_sec));  
//读到的数据包写入生成pcap文件  
pcap_dump((u_char*)des_pcap_dumper_t, &packet, pktStr);   
}  
}
pcap_dump_close(des_pcap_dumper_t);  
pcap_close(source_pcap_t);  
return 0;  
}
 
下面图片是生成的rescult.pcap的结果,把dns的数据包全部取出来了。
Ubuntu16.04安装libpcap开发库对pcap文件中的数据包进行过滤
 
本文永久更新地址:http://www.linuxdiyf.com/linux/32704.html