Skip to content

Instantly share code, notes, and snippets.

@axelkar
Last active May 7, 2026 20:29
Show Gist options
  • Select an option

  • Save axelkar/7febe7e8ac5e1d4755b05549c6fd6b1e to your computer and use it in GitHub Desktop.

Select an option

Save axelkar/7febe7e8ac5e1d4755b05549c6fd6b1e to your computer and use it in GitHub Desktop.
Usbmuxd protocol dissector for Wireshark. Passes TCP to Wireshark's built-in TCP dissector
local proto_usbmuxd = Proto("usbmuxd", "Usbmuxd Protocol")
proto_usbmuxd.fields.protocol = ProtoField.uint32("usbmuxd.protocol", "Message Kind", base.DEC)
proto_usbmuxd.fields.length = ProtoField.uint32("usbmuxd.length", "Length", base.DEC)
proto_usbmuxd.fields.magic = ProtoField.uint32("usbmuxd.magic", "Magic", base.HEX)
proto_usbmuxd.fields.tx_seq = ProtoField.uint16("usbmuxd.tx_seq", "Transmit sequence", base.DEC)
proto_usbmuxd.fields.rx_seq = ProtoField.uint16("usbmuxd.rx_seq", "Receive sequence", base.DEC)
proto_usbmuxd.fields.version_major = ProtoField.uint32("usbmuxd.version_major", "Major version", base.DEC)
proto_usbmuxd.fields.version_minor = ProtoField.uint32("usbmuxd.version_minor", "Minor version", base.DEC)
proto_usbmuxd.fields.data = ProtoField.bytes("usbmuxd.data", "Data", base.NONE)
-- Version + packet number by device ID
local usbmuxd_version = nil
local tcp_dissector = Dissector.get("tcp")
function proto_usbmuxd.dissector(buf,pinfo,tree)
pinfo.cols.protocol = proto_usbmuxd.name;
local version = 1
if usbmuxd_version and pinfo.number > usbmuxd_version.packet then
version = usbmuxd_version.version
end
local subtree = tree:add(proto_usbmuxd, buf()):append_text(" V" .. tostring(version))
mkind = buf(0, 4):uint()
local mkind_str = " (Unknown)"
if mkind == 0 then
mkind_str = " (Version)"
elseif mkind == 1 then
mkind_str = " (Control)"
elseif mkind == 2 then
mkind_str = " (Setup)"
elseif mkind == 6 then
mkind_str = " (TCP)"
end
subtree:add(proto_usbmuxd.fields.protocol, buf(0, 4)):append_text(mkind_str)
pinfo.cols.info:append(mkind_str)
subtree:add(proto_usbmuxd.fields.length, buf(4, 4))
local data_offset = 8
if version == 2 then
subtree:add(proto_usbmuxd.fields.magic, buf(8, 4))
subtree:add(proto_usbmuxd.fields.tx_seq, buf(12, 2))
subtree:add(proto_usbmuxd.fields.rx_seq, buf(14, 2))
data_offset = 16
end
if mkind == 0 then
subtree:add(proto_usbmuxd.fields.version_major, buf(data_offset, 4))
subtree:add(proto_usbmuxd.fields.version_minor, buf(data_offset+4, 4))
if tostring(pinfo.dst) == "host" then
usbmuxd_version = {
version = buf(data_offset, 4):uint(),
packet = pinfo.number
}
end
elseif mkind == 1 then
subtree:add(proto_usbmuxd.fields.data, buf(data_offset))
elseif mkind == 2 then
subtree:add(proto_usbmuxd.fields.data, buf(data_offset))
elseif mkind == 6 then
tcp_dissector:call(buf(data_offset):tvb(), pinfo, tree)
else
subtree:add(proto_usbmuxd.fields.data, buf(data_offset))
end
end
local usb_bulk_table = DissectorTable.get("usb.bulk")
usb_bulk_table:add(0xff, proto_usbmuxd)
usb_bulk_table:add(0xffff, proto_usbmuxd)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment