news 2026/9/23 1:53:34

Scapy 开发指南:从 UTScapy 测试框架到发布打包的完整协作流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Scapy 开发指南:从 UTScapy 测试框架到发布打包的完整协作流程
  • 网络
  • 网络安全

【免费下载链接】scapy

Scapy: the Python-based interactive packet manipulation program & library.

项目地址:https://gitcode.com/gh_mirrors/sc/scapy
点击查看免费下载

导读

Scapy 是一套基于 Python 的交互式数据包操作程序与库。本指南聚焦 Scapy 项目开发侧的完整协作链路:如何参与贡献、如何用 UTScapy 编写和运行回归测试、如何借助 tox 与./test/run_tests快速验证代码,以及维护者如何完成签名发布与打包。读完本文,你将掌握.uts测试语法的每一个控制符、UTScapy 全部命令行参数与配置文件的含义,并能在本仓库中亲自运行一套完整或子集的测试。


项目组织与协作入口

Scapy 的开发使用 Git 版本控制系统,参考仓库位于 secdev/scapy。项目管理基于 GitHub,提供可自由编辑的 Wiki(欢迎贡献),可用于引用 ticket、变更集与项目文件;同时提供 ticket 管理服务,避免补丁或 Bug 被遗忘。

对贡献者而言,官方建议的参与方式包括:

  • 发现 Bug 时新建 ticket;
  • 改进本文档(文档质量同样属于贡献);
  • 编写新的协议层,并通过邮件列表分享或直接提交 pull request;
  • 贡献新的回归测试;
  • 在 packet samples 页面提交新协议的抓包样本。

这些通道中,回归测试与文档改进都与本仓库内test/目录和 UTscapy 实现 直接相关,下文展开说明。


改进文档:docstring 与用法示例

文档可以从两个层面改进:

  1. 为源码补充 docstring:Scapy 源码中对函数行为的解释较少。一个包含预期输入输出说明的 docstring,能为协议层开发者和查找高级特性的用户都节省时间。
  2. 为文档增加使用示例:保持文档与最新版 Scapy 同步,并添加来自官方演示或自有实践的用法示例。

docstring 的推荐写法

文档以scapy.fields.FlagsField类为例给出范本:先写一行类的简短描述,再给出使用说明;如果合理,可以加入采用 doctest 格式的可执行示例;最后按 Sphinx Python 签名规范补充经典签名。原文示例(节选核心结构)如下:

class FlagsField(BitField): """ Handle Flag type field Make sure all your flags have a label Example: >>> from scapy.packet import Packet >>> class FlagsTest(Packet): fields_desc = [FlagsField("flags", 0, 8, ["f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7"])] >>> FlagsTest(flags=9).show2() ###[ FlagsTest ]### flags = f0+f3 >>> FlagsTest(flags=0).show2().strip() ###[ FlagsTest ]### flags = :param name: field's name :param default: default value for the field :param size: number of bits in the field :param names: (list or dict) label for each flag, Least Significant Bit tag's name is written first """

写 docstring 的工作通常与编写非回归单元测试成对进行——好文档要能被测试验证,好测试也需要文档解释意图。该FlagsField类在 scapy/fields.py 中实现。


用 UTScapy 做测试:概念与语法

什么是 UTScapy

UTScapy 是一个小型 Python 程序,位于 scapy/tools/UTscapy.py:它读取一个测试战役(campaign)文件,用 Scapy 执行这批测试,并生成报告。报告支持四种格式:text、ansi、HTML、LaTeX(当前源码还额外支持 xUnit 与 live,见下文“输出格式”)。

UTScapy 有三个基本测试容器:

  • 单元测试(unit test):一组将交由 Scapy(或其衍生版本)执行的 Python 命令。单元测试中最后一条命令的求值结果决定该单元测试的成败。
  • 测试集(test set):若干相关联单元测试的分组。
  • 测试战役(campaign):由一个或多个测试集组成。

测试集和单元测试都可以打上关键字(keywords),用于形成逻辑分组;运行战役时可按关键字筛选,从而只执行目标分组的测试。

测试签名:CRC32 与 SHA1

