目录

1..... libpcap简介... 1

2..... libpcap捕包过程... 2

2.1        数据包基本捕包流程... 2

2.2        libpcap捕包过程... 4

2.3        libpcap 1.3.0源码对照... 6

2.3.1         创建环形队列... 6

2.3.2         捕获数据包... 6

3..... libpcap捕包优化分析... 7

3.1处理流程单一:... 7

3.2高中断服务负荷:... 8

3.3内核态到用户态上下文选择:... 8

3.4数据拷贝和内存分配消耗:... 8

4..... 延伸拓展... 8

4.1 libpcap多线程捕包... 8

4.2 Linux并行运算... 9

4.3 零拷贝发包... 9

5..... 参考资料:... 9

1.  libpcap简介

libpcap是unix/linux平台下的网络数据包捕获函数包,大多数网络监控软件都以它为基础。Libpcap可以在绝大多数类unix平台下工作.Libpcap提供了系统独立的用户级别网络数据包捕获接口,并充分考虑到应用程序的可移植性。Libpcap可以在绝大多数类unix平台下工作。

在windows平台下,一个与libpcap 很类似的函数包 winpcap 提供捕获功能,其官方网站是http://winpcap.polito.it/。

2. libpcap捕包过程

2.1     数据包基本捕包流程

具体的Linux数据包处理流程如图1 所示。数据包从网卡经过内核最终到达用户空间的应用程序,其中经过三次处理:中断服务、软中断和应用程序,使用三个缓存:DMA、包队列和插口。

在网卡驱动中存在运行时内存分配,从内核到用户态时存在一次内存拷贝。

通过对图 1 进行分析可知,以下几个方面的问题可能会限制系统数据包的捕获处理能

力:

1)处理流程单一:整个处理流程串行化,其处理能力受限于整个流程的任何一处“短

板”。在多核架构系统中这样的处理方式无法发挥并行优势,存在极大的资源浪费。

2)高中断服务负荷:由于采用每接收一个数据包就产生一次中断的方式,当数据包以

很高的速率到达时,即使最快的处理器也会被持续的中断服务请求占用而无法处理数据包,从而导致数据包丢失。

3)内核态到用户态上下文选择:当数据包由内核态进入用户态时会发生上下文选择切

换,从而导致用户态任务延迟几毫秒开始。

4)数据拷贝和内存分配消耗:DMA 缓存、内核及用户内存间的数据拷贝占用了大量的CPU 资源。

2.2     libpcap捕包过程

在Linux中,数据包捕获的基础是PACKET套接字,libpcap是对PACKET套接字的简单封装.上图是libpcap的结构图,图中的流程分为两部分,箭头表示数据包的流向.上图左半部由网络子系统发起,是PACKET套接字捕获数据包的过程.PACKET套接字在网络协议栈和网卡(network interface card,NIC)设备之间设置钩子函数.当协议栈通过NIC发送数据包或者NIC接收到数据包由驱动送入协议栈处理时,数据包被钩子函数捕获送入PACKET 套接字中.

PACKET套接字的核心模块包括两个部分:

1) BPF(berkeley packet filter)过滤器.BPF根据用户设置的过滤规则计算应该接收的数据包长度值,如果该值比数据包的长度小,那么数据包将会被截短.特别地,如果该值为0,数据包会被PACKET套接字丢弃而直接返回协议栈进行网络层的处理.BPF在Linux中,BPF被用于内核进行数据包过滤,以减小提交给应用程序的数据包的包数和字节数,提高系统性能.

2)缓存队列(BufferQ).用于缓存供应用程序读取的数据包,如果队列长度超过了预设缓存区的长度,那么数据包将会被丢弃.共享内存队列,共享内存被划分为固定大小的帧,数据包被按顺序拷贝到帧中,然后内核设置数据有效位,表示该帧存放了一个有效的数据包.图2右半部由应用程序发起,从PACKET 套接字的缓存队列中获取数据包.在共享内存队列中,libpcap在打开NIC设备时,使用mmap 函数将共享内存映射到应用程序的虚拟空间中.libpcap根据帧大小按顺序读取缓存区.如果当前帧的数据有效位被设置,则将该数据包提交给应用程序处理,在处理完毕以后,libpcap清除当前帧的有效位,允许内核再次使用该帧;否则,libpcap使用poll()函数等待数据包的到达.与libpcap1.0之前版本相比,共享内存缓存队列减少了一次数据包拷贝和调用recvmsg()进入、退出内核态的系统开销,因此有较大的性能提升。

