diff options
author | Daniel Hartmeier <dhartmei@cvs.openbsd.org> | 2002-04-24 18:10:26 +0000 |
---|---|---|
committer | Daniel Hartmeier <dhartmei@cvs.openbsd.org> | 2002-04-24 18:10:26 +0000 |
commit | 1a804d4f9927039663cbdd8465f7dd1d19d99545 (patch) | |
tree | 37435a89152b1d4c3879651990532ff6a1ad89a2 /sys/net | |
parent | 785a8619f7687670e72618ee146902fc4cf704e5 (diff) |
Add dynamic (in-kernel) interface name -> address translation. Instead of
using just the interface name instead of an address and reloading the rule
set whenever the interface changes its address, the interface name can be
put in parentheses, and the kernel will keep track of changes and update
rules. There is no additional cost for evaluating rules (per packet),
the cost occurs when an interface changes address (and the rules are
traversed and updated where necessary).
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/pf.c | 398 | ||||
-rw-r--r-- | sys/net/pf_norm.c | 10 | ||||
-rw-r--r-- | sys/net/pfvar.h | 183 |
3 files changed, 434 insertions, 157 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c index af5df4d570a..684a455e36d 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.203 2002/04/23 14:32:22 dhartmei Exp $ */ +/* $OpenBSD: pf.c,v 1.204 2002/04/24 18:10:25 dhartmei Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -175,7 +175,7 @@ int *pftm_timeouts[PFTM_MAX] = { &pftm_tcp_first_packet, struct pool pf_tree_pl, pf_rule_pl, pf_nat_pl, pf_sport_pl; -struct pool pf_rdr_pl, pf_state_pl, pf_binat_pl; +struct pool pf_rdr_pl, pf_state_pl, pf_binat_pl, pf_addr_pl; struct pf_pool_limit { void *pp; @@ -202,6 +202,10 @@ struct pf_tree_node *pf_tree_search(struct pf_tree_node *, void pf_insert_state(struct pf_state *); void pf_purge_expired_states(void); void pf_purge_timeout(void *); +int pf_dynaddr_setup(struct pf_addr_wrap *, u_int8_t); +void pf_dynaddr_update(void *); +void pf_dynaddr_remove(struct pf_addr_wrap *); +void pf_dynaddr_copyout(struct pf_addr_wrap *); void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t); void pf_print_state(struct pf_state *); @@ -405,9 +409,19 @@ pf_compare_rules(struct pf_rule *a, struct pf_rule *b) a->min_ttl != b->min_ttl || a->allow_opts != b->allow_opts) return (1); - if (memcmp(&a->src, &b->src, sizeof(struct pf_rule_addr))) + if (PF_ANEQ(&a->src.addr.addr, &b->src.addr.addr, a->af) || + PF_ANEQ(&a->src.mask, &b->src.mask, a->af) || + a->src.port[0] != b->src.port[0] || + a->src.port[1] != b->src.port[1] || + a->src.not != b->src.not || + a->src.port_op != b->src.port_op) return (1); - if (memcmp(&a->dst, &b->dst, sizeof(struct pf_rule_addr))) + if (PF_ANEQ(&a->dst.addr.addr, &b->dst.addr.addr, a->af) || + PF_ANEQ(&a->dst.mask, &b->dst.mask, a->af) || + a->dst.port[0] != b->dst.port[0] || + a->dst.port[1] != b->dst.port[1] || + a->dst.not != b->dst.not || + a->dst.port_op != b->dst.port_op) return (1); if (strcmp(a->ifname, b->ifname)) return (1); @@ -424,15 +438,15 @@ pf_compare_nats(struct pf_nat *a, struct pf_nat *b) a->ifnot != b->ifnot || a->no != b->no) return (1); - if (PF_ANEQ(&a->saddr, &b->saddr, a->af)) + if (PF_ANEQ(&a->saddr.addr, &b->saddr.addr, a->af)) return (1); if (PF_ANEQ(&a->smask, &b->smask, a->af)) return (1); - if (PF_ANEQ(&a->daddr, &b->daddr, a->af)) + if (PF_ANEQ(&a->daddr.addr, &b->daddr.addr, a->af)) return (1); if (PF_ANEQ(&a->dmask, &b->dmask, a->af)) return (1); - if (PF_ANEQ(&a->raddr, &b->raddr, a->af)) + if (PF_ANEQ(&a->raddr.addr, &b->raddr.addr, a->af)) return (1); if (strcmp(a->ifname, b->ifname)) return (1); @@ -447,13 +461,13 @@ pf_compare_binats(struct pf_binat *a, struct pf_binat *b) a->af != b->af || a->no != b->no) return (1); - if (PF_ANEQ(&a->saddr, &b->saddr, a->af)) + if (PF_ANEQ(&a->saddr.addr, &b->saddr.addr, a->af)) return (1); - if (PF_ANEQ(&a->daddr, &b->daddr, a->af)) + if (PF_ANEQ(&a->daddr.addr, &b->daddr.addr, a->af)) return (1); if (PF_ANEQ(&a->dmask, &b->dmask, a->af)) return (1); - if (PF_ANEQ(&a->raddr, &b->raddr, a->af)) + if (PF_ANEQ(&a->raddr.addr, &b->raddr.addr, a->af)) return (1); if (strcmp(a->ifname, b->ifname)) return (1); @@ -474,15 +488,15 @@ pf_compare_rdrs(struct pf_rdr *a, struct pf_rdr *b) a->opts != b->opts || a->no != b->no) return (1); - if (PF_ANEQ(&a->saddr, &b->saddr, a->af)) + if (PF_ANEQ(&a->saddr.addr, &b->saddr.addr, a->af)) return (1); if (PF_ANEQ(&a->smask, &b->smask, a->af)) return (1); - if (PF_ANEQ(&a->daddr, &b->daddr, a->af)) + if (PF_ANEQ(&a->daddr.addr, &b->daddr.addr, a->af)) return (1); if (PF_ANEQ(&a->dmask, &b->dmask, a->af)) return (1); - if (PF_ANEQ(&a->raddr, &b->raddr, a->af)) + if (PF_ANEQ(&a->raddr.addr, &b->raddr.addr, a->af)) return (1); if (strcmp(a->ifname, b->ifname)) return (1); @@ -879,6 +893,103 @@ pf_purge_expired_states(void) } } +int +pf_dynaddr_setup(struct pf_addr_wrap *aw, u_int8_t af) +{ + if (aw->addr_dyn == NULL) + return (0); + aw->addr_dyn = pool_get(&pf_addr_pl, PR_NOWAIT); + if (aw->addr_dyn == NULL) + return (1); + bcopy(aw->addr.pfa.ifname, aw->addr_dyn->ifname, + sizeof(aw->addr_dyn->ifname)); + aw->addr_dyn->ifp = ifunit(aw->addr_dyn->ifname); + if (aw->addr_dyn->ifp == NULL) { + pool_put(&pf_addr_pl, aw->addr_dyn); + aw->addr_dyn = NULL; + return (1); + } + aw->addr_dyn->addr = &aw->addr; + aw->addr_dyn->af = af; + aw->addr_dyn->undefined = 1; + aw->addr_dyn->hook_cookie = hook_establish( + aw->addr_dyn->ifp->if_addrhooks, 1, + pf_dynaddr_update, aw->addr_dyn); + if (aw->addr_dyn->hook_cookie == NULL) { + pool_put(&pf_addr_pl, aw->addr_dyn); + aw->addr_dyn = NULL; + return (1); + } + pf_dynaddr_update(aw->addr_dyn); + return (0); +} + +void +pf_dynaddr_update(void *p) +{ + struct pf_addr_dyn *ad = (struct pf_addr_dyn *)p; + struct ifaddr *ia; + int s, changed = 0; + + if (ad == NULL || ad->ifp == NULL) + panic("pf_dynaddr_update"); + s = splsoftnet(); + TAILQ_FOREACH(ia, &ad->ifp->if_addrlist, ifa_list) + if (ia->ifa_addr != NULL && + ia->ifa_addr->sa_family == ad->af) { + if (ad->af == AF_INET) { + struct in_addr *a, *b; + + a = &ad->addr->v4; + b = &((struct sockaddr_in *)ia->ifa_addr) + ->sin_addr; + if (ad->undefined || + memcmp(a, b, sizeof(*a))) { + bcopy(b, a, sizeof(*a)); + changed = 1; + } + } else if (ad->af == AF_INET6) { + struct in6_addr *a, *b; + + a = &ad->addr->v6; + b = &((struct sockaddr_in6 *)ia->ifa_addr) + ->sin6_addr; + if (ad->undefined || + memcmp(a, b, sizeof(*a))) { + bcopy(b, a, sizeof(*a)); + changed = 1; + } + } + if (changed) + ad->undefined = 0; + break; + } + if (ia == NULL) + ad->undefined = 1; + splx(s); +} + +void +pf_dynaddr_remove(struct pf_addr_wrap *aw) +{ + if (aw->addr_dyn == NULL) + return; + hook_disestablish(aw->addr_dyn->ifp->if_addrhooks, + aw->addr_dyn->hook_cookie); + pool_put(&pf_addr_pl, aw->addr_dyn); + aw->addr_dyn = NULL; +} + +void +pf_dynaddr_copyout(struct pf_addr_wrap *aw) +{ + if (aw->addr_dyn == NULL) + return; + bcopy(aw->addr_dyn->ifname, aw->addr.pfa.ifname, + sizeof(aw->addr.pfa.ifname)); + aw->addr_dyn = (struct pf_addr_dyn *)1; +} + void pf_print_host(struct pf_addr *addr, u_int16_t p, u_int8_t af) { @@ -1003,6 +1114,8 @@ pfattach(int num) NULL); pool_init(&pf_sport_pl, sizeof(struct pf_port_node), 0, 0, 0, "pfsport", NULL); + pool_init(&pf_addr_pl, sizeof(struct pf_addr_dyn), 0, 0, 0, "pfaddr", + NULL); TAILQ_INIT(&pf_rules[0]); TAILQ_INIT(&pf_rules[1]); @@ -1129,6 +1242,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) while ((rule = TAILQ_FIRST(pf_rules_inactive)) != NULL) { TAILQ_REMOVE(pf_rules_inactive, rule, entries); + pf_dynaddr_remove(&rule->src.addr); + pf_dynaddr_remove(&rule->dst.addr); pool_put(&pf_rule_pl, rule); } *ticket = ++ticket_rules_inactive; @@ -1168,7 +1283,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) rule->nr = tail->nr + 1; else rule->nr = 0; - rule->ifp = NULL; if (rule->ifname[0]) { rule->ifp = ifunit(rule->ifname); if (rule->ifp == NULL) { @@ -1187,6 +1301,14 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } } else rule->rt_ifp = NULL; + if (pf_dynaddr_setup(&rule->src.addr, rule->af) || + pf_dynaddr_setup(&rule->dst.addr, rule->af)) { + pf_dynaddr_remove(&rule->src.addr); + pf_dynaddr_remove(&rule->dst.addr); + pool_put(&pf_rule_pl, rule); + error = EINVAL; + break; + } rule->evaluations = rule->packets = rule->bytes = 0; TAILQ_INSERT_TAIL(pf_rules_inactive, rule, entries); break; @@ -1221,6 +1343,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) /* Purge the old rule list. */ while ((rule = TAILQ_FIRST(old_rules)) != NULL) { TAILQ_REMOVE(old_rules, rule, entries); + pf_dynaddr_remove(&rule->src.addr); + pf_dynaddr_remove(&rule->dst.addr); pool_put(&pf_rule_pl, rule); } break; @@ -1259,6 +1383,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } bcopy(rule, &pr->rule, sizeof(struct pf_rule)); + pf_dynaddr_copyout(&pr->rule.src.addr); + pf_dynaddr_copyout(&pr->rule.dst.addr); splx(s); break; } @@ -1295,7 +1421,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } #endif /* INET6 */ - newrule->ifp = NULL; if (newrule->ifname[0]) { newrule->ifp = ifunit(newrule->ifname); if (newrule->ifp == NULL) { @@ -1303,8 +1428,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) error = EINVAL; break; } - } - newrule->rt_ifp = NULL; + } else + newrule->ifp = NULL; if (newrule->rt_ifname[0]) { newrule->rt_ifp = ifunit(newrule->rt_ifname); if (newrule->rt_ifname == NULL) { @@ -1312,6 +1437,15 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) error = EINVAL; break; } + } else + newrule->rt_ifp = NULL; + if (pf_dynaddr_setup(&newrule->src.addr, newrule->af) || + pf_dynaddr_setup(&newrule->dst.addr, newrule->af)) { + pf_dynaddr_remove(&newrule->src.addr); + pf_dynaddr_remove(&newrule->dst.addr); + pool_put(&pf_rule_pl, newrule); + error = EINVAL; + break; } newrule->evaluations = newrule->packets = 0; newrule->bytes = 0; @@ -1343,6 +1477,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) if (n->state->rule == oldrule) n->state->rule = NULL; TAILQ_REMOVE(pf_rules_active, oldrule, entries); + pf_dynaddr_remove(&oldrule->src.addr); + pf_dynaddr_remove(&oldrule->dst.addr); pool_put(&pf_rule_pl, oldrule); } else { if (oldrule == NULL) @@ -1371,6 +1507,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) struct pf_nat *nat; while ((nat = TAILQ_FIRST(pf_nats_inactive)) != NULL) { + pf_dynaddr_remove(&nat->saddr); + pf_dynaddr_remove(&nat->daddr); + pf_dynaddr_remove(&nat->raddr); TAILQ_REMOVE(pf_nats_inactive, nat, entries); pool_put(&pf_nat_pl, nat); } @@ -1415,6 +1554,16 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } } else nat->ifp = NULL; + if (pf_dynaddr_setup(&nat->saddr, nat->af) || + pf_dynaddr_setup(&nat->daddr, nat->af) || + pf_dynaddr_setup(&nat->raddr, nat->af)) { + pf_dynaddr_remove(&nat->saddr); + pf_dynaddr_remove(&nat->daddr); + pf_dynaddr_remove(&nat->raddr); + pool_put(&pf_nat_pl, nat); + error = EINVAL; + break; + } TAILQ_INSERT_TAIL(pf_nats_inactive, nat, entries); break; } @@ -1439,6 +1588,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) /* Purge the old nat list */ while ((nat = TAILQ_FIRST(old_nats)) != NULL) { + pf_dynaddr_remove(&nat->saddr); + pf_dynaddr_remove(&nat->daddr); + pf_dynaddr_remove(&nat->raddr); TAILQ_REMOVE(old_nats, nat, entries); pool_put(&pf_nat_pl, nat); } @@ -1480,6 +1632,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } bcopy(nat, &pn->nat, sizeof(struct pf_nat)); + pf_dynaddr_copyout(&pn->nat.saddr); + pf_dynaddr_copyout(&pn->nat.daddr); + pf_dynaddr_copyout(&pn->nat.raddr); splx(s); break; } @@ -1515,7 +1670,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } #endif /* INET6 */ - newnat->ifp = NULL; if (newnat->ifname[0]) { newnat->ifp = ifunit(newnat->ifname); if (newnat->ifp == NULL) { @@ -1523,6 +1677,17 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) error = EINVAL; break; } + } else + newnat->ifp = NULL; + if (pf_dynaddr_setup(&newnat->saddr, newnat->af) || + pf_dynaddr_setup(&newnat->daddr, newnat->af) || + pf_dynaddr_setup(&newnat->raddr, newnat->af)) { + pf_dynaddr_remove(&newnat->saddr); + pf_dynaddr_remove(&newnat->daddr); + pf_dynaddr_remove(&newnat->raddr); + pool_put(&pf_nat_pl, newnat); + error = EINVAL; + break; } } @@ -1545,6 +1710,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } if (pcn->action == PF_CHANGE_REMOVE) { + pf_dynaddr_remove(&oldnat->saddr); + pf_dynaddr_remove(&oldnat->daddr); + pf_dynaddr_remove(&oldnat->raddr); TAILQ_REMOVE(pf_nats_active, oldnat, entries); pool_put(&pf_nat_pl, oldnat); } else { @@ -1570,6 +1738,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) while ((binat = TAILQ_FIRST(pf_binats_inactive)) != NULL) { TAILQ_REMOVE(pf_binats_inactive, binat, entries); + pf_dynaddr_remove(&binat->saddr); + pf_dynaddr_remove(&binat->daddr); + pf_dynaddr_remove(&binat->raddr); pool_put(&pf_binat_pl, binat); } *ticket = ++ticket_binats_inactive; @@ -1613,6 +1784,16 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } } else binat->ifp = NULL; + if (pf_dynaddr_setup(&binat->saddr, binat->af) || + pf_dynaddr_setup(&binat->daddr, binat->af) || + pf_dynaddr_setup(&binat->raddr, binat->af)) { + pf_dynaddr_remove(&binat->saddr); + pf_dynaddr_remove(&binat->daddr); + pf_dynaddr_remove(&binat->raddr); + pool_put(&pf_binat_pl, binat); + error = EINVAL; + break; + } TAILQ_INSERT_TAIL(pf_binats_inactive, binat, entries); break; } @@ -1638,6 +1819,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) /* Purge the old binat list */ while ((binat = TAILQ_FIRST(old_binats)) != NULL) { TAILQ_REMOVE(old_binats, binat, entries); + pf_dynaddr_remove(&binat->saddr); + pf_dynaddr_remove(&binat->daddr); + pf_dynaddr_remove(&binat->raddr); pool_put(&pf_binat_pl, binat); } break; @@ -1678,6 +1862,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } bcopy(binat, &pb->binat, sizeof(struct pf_binat)); + pf_dynaddr_copyout(&pb->binat.saddr); + pf_dynaddr_copyout(&pb->binat.daddr); + pf_dynaddr_copyout(&pb->binat.raddr); splx(s); break; } @@ -1714,7 +1901,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } #endif /* INET6 */ - newbinat->ifp = NULL; if (newbinat->ifname[0]) { newbinat->ifp = ifunit(newbinat->ifname); if (newbinat->ifp == NULL) { @@ -1722,6 +1908,17 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) error = EINVAL; break; } + } else + newbinat->ifp = NULL; + if (pf_dynaddr_setup(&newbinat->saddr, newbinat->af) || + pf_dynaddr_setup(&newbinat->daddr, newbinat->af) || + pf_dynaddr_setup(&newbinat->raddr, newbinat->af)) { + pf_dynaddr_remove(&newbinat->saddr); + pf_dynaddr_remove(&newbinat->daddr); + pf_dynaddr_remove(&newbinat->raddr); + pool_put(&pf_binat_pl, newbinat); + error = EINVAL; + break; } } @@ -1745,6 +1942,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) if (pcn->action == PF_CHANGE_REMOVE) { TAILQ_REMOVE(pf_binats_active, oldbinat, entries); + pf_dynaddr_remove(&oldbinat->saddr); + pf_dynaddr_remove(&oldbinat->daddr); + pf_dynaddr_remove(&oldbinat->raddr); pool_put(&pf_binat_pl, oldbinat); } else { if (oldbinat == NULL) @@ -1770,6 +1970,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) while ((rdr = TAILQ_FIRST(pf_rdrs_inactive)) != NULL) { TAILQ_REMOVE(pf_rdrs_inactive, rdr, entries); + pf_dynaddr_remove(&rdr->saddr); + pf_dynaddr_remove(&rdr->daddr); + pf_dynaddr_remove(&rdr->raddr); pool_put(&pf_rdr_pl, rdr); } *ticket = ++ticket_rdrs_inactive; @@ -1813,6 +2016,16 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } } else rdr->ifp = NULL; + if (pf_dynaddr_setup(&rdr->saddr, rdr->af) || + pf_dynaddr_setup(&rdr->daddr, rdr->af) || + pf_dynaddr_setup(&rdr->raddr, rdr->af)) { + pf_dynaddr_remove(&rdr->saddr); + pf_dynaddr_remove(&rdr->daddr); + pf_dynaddr_remove(&rdr->raddr); + pool_put(&pf_rdr_pl, rdr); + error = EINVAL; + break; + } TAILQ_INSERT_TAIL(pf_rdrs_inactive, rdr, entries); break; } @@ -1838,6 +2051,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) /* Purge the old rdr list */ while ((rdr = TAILQ_FIRST(old_rdrs)) != NULL) { TAILQ_REMOVE(old_rdrs, rdr, entries); + pf_dynaddr_remove(&rdr->saddr); + pf_dynaddr_remove(&rdr->daddr); + pf_dynaddr_remove(&rdr->raddr); pool_put(&pf_rdr_pl, rdr); } break; @@ -1878,6 +2094,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } bcopy(rdr, &pr->rdr, sizeof(struct pf_rdr)); + pf_dynaddr_copyout(&pr->rdr.saddr); + pf_dynaddr_copyout(&pr->rdr.daddr); + pf_dynaddr_copyout(&pr->rdr.raddr); splx(s); break; } @@ -1913,7 +2132,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } #endif /* INET6 */ - newrdr->ifp = NULL; if (newrdr->ifname[0]) { newrdr->ifp = ifunit(newrdr->ifname); if (newrdr->ifp == NULL) { @@ -1921,6 +2139,17 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) error = EINVAL; break; } + } else + newrdr->ifp = NULL; + if (pf_dynaddr_setup(&newrdr->saddr, newrdr->af) || + pf_dynaddr_setup(&newrdr->daddr, newrdr->af) || + pf_dynaddr_setup(&newrdr->raddr, newrdr->af)) { + pf_dynaddr_remove(&newrdr->saddr); + pf_dynaddr_remove(&newrdr->daddr); + pf_dynaddr_remove(&newrdr->raddr); + pool_put(&pf_rdr_pl, newrdr); + error = EINVAL; + break; } } @@ -1944,6 +2173,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) if (pcn->action == PF_CHANGE_REMOVE) { TAILQ_REMOVE(pf_rdrs_active, oldrdr, entries); + pf_dynaddr_remove(&oldrdr->saddr); + pf_dynaddr_remove(&oldrdr->daddr); + pf_dynaddr_remove(&oldrdr->raddr); pool_put(&pf_rdr_pl, oldrdr); } else { if (oldrdr == NULL) @@ -1988,9 +2220,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) st = n->state; if ((!psk->psk_af || st->af == psk->psk_af) && (!psk->psk_proto || psk->psk_proto == st->proto) && - PF_MATCHA(psk->psk_src.not, &psk->psk_src.addr, + PF_MATCHA(psk->psk_src.not, &psk->psk_src.addr.addr, &psk->psk_src.mask, &st->lan.addr, st->af) && - PF_MATCHA(psk->psk_dst.not, &psk->psk_dst.addr, + PF_MATCHA(psk->psk_dst.not, &psk->psk_dst.addr.addr, &psk->psk_dst.mask, &st->ext.addr, st->af) && (psk->psk_src.port_op == 0 || pf_match_port(psk->psk_src.port_op, @@ -2304,7 +2536,9 @@ pf_calc_skip_steps(struct pf_rulequeue *rules) PF_CALC_SKIP_STEP(PF_SKIP_AF, s->af == r->af); PF_CALC_SKIP_STEP(PF_SKIP_PROTO, s->proto == r->proto); PF_CALC_SKIP_STEP(PF_SKIP_SRC_ADDR, - PF_AEQ(&s->src.addr, &r->src.addr, r->af) && + s->src.addr.addr_dyn == NULL && + r->src.addr.addr_dyn == NULL && + PF_AEQ(&s->src.addr.addr, &r->src.addr.addr, r->af) && PF_AEQ(&s->src.mask, &r->src.mask, r->af) && s->src.not == r->src.not); PF_CALC_SKIP_STEP(PF_SKIP_SRC_PORT, @@ -2312,7 +2546,9 @@ pf_calc_skip_steps(struct pf_rulequeue *rules) s->src.port[1] == r->src.port[1] && s->src.port_op == r->src.port_op); PF_CALC_SKIP_STEP(PF_SKIP_DST_ADDR, - PF_AEQ(&s->dst.addr, &r->dst.addr, r->af) && + s->dst.addr.addr_dyn == NULL && + r->dst.addr.addr_dyn == NULL && + PF_AEQ(&s->dst.addr.addr, &r->dst.addr.addr, r->af) && PF_AEQ(&s->dst.mask, &r->dst.mask, r->af) && s->dst.not == r->dst.not); PF_CALC_SKIP_STEP(PF_SKIP_DST_PORT, @@ -2829,13 +3065,18 @@ pf_get_nat(struct ifnet *ifp, u_int8_t proto, struct pf_addr *saddr, (n->ifp != ifp && n->ifnot)) && (!n->proto || n->proto == proto) && (!n->af || n->af == af) && - PF_MATCHA(n->snot, &n->saddr, &n->smask, saddr, af) && - PF_MATCHA(n->dnot, &n->daddr, &n->dmask, daddr, af)) + (n->saddr.addr_dyn == NULL || + !n->saddr.addr_dyn->undefined) && + PF_MATCHA(n->snot, &n->saddr.addr, &n->smask, saddr, af) && + (n->daddr.addr_dyn == NULL || + !n->daddr.addr_dyn->undefined) && + PF_MATCHA(n->dnot, &n->daddr.addr, &n->dmask, daddr, af)) nm = n; else n = TAILQ_NEXT(n, entries); } - if (nm && nm->no) + if (nm && (nm->no || (nm->raddr.addr_dyn != NULL && + nm->raddr.addr_dyn->undefined))) return (NULL); return (nm); } @@ -2854,20 +3095,34 @@ pf_get_binat(int direction, struct ifnet *ifp, u_int8_t proto, if (direction == PF_OUT && b->ifp == ifp && (!b->proto || b->proto == proto) && (!b->af || b->af == af) && - PF_MATCHA(0, &b->saddr, &fullmask, saddr, af) && - PF_MATCHA(b->dnot, &b->daddr, &b->dmask, daddr, af)) + (b->saddr.addr_dyn == NULL || + !b->saddr.addr_dyn->undefined) && + PF_MATCHA(0, &b->saddr.addr, &fullmask, saddr, af) && + (b->daddr.addr_dyn == NULL || + !b->daddr.addr_dyn->undefined) && + PF_MATCHA(b->dnot, &b->daddr.addr, &b->dmask, daddr, af)) bm = b; else if (direction == PF_IN && b->ifp == ifp && (!b->proto || b->proto == proto) && (!b->af || b->af == af) && - PF_MATCHA(0, &b->raddr, &fullmask, saddr, af) && - PF_MATCHA(b->dnot, &b->daddr, &b->dmask, daddr, af)) + (b->raddr.addr_dyn == NULL || + !b->raddr.addr_dyn->undefined) && + PF_MATCHA(0, &b->raddr.addr, &fullmask, saddr, af) && + (b->daddr.addr_dyn == NULL || + !b->daddr.addr_dyn->undefined) && + PF_MATCHA(b->dnot, &b->daddr.addr, &b->dmask, daddr, af)) bm = b; else b = TAILQ_NEXT(b, entries); } if (bm && bm->no) return (NULL); + if (bm && direction == PF_OUT && bm->raddr.addr_dyn != NULL && + bm->raddr.addr_dyn->undefined) + return (NULL); + if (bm && direction == PF_IN && bm->saddr.addr_dyn != NULL && + bm->saddr.addr_dyn->undefined) + return (NULL); return (bm); } @@ -2883,8 +3138,12 @@ pf_get_rdr(struct ifnet *ifp, u_int8_t proto, struct pf_addr *saddr, (r->ifp != ifp && r->ifnot)) && (!r->proto || r->proto == proto) && (!r->af || r->af == af) && - PF_MATCHA(r->snot, &r->saddr, &r->smask, saddr, af) && - PF_MATCHA(r->dnot, &r->daddr, &r->dmask, daddr, af) && + (r->saddr.addr_dyn == NULL || + !r->saddr.addr_dyn->undefined) && + PF_MATCHA(r->snot, &r->saddr.addr, &r->smask, saddr, af) && + (r->daddr.addr_dyn == NULL || + !r->daddr.addr_dyn->undefined) && + PF_MATCHA(r->dnot, &r->daddr.addr, &r->dmask, daddr, af) && ((!r->dport2 && (!r->dport || dport == r->dport)) || (r->dport2 && (ntohs(dport) >= ntohs(r->dport)) && ntohs(dport) <= ntohs(r->dport2)))) @@ -2892,7 +3151,8 @@ pf_get_rdr(struct ifnet *ifp, u_int8_t proto, struct pf_addr *saddr, else r = TAILQ_NEXT(r, entries); } - if (rm && rm->no) + if (rm && (rm->no || (rm->raddr.addr_dyn != NULL && + rm->raddr.addr_dyn->undefined))) return (NULL); return (rm); } @@ -2933,7 +3193,7 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp, PF_ACPY(&baddr, saddr, af); bport = th->th_sport; pf_change_ap(saddr, &th->th_sport, pd->ip_sum, - &th->th_sum, &binat->raddr, th->th_sport, 0, af); + &th->th_sum, &binat->raddr.addr, th->th_sport, 0, af); rewrite++; } /* check outgoing packet for NAT */ @@ -2946,7 +3206,8 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp, return (PF_DROP); PF_ACPY(&baddr, saddr, af); pf_change_ap(saddr, &th->th_sport, pd->ip_sum, - &th->th_sum, &nat->raddr, htons(nport), 0, af); + &th->th_sum, &nat->raddr.addr, htons(nport), + 0, af); rewrite++; } } else { @@ -2962,7 +3223,7 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp, nport = bport; PF_ACPY(&baddr, daddr, af); pf_change_ap(daddr, &th->th_dport, pd->ip_sum, - &th->th_sum, &rdr->raddr, nport, 0, af); + &th->th_sum, &rdr->raddr.addr, nport, 0, af); rewrite++; } /* check incoming packet for BINAT */ @@ -2971,7 +3232,7 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp, PF_ACPY(&baddr, daddr, af); bport = th->th_dport; pf_change_ap(daddr, &th->th_dport, pd->ip_sum, - &th->th_sum, &binat->saddr, th->th_dport, 0, af); + &th->th_sum, &binat->saddr.addr, th->th_dport, 0, af); rewrite++; } } @@ -2993,7 +3254,7 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp, r = TAILQ_NEXT(r, entries); else if (!r->src.noroute && !PF_AZERO(&r->src.mask, af) && !PF_MATCHA(r->src.not, - &r->src.addr, &r->src.mask, saddr, af)) + &r->src.addr.addr, &r->src.mask, saddr, af)) r = r->skip[PF_SKIP_SRC_ADDR]; else if (r->src.port_op && !pf_match_port(r->src.port_op, r->src.port[0], r->src.port[1], th->th_sport)) @@ -3002,7 +3263,7 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp, r = TAILQ_NEXT(r, entries); else if (!r->dst.noroute && !PF_AZERO(&r->dst.mask, af) && !PF_MATCHA(r->dst.not, - &r->dst.addr, &r->dst.mask, daddr, af)) + &r->dst.addr.addr, &r->dst.mask, daddr, af)) r = r->skip[PF_SKIP_DST_ADDR]; else if (r->dst.port_op && !pf_match_port(r->dst.port_op, r->dst.port[0], r->dst.port[1], th->th_dport)) @@ -3166,7 +3427,7 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp, PF_ACPY(&baddr, saddr, af); bport = uh->uh_sport; pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum, - &uh->uh_sum, &binat->raddr, uh->uh_sport, 1, af); + &uh->uh_sum, &binat->raddr.addr, uh->uh_sport, 1, af); rewrite++; } /* check outgoing packet for NAT */ @@ -3179,7 +3440,8 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp, return (PF_DROP); PF_ACPY(&baddr, saddr, af); pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum, - &uh->uh_sum, &nat->raddr, htons(nport), 1, af); + &uh->uh_sum, &nat->raddr.addr, htons(nport), + 1, af); rewrite++; } } else { @@ -3196,7 +3458,7 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp, PF_ACPY(&baddr, daddr, af); pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum, - &uh->uh_sum, &rdr->raddr, nport, 1, af); + &uh->uh_sum, &rdr->raddr.addr, nport, 1, af); rewrite++; } /* check incoming packet for BINAT */ @@ -3205,7 +3467,7 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp, PF_ACPY(&baddr, daddr, af); bport = uh->uh_dport; pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum, - &uh->uh_sum, &binat->saddr, uh->uh_dport, 1, af); + &uh->uh_sum, &binat->saddr.addr, uh->uh_dport, 1, af); rewrite++; } } @@ -3227,7 +3489,7 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp, r = TAILQ_NEXT(r, entries); else if (!r->src.noroute && !PF_AZERO(&r->src.mask, af) && - !PF_MATCHA(r->src.not, &r->src.addr, &r->src.mask, + !PF_MATCHA(r->src.not, &r->src.addr.addr, &r->src.mask, saddr, af)) r = r->skip[PF_SKIP_SRC_ADDR]; else if (r->src.port_op && !pf_match_port(r->src.port_op, @@ -3237,7 +3499,7 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp, r = TAILQ_NEXT(r, entries); else if (!r->dst.noroute && !PF_AZERO(&r->dst.mask, af) && - !PF_MATCHA(r->dst.not, &r->dst.addr, &r->dst.mask, + !PF_MATCHA(r->dst.not, &r->dst.addr.addr, &r->dst.mask, daddr, af)) r = r->skip[PF_SKIP_DST_ADDR]; else if (r->dst.port_op && !pf_match_port(r->dst.port_op, @@ -3413,13 +3675,13 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp, #ifdef INET case AF_INET: pf_change_a(&saddr->v4.s_addr, pd->ip_sum, - binat->raddr.v4.s_addr, 0); + binat->raddr.addr.v4.s_addr, 0); break; #endif /* INET */ #ifdef INET6 case AF_INET6: pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum, - &binat->raddr, 0); + &binat->raddr.addr, 0); rewrite++; break; #endif /* INET6 */ @@ -3433,13 +3695,13 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp, #ifdef INET case AF_INET: pf_change_a(&saddr->v4.s_addr, - pd->ip_sum, nat->raddr.v4.s_addr, 0); + pd->ip_sum, nat->raddr.addr.v4.s_addr, 0); break; #endif /* INET */ #ifdef INET6 case AF_INET6: pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum, - &nat->raddr, 0); + &nat->raddr.addr, 0); rewrite++; break; #endif /* INET6 */ @@ -3454,13 +3716,13 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp, #ifdef INET case AF_INET: pf_change_a(&daddr->v4.s_addr, - pd->ip_sum, rdr->raddr.v4.s_addr, 0); + pd->ip_sum, rdr->raddr.addr.v4.s_addr, 0); break; #endif /* INET */ #ifdef INET6 case AF_INET6: pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum, - &rdr->raddr, 0); + &rdr->raddr.addr, 0); rewrite++; break; #endif /* INET6 */ @@ -3474,13 +3736,13 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp, #ifdef INET case AF_INET: pf_change_a(&daddr->v4.s_addr, - pd->ip_sum, binat->saddr.v4.s_addr, 0); + pd->ip_sum, binat->saddr.addr.v4.s_addr, 0); break; #endif /* INET */ #ifdef INET6 case AF_INET6: pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum, - &binat->saddr, 0); + &binat->saddr.addr, 0); rewrite++; break; #endif /* INET6 */ @@ -3505,13 +3767,13 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp, r = TAILQ_NEXT(r, entries); else if (!r->src.noroute && !PF_AZERO(&r->src.mask, af) && !PF_MATCHA(r->src.not, - &r->src.addr, &r->src.mask, saddr, af)) + &r->src.addr.addr, &r->src.mask, saddr, af)) r = r->skip[PF_SKIP_SRC_ADDR]; else if (r->dst.noroute && pf_routable(daddr, af)) r = TAILQ_NEXT(r, entries); else if (!r->dst.noroute && !PF_AZERO(&r->dst.mask, af) && !PF_MATCHA(r->dst.not, - &r->dst.addr, &r->dst.mask, daddr, af)) + &r->dst.addr.addr, &r->dst.mask, daddr, af)) r = r->skip[PF_SKIP_DST_ADDR]; else if (r->ifp != NULL && r->ifp != ifp) r = TAILQ_NEXT(r, entries); @@ -3632,12 +3894,12 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp, #ifdef INET case AF_INET: pf_change_a(&saddr->v4.s_addr, pd->ip_sum, - binat->raddr.v4.s_addr, 0); + binat->raddr.addr.v4.s_addr, 0); break; #endif /* INET */ #ifdef INET6 case AF_INET6: - PF_ACPY(saddr, &binat->raddr, af); + PF_ACPY(saddr, &binat->raddr.addr, af); break; #endif /* INET6 */ } @@ -3650,12 +3912,12 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp, #ifdef INET case AF_INET: pf_change_a(&saddr->v4.s_addr, - pd->ip_sum, nat->raddr.v4.s_addr, 0); + pd->ip_sum, nat->raddr.addr.v4.s_addr, 0); break; #endif /* INET */ #ifdef INET6 case AF_INET6: - PF_ACPY(saddr, &nat->raddr, af); + PF_ACPY(saddr, &nat->raddr.addr, af); break; #endif /* INET6 */ } @@ -3669,12 +3931,12 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp, #ifdef INET case AF_INET: pf_change_a(&daddr->v4.s_addr, - pd->ip_sum, rdr->raddr.v4.s_addr, 0); + pd->ip_sum, rdr->raddr.addr.v4.s_addr, 0); break; #endif /* INET */ #ifdef INET6 case AF_INET6: - PF_ACPY(daddr, &rdr->raddr, af); + PF_ACPY(daddr, &rdr->raddr.addr, af); break; #endif /* INET6 */ } @@ -3687,12 +3949,12 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp, #ifdef INET case AF_INET: pf_change_a(&daddr->v4.s_addr, - pd->ip_sum, binat->saddr.v4.s_addr, 0); + pd->ip_sum, binat->saddr.addr.v4.s_addr, 0); break; #endif /* INET */ #ifdef INET6 case AF_INET6: - PF_ACPY(daddr, &binat->saddr, af); + PF_ACPY(daddr, &binat->saddr.addr, af); break; #endif /* INET6 */ } @@ -3716,13 +3978,13 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp, r = TAILQ_NEXT(r, entries); else if (!r->src.noroute && !PF_AZERO(&r->src.mask, af) && !PF_MATCHA(r->src.not, - &r->src.addr, &r->src.mask, pd->src, af)) + &r->src.addr.addr, &r->src.mask, pd->src, af)) r = r->skip[PF_SKIP_SRC_ADDR]; else if (r->dst.noroute && pf_routable(pd->dst, af)) r = TAILQ_NEXT(r, entries); else if (!r->src.noroute && !PF_AZERO(&r->dst.mask, af) && !PF_MATCHA(r->dst.not, - &r->dst.addr, &r->dst.mask, pd->dst, af)) + &r->dst.addr.addr, &r->dst.mask, pd->dst, af)) r = r->skip[PF_SKIP_DST_ADDR]; else if (r->rule_flag & PFRULE_FRAGMENT) r = TAILQ_NEXT(r, entries); @@ -3829,13 +4091,13 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct ifnet *ifp, r = TAILQ_NEXT(r, entries); else if (!r->src.noroute && !PF_AZERO(&r->src.mask, af) && !PF_MATCHA(r->src.not, - &r->src.addr, &r->src.mask, pd->src, af)) + &r->src.addr.addr, &r->src.mask, pd->src, af)) r = r->skip[PF_SKIP_SRC_ADDR]; else if (r->dst.noroute && pf_routable(pd->dst, af)) r = TAILQ_NEXT(r, entries); else if (!r->src.noroute && !PF_AZERO(&r->dst.mask, af) && !PF_MATCHA(r->dst.not, - &r->dst.addr, &r->dst.mask, pd->dst, af)) + &r->dst.addr.addr, &r->dst.mask, pd->dst, af)) r = r->skip[PF_SKIP_DST_ADDR]; else if (r->src.port_op || r->dst.port_op || r->flagset || r->type || r->code) diff --git a/sys/net/pf_norm.c b/sys/net/pf_norm.c index c4fb2447653..5cf6404ea1f 100644 --- a/sys/net/pf_norm.c +++ b/sys/net/pf_norm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_norm.c,v 1.23 2002/04/20 18:26:03 dhartmei Exp $ */ +/* $OpenBSD: pf_norm.c,v 1.24 2002/04/24 18:10:25 dhartmei Exp $ */ /* * Copyright 2001 Niels Provos <provos@citi.umich.edu> @@ -451,11 +451,11 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason) else if (r->proto && r->proto != h->ip_p) r = r->skip[PF_SKIP_PROTO]; else if (!PF_AZERO(&r->src.mask, AF_INET) && - !PF_MATCHA(r->src.not, &r->src.addr, &r->src.mask, + !PF_MATCHA(r->src.not, &r->src.addr.addr, &r->src.mask, (struct pf_addr *)&h->ip_src.s_addr, AF_INET)) r = r->skip[PF_SKIP_SRC_ADDR]; else if (!PF_AZERO(&r->dst.mask, AF_INET) && - !PF_MATCHA(r->dst.not, &r->dst.addr, &r->dst.mask, + !PF_MATCHA(r->dst.not, &r->dst.addr.addr, &r->dst.mask, (struct pf_addr *)&h->ip_dst.s_addr, AF_INET)) r = r->skip[PF_SKIP_DST_ADDR]; else @@ -590,7 +590,7 @@ pf_normalize_tcp(int dir, struct ifnet *ifp, struct mbuf *m, int ipoff, else if (r->src.noroute && pf_routable(pd->src, af)) r = TAILQ_NEXT(r, entries); else if (!r->src.noroute && !PF_AZERO(&r->src.mask, af) && - !PF_MATCHA(r->src.not, &r->src.addr, &r->src.mask, + !PF_MATCHA(r->src.not, &r->src.addr.addr, &r->src.mask, pd->src, af)) r = r->skip[PF_SKIP_SRC_ADDR]; else if (r->src.port_op && !pf_match_port(r->src.port_op, @@ -599,7 +599,7 @@ pf_normalize_tcp(int dir, struct ifnet *ifp, struct mbuf *m, int ipoff, else if (r->dst.noroute && pf_routable(pd->dst, af)) r = TAILQ_NEXT(r, entries); else if (!r->dst.noroute && !PF_AZERO(&r->dst.mask, af) && - !PF_MATCHA(r->dst.not, &r->dst.addr, &r->dst.mask, + !PF_MATCHA(r->dst.not, &r->dst.addr.addr, &r->dst.mask, pd->dst, af)) r = r->skip[PF_SKIP_DST_ADDR]; else if (r->dst.port_op && !pf_match_port(r->dst.port_op, diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 824be2b28bd..dfac723cae6 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.67 2002/04/23 14:32:22 dhartmei Exp $ */ +/* $OpenBSD: pfvar.h,v 1.68 2002/04/24 18:10:25 dhartmei Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -60,6 +60,7 @@ struct pf_addr { u_int8_t addr8[16]; u_int16_t addr16[8]; u_int32_t addr32[4]; + char ifname[IFNAMSIZ]; } pfa; /* 128-bit address */ #define v4 pfa.v4 #define v6 pfa.v6 @@ -68,6 +69,20 @@ struct pf_addr { #define addr32 pfa.addr32 }; +struct pf_addr_wrap { + struct pf_addr addr; + struct pf_addr_dyn *addr_dyn; +}; + +struct pf_addr_dyn { + char ifname[IFNAMSIZ]; + struct ifnet *ifp; + struct pf_addr *addr; + u_int8_t af; + void *hook_cookie; + u_int8_t undefined; +}; + /* * Address manipulation macros */ @@ -182,25 +197,17 @@ struct pf_addr { #endif /* PF_INET_INET6 */ struct pf_rule_addr { - struct pf_addr addr; - struct pf_addr mask; - u_int16_t port[2]; - u_int8_t not; - u_int8_t port_op; - u_int8_t noroute; + struct pf_addr_wrap addr; + struct pf_addr mask; + u_int16_t port[2]; + u_int8_t not; + u_int8_t port_op; + u_int8_t noroute; }; struct pf_rule { - char ifname[IFNAMSIZ]; - char rt_ifname[IFNAMSIZ]; -#define PF_RULE_LABEL_SIZE 32 - char label[PF_RULE_LABEL_SIZE]; - struct ifnet *ifp; - struct ifnet *rt_ifp; - struct pf_rule_addr src; - struct pf_rule_addr dst; - struct pf_addr rt_addr; - + struct pf_rule_addr src; + struct pf_rule_addr dst; #define PF_SKIP_ACTION 0 #define PF_SKIP_IFP 1 #define PF_SKIP_DIR 2 @@ -211,36 +218,44 @@ struct pf_rule { #define PF_SKIP_DST_ADDR 7 #define PF_SKIP_DST_PORT 8 #define PF_SKIP_COUNT 9 - struct pf_rule *skip[PF_SKIP_COUNT]; - TAILQ_ENTRY(pf_rule) entries; + struct pf_rule *skip[PF_SKIP_COUNT]; +#define PF_RULE_LABEL_SIZE 32 + char label[PF_RULE_LABEL_SIZE]; + struct pf_addr rt_addr; + char ifname[IFNAMSIZ]; + char rt_ifname[IFNAMSIZ]; + TAILQ_ENTRY(pf_rule) entries; - u_int64_t evaluations; - u_int64_t packets; - u_int64_t bytes; + u_int64_t evaluations; + u_int64_t packets; + u_int64_t bytes; - u_int16_t nr; - u_int16_t return_icmp; + struct ifnet *ifp; + struct ifnet *rt_ifp; - u_int8_t action; - u_int8_t direction; - u_int8_t log; - u_int8_t quick; + u_int16_t nr; + u_int16_t return_icmp; + + u_int8_t action; + u_int8_t direction; + u_int8_t log; + u_int8_t quick; #define PF_STATE_NORMAL 0x1 #define PF_STATE_MODULATE 0x2 - u_int8_t keep_state; - u_int8_t af; - u_int8_t proto; - u_int8_t type; - u_int8_t code; - - u_int8_t flags; - u_int8_t flagset; - - u_int8_t rule_flag; - u_int8_t min_ttl; /* minimum ttl for packet normalize */ - u_int8_t allow_opts; - u_int8_t rt; + u_int8_t keep_state; + u_int8_t af; + u_int8_t proto; + u_int8_t type; + u_int8_t code; + + u_int8_t flags; + u_int8_t flagset; + + u_int8_t rule_flag; + u_int8_t min_ttl; + u_int8_t allow_opts; + u_int8_t rt; }; #define PFRULE_RETURNRST 0x01 @@ -282,55 +297,55 @@ struct pf_state { }; struct pf_nat { - char ifname[IFNAMSIZ]; - struct ifnet *ifp; - TAILQ_ENTRY(pf_nat) entries; - struct pf_addr saddr; - struct pf_addr smask; - struct pf_addr daddr; - struct pf_addr dmask; - struct pf_addr raddr; - u_int8_t af; - u_int8_t proto; - u_int8_t snot; - u_int8_t dnot; - u_int8_t ifnot; - u_int8_t no; + char ifname[IFNAMSIZ]; + struct ifnet *ifp; + TAILQ_ENTRY(pf_nat) entries; + struct pf_addr_wrap saddr; + struct pf_addr_wrap daddr; + struct pf_addr_wrap raddr; + struct pf_addr smask; + struct pf_addr dmask; + u_int8_t af; + u_int8_t proto; + u_int8_t snot; + u_int8_t dnot; + u_int8_t ifnot; + u_int8_t no; }; struct pf_binat { - char ifname[IFNAMSIZ]; - struct ifnet *ifp; - TAILQ_ENTRY(pf_binat) entries; - struct pf_addr saddr; - struct pf_addr daddr; - struct pf_addr dmask; - struct pf_addr raddr; - u_int8_t af; - u_int8_t proto; - u_int8_t dnot; - u_int8_t no; + char ifname[IFNAMSIZ]; + struct ifnet *ifp; + TAILQ_ENTRY(pf_binat) entries; + struct pf_addr_wrap saddr; + struct pf_addr_wrap daddr; + struct pf_addr_wrap raddr; + struct pf_addr dmask; + u_int8_t af; + u_int8_t proto; + u_int8_t dnot; + u_int8_t no; }; struct pf_rdr { - char ifname[IFNAMSIZ]; - struct ifnet *ifp; - TAILQ_ENTRY(pf_rdr) entries; - struct pf_addr saddr; - struct pf_addr smask; - struct pf_addr daddr; - struct pf_addr dmask; - struct pf_addr raddr; - u_int16_t dport; - u_int16_t dport2; - u_int16_t rport; - u_int8_t af; - u_int8_t proto; - u_int8_t snot; - u_int8_t dnot; - u_int8_t ifnot; - u_int8_t opts; - u_int8_t no; + char ifname[IFNAMSIZ]; + struct ifnet *ifp; + TAILQ_ENTRY(pf_rdr) entries; + struct pf_addr_wrap saddr; + struct pf_addr_wrap daddr; + struct pf_addr_wrap raddr; + struct pf_addr smask; + struct pf_addr dmask; + u_int16_t dport; + u_int16_t dport2; + u_int16_t rport; + u_int8_t af; + u_int8_t proto; + u_int8_t snot; + u_int8_t dnot; + u_int8_t ifnot; + u_int8_t opts; + u_int8_t no; }; struct pf_tree_key { |