Appearance
Appearance
为了完整支持 pcapng 格式,我计划对 wiretap API(即 libwiretap)做出重大更改。总体模型是让 wiretap 在内部维护的数据结构方面更像 pcapng 文件格式,并在外部 API 上表现得更像 pcapng 文件格式。
这样做的理由是,我认为 pcapng 本质上是我们支持的所有文件格式的超集;如果某种文件格式支持 pcapng 不支持的内容,我也有相应计划。(后面讨论)
目前,wiretap 存在以下问题:
上述问题会给我们的各种程序/工具带来麻烦。例如,如果 pcapng 文件中间出现 IDB,tshark 就无法保存该文件,即使在 2-pass 模式下也是如此。另一个例子是,如果中间出现 IDB,capinfos 和 mergecap 会出错。
为了处理这些类型的问题,我计划执行本页概述的更改。
“未知块”将是一个由我们不了解的 pcapng block type 组成的数组。(详见后文)
“未知 pcapng options”将是一个由我们不了解且没有离散成员表示的选项组成的数组;每个选项条目都按照 pcapng 规范进行结构化和格式化。换句话说,它将保存数据包除 comments、drop count 和 flags 之外的任何 option。
数据包“options”也类似——如果文件格式有一些它想公开的每包信息,可以将其添加到“未知 pcapng options”数组中,使用 option type 0x4BAD,即 pcapng 中表示具有 do-not-copy 行为的 Custom Option 的 option type;并且它会使用自己的 PEN number。
对于 pcapng 文件中 wiretap 并不明确了解的 block/option type,它只会使用该 block/option 在 pcapng 文件中使用的相同代码编号。
如果 record_type 表示一个数据包,例如 pcapng 中的 EPB、SPB 或 PB,则会使用 REC_TYPE_PACKET,并且 wtap_read_record() 会像以前一样设置 phdr 信息(加上前面提到的更改),读者会将其作为传回的“record”使用,而不是使用 void pointer。
如果记录类型表示 SHB,或者如果任何其他文件格式有 pcapng 风格的 section 概念(据我所知没有),即类似 SHB 的记录,则会使用 REC_TYPE_SECTION_HEADER(我们会添加到 wiretap 的新类型),并且返回的结构将是当前的 wtapng_section_t。对于没有 pcapng 风格 section 概念、因而没有类似 SHB 记录的文件格式,将合成一个 REC_TYPE_SECTION_HEADER,并将其作为第一条记录提供。
如果记录描述一个或多个接口,例如 pcapng 中的 IDB,或 Microsoft Network Monitor 文件中的 “Netmon Network Info Ex” “packet”,则会使用 REC_TYPE_INTERFACE_DESCRIPTIONS(我们会添加到 wiretap 的新类型),并且使用接口数量,后面跟一个 wtapng_if_descr_t 结构的数组(“Netmon Network Info Ex” 包含捕获中所有接口的列表,而不只是单个接口;这样我们就可以让该记录在 NetMon 文件的数据包列表中显示为单条记录,从而使 Wireshark 读取时的 NetMon 数据包编号与 NetMon 读取时保持一致——我认为有一个关于此问题的 bug)。
如果记录包含接口统计信息,例如 pcapng 中的 ISB,则会使用 REC_TYPE_INTERFACE_STATISTICS(我们会添加到 wiretap 的新类型),并返回一个 wtapng_if_stats_t 结构。如果某种文件格式在一条记录中提供多个接口的信息,我们可以提供多条这样的记录,也可以像 REC_TYPE_INTERFACE_DESCRIPTIONS 那样提供一条包含多个统计信息的记录。
如果记录包含名称解析信息,则会使用 REC_TYPE_NAME_RESOLUTION(我们会添加到 wiretap 的新类型),并返回一个 wtapng_name_res_t 结构。
对于其他记录类型,如果我们认为它们对多种文件类型有用,就定义新的 REC_TYPE_ 值;否则就只对它们使用 REC_TYPE_FT_SPECIFIC_EVENT 或 REC_TYPE_FT_SPECIFIC_REPORT。
wtap_read_record() 函数还会按需将传回的 block struct 添加到内部 wtap 结构中。例如,对于 REC_TYPE_INTERFACE_DESCRIPTIONS,新的 IDB 或多个 IDB 会在内部自动追加到最近 SHB 的 IDB 数组中。这在向 dump 文件写入内容时会产生影响,如后文所述。
创建一个新的 wtap_seek_read_record(),其模型与(3)类似,但它永远不会把 block 添加到 wtap 的内部结构中。这里的前提是假设此前已经调用过 wtap_read_record(),因此已经把 block 添加到了 wtap 中。
更改当前的 wtap_read() 公共函数,使其在内部调用这个 wtap_read_record(),并持续调用直到遇到 REC_TYPE_PACKET。(即,对于 wtap_read() 的用户来说,相比之前的行为不会有重大变化)当前的 wtap_seek_read() 将只用于访问 packet record,不需要更改。
更改 wtap_open_offline(),使其不要为 legacy PCAP 文件读取器生成假的 IDB——让 PCAP 文件读取器以及所有其他文件中没有 interface description record 的格式读取器,合成一个 REC_TYPE_INTERFACE_DESCRIPTIONS record,并在合成的 REC_TYPE_SECTION_HEADER 之后提供它,前提是它们在文件头中有足够信息可这样做。对于 iptrace,由于每个数据包都有关联的 interface name,其读取器会跟踪接口名称,并在每次看到尚未见过的接口名称时合成一个 REC_TYPE_INTERFACE_DESCRIPTIONS;其他一些文件格式也可能做类似处理。
更改 wtap_file_encap(),使其对文件中的初始 IDB 执行 peek 并返回 encap;如果没有 IDB,则可能为 WTAP_ENCAP_UNKNOWN;但不要查看整个文件——除非有一个 boolean 指示要查看整个文件。这里的“peek”是指让它读取文件中的 IDB,但不要将其保存到 wtap 中。
更改 wtap_dump_open_ng()/wtap_dump_fdopen_ng() 例程,使其在打开文件时只写入第一个 SHB 以及当前与其关联的 IDB 的信息,但仍将所有传入的 SHB/IDB/NRB 的内部副本保存到 wtap_dumper 中。由于以后传入的每个 wtap_pkthdr 都会标识其各自的 SHB(和 IDB),因此可以按后文所述使用其他 SHB。
创建一个新的 wtap_dump_record() 公共函数,可用于写入任何 REC_TYPE_ 值,包括所有 packet type、新增类型,以及 REC_TYPE_FT_SPECIFIC_EVENT 和 REC_TYPE_FT_SPECIFIC_REPORT。如果传入的数据包记录属于一个已在内部 wtap_dumper 结构数组中但尚未写入文件(使用 last_recorded_shb_id 值判断)的 SHB,则它会在写入数据包之前将该 SHB+IDB 写入文件,同时写入该 SHB 的所有 IDB。(不确定 NRB 是否应该推迟到 close 时处理)
如果使用 REC_TYPE_SECTION_HEADER、REC_TYPE_INTERFACE_DESCRIPTIONS 等调用 wtap_dump_record(),则它会将它们写入文件,并保存到 wtap_dumper 结构中。
这样,应用程序就可以执行单遍读取和写入,例如 tshark/editcap/mergecap 所做的那样,其中新的 REC_TYPE_SECTION_HEADER、REC_TYPE_INTERFACE_DESCRIPTIONS 等会出现在读取+写入过程的中间。它还允许应用在任意位置+任意时间插入 block。
对于不能处理多个 SHB 的文件格式(我认为除了 pcapng 之外都是如此),如果使用新的 SHB record 调用 wtap_dump_record() 写入,或者某个数据包标识自己属于第一个 SHB 之外的 SHB,那么它们会在 dumping 期间失败。Mergecap 或 editcap 需要增强,以便能够将多个 SHB section 合并为一个。
我们是否应该从 wtap 中移除 add_new_ipv4/ipv6 callbacks,并让应用程序基于传回的 NRB block 执行该操作?
我们是否应该直接去掉 wtap_read()/wtap_seek_read()?
做这类事情的挑战在于,pcapng 文件需要永远可用/可读——既要能被未来版本的软件工具(如 wireshark)读取,也要能被旧版本的 wireshark 读取。所以,设想我们添加一个 pcapng block 或 option,用来指示给定 TCP 端口的 “decode as” protocol “foo”。从那以后,我们就不能再更改 “foo” 的 protocol name,否则会破坏 decode-as 设置。如果我们在未来的 wireshark 版本中添加某个 protocol “bar”,那么在那个未来 wireshark 中保存了 “decade-as bar” 设置的文件,就必须以某种方式在理解 “decode-as” 但不理解 “bar” 部分的旧版 wireshark 中处理。因此,我们必须让这些设置成为 wireshark 尝试应用的 best-effort 内容,同时围绕各种失败方式提供大量保护。-hadriel
对于 decryption keys,是的,我原本设想我们会创建一个 Custom Block 来保存 session keys(不是 private keys)和 algorithm meta-data 内容,并在 EPB 中使用一个 custom option 指示该数据包使用哪个 Custom Block 加密。-hadriel
关于初步想法,请参阅 Wireshark Custom Blocks/Options 的 strawman proposal。
Imported from https://wiki.wireshark.org/WiretapPcapng on 2020-08-11 23:27:37 UTC