本文函数来源,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