tcpdump mailing list archives

Re: cap_compile() generates strange code with DLT_RAW


From: Guy Harris <guy () alum mit edu>
Date: Wed, 30 May 2007 11:14:07 -0700

Anton Yuzhaninov wrote:
Hello.

When libpcap build with -DINET6 pcap_compile() generates strange pbf
code with DLT_RAW

cap_compile_nopcap(65535, DLT_RAW, &bp, "udp", 1, 0)
generates this code:

# (000) ld       #0x0
{ code=0 jt=0 jf=0 k=0 }
# (001) ldb      [6]
{ code=48 jt=0 jf=0 k=6 }
# (002) jeq      #0x11            jt 5  jf 3
{ code=21 jt=2 jf=0 k=17 }
# (003) ldb      [9]
{ code=48 jt=0 jf=0 k=9 }
# (004) jeq      #0x11            jt 5  jf 6
{ code=21 jt=0 jf=1 k=17 }
# (005) ret      #65535
{ code=6 jt=0 jf=0 k=65535 }
# (006) ret      #0
{ code=6 jt=0 jf=0 k=0 }

It seems to be wrong.

(000) - seems to be nop, why it here?

Probably because the check for the network layer protocol was, for DLT_RAW, saying "true" for IPv4 or IPv6 and "false" for everything else, and the "true" test wasn't getting optimized out.

(001), (002) - check that byte with offset 6 (4 bits from flags filed
and 4 bits from fragment offset) equal 17 (protocol number for udp)
It seems to be wrong

...for IPv4, but not for IPv6 (if the next header is UDP).

Since both "is this IPv4?" and "is this IPv6?" were being answered as "yes", it was testing both the IPv6 "next header" field and the IPv4 "protocol" field, regardless of whether the packet is IPv4 or IPv6.

I've checked in a change to, for DLT_RAW, check the version field of the IPv4/IPv6 header; the generated code if INET6 is enabled is now:

(000) ldb      [0]
(001) and      #0xf0
(002) jeq      #0x60            jt 3    jf 5
(003) ldb      [6]
(004) jeq      #0x11            jt 10   jf 11
(005) ldb      [0]
(006) and      #0xf0
(007) jeq      #0x40            jt 8    jf 11
(008) ldb      [9]
(009) jeq      #0x11            jt 10   jf 11
(010) ret      #65535
(011) ret      #0

(maybe the check for IPv6 could be "not IPv4", which might avoid the need for two tests) and if it's not enabled is now:

(000) ldb      [0]
(001) and      #0xf0
(002) jeq      #0x40            jt 3    jf 6
(003) ldb      [9]
(004) jeq      #0x11            jt 5    jf 6
(005) ret      #65535
(006) ret      #0

(just because libpcap doesn't have IPv6 support, that doesn't mean that a DLT_RAW file it's reading won't contain IPv6 packets, so it still checks).

This is checked into the main and x.9 branches.
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: