summaryrefslogtreecommitdiff
path: root/sys/net/pf.c
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2012-07-10 17:33:49 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2012-07-10 17:33:49 +0000
commit01620d380de73dc1ba5a7a966990bc1ad4484f5b (patch)
treedf7b1461191809d5bc49111ef7fe9d661a703783 /sys/net/pf.c
parentdf4fcfae18e3a99514e10dd634f3a067ccd685f5 (diff)
With address family translation, the ip length of the quoted ip
packet within the icmp error packet was wrong. Fix this by using the pd2.tot_len of the inner packet and substract the old header's length. OK mikeb@ henning@
Diffstat (limited to 'sys/net/pf.c')
-rw-r--r--sys/net/pf.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index ff0c5c0df49..47a2e510cef 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.807 2012/07/07 16:24:32 henning Exp $ */
+/* $OpenBSD: pf.c,v 1.808 2012/07/10 17:33:48 bluhm Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -2136,8 +2136,6 @@ pf_change_icmp_af(struct mbuf *m, int off, struct pf_pdesc *pd,
olen = pd2->off - off;
/* new header */
hlen = naf == AF_INET ? sizeof(*ip4) : sizeof(*ip6);
- /* data lenght */
- mlen = m->m_pkthdr.len - pd2->off;
/* trim old header */
m_adj(n, olen);
@@ -2153,7 +2151,7 @@ pf_change_icmp_af(struct mbuf *m, int off, struct pf_pdesc *pd,
bzero(ip4, sizeof(*ip4));
ip4->ip_v = IPVERSION;
ip4->ip_hl = sizeof(*ip4) >> 2;
- ip4->ip_len = htons(sizeof(*ip4) + mlen);
+ ip4->ip_len = htons(sizeof(*ip4) + pd2->tot_len - olen);
ip4->ip_id = htons(ip_randomid());
ip4->ip_off = htons(IP_DF);
ip4->ip_ttl = pd2->ttl;
@@ -2169,7 +2167,7 @@ pf_change_icmp_af(struct mbuf *m, int off, struct pf_pdesc *pd,
ip6 = mtod(n, struct ip6_hdr *);
bzero(ip6, sizeof(*ip6));
ip6->ip6_vfc = IPV6_VERSION;
- ip6->ip6_plen = htons(mlen);
+ ip6->ip6_plen = htons(pd2->tot_len - olen);
if (pd2->proto == IPPROTO_ICMP)
ip6->ip6_nxt = IPPROTO_ICMPV6;
else
@@ -4920,6 +4918,7 @@ pf_test_state_icmp(struct pf_pdesc *pd, struct pf_state **state,
pd2.off = ipoff2 + (h2.ip_hl << 2);
pd2.proto = h2.ip_p;
+ pd2.tot_len = ntohs(h2.ip_len);
pd2.src = (struct pf_addr *)&h2.ip_src;
pd2.dst = (struct pf_addr *)&h2.ip_dst;
ipsum2 = &h2.ip_sum;
@@ -4940,6 +4939,8 @@ pf_test_state_icmp(struct pf_pdesc *pd, struct pf_state **state,
if (pf_walk_header6(&pd2, &h2_6, reason) != PF_PASS)
return (PF_DROP);
+ pd2.tot_len = ntohs(h2_6.ip6_plen) +
+ sizeof(struct ip6_hdr);
pd2.src = (struct pf_addr *)&h2_6.ip6_src;
pd2.dst = (struct pf_addr *)&h2_6.ip6_dst;
ipsum2 = NULL;