Libpcap学习笔记

libpcap是Unix/Linux平台的数据包捕获库,提供了一个跨平台的包捕获API。它通过网络分接头和数据过滤器实现数据包的捕获与过滤,使用BPF算法对链路层数据包进行过滤。主要函数包括pcap_lookupdev、pcap_open_live、pcap_setfilter等,用于设备查找、打开设备、设置过滤规则等。在抓包过程中,需要设置设备、打开设备、编译和设置过滤器,然后通过pcap_loop或pcap_dispatch进行数据包捕获。
摘要由CSDN通过智能技术生成

参考

[1]http://www.tcpdump.org/pcap.html

[2]http://blog.csdn.net/lsg_down/article/details/78486614

[3]http://e-ghost.deusto.es/docs/2005/conferencias/pcap.pdf

[4]wiki

[5]API

简单介绍

libpcap(Packet Capture Library),即数据包捕获函数库,是Unix/Linux平台下的网络数据包捕获函数库。它是一个独立于系统的用户层包捕获的API接口,为底层网络监测提供了一个可移植的框架。

libpcap工作原理

​ libpcap主要由两部份组成:网络分接头(Network Tap)和数据过滤器(Packet Filter)。网络分接头从网络设备驱动程序中收集数据拷贝,过滤器决定是否接收该数据包。Libpcap利用BSD Packet Filter(BPF)算法对网卡接收到的链路层数据包进行过滤。BPF算法的基本思想是在有BPF监听的网络中,网卡驱动将接收到的数据包复制一份交给BPF过滤器,过滤器根据用户定义的规则决定是否接收此数据包以及需要拷贝该数据包的那些内容,然后将过滤后的数据给与过滤器相关联的上层应用程序。

​ libpcap的包捕获机制就是在数据链路层加一个旁路处理。当一个数据包到达网络接口时,libpcap首先利用已经创建的Socket从链路层驱动程序中获得该数据包的拷贝,再通过Tap函数将数据包发给BPF过滤器。BPF过滤器根据用户已经定义好的过滤规则对数据包进行逐一匹配,匹配成功则放入内核缓冲区,并传递给用户缓冲区,匹配失败则直接丢弃。如果没有设置过滤规则,所有数据包都将放入内核缓冲区,并传递给用户层缓冲区。

常用函数

  • pcap_lookupdev()

    函数用于查找网络设备,返回可被pcap_open_live()函数调用的网络设备名指针。

  • pcap_open_live()

    函数用于打开网络设备,并且返回用于捕获网络数据包的数据包捕获描述字。对于此网络设备的操作都要基于此网络设备描述字。

  • pcap_lookupnet()

    函数获得指定网络设备的网络号和掩码。

  • pcap_compile()

    函数用于将用户制定的过滤策略编译到过滤程序中。

  • pcap_setfilter()

    函数用于设置过滤器。

  • pcap_loop()

    函数pcap_dispatch()函数用于捕获数据包,捕获后还可以进行处理,此外pcap_next()和pcap_next_ex()两个函数也可以用来捕获数据包。

  • pcap_close()

    函数用于关闭网络设备,释放资源。

抓包步骤

  1. 设置设备。In Linux this may be something like eth0, in BSD it may be xl1, etc. We can either define this device in a string, or we can ask pcap to provide us with the name of an interface that will do the job.
  2. 初始化pcap。正式决定在那个设备上用于抓包,通过handles区别不同的设备。
  3. 编译过滤器
  4. 进入执行循环队列。
  5. 关闭会话。

1. 设置设备

  1. 参数输入
#include <stdio.h>
#include <pcap.h>

int main(int argc, char *argv[])
{
  char *dev = argv[1];

  printf("Device: %s\n", dev);
  return(0);
}
  1. 使用pcap_lookupdev查找

    注:pcap_lookupdev只返回第一个可用于嗅探的接口

#include <stdio.h>
#include <pcap.h>

int main(int argc, char *argv[])
{
  char *dev, errbuf[PCAP_ERRBUF_SIZE];

  dev = pcap_lookupdev(errbuf);
  if (dev == NULL) {
    fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
    return(2);
  }
  printf("Device: %s\n", dev);
  return(0);
}

2. 打开设备用于嗅探

使用pcap_open_live打开一个设备

pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms,
        char *ebuf)

​ 其第一个参数是我们在上一节中指定的设备,snaplen是整形的,它定义了将被pcap捕捉的最大字节数。当promisc设为true时将置指定接口为混杂模式(然而,当它置为false时接口仍处于混杂模式的非凡情况也是有可能的)。to_ms是读取时的超时值,单位是毫秒(假如为0则一直嗅探直到错误发生,为-1则不确定)。最后,ebuf是一个我们可以存入任何错误信息的字符串(就像上面的errbuf)。此函数返回其会话句柄。

​ 混杂模式与非混杂模式的区别:这两种方式区别很大。一般来说,非混杂模式的嗅探器中,主机仅嗅探那些跟它直接有关的通信,如发向它的,从它发出的,或经它路由的等都会被嗅探器捕捉。而在混杂模式中则嗅探传输线路上的所有通信。在非交换式网络中,这将是整个网络的通信。这样做最明显的优点就是使更多的包被嗅探到,它们因你嗅探网络的原因或者对你有帮助,或者没有。但是,混杂模式是可被探测到的。一个主机可以通过高强度的测试判定另一台主机是否正在进行混杂模式的嗅探。其次,它仅在非交换式的网络环境中有效工作(如集线器,或者交换中的ARP层面)。再次,在高负荷的网络中,主机的系统资源将消耗的非常严重。

示例程序:

 #include <pcap.h>
//...
 pcap_t *handle;
/*This code fragment opens the device stored in the strong "dev", tells it to read however many bytes are specified in BUFSIZ (which is defined in pcap.h). We are telling it to put the device into promiscuous mode, to sniff until an error occurs, and if there is an error, store it in the string errbuf; it uses that string to print an error message.*/
handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
if (handle == NULL) {
  fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
  return(2);
}

不是所有包的链路层头都一样。

# If your program doesn't support the link-layer header type provided by the device, it
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值