diff options
| author | s-ol <s+removethis@s-ol.nu> | 2024-02-18 19:17:25 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2024-02-18 19:17:25 +0000 |
| commit | eadeb98559ee1f4b896e016c598478fb0aebebcd (patch) | |
| tree | ed32f12740cd98b8a5ab40003b0156f7dac8ce5a /dissectors/t937.lua | |
| parent | improve wireshark dissectors (diff) | |
| download | t937-serial-eadeb98559ee1f4b896e016c598478fb0aebebcd.tar.gz t937-serial-eadeb98559ee1f4b896e016c598478fb0aebebcd.zip | |
clean up and add README
Diffstat (limited to 'dissectors/t937.lua')
| -rwxr-xr-x | dissectors/t937.lua | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/dissectors/t937.lua b/dissectors/t937.lua new file mode 100755 index 0000000..9d37ba6 --- /dev/null +++ b/dissectors/t937.lua @@ -0,0 +1,135 @@ +local proto = Proto("t937", "T-937/M Serial Control")
+
+local FUN_TABLE = {
+ [0x01] = "REQUEST_CONN",
+ [0xf1] = "CONFIRM_CONN",
+ [0x02] = "TEMP_STATUS",
+ [0x08] = "SET_HEATER",
+ [0x0d] = "SET_EXTRACTOR",
+}
+
+proto.experts.checksum = ProtoExpert.new("t937.checksum",
+ "T937 Checksum Error",
+ expert.group.CHECKSUM, expert.severity.ERROR
+)
+
+proto.fields.addr = ProtoField.uint16("t937.address", "Address", base.HEX)
+proto.fields.fun = ProtoField.uint8("t937.function", "Function", base.HEX, FUN_TABLE)
+proto.fields.len = ProtoField.uint8("t937.length", "Data Length", base.HEX)
+proto.fields.checksum = ProtoField.uint16("t937.checksum", "Message Checksum", base.HEX)
+
+proto.fields.data = ProtoField.bytes("t937.data", "Data")
+
+local function try_dissect(bytes, pinfo, tree)
+ -- minimum len is header + checksum
+ if bytes:len() < 4 + 2 then return end
+
+ local raw_len = bytes:uint(3, 1)
+ if bytes:len() < 4 + raw_len + 2 then return end
+
+ local buffer = bytes:subset(0, 4+raw_len+2):tvb("T-937 Frame")
+ local address = buffer(0, 2)
+ local fun = buffer(2, 1)
+ local len = buffer(3, 1)
+ local data = buffer(4, raw_len)
+ local checksum = buffer(4+raw_len, 2)
+
+ local sum = 0
+ for i=0,4+raw_len-1 do
+ sum = sum + buffer(i, 1):uint()
+ end
+
+ pinfo.cols.info:set("T937 " .. (FUN_TABLE[fun:uint()] or ""))
+ pinfo.cols.dst:clear_fence()
+ pinfo.cols.dst:set(address:bytes():tohex())
+
+ local sub = tree:add(proto, buffer())
+ sub:add(proto.fields.addr, address)
+ sub:add(proto.fields.fun, fun)
+ sub:add(proto.fields.len, len)
+ sub:add(proto.fields.data, data)
+
+ local cs = sub:add(proto.fields.checksum, checksum)
+ if sum ~= checksum:uint() then
+ cs:add_proto_expert_info(proto.experts.checksum, string.format(
+ "expected 0x%04x, got 0x%04x", checksum:uint(), sum
+ ))
+ end
+
+ return buffer:len()
+end
+
+local state
+
+function proto.init()
+ state = {
+ error = {},
+ rest = {
+ [P2P_DIR_SENT] = ByteArray.new(),
+ [P2P_DIR_RECV] = ByteArray.new(),
+ },
+ buffers = {},
+ last_number = -1,
+ }
+end
+
+function proto.dissector(_buf, pinfo, tree)
+ local buffers = state.buffers[pinfo.number]
+
+ if buffers then
+ for _,buffer in ipairs(buffers) do
+ try_dissect(buffer, pinfo, tree)
+ end
+ return true
+ end
+
+ local err = state.error[pinfo.p2p_dir]
+ if err then
+ if state.last_number == pinfo.number then
+ error(err)
+ else
+ return
+ end
+ end
+
+ if state.last_number >= pinfo.number then
+ error(string.format(
+ "dissection order not increasing: %d >= %d",
+ state.last_number, pinfo.number
+ ))
+ end
+
+ local rest = state.rest[pinfo.p2p_dir]
+ rest:append(_buf:bytes())
+ buffers = {}
+
+ while rest:len() > 0 do
+ local ok, len = pcall(try_dissect, rest, pinfo, tree)
+ if not ok then
+ print("GOT ERR", len, pinfo.number)
+ state.error[pinfo.p2p_dir] = len
+ state.last_number = pinfo.number
+ error(len)
+ elseif not len then
+ break
+ end
+
+ table.insert(buffers, rest:subset(0, len))
+
+ if len == rest:len() then
+ rest = ByteArray.new()
+ break
+ end
+
+ rest = rest:subset(len, rest:len() - len)
+ end
+
+ state.rest[pinfo.p2p_dir] = rest
+ state.buffers[pinfo.number] = buffers
+ state.last_number = pinfo.number
+ return true
+end
+
+pcall(proto.register_heuristic, proto, "ch340.serial_data", proto.dissector)
+pcall(proto.register_heuristic, proto, "pl2303.serial_data", proto.dissector)
+DissectorTable.get("rtacser.data"):add_for_decode_as(proto)
|