对每个单元测试、测试集和战役,UTScapy 都会计算其CRC32并作为该测试的签名显示。签名足以确认实际运行的测试与预期一致、未被修改;为防止有人恶意篡改文件同时保持 CRC32 不变,UTScapy 还会对整个文件计算一次全局SHA1

在源码中,compute_campaign_digests 展示了签名的精确计算方式:对单元测试取其剥离空白后的文本t.test.strip()计算 CRC32;测试集把所有成员测试以\0分隔后整体计算;战役则在各测试集前加\0\x01后整体计算;最后再读取整个测试文件计算 SHA1。命令行参数-C可关闭签名计算。

测试战役语法(Syntax Specifiers)

UTScapy 通过行首字符识别语法,语法指示符必须是测试文件每行的第一个字符;其后跟的文本是 UTScapy 解释的参数。没有语法指示符的行只要位于单元测试上下文中就会被当作 Python 命令执行;若出现在错误上下文,UTScapy 会拒绝并发出警告。

语法指示符含义
%给出测试战役的名称
+声明一个新的测试集
=声明一个新的单元测试
~为当前单元测试声明关键字
*表示一条会被包含进报告中的注释
#测试用例注释,解释器直接丢弃

注释的上下文归属规则

写入测试报告的注释带有上下文:每条注释都归属于最近定义的那个测试容器(单元测试、测试集或战役)。同一容器下的多条注释会被拼接起来,紧跟在对应容器的声明之后出现在报告中:

  • 整个文件的通用注释应放在声明测试战役之前
  • 与战役关联的注释,必须出现在战役声明之后、任何测试集或单元测试之前
  • 与测试集关联的注释,应放在该测试集第一个单元测试定义之前。

通用战役结构模板

% Test Campaign Name * Comment describing this campaign + Test Set 1 * comments for test set 1 = Unit Test 1 ~ keywords * Comments for unit test 1 # Python statements follow a = 1 print(a) a == 1

Python 语句靠“没有已定义的 UTScapy 语法指示符”来识别,被直接送入 Python 解释器,如同在交互式 Scapy shell(interact)中操作。循环、迭代和条件语句都允许,但必须以一个空行结尾。一个测试集可由多个单元测试组成,一个战役可定义多个测试集,甚至一个测试定义文件中可以包含多个测试战役。

关键字(keywords)的使用

关键字允许只测试整个战役的子集。例如开发测试战役期间,可以给尚在开发的测试打上debug关键字;当这些测试稳定通过后,再移除debug。也可以使用regressionlimited之类的关键字做逻辑分组。命令行中通过-k(仅保留)和-K(排除)配合关键字进行筛选。

成败判定规则

UTScapy取最后一个 Python 语句的真值作为测试通过与否的指标。最后一行可以包含多个逻辑测试;结果为0False则测试失败,否则通过。如果需要强制校验中间值,应使用assert()语句——这一点在源码 run_test 中得到印证:resNone或真值时测试判定为passed,且每个单元测试默认超时时间为 5 分钟(见 _run_test_timeout)。


UTScapy 命令行:完整参数表

UTScapy 的调用语法如下(摘自文档并对照 usage() 更新到当前实现):

Usage: UTscapy [-m module] [-f {text|ansi|HTML|LaTeX|xUnit|live}] [-o output_file] [-t testfile] [-T testfile] [-k keywords [-k ...]] [-K keywords [-K ...]] [-l] [-b] [-d|-D] [-F] [-q[q]] [-i] [-P preexecute_python_code] [-c configfile]

全部参数均可选。没有参数值的参数可以串在一起使用(如-lqF)。未指定测试文件时,测试定义从 读取;未指定输出文件时输出到 ;默认输出格式为ansi

