Libpcap编程(6)

上篇文章中针对libpcap进行了理论总结,以及部分函数和结构的介绍,这里就整个数据包抓包由浅到深进行分析。

获取网络接口名字和掩码信息

#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      //in_addr头文件
int main(int argc,char **argv)
{
	char error[PCAP_ERRBUF_SIZE];//#define PCAP_ERRBUF_SIZE 256
	struct in_addr ip;
	struct in_addr mask;
	char *interface;
	bpf_u_int32 net_ip;
	bpf_u_int32 net_mask;
	interface=pcap_lookupdev(error);//获取网络设备指针
	if(interface==NULL)
	{
		printf("pcap_lookupdev error\n");
		return -1;
	}
	printf("Network interface:%s\n",interface);
	int ret=pcap_lookupnet(interface,&net_ip,&net_mask,error);//获取网络接口地址和掩码
	if(ret<0)
	{
		printf("pcap_lookupnet error\n");
		return -1;
	}
	ip.s_addr=net_ip;
	mask.s_addr=net_mask;
	printf("Interface ip:%s\n",inet_ntoa(ip));//地址输出
	printf("Interface mask:%s\n",inet_ntoa(mask));//掩码输出
//获取所有接口
// typedef struct pcap_if pcap_if_t;
/*
 struct pcap_if {
         struct pcap_if *next;
         char *name;            
         char *description;  
         struct pcap_addr *addresses;
         bpf_u_int32 flags;     
};

*/
	
	pcap_if_t *p;
	ret=pcap_findalldevs(&p,error);
	if(ret<0)
	{
		printf("pcap_findalldevs error\n");
		return -1;
	}

	while(p!=NULL)
	{
		printf("name:%s",p->name);
		printf("\tdescription:%s\n",p->description);
		p=p->next;
		
	}
return 0;
}


     
     
    
    
   
   
执行结果:

注:代码中使用了pcap_findalldevs函数获取主机内所有可用的网络接口链表。可以看出显示中列出了4个USB接口。这是由于USB为传输协议,并不是存储协议,USB接口主要用于数据传输的,所以可以抓取到USB接口。

在获取了网络接口之后开始抓取一个数据包

#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
       
int main()
{
	char error[PCAP_ERRBUF_SIZE];
	struct pcap_pkthdr head;
	pcap_t *pcaph;//libpcap句柄
	struct bpf_program bpf_filter;//过滤规则
	char bpf_filter_string[]="src host 192.168.61.118";
	const u_char *packet_content;//数据包内容
	bpf_u_int32 mask;
	bpf_u_int32 ip;
	char *interface;
	int ret;
	
	interface=pcap_lookupdev(error);//返回可用设备指针
	assert(interface!=NULL);
	printf("interface:%s",interface);
	ret=pcap_lookupnet(interface,&ip,&mask,error);//获取网络地址和掩码信息
	assert(ret>=0);
	
	pcaph=pcap_open_live(interface,1500,1,0,error);//打开网络接口
	printf("%s\n",error);
	assert(pcaph!=NULL);
	
	pcap_compile(pcaph,&bpf_filter,bpf_filter_string,0,mask);//编译过滤规则
	pcap_setfilter(pcaph,&bpf_filter);
	packet_content=pcap_next(pcaph,&head);
	printf("capture a packet from:%s\n",interface);
	printf("The packet length is :%d\n",head.len);
	pcap_close(pcaph);
	return 0;
}


      
      
     
     
    
    
   
   
执行结果:

注意:这里可以打印error字符串输出出错的原因,该程序中后期核心转储是因为适用权限的问题,适用本代码需要有root执行权限。该段代码可以作为数据包捕获的雏形,后期整个数据包捕获都是这样的架构。
抓取多个数据包

#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
/*注意回调函数的定义
typedef void (*pcap_handler)(u_char *user, const struct pcap_pkthdr *h,
                                   const u_char *bytes);
*/
void packet_callback(u_char *argument,const struct pcap_pkthdr *pcap_header,const u_char *packet_content)
{
	static int num=1;
	printf("The %d packet is captured\n",num);
	num++;
}
int main()
{
	pcap_t *pcaph;
	char error[PCAP_ERRBUF_SIZE];
	char *interface;
	struct bpf_program bpf_filter;
	char bpf_filter_string[]="src host 192.168.61.118";
	bpf_u_int32 mask;
	bpf_u_int32 ip;
	interface=pcap_lookupdev(error);
	pcap_lookupnet(interface,&ip,&mask,error);
	pcaph=pcap_open_live(interface,BUFSIZ,1,0,error);
	pcap_compile(pcaph,&bpf_filter,bpf_filter_string,0,mask);
	pcap_setfilter(pcaph,&bpf_filter);
	pcap_loop(pcaph,5,packet_callback,NULL);//循环接收5个数据包
	pcap_close(pcaph);
	return 0;
}


     
     
    
    
   
   
执行ping命令:


运行代码:


与上一个内容类似,该段代码需要要root权限下执行,否则将会报错核心转储。另外规则的制定需要参考上一篇博文的理论基础部分。后期的分析将会深入到TCP/IP各个层去,这里面涉及各层的协议。抓取和分析,这里作为一个专题讲述。(先运行代码在主机(192.168.61.117),再使用主机(192.168.61.118)ping(192.168.61.117))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值