From 2e987e0a1473b2183d739d383f88ac5f3f6c92bf Mon Sep 17 00:00:00 2001 From: kn Date: Sat, 12 Sep 2020 09:27:23 +0000 Subject: Fix byte order handling for DLT_LOOP links Fixing filters on DLT_LOOP revealed that we treat DLT_NULL, DLT_ENC and DLT_LOOP the same way even though DLT_LOOP stores the AF value in network not byte order like the rest. This amends the missing conversion which ought to land with the recent commit exposing the byte order mismatch: revision 1.53 date: 2020/07/21 22:44:55; author: dlg; state: Exp; lines: +2 -2; DLT_LOOP does have a link header, so tell pcap-filter so it can use it. ... debugged with and ok kn@ Discussed with bluhm who reported src/regress/sys/netinet6/rip6cksum/ failing on i386 after above commit. The comment in this commit is taken from libpcap upstream as is modulo additional file-save related byte-order handling which we don't seem to do. OK bluhm --- lib/libpcap/gencode.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'lib/libpcap') diff --git a/lib/libpcap/gencode.c b/lib/libpcap/gencode.c index 4e858f001e7..a9fb14be943 100644 --- a/lib/libpcap/gencode.c +++ b/lib/libpcap/gencode.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gencode.c,v 1.55 2020/08/03 03:40:02 dlg Exp $ */ +/* $OpenBSD: gencode.c,v 1.56 2020/09/12 09:27:22 kn Exp $ */ /* * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 @@ -912,16 +912,33 @@ gen_linktype(proto) case DLT_LOOP: case DLT_ENC: case DLT_NULL: - /* XXX */ + { + int v; + if (proto == ETHERTYPE_IP) - return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET))); + v = AF_INET; #ifdef INET6 else if (proto == ETHERTYPE_IPV6) - return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET6))); + v = AF_INET6; #endif /* INET6 */ else return gen_false(); + + /* + * For DLT_NULL, the link-layer header is a 32-bit word + * containing an AF_ value in *host* byte order, and for + * DLT_ENC, the link-layer header begins with a 32-bit + * word containing an AF_ value in host byte order. + * + * For DLT_LOOP, the link-layer header is a 32-bit + * word containing an AF_ value in *network* byte order. + */ + if (linktype != DLT_LOOP) + v = htonl(v); + + return (gen_cmp(0, BPF_W, (bpf_int32)v)); break; + } case DLT_PFLOG: if (proto == ETHERTYPE_IP) return (gen_cmp(offsetof(struct pfloghdr, af), BPF_B, -- cgit v1.2.3