Lua - Показать поле ASCII 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 из каждого байта значения поля:
Я не знаю, как заставить это работать так, чтобы это отображало значение 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 ответа
Вот альтернативный метод, который также работает для меня. Я не уверен, что вы предпочитаете, но теперь у вас есть 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:
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:
Скомпилировано (64-битное) с 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.
Вероятно, есть более эффективный способ сделать это, но вы могли бы попробовать что-то подобное?
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)))
)
)