Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

I think there's an even easier way to achieve the same results using something like this:

f.data = ProtoField.bytes("S8HR_proto.data", "Data Hex")

local tvbr = buffer(offset, tlvlen)
tlv_tree:add(f.data, tvbr):
    append_text(", Data ASCII: " .. Struct.fromhex(tostring(tvbr:bytes())))

Unfortunately, at least as far as I can tell, neither solution displays non-printable characters very well, and if there's a 0 in the bytestream, then the string will be truncated. So to deal with that, here's an alternate solution:

function bytes2ascii(bytearr)
    local ascii = {}

    for i = 1, bytearr:len() do
        local b = bytearr:get_index(i - 1)
        if b >= 32 and b <= 127 then
            ascii[i] = string.char(b)
        else
            ascii[i] = '.'
        end
    end
    return table.concat(ascii)
end

f.data = ProtoField.bytes("S8HR_proto.data", "Data Hex")

local tvbr = buffer(offset, tlvlen)
tlv_tree:add(f.data, tvbr):
    append_text(", Data ASCII: " .. bytes2ascii(tvbr:bytes()))

And if you want to be able to filter the field separately between binary and ASCII data, then you might consider adding separate fields, e.g.:

f.data = ProtoField.bytes("S8HR_proto.data", "Data Hex")
f.asciidata = ProtoField.bytes("S8HR_proto.asciidata", "Data ASCII")

local tvbr = buffer(offset, tlvlen)
tlv_tree:add(f.data, tvbr)
tlv_tree:add(f.data, tvbr, bytes2ascii(tvbr:bytes()))

You can also mark it as a Generated field too if you'd like:

tlv_tree:add(f.data, tvbr, bytes2ascii(tvbr:bytes())):set_generated()

There may be other solutions too, depending on what you're expecting for your output. For example, unless I'm misreading the documentation then at least in theory it should be possible to call tvbr:string(), as per the documentation in section 11.8.3.18. tvbrange:string([encoding]); however that didn't work in my testing, so I suspect there's a Wireshark bug here, either in the implementation or in the documentation, because it doesn't work as advertised, namely:

Returns
A string containing all bytes in the TvbRange including all zeroes (e.g., "a\000bc\000").

I think there's an even easier way to achieve the same results using something like this:

f.data = ProtoField.bytes("S8HR_proto.data", "Data Hex")

local tvbr = buffer(offset, tlvlen)
tlv_tree:add(f.data, tvbr):
    append_text(", Data ASCII: " .. Struct.fromhex(tostring(tvbr:bytes())))

Unfortunately, at least as far as I can tell, neither solution displays non-printable characters very well, and if there's a 0 in the bytestream, then the string will be truncated. So to deal with that, here's an alternate solution:

function bytes2ascii(bytearr)
    local ascii = {}

    for i = 1, bytearr:len() do
        local b = bytearr:get_index(i - 1)
        if b >= 32 and b <= 127 then
            ascii[i] = string.char(b)
        else
            ascii[i] = '.'
        end
    end
    return table.concat(ascii)
end

f.data = ProtoField.bytes("S8HR_proto.data", "Data Hex")

local tvbr = buffer(offset, tlvlen)
tlv_tree:add(f.data, tvbr):
    append_text(", Data ASCII: " .. bytes2ascii(tvbr:bytes()))

And if you want to be able to filter the field separately between binary and ASCII data, then you might consider adding separate fields, e.g.:

f.data = ProtoField.bytes("S8HR_proto.data", "Data Hex")
Hex", base.NONE)
f.asciidata = ProtoField.bytes("S8HR_proto.asciidata", ProtoField.string("S8HR_proto.asciidata", "Data ASCII")
ASCII", base.ASCII)

local tvbr = buffer(offset, tlvlen)
tlv_tree:add(f.data, tvbr)
tlv_tree:add(f.data, tlv_tree:add(f.asciidata, tvbr, bytes2ascii(tvbr:bytes()))

You can also mark it as a Generated field too if you'd like:

tlv_tree:add(f.data, tvbr, bytes2ascii(tvbr:bytes())):set_generated()

There may be other solutions too, depending on what you're expecting for your output. For example, unless I'm misreading the documentation then at least in theory it should be possible to call tvbr:string(), as per the documentation in section 11.8.3.18. tvbrange:string([encoding]); however that didn't work in my testing, so I suspect there's a Wireshark bug here, either in the implementation or in the documentation, because it doesn't work as advertised, namely:

Returns
A string containing all bytes in the TvbRange including all zeroes (e.g., "a\000bc\000"). "a\000bc\000").