diff options
-rw-r--r-- | sbin/pfctl/pfctl_parser.c | 28 | ||||
-rw-r--r-- | sys/net/pf.c | 39 | ||||
-rw-r--r-- | sys/net/pfvar.h | 8 |
3 files changed, 63 insertions, 12 deletions
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index 74d9418ba6b..074407a5640 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.c,v 1.23 2001/07/01 17:04:13 kjell Exp $ */ +/* $OpenBSD: pfctl_parser.c,v 1.24 2001/07/01 17:16:02 kjell Exp $ */ /* * Copyright (c) 2001, Daniel Hartmeier @@ -282,9 +282,14 @@ print_rdr(struct pf_rdr *r) printf("/"); print_addr(r->dmask); } - printf(" port %u -> ", ntohs(r->dport)); + printf(" port %u", ntohs(r->dport)); + if (r->opts & PF_DPORT_RANGE) + printf(":%u", ntohs(r->dport2)); + printf(" -> "); print_addr(r->raddr); printf(" port %u", ntohs(r->rport)); + if (r->opts & PF_RPORT_RANGE) + printf(":*"); switch (r->proto) { case IPPROTO_TCP: printf(" proto tcp"); @@ -979,7 +984,7 @@ parse_nat(int n, char *l, struct pf_nat *nat) int parse_rdr(int n, char *l, struct pf_rdr *rdr) { - char *w; + char *w, *s; memset(rdr, 0, sizeof(struct pf_rdr)); w = next_word(&l); @@ -1017,7 +1022,17 @@ parse_rdr(int n, char *l, struct pf_rdr *rdr) return (0); } w = next_word(&l); - rdr->dport = htons(next_number(&w)); + /* check for port range */ + if ((s = strchr(w, ':')) == NULL) { + rdr->dport = htons(next_number(&w)); + rdr->dport2 = rdr->dport; + } else { + *s++ = '\0'; + rdr->dport = htons(next_number(&w)); + rdr->dport2 = htons(next_number(&s)); + rdr->opts |= PF_DPORT_RANGE; + } + w = next_word(&l); /* -> */ @@ -1037,6 +1052,11 @@ parse_rdr(int n, char *l, struct pf_rdr *rdr) return (0); } w = next_word(&l); + /* check if redirected port is a range */ + if ((s = strchr(w, ':')) != NULL) { + rdr->opts |= PF_RPORT_RANGE; + } + rdr->rport = htons(next_number(&w)); w = next_word(&l); diff --git a/sys/net/pf.c b/sys/net/pf.c index 98e4763553a..acd5f1de851 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.90 2001/07/01 11:22:45 dhartmei Exp $ */ +/* $OpenBSD: pf.c,v 1.91 2001/07/01 17:16:03 kjell Exp $ */ /* * Copyright (c) 2001, Daniel Hartmeier @@ -183,6 +183,7 @@ int pf_match_addr(u_int8_t, u_int32_t, u_int32_t, u_int32_t); int pf_match_port(u_int8_t, u_int16_t, u_int16_t, u_int16_t); +u_int16_t pf_map_port_range(struct pf_rdr *, u_int16_t); struct pf_nat *pf_get_nat(struct ifnet *, u_int8_t, u_int32_t); struct pf_rdr *pf_get_rdr(struct ifnet *, u_int8_t, u_int32_t, u_int16_t); @@ -1343,7 +1344,8 @@ pf_get_rdr(struct ifnet *ifp, u_int8_t proto, u_int32_t addr, u_int16_t port) if (r->ifp == ifp && (!r->proto || r->proto == proto) && pf_match_addr(r->not, r->daddr, r->dmask, addr) && - ((r->dport == 0) || (r->dport == port))) + (ntohs(port) >= ntohs(r->dport)) && + (ntohs(port) <= ntohs(r->dport2))) rm = r; else r = TAILQ_NEXT(r, entries); @@ -1365,6 +1367,18 @@ pf_get_rdr(struct ifnet *ifp, u_int8_t proto, u_int32_t addr, u_int16_t port) pf_status.counters[x]++; \ } while (0) +u_int16_t +pf_map_port_range(struct pf_rdr *rdr, u_int16_t port) +{ + u_int32_t nport; + + nport = ntohs(rdr->rport) - ntohs(rdr->dport) + ntohs(port); + /* wrap around if necessary */ + if (nport > 65535) + nport -= 65535; + return htons((u_int16_t)nport); +} + int pf_test_tcp(int direction, struct ifnet *ifp, struct mbuf *m, int ipoff, int off, struct ip *h, struct tcphdr *th) @@ -1372,7 +1386,7 @@ pf_test_tcp(int direction, struct ifnet *ifp, struct mbuf *m, struct pf_nat *nat = NULL; struct pf_rdr *rdr = NULL; u_int32_t baddr; - u_int16_t bport; + u_int16_t bport, nport; struct pf_rule *r, *rm = NULL; u_short reason; int rewrite = 0; @@ -1394,9 +1408,14 @@ pf_test_tcp(int direction, struct ifnet *ifp, struct mbuf *m, th->th_dport)) != NULL) { baddr = h->ip_dst.s_addr; bport = th->th_dport; + if (rdr->opts & PF_RPORT_RANGE) + nport = pf_map_port_range(rdr, th->th_dport); + else + nport = rdr->rport; + pf_change_ap(&h->ip_dst.s_addr, &th->th_dport, - &h->ip_sum, &th->th_sum, rdr->raddr, - rdr->rport ? rdr->rport : th->th_dport); + &h->ip_sum, &th->th_sum, rdr->raddr, nport); + rewrite++; } } @@ -1519,7 +1538,7 @@ pf_test_udp(int direction, struct ifnet *ifp, struct mbuf *m, struct pf_nat *nat = NULL; struct pf_rdr *rdr = NULL; u_int32_t baddr; - u_int16_t bport; + u_int16_t bport, nport; struct pf_rule *r, *rm = NULL; u_short reason; int rewrite = 0; @@ -1541,9 +1560,15 @@ pf_test_udp(int direction, struct ifnet *ifp, struct mbuf *m, uh->uh_dport)) != NULL) { baddr = h->ip_dst.s_addr; bport = uh->uh_dport; + if (rdr->opts & PF_RPORT_RANGE) + nport = pf_map_port_range(rdr, uh->uh_dport); + else + nport = rdr->rport; + pf_change_ap(&h->ip_dst.s_addr, &uh->uh_dport, &h->ip_sum, &uh->uh_sum, rdr->raddr, - rdr->rport ? rdr->rport : uh->uh_dport); + nport); + rewrite++; } } diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 5c581e8043c..0ca01b88afb 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.26 2001/06/29 03:09:14 angelos Exp $ */ +/* $OpenBSD: pfvar.h,v 1.27 2001/07/01 17:16:03 kjell Exp $ */ /* * Copyright (c) 2001, Daniel Hartmeier @@ -119,11 +119,17 @@ struct pf_rdr { u_int32_t dmask; u_int32_t raddr; u_int16_t dport; + u_int16_t dport2; u_int16_t rport; u_int8_t proto; u_int8_t not; + u_int8_t opts; }; +/* flags for RDR options */ +#define PF_DPORT_RANGE 0x01 /* Dest port uses range */ +#define PF_RPORT_RANGE 0x02 /* RDR'ed port uses range */ + /* Reasons code for passing/dropping a packet */ #define PFRES_MATCH 0 /* Explicit match of a rule */ #define PFRES_BADOFF 1 /* Bad offset for pull_hdr */ |