summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2016-10-18 11:20:43 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2016-10-18 11:20:43 +0000
commitc0edf1d09650bff29054261f1bad27931590c156 (patch)
tree27a5b304241e667f455648dad96cd8b456d69729 /sys/net
parent2febd3c4ff6e2a5cc67ea4a7965a0f6448466069 (diff)
The checksum of a ICMP "need to frag" packet for TCP was wrong when
created from a ICMP6 "too big" packet. The function pf_change_icmp_af() has code to adjust the pseudo-header checksum in the ICMP6 case, but pf_test_state_icmp() changed the proto before the case was entered. So call pf_change_icmp_af() before the pd->proto is converted in the TCP and UDP payload case like it was already done for ICMP and ICMP6 payload. Found by sys/net/pf_forward regress test; OK henning@
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/pf.c20
1 files changed, 9 insertions, 11 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 340a8f695b6..aa7b9f33b8a 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.989 2016/10/09 18:01:57 henning Exp $ */
+/* $OpenBSD: pf.c,v 1.990 2016/10/18 11:20:42 bluhm Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -5104,6 +5104,10 @@ pf_test_state_icmp(struct pf_pdesc *pd, struct pf_state **state,
m_copyback(pd->m, pd->off,
sizeof(struct icmp6_hdr),
pd->hdr.icmp6, M_NOWAIT);
+ if (pf_change_icmp_af(pd->m, ipoff2,
+ pd, &pd2, &nk->addr[sidx],
+ &nk->addr[didx], pd->af, nk->af))
+ return (PF_DROP);
if (nk->af == AF_INET)
pd->proto = IPPROTO_ICMP;
else
@@ -5117,11 +5121,6 @@ pf_test_state_icmp(struct pf_pdesc *pd, struct pf_state **state,
&nk->addr[pd2.didx], nk->af);
pd->naf = nk->af;
- if (pf_change_icmp_af(pd->m, ipoff2,
- pd, &pd2, &nk->addr[sidx],
- &nk->addr[didx], pd->af, nk->af))
- return (PF_DROP);
-
pf_patch_16(pd,
&th.th_sport, nk->port[sidx]);
pf_patch_16(pd,
@@ -5220,6 +5219,10 @@ pf_test_state_icmp(struct pf_pdesc *pd, struct pf_state **state,
m_copyback(pd->m, pd->off,
sizeof(struct icmp6_hdr),
pd->hdr.icmp6, M_NOWAIT);
+ if (pf_change_icmp_af(pd->m, ipoff2,
+ pd, &pd2, &nk->addr[sidx],
+ &nk->addr[didx], pd->af, nk->af))
+ return (PF_DROP);
if (nk->af == AF_INET)
pd->proto = IPPROTO_ICMP;
else
@@ -5233,11 +5236,6 @@ pf_test_state_icmp(struct pf_pdesc *pd, struct pf_state **state,
&nk->addr[pd2.didx], nk->af);
pd->naf = nk->af;
- if (pf_change_icmp_af(pd->m, ipoff2,
- pd, &pd2, &nk->addr[sidx],
- &nk->addr[didx], pd->af, nk->af))
- return (PF_DROP);
-
pf_patch_16(pd,
&uh.uh_sport, nk->port[sidx]);
pf_patch_16(pd,