Соберите PDU в Луа Wireshark диссектора
В системе у меня есть собственный протокол, и я хотел бы внедрить анализатор Wireshark, чтобы я мог использовать Wireshark для анализа связи.
Объекты отправляются по протоколу, назовем их "Сообщения". Каждое сообщение может быть большим, может быть до 100 МБ, оно также может быть очень маленьким, например, 50 байт.
Каждое сообщение разбивается на куски размером около 1 кБ и помечается порядковым номером и идентификатором сообщения-подсказки, которые можно использовать на другом конце для повторной сборки сообщений.
До сих пор я успешно создал диссектор, который будет индивидуально регистрировать все чанки в Wireshark, но я хочу пойти дальше и также записывать все сообщения (чанки, собранные в сообщения) в Wireshark. Можно ли это сделать и как? Возможно ли реализовать диссектор поверх того диссектора, который я разработал ниже?
Если возможно реализовать диссектор поверх приведенного ниже, как я могу убедиться, что он будет анализировать только мои прото-PDU? Приведенный ниже диссектор запускает определенный порт TCP, но это не сработает для диссектора второй фазы...
myproto_proto = Proto("myproto", "My Protocol")
function myproto_proto.dissector(buffer, pinfo, tree)
pinfo.cols.protocol = "myproto"
local message_length = buffer(0, 4):le_uint()+4
if message_length>pinfo.len then
pinfo.desegment_len = message_length
pinfo.desegment_offset = 0
return;
end
local subtree = tree:add(myproto_proto, buffer(), "My Protocol Data")
local packet = subtree:add(buffer(0, message_length), "Chunk")
packet:add(buffer(0, 4), "Packet length: " .. buffer(0, 4):le_uint())
packet:add(buffer(32, 16), "Message ID")
packet:add(buffer(48, 4), "Block ID: " .. buffer(48, 4):le_uint())
packet:add(buffer(52, 4), "Max Block ID: " .. buffer(52, 4):le_uint())
packet:add(buffer(68, message_length-68-20), "Data")
pinfo.desegment_len = 0
pinfo.desegment_offset = message_length
return
end
tcp_table = DissectorTable.get("tcp.port")
tcp_table:add(1234, myproto_proto)
1 ответ
Допустим, вы создали второй диссектор msgproto
, Поскольку у вас, кажется, нет мультиплексирования между порциями и сообщениями, вам не нужно настраивать таблицу анализатора. Вместо этого в конце myproto_proto.dissector
ты делаешь
msgproto.dissector:call(buffer(68, message_length-68-20):tvb, pinfo, tree)
Это передаст все данные чанка на ваш msgproto
, В диссекторе протокола сообщений вы можете использовать поля протокола чанка и, конечно, tvb, который будет содержать только данные одного чанка. Теперь вам нужно собрать куски в один великолепно огромный телевизор. Сделать msgproto
иметь состояние:
local stateMap = {}
function msgproto.init()
stateMap = {}
end
Преобразуйте свой TVB в ByteArray и сохраните в stateMap
вместе с массивами из других вызовов вашего диссектора. Когда вы собрали все свои данные в один массив, давайте назовем его oarr
, сделайте из этого твб:
local otvb = ByteArray.tvb(oarr, "message data")
-- starting from 0, need to pass a tvb range, not a tvb.
stree:add(msgproto.fields.payload, otvb(0))
Предполагается, что у вас есть payload
поле типа Protofield.bytes
, Этот код заставит новую область данных под названием "данные сообщения" появиться рядом с вашей обычной панелью "Рамка" в нижней части окна Wireshark.
Я не уверен, насколько хорошо Wireshark понравятся ваши сверхбольшие буферы. Кроме того, я совершенно уверен, что изложенный выше подход будет работать. Я не использовал описанные методы в этом точном порядке, но я использовал все описанные методы, например, чтобы создать новую панель байтов, заполненную данными, сдутыми в чистом Lua.