参数参数值对 UTScapy 的含义
-ttestfile输入定义测试战役的测试文件(默认 = ,可多次使用,支持*通配符展开)
-Ttestfile-t使用*时,移除指定文件(可多次使用)
-ooutput_file测试战役结果的输出文件(默认 = )
-ftest输出报告格式:ansi、HTML、LaTeX、text(默认 = ansi);当前实现还支持xUnitlive
-l本地生成报告关联文件。对 HTML,生成 JavaScript 与样式表(离线可用)
-F仅展开失败的测试用例(默认在 HTML 输出中展开)
-b第一个战役失败后不停止(默认在首个失败战役处停止)
-d执行战役前打印一份简明的战役清单
-D打印简明战役清单后停止,不执行战役
-R将战役以 reStructuredText 格式导出(当前实现新增,用于生成文档示例)
-C不计算测试签名(CRC 与 SHA)
-cconfigfile加载.utsc配置文件(JSON),见下文
-i测试失败时进入 Python 解释器(交互调试)
-q执行测试时不向屏幕更新进度(quiet)
-qq静默模式(silent)
-ntestnum只执行指定编号的测试。测试编号可通过-d/-D获取;支持逗号分隔与区间,如1, 3-7, 12
-mmodule执行前加载额外模块并注入命名空间。适合测试 Scapy 衍生版本;注意:以__main__方式设计的衍生程序不会被 UTScapy 以__main__调用
-kkw1, kw2, ...只包含含关键字 kw1 的测试。可指定多个关键字(可多次使用)
-Kkw1, kw2, ...排除含关键字 kw1 的测试。可指定多个关键字(可多次使用)
-Ppython_code在运行测试前预执行一段 Python 代码
-N强制以非 root 模式运行
-x使用 pyannotate 收集类型注解信息

-t支持通配符展开:源码 resolve_testfiles 会用glob把包含*的参数展开为实际文件列表。-n的参数解析支持区间语法,见 main 中的-n分支。

此外,UTScapy 会自动按环境追加排除关键字:非 root 运行时排除needs_root测试;大端平台排除little_endian_only;libpcap 或 Windows 环境排除not_libpcap;Python 低于 3.8 时排除needs_py38plusdisabled关键字则始终被排除(见 main)。


完整示例:一个包含多个测试集的战役

下面是一个简单的多测试集战役示例,同时演示了关键字的子集筛选。注意第 3、5 个单元测试用assert()检查中间结果;第 2、5 个单元测试故意设计为失败

% Example Test Campaign # Comment describing this campaign # # To run this campaign, try: # ./UTscapy.py -t example_campaign.txt -f html -o example_campaign.html -F # * This comment is associated with the test campaign and will appear * in the produced output. + Test Set 1 = Unit Test 1 ~ test_set_1 simple a = 1 print(a) = Unit test 2 ~ test_set_1 simple * this test will fail b = 2 a == b = Unit test 3 ~ test_set_1 harder a = 1 b = 2 c = "hello" assert (a != b) c == "hello" + Test Set 2 = Unit Test 4 ~ test_set_2 harder b = 2 d = b d is b = Unit Test 5 ~ test_set_2 harder hardest a = 2 b = 3 d = 4 e = (a * b)**d # The following statement evaluates to False but is not last; continue e == 6 # assert evaluates to False; stop test and fail assert (e == 7) e == 1296 = Unit Test 6 ~ test_set_2 hardest print(e) e == 1296

要点回顾:单元测试 2 中a == b是最后一条语句且为False,因此失败;单元测试 5 中虽然e == 6为假,但它不是最后一条语句,真正导致失败的是assert(e == 7);单元测试 6 复用前一个测试留下的变量e(测试之间共享同一个交互式会话命名空间)。

仓库内真实示例

仓库自身的.uts测试文件就是最好的模板。以 test/scapy/crc.uts 为例,它展示了战役头、注释、测试集与单元测试的标准写法,且最后一个表达式p1 == p3 and p2 != p3 and p1 != p2直接作为通过判据。

运行与查看报告

将上面的示例保存为demo_campaign.txt后,可以用以下命令运行并生成 HTML 报告:

./test/run_tests -t demo_campaign.txt -f html -o demo_campaign.html -F -l

然后打开生成的demo_campaign.html查看结果。这里的-F让失败用例默认展开,-l把报告所需的 JS/CSS 生成为本地文件(离线可查看)。


用 tox 与 run_tests 测试 Scapy

tox:一键全量测试

