diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2012-01-16 16:38:02 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2012-01-16 16:38:02 +0000 |
commit | 082c28ce84826bbddba7d3259503f056fd062515 (patch) | |
tree | 7c4463a10ed3fc40941e184aeaac45d136287a82 | |
parent | 197679ac3ac6257cd4f18f9f5d3c4a17ce63411b (diff) |
Pass struct pf_pdesc to pf_walk_option6() and pf_walk_header6() to
make their argument list shorter. Also fix a bug where pf_walk_option6()
used the outer header in the pd2 case.
ok henning@ mikeb@
-rw-r--r-- | sys/net/pf.c | 118 | ||||
-rw-r--r-- | sys/net/pfvar.h | 3 |
2 files changed, 57 insertions, 64 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c index 80f068874d8..607fcf961e4 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.793 2012/01/15 22:55:35 bluhm Exp $ */ +/* $OpenBSD: pf.c,v 1.794 2012/01/16 16:38:01 bluhm Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -217,10 +217,10 @@ void pf_set_rt_ifp(struct pf_state *, int pf_check_proto_cksum(struct mbuf *, int, int, u_int8_t, sa_family_t); struct pf_divert *pf_get_divert(struct mbuf *); -int pf_walk_option6(struct mbuf *, int, int, u_int32_t *, +int pf_walk_option6(struct pf_pdesc *, struct ip6_hdr *, + int, int, u_short *); +int pf_walk_header6(struct pf_pdesc *, struct ip6_hdr *, u_short *); -int pf_walk_header6(struct mbuf *, struct ip6_hdr *, int *, - int *, int *, u_int8_t *, u_int32_t *, u_short *); void pf_print_state_parts(struct pf_state *, struct pf_state_key *, struct pf_state_key *); int pf_addr_wrap_neq(struct pf_addr_wrap *, @@ -4759,8 +4759,6 @@ pf_test_state_icmp(struct pf_pdesc *pd, struct pf_state **state, #endif /* INET */ #ifdef INET6 struct ip6_hdr h2_6; - int fragoff2, extoff2; - u_int32_t jumbolen; #endif /* INET6 */ u_int16_t *ipsum2; int ipoff2; @@ -4817,9 +4815,7 @@ pf_test_state_icmp(struct pf_pdesc *pd, struct pf_state **state, } pd2.off = ipoff2; - if (pf_walk_header6(pd2.m, &h2_6, &pd2.off, &extoff2, - &fragoff2, &pd2.proto, &jumbolen, reason) - != PF_PASS) + if (pf_walk_header6(&pd2, &h2_6, reason) != PF_PASS) return (PF_DROP); pd2.src = (struct pf_addr *)&h2_6.ip6_src; @@ -6124,16 +6120,15 @@ pf_get_divert(struct mbuf *m) } int -pf_walk_option6(struct mbuf *m, int off, int end, u_int32_t *jumbolen, +pf_walk_option6(struct pf_pdesc *pd, struct ip6_hdr *h, int off, int end, u_short *reason) { struct ip6_opt opt; struct ip6_opt_jumbo jumbo; - struct ip6_hdr *h = mtod(m, struct ip6_hdr *); while (off < end) { - if (!pf_pull_hdr(m, off, &opt.ip6o_type, sizeof(opt.ip6o_type), - NULL, reason, AF_INET6)) { + if (!pf_pull_hdr(pd->m, off, &opt.ip6o_type, + sizeof(opt.ip6o_type), NULL, reason, AF_INET6)) { DPFPRINTF(LOG_NOTICE, "IPv6 short opt type"); return (PF_DROP); } @@ -6141,7 +6136,7 @@ pf_walk_option6(struct mbuf *m, int off, int end, u_int32_t *jumbolen, off++; continue; } - if (!pf_pull_hdr(m, off, &opt, sizeof(opt), + if (!pf_pull_hdr(pd->m, off, &opt, sizeof(opt), NULL, reason, AF_INET6)) { DPFPRINTF(LOG_NOTICE, "IPv6 short opt"); return (PF_DROP); @@ -6153,7 +6148,7 @@ pf_walk_option6(struct mbuf *m, int off, int end, u_int32_t *jumbolen, } switch (opt.ip6o_type) { case IP6OPT_JUMBO: - if (*jumbolen != 0) { + if (pd->jumbolen != 0) { DPFPRINTF(LOG_NOTICE, "IPv6 multiple jumbo"); REASON_SET(reason, PFRES_IPOPTIONS); return (PF_DROP); @@ -6163,15 +6158,15 @@ pf_walk_option6(struct mbuf *m, int off, int end, u_int32_t *jumbolen, REASON_SET(reason, PFRES_IPOPTIONS); return (PF_DROP); } - if (!pf_pull_hdr(m, off, &jumbo, sizeof(jumbo), + if (!pf_pull_hdr(pd->m, off, &jumbo, sizeof(jumbo), NULL, reason, AF_INET6)) { DPFPRINTF(LOG_NOTICE, "IPv6 short jumbo"); return (PF_DROP); } - memcpy(jumbolen, jumbo.ip6oj_jumbo_len, - sizeof(*jumbolen)); - *jumbolen = ntohl(*jumbolen); - if (*jumbolen < IPV6_MAXPACKET) { + memcpy(&pd->jumbolen, jumbo.ip6oj_jumbo_len, + sizeof(pd->jumbolen)); + pd->jumbolen = ntohl(pd->jumbolen); + if (pd->jumbolen < IPV6_MAXPACKET) { DPFPRINTF(LOG_NOTICE, "IPv6 short jumbolen"); REASON_SET(reason, PFRES_IPOPTIONS); return (PF_DROP); @@ -6187,43 +6182,41 @@ pf_walk_option6(struct mbuf *m, int off, int end, u_int32_t *jumbolen, } int -pf_walk_header6(struct mbuf *m, struct ip6_hdr *h, int *off, int *extoff, - int *fragoff, u_int8_t *nxt, u_int32_t *jumbolen, u_short *reason) +pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason) { struct ip6_frag frag; struct ip6_ext ext; struct ip6_rthdr rthdr; int rthdr_cnt = 0; - *off += sizeof(struct ip6_hdr); - *extoff = *fragoff = 0; - *nxt = h->ip6_nxt; - *jumbolen = 0; + pd->off += sizeof(struct ip6_hdr); + pd->fragoff = pd->extoff = pd->jumbolen = 0; + pd->proto = h->ip6_nxt; for (;;) { - switch (*nxt) { + switch (pd->proto) { case IPPROTO_FRAGMENT: - if (*fragoff != 0) { + if (pd->fragoff != 0) { DPFPRINTF(LOG_NOTICE, "IPv6 multiple fragment"); REASON_SET(reason, PFRES_FRAG); return (PF_DROP); } /* jumbo payload packets cannot be fragmented */ - if (*jumbolen != 0) { + if (pd->jumbolen != 0) { DPFPRINTF(LOG_NOTICE, "IPv6 fragmented jumbo"); REASON_SET(reason, PFRES_FRAG); return (PF_DROP); } - if (!pf_pull_hdr(m, *off, &frag, sizeof(frag), + if (!pf_pull_hdr(pd->m, pd->off, &frag, sizeof(frag), NULL, reason, AF_INET6)) { DPFPRINTF(LOG_NOTICE, "IPv6 short fragment"); return (PF_DROP); } - *fragoff = *off; + pd->fragoff = pd->off; /* stop walking over non initial fragments */ if ((frag.ip6f_offlg & IP6F_OFF_MASK) != 0) return (PF_PASS); - *off += sizeof(frag); - *nxt = frag.ip6f_nxt; + pd->off += sizeof(frag); + pd->proto = frag.ip6f_nxt; break; case IPPROTO_ROUTING: if (rthdr_cnt++) { @@ -6231,13 +6224,13 @@ pf_walk_header6(struct mbuf *m, struct ip6_hdr *h, int *off, int *extoff, REASON_SET(reason, PFRES_IPOPTIONS); return (PF_DROP); } - if (!pf_pull_hdr(m, *off, &rthdr, sizeof(rthdr), + if (!pf_pull_hdr(pd->m, pd->off, &rthdr, sizeof(rthdr), NULL, reason, AF_INET6)) { DPFPRINTF(LOG_NOTICE, "IPv6 short rthdr"); /* fragments may be short */ - if (*fragoff != 0) { - *off = *fragoff; - *nxt = IPPROTO_FRAGMENT; + if (pd->fragoff != 0) { + pd->off = pd->fragoff; + pd->proto = IPPROTO_FRAGMENT; return (PF_PASS); } return (PF_DROP); @@ -6251,48 +6244,50 @@ pf_walk_header6(struct mbuf *m, struct ip6_hdr *h, int *off, int *extoff, case IPPROTO_AH: case IPPROTO_HOPOPTS: case IPPROTO_DSTOPTS: - if (!pf_pull_hdr(m, *off, &ext, sizeof(ext), + if (!pf_pull_hdr(pd->m, pd->off, &ext, sizeof(ext), NULL, reason, AF_INET6)) { DPFPRINTF(LOG_NOTICE, "IPv6 short exthdr"); /* fragments may be short */ - if (*fragoff != 0) { - *off = *fragoff; - *nxt = IPPROTO_FRAGMENT; + if (pd->fragoff != 0) { + pd->off = pd->fragoff; + pd->proto = IPPROTO_FRAGMENT; return (PF_PASS); } return (PF_DROP); } /* reassembly needs the ext header before the frag */ - if (*fragoff == 0) - *extoff = *off; - if (*nxt == IPPROTO_HOPOPTS && *fragoff == 0) { - if (pf_walk_option6(m, *off + sizeof(ext), - *off + (ext.ip6e_len + 1) * 8, jumbolen, - reason) != PF_PASS) + if (pd->fragoff == 0) + pd->extoff = pd->off; + if (pd->proto == IPPROTO_HOPOPTS && pd->fragoff == 0) { + if (pf_walk_option6(pd, h, + pd->off + sizeof(ext), + pd->off + (ext.ip6e_len + 1) * 8, reason) + != PF_PASS) return (PF_DROP); - if (ntohs(h->ip6_plen) == 0 && *jumbolen != 0) { + if (ntohs(h->ip6_plen) == 0 && + pd->jumbolen != 0) { DPFPRINTF(LOG_NOTICE, "IPv6 missing jumbo"); REASON_SET(reason, PFRES_IPOPTIONS); return (PF_DROP); } } - if (*nxt == IPPROTO_AH) - *off += (ext.ip6e_len + 2) * 4; + if (pd->proto == IPPROTO_AH) + pd->off += (ext.ip6e_len + 2) * 4; else - *off += (ext.ip6e_len + 1) * 8; - *nxt = ext.ip6e_nxt; + pd->off += (ext.ip6e_len + 1) * 8; + pd->proto = ext.ip6e_nxt; break; case IPPROTO_TCP: case IPPROTO_UDP: case IPPROTO_ICMPV6: /* fragments may be short, ignore inner header then */ - if (*fragoff != 0 && ntohs(h->ip6_plen) < *off + - (*nxt == IPPROTO_TCP ? sizeof(struct tcphdr) : - *nxt == IPPROTO_UDP ? sizeof(struct udphdr) : + if (pd->fragoff != 0 && ntohs(h->ip6_plen) < pd->off + + (pd->proto == IPPROTO_TCP ? sizeof(struct tcphdr) : + pd->proto == IPPROTO_UDP ? sizeof(struct udphdr) : sizeof(struct icmp6_hdr))) { - *off = *fragoff; - *nxt = IPPROTO_FRAGMENT; + pd->off = pd->fragoff; + pd->proto = IPPROTO_FRAGMENT; } /* FALLTHROUGH */ default: @@ -6354,8 +6349,6 @@ pf_setup_pdesc(struct pf_pdesc *pd, void *pdhdrs, sa_family_t af, int dir, #ifdef INET6 case AF_INET6: { struct ip6_hdr *h; - u_int32_t jumbolen; - u_int8_t nxt; /* Check for illegal packets */ if (pd->m->m_pkthdr.len < (int)sizeof(struct ip6_hdr)) { @@ -6372,8 +6365,7 @@ pf_setup_pdesc(struct pf_pdesc *pd, void *pdhdrs, sa_family_t af, int dir, return (PF_DROP); } - if (pf_walk_header6(pd->m, h, &pd->off, &pd->extoff, - &pd->fragoff, &nxt, &jumbolen, reason) != PF_PASS) + if (pf_walk_header6(pd, h, reason) != PF_PASS) return (PF_DROP); #if 1 @@ -6381,7 +6373,7 @@ pf_setup_pdesc(struct pf_pdesc *pd, void *pdhdrs, sa_family_t af, int dir, * we do not support jumbogram yet. if we keep going, zero * ip6_plen will do something bad, so drop the packet for now. */ - if (jumbolen != 0) { + if (pd->jumbolen != 0) { REASON_SET(reason, PFRES_NORM); return (PF_DROP); } @@ -6389,7 +6381,7 @@ pf_setup_pdesc(struct pf_pdesc *pd, void *pdhdrs, sa_family_t af, int dir, pd->src = (struct pf_addr *)&h->ip6_src; pd->dst = (struct pf_addr *)&h->ip6_dst; - pd->virtual_proto = pd->proto = nxt; + pd->virtual_proto = pd->proto; pd->tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr); pd->tos = 0; pd->ttl = h->ip6_hlim; diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index aae141027e3..b93f66b327e 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.359 2012/01/15 22:55:35 bluhm Exp $ */ +/* $OpenBSD: pfvar.h,v 1.360 2012/01/16 16:38:01 bluhm Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -1256,6 +1256,7 @@ struct pf_pdesc { u_int32_t p_len; /* length of protocol payload */ u_int32_t extoff; /* extentsion header offset */ u_int32_t fragoff; /* fragment header offset */ + u_int32_t jumbolen; /* length from v6 jumbo header */ u_int32_t badopts; /* v4 options or v6 routing headers */ u_int16_t rdomain; /* original routing domain */ |