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

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


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
permanent link

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
Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Question tags:

×637
×431

question asked: 18 Apr '13, 04:29

question was seen: 7,550 times

last updated: 19 Apr '13, 06:18

p​o​w​e​r​e​d by O​S​Q​A