diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2011-07-03 18:08:03 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2011-07-03 18:08:03 +0000 |
commit | 290bab090bc67572eb2bf028c29cce8ad9b3a4cf (patch) | |
tree | 74ab9220dd3a3c8d9b93504c1229511ac469d1fc | |
parent | 5e8956aa7b03d707c09eaa06052aa50d1bee50fb (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.c | 71 | ||||
-rw-r--r-- | sys/net/pf_norm.c | 8 |
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 */ |