把上面比较抽象的文字翻译成一个简单的示例图如下所示:

2.3     libpcap 1.3.0源码对照

对应于libpcap 1.3.0源代码如下:

2.3.1  创建环形队列

主要步骤:

1.[setup] socket() -------> creation of the capture socket
2.setsockopt() ---> allocation of the circular buffer (ring)
3.mmap() ---------> maping of the allocated buffer to the

user process

对应libpcap-1.3.0源代码:

static int

create_ring(pcap_t *handle, int *status)函数中:

2.pcap-linux.c:3594行

if (setsockopt(handle->fd, SOL_PACKET, PACKET_RX_RING,

(void *) &req, sizeof(req))) {

3.Pcap-linux.c:3627行

handle->md.mmapbuf = mmap(0, handle->md.mmapbuflen,

PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);

2.3.2  捕获数据包

[capture] poll() ---------> to wait for incoming packets

[process]trigger the user process

[reset frame] reset the status of the frame for kernel to reuse

对应libpcap-1.3.0源代码:

static int

pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)函数中:

1.pcap-linux.c:3811行

ret = poll(&pollinfo, 1, timeout);

2.pcap-linux.c:4053行

callback(user, &pcaphdr, bp);

3.pcap-linux.c:4060行

switch (handle->md.tp_version) {

case TPACKET_V1:

h.h1->tp_status = TP_STATUS_KERNEL;

break;

3.  libpcap捕包优化分析

我们把之前2.1提到的可能会限制系统数据包的捕获处理能力的地方写出来:

3.1处理流程单一:

因为原生的libpcap是单线程的,一个数据包的处理流程是“捕包—处理包—捕下个包-处理下个包。。。”所以处理包的时间长短会影响下一个捕包的开始时间,解决这个有2个办法,一个是优化处理包流程,缩短处理包时间,但这个方法治标不治本,另一个方法是用多线程的方式捕包和处理包。

3.2高中断服务负荷:

这个是操作系统捕包的关键,现在一般有2种思路

A:把网卡的多个收包队列中断均衡的绑定到多个不同的cpu上。(网上有很多教程)

B:更换网卡驱动,可以把网卡一般现有的驱动即依赖中断接收数据包,改为轮询方式,例如现在的NAPI驱动和Intel的DPDK都有用到。

3.3内核态到用户态上下文选择:

现在的libpcap1.3.0支持一次捕获多个数据包, 通过指定pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)接口中的cnt变量,而且现在的捕包不是基于recvmsg的系统调用,而是共享内存队列,所以大大减少了上下切换。

3.4数据拷贝和内存分配消耗:

由于采用了现在的共享内存环形队列,即零拷贝技术,用户态和内核态只有一份数据拷贝,所以捕获每个数据包都减少了一次数据拷贝。

4.  延伸拓展

4.1 libpcap多线程捕包

用什么样的多线程架构方式更能发挥libpcap捕包性能?

4.2 Linux并行运算

使用多线程或移植到多线程的时候,有什么注意事项?

4.3 零拷贝发包

既然操作系统有“PACKET_RX_RING”这个关键字支持零拷贝捕包,那会不会也有零拷贝发包呢?

5. 参考资料:

Libpcap-MT:一种多线程的通用数据包捕获库

温曙光,文献资料

高速网络数据包捕获技术研究

郭占东,文献资料

网络安全开发包详解

刘文涛,书籍

基于 linux 平台的 libpcap 源代码分析

施聪,IBM论坛

PACKET_MMAP's documentation

Uaca,国外网络资料

转载于:https://www.cnblogs.com/dodng/p/4367734.html

