一、libpcap的简介

Libpcap是Packet Capture Libray的英文缩写,即数据包捕获开源的C函数库,用于捕获网卡数据或分析pcap格式的抓包报文。Tcpdump和wireshark均是以此为基础的。

主要功能有:网络报文抓取;网络报文的构建;抓包文件的分析;自定义BFP过滤。

二、网络报文

网络报文是按照协议层次逐层构建的,简单按照四层协议来理解就是在应用层数据和协议的基础上构建传输层报文,在传输层协议的基础上构建网络层报文,在网络层报文的基础上构建数据链路/物理层报文。

图1.网络分层图

三、应用说明

libpcap主要用于网络嗅探,如下图:

基于libpcap的应用一般处理过程:

四、libpcap工作原理

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

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

五、常用函数说明

调用 libpcap 库函数前要包含的头文件:

#include <pcap/pcap.h>

调用 libpcap 库抓包的流程:

  1. 查找网卡,目的是发现可用的网卡,实现的函数为 pcap_lookupdev() 。
  2. 获得网卡参数,这里是利用 pcap_lookupnet() 函数,获得指定网卡的 IP 地址和子网掩码。
  3. 打开网卡,利用第一步的返回值,决定使用哪个网卡,调用pcap_open_live() 将其打开。
  4. 编译过滤策略,Lipcap 的重要功能就是提供数据包的过滤,实现的函数是pcap_compile() 。
  5. 设置过滤器,调用 pcap_setfilter() 函数将编译好的过滤策略设置到相应网卡。
  6. 开始捕获数据包,有多种实现函数,具有不同的特性。
  7. 关闭网卡,释放资源。

如果是用源码包编译安装的话,在 tests 目录下有几个例程可以参考。

1、获取网络接口

首先我们需要获取监听的网络接口,我们可以手动指定或让libpcap自动选择,先介绍如何让libpcap自动选择:

//这个函数返回第一个合适的网络接口的字符串指针,如果出错,则errbuf存放出错信息字符串,errbuf至少应该是PCAP_ERRBUF_SIZE个字节长度的,注意,很多libpcap函数都有这个参数。
//pcap_lookupdev()一般可以在跨平台的,且各个平台上的网络接口名称都不相同的情况下使用。如果我们手动指定要监听的网络接口,则这一步跳过,我们在第二步中将要监听的网络接口字符串硬编码在pcap_open_live里。
char * pcap_lookupdev(char * errbuf)

2、释放网络接口

void pcap_close(pcap_t * p)
//该函数用于关闭pcap_open_live()获取的pcap_t的网络接口对象并释放相关资源。

3、打开网络接口

//这个函数会返回指定接口的pcap_t类型指针,后面的所有操作都要使用这个指针。
pcap_t *pcap_open_live(const char * device, int snaplen, int promisc, int to_ms, char * errbuf)
//device:网络接口字符串,可以直接使用硬编码,比如eth0。
//snaplen:对于每个数据包,从开头要抓多少个字节,我们可以设置这个值来只抓每个数据包的头部,而不关心具体的内容。典型的以太网帧长度是1518字节,但其他的某些协议的数据包会更长一点,但任何一个协议的一个数据包长度都必然小于65535个字节。
//promisc:指定是否打开混杂模式(Promiscuous Mode),0表示非混杂模式,任何其他值表示混合模式。如果要打开混杂模式,那么网卡必须也要打开混杂模式,可以使用如下的命令打开eth0混杂模式:ifconfig eth0
//to_ms:抓包时长单位为毫秒,0标示一直等待。
//errbuf: 输出参数,打开网络接口失败原因。

4、获取数据包

打开网络接口后就已经开始监听了,那如何知道收到了数据包呢?有下面3种方法:

1)pcap_next

u_char * pcap_next(pcap_t * p, struct pcap_pkthdr * h)
//如果返回值为NULL,表示没有抓到包
//第一个参数是第2步返回的pcap_t类型的指针
//第二个参数是保存收到的第一个数据包的pcap_pkthdr类型的指针
//pcap_pkthdr类型的定义如下:
struct pcap_pkthdr
{struct timeval ts;    /* time stamp */bpf_u_int32 caplen;   /* length of portion present */bpf_u_int32 len;      /* length this packet (off wire) */
};
//注意这个函数只要收到一个数据包后就会立即返回

2)pcap_loop

int pcap_loop(pcap_t * p, int cnt, pcap_handler callback, u_char * user)
//第一个参数是第2步返回的pcap_t类型的指针
//第二个参数是需要抓的数据包的个数,一旦抓到了cnt个数据包,pcap_loop立即返回。负数的cnt表示pcap_loop永远循环抓包,直到出现错误。
//第三个参数是一个回调函数指针,它必须是如下的形式:
void callback(u_char * userarg, const struct pcap_pkthdr * pkthdr, const u_char * packet)
//第一个参数是pcap_loop的最后一个参数,当收到足够数量的包后pcap_loop会调用callback回调函数,同时将pcap_loop()的user参数传递给它
//第二个参数是收到的数据包的pcap_pkthdr类型的指针
//第三个参数是收到的数据包数据

