luawiresharkwireshark-dissector

Displaying the bits values of a number in Wireshark Postdissector


I am writing a wireshark dissector of a custom protocol using LUA.For this custom protocol,there are no underlying TCP port or UDP port hence i have written a postdissector. I am able to capture the payload from the below layers and convert it into a string.

local io_b = tostring(customprotocol)

After this, io_b has the following data

io_b = 10:10:10:10:01:0f:00:0d:00:00:00:00:01:00:00:00:00:20:0a:00:00

At first I split this string with : as the seperator and copy the elements into an array/table.

datafields = {}
index = 1

for value in string.gmatch(io_b, "[^:]+") do 
   datafields[index] = value
   index = index + 1
end

Then I read each element of the datafield array as a uint8 value and check if a bit is set in that datafield element.How to make sure that each element of the table is uint8?

function lshift(x, by)
    return x * 2 ^ by
end

--checks if a bit is set at a position
function IsBitSet( b, pos)
    if b ~= nil then
      return tostring(bit32.band(tonumber(b),lshift(1,pos)) ~= 0)
    else
      return "nil"
    end
end

Then I want to display the value of each bit in the wireshark.I dont care about the first four bytes. The script displays each bit of the 5th byte(which is the 1st considered byte) correctly but displays all the bits value of the 6th byte and other remaining bytes as "nil".

 local data_in_2 = subtree:add(customprotocol,"secondbyte") 
 data_in_2:add(firstbit,(IsBitSet((datafields[6]),7)))
 data_in_2:add(secondbit,(IsBitSet((datafields[6]),6)))
 data_in_2:add(thirdbit,(IsBitSet((datafields[6]),5)))
 data_in_2:add(fourbit,(IsBitSet((datafields[6]),4)))
 data_in_2:add(fivebit,(IsBitSet((datafields[6]),3)))
 data_in_2:add(sixbit,(IsBitSet((datafields[6]),2)))
 data_in_2:add(sevenbit,(IsBitSet((datafields[6]),1)))
 data_in_2:add(eightbit,(IsBitSet((datafields[6]),0)))

What am i doing wrong?


Solution

  • Maybe i am wrong but it seems you can do it simpler with...

    io_b = '10:10:10:10:01:0f:00:0d:00:00:00:00:01:00:00:00:00:20:0a:00:00'
    -- Now replace all : on the fly with nothing and convert it with @Egor' comment tip
    -- Simply by using string method gsub() from within io_b
    b_num = tonumber(io_b:gsub('%:', ''), 16)
    print(b_num)
    -- Output: 537526272
    

    @shakingwindow - I cant comment so i ask here...
    Do you mean...

    io_b = '10:10:10:10:01:0f:00:0d:00:00:00:00:01:00:00:00:00:20:0a:00:00'
    -- Converting HEX to string - Replacing : with ,
    io_hex = io_b:gsub('[%x]+', '"%1"'):gsub(':', ',')
    -- Converting string to table
    io_hex_tab = load('return {' .. io_hex .. '}')()
    -- Put out key/value pairs by converting HEX value string to a number on the fly
    for key, value in pairs(io_hex_tab) do
     print(key, '=', tonumber(value, 16))
    end
    

    ...that puts out...

    1   =   16
    2   =   16
    3   =   16
    4   =   16
    5   =   1
    6   =   15
    7   =   0
    8   =   13
    9   =   0
    10  =   0
    11  =   0
    12  =   0
    13  =   1
    14  =   0
    15  =   0
    16  =   0
    17  =   0
    18  =   32
    19  =   10
    20  =   0
    21  =   0
    

    ...?