This diff simplifies the verification of ICMP checksums in
pf_check_proto_cksum() by letting it use the same in4_cksum() call that
is used for TCP and UDP checksums.
As a bonus, since in4_cksum() doesn't need that m_data/m_len dance the
code becomes much shorter as well.
OK?
Index: pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.865
diff -u -p -U10 -r1.865 pf.c
--- pf.c 22 Jan 2014 04:33:34 -0000 1.865
+++ pf.c 22 Jan 2014 22:33:23 -0000
@@ -5875,37 +5875,25 @@ pf_check_proto_cksum(struct pf_pdesc *pd
return (0);
}
if (pd->m->m_pkthdr.csum_flags & flag_bad || off < sizeof(struct ip) ||
pd->m->m_pkthdr.len < off + len) {
pd->csum_status = PF_CSUM_BAD;
return (1);
}
switch (af) {
#ifdef INET
case AF_INET:
- if (p == IPPROTO_ICMP) {
- if (pd->m->m_len < off) {
- pd->csum_status = PF_CSUM_BAD;
- return (1);
- }
- pd->m->m_data += off;
- pd->m->m_len -= off;
- sum = in_cksum(pd->m, len);
- pd->m->m_data -= off;
- pd->m->m_len += off;
- } else {
- if (pd->m->m_len < sizeof(struct ip)) {
- pd->csum_status = PF_CSUM_BAD;
- return (1);
- }
- sum = in4_cksum(pd->m, p, off, len);
+ if (pd->m->m_len < sizeof(struct ip)) {
+ pd->csum_status = PF_CSUM_BAD;
+ return (1);
}
+ sum = in4_cksum(pd->m, (p == IPPROTO_ICMP ? 0 : p), off, len);
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
if (pd->m->m_len < sizeof(struct ip6_hdr)) {
pd->csum_status = PF_CSUM_BAD;
return (1);
}
sum = in6_cksum(pd->m, p, off, len);
break;