-
-
Save JJTech0130/da77af43269076f6ea78f69471d1df6e to your computer and use it in GitHub Desktop.
Usbmuxd protocol dissector for Wireshark. Passes TCP to Wireshark's built-in TCP dissector
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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") | |
| local f_usb_ep_dir = Field.new("usb.endpoint_address.direction") | |
| 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)) | |
| -- Version response comes from the device (IN endpoint) | |
| 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 | |
| -- USB addresses confuse the TCP conversation tracker. Override with stable | |
| -- fake IPs derived from bus/device so streams are uniquely keyed per device. | |
| -- Device IP: <bus>.<dev>.0.2, Host IP: <bus>.0.0.1 | |
| local src_str = tostring(pinfo.src) | |
| local usb_str = src_str ~= "host" and src_str or tostring(pinfo.dst) | |
| local bus, dev = usb_str:match("^(%d+)%.(%d+)%.") | |
| if bus then | |
| local ep_dir = f_usb_ep_dir() | |
| local dev_ip = bus .. "." .. dev .. ".0.2" | |
| local host_ip = bus .. ".0.0.1" | |
| -- use the endpoint direction bit to determine actual flow direction. | |
| pinfo.src = Address.ip(ep_dir and ep_dir.value == 1 and dev_ip or host_ip) | |
| pinfo.dst = Address.ip(ep_dir and ep_dir.value == 1 and host_ip or dev_ip) | |
| pinfo.net_src = pinfo.src | |
| pinfo.net_dst = pinfo.dst | |
| end | |
| 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