tox命令简化了 Scapy 的测试:它会自动创建虚拟环境并安装必需的 Python 模块。例如在全新 Debian 上,下面这条命令无需任何外部依赖即可启动全部单元测试:

tox -- -K vcan_socket -K tcpdump -K tshark -K nmap -K manufdb -K crypto

注意:这会在所有可用的 Python 版本上触发单元测试,除非用-e指定版本。从 tox.ini 可以看到默认环境列表为py{37..314}-{linux,bsd,windows}-{non_root,root},每个环境最终都调用python -m scapy.tools.UTscapy -c <平台配置文件>来执行测试。

run_tests:单环境快速回归

为方便普通用户和打包维护者,仓库提供了一个在单个(默认 Python)环境运行的工具:

./test/run_tests

不加参数时,test/run_tests 会通过 tox 运行测试,并自动附加-K tcpdump -K wireshark -K tshark -K ci_only -K vcan_socket -K automotive_comm -K imports -K scanner等排除项,确保不依赖外部软件;若带参数,则直接调用 UTScapy(例如./test/run_tests -t tls.uts -F)。它的唯一前置依赖是 Python 3 与 tox。

.utsc 配置文件

tox 中出现的test/configs/linux.utsc等文件是 UTScapy 的 JSON 配置。以 test/configs/linux.utsc 为例,它支持如下字段(与 parse_config_file 对应):

  • testfiles:测试文件列表,支持*通配符;
  • remove_testfiles:从testfiles中移除的文件;
  • breakfailed:首个失败战役后是否停止;
  • onlyfailed:报告中是否只展开失败用例;
  • extensions:要加载的 Scapy 扩展(如scapy-rpc);
  • preexec:运行前预执行代码的字典,键支持通配符,%name%会被替换为文件名主干(如对test/scapy/layers/tls/*.uts预执行load_layer("tls"),对test/contrib/*.uts预执行load_contrib("%name%"));
  • global_preexec:对所有文件生效的全局预执行代码;
  • kw_ko/kw_ok:默认排除 / 保留的关键字;
  • 其余字段还包括verbdumpdocscrcoutputfilelocalformatnummodules等,语义与命令行参数一致。

配置文件通过-c参数加载,命令行参数仍可叠加生效。


为 .uts 文件配置 VIM 语法高亮

UTScapy 的测试文件使用.uts后缀。仓库在 doc/syntax/vim_uts_syntax/ 提供了 Vim 语法高亮插件,目录结构为:

  • ftdetect/filetype.vimftdetect/uts.vim:文件类型识别;
  • syntax/uts.vim:语法高亮定义。

ftdetectsyntax两个目录中的文件复制到~/.vim/并保持目录结构即可。如果~/.vim/ftdetect/filetype.vim已存在,可能需要手动合并该文件。可执行命令:

cp -i -v ftdetect/filetype.vim $HOME/.vim/ftdetect/filetype.vim cp -i -v ftdetect/uts.vim $HOME/.vim/ftdetect/uts.vim cp -i -v syntax/uts.vim $HOME/.vim/syntax/uts.vim

也可以直接运行仓库内的 install.sh 自动安装(脚本要求当前目录为doc/syntax/vim_uts_syntax,且~/.vim已存在,使用cp -i交互确认避免覆盖已有文件)。


发布 Scapy:签名标签与流程

发布前的检查清单

一个 Scapy 发布在底层体现为一个签名 git tag。维护者在签署提交前必须:

  • 确认对应的 CI(Travis / AppVeyor)测试全部通过;
  • 在本地运行./run_scapy
  • 运行tox
  • 使用 doc/vagrant_ci/ 提供的 Vagrant 环境在 BSD 上运行单元测试。

签名并发布 tag

以 v2.4.3 为例,签名与发布流程如下:

$ git tag -s v2.4.3 -m "Release 2.4.3" $ git tag v2.4.3 -v $ git push --tags

也可以发布候选版本(RC)。例如首个 RC 会打上v2.4.3rc1标签,提交信息为2.4.3 Release Candidate #1

若尚未配置签名密钥,可配置为 SSH 密钥再注册使用:

$ git config --global gpg.format ssh $ git config --global user.signingkey ~/.ssh/examplekey.pub

上传到 PyPI

上传到 PyPI 之前,执行发布的维护者邮箱地址必须已写入 pyproject.toml 的维护者字段。随后构建并上传:

$ pip install --upgrade build $ SCAPY_VERSION=2.6.0rc1 python -m build $ twine check dist/* $ twine upload dist/*

警告:上传前务必清理dist/目录中的残留文件,其中应只包含源码包与 wheel 包;同时确认 wheel 文件名以*-py3-none-any.whl结尾。


打包 Scapy:版本一致性与轻量验证

打包 Scapy 时,应在设置SCAPY_VERSION环境变量的前提下执行源码构建,确保版本信息保持一致:

$ SCAPY_VERSION=2.5.0 python3 -m build ... Successfully built scapy-2.5.0.tar.gz and scapy-2.5.0-py3-none-any.whl

打包过程中若想顺便测试 Scapy,官方建议直接使用无参数./test/run_tests。它会运行一组不依赖外部软件的子集测试,验证起来更简单,唯一依赖是 tox。

$ ./test/run_tests

从 run_tests 的实现在打包时也能看到一致性保障的另一面:tox.initwine环境会以SCAPY_VERSION=3.0.0构建并执行twine check --strictgitarchive环境则验证从 git archive 安装后的版本读取是否正确,这些自动化步骤共同保证了发布版本号与构建产物的严格一致。


总结

从贡献入口、docstring 规范,到 UTScapy 的语法控制符、命令行与配置文件、tox 与 run_tests 的用法、Vim 高亮安装,再到签名发布与版本一致的打包流程,本指南覆盖了 Scapy 开发侧从“写测试”到“发版本”的完整闭环。无论你是准备提交第一个协议层补丁,还是负责维护发布流水线,都可以从 scapy/tools/UTscapy.py 的实现细节与 test/ 目录下的真实用例中获得一手参考。

  • 网络
  • 网络安全

【免费下载链接】scapy

Scapy: the Python-based interactive packet manipulation program & library.

项目地址:https://gitcode.com/gh_mirrors/sc/scapy
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/23 1:53:34

5步搞定termux下载:一文搞懂底层原理与避坑指南

5步搞定termux下载:一文搞懂底层原理与避坑指南 复制来的代码跑不通,报错信息像天书一样滚过去,心里那个急啊,真不知道从哪下手调。别慌,这种“环境没搭对”导致的死局,90%的情况都出在基础工具链上。今天咱们不整虚的,直接 一文搞懂 Termux 的底层逻辑,从下载、安装到环境配置,把那些藏在…

作者头像 李华
网站建设 2026/9/23 1:53:29

3步搞定member 247性能坑,高频面试题实操指南

3步搞定member 247性能坑,高频面试题实操指南 报错一堆看不懂 StackTrace?别慌,这不只是你的问题。很多开发在调试 member 247 相关模块时,面对满屏红色的异常信息,第一反应往往是“这代码谁写的”,而不是“哪里慢了”。实际上,这类问题常出现在 高频面试题…

作者头像 李华
网站建设 2026/9/23 1:53:13

办公软件教程速查手册:3个源码细节搞定项目搭建

办公软件教程速查手册:3个源码细节搞定项目搭建 学会语法却不知怎么搭项目,是绝大多数初学者卡在“入门”到“实战”之间的死结。很多人背熟了API,打开编辑器却对着空白文件发呆,不知道一个最小可运行的程序长什么样,更不知道那些看似枯燥的配置项背后藏着怎样的工程逻辑。…

作者头像 李华
网站建设 2026/9/23 1:53:04

情葬泪痕碗攻略新手避坑指南

情葬泪痕碗攻略新手避坑指南 复制来的代码跑不通,报错信息满屏红字,你盯着屏幕发呆,脑子里全是“我哪里写错了”。这种抓狂时刻,很多初学者都经历过。其实,问题往往不在逻辑,而在环境、依赖或配置细节。今天这篇 情葬泪痕碗攻略 ,就是帮你快速定位并解决这类“玄学”问题,专门写给刚入行的新人,主打一个…

作者头像 李华