11.7.1. TreeItem
<lua_class_TreeItem,TreeItem>>s 表示显示在Wireshark的数据包详情面板( packet details pane上的信息, 在Tshark上则是数据包详情界面(packet details view) ,一个 TreeItem 代表树上的一个节点,同时它也可以作为一个包含子节点列表的子树(subtree)。一个子树的子节点可以有零个或多个姊妹节点,这些姊妹节点也就是该子树的其他子节点;
在解析、启发式解析、后置解析的过程中,一个根(root) <lua_class_TreeItem ,TreeItem>>作为函数回调的第三个参数传递给解析器(e.g., myproto.dissector(tvbuf,pktinfo,root));
为了提高性能,在某些情况下 ,项并没有被真正的添加到树中。例如当数据包当前并没有在 Wireshark 的可视窗口面板(visible window pane)被展示/检索出来, 或者 Tshark 没有启用 -V 开关。不过 “添加( add)” 类型的 TreeItem 方法仍然可以被调用,并且仍可以返回一个 TreeItem 对象- 但信息(info)并没有被真正的添加到树中;
因此,你通常不需要关心是否有一个真正的树存在, 不过如果你出于某些理由非要知道的话,你可以使用TreeItem.visible 属性获取器来检索状态;
11.7.1.1. treeitem:add_packet_field(protofield, [tvbrange], encoding, [label])
向该树项(TreeItem)添加一个一个给定的 ProtoField 对象的新子树, 返回一个新的子 TreeItem;
不同于 TreeItem:add() 与 TreeItem:add_le() ,该方法中的 ProtoField 参数是非可选的,即必要的,而且也不能是一个 Proto 对象. 相反,该方法的第一个参数只能使用 ProtoField 来从传入的 TvbRange 中确定提取的字段类型, 并在GUI的数据包字节面板( Packet Bytes pane)中高亮相关字节(如果有GUI的话),,等等;
如果没有指定 TvbRange , 则不会有字节被高亮显示,字段的值也将无法确定。在这种情况下, ProtoField 必须被定义/创建为没有长度的类型,否则就会发生错误。然而,出于向后兼容的缘故,encoding 参数仍然必须要制定;
不同于 TreeItem:add() 与 TreeItem:add_le() ,,该方法可以通过设置 ENC_BIG_ENDIAN 或者ENC_LITTLE_ENDIAN. encoding 参数,来决定是执行big-endian还是little-endian解码;
该方法的签名如下:
tree_item:add_packet_field(proto_field [,tvbrange], encoding, ...)
在1.11.3版本的 Wireshark 中,该方法被修改为不仅仅返回一个子 TreeItem 。
一个子 TreeItem 是该方法的第一个返回值,此外它还将返回提取到的字段值 (即,一个数字, UInt64, Address, 等等). 如果它不能从 TvbRange 中提取到值,则仍返回一个子 TreeItem,而第二个返回值则为nil;
在1.11.3版本的 Wireshark 中,该方法的另一个新特性是能够从 TvbRange 的字符串编码中提取原生数字(native number)ProtoFields,用于基于ASCII和类似的字符串的编码。例如,可以从一个包含ASCII字符串 "123 "的 TvbRange 中提取一个 ftypes.UINT32 类型的 ProtoField,无论是在树中还是在这个函数的第二个返回值中,它都将正确地将ASCII解码为数字123。要做到这一点,你必须将此函数的编码参数设置为适当的字符串ENC_ * 值,并与 ENC_STRING 值进行比特化处理(见init.lua)。ENC_STRING 被保证为唯一的位标志,因此它也可以直接添加而不是按位或(bitwise-or'ed)。只有单字节的ASCII数字字符串编码类型可用于此,如ENC_ASCII 和 ENC_UTF_8;
例如, 一个叫“tvb”的 Tvb中含有一个字符串“123” :
-- this is done earlier in the script
local myfield = ProtoField.new("Transaction ID", "myproto.trans_id", ftypes.UINT16)
-- this is done inside a dissector, post-dissector, or heuristic function
-- child will be the created child tree, and value will be the number 123 or nil on failure
local child, value = tree:add_packet_field(myfield, tvb:range(0,3), ENC_UTF_8 + ENC_STRING)
-
参数
-
protofield
要添加到树中的 ProtoField 字段对象;
-
tvbrange(可选)
该树项所覆盖/代表的数据包中的 TvbRange 字节数;
-
encoding
该字段在 TvbRange 中的编码方式;
-
label (可选)
一个或多个要追加到所创建的 TreeItem 上的字符串;
-
-
返回值
- 一个新的子 TreeItem, 该字段提取到的值,没有则为nil,以及偏移量,没有则为nil;
11.7.1.2. treeitem:add([protofield], [tvbrange], [value], [label])
向该树项中添加一个新的子项,返回一个新的 TreeItem ;
如果 Protofield 代表一个数值(int, uint 或 float),那么它将被视为大端序数(网络顺序)值;
这个方法有一个复杂的形式。'treeitem:add([protofield,] [tvbrange,] value], label)',这样,如果第一个参数是ProtoField 或 Proto,第二个参数是 TvbRange,并且第三个参数也被给定了,那么第三个参数就是 value;但是如果第二个参数不是一个 TvbRange,那么它就是 value(而不是把第二个参数填成'nil',这对该方法是无效的)。如果第一个参数是一个非 ProtoField和一个非 Proto,那么这个参数既可以是 TvbRange,也可以是一个 label,而 value 是不使用的;
11.7.2. 示例
local proto_foo = Proto("foo", "Foo Protocol")
proto_foo.fields.bytes = ProtoField.bytes("foo.bytes", "Byte array")
proto_foo.fields.u16 = ProtoField.uint16("foo.u16", "Unsigned short", base.HEX)
function proto_foo.dissector(buf, pinfo, tree)
-- ignore packets less than 4 bytes long
if buf:len() < 4 then return end
-- ##############################################
-- # Assume buf(0,4) == {0x00, 0x01, 0x00, 0x02}
-- ##############################################
local t = tree:add( proto_foo, buf() )
-- Adds a byte array that shows as: "Byte array: 00010002"
t:add( proto_foo.fields.bytes, buf(0,4) )
-- Adds a byte array that shows as "Byte array: 313233"
-- (the ASCII char code of each character in "123")
t:add( proto_foo.fields.bytes, buf(0,4), "123" )
-- Adds a tree item that shows as: "Unsigned short: 0x0001"
t:add( proto_foo.fields.u16, buf(0,2) )
-- Adds a tree item that shows as: "Unsigned short: 0x0064"
t:add( proto_foo.fields.u16, buf(0,2), 100 )
-- Adds a tree item that shows as: "Unsigned short: 0x0064 ( big endian )"
t:add( proto_foo.fields.u16, buf(1,2), 100, nil, "(", nil, "big", 999, nil, "endian", nil, ")" )
-- LITTLE ENDIAN: Adds a tree item that shows as: "Unsigned short: 0x0100"
t:add_le( proto_foo.fields.u16, buf(0,2) )
-- LITTLE ENDIAN: Adds a tree item that shows as: "Unsigned short: 0x6400"
t:add_le( proto_foo.fields.u16, buf(0,2), 100 )
-- LITTLE ENDIAN: Adds a tree item that shows as: "Unsigned short: 0x6400 ( little endian )"
t:add_le( proto_foo.fields.u16, buf(1,2), 100, nil, "(", nil, "little", 999, nil, "endian", nil, ")" )
end
udp_table = DissectorTable.get("udp.port")
udp_table:add(7777, proto_foo)
-
参数
-
protofield (可选)
一个要添加到树中的 ProtoField 字段或一个 Proto 协议对象;
-
tvbrange (可选)
该树项所覆盖/代表的数据包中的 TvbRange 字节数;
-
value (可选)
字段的值,取代 ProtoField/Proto 中字段的值;
-
label (可选)
一个或多个字符串,用于树项的标签,取代 ProtoField/Proto 的标签;
-
-
返回值
- 一个新的子 TreeItem;
11.7.2.1. treeitem:add_le([protofield], [tvbrange], [value], [label])
向该树项中添加一个新的子项,返回一个新的 TreeItem ;
如果 Protofield 代表一个数值(int, uint 或 float),那么它将被视为小端序数值;
这个方法有一个复杂的形式。'treeitem:add([protofield,] [tvbrange,] value], label)',这样,如果第一个参数是ProtoField 或 Proto,第二个参数是 TvbRange,并且第三个参数也被给定了,那么第三个参数就是 value;但是如果第二个参数不是一个 TvbRange,那么它就是 value(而不是把第二个参数填成'nil',这对该方法是无效的)。如果第一个参数是一个非 ProtoField和一个非 Proto,那么这个参数既可以是 TvbRange,也可以是一个 label,而 value 是不使用的;
-
参数
-
protofield (可选)
一个要添加到树中的 ProtoField 字段或一个 Proto 协议对象;
-
tvbrange (可选)
该树项所覆盖/代表的数据包中的 TvbRange 字节数;
-
value (可选)
字段的值,取代 ProtoField/Proto 中的字段值;
-
label (可选)
一个或多个字符串,用于树项的标签,取代 ProtoField/Proto 的标签;
-
-
返回值
- 一个新的子 TreeItem;
11.7.2.2. treeitem:set_text(text)
设置标签的文本;
之前,使用此方法不返回任何东西,但自从 1.11.3 版本开始,它会返回一个相同的树项,以允许链式调用;
-
参数
-
text
要使用的文本;
-
-
返回值
- 一个相同的树项;
11.7.2.3. treeitem:append_text(text)
在标签上添加文本;
之前,使用此方法不返回任何东西,但自从 1.11.3 版本开始,它会返回一个相同的树项,以允许链式调用;
-
参数
-
text
用来添加的文本;
-
-
返回值
- 一个相同的树项;
11.7.2.4. treeitem:prepend_text(text)
在标签的前部添加文本;
之前,使用此方法不返回任何东西,但自从 1.11.3 版本开始,它会返回一个相同的树项,以允许链式调用;
-
参数
-
text
用来添加的文本;
-
-
返回值
- 一个相同的树项;
11.7.2.5. treeitem:add_expert_info([group], [severity], [text])
设置项目的专家标志,并将专家信息添加到数据包中;
这个函数不会为一个协议创建一个真正的可过滤的专家信息。相反,你应该使用TreeItem.add_proto_expert_info() 来达成这个目的;
ps:这个函数只是为了向后兼容而提供,不应该在新的Lua代码中使用。它可能在未来被删除。你应该只使用TreeItem.add_proto_expert_info() ;
-
参数
-
group (可选)
可以是:
PI_CHECKSUM,PI_SEQUENCE,PI_RESPONSE_CODE,PI_REQUEST_CODE,PI_UNDECODED,PI_REASSEMBLE,PI_MALFORMED或PI_DEBUG. -
severity (可选)
可以是:
PI_CHAT,PI_NOTE,PI_WARN, 或PI_ERROR. -
text (可选)
专家信息要展示的文本;
-
-
返回值
- 一个相同的树项;
11.7.2.6. treeitem:add_proto_expert_info(expert, [text])
设置树项的专家标志,并将专家信息添加到数据包中;
-
参数
-
expert
需要添加到树中的 ProtoExpert 对象;
-
text (可选)
专家信息要展示的文本 (默认使用注册文本);
-
-
返回值
- 一个相同的树项;
11.7.2.7. treeitem:add_tvb_expert_info(expert, tvb, [text])
设置该树项的专家标志,并向数据包添加与数据包中 Tvb 或 TvbRange 相关的字节 ;
-
参数
-
expert
需要添加到树中的 ProtoExpert 对象;
-
tvb
与专家信息相关的 Tvb 或 TvbRange 对象字节;
-
text (可选)
专家信息要展示的文本 (默认使用注册文本);
-
-
返回值
- 一个相同的树项;
11.7.2.8. treeitem:set_generated([bool])
将 TreeItem 标记为一个生成字段(generated field)(有数据推断但不包含在数据包中);
之前,使用此方法不返回任何东西,但自从 1.11.3 版本开始,它会返回一个相同的树项,以允许链式调用;
-
参数
-
bool (optional)
一个 Lua 的布尔型,如果为 Ture 则将 TreeItem 标记为生成字段,否则将其清除(默认为Ture)
-
-
返回值
- 一个相同的树项;
11.7.2.9. treeitem:set_hidden([bool])
将 TreeItem 标记为隐藏字段(既不显示也不在过滤器中使用);已废弃
之前,使用此方法不返回任何东西,但自从 1.11.3 版本开始,它会返回一个相同的树项,以允许链式调用;
-
参数
-
bool (optional)
一个 Lua 的布尔型,如果为 Ture 则将 TreeItem 标记为生成字段,否则将其清除(默认为Ture)
-
-
返回值
- 一个相同的树项;
11.7.2.10. treeitem:set_len(len)
在 TreeItem 已经被创建之后,在 tvb 的内部设置其长度;
之前,使用此方法不返回任何东西,但自从 1.11.3 版本开始,它会返回一个相同的树项,以允许链式调用;
-
参数
-
len
要使用的长度;
-
-
返回值
- 一个相同的树项;
11.7.2.11. treeitem:referenced(protofield)
检查一个 ProtoField 或 Dissector 是否被一个过滤器/Tap/UI引用;
如果该方法返回 False,意味着这个字段(或Dissector)不需要被解析,可以安全地跳过。通过跳过一个字段而不是解析它,解析器通常会运行得更快,因为 Wireshark 在不需要这个字段时不会做额外的解析工作;
你可以把它和 TreeItem.visible 属性结合起来使用。当 TreeItem 是可见的,该方法将总是返回 TRUE。当它不可见并且字段没有被引用时,你可以通过不解析字段来加快解析速度,因为显示或过滤时将不需要它;
该方法需要一个参数,可以是一个 ProtoField 或 Dissector ;
当你需要决定是否调用一个子 Dissector 时,Dissector 形式很有用。
-
参数
-
protofield
需要检查是否被引用的 ProtoField 或 Dissector ;
-
-
返回值
- 表示该 ProtoField/Dissector 是否被引用的布尔值;
11.7.2.12. treeitem:__tostring()
返回一个 TreeItem 的调试信息字符串;
11.7.2.13. treeitem.text
模式:仅用于检索或赋值(Mode: Retrieve or assign);
设置或获取该 TreeItem 的 显示字符串 (string);
当作为获取器时,如果该 TreeItem 没有显示字符串,则返回nil;
11.7.2.14. treeitem.visible
模式:仅用于检索(Mode: Retrieve only)
获取该 TreeItem 的子树的状态 (boolean);
11.7.2.15. treeitem.generated
模式:仅用于检索或赋值(Mode: Retrieve or assign);
设置或获取该 TreeItem 的 生成状态 (boolean);
11.7.2.16. treeitem.hidden
模式:仅用于检索或赋值(Mode: Retrieve or assign);
设置/获取 TreeItem的隐藏状态 (boolean).
11.7.2.17. treeitem.len
模式:仅用于检索或赋值(Mode: Retrieve or assign);
在 TreeItem以及被创建后, 设置/获取 TreeItem 在 tvb 内部的长度;