title: Deconstructing BPF filter in TCPdump
body: <p>Trying to deconstruct this TCPdump BPF style filter, and need some help:</p>
  
  <pre><code>'tcp[((tcp[12:1] &amp; 0xf0) &gt;&gt; 2):4] = 0x47455420'
  </code></pre>
  
  <p>Its taken from <a href="https://www.wireshark.org/lists/wireshark-users/201003/msg00024.html" rel="nofollow">here</a></p>
  
  <p>Steps that have taken to better understand what is going on:</p>
  
  <pre><code>1. Lets convert the 0x47455420 to ascii 
      ===&gt; GET 
      ===&gt; tcp[((tcp[12:1] &amp; 0xf0) &gt;&gt; 2):4] = GET
  2. Examine the inner tcp filter: (tcp[12:1] &amp; 0xf0) 
      ===&gt; the 0xf0 == 0000 0000 1111 0000 ===&gt; I suppose it is save to discard the upper zeros so I can write 1111 0000
      ===&gt; tcp[12:1] == 08 (start filtering from byte 13 (0 based indexing, so you could also say start with the byte that has index 12) for 1 byte, so only 13th byte);
      ===&gt; 08 == 0000 1000
      ===&gt; 0000 1000 &amp; 1111 0000 == 0000 (bitwise and = if both are 1 then end result is one)
  </code></pre>
  
  <p>This is where I got confused. The explanation in the hyperlink I provided above is saying </p>
  
  <p><code>multiply it by four ( (tcp[12:1] &amp; 0xf0)&gt;&gt;2 ) which should give the tcp header length</code></p>
  
  <p>Impossible if it is zero. Please:</p>
  
  <ol>
  <li>help me find the mistake in my calculations (maybe I'm mixing TCP and IP headers?);</li>
  <li>provide some guidance whether my logic is correct.</li>
  </ol>
  
  <p>This is the packet:</p>
  
  <pre><code>19:10:30.091065 IP (tos 0x0, ttl 63, id 40127, offset 0, flags [DF], proto TCP (6), length 2786)
  10.240.35.81.47856 &gt; 172.17.13.201.8080: Flags [P.], cksum 0xf2ef (incorrect -&gt; 0xb8f8), seq 2263020471:2263023205, ack 4187927811, win 28, options [nop,nop,TS val 1906863883 ecr 214445688], length 2734
  0x0000:  1a17 8e8a a3a0 026d 627d 049c 0800 4500  .......mb}....E.
           0,1  2,3  ...  ...  ...  ...  12,13 ...                    &lt;=== byte indexes
           1,2  3,4  ...  ...  ...  ...  13,14 ...                    &lt;=== counting how many bytes
  0x0010:  0ae2 9cbf 4000 3f06 ac3b 0af0 2351 ac11  ....@.?..;..#Q..  &lt;=== 0x0010 number correctly identifies that the first two diggits are the 16th byte
           16,17 ... ...
  0x0020:  0dc9 baf0 1f90 86e2 f3b7 f99e b503 8018  ................
  0x0030:  001c f2ef 0000 0101 080a 71a8 6f0b 0cc8  ..........q.o...
  0x0040:  2e78 4745 5420 2f69 636f 6e73 2f75 6e6b  .xGET./icons/unk
  0x0050:  6e6f 776e 2e67 6966 2048 5454 502f 312e  nown.gif.HTTP/1.
  0x0060:  310d 0a68 6f73 743a 2070 6870 2d6d 696e  1..host:.php-min
  </code></pre>