Linux网络抓包工具tcpdump是如何实现抓包的,在哪个位置抓包的?

Linux网络抓包工具tcpdump是如何实现抓包的,在哪个位置抓包的?

  • 1. tcpdump抓包架构
  • 2. BPF介绍
  • 3. 从内核层面看tcpdump抓包流程
    • 3.1. 创建socket套接字
    • 3.2. 挂载BPF程序
  • 4. 网络收包抓取
  • 5. 网络发包抓取
  • 6. 疑问和思考
    • 6.1 tcpdump抓包跟网卡、内核之间的顺序是怎么样的?
    • 6.2 tcpdump抓包分析到服务端响应ping延迟,怎么判断是是客户端到服务端的传输过程慢还是服务端的内核处理慢?
  • 7. 参考文档

随着G行架构从集中式体系向分布式式体系转型,行内系统服务快速增多,不同的服务短期内需要在集中式体系、分布式体系之间互相调用,调用链复杂,网络通讯相关问题时有发生。系统管理员在排查网络问题时就用到一款网络抓包工具tcpdump,该工具可以将网络中传送的数据包完全截获下来进行分析,能有效的排查复杂环境的网络问题。本文将从原理的角度分析tcpdump在Linux系统的实现。

主要是希望能够分析实现原理,以协助判断tcpdump抓的是网卡的包,还是经过内核处理后的包?对于分析服务器处理网络包过程有很大帮助。


1. tcpdump抓包架构

tcpdump由C语言开发,主要功能通过libpcap库实现,而libpcap是linux平台下的一个网络数据包捕获功能包, 通过内核BPF技术实现数据过滤功能。tcpdump使用BPF虚拟机的指令集定义过滤器表达式,然后传递给内核,并由解释器执行,这使得包过滤可以在内核中进行,避免了向用户态进程复制全部数据包,从而提升数据包的过滤性能。tcpdump将包过滤指令注入到内核,返回按条件过滤的数据包,提供多种输出功能将抓取的报文格式化处理能力。

在这里插入图片描述

tcpdump的包过滤指令由BPF代码实现,通过对libpcap库的调用可以把一个输入输出的逻辑表达式变为BPF代码,实现在用户输入的命令行和BPF代码之间的转换。tcpdump 程序支持使用 -d参数来 dump 出过滤规则转化后的BPF指令字节码。

2. BPF介绍

BPF(Berkeley Packet Filter ),中文翻译为伯克利包过滤器,是类 Unix 系统上数据链路层的一种原始接口,提供一种网络数据包过滤方法。随着技术的发展,人们在BPF的基础上又提出了eBPF(extended BPF)。经过重新设计,eBPF 演进为一个通用执行引擎,在不更改内核代码的前提下,实时获取和修改操作系统的行为,可基于此开发性能分析工具、软件定义网络等诸多场景,而原来的BPF则称为cBPF(classic BPF)。

现在,Linux 内核只运行eBPF,内核会将加载的cBPF字节码透明地转换成 eBPF再执行。eBPF新的设计针对现代硬件进行了优化,eBPF 生成的指令集比旧的 BPF 解释器生成的机器码执行得更快。扩展版本也增加了虚拟机中的寄存器数量,将原有的2个32位寄存器增加到10个64位寄存器。

eBPF 程序需要挂载到某个内核路径(挂载点)才能被执行,常见的挂载点有:系统调用,内核函数进入/退出,内核跟踪点,网络数据包等等,根据挂载点功能的不同,可以分为以下四类,tcpdump挂载点即为第二类:

  1. 性能跟踪(kprobes/uprobes/tracepoints)
  2. 网络(socket/xdp)
  3. 容器(cgroup)
  4. 安全(seccomp)

在这里插入图片描述
cpdump使用的包过滤指令即为cBPF,内核将提交来的cBPF字节码转化成eBPF代码加载进BPF虚拟机中,使用系统调用函数setsockopt()将BPF 程序挂载在 socket套接字上,进而过滤数据包,而BPF代码是则由内核调用BPF运行函数__bpf_prog_run()来执行。

3. 从内核层面看tcpdump抓包流程

