diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2016-06-24 13:55:58 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2016-06-24 13:55:58 +0000 |
commit | 02a2dbc385d4e7eb1326144e2f4e0e6b8d2b5c03 (patch) | |
tree | 2c7bc576cb8064ab0e0542e291ac799fa7d7dfa9 /sys | |
parent | 0afe44114802de6a2b8318968d890bd884d5d631 (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.c | 31 |
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); |