您的位置:首页 > 运维架构 > Linux

linux平台libpcap函数分析及流程(…

2013-07-10 10:30 302 查看
   
本文函数来源,libpcapHakin9LuisMartinGarcia.pdf文档,文档只有9页,是英文版的,不过讲得比较详细,而且能帮助理解,我通过对文档的学习,然后结合网上的一些资料加以总结。

 

   
这些天一直都在学习写一些抓包代码,由一片空白开始学习,通过在网上搜索资料,不断的摸索,慢慢地有了一些头绪,我将我的一些小小心得与大学分享。我总结的这些函数到处都可见,没有什么特别之处,只是让大家能了解编写代码的步骤,然后将函数功能说得齐全一点,尽量减少大家查找资料的时间。

   

   
在此之前说明一下,以下函数包涵在头文件中,还请大家在网上下载libpcap的安装包安装在自己机器上,保证程序正确运行,我将在下一讲给出与本文档相对应的源代码,好了,我们开始介绍下面的函数。

 

step 1: 获取网络接口

函数原型:char * pcap_lookupdev(char * errbuf)

    
返回第一个合适的网络接口的字符串指针,如果出错,则errbuf存放出错信息字符串,errbuf至少应该是PCAP_ERRBUF_SIZE个字节长度的。

注意,很多libpcap函数都有这个参数。

     
pcap_lookupdev()一般可以在跨平台的,且各个平台上的网络接口名称都不相同的情况下使用。如果我们手动指定要监听的网络接口,则这一步跳过,我们在第二步中将要监听的网络接口字符串硬编码在pcap_open_live里。 

 

step 2:  打开网络接口

函数原型:pcap_t * pcap_open_live(const char * device, int snaplen, int
promisc, int to_ms, char * errbuf)

函数功能:返回指定接口的pcap_t类型指针,后面的所有操作都要使用这个指针。

返回值:如果函数成功执行,则返回一个指向数据报捕获的指针;如果错误,返回null,ebuf存放出错信息

参数

  
device:是pcap_lookupdev函数获取的网络接口字符串,可以直接使用硬编码。

  
snaplen:是对于每个数据包,从开头要抓多少个字节,我们可以设置这个值来只抓每个数据包的头部,而不关心具体的内容。典型的以太网帧长度是1518字节,但其他的某些协议的数据包会更长一点,但任何一个协议的一个数据包长度都必然小于65535个字节。

   promisc:指定是否打开混杂模式(Promiscuous
Mode),0表示非混杂模式,任何其他值表示混合模式。如果要打开混杂模式,那么网卡必须也要打开混杂模式,可以使用如下的命令打开eth0混杂模式:ifconfig
eth0 promisc。

  
to_ms:指定需要等待的毫秒数,超过这个数值后,第3步获取数据包的这几个函数就会立即返回。0表示一直等待直到有数据包到来。

   errbuf:是存放出错信息的数组。

 

step3: Look up info from the capture device 
可以获取指定设备的ip地址,子网掩码等信息。                  

函数原型:int pcap_lookupnet(const char * device, bpf_u_int32 * netaddr,
bpf_u_int32 * mask, char * errbuf)

返回值:pcap_lookupnet()失败返回-1,同时errbuf中存放相关的错误消息。

参数:

  
netaddr:传出参数,指定网络接口的ip地址。

   mask:传出参数,指定网络接口的子网掩码。

  
使用inet_ntoa()可将其转换为可读的点分十进制形式的字符串。

 

step4: 编译过滤表达式: Packets with ACK or PSH-ACK flags
set  

函数原型:int pcap_compile(pcap_t * p, struct bpf_program * fp, char *
str, int optimize, bpf_u_int32 netmask)

参数:

  fp:是一个bpf_program结构的指针传出参数,存放编译后的bpf

  str:过滤表达式

  optimize:是否需要优化过滤表达式

  netmask:指定本地网络的网络掩码,简单设置为0即可 

 

step5: Load the filter program into the packet capture
device.           

函数原型:int pcap_setfilter(pcap_t * phandle,  struct
bpf_program * fp)

返回值:出错时返回-1;成功时返回0

参数:

  fp:是bpf_program结构指针,即前一步pcap_compile()的第二个参数

 

step6: 开始捕获数据

函数原型:u_char * pcap_next(pcap_t * phandle, struct pcap_pkthdr *
pkthdr)

返回值:如果返回值为NULL,表示没有抓到包

参数:

  phandle:是第2步返回的pcap_t类型的指针

  pkthdr:是保存收到的第一个数据包的pcap_pkthdr类型的指针

 

pcap_loop函数与pcap_next一样都是捕获数据,不过此函数能循环捕获。

函数功能:捕获数据包,不会响应pcap_open_live()函数设置的超时时间

函数原型:int pcap_loop(pcap_t * p,int cnt, pcap_handler callback, uchar
* user);

参数:

  p
是由pcap_open_live()返回的所打的网卡的指针;

  cnt用于设置所捕获数据包的个数,若cnt参数为负值时pcap_loop()函数将始终循环运行,除非出现错误。

  pcap_handler是与void
packet_handler()使用的一个参数,即回调函数的名称;

  user是留给用户使用的,其值一般为NULL

第三个参数是一个回调函数指针,回调函数其原型如下:

  void callback(u_char*
argument,const struct pcap_pkthdr* pkthdr,const u_char*
packet_content)

  参数argument是从函数pcap_loop()传递过来的。注意:这里的参数就是指
pcap_loop中的 *user 参数;

  参数pcap_pkthdr
表示捕获到的数据包基本信息,包括时间,长度等信息;

  参数pcap_content表示的捕获到的数据包的内容。

 

   
好了,函数的介绍就说到这里了,这仅仅是应用于抓包的几个重要函数,将格式与作用加以了解与介绍。如果大家对此感兴的话,在网上找了一篇文章,里面函数很多:http://blog.csdn.net/wangjiannuaa/article/details/7310716

    

   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: