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.