Scapy 的开发

项目组织

scapy开发使用了git版本控制系统。scapy的参考存储库位于https://github.com/secdev/scapy/。

项目管理是通过 Github . 它提供了一个可自由编辑的 Wiki (请贡献!)它可以引用项目中的票据、变更集和文件。它还提供了一个票据管理服务,用于避免忘记补丁或错误。

如何贡献

  • 在scapy中发现了一个bug? Add a ticket .

  • 改进此文档。

  • 编程一个新层并在邮件列表中共享它,或者创建一个请求。

  • 贡献新 regression tests .

  • 在上上载新协议的数据包示例 packet samples page .

改进文档

可通过以下几种方式改进文档:

  • 向源代码添加docstring。

  • 向文档中添加使用示例。

添加文档字符串

对于函数所做的工作,scapy源代码几乎没有解释。通过添加解释和预期的输入和输出参数,docstring有助于为寻找高级特性的层开发人员和用户节省时间。

DocString示例 scapy.fields.FlagsField 班级::

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
   """

它将包含对类的简短的一行描述,后面还有一些关于其用法的指示。如果使用 doctest 格式。最后,可以在下面添加经典的python签名 sphinx documentation .

此任务与编写非回归单元测试配合使用。

文档

改进文档内容的一种方法是使其与最新版本的scapy保持同步。您还可以通过添加自己的使用示例或直接从现有的在线欺诈演示中收集的使用示例来提供帮助。

使用utscapy进行测试

什么是 UTScapy?

utscapy是一个小型的python程序,它读取测试活动,用scapy运行活动,并生成一个指示测试状态的报告。报告可以是以下四种格式之一:文本、ANSI、HTML或LaTex。

有三个基本的测试容器,分别是utscapy、单元测试、测试集和测试活动。单元测试是由scapy或scapy的派生工作运行的scapy命令列表。单元测试中最后一个命令的评估将决定单个单元测试的最终结果。测试集是一组具有某种关联的单元测试。测试活动由一个或多个测试集组成。测试集和单元测试可以被赋予关键字以形成逻辑分组。运行活动时,可以通过关键字选择测试。这允许用户在所需的分组内运行测试。

对于每个单元测试、测试集和活动,将计算测试的CRC32并显示为该测试的签名。此测试签名足以确定实际的测试运行是预期的,而不是已修改的。如果在不更改CRC32的情况下与试图修改或损坏文件的坏人打交道,则会在整个文件上计算全局sha1。

测试活动的语法

表1显示了utscapy正在寻找的语法指示器。语法说明符必须作为定义测试的文本文件每行的第一个字符出现。语法说明符后面的文本描述是由utscapy解释的参数。如果行出现在单元测试的上下文中,那么不带前导语法说明符的行将被视为python命令。没有语法说明符出现在正确上下文之外的行将被utscapy拒绝,并发出警告。

语法说明符

定义

‘%’

给出测试活动的名称。

“+”

宣布新的测试集。

“=”

宣布新的单元测试。

“~”

宣布当前单元测试的关键字。

‘*’

表示将包含在报告中的注释。

'''

解释器丢弃的测试用例注释。

表1-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

通过缺少定义的utscapy语法说明符来标识python语句。python语句被直接发送到python解释器,就好像在交互scapy shell中操作一样。 (interact )允许循环、迭代和条件,但必须以空行结束。一个测试集可以由多个单元测试组成,并且可以为每个活动定义多个测试集。甚至可以在特定的测试定义文件中进行多个测试活动。使用关键字可以测试整个活动的子集。例如,在开发测试活动期间,用户可能希望用关键字“debug”标记正在开发的新测试。一旦测试成功运行到所需的结论,就可以删除关键字“debug”。也可以使用“回归”或“有限”等关键字。

值得注意的是,utscapy使用最后一条python语句中的真值作为测试是否通过的指示器。最后一行可能出现多个逻辑测试。如果结果为0或错误,则测试失败。否则,测试通过。如果需要,使用assert()语句可以强制计算中间值。

utscapy的语法如表3-utscapy命令行语法所示:

[root@localhost scapy]# ./UTscapy.py –h
Usage: UTscapy [-m module] [-f {text|ansi|HTML|LaTeX}] [-o output_file]
               [-t testfile] [-k keywords [-k ...]] [-K keywords [-K ...]]
               [-l] [-d|-D] [-F] [-q[q]]
-l              : generate local files
-F              : expand only failed tests
-d              : dump campaign
-D              : dump campaign and stop
-C              : don't calculate CRC and SHA
-q              : quiet mode
-qq             : [silent mode]
-n <testnum>    : only tests whose numbers are given (eg. 1,3-7,12)
-m <module>     : additional module to put in the namespace
-k <kw1>,<kw2>,...      : include only tests with one of those keywords (can be used many times)
-K <kw1>,<kw2>,...      : remove tests with one of those keywords (can be used many times)

表3-utscapy命令行语法

所有参数都是可选的。没有关联参数值的参数可以串在一起(即 –lqF )如果未指定测试文件,则测试定义来自<stdin>。同样,如果未指定输出文件,则将其定向到<stdout>。默认输出格式为“ansi”。表4列出了参数、相关参数值及其对utscapy的意义。

论证

自变量值

对utscapy的意义

-t

测试文件

输入定义测试活动的测试文件(默认值=<stdin>)

-o

output_file

测试活动结果输出文件(默认值=<stdout>)

-f

测试

ANSI、HTML、LaTex、格式化输出报告(默认值=ANSI)

-l

在本地生成与报表关联的文件。对于HTML,生成javascript和样式表

-F

默认情况下,失败的测试用例将在HTML输出中展开

-d

在执行活动之前打印活动的简要列表

-D

打印一个简短的活动列表并停止。不执行市场活动

-C

不计算测试签名

-q

执行测试时不要将测试进度更新到屏幕

-qq

静默模式

-n

试验室

只执行按编号列出的那些测试。可以使用-d或-d检索测试编号。测试可以以逗号分隔的列表形式列出,并且可以包括范围(例如1、3-7、12)

-m

模块

在执行测试之前加载模块。可用于测试scapy衍生作品。注:utscapy不会以“主”的形式调用将要作为“主”执行的派生作品。

-k

kw1, kw2, ...

仅包括关键字“kw1”的测试。可以指定多个关键字。

-K

kw1, kw2, ...

排除关键字为“kw1”的测试。可以指定多个关键字。

表4-utscapy参数

表5显示了一个具有多个测试集定义的简单测试活动。此外,还指定了允许执行有限数量测试用例的关键字。注意使用 assert() 测试3和5中用于检查中间结果的语句。试验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

要查看针对scapy的示例,请访问http://www.secdev.org/projects/utscapy。将页面底部的示例剪切并粘贴到文件中 demo_campaign.txt 然后用乌茨卡皮对付它:

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

检查文件中生成的输出 demo_campaign.html .

用毒理学方法检测SCAPY

这个 tox 命令简化了测试技巧。它将自动创建虚拟环境并安装必需的python模块。

例如,在新的Debian安装上,以下命令将自动启动所有scapy单元测试,而不需要任何外部依赖:

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

备注

这将在所有可用的Python版本上触发单元测试,除非您指定 -e 选项。见下文

为了您的方便,也为了包维护人员,我们提供了一个仅在单个(默认Python)环境上运行tox的实用程序,同样没有外部依赖::

./test/run_tests

.uts文件的vim语法突出显示

从复制所有文件 scapy/doc/syntax/vim_uts_syntax/ftdetectscapy/doc/syntax/vim_uts_syntax/syntax 进入之内 ~/.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

或者,安装脚本 scapy/doc/syntax/vim_uts_syntax/ 是否自动安装。

释放Scapy

在引擎盖下,Scapy释放被表示为一个签名的git标签。在签署提交之前,希望创建发布的维护者必须:

  • 检查相应的Travis和AppVeyor测试是否通过

  • 运行 ./run_scapy 本地

  • 运行 tox

  • 使用中的Vagrant设置在BSD上运行单元测试 scapy/doc/vagrant_ci/

以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 .

Prior to uploading the release to PyPi, the mail address of the maintainer performing the release must be added next to his name in pyproject.toml. See this for details.

The following commands can then be used:

pip install --upgrade build
python -m build
twine check dist/*
twine upload dist/*

警告

Make sure that you don't have left-overs in your dist/ folder ! There should only be the source and the wheel for the package. Also check that the wheel ends in *-py3-none-any.whl !

Packaging Scapy

When packaging Scapy, you should build the source while setting the SCAPY_VERSION variable, in order to make sure that the version remains consistent.

$ 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

If you want to test Scapy while packaging it, you are encouraged to use the ./run_tests script with no arguments. It will run a subset of the tests that don't use any external dependency, and will be easier to test. The only dependency is tox

$ ./test/run_tests