diff --git a/contrib/pf/ftp-proxy/filter.c b/contrib/pf/ftp-proxy/filter.c index 4277e079f3b..612e35c4ac6 100644 --- a/contrib/pf/ftp-proxy/filter.c +++ b/contrib/pf/ftp-proxy/filter.c @@ -58,6 +58,7 @@ static uint32_t pfpool_ticket; static struct pfioc_trans pft; static struct pfioc_trans_e pfte[TRANS_SIZE]; static int dev, rule_log; +static struct pfctl_handle *pfh = NULL; static const char *qname, *tagname; int @@ -73,7 +74,7 @@ add_filter(u_int32_t id, u_int8_t dir, struct sockaddr *src, return (-1); pfrule.direction = dir; - if (pfctl_add_rule(dev, &pfrule, pfanchor, pfanchor_call, + if (pfctl_add_rule_h(pfh, &pfrule, pfanchor, pfanchor_call, pfticket, pfpool_ticket)) return (-1); @@ -108,7 +109,7 @@ add_nat(u_int32_t id, struct sockaddr *src, struct sockaddr *dst, pfrule.rpool.proxy_port[0] = nat_range_low; pfrule.rpool.proxy_port[1] = nat_range_high; - if (pfctl_add_rule(dev, &pfrule, pfanchor, pfanchor_call, + if (pfctl_add_rule_h(pfh, &pfrule, pfanchor, pfanchor_call, pfticket, pfpool_ticket)) return (-1); @@ -141,7 +142,7 @@ add_rdr(u_int32_t id, struct sockaddr *src, struct sockaddr *dst, return (-1); pfrule.rpool.proxy_port[0] = rdr_port; - if (pfctl_add_rule(dev, &pfrule, pfanchor, pfanchor_call, + if (pfctl_add_rule_h(pfh, &pfrule, pfanchor, pfanchor_call, pfticket, pfpool_ticket)) return (-1); @@ -182,6 +183,9 @@ init_filter(const char *opt_qname, const char *opt_tagname, int opt_verbose) dev = open("/dev/pf", O_RDWR); if (dev == -1) err(1, "open /dev/pf"); + pfh = pfctl_open(PF_DEVICE); + if (pfh == NULL) + err(1, "pfctl_open"); status = pfctl_get_status(dev); if (status == NULL) err(1, "DIOCGETSTATUS"); diff --git a/contrib/pf/tftp-proxy/filter.c b/contrib/pf/tftp-proxy/filter.c index 966628464d2..f372ddd0aea 100644 --- a/contrib/pf/tftp-proxy/filter.c +++ b/contrib/pf/tftp-proxy/filter.c @@ -62,6 +62,7 @@ static char pfanchor_call[PF_ANCHOR_NAME_SIZE]; static struct pfioc_trans pft; static struct pfioc_trans_e pfte[TRANS_SIZE]; static int dev, rule_log; +static struct pfctl_handle *pfh = NULL; static char *qname; int @@ -77,7 +78,7 @@ add_filter(u_int32_t id, u_int8_t dir, struct sockaddr *src, return (-1); pfrule.direction = dir; - if (pfctl_add_rule(dev, &pfrule, pfanchor, pfanchor_call, + if (pfctl_add_rule_h(pfh, &pfrule, pfanchor, pfanchor_call, pfticket, pfpool_ticket)) return (-1); @@ -112,7 +113,7 @@ add_nat(u_int32_t id, struct sockaddr *src, struct sockaddr *dst, pfrule.rpool.proxy_port[0] = nat_range_low; pfrule.rpool.proxy_port[1] = nat_range_high; - if (pfctl_add_rule(dev, &pfrule, pfanchor, pfanchor_call, + if (pfctl_add_rule_h(pfh, &pfrule, pfanchor, pfanchor_call, pfticket, pfpool_ticket)) return (-1); @@ -145,7 +146,7 @@ add_rdr(u_int32_t id, struct sockaddr *src, struct sockaddr *dst, return (-1); pfrule.rpool.proxy_port[0] = rdr_port; - if (pfctl_add_rule(dev, &pfrule, pfanchor, pfanchor_call, + if (pfctl_add_rule_h(pfh, &pfrule, pfanchor, pfanchor_call, pfticket, pfpool_ticket)) return (-1); @@ -187,6 +188,11 @@ init_filter(char *opt_qname, int opt_verbose) syslog(LOG_ERR, "can't open /dev/pf"); exit(1); } + pfh = pfctl_open(PF_DEVICE); + if (pfh == NULL) { + syslog(LOG_ERR, "can't pfctl_open()"); + exit(1); + } status = pfctl_get_status(dev); if (status == NULL) { syslog(LOG_ERR, "DIOCGETSTATUS"); diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index 94949a5a733..2db3f0ede99 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -1116,20 +1116,37 @@ snl_add_msg_attr_pf_rule(struct snl_writer *nw, uint32_t type, const struct pfct int pfctl_add_rule(int dev __unused, const struct pfctl_rule *r, const char *anchor, const char *anchor_call, uint32_t ticket, uint32_t pool_ticket) +{ + struct pfctl_handle *h; + int ret; + + h = pfctl_open(PF_DEVICE); + if (h == NULL) + return (ENODEV); + + ret = pfctl_add_rule_h(h, r, anchor, anchor_call, ticket, pool_ticket); + + pfctl_close(h); + + return (ret); +} + +int +pfctl_add_rule_h(struct pfctl_handle *h, const struct pfctl_rule *r, + const char *anchor, const char *anchor_call, uint32_t ticket, + uint32_t pool_ticket) { struct snl_writer nw; - struct snl_state ss = {}; struct snl_errmsg_data e = {}; struct nlmsghdr *hdr; uint32_t seq_id; int family_id; - snl_init(&ss, NETLINK_GENERIC); - family_id = snl_get_genl_family(&ss, PFNL_FAMILY_NAME); + family_id = snl_get_genl_family(&h->ss, PFNL_FAMILY_NAME); if (family_id == 0) return (ENOTSUP); - snl_init_writer(&ss, &nw); + snl_init_writer(&h->ss, &nw); hdr = snl_create_genl_msg_request(&nw, family_id, PFNL_CMD_ADDRULE); hdr->nlmsg_flags |= NLM_F_DUMP; snl_add_msg_attr_u32(&nw, PF_ART_TICKET, ticket); @@ -1144,10 +1161,10 @@ pfctl_add_rule(int dev __unused, const struct pfctl_rule *r, const char *anchor, seq_id = hdr->nlmsg_seq; - if (! snl_send_message(&ss, hdr)) + if (! snl_send_message(&h->ss, hdr)) return (ENXIO); - while ((hdr = snl_read_reply_multi(&ss, seq_id, &e)) != NULL) { + while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) { } return (e.error); diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h index f128e534089..cd72d04d671 100644 --- a/lib/libpfctl/libpfctl.h +++ b/lib/libpfctl/libpfctl.h @@ -421,6 +421,9 @@ int pfctl_get_clear_rule(int dev, uint32_t nr, uint32_t ticket, int pfctl_add_rule(int dev, const struct pfctl_rule *r, const char *anchor, const char *anchor_call, uint32_t ticket, uint32_t pool_ticket); +int pfctl_add_rule_h(struct pfctl_handle *h, const struct pfctl_rule *r, + const char *anchor, const char *anchor_call, uint32_t ticket, + uint32_t pool_ticket); int pfctl_set_keepcounters(int dev, bool keep); int pfctl_get_creatorids(struct pfctl_handle *h, uint32_t *creators, size_t *len);