Lua - 显示字段ASCII解析器

时间:2017-08-07 09:06:45

标签: filter lua wireshark-dissector protofield

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

以下是我到目前为止所测试的字段的定义:

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表值:

我不知道如何使其工作,以便在数据包视图上显示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

2 个答案:

答案 0 :(得分:1)

这是另一种对我有用的方法。我不确定你喜欢哪个,但你现在有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的“文件 - >从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编译(64位),使用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。

答案 1 :(得分:0)

这可能是一种更有效的方法,但您可以尝试这样的事情吗?

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