Wireshark 学习笔记

Wireshark 学习笔记

Wireshark 是网络技术学习中会经常用到的一个抓包分析工具,若想对网络协议有更深一步的理解,可以深入的学习一下 Wireshark 的内部实现,这篇学习笔记就是我最近学习研究的一些心得,后续将不定期更新。

对于大部分使用者来说,可以相对熟练使用 Wireshark 抓包并进行简单分析就够了。对于一些网络工程师来说,可以借助 Wireshark 一些自带功能并结合网络数据包信息来分析网络问题,可以说是比较高级的使用了。这方面推荐两本相关书籍《Wireshark网络分析就这么简单》,《Wireshark网络分析的艺术》,作者林沛满,微信读书上有这两本书的电子版。

在网络上搜索 Wireshark一般也是各种使用技巧,对于内部实现机制介绍的比较少,仅有的一部分很大比例是介绍如何使用 C 语言或者 Lua编写 dissector,中文可以译作解析器。既然这样,如果想了解 Wireshark 一些内部实现机制,只好老老实实去官网找资料了。

官网地址 Wireshark · Go Deep

这是Wireshark的官方网站,这页面显示目前支持的稳定版本,截止本文撰写之时,稳定版本为3.6.16和4.0.8,开发版本为4.1.0,以及配套的Docmentation(这个文档对应的是master主线,也就是上述开发版本)。除此之外,可以从如下几个大类来学习Wireshark。

Get Help (主要面向用户)

  1. Ask a Question 使用中遇到问题可以在这里提问求助
  2. FAQs 一些常见问题
  3. Documentation 在线帮助文档
  4. Mailing Lists 邮件列表
  5. Online Tools 在线工具
  6. Issue Tracker 问题跟踪工具
  7. Wiki Wiki页面

Contribute (主要面向开发者)

  1. Developer’s Guide 开发者指导
  2. Browse the Code 浏览代码

所以从上述分类来看,对于开发主要是两块内容:开发者指导,以及代码库。Wireshark和其他很多开发项目不同之处在于,Wireshark的代码库使用 GitLab,GitHub 上的代码只是同步的镜像,不接受PR,不处理issue。GitLab 的好处是连接速度快且稳定,对于很多使用GitLab 做为主力版本管理工具的人来说,学习成本也比较低,其实GitLab 与GitHub 很多操作都比较接近。另外,在国内可以在手机上使用JiHu GitLab 连接 GitLab 服务器,也就是说可以手机上看 Wireshark 的源代码,有些时候还是很方便的。

Wireshark Developer’s Guide

  1. 主要内容介绍

这里是开发者需要了解的一些主要内容,但不是全部,因为代码目录中的 doc 还有很多开发者需要阅读的文章,那里有更加细致的说明。我理解这个开发者指南就是一份开发地图,你可以通过他找到你关心的,但不要指望这里有所有的东西。

比如在Foreword中提到,对于 Windows 环境下的开发者而言,构建编译环境可能更具有挑战,因为很多方法和工具对于 UNIX 环境来说很普通,但是 Windows 上就要费一番周折。如果你选择开发环境,读过这里你就对 Windows 下的开发有心理准备了。当然你可以在 UNIX 下开发 Windows 下的程序,不过这又需要交叉编译了,去开发者指南看看有没有这方面介绍。

对于很多想参与 Wireshark 的开发者而言,从修改一个已经支持的解析器开始是个不错的选择,开发者指南也是这么推荐的。如果选择用 Lua 其实都不用太关注 Wireshark 代码及编译,只需要看看一些接口怎么调用就行,如果你要用 C 语言来完成,那就要多做很多工作了,特别是你想将解析器内置到 Wireshark 版本中,而这就是你 Wireshark 开发之路最好的开始。

1) 构建环境

这部分主要介绍如何搭建编译环境,如何在不同的平台编译Wireshark,如何进行调试,以及一些工具介绍。

2) 开发相关

这部分介绍Wireshark的内部机制,包括软件框架,主要组件,抓包机制,解析器机制,Lua 支持及API, UI实现,test测试。

