IPv6 packets can contain headers (like options) before the TCP/UDP/ICMP6

header. pf finds the first TCP/UDP/ICMP6 header to filter by traversing
the header chain. In the case where headers are skipped, the protocol
checksum verification used the wrong length (included the skipped headers),
leading to incorrectly mismatching checksums. Such IPv6 packets with
headers were silently dropped.

Discovered by:	Bernhard Schmidt
MFC after:	1 week
This commit is contained in:
Daniel Hartmeier 2004-12-05 12:15:43 +00:00
parent 18c3f40e94
commit 8092705059

View File

@ -6334,7 +6334,8 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0)
goto done;
}
if (dir == PF_IN && pf_check_proto_cksum(m, off,
ntohs(h->ip6_plen), IPPROTO_TCP, AF_INET6)) {
ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)),
IPPROTO_TCP, AF_INET6)) {
action = PF_DROP;
goto done;
}
@ -6372,7 +6373,8 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0)
goto done;
}
if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m,
off, ntohs(h->ip6_plen), IPPROTO_UDP, AF_INET6)) {
off, ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)),
IPPROTO_UDP, AF_INET6)) {
action = PF_DROP;
goto done;
}
@ -6411,7 +6413,8 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0)
goto done;
}
if (dir == PF_IN && pf_check_proto_cksum(m, off,
ntohs(h->ip6_plen), IPPROTO_ICMPV6, AF_INET6)) {
ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)),
IPPROTO_ICMPV6, AF_INET6)) {
action = PF_DROP;
goto done;
}