Wireshark-users: Re: [Wireshark-users] Bitshifting With BPF in wireshark

From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Thu, 18 Jun 2015 17:15:51 -0700
On Jun 18, 2015, at 5:00 PM, asdfdsfds <angelofthedark@xxxxxxxxxxxxxxx> wrote:

> Hi, Write I have a question about BPF,

...which is the same in Wireshark and elsewhere, such as in tcpdump.

> I have the following filter
> 
> tcp [((tcp [12] & 0xF0) >> 2): 4] = 0x12341234
> 
> My question is the following
> (tcp [12] & 0xF0) >> 2
> 
> the bitshifting is performed clockwise to multiply the result of
> 
> (tcp [12] & 0xF0)

The result of (tcp[12] & 0xF0) is a 1-byte value, with the 4 uppermost bits containing the length of the TCP header, in units of 32-bit (4-byte) words, and the 4 lowermost bits containing 0.

So that result is *16 times* the number of 32-bit words in the TCP header, because of those 4 extra 0's at the end.

So it needs to be divided by 16 and then multiplied by 4, in order to get the number of *bytes* in the TCP header.

16/4 = 4, so that's equivalent to dividing by 4.

Therefore:

> Why bitshifting is the right and not the left?

Because you're dividing, not multiplying.

Alternatively, you could think of it as shifting right by 4 bits, to move the uppermost 4 bits into the lowermost 4 bits, and then shifting left by 2 bits, to multiply by 4.

> I saw filters where the IP header is made to the left as it should be .

In the IPv4 header, there's a byte with the IP version number in the uppermost 4 bits and the IP header length in the *lowermost* 4 bits, so all you need to do to get the IP header length is mask with 0x0F and shift left by 2 bits.

In the TCP header, there's a byte with the "data offset" (TCP header length) in the *uppermost* 4 bits, so you need to shift *right*.

So *both* are as they should be.

RFC 791:

	http://tools.ietf.org/html/rfc791

and RFC 793:

	http://tools.ietf.org/html/rfc793

are your friends here.