Skip to content

Instantly share code, notes, and snippets.

@xWTF
Last active November 19, 2022 14:22
Show Gist options
  • Save xWTF/e124db3e48abc92184e583168fea5edb to your computer and use it in GitHub Desktop.
Save xWTF/e124db3e48abc92184e583168fea5edb to your computer and use it in GitHub Desktop.
Wireshark Lua Dissector: Yamux (Yet another Multiplexer) by HashiCorp
--[[
Wireshark Lua Dissector
Protocol: [Yamux](https://github.com/hashicorp/yamux) by HashiCorp
Get updates from [this gist](https://gist.github.com/xWTF/e124db3e48abc92184e583168fea5edb)
Copyright © 2022 xWTF
This work is free. You can redistribute it and/or modify it under the
terms of the Do What The Fuck You Want To Public License, Version 2,
as published by Sam Hocevar. See the COPYING file or http://www.wtfpl.net/
for more details.
--]]
local yamux_protocol = Proto("Yamux", "Yamux Protocol");
local types = {
[0x0] = "Data",
[0x1] = "Window Update",
[0x2] = "Ping",
[0x3] = "Go Away"
}
local flagMasks = {
[0x0] = "",
[0x1] = "SYN",
[0x2] = "ACK",
[0x4] = "FIN",
[0x8] = "RST"
}
local goAwayErrors = {
[0x0] = "Normal termination",
[0x1] = "Protocol error",
[0x2] = "Internal error"
}
local f_version = ProtoField.uint8("yamux.version", "Version")
local f_type = ProtoField.uint8("yamux.type", "Type", base.HEX, types)
local f_flags = ProtoField.uint16("yamux.flags", "Flags", base.HEX, flagMasks, 0xFF)
local f_stream = ProtoField.uint32("yamux.stream", "Stream ID")
local f_length = ProtoField.uint32("yamux.len", "Length")
local f_payload = ProtoField.bytes("yamux.payload", "Yamux payload")
yamux_protocol.fields = {f_version, f_type, f_flags, f_stream, f_length, f_payload}
local function dissect(offset, buf, tree)
local tvb_len = buf:len() - offset
-- minimal header length is 12 bytes
if tvb_len < 12 then
return tvb_len - 12
end
-- the version field is always set to 0
local version = buf(offset, 1)
if version:uint() ~= 0 then
return 0
end
local type = buf(offset + 1, 1):uint()
if types[type] == nil then
return 0
end
local t = tree:add(yamux_protocol, buf(offset, 12))
t:add(f_version, version)
t:add(f_type, buf(offset + 1, 1))
t:add(f_flags, buf(offset + 2, 2))
t:add(f_stream, buf(offset + 4, 4))
local payload_len = buf(offset + 8, 4)
local item_length = t:add(f_length, payload_len)
payload_len = payload_len:uint()
tvb_len = tvb_len - 12
if type == 0x0 then
if tvb_len < payload_len then
return tvb_len - payload_len
end
t:add(f_payload, buf(offset + 12, payload_len))
t:set_len(12 + payload_len)
return 12 + payload_len
elseif type == 0x3 then
item_length:set_text(goAwayErrors[payload_len])
end
return 12
end
function yamux_protocol.dissector(buf, pkt, tree)
local tvb_len = buf:len()
if tvb_len < 12 then
return 0
end
local offset = pkt.desegment_offset or 0
while offset < tvb_len do
local count = dissect(offset, buf, tree)
if count == 0 then
return offset
end
pkt.cols.protocol = yamux_protocol.name
if count < 0 then
pkt.desegment_len = -count
pkt.desegment_offset = offset
return count
end
offset = offset + count
end
return offset
end
local tcp_port_table = DissectorTable.get("tcp.port")
-- register your port here
tcp_port_table:add(4647, yamux_protocol)
tcp_port_table:add(7000, yamux_protocol)
tcp_port_table:add(8300, yamux_protocol)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment