diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2012-07-10 17:33:49 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2012-07-10 17:33:49 +0000 |
commit | 01620d380de73dc1ba5a7a966990bc1ad4484f5b (patch) | |
tree | df7b1461191809d5bc49111ef7fe9d661a703783 /sys/net/pf.c | |
parent | df4fcfae18e3a99514e10dd634f3a067ccd685f5 (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.c | 11 |
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; |