3)pcap_dispatch

int pcap_dispatch(pcap_t * p, int cnt, pcap_handler callback, u_char * user)
//这个函数和pcap_loop()非常类似,只是在超过to_ms毫秒后就会返回(to_ms是pcap_open_live()的第4个参数)

5、分析数据包

我们既然已经抓到数据包了,那么我们要开始分析了,这部分留给读者自己完成,具体内容可以参考相关的网络协议说明。在本文的最后,我会示范性的写一个分析arp协议的sniffer,仅供参考。要特别注意一点,网络上的数据是网络字节顺序的,因此分析前需要转换为主机字节顺序(ntohs()函数)。

6、过滤数据包

我们抓到的数据包往往很多,如何过滤掉我们不感兴趣的数据包呢?
几乎所有的操作系统(BSD, AIX, Mac OS, Linux等)都会在内核中提供过滤数据包的方法,主要都是基于BSD Packet Filter(BPF)结构的。libpcap利用BPF来过滤数据包。
过滤数据包需要完成3件事:

  1. 构造一个过滤表达式
  2. 编译这个表达式
  3. 应用这个过滤器

1)构造一个过滤表达式

BPF使用一种类似于汇编语言的语法书写过滤表达式,不过libpcap和tcpdump都把它封装成更高级且更容易的语法了,具体可以man tcpdump,以下是一些例子:

src host 192.168.1.177
//只接收源ip地址是192.168.1.177的数据包dst port 80
//只接收tcp/udp的目的端口是80的数据包not tcp
//只接收不使用tcp协议的数据包tcp[13] == 0x02 and (dst port 22 or dst port 23)
//只接收SYN标志位置位且目标端口是22或23的数据包(tcp首部开始的第13个字节)icmp[icmptype] == icmp-echoreply or icmp[icmptype] == icmp-echo
//只接收icmp的ping请求和ping响应的数据包ehter dst 00:e0:09:c1:0e:82
//只接收以太网mac地址是00:e0:09:c1:0e:82的数据包ip[8] == 5
//只接收ip的ttl=5的数据包(ip首部开始的第8个字节)

2)编译这个表达式

构造完过滤表达式后,我们需要编译它,使用如下函数:

int pcap_compile(pcap_t * p, struct bpf_program * fp, char * str, int optimize, bpf_u_int32 netmask)
//fp:这是一个传出参数,存放编译后的bpf
//str:过滤表达式
//optimize:是否需要优化过滤表达式
//metmask:简单设置为0即可

3)应用这个过滤器

最后我们需要应用这个过滤表达式:

int pcap_setfilter(pcap_t * p,  struct bpf_program * fp)
//第二个参数fp就是前一步pcap_compile()的第二个参数

应用完过滤表达式之后我们便可以使用pcap_loop()或pcap_next()等抓包函数来抓包了。

7、打开离线的pcap文件

pcap_t *pcap_open_offline(const char *fname, char *errbuf)
//fname :文件名称。
//errbuf :打开失败的错误信息。

8、打开网络包保存文件

pcap_dumper_t *pcap_dump_open(pcap_t *p, const char *fname)
//p:是我们已经打开的网络设备,从这个设备接收数据包。
//fname:是我们要写入的文件名,随便起。
//return: 如果出错,会返回NULL。可以借此检查这个文件有没有打开。

9、将网络包写入文件

void pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
//user:就是文件描述符dumpfp,只不过要做一下类型转换。
//由于这个函数一般在pcap_loop()的函数指针所指向的packet_handler中使用,所以packet_handler中的user就是这里的user。
//h:就是pkt_header

10、网络包文件关闭

pcap_dump_close(pcap_dumper_t * t);

数据结构说明:

struct pcap_pkthdr {struct timeval ts;  /* time stamp */bpf_u_int32 caplen; /* 抓到的数据包实际长度 */bpf_u_int32 len;    /*数据包的长度 */
};

原文链接:
https://www.jianshu.com/p/77ee42f0fea6
https://blog.csdn.net/htttw/article/details/7521053
https://shaocheng.li/posts/2018/04/23/

