ANNOUNCEMENT: Live Wireshark University & Allegro Packets online APAC Wireshark Training Session
April 17th, 2024 | 14:30-16:00 SGT (UTC+8) | Online

Wireshark-dev: Re: [Wireshark-dev] Lua dissector: How to set sub-field bit widths using prefere

From: "Maynard, Chris" <Christopher.Maynard@xxxxxxx>
Date: Tue, 4 Sep 2018 16:08:01 +0000

You might want to implement a function to handle this, something like so?

 

local function dissect_RuPortId_F(tree, buffer)

 

    local t = {}

    local mask = 2^my_protocol.prefs.ru_port_id_width - 1

    local val = bit.band(buffer(4, 2):uint(), mask)

 

    for i = 15, 0, -1 do

        if bit.band(bit.rshift(mask, i), 1) == 1 then

            table.insert(t, (bit.band(bit.rshift(val, i), 1) == 1 and '1') or '0')

        else

            table.insert(t, '.')

        end

 

        if (i % 4) == 0 then

            table.insert(t, ' ')

        end

    end

    tree:add(RuPortId_F, buffer(4, 2)):set_text(table.concat(t) .. " = Ru Port ID: " .. val)

 

end -- dissect_RuPortId_F()

 

 

dissect_RuPortId_F(tree, buffer)

 

If the offset isn’t fixed at 4, then you can pass that as an argument too, and if you want to be able to add any information to the Info column, then pass pinfo also.

 

And you probably want to limit the bit width to only values between 1-16.  One way to do this is to use an enum preference instead of a uint preference, e.g.:

 

local ru_port_id_width_enums = {

{1, "1", 1}, {2, "2", 2}, {3, "3", 3}, {4, "4", 4},

{5, "5", 5}, {6, "6", 6}, {7, "7", 7}, {8, "8", 8},

{9, "9", 9}, {10, "10", 10}, {11, "11", 11}, {12, "12", 12},

{13, "13", 13}, {14, "14", 14}, {15, "15", 15}, {16, "16", 16}

}

my_protocol.prefs.ru_port_id_width = Pref.enum("RU Port ID width", 4, "The RU Port ID width, in bits (1-16)", ru_port_id_width_enums, false)

 

You *may* be able to still error check the preference if declared as a uint using a my_protocol.prefs_changed() function[1], but the enum type seems ok here, and anyway, I’m actually not entirely sure how to do it since the following does not work:

 

function my_protocol.prefs_changed()

 

    if my_protocol.prefs.ru_port_id_width < 1 then

        my_protocol.prefs.ru_port_id_width = 1

    end

 

    if my_protocol.prefs.ru_port_id_width > 16 then

        my_protocol.prefs.ru_port_id_width = 16

    end

 

end -- my_protocol.prefs_changed()

 

Here, you end up with an error of the sort, “Lua: Error During execution of prefs apply callback: [string “C:\Users\cmaynard\AppData\Roaming\Wireshark\p…”:51: bad argument #3 to '__newindex' (userdata expected, got number)”.  As far as I can tell, there seems to be no way to limit preferences to a valid range in Lua.  If this is the case, then it seems to be a limitation worthy of an enhancement bug report.

 

Hope it helps.

- Chris

[1]: See 11.6.4.6. proto.prefs_changed at https://www.wireshark.org/docs/wsdg_html_chunked/lua_module_Proto.html

 

 

From: Wireshark-dev [mailto:wireshark-dev-bounces@xxxxxxxxxxxxx] On Behalf Of David Aldrich
Sent: Monday, September 3, 2018 11:32 AM
To: wireshark-dev@xxxxxxxxxxxxx
Subject: [Wireshark-dev] Lua dissector: How to set sub-field bit widths using preferences?

 

Our protocol includes a 16-bit field which is sub-divided into 4 sub-fields.  The width of those sub-fields is variable so I want to specify the widths using Wireshark preferences.  I understand how to create and read  Wireshark preferences but I am unsure of how to apply them in this circumstance.

 

My code structure looks like this:

 

my_protocol = Proto("...""...")

 

-- Create a preference

my_protocol.prefs.ru_port_id_width = Pref.uint( "RU_Port_ID width ", 4 )

 

-- Read the preference

ru_port_id_width = my_protocol.prefs.ru_port_id_width

 

-- Specify a field using the preference

RuPortId_F = ProtoField.uint16("...", "...", base.HEX, NULL, ((2^ru_port_id_width)-1))

 

-- Create a fields table and add the field to it

xran_protocol.fields = {RuPortId_F}

 

-- Then specify the dissector function

function my_protocol.dissector(buffer, pinfo,tree)

 

    -- Show the field in a subtree

    local RtcidPcid_range = buffer(4,2)                 -- the 16-bit field

    local ecpriRtcidPcid = ecpriRtcidPcid_range:uint()

    subtree:add(RuPortId_F, RtcidPcid_range, RtcidPcid) -- the variable width sub-field

 

 

The trouble with this is that the preference is only read at startup. A new value can't be specified by the user without restarting Wireshark to apply it.

 

Is there a better sequence of code that I code use to overcome this limitation?

 

Best regards

 

David

 

 

 

 

 

 

CONFIDENTIALITY NOTICE: This message is the property of International Game Technology PLC and/or its subsidiaries and may contain proprietary, confidential or trade secret information.  This message is intended solely for the use of the addressee.  If you are not the intended recipient and have received this message in error, please delete this message from your system. Any unauthorized reading, distribution, copying, or other use of this message or its attachments is strictly prohibited.