上图(Wireshark function blocks)是Wireshark功能模块,灰色背景是Wireshark程序,下面的Dumpcap是独立于Wireshark的一个程序,但是也在Wireshark安装目录中,主要负责和抓包工具WinPcap/libpcap交互,之所以这么设计是为了将Wireshark完全放在用户模式下,具体可以看这里的说明。其实我们每次用Wireshark抓包的时候,都会在系统的Temp目录临时生成一个抓包文件(pcapng格式),当停止抓包的时候,会将内存中所有的抓包数据都存储到这个文件中(可以在Wireshark主界面的左下角看到临时文件的名称和路径)。所以当我们保存抓包数据的时候,其实是将临时文件保存到我们需要的目录中。抓包其实就是Wireshark通过Dumpcap来实现的,后面Wireshark再通过Wiretap模块读写硬盘上的pcapng文件,进而通过dissector(解析器)来分析文件。

Wireshark Code Repository

  1. 如何获取代码

看似很简单的问题吧,但是实际上有点小难度。因为如果你直接用git clone命令,可能会遇到下面的错误提示:

Cloning into 'wireshark'...
remote: Enumerating objects: 706486, done.
remote: Counting objects: 100% (1440/1440), done.
remote: Compressing objects: 100% (839/839), done.
error: RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2)
error: 56757 bytes of body are still expected
fetch-pack: unexpected disconnect while reading sideband packet
fatal: early EOF
fatal: fetch-pack: invalid index-pack output

根据上面的错误提示“RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly”在搜索引擎找一下,很大概率是教你如何设置 Git 的缓存大小,或者修改SSH方式。其实官网针对这个问题有些提示,具体参考这里:

https://www.wireshark.org/docs/wsdg_html_chunked/ChSrcObtain.html#ChSrcGit。

其中提到:

Next, clone the Wireshark repository:

# If you have a GitLab account, you can use the SSH URL:
$ git clone -o upstream git@gitlab.com:wireshark/wireshark.git
# If you don't you can use the HTTPS URL:
$ git clone -o upstream https://gitlab.com/wireshark/wireshark.git
# You can speed up cloning in either case by adding --shallow-since=1year or --depth=5000.
The clone only has to be done once. This will copy all the sources (including directories) from the server to your machine and check out the latest version.

The -o upstream flag uses the origin name “upstream” for the repository instead of the default “origin” as described in the GitLab documentation.

Cloning may take some time depending on the speed of your internet connection.

The --shallow-since=1year option limits cloned commits to the last 1 year.

The --depth=5000 option limits cloned commits to the last 5000.

也就是说,通过添加- -shallow-since=1year 或 – -depth=5000选项来降低git clone commit的数量来加快git clone的速度。因为对于大部分人来说,1年前或者5000个commit之前的信息基本都用不上。在我的开发环境里,最后当depth配置为100的时候,git clone成功。

Cloning into 'wireshark'...
remote: Enumerating objects: 7939, done.
remote: Counting objects: 100% (7939/7939), done.
remote: Compressing objects: 100% (6950/6950), done.
remote: Total 7939 (delta 1759), reused 3508 (delta 936), pack-reused 0
Receiving objects: 100% (7939/7939), 57.33 MiB | 101.00 KiB/s, done.
Resolving deltas: 100% (1759/1759), done.
Updating files: 100% (6662/6662), done.

由上述显示可以看出,Enumerating Ojbects已经由最初的706486降低为7939,所以 Git 相关文件大小减少了很多,这样git clone起来才快了很多。

这个方法 会带来两个问题: 1) 只能看指定个数内的 commit 记录;2) 无法切换到其他远程分支。对于这两个问题,可以查看这篇文章。需要提醒的是,如果想要同时实现二者,则需要同时执行上面提到的两个配置才能都生效。

另外,如果depth配置的如果大了还可能出现下面的错误信息:

$ git clone --depth=100 git@gitlab.com:thinkdancer/wireshark.git
Cloning into 'wireshark'...
remote: Enumerating objects: 8106, done.
remote: Counting objects: 100% (8106/8106), done.
remote: Compressing objects: 100% (7078/7078), done.
ssh_dispatch_run_fatal: Connection to 2606:4700:90:0:f22e:fbec:5bed:a9b9 port 22: message authentication code incorrect
fetch-pack: unexpected disconnect while reading sideband packet
fatal: early EOF
fatal: fetch-pack: invalid index-pack output

上面depth配置为100,一次成功一次失败,原因是这是两次不同的git clone,因为commit变化了,所以同样的100其实数据是不一样的。

除了在 PC 端通过代码编辑器,比如现在大火的 VS Code,还可以在手机端用 JuHu GitLab 查看代码,当然如果要修改代码还是 PC 端更高效一些。

Comments are closed.