This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

How do I extract buffer values from a ProtoField?

0

Let's say I have an packet that looks like this:

[ ETH, IP, myHeader ]

MyHeader is my own protocol which consists of myHeader.x1 (the first three bits) and myHeader.x2 (the next 5 bits).

What I want to do is loop through the whole pcap file to find all the frames, where a condition is fulfilled that myHeader.x1 AND myHeader.x2 are of a certain value.

The place where I am stuck at is the if-statement. I do not know how to retreive the value for x1 and x2. The following snippet:

local variable = buffer(offset, 1) 
if (variable:uint() == somevalue) 
...

works, but it gets the whole byte while I am only interested in the first three bits and the other five bits as two separate values. Does anybody know how to do this? I will provide the code for further clarity below. Look at the if-statement.

-- Initiate and collect data
MYPROTO = Proto ("myproto", "myheader")

local Header = MYPROTO.fields Header.x1 = ProtoField.uint8 ("myproto.x1", "X1", base.DEC, nil, 0xE0) Header.x2 = ProtoField.uint8 ("myproto.x2", "X2", base.DEC, nil, 0x1F)

function MYPROTO.dissector (buffer, pinfo, tree) local offset = 0 local subtree = tree:add (MYPROTO, buffer(offset, 2))
subtree:add (Header.x1, buffer(offset, 1)) subtree:add (Header.x2, buffer(offset, 1)) offset = offset + 1

if (Header.x1 == 2 AND Header.x2 == 3) then
    print frame.row 
end

end

– Register the dissector udp_table = DissectorTable.get("ip.proto") udp_table:add(0xFFF, MYPROTO)

Any help is greatly appreciated!

asked 18 Apr ‘13, 04:29

harkap's gravatar image

harkap
58811
accept rate: 0%

edited 18 Apr ‘13, 22:24

helloworld's gravatar image

helloworld
3.1k42041


One Answer:

2
if (Header.x1 == 2 AND Header.x2 == 3)

This is a common mistake. The ProtoField cannot be used to extract values in this manner. You have to manipulate the TvbRange (the object of buffer(offset, 1) in your code) to get the bitfields. There are a few ways to do this.

Option 1: TvbRange:bitfield()

You can use TvbRange:bitfield() to extract a subset of bits from the buffer.

-- get first 3 bits starting from bit 0 (leftmost bit);
-- and next 5 bits starting from bit 3
local first3 = buffer(offset,1):bitfield(0,3)
local next5 = buffer(offset,1):bitfield(3,5)

if (first3 == 2) AND (next5 == 3) then print 'foo' end

Option 2: Lua bitop

You can use the built-in Lua bitop library to mask and/or shift bits of an integer, extracted from the buffer:

local byte = buffer(0,1):uint()

– assume bit 0 is leftmost – right-shift 5 bits to get upper 3 local bits0to2 = bit.rshift(byte, 5)

– mask out upper 3 bits to get lower 5 local bits3to7 = bit.band(byte, 0x1F)

Option 3: 8-bit comparison

If you always compare the first 3 bits and the last 5, you could probably compare all 8 bits at once:

– in your example, you check for x1 == 2 and x2 == 3,
– which is equal to 0100 0011 (0x43)
if buffer(offset, 1):uint() == 0x43 then
print 'foo'
end

answered 18 Apr ‘13, 22:20

helloworld's gravatar image

helloworld
3.1k42041
accept rate: 28%

edited 18 Apr ‘13, 22:22

Thank you helloworld, you are king =)

just wish it had been stated somewhere as easily as you just showed here so that I wouldnt have spent so much time on this..

(19 Apr ‘13, 06:18) harkap