hello folks :

As you guys have been aware, I am hacking libpcap for a while. Me and
Bill noticed something seriously broken for any filter expression that
has a "not vlan" in it. For example, take a look at the filter code
generated by libpcap with an expression like "not vlan and tcp port
80" :

BpfExpression '(not vlan and tcp port 80)'
      { 0x28,  0,  0, 0x0000000c }, //(000) ldh  [12]
      { 0x15, 19,  0, 0x00008100 }, //(001) jeq  #0x8100     jt 21      jf 2
      { 0x28,  0,  0, 0x00000010 }, //(002) ldh  [16]
      { 0x15,  0,  6, 0x000086dd }, //(003) jeq  #0x86dd     jt 4       jf 10
      { 0x30,  0,  0, 0x00000018 }, //(004) ldb  [24]
      { 0x15,  0, 15, 0x00000006 }, //(005) jeq  #0x6        jt 6       jf 21
      { 0x28,  0,  0, 0x0000003a }, //(006) ldh  [58]
      { 0x15, 12,  0, 0x00000050 }, //(007) jeq  #0x50       jt 20      jf 8
      { 0x28,  0,  0, 0x0000003c }, //(008) ldh  [60]
      { 0x15, 10, 11, 0x00000050 }, //(009) jeq  #0x50       jt 20      jf 21
      { 0x15,  0, 10, 0x00000800 }, //(010) jeq  #0x800      jt 11      jf 21
      { 0x30,  0,  0, 0x0000001b }, //(011) ldb  [27]
      { 0x15,  0,  8, 0x00000006 }, //(012) jeq  #0x6        jt 13      jf 21
      { 0x28,  0,  0, 0x00000018 }, //(013) ldh  [24]
      { 0x45,  6,  0, 0x00001fff }, //(014) jset #0x1fff     jt 21      jf 15
      { 0xb1,  0,  0, 0x00000012 }, //(015) ldxb 4*([18]&0xf)
      { 0x48,  0,  0, 0x00000012 }, //(016) ldh  [x + 18]
      { 0x15,  2,  0, 0x00000050 }, //(017) jeq  #0x50       jt 20      jf 18
      { 0x48,  0,  0, 0x00000014 }, //(018) ldh  [x + 20]
      { 0x15,  0,  1, 0x00000050 }, //(019) jeq  #0x50       jt 20      jf 21
      {  0x6,  0,  0, 0x0000ffff }, //(020) ret  #65535
      {  0x6,  0,  0, 0x00000000 }, //(021) ret  #0


As you can see, it loads offset 12 (ethertype). For vlan packets, it
jumps to #21 and returns false right away. However, for packets that
are not vlan tagged, it goes to #2 which loads offset 16 in the
packet. Notice that this is wrong! The offsets should be incremented
by 4 only for vlan tagged packets and not for non-vlan packets. The
problem is that in gencode.c, the off_linktype increments by 4
unconditionally whether or not the packet actually contains a vlan
tag. We do not want to increment this offset if "not vlan" is true. So
the above filter code is generated wrong.

I just wanted to point this out to folks who wishes to dig in and fix
it. I do not have time right now to think of a proper solution. It
would seem using unconditional increments of offsets like off_linktype
below the parser is not going to work. How do you know if the parser
is going to take your code generated from the "vlan" expression and
just negate it? Or may be we can hack another rule in grammar.y. I
don't know.

cheers,
ani
_______________________________________________
tcpdump-workers mailing list
tcpdump-workers@lists.tcpdump.org
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers

Reply via email to