众所周知,应用在接收报文的时候,硬件的硬中断首先触发内核的 软中断 ,通过 内核驱动程序 进入 网络设备层 进行数据包的处理,然后数据包进入 协议栈 的网络层和传输层,最后被用户进程接收。

而应用在发送报文时,首先经过内核的 协议层 ,由邻居子系统实现L3层ip地址转化为L2层mac地址,然后进入 网络设备层 ,数据包处理完成后,经 驱动程序 流转,最后由 硬件 将报文发出。

tcpdump为了能抓取数据包,首先需要创建socket套接字,用于在应用系统接收和发送报文时获取抓取的数据包,然后将过滤条件也就是对应的BPF程序注入到内核网络设备层,获取过滤后的数据包后再进行格式化处理。


在这里插入图片描述

说明
在生产中常见的,如果单个cpu核心被持续打满,会影响内核将网络包从队列中取出,并存放到协议栈,从而导致机器响应包延迟

在硬件接收到网络包,触发硬中断后,将相关网络包存放到内部队列,队列满后出发软中断通知内核接受相关的流量包,内核接收流量包后,对应的队列清空以继续接收后续的流量包,这个过程占用的cpu很少。

内核接收到软中断信号后,会调用cpu资源以接收相关的流量包,放到协议栈并进行后续的处理。如果软中断很频繁,内核就需要频繁的调用cpu响应,会很需要消耗cpu资源。特别是如果内核响应软中断的cpu绑定到固定某个cpu核时,表现更为明显

3.1. 创建socket套接字

tcpdump首先通过libpcap库,调用socket()函数创建PF_PACKET套接字,该套接字提供L2层抓包分析能力,所有的底层L2包都会给到PF_PACKET 模块的回调处理函数即下文的网络收包和发包都用到的内核函数packet_rcv()函数,通过该函数将数据包写入到缓存队列,libpcap库使用系统调用函数recvfrom ()复制一份数据给tcpdump。

在这里插入图片描述

3.2. 挂载BPF程序

tcpdump使用libpcap库的pcap_compile()函数将用户制定的过滤策略转换为BPF代码,然后使用pcap_setfilter()函数调用install_bpf_program()函数装载BPF程序,install_bpf_program()函数调用系统调用函数setsockopt(),设置SO_ATTACH_FILTER参数将BPF程序下发给内核底层,将规则注入到内核,设置过滤器,从而让规则生效。

在这里插入图片描述

4. 网络收包抓取

应用接收报文时,在网络设备层,驱动程序首先调用内核函数netif_receive_skb(),通过deliver_skb()调用回调函数packet_rcv(),并使用BPF运行函数__bpf_prog_run(),来执行BPF程序过滤数据包,然后将数据包存入队列,最终复制数据包给tcpdump。而应用接收数据包则根据包的协议,选择udp或者tcp将报文送到用户进程。

在这里插入图片描述

5. 网络发包抓取

应用在发送报文时,首先通过邻居子系统进入网络设备层,然后调用内核函数dev_hard_start_xmit(),该函数同样使用网络收包流程中使用的deliver_skb()函数调用回调函数packet_rcv(),并通过调用BPF运行函数__bpf_prog_run(),来执行BPF程序过滤数据包,然后将数据包存入队列,最终复制数据包给tcpdump。而应用发送数据包则通过驱动程序发送出去。

在这里插入图片描述

6. 疑问和思考

6.1 tcpdump抓包跟网卡、内核之间的顺序是怎么样的?

TCPDump实际上是通过libpcap库来实现的,它可以在网卡和内核之间获取数据包。
当你运行tcpdump时,它会使用libpcap库来打开一个网络接口,这样就可以捕获该接口上的数据包。libpcap库通过操作系统提供的类似于BPF(Berkeley Packet Filter)的机制来实现这一点。这种机制允许libpcap指定一组过滤规则,以便仅捕获符合这些规则的数据包。一旦数据包被捕获,libpcap会将其传递给TCPDump进行进一步处理,最终以用户友好的方式呈现给用户。
所以,tcpdump获取的数据包实际上是在 网卡和内核之间 获取的,它通过libpcap库利用操作系统提供的网络抓包机制来实现。

