Статья написана под впечатлением от ранее опубликованной Пишем плагин-диссектор для Wireshark, в виде её продолжения.
В качестве альтернативы написанию плагинов на Си, Wireshark предлагает API для скриптовых языков – Lua и Python. К сожалению, оказалось, что в Windows-сборке Python до сих пор не поддерживается. Зато есть Lua.
Преимущества скриптового подхода:
Напишем аналогичный плагин-диссектор для разбора протокола FOO, используя Lua. Сам протокол описан вRFC оригинальной статье, и здесь для краткости не рассматривается.
Первым делом запускаем Wireshark, и в окошке About проверяем, что сборка включает Lua:

Далее, находим файл init.lua в папке Wireshark. Убеждаемся, что расширение Lua включено:
Добавляем в конец файла путь к нашему плагину:
На этом подготовительная работа завершена, все просто.
Я постарался сохранить авторские имена переменных и сделать вывод в Wireshark максимально похожим. Открываем foo_dissector.lua в текстовом редакторе и пишем:
Готово, можно запускать Wireshark.

Кстати, для отладки удобнее и быстрее использовать текстовую версию «великого рассекателя пакетов» — TShark.
Lua Support in Wireshark
www.wireshark.org/docs/wsug_html_chunked/wsluarm.html
Devendra @ Work — Create a Wireshark dissector in Lua
delog.wordpress.com/2010/09/27/create-a-wireshark-dissector-in-lua
Stig Bjørlykke — Lua Scripting in Wireshark
ссылка на PDF: DT06_Bjorlykke_Lua Scripting in Wireshark.pdf
В качестве альтернативы написанию плагинов на Си, Wireshark предлагает API для скриптовых языков – Lua и Python. К сожалению, оказалось, что в Windows-сборке Python до сих пор не поддерживается. Зато есть Lua.
Преимущества скриптового подхода:
- Никакого шаманства с Makefile, сборками и пересборками плагина
- Низкий порог входа – код проще для новичков и/или не знакомых с Си
- Более компактная программа (что на данном примере практически незаметно)
- Скорость разбора протокола ниже, по сравнению с диссектором на Си
- Плагины на Lua нельзя сделать частью дистрибутива Wireshark
- Для быстрого прототипирования и отладки диссектор пишется на Lua/Python
- Далее, если необходимо, готовый уже прототип переписывается на Си
- Profit!
Напишем аналогичный плагин-диссектор для разбора протокола FOO, используя Lua. Сам протокол описан в
Настройка окружения
Первым делом запускаем Wireshark, и в окошке About проверяем, что сборка включает Lua:

Далее, находим файл init.lua в папке Wireshark. Убеждаемся, что расширение Lua включено:
disable_lua = false
Добавляем в конец файла путь к нашему плагину:
FOOPROTO_SCRIPT_PATH = "C:\\!my\\habr\\"
dofile(FOOPROTO_SCRIPT_PATH .. "foo_dissector.lua")
На этом подготовительная работа завершена, все просто.
Код диссектора
Я постарался сохранить авторские имена переменных и сделать вывод в Wireshark максимально похожим. Открываем foo_dissector.lua в текстовом редакторе и пишем:
p_foo = Proto("foo", "FOO Protocol") -- Определение нового протокола
-- Текстовые отображения некоторых типов данных
packettypes = { "Ping request", "Ping acknowledgment", "Print payload" }
packetbool = { [0] = "False", "True" }
-- Заголовки протокола
local f_hdr_version = ProtoField.uint8("foo.hdr.version",
"FOO Header Version", base.DEC, {"Version 1"})
local f_hdr_type = ProtoField.uint8("foo.hdr.type",
"FOO Header Type", base.DEC, packettypes)
local f_hdr_flags = ProtoField.uint8("foo.hdr.flags", "FOO Header Flags", base.HEX)
-- Битовые флаги
local f_hdr_flags_first = ProtoField.uint8("foo.hdr.flags.first",
"FOO first flag", base.DEC, packetbool, 0x01)
local f_hdr_flags_second = ProtoField.uint8("foo.hdr.flags.second",
"FOO second flag", base.DEC, packetbool, 0x02)
local f_hdr_flags_onemore = ProtoField.uint8("foo.hdr.flags.onemore",
"FOO onemore flag", base.DEC, packetbool, 0x04)
-- Остаток заголовка и данные
local f_hdr_bool = ProtoField.bool ("foo.hdr.bool", "FOO Header Boolean")
local f_pl_len = ProtoField.uint32("foo.pl_len", "FOO Payload Length")
local f_payload = ProtoField.string("foo.payload", "FOO Payload", base.STRING)
-- Регистрируем все поля протокола
p_foo.fields = { f_hdr_version, f_hdr_type, f_hdr_flags,
f_hdr_flags_first, f_hdr_flags_second, f_hdr_flags_onemore,
f_hdr_bool, f_pl_len, f_payload }
-- Собственно функция диссектора для протокола FOO
function p_foo.dissector(buf, pinfo, tree)
if buf:len() == 0 then return end
pinfo.cols.protocol = p_foo.name -- в колонке Protocol будет название протокола
subtree = tree:add(p_foo, buf(0)) -- создаем поддерево
subtree:add(f_hdr_version, buf(0,1)) -- начинаем добавлять поля
local ver = buf(0,1):uint()
if ver == 1 then
local type_str = packettypes[buf(1,1):uint()]
if type_str == nil then type_str = "Unknown" end
pinfo.cols.info = "Type: " .. type_str -- в колонке Info будет отображаться тип пакета
subtree:add(f_hdr_type, buf(1,1))
subtree:add(f_hdr_flags, buf(2,1))
subtree:add(f_hdr_flags_first, buf(2,1))
subtree:add(f_hdr_flags_second, buf(2,1))
subtree:add(f_hdr_flags_onemore, buf(2,1))
subtree:add(f_hdr_bool, buf(3,1))
subtree:add_le(f_pl_len, buf(4,4)) -- поле длины в Little Endian
local pl_len = buf(4,4):le_uint()
subtree:add(f_payload, buf(8,pl_len)) -- данные
else
subtree:append_text(string.format(", Unknown version of Foo protocol (0x%02x)", ver))
end
end
-- регистрируем диссектор на UDP порт 35000
local udp_dissector_table = DissectorTable.get("udp.port")
udp_dissector_table:add(35000, p_foo)
Готово, можно запускать Wireshark.
Результат

Кстати, для отладки удобнее и быстрее использовать текстовую версию «великого рассекателя пакетов» — TShark.
Список источников
Lua Support in Wireshark
www.wireshark.org/docs/wsug_html_chunked/wsluarm.html
Devendra @ Work — Create a Wireshark dissector in Lua
delog.wordpress.com/2010/09/27/create-a-wireshark-dissector-in-lua
Stig Bjørlykke — Lua Scripting in Wireshark
ссылка на PDF: DT06_Bjorlykke_Lua Scripting in Wireshark.pdf