赞
踩
1、捕获各种数据包
eg:网络流量统计
2、过滤网络数据包
eg:过滤掉本地的一些数据,类似防火墙
3、分析网络数据包
eg:分析网络协议,数据的采集
4、存储网络数据包
eg:保存捕获的数据以为将来进行分析
sudo apt-get install libpcap-dev
①打开网络设备
②设备过滤规则(可选)
③捕获数据
④关闭网络设备
头文件:#include <pcap.h>
编译时需要加上: -lpcap
pcap_lookupdev( )
原型:
char *pcap_lookupdev(char *errbuf)
功能:得到可用的网络设备名指针
参数:errbuf:存放相关的错误信息
返回值:成功返回设备名指针;
失败返回NULL
例子:
char *dev = NULL;
char *err_buf[100]="";
dev = pcap_lookupdev(err_buf);
if(dev ==NULL)
{
perror("pcap_lookupdev");
exit(-1);
}
pcap_open_live( )
原型:
pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf);
功能:打开一个用于捕获数据的接口
参数:device:网络接口的名字
snaplen:捕获数据包的长度
promise:1代表混杂模式,其他代表非混杂模式
to_ms:等待时间
ebuf:存储错误信息
返回值:返回一个Libpcap句柄
例子:
char error_content[PACP_ERRBUF_SIZE]="";
pcap_t * pcap_handle=NULL;
pcap_handle = pcap_open_live("eth0",1024,1,0,error_content);
pcap_lookupnet( )
原型:
int pcap_lookupnet(char *device, buf_u_int32 *netp, bpf_u_int32 *maskp, char *errbuf);
功能:获得指定网络设备的网络号和掩码
函数:device:网络设备名
netp:存放网络号的指针
maskp:存放掩码的指针
errbuf:存放出错信息
返回值:成功:0,失败:-1
例子:
unsigned int net_ip; //网络地址
unsigned int net_mask; //子网掩码
res = pcap_lookupnet(dev, &net_ip, &net_mask, error_content);
if(res == -1)
{
perror("pcap_lookupnet");
exit(-1);
}
1、pcap_compile( ) 将用户的规则转换成pcap的规则
原型:
int pcap_compile(pcap_t *p, struct bpf_program *program, char *buf,
int optimize, bpf_u_int32 mask);
功能:编译BPF过滤规则
参数:p:Libpcap句柄
program:bpf过滤规则(pcap识别的规则)
buf:过滤规则字符串(用户识别的规则)
optimize:优化
mask:掩码
返回值:成功返回0,失败返回-1
例子:
struct bpf_program bpf_filter;
char *bpf_filter_string = "arp or ip";
if(pcap_compile(pcap_handle,&bpf_filter,bpf_filter_string,0,0xffffff00)<0)//编译BPF过滤规则
{
perror("pcap_compile");
}
2、pcap_setfillter( ) 将pcap识别的规则,设置到pcap结束数据的句柄中
原型:
int pcap_setfilter(pcap *p, struct bpf_program *fp);
功能:设置BPF过滤规则
参数:p:Libpcap句柄
fp:BPF过滤规则
返回值:成功返回0,失败返回-1
例子:
if(pcap_setfilter(pcap_handle,&bpf_filter<0) )
{
perror("pcap_setfilter");
}
过滤规则:
设置捕获源端口9000的报文规则
#include <stdio.h> #include <pcap.h> //pcap_loop每收到一个报文,就会调用一次回调函数 void callback(u_char *arg,const struct pcap_pkthdr *packet_header,const u_char *packet_content) { unsigned char *msg = packet_content; printf("报文长度:%u\n",packet_header->caplen); //msg的地址解析和原始套接字一样 //解析msg的mac地址 char src_mac[18] = ""; char dst_mac[18] = ""; sprintf(dst_mac,"02x:02x:02x:02x:02x:02x",msg[0],msg[1],msg[2],msg[3],msg[4],msg[5]); sprintf(src_mac,"02x:02x:02x:02x:02x:02x",msg[0+6],msg[1+6],msg[2+6],msg[3+6],msg[4+6],msg[5+6]); printf("%s--->%s\n",src_mac,dst_mac); } int main() { //1.创建一个pcap句柄 pcap_t *pcap_handle = NULL; pcap_handle = pcap_open_live("enp0s3",1500,0,0,NULL); //设置过滤规则 struct bpf_program program; pcap_compile(pcap_handle,&program,"src port 9000",0,0xffffff00); pcap_setfilter(pcap_handle,&program); //2.接收数据 //带阻塞 pcap_loop(pcap_handle,5,callback,NULL); //关闭句柄 pcap_close(pcap_handle); return 0; }
1、pcap_next( ) ;调用一次只接收一个报文
struct pcap_pkthdr结构体头信息:记录接收数据的时间及报文长度
原型:
const u_cahr *pcap_next(pacp_t *p, struct pcap_pkthdr *h);
功能:捕获一个网络数据包
参数:p:Libpcap句柄
h:数据包头
返回值:捕获的数据包的地址
例子:
#include <stdio.h> #include <pcap.h> int main() { //1.创建一个pcap句柄 pcap_t *pcap_handle = NULL; pcap_handle = pcap_open_live("enp0s3",1500,0,0,NULL); //2.接收数据 //定义头信息 struct pcap_pkthdr pck_hdr; //记录收到数据的时间和报文长度 unsigned char *msg = ""; //存放接收到的帧数据 msg:ip udp/tcp data msg = pcap_next(pcap_handle, &pck_hdr); printf("报文长度:%u\n",pck_hdr.caplen); //msg的地址解析和原始套接字一样 //解析msg的mac地址 char src_mac[18] = ""; char dst_mac[18] = ""; sprintf(dst_mac,"02x:02x:02x:02x:02x:02x",msg[0],msg[1],msg[2],msg[3],msg[4],msg[5]); sprintf(src_mac,"02x:02x:02x:02x:02x:02x",msg[0+6],msg[1+6],msg[2+6],msg[3+6],msg[4+6],msg[5+6]); printf("%s--->%s\n",src_mac,dst_mac); //关闭句柄 pcap_close(pcap_handle); return 0; }
2、pcap_loop( ); 调用一次不停接收报文
原型:
int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user);
功能:循环捕获网络数据包,指导遇到错误或者满足退出条件。每捕获一个数据包就会调用callback指示的回调函数,
所以,可以再回调函数中进行数据包的处理操作。
参数:p:Libpcap句柄
cnt:指定捕获数据包的个数,如果是-1,就会永无休止的捕获。
callbcak:回调函数
user:向回调函数中传递的参数
返回值:成功返回0;失败返回负数
回调函数如何定义
定义回调函数:
定义回调函数
void callback(unsigned char *argument,
const struct pcap_pkthdr *packet_header,
const unsigned char *packet_content);
/*参数1:argument存放pcap_loop传递过来的user用户数据
参数2:packet_header存放接收到的报文的时间以及长度
参数3:packet_content接收到的网络帧数据
*/
例子:
#include <stdio.h> #include <pcap.h> //pcap_loop每收到一个报文,就会调用一次回调函数 void callback(u_char *arg,const struct pcap_pkthdr *packet_header,const u_char *packet_content) { unsigned char *msg = packet_content; printf("报文长度:%u\n",packet_header->caplen); //msg的地址解析和原始套接字一样 //解析msg的mac地址 char src_mac[18] = ""; char dst_mac[18] = ""; sprintf(dst_mac,"02x:02x:02x:02x:02x:02x",msg[0],msg[1],msg[2],msg[3],msg[4],msg[5]); sprintf(src_mac,"02x:02x:02x:02x:02x:02x",msg[0+6],msg[1+6],msg[2+6],msg[3+6],msg[4+6],msg[5+6]); printf("%s--->%s\n",src_mac,dst_mac); } int main() { //1.创建一个pcap句柄 pcap_t *pcap_handle = NULL; pcap_handle = pcap_open_live("enp0s3",1500,0,0,NULL); //2.接收数据 //带阻塞 pcap_loop(pcap_handle,5,callback,NULL); //关闭句柄 pcap_close(pcap_handle); return 0; }
pcap_close( )
原型:
void pcap_close(pcap_t *p);
功能:关闭libpcap操作,并销毁相应的资源。
参数:p:需要关闭的Libpcap句柄
例子:
pcap_close(pacap_handle);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。