summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2016-06-24 13:55:58 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2016-06-24 13:55:58 +0000
commit02a2dbc385d4e7eb1326144e2f4e0e6b8d2b5c03 (patch)
tree2c7bc576cb8064ab0e0542e291ac799fa7d7dfa9 /sys
parent0afe44114802de6a2b8318968d890bd884d5d631 (diff)
The function pf_get_sport() did work for out rules only. Make it
aware of the direction of the packet. Now nat-to can be used by in rules and together with divert-to. Collisions with existing states are found and produce a "NAT proxy port allocation failed" message. OK henning@ mikeb@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/pf_lb.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/sys/net/pf_lb.c b/sys/net/pf_lb.c
index 6ac74760a7c..163977962d1 100644
--- a/sys/net/pf_lb.c
+++ b/sys/net/pf_lb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_lb.c,v 1.53 2016/06/15 11:36:06 mikeb Exp $ */
+/* $OpenBSD: pf_lb.c,v 1.54 2016/06/24 13:55:57 bluhm Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -155,6 +155,9 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_rule *r,
struct pf_state_key_cmp key;
struct pf_addr init_addr;
u_int16_t cut;
+ int dir = (pd->dir == PF_IN) ? PF_OUT : PF_IN;
+ int sidx = pd->sidx;
+ int didx = pd->didx;
bzero(&init_addr, sizeof(init_addr));
if (pf_map_addr(pd->naf, r, &pd->nsaddr, naddr, &init_addr, sn, &r->nat,
@@ -182,9 +185,9 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_rule *r,
key.af = pd->naf;
key.proto = pd->proto;
key.rdomain = pd->rdomain;
- PF_ACPY(&key.addr[0], &pd->ndaddr, key.af);
- PF_ACPY(&key.addr[1], naddr, key.af);
- key.port[0] = pd->ndport;
+ PF_ACPY(&key.addr[didx], &pd->ndaddr, key.af);
+ PF_ACPY(&key.addr[sidx], naddr, key.af);
+ key.port[didx] = pd->ndport;
/*
* port search; start random, step;
@@ -194,20 +197,20 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_rule *r,
pd->proto == IPPROTO_ICMP || pd->proto == IPPROTO_ICMPV6)) {
/* XXX bug: icmp states dont use the id on both
* XXX sides (traceroute -I through nat) */
- key.port[1] = pd->nsport;
- if (pf_find_state_all(&key, PF_IN, NULL) == NULL) {
+ key.port[sidx] = pd->nsport;
+ if (pf_find_state_all(&key, dir, NULL) == NULL) {
*nport = pd->nsport;
return (0);
}
} else if (low == 0 && high == 0) {
- key.port[1] = pd->nsport;
- if (pf_find_state_all(&key, PF_IN, NULL) == NULL) {
+ key.port[sidx] = pd->nsport;
+ if (pf_find_state_all(&key, dir, NULL) == NULL) {
*nport = pd->nsport;
return (0);
}
} else if (low == high) {
- key.port[1] = htons(low);
- if (pf_find_state_all(&key, PF_IN, NULL) == NULL) {
+ key.port[sidx] = htons(low);
+ if (pf_find_state_all(&key, dir, NULL) == NULL) {
*nport = htons(low);
return (0);
}
@@ -223,16 +226,16 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_rule *r,
cut = arc4random_uniform(1 + high - low) + low;
/* low <= cut <= high */
for (tmp = cut; tmp <= high; ++(tmp)) {
- key.port[1] = htons(tmp);
- if (pf_find_state_all(&key, PF_IN, NULL) ==
+ key.port[sidx] = htons(tmp);
+ if (pf_find_state_all(&key, dir, NULL) ==
NULL && !in_baddynamic(tmp, pd->proto)) {
*nport = htons(tmp);
return (0);
}
}
for (tmp = cut - 1; tmp >= low; --(tmp)) {
- key.port[1] = htons(tmp);
- if (pf_find_state_all(&key, PF_IN, NULL) ==
+ key.port[sidx] = htons(tmp);
+ if (pf_find_state_all(&key, dir, NULL) ==
NULL && !in_baddynamic(tmp, pd->proto)) {
*nport = htons(tmp);
return (0);