Lua - 显示字段 ASCII Dissector

Lua - Display field ASCII Dissector

我目前正在开发我的第一个 Protocol Dissector。我面临一个我无法解决的问题。基本上我有一个 8 字节长的字段(但定义超过 9 个字节),所以我创建了一个位域来定义这个原型字段。

以下是我目前测试过的字段的定义:

a) local harer_id = ProtoField.string   ("myProto.harer_id","Harer ID", base.ASCII)
b) local harer_id =  ProtoField.uint64   ("myProto.harer_id", "Harer ID", base.HEX )

然后我按照以下方式将它添加到解剖树中:

  local harer_id_long = tvbuf:range(16,9)
  body:add(harer_id, harer_id_long:bitfield(4,64))

最终会出现以下错误:

a) Gives no error but it doesnt return the value on ASCII format
    What I get: 0x0000000000313030
    What I want: 0x0000000000313030 (100)
b) calling 'add' on bad self (string expected, got userdata)

如果您有任何建议,我将不胜感激。

提前谢谢你,

马丁

编辑 1:

我写了这段代码,它将从字段值的每个字节中获取 ASCII table 值:

我不知道如何让它工作,以便它在数据包视图上显示 ASCII 值。

 function getASCII (str)
    resultStr = ""
    asciiValue="" 
    for i = 3, string.len(tostring(str))-1, 2 do
        asciiValue = string.char(tonumber(tostring(string.sub(tostring(str),i,i+1)), 16))
        if asciiValue~=nil then 
            resultStr = resultStr .. tostring(tonumber(asciiValue))
        end
    end
    resultStr = string.gsub(resultStr, "nil", "") 
    return resultStr
 end

可能有更有效的方法来执行此操作,但您可以尝试这样的方法吗?

harer_id = ProtoField.string("myProto.harer_id", "Harer ID", base.ASCII)

harer_item = body:add(harer_id, tvbuf(16, 9))
harer_item:set_text("Harer ID: " ..
    tonumber(
        string.char(bit.bor(bit.band(bit.lshift(tvbuf(16, 1):uint(), 4), 0xf0), bit.rshift(tvbuf(17, 1):uint(), 4))) ..
        string.char(bit.bor(bit.band(bit.lshift(tvbuf(17, 1):uint(), 4), 0xf0), bit.rshift(tvbuf(18, 1):uint(), 4))) ..
        string.char(bit.bor(bit.band(bit.lshift(tvbuf(18, 1):uint(), 4), 0xf0), bit.rshift(tvbuf(19, 1):uint(), 4))) ..
        string.char(bit.bor(bit.band(bit.lshift(tvbuf(19, 1):uint(), 4), 0xf0), bit.rshift(tvbuf(20, 1):uint(), 4))) ..
        string.char(bit.bor(bit.band(bit.lshift(tvbuf(20, 1):uint(), 4), 0xf0), bit.rshift(tvbuf(21, 1):uint(), 4))) ..
        string.char(bit.bor(bit.band(bit.lshift(tvbuf(21, 1):uint(), 4), 0xf0), bit.rshift(tvbuf(22, 1):uint(), 4))) ..
        string.char(bit.bor(bit.band(bit.lshift(tvbuf(22, 1):uint(), 4), 0xf0), bit.rshift(tvbuf(23, 1):uint(), 4))) ..
        string.char(bit.bor(bit.band(bit.lshift(tvbuf(23, 1):uint(), 4), 0xf0), bit.rshift(tvbuf(24, 1):uint(), 4)))
        )
    )

这是对我也适用的替代方法。我不确定你更喜欢哪个,但你现在有 2 个可供选择(假设你可以使用我原来的方法):

local harer_id = ProtoField.uint64("myProto.harer_id", "Harer ID", base.HEX)

harer_item = body:add(harer_id, tvbuf(16, 9):bitfield(4, 64))
harer_item:set_len(9)

vals = {}
for i = 0, 7 do
    vals[i] = bit.bor(buf(16 + i, 2):bitfield(4, 8), 0x30)
end
harer_item:append_text(" (" ..
    tonumber(string.format("%c%c%c%c%c%c%c%c", vals[0], vals[1], vals[2], vals[3], vals[4], vals[5], vals[6], vals[7])) ..
    ")")

编辑:这是一个简单的Lua解析器和样本包,您可以使用它来测试这个解决方案:

-- Protocol
local p_foo = Proto("foo", "FOO Protocol")

-- Fields
local f_foo_res1 = ProtoField.uint8("foo.res1", "Reserved 1", base.DEC, nil, 0xf0)
local f_foo_str = ProtoField.uint64("foo.str", "String", base.HEX)
local f_foo_res2 = ProtoField.uint8("foo.res2", "Reserved 2 ", base.DEC, nil, 0x0f)
local f_foo_res3 = ProtoField.uint8("foo.res3", "Reserved 3", base.HEX)
local f_foo_ipv6 = ProtoField.ipv6("foo.ipv6", "IPv6 Address")

p_foo.fields = { f_foo_res1, f_foo_str, f_foo_res2, f_foo_res3, f_foo_ipv6 }

-- Dissection
function p_foo.dissector(buf, pinfo, tree)
    local foo_tree = tree:add(p_foo, buf(0,-1))

    pinfo.cols.protocol:set("FOO")
    foo_tree:add(f_foo_res1, buf(0, 1))

    str_item = foo_tree:add(f_foo_str, buf(0, 9):bitfield(4, 64))
    str_item:set_len(9)

    vals = {}
    for i = 0, 7 do
        vals[i] = bit.bor(buf(i, 2):bitfield(4, 8), 0x30)
    end
    str_item:append_text(" (" ..
        tonumber(string.format("%c%c%c%c%c%c%c%c", vals[0], vals[1], vals[2], vals[3], vals[4], vals[5], vals[6], vals[7])) ..
        ")")

    foo_tree:add(f_foo_res2, buf(9, 1))
    foo_tree:add(f_foo_res3, buf(10, 1))
    foo_tree:add(f_foo_ipv6, buf(11, 16))
end

-- Registration
local udp_table = DissectorTable.get("udp.port")
udp_table:add(33333, p_foo)

使用text2pcap将此数据转换为Wireshark可以读取的数据包或使用Wireshark的"File -> Import From Hex Dump..."功能:

0000  00 0e b6 00 00 02 00 0e b6 00 00 01 08 00 45 00
0010  00 37 00 00 40 00 40 11 b5 ea c0 00 02 65 c0 00
0020  02 66 82 35 82 35 00 23 00 00 03 03 13 23 33 43
0030  53 63 70 80 64 20 01 0d b8 00 00 00 00 00 00 00
0040  00 00 00 00 01

我的 Wireshark 详细信息:
使用 Qt 5.6.2、WinPcap (4_1_3)、GLib 2.42.0 和 zlib 1.2.8,SMI 0.4.8,c-ares 1.12.0,Lua 5.2.4,GnuTLS 3.4.11,使用 Gcrypt 1.7.6,使用 MIT Kerberos,使用 GeoIP,使用 nghttp2 1.14.0, 使用 LZ4、使用 Snappy、使用 libxml2 2.9.4、使用 QtMultimedia、使用 AirPcap、使用 SBC,带 SpanDSP。