Loopback four fixes from OpenBSD for problems reported to the freebsd-pf
mailing list onto the vendor branch: pf_ioctl.c Revision 1.153 Sun Aug 7 11:37:33 2005 UTC by dhartmei | verify ticket in DIOCADDADDR, from Boris Polevoy, ok deraadt@ pf_ioctl.c Revision 1.158 Mon Sep 5 14:51:08 2005 UTC by dhartmei | in DIOCCHANGERULE, properly initialize table, if used in NAT rule. | from Boris Polevoy <vapcom at mail dot ru>, ok mcbride@ pf.c Revision 1.502 Mon Aug 22 11:54:25 2005 UTC by dhartmei | when nat'ing icmp 'connections', replace icmp id with proxy values | (similar to proxy ports for tcp/udp). not all clients use | per-invokation random ids, this allows multiple concurrent | connections from such clients. | thanks for testing to Rod Whitworth, "looks ok" markus@ pf.c Revision 1.501 Mon Aug 22 09:48:05 2005 UTC by dhartmei | fix rdr to bitmask replacement address pool. patch from Max Laier, | reported by Boris Polevoy, tested by Jean Debogue, ok henning@
This commit is contained in:
parent
a0d335db26
commit
608d90c70d
@ -2153,6 +2153,11 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
|
||||
if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
|
||||
return (1);
|
||||
|
||||
if (proto == IPPROTO_ICMP) {
|
||||
low = 1;
|
||||
high = 65535;
|
||||
}
|
||||
|
||||
do {
|
||||
key.af = af;
|
||||
key.proto = proto;
|
||||
@ -2164,7 +2169,8 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
|
||||
* port search; start random, step;
|
||||
* similar 2 portloop in in_pcbbind
|
||||
*/
|
||||
if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP)) {
|
||||
if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP ||
|
||||
proto == IPPROTO_ICMP)) {
|
||||
key.gwy.port = dport;
|
||||
if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL)
|
||||
return (0);
|
||||
@ -2420,6 +2426,11 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
|
||||
case PF_RDR: {
|
||||
if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn))
|
||||
return (NULL);
|
||||
if ((r->rpool.opts & PF_POOL_TYPEMASK) ==
|
||||
PF_POOL_BITMASK)
|
||||
PF_POOLMASK(naddr, naddr,
|
||||
&r->rpool.cur->addr.v.a.mask, daddr,
|
||||
pd->af);
|
||||
|
||||
if (r->rpool.proxy_port[1]) {
|
||||
u_int32_t tmp_nport;
|
||||
@ -3335,7 +3346,7 @@ pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
|
||||
struct pf_ruleset *ruleset = NULL;
|
||||
struct pf_src_node *nsn = NULL;
|
||||
u_short reason;
|
||||
u_int16_t icmpid;
|
||||
u_int16_t icmpid, bport, nport = 0;
|
||||
sa_family_t af = pd->af;
|
||||
u_int8_t icmptype, icmpcode;
|
||||
int state_icmp = 0;
|
||||
@ -3384,15 +3395,21 @@ pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
|
||||
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
|
||||
|
||||
if (direction == PF_OUT) {
|
||||
bport = nport = icmpid;
|
||||
/* check outgoing packet for BINAT/NAT */
|
||||
if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn,
|
||||
saddr, icmpid, daddr, icmpid, &pd->naddr, NULL)) != NULL) {
|
||||
saddr, icmpid, daddr, icmpid, &pd->naddr, &nport)) !=
|
||||
NULL) {
|
||||
PF_ACPY(&pd->baddr, saddr, af);
|
||||
switch (af) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
pf_change_a(&saddr->v4.s_addr, pd->ip_sum,
|
||||
pd->naddr.v4.s_addr, 0);
|
||||
pd->hdr.icmp->icmp_cksum = pf_cksum_fixup(
|
||||
pd->hdr.icmp->icmp_cksum, icmpid, nport, 0);
|
||||
pd->hdr.icmp->icmp_id = nport;
|
||||
m_copyback(m, off, ICMP_MINLEN, pd->hdr.icmp);
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
@ -3408,9 +3425,11 @@ pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
|
||||
pd->nat_rule = nr;
|
||||
}
|
||||
} else {
|
||||
bport = nport = icmpid;
|
||||
/* check incoming packet for BINAT/RDR */
|
||||
if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn,
|
||||
saddr, icmpid, daddr, icmpid, &pd->naddr, NULL)) != NULL) {
|
||||
saddr, icmpid, daddr, icmpid, &pd->naddr, &nport)) !=
|
||||
NULL) {
|
||||
PF_ACPY(&pd->baddr, daddr, af);
|
||||
switch (af) {
|
||||
#ifdef INET
|
||||
@ -3560,24 +3579,28 @@ pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
|
||||
s->af = af;
|
||||
if (direction == PF_OUT) {
|
||||
PF_ACPY(&s->gwy.addr, saddr, af);
|
||||
s->gwy.port = icmpid;
|
||||
s->gwy.port = nport;
|
||||
PF_ACPY(&s->ext.addr, daddr, af);
|
||||
s->ext.port = icmpid;
|
||||
if (nr != NULL)
|
||||
s->ext.port = 0;
|
||||
if (nr != NULL) {
|
||||
PF_ACPY(&s->lan.addr, &pd->baddr, af);
|
||||
else
|
||||
s->lan.port = bport;
|
||||
} else {
|
||||
PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
|
||||
s->lan.port = icmpid;
|
||||
s->lan.port = s->gwy.port;
|
||||
}
|
||||
} else {
|
||||
PF_ACPY(&s->lan.addr, daddr, af);
|
||||
s->lan.port = icmpid;
|
||||
s->lan.port = nport;
|
||||
PF_ACPY(&s->ext.addr, saddr, af);
|
||||
s->ext.port = icmpid;
|
||||
if (nr != NULL)
|
||||
s->ext.port = 0;
|
||||
if (nr != NULL) {
|
||||
PF_ACPY(&s->gwy.addr, &pd->baddr, af);
|
||||
else
|
||||
s->gwy.port = bport;
|
||||
} else {
|
||||
PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
|
||||
s->gwy.port = icmpid;
|
||||
s->gwy.port = s->lan.port;
|
||||
}
|
||||
}
|
||||
s->creation = time_second;
|
||||
s->expire = time_second;
|
||||
@ -4506,13 +4529,13 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
|
||||
if (direction == PF_IN) {
|
||||
PF_ACPY(&key.ext.addr, pd->src, key.af);
|
||||
PF_ACPY(&key.gwy.addr, pd->dst, key.af);
|
||||
key.ext.port = icmpid;
|
||||
key.ext.port = 0;
|
||||
key.gwy.port = icmpid;
|
||||
} else {
|
||||
PF_ACPY(&key.lan.addr, pd->src, key.af);
|
||||
PF_ACPY(&key.ext.addr, pd->dst, key.af);
|
||||
key.lan.port = icmpid;
|
||||
key.ext.port = icmpid;
|
||||
key.ext.port = 0;
|
||||
}
|
||||
|
||||
STATE_LOOKUP();
|
||||
@ -4521,7 +4544,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
|
||||
(*state)->timeout = PFTM_ICMP_ERROR_REPLY;
|
||||
|
||||
/* translate source/destination address, if necessary */
|
||||
if (PF_ANEQ(&(*state)->lan.addr, &(*state)->gwy.addr, pd->af)) {
|
||||
if (STATE_TRANSLATE(*state)) {
|
||||
if (direction == PF_OUT) {
|
||||
switch (pd->af) {
|
||||
#ifdef INET
|
||||
@ -4529,6 +4552,14 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
|
||||
pf_change_a(&saddr->v4.s_addr,
|
||||
pd->ip_sum,
|
||||
(*state)->gwy.addr.v4.s_addr, 0);
|
||||
pd->hdr.icmp->icmp_cksum =
|
||||
pf_cksum_fixup(
|
||||
pd->hdr.icmp->icmp_cksum, icmpid,
|
||||
(*state)->gwy.port, 0);
|
||||
pd->hdr.icmp->icmp_id =
|
||||
(*state)->gwy.port;
|
||||
m_copyback(m, off, ICMP_MINLEN,
|
||||
pd->hdr.icmp);
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
@ -4549,6 +4580,14 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
|
||||
pf_change_a(&daddr->v4.s_addr,
|
||||
pd->ip_sum,
|
||||
(*state)->lan.addr.v4.s_addr, 0);
|
||||
pd->hdr.icmp->icmp_cksum =
|
||||
pf_cksum_fixup(
|
||||
pd->hdr.icmp->icmp_cksum, icmpid,
|
||||
(*state)->lan.port, 0);
|
||||
pd->hdr.icmp->icmp_id =
|
||||
(*state)->lan.port;
|
||||
m_copyback(m, off, ICMP_MINLEN,
|
||||
pd->hdr.icmp);
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
@ -4875,13 +4914,13 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
|
||||
if (direction == PF_IN) {
|
||||
PF_ACPY(&key.ext.addr, pd2.dst, key.af);
|
||||
PF_ACPY(&key.gwy.addr, pd2.src, key.af);
|
||||
key.ext.port = iih.icmp_id;
|
||||
key.ext.port = 0;
|
||||
key.gwy.port = iih.icmp_id;
|
||||
} else {
|
||||
PF_ACPY(&key.lan.addr, pd2.dst, key.af);
|
||||
PF_ACPY(&key.ext.addr, pd2.src, key.af);
|
||||
key.lan.port = iih.icmp_id;
|
||||
key.ext.port = iih.icmp_id;
|
||||
key.ext.port = 0;
|
||||
}
|
||||
|
||||
STATE_LOOKUP();
|
||||
@ -4927,13 +4966,13 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
|
||||
if (direction == PF_IN) {
|
||||
PF_ACPY(&key.ext.addr, pd2.dst, key.af);
|
||||
PF_ACPY(&key.gwy.addr, pd2.src, key.af);
|
||||
key.ext.port = iih.icmp6_id;
|
||||
key.ext.port = 0;
|
||||
key.gwy.port = iih.icmp6_id;
|
||||
} else {
|
||||
PF_ACPY(&key.lan.addr, pd2.dst, key.af);
|
||||
PF_ACPY(&key.ext.addr, pd2.src, key.af);
|
||||
key.lan.port = iih.icmp6_id;
|
||||
key.ext.port = iih.icmp6_id;
|
||||
key.ext.port = 0;
|
||||
}
|
||||
|
||||
STATE_LOOKUP();
|
||||
|
@ -1454,6 +1454,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
|
||||
error = EINVAL;
|
||||
if (pf_anchor_setup(newrule, ruleset, pcr->anchor_call))
|
||||
error = EINVAL;
|
||||
TAILQ_FOREACH(pa, &pf_pabuf, entries)
|
||||
if (pf_tbladdr_setup(ruleset, &pa->addr))
|
||||
error = EINVAL;
|
||||
|
||||
if (newrule->overload_tblname[0]) {
|
||||
if ((newrule->overload_tbl = pfr_attach_table(
|
||||
@ -2035,6 +2038,10 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
|
||||
case DIOCADDADDR: {
|
||||
struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
|
||||
|
||||
if (pp->ticket != ticket_pabuf) {
|
||||
error = EBUSY;
|
||||
break;
|
||||
}
|
||||
#ifndef INET
|
||||
if (pp->af == AF_INET) {
|
||||
error = EAFNOSUPPORT;
|
||||
|
Loading…
Reference in New Issue
Block a user