Download raw body.
libpcap: teach gencode how to match ipv6 and ipv4 packets for DLT_RAW
this allows you filter on ip and ip6 packets like you do on other DLTs
by looking at the first nibble.
before this libpcap would just say "yes" if you asked for just ip or
ip6:
xdlg@oak ~$ tcpdump -r erspan.raw.pcap -d ip
(000) ret #116
xdlg@oak ~$ tcpdump -r erspan.raw.pcap -d ip6
(000) ret #116
or worse:
xdlg@oak ~$ tcpdump -r erspan.raw.pcap -d mpls
(000) ldh [-1]
(001) jeq #0x8847 jt 2 jf 3
(002) ret #116
(003) ret #0
xdlg@oak ~$ tcpdump -r erspan.raw.pcap -d arp
(000) ldh [-1]
(001) jeq #0x806 jt 2 jf 3
(002) ret #116
(003) ret #0
with this diff it can match on the packet:
xdlg@pitcher ~$ tcpdump -r erspan.raw.pcap -d ip
(000) ldb [x + 0]
(001) rsh #4
(002) jeq #0x4 jt 3 jf 4
(003) ret #116
(004) ret #0
xdlg@pitcher ~$ tcpdump -r erspan.raw.pcap -d ip6
(000) ldb [x + 0]
(001) rsh #4
(002) jeq #0x6 jt 3 jf 4
(003) ret #116
(004) ret #0
we also get this:
xdlg@pitcher ~$ tcpdump -r erspan.raw.pcap -d arp
tcpdump: expression rejects all packets
ok?
Index: gencode.c
===================================================================
RCS file: /cvs/src/lib/libpcap/gencode.c,v
diff -u -p -r1.67 gencode.c
--- gencode.c 15 Sep 2024 07:14:58 -0000 1.67
+++ gencode.c 5 Jun 2025 05:51:30 -0000
@@ -768,12 +768,14 @@ init_linktype(int type)
off_nl = 12;
return;
- case DLT_USBPCAP:
- /* FALLTHROUGH */
case DLT_RAW:
- off_linktype = -1;
+ off_linktype = 0;
off_nl = 0;
return;
+ case DLT_USBPCAP:
+ off_linktype = -1;
+ off_nl = 0;
+ break;
}
bpf_error("unknown data link type 0x%x", linktype);
/* NOTREACHED */
@@ -910,6 +912,38 @@ gen_linktype(int proto)
return (gen_cmp(0, BPF_W, (bpf_int32)v));
break;
}
+ case DLT_RAW: {
+ struct slist *s0, *s1;
+ struct block *b;
+ int v;
+
+ switch (proto) {
+ case ETHERTYPE_IP:
+ v = 4;
+ break;
+ case ETHERTYPE_IPV6:
+ v = 6;
+ break;
+ default:
+ return gen_false();
+ }
+
+ /* A = p[X+off_linktype] */
+ s0 = new_stmt(BPF_LD|BPF_B|BPF_IND);
+ s0->s.k = off_linktype;
+
+ /* A = A >> 4 */
+ s1 = new_stmt(BPF_ALU|BPF_RSH|BPF_K);
+ s1->s.k = 4;
+ sappend(s0, s1);
+
+ b0 = new_block(JMP(BPF_JEQ));
+ b0->stmts = s0;
+ b0->s.k = v;
+
+ return (b0);
+ }
+
case DLT_PFLOG:
if (proto == ETHERTYPE_IP)
return (gen_cmp(offsetof(struct pfloghdr, af), BPF_B,
libpcap: teach gencode how to match ipv6 and ipv4 packets for DLT_RAW