第 8 章数据包捕获
本章需要复审和扩展。
8.1. 如何向Libpcap 添加新的捕获类型
在本次讨论中,我假设您使用的是 libpcap1.0 或更高版本。您可能不想使用早于1.0 的版本,即使您使用的任何操作系统恰好包含libpcap - 旧版本对于添加对标准网络接口以外的设备的支持并不友好。
首先,阅读《有关编写新 libpcap 模块的 libpcap 文档》(libpcap/README.capture-module at master · the-tcpdump-group/libpcap · GitHub)
(它目前不完整,但我会随着时间的推移完成它。如果你有贡献,请随时提交请求请求。)
如果您必须引入一个或多个新DLT_*值,您还必须在 Wireshark 中为这些DLT_*值添加支持到 wiretap/pcap-common.c,这可能意味着将一个或多个 WTAP_ENCAP 类型添加到wtap.h和 wiretap/wtap.c中的encap_table[] 表。然后,您必须为链路层协议或协议编写一个或多个解析器,并通过调用dissector_add_uint()将它们自己注册到wtap_encap解析器表,并使用适当的 WTAP_ENCAP值。
8.2. Extcap:开发人员指南
extcap接口是一个多功能的插件接口,它允许外部二进制文件直接在Wireshark中充当捕获接口。它用于捕获源不是传统捕获模型(实时捕获,来自接口、管道、文件等)的场景。典型的例子是将某种复杂的硬件连接到主Wireshark应用程序。
不使用extcap时,数据捕获总是可以通过直接写入捕获文件来实现:
使用捕获文件进行传统捕获的Bash示例。
$ the-esoteric-binary --the-strange-flag --interface=stream1 --file dumpfile.pcap & $wireshark dumpfile.pcap
但是extcap接口允许使用Wireshark GUI轻松建立和配置此类连接。
extcap子系统由多个 extcap 二进制文件组成,这些二进制文件由GUI连续自动调用。在接下来的章节中,我们将把它们称为“extcaps”。
Extcaps 可以是extcap目录中的任何二进制文件或脚本。请注意,脚本需要是可执行的,而无需在调用之前预先设置脚本解释器。
注意!Windows用户由于限制,直接调用脚本可能并不总是有效。在这种情况下,可以提供批处理文件,然后执行脚本。有关更多信息,请参阅第 8.2.1.4.1 节“在 Windows 上执行基于脚本的 extcap”。
当 Wireshark 启动一个 extcap 时,它会自动将其安装路径(例如典型的安装目录是C:\Program Files\Wireshark\)添加到DLL搜索路径中,以便可以找到extcap库依赖项(它不是设计为手动启动的)。这是故意这样做的。extcap文件夹中应该只有extcap程序(可执行文件、python 脚本……)以减少启动时间,并且不要让Wireshark 尝试执行其他文件类型。
8.2.1. Extcap 命令行界面
先是设置过程(setup process),之后才开始真正捕获。该设置过程可以由用户手动完成也可以由GUI 自动完成。执行的所有步骤都是针对每个 extcap 完成的。
让我们来完成这些步骤。
8.2.1.1. 查询可用接口
在第一步中查询extcap的接口。
$ extcapbin --extcap-interfaces
此调用必须打印此extcap的现有接口,并且必须返回 0。输出必须符合为extcap指定的语法,语法说明在 doc/extcap.4 生成的手册页(在构建目录中)中。
从 Wireshark 2.9 开始,此调用扩展为--extcap-version=x.x,x.x为调用Wireshark的版本信息。这可用于根据不同Wireshark版本更改行为。
查询接口调用示例。
$ extcap_example.py --extcap-interfaces --extcap-version=3.0 extcap {version=1.0}{help=Some help url} interface {value=example1}{display=Example interface 1 for extcap} interface {value=example2}{display=Example interface 2 for extcap}
extcap语句的version参数(可以根据需要存在多次,但只使用最后一个)将用于在Wireshark的 about 对话框中显示 extcap 接口的版本信息。
每个接口的value将在后续调用中用作接口名称IFACE。
使用help参数,接口可以为extcap实用程序提供通用帮助 URL。
8.2.1.2. 向每个接口请求 DLT
对于步骤 1 返回的所有接口,查询 extcap 二进制文件的所有有效 DLT。
$ extcap_example.py --extcap-dlts --extcap-interface IFACE
此调用必须打印指定接口的有效 DLT。此调用是针对所有接口进行的,并且必须返回 0。
DLT查询示例。
$ extcap_example.py --extcap-interface IFACE --extcap-dlts dlt {number=147}{name=USER1}{display=Demo Implementation for Extcap}
既不提供接口列表也不提供 DLT 列表的二进制文件或脚本将不会显示在extcap接口列表中。
8.2.1.3. extcap 配置接口
extcap二进制文件要配置特定接口
$ extcap_example.py --extcap-interface IFACE --extcap-config
每个接口都可以有仅对这个接口有效的自定义选项。这些配置选项是在运行实际捕获时在命令行上指定的。为了允许终端用户指定某些选项,可以使 extcap配置参数提供这些选项。
为了分享接口可用的选项,extcap需要响应命令--extcap-config显示所有可用选项(也称为附加命令行选项)。
这些选项通过对话框自动呈现给用户,用于各个界面。
接口选项示例。
$ extcap_example.py --extcap-interface IFACE --extcap-config
arg {number=0}{call=--delay}{display=Time delay}{tooltip=包之间的时间延迟}{type=integer}{range=1,15}{required=true}
arg {number=1}{call=--message}{display=Message}{tooltip=包信息内容}{placeholder=请在此处输入信息...}{type=string}
arg {number=2}{call=--verify}{display=Verify}{tooltip=验证包内容}{type=boolflag}
arg {number=3}{call=--remote}{display=Remote Channel}{tooltip=远程频道选择器}{type=selector}
arg {number=4}{call=--server}{display=IP address for log server}{type=string}{validation=\\b(?:(?:25[0-5]|2[0- 4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0- 9]|[01]?[0-9][0-9]?)\\b}
value {arg=3}{value=if1}{display=Remote1}{default=true}
value {arg=3}{value=if2}{display=Remote2}{default=false}
现在用户可以单击选项并更改它们。当捕获启动时,它们被发送到 extcap。
有以下三种选项可供选择:
Flag | 例如boolflag期望该选项存在,导致相应的条目设置为 true,否则为 false |
Value | 是基于值的选项,每个选项都期望通过命令行调用获得一个值 |
Selection | 是选择,可以在命令行中多次显示。两者都期望配置列表中的后续“value”项,并通过 arg 选择相应的参数 |
8.2.1.4. 捕获过程
在列出了接口并且配置后,就可以开始捕获。
$ extcap_example.py --extcap-interface IFACE [params] --capture [--extcap-capture-filter CFILTER] --FIFO FIFO
要运行捕获,extcap 必须实现--capture,--extcap-capture-filter 和--fifo选项。
它们由Wireshark自动添加,打开fifo进行阅读。所有其他选项都会自动添加以运行捕获。extcap接口像所有其他接口一样使用(意味着支持在多个接口上捕获,以及停止和重新启动捕获)。
8.2.1.4.1. 在 Windows 上执行基于脚本的 extcap
要在Windows上使用脚本,请在extcap文件夹中生成一个 <scriptname>.bat,其内容如下(在本例中为基于Python的extcap实用程序):
@echo off <python解释器的路径> <脚本文件的路径> %*
Windows 无法直接执行大多数脚本(Powershell 是一个例外),这也适用于除 VBScript 和 PowerShell 之外的所有其他基于脚本的格式
8.2.2. Extcap参数
extcap接口提供了生成GUI对话框以设置和调整extcap二进制文件设置的可能性。
所有选项都必须提供一个编号,以识别它们。没有NUMBER可提供两次。此外,所有选项都必须显示元素CALL和DISPLAY,其中call在命令行上提供参数名称并在GUI中显示名称。
此外还可以提供TOOLTIP和PLACEHOLDER,这将在GUI中向用户解释要输入到该字段中的内容。
这些选项有类型(type),支持以下类型:
INTEGER, UNSIGNED, LONG, DOUBLE | 用于输入特定数值数据类型的字段。可以提供默认值(DEFAULT)以及范围(RANGE) arg {number=0}{call=--delay}{display=Time delay}{tooltip=包之间的时间延迟}{type=integer}{range=1,15}{default=0} |
STRING | 让用户为捕获提供一个字符串 arg {number=1}{call=--server}{display=IP Address}{tooltip=日志服务器的IP地址}{type=string}{validation=\\b(?:(?:25[0-5 ]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0 -4][0-9]|[01]?[0-9][0-9]?)\\b} validation允许提供正则表达式字符串,用于检查用户输入是否超出正常数据类型或范围检查的有效性。必须转义反斜杠(如 \b 中的 \b) |
PASSWORD | 让用户为捕获提供一个masked string。保存extcap配置时,不保存密码字符串 arg {number=0}{call=--password}{display=用户密码}{tooltip=连接密码}{type=password} |
BOOLEAN, BOOLFLAG | 让用户为捕获提供一个true/false。BOOLFLAG值仅在设置为true时才会出现在命令行中,否则它们将不会添加到extcap接口的命令行调用中 arg {number=2}{call=--verify}{display=Verify}{tooltip=验证包内容}{type=boolflag} |
FILESELECT | 让用户提供文件路径。如果提供了MUTEXIST=true,GUI 会为用户提供一个选择文件的对话框。当使用 MUTEXIST=false 时,GUI 会为用户提供一个用于保存文件的文件对话框。 arg {number=3}{call=--logfile}{display=Logfile}{tooltip=日志消息文件}{type=fileselect}{mustexist=false} |
SELECTOR, RADIO, MULTICHECK | 选项字段,用户可以从中选择一个或多个选项。如果为值项提供了 PARENT,则 MULTICHECK 和 SELECTOR 的选项字段将以树状结构呈现。SELECTOR 和 RADIO 值必须提供一个默认值,这将是为此参数提供给 extcap 二进制文件的值 arg {number=3}{call=--remote}{display=remote channel}{tooltip=远程频道选择器}{type=selector} value {arg=3}{value=if1}{display=Remote1}{default=true} value {arg=3}{value=if2}{display=Remote2}{default=false} |
8.2.2.1. 重新加载选择器
可以从Wireshark中extcap应用程序的配置对话框中重新加载选择器。使用 reload 参数(默认为 false),可以将条目标记为可重新加载。
arg {number=3}{call=--remote}{display=Remote Channel}{tooltip=Remote Channel Selector}{type=selector}{reload=true}{placeholder=Load interfaces...}
定义后,用户将在此 extcap 应用程序的配置对话框中显示一个按钮,在本例中为文本“Load interfaces...”,如果未提供文本,则为通用的“Reload”文本。
然后以使用所有已填写的参数和附加参数--extcap-reload-option <option_name>再次调用extcap实用程序。预计会为此选项返回一个值部分,就像在正常配置期间一样。提供的选项列表然后作为选择呈现,如果先前选择的选项依旧适用,将重新选中它。
8.2.2.2. 参数验证
在使用 extcap 选项对话框开始捕获之前,参数可以设置为{required=true}来强制要求提供一个值。如果简单的通过双击启动 extcap则不会检查此项。它为客户标记了必要的字段以确保最终客户能够看到所需的参数。
此外,还可以使用正则表达式检查文本和数字参数,该表达式是使用validation属性提供的(参见上面的示例)。这种检查的语法与Qt RegExp 类的语法相同。此功能仅在Wireshark的Qt版本中有效。
8.2.3. 工具栏控件
extcap实用程序可以为在interface工具栏中使用的控件提供配置。这些控件是双向的(bidirectional ),当正在捕获时可用于控制extcap实用程序。
这使它可以根据捕获过程中发现的情况更改配置、设置临时值或提供其他输入,而无需重新启动当前捕获。
带有工具栏控件的界面定义示例。
$ extcap_example.py --extcap-interfaces
extcap {version=1.0}{display=Example extcap interface}
interface {value=example1}{display=Example interface 1 for extcap}
interface {value=example2}{display=Example interface 2 for extcap}
control {number=0}{type=string}{display=Message}{tooltip=Package message content. Must start with a capital letter.}{validation=[AZ]+}{required=true}
control {number=1}{type=selector}{display=Time delay}{tooltip=Time delay between packages}
control {number=2}{type=boolean}{display=Verify}{default=true}{tooltip=Verify package content}
control {number=3}{type=button}{display=Turn on}{tooltip=Turn on or off}
control {number=4}{type=button}{role=logger}{display=Log}{tooltip=Show capture log}
value {control=1}{value=1}{display=1 sec}
value {control=1}{value=2}{display=2 sec}{default=true}
所有控件都将在针对extcap实用程序的工具栏中显示为GUI元素。但是由于存在其他不使用 GUI 的捕获工具(例如 tshark、tfshark),所以extcap 不能依赖于使用这些控件(它们是可选的)。
8.2.3.1. 控件
控件类似ARGUMENTS,但没有CALL元素。所有控件都可以在启动时被赋予一个默认值,并且大多数可以在捕获期间由extcap和用户更改(取决于控件的类型)。
所有控件都必须提供一个用于识别它们的NUMBER。相同的NUMBER不能提供给两个不同的控件。此外,所有选项都必须显示元素TYPE和DISPLAY,其中TYPE是要添加到工具栏的控件类型而DISPLAY是在GUI中显示的名称。
此外,还可以提供TOOLTIP和PLACEHOLDER,这将在GUI中为用户提供解释。
除了记录器(logger)、帮助和恢复按钮( help and restore buttons)之外的所有控件都可以在捕获期间由extcap在GUI中禁用和启用。这可能是因为设置一次(set-once)操作,或是需要一些时间才能完成的操作(This can be because of set-once operations, or operations which takes some time to complete.)。
开始捕获时,用户更改的所有控制值(不等于默认值)将发送到 extcap 实用程序。extcap 实用程序可能会选择丢弃初始值并设置新值,具体取决于实现。
这些 TYPE 被定义为控件:
BOOLEAN | 这提供了一个可以设置true/false值的复选框。 extcap实用程序可以在启动时设置默认值,并且可以在捕获时更改(设置)和接收值更改。如值非默认值,则开始捕获时GUI 将发送这个值。 有效载荷是二进制值0或1的一个字节。 有效命令:Set value, Enable, Disable. |
BUTTON | 这提供了一个具有不同角色的按钮: CONTROL 按下此按钮将发送信号。如果没有配置角色,这是默认设置。该按钮仅在捕获时启用。 extcap 实用程序可以在启动时设置按钮文本,并且可以在捕获时更改(设置)按钮文本和接收按钮按下信号。在不捕获时按钮被禁用同时按钮文本恢复为默认文本。 有效载荷(payload)是按钮文本或空(信号)。 有效命令:Set value, Enable, Disable. LOGGER 它提供了一种日志机制,extcap 实用程序可以在其中发送要在日志窗口中显示的日志条目。这种通信是单向的。 负载(payload)是日志条目,应该以换行符结束。最大长度为 65535 字节。 有效命令:Set log entry, Add log entry. Set命令会在添加条目之前清除日志。 HELP 如果已配置,此按钮将打开帮助页面。该角色没有控制权,不会用于交流。 有效命令:无。 RESTORE 此按钮会将所有控制值恢复为默认值。该角色没有控制权,不会用于交流。该按钮仅在未捕获时启用。 有效命令:无。 |
SELECTOR | 它提供了一个可以选择固定值的组合框。 extcap实用程序可以在启动时设置默认值,在捕获时可以添加和删除值,并可在(组合框)选中值发生更改时收到通知。开始捕获时,如值与默认值不同则GUI 将发送这个值。 有效负载(payload)是一个带有值的字符串,如果它与值不同,则可以选择带有显示值的字符串。这两个字符串值由空字符分隔。(The payload is a string with the value, and optionally a string with a display value if this is different from the value. This two string values are separated by a null character.) 有效命令:Set selected value, Add value, Remove value, Enable, Disable. 如果值为空,Remove 命令将删除所有条目。 |
STRING | 它提供了一个文本编辑行,可以设置字符串或任何可以用字符串表示的值(整数、浮点数、日期等)。 extcap实用程序可以在启动时设置默认字符串值,并且可以在捕获时更改(设置)和接收值的更改。开始捕获时,如值与默认值不同则GUI将发送这个值。 有效负载(payload)是一个带有值的字符串。最大长度为 32767 字节。 有效的控制命令:Set value, Enable, Disable. 元素VALIDATION允许提供正则表达式字符串,用于检查用户输入的有效性,是否超出正常数据类型或做范围检查。反斜杠必须转义(如\b转为\\b)。 |
8.2.3.2. 消息
除了控件之外,还可以从extcap实用程序向用户发送一条消息。该消息可以放在状态栏中或显示在用户必须接受的信息对话框、警告对话框或错误对话框中。此消息不使用NUMBER参数,因此它可以具有任何值。
8.2.3.2.1. 控件协议
通过控件管道进行通信的协议具有固定大小的 6 字节标头和 0 - 65535 字节的有效载荷。
表 8.1。控制包:
Sync Pipe Indication (1 byte) |
Message Length (3 bytes network order) |
Control Number (1 byte) |
Command (1 byte) |
Payload (0 - 65535 bytes) |
Sync Pipe Indication:
公共同步管道指示。该协议使用值“T”。
Message Length:
有效载荷(payload)长度 + 2 个字节用于控制号和命令。
Control Number:
标识控件的唯一编号。这个数字还给出了界面工具栏中控件的顺序。
表 8.2。控件的命令和应用程序
命令字节 | 命令名称 | 控件类型 |
0 | Initialized | none |
1 | Set | boolean / button / logger / selector / string |
2 | Add | logger / selector |
3 | Remove | selector |
4 | Enable | boolean / button / selector / string |
5 | Disable | boolean / button / selector / string |
6 | Statusbar message | none |
7 | Information message | none |
8 | Warning message | none |
9 | Error message | none |
在开始捕获且GUI已发出所有用户修改过的控件的值后,Initialized命令从GUI发送到extcap实用程序。这表明GUI已准备好接收控制值。
GUI只会发送Initialized和Set命令。extcap实用程序不应发送该Initialized命令。
带有未知控制号或命令的消息将被忽略且无任何提示。