summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2011-07-03 18:08:03 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2011-07-03 18:08:03 +0000
commit290bab090bc67572eb2bf028c29cce8ad9b3a4cf (patch)
tree74ab9220dd3a3c8d9b93504c1229511ac469d1fc
parent5e8956aa7b03d707c09eaa06052aa50d1bee50fb (diff)
Refactor the fragment handling in pf_setup_pdesc() so that AF_INET
and AF_INET6 are doing the fragment handling the same way. Makes code more readable. With and OK bluhm@
-rw-r--r--sys/net/pf.c71
-rw-r--r--sys/net/pf_norm.c8
2 files changed, 39 insertions, 40 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index b6fa2989f73..06bbb25360f 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.752 2011/07/01 21:00:40 bluhm Exp $ */
+/* $OpenBSD: pf.c,v 1.753 2011/07/03 18:08:02 claudio Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -5495,12 +5495,29 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
*off = h->ip_hl << 2;
if (*off < (int)sizeof(struct ip) ||
- *off > ntohs(h->ip_len)) {
+ *off > ntohs(h->ip_len) ||
+ m->m_pkthdr.len < ntohs(h->ip_len)) {
*action = PF_DROP;
REASON_SET(reason, PFRES_SHORT);
return (-1);
}
+ /* packet reassembly */
+ if (h->ip_off & htons(IP_MF | IP_OFFMASK) &&
+ pf_normalize_ip(m0, dir, reason) != PF_PASS) {
+ *action = PF_DROP;
+ return (-1);
+ }
+ m = *m0;
+ if (m == NULL) {
+ /* packet sits in reassembly queue, no error */
+ *action = PF_PASS;
+ return (-1);
+ }
+ /* refetch header, recalc offset and update pd */
+ h = mtod(m, struct ip *);
+ *off = h->ip_hl << 2;
+
pd->src = (struct pf_addr *)&h->ip_src;
pd->dst = (struct pf_addr *)&h->ip_dst;
pd->sport = pd->dport = NULL;
@@ -5515,41 +5532,18 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
pd->rdomain = rtable_l2(m->m_pkthdr.rdomain);
if (h->ip_off & htons(IP_MF | IP_OFFMASK)) {
- if (!pf_status.reass) {
- /*
- * handle fragments that aren't reassembled by
- * normalization
- */
- if (kif == NULL || r == NULL) /* pflog */
- *action = PF_DROP;
- else
- *action = pf_test_fragment(r, dir, kif,
- m, pd, a, ruleset);
- if (*action == PF_PASS)
- /* m is still valid, return success */
- return (0);
- REASON_SET(reason, PFRES_FRAG);
- return (-1);
- }
- /* packet reassembly */
- if (pf_normalize_ip(m0, dir, reason) != PF_PASS) {
+ /*
+ * handle fragments that aren't reassembled by
+ * normalization
+ */
+ if (kif == NULL || r == NULL) /* pflog */
*action = PF_DROP;
- return (-1);
- }
- m = *m0;
- if (m == NULL) {
- /* packet sits in reassembly queue, no error */
- *action = PF_PASS;
- return (-1);
- }
- /* refetch header, recalc offset and update pd */
- h = mtod(m, struct ip *);
- *off = h->ip_hl << 2;
- pd->src = (struct pf_addr *)&h->ip_src;
- pd->dst = (struct pf_addr *)&h->ip_dst;
- pd->ip_sum = &h->ip_sum;
- pd->tot_len = ntohs(h->ip_len);
- pd->tos = h->ip_tos;
+ else
+ *action = pf_test_fragment(r, dir, kif,
+ m, pd, a, ruleset);
+ if (*action != PF_PASS)
+ REASON_SET(reason, PFRES_FRAG);
+ return (-1);
}
switch (h->ip_p) {
@@ -5607,8 +5601,7 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
}
/* packet reassembly */
- if (pf_status.reass &&
- pf_normalize_ip6(m0, dir, reason) != PF_PASS) {
+ if (pf_normalize_ip6(m0, dir, reason) != PF_PASS) {
*action = PF_DROP;
return (-1);
}
@@ -5652,7 +5645,7 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
else
*action = pf_test_fragment(r, dir, kif,
m, pd, a, ruleset);
- if (*action == PF_DROP)
+ if (*action != PF_PASS)
REASON_SET(reason, PFRES_FRAG);
return (-1);
case IPPROTO_ROUTING: {
diff --git a/sys/net/pf_norm.c b/sys/net/pf_norm.c
index 61761f0f37b..6d42f096422 100644
--- a/sys/net/pf_norm.c
+++ b/sys/net/pf_norm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_norm.c,v 1.135 2011/06/21 08:59:47 bluhm Exp $ */
+/* $OpenBSD: pf_norm.c,v 1.136 2011/07/03 18:08:02 claudio Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
@@ -764,6 +764,9 @@ pf_normalize_ip(struct mbuf **m0, int dir, u_short *reason)
return (PF_DROP);
}
+ if (!pf_status.reass)
+ return (PF_PASS); /* no reassembly */
+
/* Returns PF_DROP or *m0 is NULL or completely reassembled mbuf */
if (pf_reassemble(m0, h, dir, reason) != PF_PASS)
return (PF_DROP);
@@ -896,6 +899,9 @@ pf_normalize_ip6(struct mbuf **m0, int dir, u_short *reason)
if (sizeof(struct ip6_hdr) + plen > m->m_pkthdr.len)
goto shortpkt;
+ if (!pf_status.reass)
+ return (PF_PASS); /* no reassembly */
+
if (!pf_pull_hdr(m, off, &frag, sizeof(frag), NULL, NULL, AF_INET6))
goto shortpkt;
/* offset now points to data portion */