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

2024-04-29 13:36

本文主要是介绍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. 参考文档

暂无

这篇关于Linux网络抓包工具tcpdump是如何实现抓包的,在哪个位置抓包的?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/946234

相关文章

linux-基础知识3

打包和压缩 zip 安装zip软件包 yum -y install zip unzip 压缩打包命令: zip -q -r -d -u 压缩包文件名 目录和文件名列表 -q:不显示命令执行过程-r:递归处理,打包各级子目录和文件-u:把文件增加/替换到压缩包中-d:从压缩包中删除指定的文件 解压:unzip 压缩包名 打包文件 把压缩包从服务器下载到本地 把压缩包上传到服务器(zip

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo