Guy Harris writes:

tcp && (ip[2:2] > (((ip[0]&0xF) + (tcp[12] >> 4)) << 2))

Extending this to check for TCP or UDP with non-empty payload, I got the following:

# tcpdump -d 'ip && ((tcp && (ip[2:2] > ((ip[0]&0xF) + (tcp[12] >> 4)) << 2)) || (udp && udp[4:2] > 8))'
(000) ldh      [12]
(001) jeq      #0x800           jt 2    jf 27
(002) ldb      [23]
(003) jeq      #0x6             jt 4    jf 19
(004) ldh      [16]
(005) st       M[1]
(006) ldb      [14]
(007) and      #0xf
(008) st       M[4]
(009) ldxb     4*([14]&0xf)
(010) ldb      [x + 26]
(011) rsh      #4
(012) tax
(013) ld       M[4]
(014) add      x
(015) lsh      #2
(016) tax
(017) ld       M[1]
(018) jgt      x                jt 26   jf 27
(019) jeq      #0x11            jt 20   jf 27
(020) ldh      [20]
(021) jset     #0x1fff          jt 27   jf 22
(022) ldxb     4*([14]&0xf)
(023) ldh      [x + 18]
(024) ldx      #0x8
(025) jgt      x                jt 26   jf 27
(026) ret      #96
(027) ret      #0

Of note are that a special-purpose "iphdrsize" keyword that compiles directly to the special-purpose ldxb instruction would allow the optimizer to eliminate several instructions, and that the UDP case includes an implicit check for IP fragments that the TCP case does not. Now, you should generally not see TCP fragments if Path MTU discovery is working correctly, but it does happen, so an explicit check for "ip[6:2]&0x1FFF=0" should probably be added to the expression to either explicitly reject or accept non-initial fragments for TCP or UDP.

@alex

-
This is the tcpdump-workers list.
Visit https://lists.sandelman.ca/ to unsubscribe.

Reply via email to