基于Linux平台的libpcap源码分析和优化相关推荐

  1. 【SemiDrive源码分析】【X9芯片启动流程】08 - X9平台 lk 目录源码分析 之 目录介绍

    [SemiDrive源码分析][X9芯片启动流程]08 - X9平台 lk 目录源码分析 之 目录介绍 一./rtos/lk/ 目录结构分析 1.1 /rtos/lk_boot/ 目录结构分析 1.2 ...

  2. linux显示启动logo源码分析以及修改显示logo

    1.linux显示启动logo整个流程分析 (1)logo图片在内核源码中是以ppm格式的文件保存,在编译内核时会把ppm格式的文件自动转换成.c文件,在c文件中会构造一个struct linux_l ...

  3. Linux brk(),mmap()系统调用源码分析3:brk()的内存申请流程

    Linux brk(),mmap()系统调用源码分析 brk()的内存申请流程 荣涛 2021年4月30日 内核版本:linux-5.10.13 注释版代码:https://github.com/Rt ...

  4. linux nDPI 协议检测 源码分析

    关于nDPI的基本功能就不在这介绍了,有兴趣了解的读者可以阅读官方的快速入门指南:https://github.com/ntop/nDPI/blob/dev/doc/nDPI_QuickStartGu ...

  5. Linux系统编程 / triggerhappy 源码分析(3.select 的应用)

    哈喽,我是老吴,继续记录我的学习心得. 一.进步的滞后性 我们期望进步是线性: 每一个人付出一些努力后,都希望它有立竿见影的效果. 现实是: 做出努力后,结果的显现往往滞后. 只有在几个月或几年后,我 ...

  6. mosquito源码分析和优化

    源码分析 Mosquito的优化--epoll优化(七) Mosquito的优化--订阅树优化(八) Mosquito的优化--其他优化(九) 其它问题

  7. 基于 linux 平台的 libpcap 源代码分析

    libpcap 是 unix/linux 平台下的网络数据包捕获函数包,大多数网络监控软件都以它为基础.Libpcap 可以在绝大多数类 unix 平台下工作,本文分析了 libpcap 在 linu ...

  8. linux gnu binutils,binutils源码分析之准备篇

    1.什么是binutils 先写一个简单的hello_world.c程序. #include int main() { printf("Hello World!\n"); retu ...

  9. linux之虚拟文件系统源码分析(详解)

    文章目录 前言 基础知识 VFS的数据结构 正篇 前言 ​ 虚拟文件系统是一个很庞大的架构,如果要分析的面面俱到,会显得特别复杂而笨拙,让人看着看着,就不知所云了(当然主要还是笔者太菜),所以这篇博客 ...

  10. Java -- 基于JDK1.8的LinkedList源码分析

    1,上周末我们一起分析了ArrayList的源码并进行了一些总结,因为最近在看Collection这一块的东西,下面的图也是大致的总结了Collection里面重要的接口和类,如果没有意外的话后面基本 ...

最新文章

  1. java基础(十三)-----详解内部类——Java高级开发必须懂的
  2. 基于Qt的OpenGL可编程管线学习(9)- X射线
  3. 这个操作稳!云厂商开设免费云计算课程,学员独享49元主机套餐包年!
  4. 结构型模式:桥接模式
  5. U811.1接口EAI系列之六--物料上传--VB语言
  6. iphone日历显示周视图_用敬业签记录放假安排 2021年放假安排日历
  7. 手机User-Agent大全(Android爬虫)
  8. Flash Builder4.6 入门Demo_trace
  9. PostgreSQL的pg_hba.conf文件讲解
  10. 江苏实时分析评价系统项目总结报告
  11. MySQL 中的日期时间类型
  12. 求二叉树中某结点的父结点(左右孩子表示法)
  13. radius服务器连接无线网络,验证RADIUS服务器连接用测验AAA RADIUS命令
  14. 32位win10服务器系统,win10原版32位
  15. RBAC 模型是什么?
  16. 认证认可机构收费项目和标准
  17. 【Rust日报】 2019-01-26
  18. 计算机开机屏幕英语,电脑开机进不了系统,屏幕一堆英文数字怎么办?别急有方法...
  19. Selenium小技巧 修改ip+ua 改变窗口大小 手机模式 加载本地缓存
  20. [计算机网络] 域名系统

热门文章

  1. apache的开源项目-模板引擎(Velocity)(转)
  2. 玩转html5(三)---智能表单(form),使排版更加方便
  3. C++字符串拼接效率比较(+=、append、stringstream、spintf)
  4. 小辣椒android密码怎样开,小辣椒手机忘记密码怎么恢复出厂设置
  5. python统计图的三层结构设计代码_【Python数据可视化】用Matplotlib绘制常见统计图,中文显示字体任意设置...
  6. android 7.0 截图,Android,_7.0系统拍照后,使用系统截图功能,截图保存时崩溃如何解决,Android - phpStudy...
  7. python 函数定义位置_PYTHON--函数定义
  8. Nginx源码分析 - 基础数据结构篇 - 双向链表结构 ngx_queue.c(05)
  9. ribbon基于接口配置超时_Spring Cloud第二篇:服务消费者RestTemplate+Ribbon
  10. java使用mysql的escape遇到的坑