libpcap介绍(一)相关推荐

  1. libpcap解析pcapng文件

    libpcap介绍 libpcap(Packet Capture Library)即数据包捕获函数库,是Unix/Linux平台下的网络数据包捕获函数库.它是独立于系统的用户层包捕获的API接口,为底 ...

  2. Linux网络编程——千峰物联网笔记

    B站视频:千峰物联网学科linux网络编程 网址:https://www.bilibili.com/video/BV1RJ411B761?p=1 目录 第一章:计算机网络概述 1.1计算机网络发展简史 ...

  3. libpcap c语言,libpcap库主要函数介绍

    libpcap是一个C语言库,libpcap的英文意思是 Packet Capture library,即数据包捕获函数库,其功能是通过网卡抓取网络以太网中的数据包.这个库为不同的平台提供了一致的c函 ...

  4. linux 抓包生成文件,Linux下使用libpcap进行网络抓包并保存到文件(函数介绍)

    libpcap是一个抓取网络数据报文的C语言函数库,使用这个库可以非常方便的抓取网络上的报文,方便我们分析经过我们设备上的各种报文: 使用libcap库编译时都要在后面加上-lpcap选项 使用pca ...

  5. 内核网络中的GRO、RFS、RPS技术介绍和调优

    内核网络中的GRO.RFS.RPS技术介绍和调优 1. 前言 2. GRO(Generic Receive Offloading) 2.1 使用 ethtool 修改 GRO 配置 2.2 napi_ ...

  6. tcpdump的简单选项介绍

    tcpdump采用命令行方式,它的命令格式为: tcpdump [ -AdDeflLnNOpqRStuUvxX ] [ -c count ] [ -C file_size ] [ -F file ] ...

  7. Linux -- ***检测系统(IDS)介绍及应用(1)

    一.***检测工具简介 Internet上的服务器一般都会被安置在防火墙的DMZ(Demilitarized Zone)区,受到防火墙的保护.这在一定程度可以防止具有已知非法特征的危险连接和恶意*** ...

  8. 网络抓包工具wireshark and tcpdump 及其实现基于的libpcap

    最近无意中看到博客园中一篇介绍wireshark的文章,写得不错,它简单清楚介绍了wireshark的使用 简介 wireshark以前叫做Ethereal, 在大学时候的网络课程中就常看到它,它是世 ...

  9. Network 之四 常用 Linux 网络命令及网络调试工具介绍

    网络互连模型 主要就是值得 OSI 参考模型与 TCP/IP 五层模型: 下面再来一张详细点的(来源于科来网络): 网络命令   目前,我们常用的网络相关的命令有两大类:net-tools 和 ipr ...

最新文章

  1. LabVIEW机器视觉系统图像畸变、校准和矫正(基础篇—3)
  2. MagicDraw UML 16.8 安装教程
  3. mahout贝叶斯分类器测试样例
  4. 第三次学JAVA再学不好就吃翔(part87)--Arrays工具类的asList方法
  5. Java代理系列-静态代理
  6. 互联网日报 | 8月4日 星期三 | 京东货运航空筹建获批;小米手机出货量在欧洲首次登顶;阿里全球年度活跃消费者11.8亿...
  7. linux java缓存失效_转载:Linux服务器Cache占用过多内存导致系统内存不足最终java应用程序崩溃解决方案...
  8. delphi 软件在线人数统计_【大学分析】计算机爆满,软件爆冷!这所985大学考研分数截然不同!...
  9. ProcExp和TaskMgr的列对比
  10. 经典Flash MX 2004教程全集
  11. 电子计算机与其它计算机工具的本质区别是,电子计算机与其他计算工具的本质区别是...
  12. centos是arm还是amd_amd系列cpu安装linux
  13. 总结Python设置Excel单元格样式的一切,比官方文档还详细
  14. 用java编国际象棋3之将军与悔棋
  15. Nmap常用命令总结
  16. 12月世界燕窝滋补品展|上海燕博会|冻干(即食)燕窝展谈食用燕窝
  17. 考虑不同充电需求的电动汽车协调充电调度方法 提出了一种电动汽车(EV)的协调充电调度方法
  18. 数字孪生解决方案-最新全套文件
  19. 超声波引导系统开源(三)485通信原理
  20. vue 调用webservice_c#:WebService及其几种调用方式

热门文章

  1. python培训班一般多少钱-广州Python培训机构一般多少钱
  2. python面试常见问题-Python面试中最常见的25个问题
  3. 2018python培训-2018传智播客Python基础班+就业班(15期)
  4. python官网下载好慢1001python官网下载好慢-Python|时间复杂度测试
  5. python帮助文档中文版下载-python3.5.2官方帮助文档 参考手册(CHM版)
  6. arcgis python编程案例-ArcGIS Python编程案例-电子资料链接
  7. python课程设计报告总结-上海python课程设计报告数据处理
  8. python100行代码-100 Lines Python
  9. python哪本好-最好的Python入门教材是哪本?
  10. 用python 爬取百度百科内容-使用python爬取小说全部内容