6.2 tcpdump抓包分析到服务端响应ping延迟,怎么判断是是客户端到服务端的传输过程慢还是服务端的内核处理慢?

通过6.1的问题知道了tcpdump是在网卡和内核之间的,通过tcpudump抓包

  • 收包还没有经过内核处理
  • 发包需要内核协议栈处理后,经过tcpdump到达网卡

因此只需要在服务端和客户端抓包

  1. 对比相同一个包,在客户端发出后和服务端接收到的时间查,这个是客户端和服务端网卡之间的流量传输过程
  2. 在对比,服务端抓到的包中,收发2个包之间的时间差,这个时间差就是服务端收到包后的响应时间差
  3. 对比这两个时间差,就能知道时间主要消耗在哪个层面

如下图可以获知,客户端到服务端之间传输耗时1s,但是服务端处理很快
在这里插入图片描述

如下图可以获知,服务端接收到网络包后处理时间耗时1s,由于只是做简单的ping命令,因此主要的耗时消耗在内核上,还需要配合排查处理内核中断的cpu使用率是否很高,才能进一步分析问题原因。

在这里插入图片描述

7. 参考文档

暂无

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/5018.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL | 第八篇】在MySQL中,如何定位慢查询以及对应解决方法?

文章目录 8.在MySQL中,如何定位慢查询以及对应解决方法?8.1MySQL慢查询日志8.1.1开启慢查询(1)修改配置文件(2)设置全局变量 8.1.2日志记录在表上(实践)8.1.3日志记录在文件上&#…

大数据开发工作中的数仓设计(Hadoop,hive ,mysql )

1.HUE工具介绍使用 HUE是CDH提供一个hive和hdfs的操作工具,在hue中编写了hiveSQl也可以操作hdfs的文件 http://主机名字:端口号 hdfs的web访问端口 http://主机名字:端口号 hdfs的程序访问端口 进入后确保hdfs hive yarn 开启 在点击hue开启 在这里面也可以进行h…

Xinlinx FPGA如何降低Block RAM的功耗

FPGA中降低Block RAM的功耗有两种方式,分别是选择合适的写操作模式以及Block RAM的实现算法及综合设置。我们知道对于采用IP核生成对应的RAM时,会有最小面积算法、低功耗算法以及固定原语,但是采用最小功耗算法有时由于级联长度导致无法实现&…

币圈Cryptosquare论坛

Cryptosquare综合性资讯论坛汇集了币圈新闻、空投信息、社会热点以及与Web3相关的工作信息。让我们一起解锁加密世界的种种可能性,探索Cryptosquare论坛带来的精彩! 币圈新闻板块: Cryptosquare论坛的币圈新闻板块是用户获取最新加密货币行业…

Elasticsearch中【文档查询】DSL语句以及对应的Java实现

目录 全文检索查询 精准查询 布尔查询 排序、分页查询 高亮 地理查询 复合查询 Elasticsearch提供了基于JSON的DSL(Domain Specific Language)来定义查询。常见的查询类型包括: 查询所有:查询出所有数据,一般测…

全新突破:「Paraverse平行云」实现3D/XR企业级应用全面接入Apple Vision Pro

在前不久举行的GTC开发者大会上,英伟达引领行业风向,宣布其Omniverse平台能够助力企业将3D/XR应用流畅传输至Apple Vision Pro混合现实头显。在英伟达与苹果这两大科技巨头的合作下,此举标志着3D/XR技术迈向新纪元的关键一步。「Paraverse平行云」实时云…

《HCIP-openEuler实验指导手册》1.6 Apache静态资源配置

知识点 常用用途: 软件仓库镜像及提供下载服务: 配置步骤 删除网站主目录中的文件(本实验机目录为/home/source ip为192.168.12.137 端口为81) cd /home/source rm -rf *在主目录中新建6个文件夹如下图 mkdir test{1..6}新建…

将本地.mp4推流成rtsp流?(windows)

概述 如何在本地机器上进行rtsp推流整个操作? 1.软件安装 1. 推流-ffmpeg下载 从官网下载windows版本,该版本已经编译好了 放到C:下找一个目录解压,我放到C:\ffmpeg-7.0-essentials_build\进入系统环境变量设置:将…

