Fix capture of fragmented ipv6 packets

This commit is contained in:
Michal Sekletar 2011-09-06 13:46:12 +02:00
parent 70b655cbd0
commit 1fe2be8921
2 changed files with 82 additions and 1 deletions

76
libpcap-fragment.patch Normal file
View File

@ -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

View File

@ -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 <msekleta@redhat.com> 14:1.1.1-4
- fix capture of fragmented ipv6 packets
* Fri Apr 22 2011 Miroslav Lichvar <mlichvar@redhat.com> 14:1.1.1-3
- ignore /sys/net/dev files on ENODEV (#693943)
- drop ppp patch