前面针对libpcap的编程可信部分已经记录的差不多了,这里进行最后一个部分的总结。协议分析,主要是以一个以太网协议作为因子,后期别的协议采用同样的方式。层层深入分析。
源代码程序:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main() { char error[PCAP_ERRBUF_SIZE]; pcap_t *pcaph; const u_char *ef; bpf_u_int32 mask; bpf_u_int32 ip; char *interface; int ret; u_char *p; struct ether_header *peth; struct bpf_program bpf_filter; struct pcap_pkthdr protocol_header; interface=pcap_lookupdev(error); if(interface) printf("Interface:%s\n",interface); else return -1; ret=pcap_lookupnet(interface,&ip,&mask,error); assert(ret>=0); pcaph=pcap_open_live(interface,BUFSIZ,1,0,error); assert(pcaph!=NULL); pcap_compile(pcaph,&bpf_filter,"icmp src host 192.168.61.118",0,mask); pcap_setfilter(pcaph,&bpf_filter); ef=pcap_next(pcaph,&protocol_header); peth=(struct ether_header*)ef; //printf("%#x\n",peth->ether_type); switch(ntohs(peth->ether_type)) { case 0x0800: printf("这是一个IP数据报\n"); break; case 0x0806: printf("这是一个ARP报文\n"); break; case 0x9000: printf("这是一个环回数据报\n"); break; default: printf("不清楚协议的类型\n"); } p=peth->ether_dhost; printf("%d\n",ETH_ALEN); printf("dest MAC :%x-%x-%x-%x-%x-%x\n",p[0],p[1],p[2],p[3],p[4],p[5]); p=peth->ether_shost; printf("dest MAC :%x-%x-%x-%x-%x-%x\n",p[0],p[1],p[2],p[3],p[4],p[5]); return 0; }
上文中为一个以太网数据包的抓取。相应的AQP数据包抓取只需要将相应的报头数据结构加上相应的首部长度就可以了。这个可以参考之前的packet编程的实现方式。系统中针对不同的头文件。
比如:以太网首部在:net/ethernet.h
arp首部:net/if_arp.h
icmp、igmp、tcp、ip这些首部可以在netinet/这个目录下查找到。
通过简单的理解Libpcap对数据包的抓取这部分的工作已经完成,后期将会针对网络数据包构造库libnet进行总结。