summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/net/pf.c478
-rw-r--r--sys/net/pfvar.h62
2 files changed, 369 insertions, 171 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index b5d5c38ab69..9050c8977ab 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.32 2001/06/25 16:53:20 jasoni Exp $ */
+/* $OpenBSD: pf.c,v 1.33 2001/06/25 17:17:04 dhartmei Exp $ */
/*
* Copyright (c) 2001, Daniel Hartmeier
@@ -74,16 +74,27 @@ struct pf_tree_node {
* Global variables
*/
-struct pf_rule *pf_rulehead;
-struct pf_nat *pf_nathead;
-struct pf_rdr *pf_rdrhead;
-struct pf_state *pfstatehead;
+struct pf_rule *pf_rulehead_active;
+struct pf_rule *pf_rulehead_inactive;
+struct pf_rule *pf_ruletail_active;
+struct pf_rule *pf_ruletail_inactive;
+struct pf_nat *pf_nathead_active;
+struct pf_nat *pf_nathead_inactive;
+struct pf_rdr *pf_rdrhead_active;
+struct pf_rdr *pf_rdrhead_inactive;
+struct pf_state *pf_statehead;
struct pf_tree_node *tree_lan_ext, *tree_ext_gwy;
struct timeval pftv;
struct pf_status pf_status;
struct ifnet *status_ifp;
u_int32_t pf_last_purge = 0;
+u_int32_t ticket_rules_active = 0;
+u_int32_t ticket_rules_inactive = 0;
+u_int32_t ticket_nats_active = 0;
+u_int32_t ticket_nats_inactive = 0;
+u_int32_t ticket_rdrs_active = 0;
+u_int32_t ticket_rdrs_inactive = 0;
u_int16_t pf_next_port_tcp = 50001;
u_int16_t pf_next_port_udp = 50001;
@@ -365,8 +376,8 @@ insert_state(struct pf_state *state)
printf("pf: ERROR! insert failed\n");
}
- state->next = pfstatehead;
- pfstatehead = state;
+ state->next = pf_statehead;
+ pf_statehead = state;
pf_status.state_inserts++;
pf_status.states++;
@@ -376,7 +387,7 @@ void
purge_expired_states(void)
{
struct pf_tree_key key;
- struct pf_state *cur = pfstatehead, *prev = NULL;
+ struct pf_state *cur = pf_statehead, *prev = NULL;
while (cur != NULL) {
if (cur->expire <= pftv.tv_sec) {
@@ -401,9 +412,9 @@ purge_expired_states(void)
tree_remove(&tree_ext_gwy, &key);
if (find_state(tree_ext_gwy, &key) != NULL)
printf("pf: ERROR! remove failed\n");
- (prev ? prev->next : pfstatehead) = cur->next;
+ (prev ? prev->next : pf_statehead) = cur->next;
pool_put(&pf_state_pl, cur);
- cur = (prev ? prev->next : pfstatehead);
+ cur = (prev ? prev->next : pf_statehead);
pf_status.state_removals++;
pf_status.states--;
} else {
@@ -509,34 +520,17 @@ int
pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
{
int error = 0;
- struct pfioc *ub;
- void *kb = NULL;
int s;
if (!(flags & FWRITE))
return (EACCES);
if ((cmd != DIOCSTART) && (cmd != DIOCSTOP) && (cmd != DIOCCLRSTATES)) {
- ub = (struct pfioc *)addr;
- if (ub == NULL)
+ if (addr == NULL) {
return (EINVAL);
- kb = malloc(ub->size, M_DEVBUF, M_NOWAIT);
- if (kb == NULL)
- return (ENOMEM);
- if (copyin(ub->buffer, kb, ub->size)) {
- free(kb, M_DEVBUF);
- return (EIO);
}
}
- s = splsoftnet();
-
- microtime(&pftv);
- if (pftv.tv_sec - pf_last_purge >= 10) {
- purge_expired_states();
- pf_last_purge = pftv.tv_sec;
- }
-
switch (cmd) {
case DIOCSTART:
@@ -561,143 +555,314 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
break;
- case DIOCSETRULES: {
- struct pf_rule *rules = (struct pf_rule *)kb, *ruletail = NULL;
- u_int16_t n;
- while (pf_rulehead != NULL) {
- struct pf_rule *next = pf_rulehead->next;
- pool_put(&pf_rule_pl, pf_rulehead);
- pf_rulehead = next;
+ case DIOCBEGINRULES: {
+ u_int32_t *ticket = (u_int32_t *)addr;
+
+ while (pf_rulehead_inactive != NULL) {
+ struct pf_rule *next = pf_rulehead_inactive->next;
+ pool_put(&pf_rule_pl, pf_rulehead_inactive);
+ pf_rulehead_inactive = next;
}
- for (n = 0; n < ub->entries; ++n) {
- struct pf_rule *rule;
+ *ticket = ++ticket_rules_inactive;
+ break;
+ }
+
+ case DIOCADDRULE: {
+ struct pfioc_rule *pr = (struct pfioc_rule *)addr;
+ struct pf_rule *rule;
- rule = pool_get(&pf_rule_pl, PR_NOWAIT);
- if (rule == NULL) {
- error = ENOMEM;
+ if (pr->ticket != ticket_rules_inactive) {
+ error = EBUSY;
+ goto done;
+ }
+ rule = pool_get(&pf_rule_pl, PR_NOWAIT);
+ if (rule == NULL) {
+ error = ENOMEM;
+ goto done;
+ }
+ bcopy(&pr->rule, rule, sizeof(struct pf_rule));
+ rule->ifp = NULL;
+ if (rule->ifname[0]) {
+ rule->ifp = ifunit(rule->ifname);
+ if (rule->ifp == NULL) {
+ pool_put(&pf_rule_pl, rule);
+ error = EINVAL;
goto done;
}
- bcopy(rules + n, rule, sizeof(struct pf_rule));
- rule->ifp = NULL;
- if (rule->ifname[0]) {
- rule->ifp = ifunit(rule->ifname);
- if (rule->ifp == NULL) {
- pool_put(&pf_rule_pl, rule);
- error = EINVAL;
- goto done;
- }
- }
- rule->next = NULL;
- if (ruletail != NULL) {
- ruletail->next = rule;
- ruletail = rule;
- } else
- pf_rulehead = ruletail = rule;
}
+ rule->next = NULL;
+ if (pf_ruletail_inactive != NULL) {
+ pf_ruletail_inactive->next = rule;
+ pf_ruletail_inactive = rule;
+ } else
+ pf_rulehead_inactive = pf_ruletail_inactive = rule;
+ break;
+ }
+
+ case DIOCCOMMITRULES: {
+ u_int32_t *ticket = (u_int32_t *)addr;
+
+ if (*ticket != ticket_rules_inactive) {
+ error = EBUSY;
+ goto done;
+ }
+ s = splsoftnet();
+ while (pf_rulehead_active != NULL) {
+ struct pf_rule *next = pf_rulehead_active->next;
+ pool_put(&pf_rule_pl, pf_rulehead_active);
+ pf_rulehead_active = next;
+ }
+ pf_rulehead_active = pf_rulehead_inactive;
+ pf_ruletail_active = pf_ruletail_inactive;
+ pf_rulehead_inactive = NULL;
+ pf_ruletail_inactive = NULL;
+ ticket_rules_active = ticket_rules_inactive;
+ splx(s);
break;
}
case DIOCGETRULES: {
- struct pf_rule *rules = (struct pf_rule *)kb;
- struct pf_rule *rule = pf_rulehead;
- u_int16_t n = 0;
- while ((rule != NULL) && (n < ub->entries)) {
- bcopy(rule, rules + n, sizeof(struct pf_rule));
- n++;
+ struct pfioc_rule *pr = (struct pfioc_rule *)addr;
+ struct pf_rule *rule;
+
+ s = splsoftnet();
+ rule = pf_rulehead_active;
+ pr->nr = 0;
+ while (rule != NULL) {
+ pr->nr++;
+ rule = rule->next;
+ }
+ pr->ticket = ticket_rules_active;
+ splx(s);
+ break;
+ }
+
+ case DIOCGETRULE: {
+ struct pfioc_rule *pr = (struct pfioc_rule *)addr;
+ struct pf_rule *rule;
+ u_int32_t nr;
+
+ if (pr->ticket != ticket_rules_active) {
+ error = EBUSY;
+ goto done;
+ }
+ s = splsoftnet();
+ rule = pf_rulehead_active;
+ nr = 0;
+ while ((rule != NULL) && (nr < pr->nr)) {
rule = rule->next;
+ nr++;
+ }
+ if (rule == NULL) {
+ error = EBUSY;
+ splx(s);
+ goto done;
}
- ub->entries = n;
+ bcopy(rule, &pr->rule, sizeof(struct pf_rule));
+ splx(s);
break;
}
- case DIOCSETNAT: {
- struct pf_nat *nats = (struct pf_nat *)kb;
- u_int16_t n;
- while (pf_nathead != NULL) {
- struct pf_nat *next = pf_nathead->next;
+ case DIOCBEGINNATS: {
+ u_int32_t *ticket = (u_int32_t *)addr;
- pool_put(&pf_nat_pl, pf_nathead);
- pf_nathead = next;
+ while (pf_nathead_inactive != NULL) {
+ struct pf_nat *next = pf_nathead_inactive->next;
+ pool_put(&pf_nat_pl, pf_nathead_inactive);
+ pf_nathead_inactive = next;
}
- for (n = 0; n < ub->entries; ++n) {
- struct pf_nat *nat;
+ *ticket = ++ticket_nats_inactive;
+ break;
+ }
- nat = pool_get(&pf_nat_pl, PR_NOWAIT);
- if (nat == NULL) {
- error = ENOMEM;
- goto done;
- }
- bcopy(nats + n, nat, sizeof(struct pf_nat));
- nat->ifp = ifunit(nat->ifname);
- if (nat->ifp == NULL) {
- pool_put(&pf_nat_pl, nat);
- error = EINVAL;
- goto done;
- }
- nat->next = pf_nathead;
- pf_nathead = nat;
+ case DIOCADDNAT: {
+ struct pfioc_nat *pn = (struct pfioc_nat *)addr;
+ struct pf_nat *nat;
+
+ if (pn->ticket != ticket_nats_inactive) {
+ error = EBUSY;
+ goto done;
+ }
+ nat = pool_get(&pf_nat_pl, PR_NOWAIT);
+ if (nat == NULL) {
+ error = ENOMEM;
+ goto done;
+ }
+ bcopy(&pn->nat, nat, sizeof(struct pf_nat));
+ nat->ifp = ifunit(nat->ifname);
+ if (nat->ifp == NULL) {
+ pool_put(&pf_nat_pl, nat);
+ error = EINVAL;
+ goto done;
+ }
+ nat->next = pf_nathead_inactive;
+ pf_nathead_inactive = nat;
+ break;
+ }
+
+ case DIOCCOMMITNATS: {
+ u_int32_t *ticket = (u_int32_t *)addr;
+
+ if (*ticket != ticket_nats_inactive) {
+ error = EBUSY;
+ goto done;
+ }
+ s = splsoftnet();
+ while (pf_nathead_active != NULL) {
+ struct pf_nat *next = pf_nathead_active->next;
+ pool_put(&pf_nat_pl, pf_nathead_active);
+ pf_nathead_active = next;
+ }
+ pf_nathead_active = pf_nathead_inactive;
+ pf_nathead_inactive = NULL;
+ ticket_nats_active = ticket_nats_inactive;
+ splx(s);
+ break;
+ }
+
+ case DIOCGETNATS: {
+ struct pfioc_nat *pn = (struct pfioc_nat *)addr;
+ struct pf_nat *nat;
+
+ s = splsoftnet();
+ nat = pf_nathead_active;
+ pn->nr = 0;
+ while (nat != NULL) {
+ pn->nr++;
+ nat = nat->next;
}
+ pn->ticket = ticket_nats_active;
+ splx(s);
break;
}
case DIOCGETNAT: {
- struct pf_nat *nats = (struct pf_nat *)kb;
- struct pf_nat *nat = pf_nathead;
- u_int16_t n = 0;
- while ((nat != NULL) && (n < ub->entries)) {
- bcopy(nat, nats + n, sizeof(struct pf_nat));
- n++;
+ struct pfioc_nat *pn = (struct pfioc_nat *)addr;
+ struct pf_nat *nat;
+ u_int32_t nr;
+
+ if (pn->ticket != ticket_nats_active) {
+ error = EBUSY;
+ goto done;
+ }
+ s = splsoftnet();
+ nat = pf_nathead_active;
+ nr = 0;
+ while ((nat != NULL) && (nr < pn->nr)) {
nat = nat->next;
+ nr++;
}
- ub->entries = n;
+ if (nat == NULL) {
+ error = EBUSY;
+ splx(s);
+ goto done;
+ }
+ bcopy(nat, &pn->nat, sizeof(struct pf_nat));
+ splx(s);
break;
}
- case DIOCSETRDR: {
- struct pf_rdr *rdrs = (struct pf_rdr *)kb;
- u_int16_t n;
- while (pf_rdrhead != NULL) {
- struct pf_rdr *next = pf_rdrhead->next;
+ case DIOCBEGINRDRS: {
+ u_int32_t *ticket = (u_int32_t *)addr;
- pool_put(&pf_rdr_pl, pf_rdrhead);
- pf_rdrhead = next;
+ while (pf_rdrhead_inactive != NULL) {
+ struct pf_rdr *next = pf_rdrhead_inactive->next;
+ pool_put(&pf_rdr_pl, pf_rdrhead_inactive);
+ pf_rdrhead_inactive = next;
}
- for (n = 0; n < ub->entries; ++n) {
- struct pf_rdr *rdr;
+ *ticket = ++ticket_rdrs_inactive;
+ break;
+ }
- rdr = pool_get(&pf_rdr_pl, PR_NOWAIT);
- if (rdr == NULL) {
- error = ENOMEM;
- goto done;
- }
- bcopy(rdrs + n, rdr, sizeof(struct pf_rdr));
- rdr->ifp = ifunit(rdr->ifname);
- if (rdr->ifp == NULL) {
- pool_put(&pf_rdr_pl, rdr);
- error = EINVAL;
- goto done;
- }
- rdr->next = pf_rdrhead;
- pf_rdrhead = rdr;
+ case DIOCADDRDR: {
+ struct pfioc_rdr *pr = (struct pfioc_rdr *)addr;
+ struct pf_rdr *rdr;
+
+ if (pr->ticket != ticket_rdrs_inactive) {
+ error = EBUSY;
+ goto done;
+ }
+ rdr = pool_get(&pf_rdr_pl, PR_NOWAIT);
+ if (rdr == NULL) {
+ error = ENOMEM;
+ goto done;
+ }
+ bcopy(&pr->rdr, rdr, sizeof(struct pf_rdr));
+ rdr->ifp = ifunit(rdr->ifname);
+ if (rdr->ifp == NULL) {
+ pool_put(&pf_rdr_pl, rdr);
+ error = EINVAL;
+ goto done;
}
+ rdr->next = pf_rdrhead_inactive;
+ pf_rdrhead_inactive = rdr;
+ break;
+ }
+
+ case DIOCCOMMITRDRS: {
+ u_int32_t *ticket = (u_int32_t *)addr;
+
+ if (*ticket != ticket_rdrs_inactive) {
+ error = EBUSY;
+ goto done;
+ }
+ s = splsoftnet();
+ while (pf_rdrhead_active != NULL) {
+ struct pf_rdr *next = pf_rdrhead_active->next;
+ pool_put(&pf_rdr_pl, pf_rdrhead_active);
+ pf_rdrhead_active = next;
+ }
+ pf_rdrhead_active = pf_rdrhead_inactive;
+ pf_rdrhead_inactive = NULL;
+ ticket_rdrs_active = ticket_rdrs_inactive;
+ splx(s);
+ break;
+ }
+
+ case DIOCGETRDRS: {
+ struct pfioc_rdr *pr = (struct pfioc_rdr *)addr;
+ struct pf_rdr *rdr;
+
+ s = splsoftnet();
+ rdr = pf_rdrhead_active;
+ pr->nr = 0;
+ while (rdr != NULL) {
+ pr->nr++;
+ rdr = rdr->next;
+ }
+ pr->ticket = ticket_rdrs_active;
+ splx(s);
break;
}
case DIOCGETRDR: {
- struct pf_rdr *rdrs = (struct pf_rdr *)kb;
- struct pf_rdr *rdr = pf_rdrhead;
- u_int16_t n = 0;
- while ((rdr != NULL) && (n < ub->entries)) {
- bcopy(rdr, rdrs + n, sizeof(struct pf_rdr));
- n++;
+ struct pfioc_rdr *pr = (struct pfioc_rdr *)addr;
+ struct pf_rdr *rdr;
+ u_int32_t nr;
+
+ if (pr->ticket != ticket_rdrs_active) {
+ error = EBUSY;
+ goto done;
+ }
+ s = splsoftnet();
+ rdr = pf_rdrhead_active;
+ nr = 0;
+ while ((rdr != NULL) && (nr < pr->nr)) {
rdr = rdr->next;
+ nr++;
+ }
+ if (rdr == NULL) {
+ error = EBUSY;
+ splx(s);
+ goto done;
}
- ub->entries = n;
+ bcopy(rdr, &pr->rdr, sizeof(struct pf_rdr));
+ splx(s);
break;
}
case DIOCCLRSTATES: {
- struct pf_state *state = pfstatehead;
+ struct pf_state *state = pf_statehead;
while (state != NULL) {
state->expire = 0;
state = state->next;
@@ -706,29 +871,35 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
}
- case DIOCGETSTATES: {
- struct pf_state *states = (struct pf_state *)kb;
+ case DIOCGETSTATE: {
+ struct pfioc_state *ps = (struct pfioc_state *)addr;
struct pf_state *state;
- u_int16_t n = 0;
- state = pfstatehead;
- while ((state != NULL) && (n < ub->entries)) {
- bcopy(state, states + n, sizeof(struct pf_state));
- states[n].creation = pftv.tv_sec - states[n].creation;
- if (states[n].expire <= pftv.tv_sec)
- states[n].expire = 0;
- else
- states[n].expire -= pftv.tv_sec;
- n++;
+ u_int32_t nr;
+
+ state = pf_statehead;
+ nr = 0;
+ while ((state != NULL) && (nr < ps->nr)) {
state = state->next;
+ nr++;
}
- ub->entries = n;
+ if (state == NULL) {
+ error = EBUSY;
+ goto done;
+ }
+ bcopy(state, &ps->state, sizeof(struct pf_state));
+ ps->state.creation = pftv.tv_sec - ps->state.creation;
+ if (ps->state.expire <= pftv.tv_sec)
+ ps->state.expire = 0;
+ else
+ ps->state.expire -= pftv.tv_sec;
break;
}
case DIOCSETSTATUSIF: {
- char *ifname = (char *)kb;
- struct ifnet *ifp = ifunit(ifname);
- if (ifp == NULL)
+ struct pfioc_if *pi = (struct pfioc_if *)addr;
+ struct ifnet *ifp;
+
+ if ((ifp = ifunit(pi->ifname)) == NULL)
error = EINVAL;
else
status_ifp = ifp;
@@ -736,12 +907,15 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
case DIOCGETSTATUS: {
- struct pf_status *st = (struct pf_status *)kb;
+ struct pf_status *s = (struct pf_status *)addr;
u_int8_t running = pf_status.running;
u_int32_t states = pf_status.states;
- bcopy(&pf_status, st, sizeof(struct pf_status));
- st->since = st->since ? pftv.tv_sec - st->since : 0;
- ub->entries = 1;
+
+ bcopy(&pf_status, s, sizeof(struct pf_status));
+ if (s->since)
+ s->since = pftv.tv_sec - s->since;
+ else
+ s->since = 0;
bzero(&pf_status, sizeof(struct pf_status));
pf_status.running = running;
pf_status.states = states;
@@ -755,12 +929,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
done:
- splx(s);
- if (kb != NULL) {
- if (copyout(kb, ub->buffer, ub->size))
- error = EIO;
- free(kb, M_DEVBUF);
- }
return (error);
}
@@ -932,7 +1100,7 @@ match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p)
struct pf_nat *
get_nat(struct ifnet *ifp, u_int8_t proto, u_int32_t addr)
{
- struct pf_nat *n = pf_nathead, *nm = NULL;
+ struct pf_nat *n = pf_nathead_active, *nm = NULL;
while (n && nm == NULL) {
if (n->ifp == ifp &&
@@ -948,7 +1116,7 @@ get_nat(struct ifnet *ifp, u_int8_t proto, u_int32_t addr)
struct pf_rdr *
get_rdr(struct ifnet *ifp, u_int8_t proto, u_int32_t addr, u_int16_t port)
{
- struct pf_rdr *r = pf_rdrhead, *rm = NULL;
+ struct pf_rdr *r = pf_rdrhead_active, *rm = NULL;
while (r && rm == NULL) {
if (r->ifp == ifp &&
(!r->proto || r->proto == proto) &&
@@ -969,7 +1137,7 @@ pf_test_tcp(int direction, struct ifnet *ifp, int off, struct ip *h,
struct pf_rdr *rdr = NULL;
u_int32_t baddr;
u_int16_t bport;
- struct pf_rule *r = pf_rulehead, *rm = NULL;
+ struct pf_rule *r = pf_rulehead_active, *rm = NULL;
u_int16_t nr = 1, mnr = 0;
if (direction == PF_OUT) {
@@ -1113,7 +1281,7 @@ pf_test_udp(int direction, struct ifnet *ifp, int off, struct ip *h,
struct pf_rdr *rdr = NULL;
u_int32_t baddr;
u_int16_t bport;
- struct pf_rule *r = pf_rulehead, *rm = NULL;
+ struct pf_rule *r = pf_rulehead_active, *rm = NULL;
u_int16_t nr = 1, mnr = 0;
if (direction == PF_OUT) {
@@ -1233,7 +1401,7 @@ pf_test_icmp(int direction, struct ifnet *ifp, int off, struct ip *h,
{
struct pf_nat *nat = NULL;
u_int32_t baddr;
- struct pf_rule *r = pf_rulehead, *rm = NULL;
+ struct pf_rule *r = pf_rulehead_active, *rm = NULL;
u_int16_t nr = 1, mnr = 0;
if (direction == PF_OUT) {
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index e3ff3152f0c..af8a7f277cf 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.9 2001/06/25 10:07:15 art Exp $ */
+/* $OpenBSD: pfvar.h,v 1.10 2001/06/25 17:17:03 dhartmei Exp $ */
/*
* Copyright (c) 2001, Daniel Hartmeier
@@ -129,13 +129,34 @@ struct pf_status {
};
/*
- * ioctl parameter structure
+ * ioctl parameter structures
*/
-struct pfioc {
- u_int32_t size;
- u_int16_t entries;
- void *buffer;
+struct pfioc_rule {
+ u_int32_t ticket;
+ u_int32_t nr;
+ struct pf_rule rule;
+};
+
+struct pfioc_nat {
+ u_int32_t ticket;
+ u_int32_t nr;
+ struct pf_nat nat;
+};
+
+struct pfioc_rdr {
+ u_int32_t ticket;
+ u_int32_t nr;
+ struct pf_rdr rdr;
+};
+
+struct pfioc_state {
+ u_int32_t nr;
+ struct pf_state state;
+};
+
+struct pfioc_if {
+ char ifname[IFNAMSIZ];
};
/*
@@ -144,16 +165,25 @@ struct pfioc {
#define DIOCSTART _IO ('D', 1)
#define DIOCSTOP _IO ('D', 2)
-#define DIOCSETRULES _IOWR('D', 3, struct pfioc)
-#define DIOCGETRULES _IOWR('D', 4, struct pfioc)
-#define DIOCSETNAT _IOWR('D', 5, struct pfioc)
-#define DIOCGETNAT _IOWR('D', 6, struct pfioc)
-#define DIOCSETRDR _IOWR('D', 7, struct pfioc)
-#define DIOCGETRDR _IOWR('D', 8, struct pfioc)
-#define DIOCCLRSTATES _IO ('D', 9)
-#define DIOCGETSTATES _IOWR('D', 10, struct pfioc)
-#define DIOCSETSTATUSIF _IOWR('D', 11, struct pfioc)
-#define DIOCGETSTATUS _IOWR('D', 12, struct pfioc)
+#define DIOCBEGINRULES _IOWR('D', 3, u_int32_t)
+#define DIOCADDRULE _IOWR('D', 4, struct pfioc_rule)
+#define DIOCCOMMITRULES _IOWR('D', 5, u_int32_t)
+#define DIOCGETRULES _IOWR('D', 6, struct pfioc_rule)
+#define DIOCGETRULE _IOWR('D', 7, struct pfioc_rule)
+#define DIOCBEGINNATS _IOWR('D', 8, u_int32_t)
+#define DIOCADDNAT _IOWR('D', 9, struct pfioc_nat)
+#define DIOCCOMMITNATS _IOWR('D', 10, u_int32_t)
+#define DIOCGETNATS _IOWR('D', 11, struct pfioc_nat)
+#define DIOCGETNAT _IOWR('D', 12, struct pfioc_nat)
+#define DIOCBEGINRDRS _IOWR('D', 13, u_int32_t)
+#define DIOCADDRDR _IOWR('D', 14, struct pfioc_rdr)
+#define DIOCCOMMITRDRS _IOWR('D', 15, u_int32_t)
+#define DIOCGETRDRS _IOWR('D', 16, struct pfioc_rdr)
+#define DIOCGETRDR _IOWR('D', 17, struct pfioc_rdr)
+#define DIOCCLRSTATES _IO ('D', 18)
+#define DIOCGETSTATE _IOWR('D', 19, struct pfioc_state)
+#define DIOCSETSTATUSIF _IOWR('D', 20, struct pfioc_if)
+#define DIOCGETSTATUS _IOWR('D', 21, struct pf_status)
#ifdef _KERNEL