From 1fe2be8921b8441cf146c762fa2895e4663e5371 Mon Sep 17 00:00:00 2001 From: Michal Sekletar Date: Tue, 6 Sep 2011 13:46:12 +0200 Subject: [PATCH] Fix capture of fragmented ipv6 packets --- libpcap-fragment.patch | 76 ++++++++++++++++++++++++++++++++++++++++++ libpcap.spec | 7 +++- 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 libpcap-fragment.patch diff --git a/libpcap-fragment.patch b/libpcap-fragment.patch new file mode 100644 index 0000000..07442cf --- /dev/null +++ b/libpcap-fragment.patch @@ -0,0 +1,76 @@ +diff --git a/gencode.c b/gencode.c +index 1f2e6a3..2b624df 100644 +--- a/gencode.c ++++ b/gencode.c +@@ -5160,7 +5160,7 @@ gen_ipfrag() + struct slist *s; + struct block *b; + +- /* not ip frag */ ++ /* not IPv4 frag other than the first frag */ + s = gen_load_a(OR_NET, 6, BPF_H); + b = new_block(JMP(BPF_JSET)); + b->s.k = 0x1fff; +@@ -5203,7 +5203,7 @@ gen_portop(port, proto, dir) + { + struct block *b0, *b1, *tmp; + +- /* ip proto 'proto' */ ++ /* ip proto 'proto' and not a fragment other than the first fragment */ + tmp = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)proto); + b0 = gen_ipfrag(); + gen_and(tmp, b0); +@@ -5295,6 +5295,7 @@ gen_portop6(port, proto, dir) + struct block *b0, *b1, *tmp; + + /* ip6 proto 'proto' */ ++ /* XXX - catch the first fragment of a fragmented packet? */ + b0 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)proto); + + switch (dir) { +@@ -5396,7 +5397,7 @@ gen_portrangeop(port1, port2, proto, dir) + { + struct block *b0, *b1, *tmp; + +- /* ip proto 'proto' */ ++ /* ip proto 'proto' and not a fragment other than the first fragment */ + tmp = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)proto); + b0 = gen_ipfrag(); + gen_and(tmp, b0); +@@ -5500,6 +5501,7 @@ gen_portrangeop6(port1, port2, proto, dir) + struct block *b0, *b1, *tmp; + + /* ip6 proto 'proto' */ ++ /* XXX - catch the first fragment of a fragmented packet? */ + b0 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)proto); + + switch (dir) { +@@ -5976,6 +5978,11 @@ gen_proto(v, proto, dir) + int dir; + { + struct block *b0, *b1; ++#ifdef INET6 ++#ifndef CHASE_CHAIN ++ struct block *b2; ++#endif ++#endif + + if (dir != Q_DEFAULT) + bpf_error("direction applied to 'proto'"); +@@ -6140,7 +6147,15 @@ gen_proto(v, proto, dir) + case Q_IPV6: + b0 = gen_linktype(ETHERTYPE_IPV6); + #ifndef CHASE_CHAIN +- b1 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)v); ++ /* ++ * Also check for a fragment header before the final ++ * header. ++ */ ++ b2 = gen_cmp(OR_NET, 6, BPF_B, IPPROTO_FRAGMENT); ++ b1 = gen_cmp(OR_NET, 40, BPF_B, (bpf_int32)v); ++ gen_and(b2, b1); ++ b2 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)v); ++ gen_or(b2, b1); + #else + b1 = gen_protochain(v, Q_IPV6); + #endif diff --git a/libpcap.spec b/libpcap.spec index 39b6b79..0d40617 100644 --- a/libpcap.spec +++ b/libpcap.spec @@ -1,7 +1,7 @@ Name: libpcap Epoch: 14 Version: 1.1.1 -Release: 3%{?dist} +Release: 4%{?dist} Summary: A system-independent interface for user-level packet capture Group: Development/Libraries License: BSD with advertising @@ -14,6 +14,7 @@ Patch1: libpcap-man.patch Patch2: libpcap-multilib.patch Patch3: libpcap-s390.patch Patch4: libpcap-nodev.patch +Patch5: libpcap-fragment.patch %description Libpcap provides a portable framework for low-level network @@ -51,6 +52,7 @@ resources needed for developing libpcap applications. %patch2 -p1 -b .multilib %patch3 -p1 -b .s390 %patch4 -p1 -b .nodev +%patch5 -p1 -b .fragment #sparc needs -fPIC %ifarch %{sparc} @@ -92,6 +94,9 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/man5/pcap*.5* %changelog +* Tue Sep 06 2011 Michal Sekletar 14:1.1.1-4 +- fix capture of fragmented ipv6 packets + * Fri Apr 22 2011 Miroslav Lichvar 14:1.1.1-3 - ignore /sys/net/dev files on ENODEV (#693943) - drop ppp patch