From 3496f70d6dceda52078b81ae50afbd12564dc1bf Mon Sep 17 00:00:00 2001 From: XeonSquared Date: Thu, 19 Dec 2019 20:47:33 +1100 Subject: [PATCH] added an initial InterMinitel packet dissector for Wireshark --- vTunnel/Wireshark/imtdissector.lua | 70 ++++++++++++++++++++++++++++++ vTunnel/Wireshark/interminitel.lua | 66 ++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 vTunnel/Wireshark/imtdissector.lua create mode 100644 vTunnel/Wireshark/interminitel.lua diff --git a/vTunnel/Wireshark/imtdissector.lua b/vTunnel/Wireshark/imtdissector.lua new file mode 100644 index 0000000..815c038 --- /dev/null +++ b/vTunnel/Wireshark/imtdissector.lua @@ -0,0 +1,70 @@ +local imtp = Proto("imt","InterMinitel") +local imt = require "interminitel" + +local pid = ProtoField.string("imt.packet_id","Packet ID") +local ptype = ProtoField.int32("imt.packet_type","Packet type") +local dest = ProtoField.string("imt.destination","Destination address") +local src = ProtoField.string("imt.source","Source address") +local port = ProtoField.int32("imt.port","Port") +local data = ProtoField.string("imt.data","Data") +local conv = ProtoField.int32("imt.conversation","Conversation") +local cport = ProtoField.int32("imt.conversation_port","Conversation Port") + +local seg = ProtoField.string("imt.segment","Segment") + +imtp.fields = {pid, ptype, dest, src, port, data, conv, cport} + +local conversations = {} +local function checkConversation(p,c) + if p[5] == c.port and c.addresses[p[4]] and c.addresses[p[3]] then + return true + end + return false +end +local conversationPackets = {} + +function imtp.dissector(buffer,pinfo,tree) + pinfo.cols.protocol=imtp.name + local d = buffer():string() + local dp, sp = imt.decodePacket(d) + local subtree = tree:add(imtp,"InterMinitel Data") + for k,v in pairs(dp) do + subtree:add(imtp.fields[k], buffer(sp[k], tostring(v):len()), v) + end + pinfo.cols.src = dp[4] + pinfo.cols.dst = dp[3] + pinfo.cols.src_port = dp[5] + pinfo.cols.dst_port = dp[5] + if dp[2] == "0" then + pinfo.cols.info = "Unreliable packet." + elseif dp[2] == "1" then + pinfo.cols.info = "Reliable packet." + elseif dp[2] == "2" then + pinfo.cols.info = "Acknowledgement packet for '"..dp[6].."'" + end + if dp[6] == "openstream" then + local t = {addresses = {}, iport = dp[5]} + t.addresses[dp[3]] = true + t.addresses[dp[4]] = true + t.id = conversationPackets[dp[1]] or #conversations+1 + print("Conversation started by "..dp[4].." talking to "..dp[3].." on port "..tostring(dp[5])) + conversations[t.id] = t + subtree:add(conv, t.id):set_generated() + subtree:add(cport, t.iport):set_generated() + conversationPackets[dp[1]] = t.id + end + for k,v in pairs(conversations) do + if not v.port and v.iport == dp[5] and tonumber(dp[6]) and v.addresses[dp[3]] and v.addresses[dp[4]] then + v.port = tostring(tonumber(dp[6])) + print(string.format("Conversation %d port set to %d",k,v.port)) + subtree:add(conv, v.id):set_generated() + subtree:add(cport, v.iport):set_generated() + conversationPackets[dp[1]] = v.id + elseif checkConversation(dp,v) then + print(dp[1].." is part of "..tostring(k)) + subtree:add(conv, v.id):set_generated() + subtree:add(cport, v.iport):set_generated() + conversationPackets[dp[1]] = v.id + end + end +end diff --git a/vTunnel/Wireshark/interminitel.lua b/vTunnel/Wireshark/interminitel.lua new file mode 100644 index 0000000..ee915ce --- /dev/null +++ b/vTunnel/Wireshark/interminitel.lua @@ -0,0 +1,66 @@ +local imt = {} + +imt.ttypes = {} +imt.ttypes.string=1 +imt.ttypes.number=2 + +imt.ftypes = {tostring,tonumber} + +function imt.to16bn(n) + return string.char(math.floor(n/256))..string.char(math.floor(n%256)) +end +function imt.from16bn(s) + return (string.byte(s,1,1)*256)+string.byte(s,2,2) +end + +function imt.encodePacket(...) + local tArgs = {...} + local packet = string.char(#tArgs%256) + for _,segment in ipairs(tArgs) do + local segtype = type(segment) + segment = tostring(segment) + packet = packet .. imt.to16bn(segment:len()) .. string.char(imt.ttypes[segtype]) .. tostring(segment) + end + packet = imt.to16bn(packet:len()) .. packet + return packet +end + +function imt.decodePacket(s) + local count=0 + local function getfirst(n) + local ns = s:sub(1,n) + s=s:sub(n+1) + count=count+n + return ns + end + if s:len() < 2 then return false end + local plen = imt.from16bn(getfirst(2)) + local segments, starts = {}, {} + if s:len() < plen then return false end + local nsegments = string.byte(getfirst(1)) +-- print(tostring(plen).." bytes, "..tostring(nsegments).." segments") + for i = 1, nsegments do + starts[#starts+1] = count+3 + local seglen = imt.from16bn(getfirst(2)) + local segtype = imt.ftypes[string.byte(getfirst(1))] + local segment = getfirst(seglen) +-- print(seglen,segtype,segment,type(segment)) + segments[#segments+1] = segment + end + return segments, starts +end +function imt.getRemainder(s) + local function getfirst(n) + local ns = s:sub(1,n) + s=s:sub(n+1) + return ns + end + local plen = imt.from16bn(getfirst(2)) + if s:len() > plen then + getfirst(plen) + return s + end + return nil +end + +return imt