使用nodejs和python脚本实现爬虫程序,并将抓取数据生成词云图看板

创建项目,初始化目录结构。 创建项目名称为pachong。运行 npm init -y 初始化项目。修改package.json文件中的type属性为module。安装 npm 包:npm install puppeteer #爬虫 | 自动化UI测试首先确保你的电脑上有python3环境安装两个python包 pip instal…

c#数据库: 8.在窗体上显示学生信息

以上一章学生信息表为例,首先将查询的学生信息存储到数据集中,然后将数据集与数据显示控件绑定,从而实现学生信息在窗体上的显示 (1)创建一个名为StudentGridView的窗体应用程序,为窗体添加一个DataGridVi…

Stable Diffusion 模型分享:Counterfeit-V3.0(动漫)

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里,订阅后可阅读专栏内所有文章。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八 下载地址 模型介绍 高质量动漫风格模型。 条目内容类型大模型基础模…

Java进阶-JINQ详解与使用

本文详细介绍了JINQ(Java Integrated Query),一种强化Java中数据查询能力的库,提供类SQL的查询语法和类型安全的操作。文章首先解释了JINQ的基本功能和应用,随后通过具体示例展示了如何使用JINQ进行数据过滤、投影、连…

Unity镂空图像做法

问题和解决方案 现在要完成一个需求,即镂空中间部分的image,外围image可以定义颜色并可选屏蔽点击,而中间的image需要透明且可以穿透,必须不能屏蔽点击。 由此拆分成了两个问题: 1.定义外围image颜色,内…

Facebook的语言学:社交媒体如何影响我们的沟通方式

1. 引言 社交媒体已经成为人们日常生活中不可或缺的一部分,而Facebook作为其中最具影响力的平台之一,不仅改变了人们之间的社交方式,也对我们的语言学产生了深远的影响。本文将深入探讨Facebook的语言学特点,以及它如何塑造和改变…

Spring6 当中 获取 Bean 的四种方式

1. Spring6 当中 获取 Bean 的四种方式 文章目录 1. Spring6 当中 获取 Bean 的四种方式每博一文案1.1 第一种方式:通过构造方法获取 Bean1.2 第二种方式:通过简单工厂模式获取 Bean1.3 第三种方式:通过 factory-bean 属性获取 Bean1.4 第四种…

【保姆级教程】用IDEA2023版本给RuoYi-Vue添加子模块

文章目录 前言添加子模块新建子模块新建子模块界面?新建子模块界面! 修改pom依赖配置RuoYiApplication添加测试接口配置接口权限测试 前言 若依前后端分离框架能够极大方便当前开发任务,并且使用的技术栈也相当丰富,但是目前只提…

Docker 中安装单体架构 Redis 的 Shell 脚本

该脚本用于实现 root 用户在 Linux 操作系统下的 Docker 中安装单体架构 Redis Shell 脚本 Git 仓库地址 Gitee:https://gitee.com/tongchaowei/common-shell/tree/main/root 执行脚本 bash ./docker-redis-install-single.sh需要注意的 该脚本会先检查是否安…

数学建模--图论最短路径基础

1.图的定义 学过数据结构或者离散数学的小伙伴们应该知道图的概念,我在这里简单的介绍一下: 图的概念和我们理解的是很不一样的,这里的图并不是我们的生活里面的图片,而是一种表示不同的数据之间的关系,例如这里的5个…

C++中auto关键字的用法详解

1.简介 auto作为一个C语言就存在的关键字,在C语言和C之间却有很大区别。 在C语言中auto修饰的变量,是具有自动存储器的局部变量,但因为局部变量默认类别默认是auto修饰导致一直没有人去使用它。 C11中,标准委员会赋予了auto全新…

XY_RE复现(二)

一,何须相思煮余年 0x55 0x8b 0xec 0x81 0xec 0xa8 0x0 0x0 0x0 0xa1 0x0 0x40 0x41 0x0 0x33 0xc5 0x89 0x45 0xfc 0x68 0x9c 0x0 0x0 0x0 0x6a 0x0 0x8d 0x85 0x60 0xff 0xff 0xff 0x50 0xe8 0x7a 0xc 0x0 0x0 0x83 0xc4…