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.