Skip to content

Instantly share code, notes, and snippets.

@broofa
Created August 13, 2018 18:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save broofa/b1bc17f9be900507927012d83b72e185 to your computer and use it in GitHub Desktop.
Save broofa/b1bc17f9be900507927012d83b72e185 to your computer and use it in GitHub Desktop.
-- b-CAP.lua
--
-- a basic Wireshark's LUA dissector for Binary Controller Access Protocol
-- see README for installation and usage
--
-- Copyright (C) 2014 DENSO WAVE INCORPORATED
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-- b-CAP definition
bCAP_proto = Proto("b-cap", "b-CAP", "Binary Controller Access Protocol")
-- function: main
function bCAP_proto.dissector(buffer, pinfo, tree)
pinfo.cols.protocol = "b-CAP"
local subtree = tree:add(bCAP_proto, buffer(), "b-CAP Packet")
if buffer(0, 1):uint() ~= 1 or buffer(buffer:len() - 1, 1):uint() ~= 4 then
subtree:add(buffer(), "Error: Message length is too long")
return
end
-- pinfo.port_type -> tcp: 2, udp: 3 (maybe)
if buffer(buffer:len() - 2, 1):uint() == 1 then
subtree:add(buffer(), "Error: This message compressed by ZIP")
return
end
subtree:add(buffer(1, 4), "Message length: " .. buffer(1, 4):le_uint())
subtree:add(buffer(5, 2), "Serial number: " .. buffer(5, 2):le_uint())
subtree:add(buffer(7, 2), "Version or Retry: " .. buffer(7, 2):le_uint())
subtree:add(buffer(9, 4), "Function ID or Return code: " .. buffer(9, 4):le_int())
local num = buffer(13, 2):le_uint()
subtree:add(buffer(13, 2), "# of Args: " .. num)
-- tvb -> Variant array
tvb2VariantArray(subtree, buffer, 15, num, true)
end
-- load table of udp.port
udp_table = DissectorTable.get("udp.port")
udp_table:add(5007, bCAP_proto)
-- load table of tcp.port
tcp_table = DissectorTable.get("tcp.port")
tcp_table:add(5007, bCAP_proto)
-- function: tvb -> Variant arrray
function tvb2VariantArray(tree, buffer, offset, num, first)
local tmp = offset
for i = 0, (num - 1) do
local subtree
if first then
subtree = tree:add(buffer(offset, buffer(offset, 4):le_int() + 4), "Arg " .. i)
offset = offset + 4
else
subtree = tree:add(i .. ":")
end
-- Data type
local type = buffer(offset, 2):le_int()
subtree:add(buffer(offset, 2), "Data type: " .. DataType2String(type))
offset = offset + 2
-- The number of arrays
local ary = buffer(offset, 4):le_uint()
subtree:add(buffer(offset, 4), "The number of arrays: " .. ary)
offset = offset + 4
-- Variant
offset = offset + tvb2Variant(subtree, buffer, offset, type, ary)
end
return offset - tmp
end
-- function: tvb -> Variant
function tvb2Variant(tree, buffer, offset, type, ary)
local tmp = offset
local str
if type >= 0x2000 then
type = type - 0x2000
if type == 17 then -- UI1 | ARRAY
for i = 0, (ary - 1) do
if i == 0 then
str = buffer(offset, 1):le_uint()
else
str = str .. ", " .. buffer(offset + i, 1):le_uint()
end
end
tree:add(buffer(offset, ary), "Data: " .. str)
offset = offset + ary
elseif type == 2 then -- I2 | ARRAY
for i = 0, (ary - 1) do
if i == 0 then
str = buffer(offset, 2):le_uint()
else
str = str .. ", " .. buffer(offset + 2 * i, 2):le_int()
end
end
tree:add(buffer(offset, 2 * ary), "Data: " .. str)
offset = offset + 2 * ary
elseif type == 18 then -- UI2 | ARRAY
for i = 0, (ary - 1) do
if i == 0 then
str = buffer(offset, 2):le_uint()
else
str = str .. ", " .. buffer(offset + 2 * i, 2):le_uint()
end
end
tree:add(buffer(offset, 2 * ary), "Data: " .. str)
offset = offset + 2 * ary
elseif type == 3 then -- I4 | ARRAY
for i = 0, (ary - 1) do
if i == 0 then
str = buffer(offset, 4):le_uint()
else
str = str .. ", " .. buffer(offset + 4 * i, 4):le_int()
end
end
tree:add(buffer(offset, 4 * ary), "Data: " .. str)
offset = offset + 4 * ary
elseif type == 19 then -- UI4 | ARRAY
for i = 0, (ary - 1) do
if i == 0 then
str = buffer(offset, 4):le_uint()
else
str = str .. ", " .. buffer(offset + 4 * i, 4):le_uint()
end
end
tree:add(buffer(offset, 4 * ary), "Data: " .. str)
offset = offset + 4 * ary
elseif type == 4 then -- R4 | ARRAY
for i = 0, (ary - 1) do
if i == 0 then
str = buffer(offset, 4):le_float()
else
str = str .. ", " .. buffer(offset + 4 * i, 4):le_float()
end
end
tree:add(buffer(offset, 4 * ary), "Data: " .. str)
offset = offset + 4 * ary
elseif type == 5 then -- R8 | ARRAY
for i = 0, (ary - 1) do
if i == 0 then
str = buffer(offset, 8):le_float()
else
str = str .. ", " .. buffer(offset + 8 * i, 8):le_float()
end
end
tree:add(buffer(offset, 8 * ary), "Data: " .. str)
offset = offset + 8 * ary
elseif type == 6 then -- CY | ARRAY
for i = 0, (ary - 1) do
if i == 0 then
str = buffer(offset, 8):le_int64()
else
str = str .. ", " .. buffer(offset + 8 * i, 8):le_int64()
end
end
tree:add(buffer(offset, 8 * ary), "Data: " .. str)
offset = offset + 8 * ary
elseif type == 7 then -- DATE | ARRAY
for i = 0, (ary - 1) do
if i == 0 then
str = buffer(offset, 8):le_float()
else
str = str .. ", " .. buffer(offset + 8 * i, 8):le_float()
end
end
tree:add(buffer(offset, 8 * ary), "Data: " .. str)
offset = offset + 8 * ary
elseif type == 11 then -- BOOL | ARRAY
for i = 0, (ary - 1) do
if i == 0 then
if buffer(offset, 2):le_int() == 0 then
str = "False"
else
str = "True"
end
else
if buffer(offset + 2 * i, 2):le_int() == 0 then
str = str .. ", False"
else
str = str .. ", True"
end
end
end
tree:add(buffer(offset, 2 * ary), "Data: " .. str)
offset = offset + 2 * ary
elseif type == 8 then -- BSTR | ARRAY
local len, mem
mem = offset
for i = 0, (ary - 1) do
len = buffer(offset, 4):le_uint()
if i == 0 then
if len > 0 then
str = buffer(offset + 4, len):le_ustring()
else
str = ""
end
else
str = str .. ", "
if len > 0 then
str = str .. buffer(offset + 4, len):le_ustring()
end
end
offset = offset + 4 + len
end
tree:add(buffer(mem, offset - mem), "Data: " .. str)
elseif type == 12 then -- VARIANT | ARRAY
local len = tvb2VariantArray(tree, buffer, offset, ary, false)
offset = offset + len
end
else
if type == 10 then -- ERROR
str = buffer(offset, 4):le_int()
tree:add(buffer(offset, 4), "Data: " .. str)
offset = offset + 4
elseif type == 17 then -- UI1
str = buffer(offset, 1):le_uint()
tree:add(buffer(offset, 1), "Data: " .. str)
offset = offset + 1
elseif type == 2 then -- I2
str = buffer(offset, 2):le_int()
tree:add(buffer(offset, 2), "Data: " .. str)
offset = offset + 2
elseif type == 18 then -- UI2
str = buffer(offset, 2):le_uint()
tree:add(buffer(offset, 2), "Data: " .. str)
offset = offset + 2
elseif type == 3 then -- I4
str = buffer(offset, 4):le_int()
tree:add(buffer(offset, 4), "Data: " .. str)
offset = offset + 4
elseif type == 19 then -- UI4
str = buffer(offset, 4):le_uint()
tree:add(buffer(offset, 4), "Data: " .. str)
offset = offset + 4
elseif type == 4 then -- R4
str = buffer(offset, 4):le_float()
tree:add(buffer(offset, 4), "Data: " .. str)
offset = offset + 4
elseif type == 5 then -- R8
str = buffer(offset, 8):le_float()
tree:add(buffer(offset, 8), "Data: " .. str)
offset = offset + 8
elseif type == 6 then -- CY
str = buffer(offset, 8):le_int64()
tree:add(buffer(offset, 8), "Data: " .. str)
offset = offset + 8
elseif type == 7 then -- DATE
str = buffer(offset, 8):le_float()
tree:add(buffer(offset, 8), "Data: " .. str)
offset = offset + 8
elseif type == 11 then -- BOOL
if buffer(offset, 2):le_int() == 0 then
str = "False"
else
str = "True"
end
tree:add(buffer(offset, 2), "Data: " .. str)
offset = offset + 2
elseif type == 8 then -- BSTR
local len = buffer(offset, 4):le_uint()
if len > 0 then
str = buffer(offset + 4, len):le_ustring()
else
str = ""
end
tree:add(buffer(offset, 4 + len), "Data: " .. str)
offset = offset + 4 + len
end
end
return offset - tmp
end
-- Data type string
function DataType2String(type)
local strReturn = ""
if type >= 0x2000 then
strReturn = "VT_ARRAY | "
type = type - 0x2000
end
if type == 0 then
strReturn = strReturn .. "VT_EMPTY"
elseif type == 1 then
strReturn = strReturn .. "VT_NULL"
elseif type == 10 then
strReturn = strReturn .. "VT_ERROR"
elseif type == 17 then
strReturn = strReturn .. "VT_UI1"
elseif type == 2 then
strReturn = strReturn .. "VT_I2"
elseif type == 18 then
strReturn = strReturn .. "VT_UI2"
elseif type == 3 then
strReturn = strReturn .. "VT_I4"
elseif type == 19 then
strReturn = strReturn .. "VT_UI4"
elseif type == 4 then
strReturn = strReturn .. "VT_R4"
elseif type == 5 then
strReturn = strReturn .. "VT_R8"
elseif type == 6 then
strReturn = strReturn .. "VT_CY"
elseif type == 7 then
strReturn = strReturn .. "VT_DATE"
elseif type == 11 then
strReturn = strReturn .. "VT_BOOL"
elseif type == 8 then
strReturn = strReturn .. "VT_BSTR"
elseif type == 12 then
strReturn = strReturn .. "VT_VARIANT"
end
return strReturn
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment