added an initial InterMinitel packet dissector for Wireshark

This commit is contained in:
Izaya 2019-12-19 20:47:33 +11:00
parent 5c1730d9d3
commit 3496f70d6d
2 changed files with 136 additions and 0 deletions

View File

@ -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

View File

@ -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