magのOSS備忘録

使ったOSSソフトウェアについて書いていきます。

Wiresharkの独自プラグインで既存のDissectorを呼び出す

独自にLuaで定義したプラグイン(Dissector)にてJSON形式データをパースしたかったので, 既存のDissectorを利用した.

下記のように呼び出せばよい.

--
-- プロトコルを作成する.
--
json_proto = Proto("json_proto", "Description: JSON Test Protocol")

-- 名前が長いのでjson_proto.fieldsに別名をつける.
f_json = json_proto.fields

--
-- プロトコルの各フィールドについて型情報, 表示フィルタ, ラベル名等をそれぞれ定義する.
--

-- フレーム境界を認識するためのJSON形式データ長.
f_json.len  = ProtoField.uint32("json_proto.len",  "JSON Data Length", base.DEC)

-- JSON形式データ.
f_json.data = ProtoField.string("json_proto.data", "JSON Data",        base.ASCII)

--
-- 定義したProtoにdissectorという名称の関数を定義する.
--
function json_proto.dissector(buffer, pinfo, tree)
    pinfo.cols.protocol = "JSON Test Protocol"

    local subtree = tree:add(json_proto, buffer(), "JSON Test Protocol")
    local length = buffer(0, 4):uint()

    -- サブツリーに各フィールドを追加する.
    subtree:add(f_json.len,  buffer(0, 4),      length)
    -- ※蛇足だが文字列としても表示しておく.
    subtree:add(f_json.data, buffer(4, length), buffer(4, length):string())

    --
    -- Wireshark組み込みのJSON用のDissectorを呼び出す.
    --
    local json_dissector = Dissector.get("json")
    json_dissector:call(buffer(4, length):tvb(), pinfo, subtree)
end

--
-- 定義したプロトコルとTCPポート 20000 を紐付ける.
--
tcp_table = DissectorTable.get("tcp.port")
tcp_table:add(20000, json_proto)

Wiresharkにこのプラグインを読み込ませ, キャプチャしたパケットを見ると下記のように表示される.

f:id:boiled_mag:20180506151717p:plain
Wiresharkでの表示

参考

11.6. Functions for new protocols and dissectors

LuaAPI/Dissector - The Wireshark Wiki