Changeset View
Changeset View
Standalone View
Standalone View
sbin/pfctl/pfctl.c
Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | |||||
int pfctl_load_debug(struct pfctl *, unsigned int); | int pfctl_load_debug(struct pfctl *, unsigned int); | ||||
int pfctl_load_logif(struct pfctl *, char *); | int pfctl_load_logif(struct pfctl *, char *); | ||||
int pfctl_load_hostid(struct pfctl *, u_int32_t); | int pfctl_load_hostid(struct pfctl *, u_int32_t); | ||||
int pfctl_load_syncookies(struct pfctl *, u_int8_t); | int pfctl_load_syncookies(struct pfctl *, u_int8_t); | ||||
int pfctl_get_pool(int, struct pfctl_pool *, u_int32_t, u_int32_t, int, | int pfctl_get_pool(int, struct pfctl_pool *, u_int32_t, u_int32_t, int, | ||||
char *); | char *); | ||||
void pfctl_print_eth_rule_counters(struct pfctl_eth_rule *, int); | void pfctl_print_eth_rule_counters(struct pfctl_eth_rule *, int); | ||||
void pfctl_print_rule_counters(struct pfctl_rule *, int); | void pfctl_print_rule_counters(struct pfctl_rule *, int); | ||||
int pfctl_show_eth_rules(int, int, enum pfctl_show); | int pfctl_show_eth_rules(int, char *, int, enum pfctl_show, char *, int); | ||||
int pfctl_show_rules(int, char *, int, enum pfctl_show, char *, int); | int pfctl_show_rules(int, char *, int, enum pfctl_show, char *, int); | ||||
int pfctl_show_nat(int, int, char *); | int pfctl_show_nat(int, int, char *); | ||||
int pfctl_show_src_nodes(int, int); | int pfctl_show_src_nodes(int, int); | ||||
int pfctl_show_states(int, const char *, int); | int pfctl_show_states(int, const char *, int); | ||||
int pfctl_show_status(int, int); | int pfctl_show_status(int, int); | ||||
int pfctl_show_running(int); | int pfctl_show_running(int); | ||||
int pfctl_show_timeouts(int, int); | int pfctl_show_timeouts(int, int); | ||||
int pfctl_show_limits(int, int); | int pfctl_show_limits(int, int); | ||||
void pfctl_debug(int, u_int32_t, int); | void pfctl_debug(int, u_int32_t, int); | ||||
int pfctl_test_altqsupport(int, int); | int pfctl_test_altqsupport(int, int); | ||||
int pfctl_show_anchors(int, int, char *); | int pfctl_show_anchors(int, int, char *); | ||||
int pfctl_ruleset_trans(struct pfctl *, char *, struct pfctl_anchor *); | int pfctl_ruleset_trans(struct pfctl *, char *, struct pfctl_anchor *, bool); | ||||
int pfctl_load_eth_ruleset(struct pfctl *); | int pfctl_eth_ruleset_trans(struct pfctl *, char *, | ||||
struct pfctl_eth_anchor *); | |||||
int pfctl_load_eth_ruleset(struct pfctl *, char *, | |||||
struct pfctl_eth_ruleset *, int); | |||||
int pfctl_load_eth_rule(struct pfctl *, char *, struct pfctl_eth_rule *, | |||||
int); | |||||
int pfctl_load_ruleset(struct pfctl *, char *, | int pfctl_load_ruleset(struct pfctl *, char *, | ||||
struct pfctl_ruleset *, int, int); | struct pfctl_ruleset *, int, int); | ||||
int pfctl_load_rule(struct pfctl *, char *, struct pfctl_rule *, int); | int pfctl_load_rule(struct pfctl *, char *, struct pfctl_rule *, int); | ||||
const char *pfctl_lookup_option(char *, const char * const *); | const char *pfctl_lookup_option(char *, const char * const *); | ||||
static struct pfctl_anchor_global pf_anchors; | static struct pfctl_anchor_global pf_anchors; | ||||
static struct pfctl_anchor pf_main_anchor; | struct pfctl_anchor pf_main_anchor; | ||||
struct pfctl_eth_anchor pf_eth_main_anchor; | |||||
static struct pfr_buffer skip_b; | static struct pfr_buffer skip_b; | ||||
static const char *clearopt; | static const char *clearopt; | ||||
static char *rulesopt; | static char *rulesopt; | ||||
static const char *showopt; | static const char *showopt; | ||||
static const char *debugopt; | static const char *debugopt; | ||||
static char *anchoropt; | static char *anchoropt; | ||||
static const char *optiopt = NULL; | static const char *optiopt = NULL; | ||||
▲ Show 20 Lines • Show All 917 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
if (!first_title) | if (!first_title) | ||||
printf("\n"); | printf("\n"); | ||||
first_title = 0; | first_title = 0; | ||||
printf("%s\n", title); | printf("%s\n", title); | ||||
} | } | ||||
int | int | ||||
pfctl_show_eth_rules(int dev, int opts, enum pfctl_show format) | pfctl_show_eth_rules(int dev, char *path, int opts, enum pfctl_show format, | ||||
char *anchorname, int depth) | |||||
{ | { | ||||
char anchor_call[MAXPATHLEN]; | |||||
struct pfctl_eth_rules_info info; | struct pfctl_eth_rules_info info; | ||||
struct pfctl_eth_rule rule; | struct pfctl_eth_rule rule; | ||||
int dotitle = opts & PF_OPT_SHOWALL; | int dotitle = opts & PF_OPT_SHOWALL; | ||||
int len = strlen(path); | |||||
int brace; | |||||
char *p; | |||||
if (pfctl_get_eth_rules_info(dev, &info)) { | if (path[0]) | ||||
snprintf(&path[len], MAXPATHLEN - len, "/%s", anchorname); | |||||
else | |||||
snprintf(&path[len], MAXPATHLEN - len, "%s", anchorname); | |||||
if (pfctl_get_eth_rules_info(dev, &info, path)) { | |||||
warn("DIOCGETETHRULES"); | warn("DIOCGETETHRULES"); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
for (int nr = 0; nr < info.nr; nr++) { | for (int nr = 0; nr < info.nr; nr++) { | ||||
if (pfctl_get_eth_rule(dev, nr, info.ticket, &rule, | brace = 0; | ||||
opts & PF_OPT_CLRRULECTRS) != 0) { | INDENT(depth, !(opts & PF_OPT_VERBOSE)); | ||||
if (pfctl_get_eth_rule(dev, nr, info.ticket, path, &rule, | |||||
opts & PF_OPT_CLRRULECTRS, anchor_call) != 0) { | |||||
warn("DIOCGETETHRULE"); | warn("DIOCGETETHRULE"); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
if (anchor_call[0] && | |||||
((((p = strrchr(anchor_call, '_')) != NULL) && | |||||
(p == anchor_call || | |||||
*(--p) == '/')) || (opts & PF_OPT_RECURSE))) { | |||||
brace++; | |||||
if ((p = strrchr(anchor_call, '/')) != | |||||
NULL) | |||||
p++; | |||||
else | |||||
p = &anchor_call[0]; | |||||
} else | |||||
p = &anchor_call[0]; | |||||
if (dotitle) { | if (dotitle) { | ||||
pfctl_print_title("ETH RULES:"); | pfctl_print_title("ETH RULES:"); | ||||
dotitle = 0; | dotitle = 0; | ||||
} | } | ||||
print_eth_rule(&rule, opts & (PF_OPT_VERBOSE2 | PF_OPT_DEBUG)); | print_eth_rule(&rule, anchor_call, | ||||
opts & (PF_OPT_VERBOSE2 | PF_OPT_DEBUG)); | |||||
if (brace) | |||||
printf(" {\n"); | |||||
else | |||||
printf("\n"); | printf("\n"); | ||||
pfctl_print_eth_rule_counters(&rule, opts); | pfctl_print_eth_rule_counters(&rule, opts); | ||||
if (brace) { | |||||
pfctl_show_eth_rules(dev, path, opts, format, | |||||
p, depth + 1); | |||||
INDENT(depth, !(opts & PF_OPT_VERBOSE)); | |||||
printf("}\n"); | |||||
} | } | ||||
} | |||||
path[len] = '\0'; | |||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format, | pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format, | ||||
char *anchorname, int depth) | char *anchorname, int depth) | ||||
{ | { | ||||
struct pfioc_rule pr; | struct pfioc_rule pr; | ||||
▲ Show 20 Lines • Show All 415 Lines • ▼ Show 20 Lines | pfctl_append_rule(struct pfctl *pf, struct pfctl_rule *r, | ||||
TAILQ_INIT(&rule->rpool.list); | TAILQ_INIT(&rule->rpool.list); | ||||
pfctl_move_pool(&r->rpool, &rule->rpool); | pfctl_move_pool(&r->rpool, &rule->rpool); | ||||
TAILQ_INSERT_TAIL(rs->rules[rs_num].active.ptr, rule, entries); | TAILQ_INSERT_TAIL(rs->rules[rs_num].active.ptr, rule, entries); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
pfctl_ruleset_trans(struct pfctl *pf, char *path, struct pfctl_anchor *a) | pfctl_append_eth_rule(struct pfctl *pf, struct pfctl_eth_rule *r, | ||||
const char *anchor_call) | |||||
{ | { | ||||
struct pfctl_eth_rule *rule; | |||||
struct pfctl_eth_ruleset *rs; | |||||
char *p; | |||||
rs = &pf->eanchor->ruleset; | |||||
if (anchor_call[0] && r->anchor == NULL) { | |||||
/* | |||||
* Don't make non-brace anchors part of the main anchor pool. | |||||
*/ | |||||
if ((r->anchor = calloc(1, sizeof(*r->anchor))) == NULL) | |||||
err(1, "pfctl_append_rule: calloc"); | |||||
pf_init_eth_ruleset(&r->anchor->ruleset); | |||||
r->anchor->ruleset.anchor = r->anchor; | |||||
if (strlcpy(r->anchor->path, anchor_call, | |||||
sizeof(rule->anchor->path)) >= sizeof(rule->anchor->path)) | |||||
errx(1, "pfctl_append_rule: strlcpy"); | |||||
if ((p = strrchr(anchor_call, '/')) != NULL) { | |||||
if (!strlen(p)) | |||||
err(1, "pfctl_append_eth_rule: bad anchor name %s", | |||||
anchor_call); | |||||
} else | |||||
p = (char *)anchor_call; | |||||
if (strlcpy(r->anchor->name, p, | |||||
sizeof(rule->anchor->name)) >= sizeof(rule->anchor->name)) | |||||
errx(1, "pfctl_append_eth_rule: strlcpy"); | |||||
} | |||||
if ((rule = calloc(1, sizeof(*rule))) == NULL) | |||||
err(1, "calloc"); | |||||
bcopy(r, rule, sizeof(*rule)); | |||||
TAILQ_INSERT_TAIL(&rs->rules, rule, entries); | |||||
return (0); | |||||
} | |||||
int | |||||
pfctl_eth_ruleset_trans(struct pfctl *pf, char *path, | |||||
struct pfctl_eth_anchor *a) | |||||
{ | |||||
int osize = pf->trans->pfrb_size; | int osize = pf->trans->pfrb_size; | ||||
if ((pf->loadopt & PFCTL_FLAG_ETH) != 0) { | if ((pf->loadopt & PFCTL_FLAG_ETH) != 0) { | ||||
if (! path[0]) { | |||||
if (pfctl_add_trans(pf->trans, PF_RULESET_ETH, path)) | if (pfctl_add_trans(pf->trans, PF_RULESET_ETH, path)) | ||||
return (1); | return (1); | ||||
} | } | ||||
if (pfctl_trans(pf->dev, pf->trans, DIOCXBEGIN, osize)) | |||||
return (5); | |||||
return (0); | |||||
} | } | ||||
int | |||||
pfctl_ruleset_trans(struct pfctl *pf, char *path, struct pfctl_anchor *a, bool do_eth) | |||||
{ | |||||
int osize = pf->trans->pfrb_size; | |||||
if ((pf->loadopt & PFCTL_FLAG_ETH) != 0 && do_eth) { | |||||
if (pfctl_add_trans(pf->trans, PF_RULESET_ETH, path)) | |||||
return (1); | |||||
} | |||||
if ((pf->loadopt & PFCTL_FLAG_NAT) != 0) { | if ((pf->loadopt & PFCTL_FLAG_NAT) != 0) { | ||||
if (pfctl_add_trans(pf->trans, PF_RULESET_NAT, path) || | if (pfctl_add_trans(pf->trans, PF_RULESET_NAT, path) || | ||||
pfctl_add_trans(pf->trans, PF_RULESET_BINAT, path) || | pfctl_add_trans(pf->trans, PF_RULESET_BINAT, path) || | ||||
pfctl_add_trans(pf->trans, PF_RULESET_RDR, path)) | pfctl_add_trans(pf->trans, PF_RULESET_RDR, path)) | ||||
return (1); | return (1); | ||||
} | } | ||||
if (a == pf->astack[0] && ((altqsupport && | if (a == pf->astack[0] && ((altqsupport && | ||||
(pf->loadopt & PFCTL_FLAG_ALTQ) != 0))) { | (pf->loadopt & PFCTL_FLAG_ALTQ) != 0))) { | ||||
Show All 10 Lines | if (pfctl_add_trans(pf->trans, PF_RULESET_TABLE, path)) | ||||
return (4); | return (4); | ||||
if (pfctl_trans(pf->dev, pf->trans, DIOCXBEGIN, osize)) | if (pfctl_trans(pf->dev, pf->trans, DIOCXBEGIN, osize)) | ||||
return (5); | return (5); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
pfctl_load_eth_ruleset(struct pfctl *pf) | pfctl_load_eth_ruleset(struct pfctl *pf, char *path, | ||||
struct pfctl_eth_ruleset *rs, int depth) | |||||
{ | { | ||||
struct pfctl_eth_rule *r; | struct pfctl_eth_rule *r; | ||||
int error; | int error, len = strlen(path); | ||||
int brace = 0; | |||||
while ((r = TAILQ_FIRST(&pf->eth_rules)) != NULL) { | pf->eanchor = rs->anchor; | ||||
TAILQ_REMOVE(&pf->eth_rules, r, entries); | if (path[0]) | ||||
snprintf(&path[len], MAXPATHLEN - len, "/%s", pf->eanchor->name); | |||||
else | |||||
snprintf(&path[len], MAXPATHLEN - len, "%s", pf->eanchor->name); | |||||
if ((pf->opts & PF_OPT_NOACTION) == 0) { | if (depth) { | ||||
error = pfctl_add_eth_rule(pf->dev, r, pf->eth_ticket); | if (TAILQ_FIRST(&rs->rules) != NULL) { | ||||
brace++; | |||||
if (pf->opts & PF_OPT_VERBOSE) | |||||
printf(" {\n"); | |||||
if ((pf->opts & PF_OPT_NOACTION) == 0 && | |||||
(error = pfctl_eth_ruleset_trans(pf, | |||||
path, rs->anchor))) { | |||||
printf("pfctl_load_eth_rulesets: " | |||||
"pfctl_eth_ruleset_trans %d\n", error); | |||||
goto error; | |||||
} | |||||
} else if (pf->opts & PF_OPT_VERBOSE) | |||||
printf("\n"); | |||||
} | |||||
while ((r = TAILQ_FIRST(&rs->rules)) != NULL) { | |||||
TAILQ_REMOVE(&rs->rules, r, entries); | |||||
error = pfctl_load_eth_rule(pf, path, r, depth); | |||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
} | |||||
if (r->anchor) { | |||||
if ((error = pfctl_load_eth_ruleset(pf, path, | |||||
&r->anchor->ruleset, depth + 1))) | |||||
return (error); | |||||
} | |||||
free(r); | free(r); | ||||
} | } | ||||
if (brace && pf->opts & PF_OPT_VERBOSE) { | |||||
INDENT(depth - 1, (pf->opts & PF_OPT_VERBOSE)); | |||||
printf("}\n"); | |||||
} | |||||
path[len] = '\0'; | |||||
return (0); | return (0); | ||||
error: | |||||
path[len] = '\0'; | |||||
return (error); | |||||
} | } | ||||
int | int | ||||
pfctl_load_eth_rule(struct pfctl *pf, char *path, struct pfctl_eth_rule *r, | |||||
int depth) | |||||
{ | |||||
char *name; | |||||
char anchor[PF_ANCHOR_NAME_SIZE]; | |||||
int len = strlen(path); | |||||
if (strlcpy(anchor, path, sizeof(anchor)) >= sizeof(anchor)) | |||||
errx(1, "pfctl_load_eth_rule: strlcpy"); | |||||
if (r->anchor) { | |||||
if (r->anchor->match) { | |||||
if (path[0]) | |||||
snprintf(&path[len], MAXPATHLEN - len, | |||||
"/%s", r->anchor->name); | |||||
else | |||||
snprintf(&path[len], MAXPATHLEN - len, | |||||
"%s", r->anchor->name); | |||||
name = r->anchor->name; | |||||
} else | |||||
name = r->anchor->path; | |||||
} else | |||||
name = ""; | |||||
if ((pf->opts & PF_OPT_NOACTION) == 0) | |||||
if (pfctl_add_eth_rule(pf->dev, r, anchor, name, | |||||
pf->eth_ticket)) | |||||
err(1, "DIOCADDETHRULENV"); | |||||
path[len] = '\0'; | |||||
return (0); | |||||
} | |||||
int | |||||
pfctl_load_ruleset(struct pfctl *pf, char *path, struct pfctl_ruleset *rs, | pfctl_load_ruleset(struct pfctl *pf, char *path, struct pfctl_ruleset *rs, | ||||
int rs_num, int depth) | int rs_num, int depth) | ||||
{ | { | ||||
struct pfctl_rule *r; | struct pfctl_rule *r; | ||||
int error, len = strlen(path); | int error, len = strlen(path); | ||||
int brace = 0; | int brace = 0; | ||||
pf->anchor = rs->anchor; | pf->anchor = rs->anchor; | ||||
if (path[0]) | if (path[0]) | ||||
snprintf(&path[len], MAXPATHLEN - len, "/%s", pf->anchor->name); | snprintf(&path[len], MAXPATHLEN - len, "/%s", pf->anchor->name); | ||||
else | else | ||||
snprintf(&path[len], MAXPATHLEN - len, "%s", pf->anchor->name); | snprintf(&path[len], MAXPATHLEN - len, "%s", pf->anchor->name); | ||||
if (depth) { | if (depth) { | ||||
if (TAILQ_FIRST(rs->rules[rs_num].active.ptr) != NULL) { | if (TAILQ_FIRST(rs->rules[rs_num].active.ptr) != NULL) { | ||||
brace++; | brace++; | ||||
if (pf->opts & PF_OPT_VERBOSE) | if (pf->opts & PF_OPT_VERBOSE) | ||||
printf(" {\n"); | printf(" {\n"); | ||||
if ((pf->opts & PF_OPT_NOACTION) == 0 && | if ((pf->opts & PF_OPT_NOACTION) == 0 && | ||||
(error = pfctl_ruleset_trans(pf, | (error = pfctl_ruleset_trans(pf, | ||||
path, rs->anchor))) { | path, rs->anchor, false))) { | ||||
printf("pfctl_load_rulesets: " | printf("pfctl_load_rulesets: " | ||||
"pfctl_ruleset_trans %d\n", error); | "pfctl_ruleset_trans %d\n", error); | ||||
goto error; | goto error; | ||||
} | } | ||||
} else if (pf->opts & PF_OPT_VERBOSE) | } else if (pf->opts & PF_OPT_VERBOSE) | ||||
printf("\n"); | printf("\n"); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
#define ERR(x) do { warn(x); goto _error; } while(0) | #define ERR(x) do { warn(x); goto _error; } while(0) | ||||
#define ERRX(x) do { warnx(x); goto _error; } while(0) | #define ERRX(x) do { warnx(x); goto _error; } while(0) | ||||
struct pfr_buffer *t, buf; | struct pfr_buffer *t, buf; | ||||
struct pfioc_altq pa; | struct pfioc_altq pa; | ||||
struct pfctl pf; | struct pfctl pf; | ||||
struct pfctl_ruleset *rs; | struct pfctl_ruleset *rs; | ||||
struct pfctl_eth_ruleset *ethrs; | |||||
struct pfr_table trs; | struct pfr_table trs; | ||||
char *path; | char *path; | ||||
int osize; | int osize; | ||||
RB_INIT(&pf_anchors); | RB_INIT(&pf_anchors); | ||||
memset(&pf_main_anchor, 0, sizeof(pf_main_anchor)); | memset(&pf_main_anchor, 0, sizeof(pf_main_anchor)); | ||||
pf_init_ruleset(&pf_main_anchor.ruleset); | pf_init_ruleset(&pf_main_anchor.ruleset); | ||||
pf_main_anchor.ruleset.anchor = &pf_main_anchor; | pf_main_anchor.ruleset.anchor = &pf_main_anchor; | ||||
memset(&pf_eth_main_anchor, 0, sizeof(pf_eth_main_anchor)); | |||||
pf_init_eth_ruleset(&pf_eth_main_anchor.ruleset); | |||||
pf_eth_main_anchor.ruleset.anchor = &pf_eth_main_anchor; | |||||
if (trans == NULL) { | if (trans == NULL) { | ||||
bzero(&buf, sizeof(buf)); | bzero(&buf, sizeof(buf)); | ||||
buf.pfrb_type = PFRB_TRANS; | buf.pfrb_type = PFRB_TRANS; | ||||
t = &buf; | t = &buf; | ||||
osize = 0; | osize = 0; | ||||
} else { | } else { | ||||
t = trans; | t = trans; | ||||
osize = t->pfrb_size; | osize = t->pfrb_size; | ||||
} | } | ||||
memset(&pa, 0, sizeof(pa)); | memset(&pa, 0, sizeof(pa)); | ||||
pa.version = PFIOC_ALTQ_VERSION; | pa.version = PFIOC_ALTQ_VERSION; | ||||
memset(&pf, 0, sizeof(pf)); | memset(&pf, 0, sizeof(pf)); | ||||
memset(&trs, 0, sizeof(trs)); | memset(&trs, 0, sizeof(trs)); | ||||
if ((path = calloc(1, MAXPATHLEN)) == NULL) | if ((path = calloc(1, MAXPATHLEN)) == NULL) | ||||
ERRX("pfctl_rules: calloc"); | ERRX("pfctl_rules: calloc"); | ||||
if (strlcpy(trs.pfrt_anchor, anchorname, | if (strlcpy(trs.pfrt_anchor, anchorname, | ||||
sizeof(trs.pfrt_anchor)) >= sizeof(trs.pfrt_anchor)) | sizeof(trs.pfrt_anchor)) >= sizeof(trs.pfrt_anchor)) | ||||
ERRX("pfctl_rules: strlcpy"); | ERRX("pfctl_rules: strlcpy"); | ||||
pf.dev = dev; | pf.dev = dev; | ||||
pf.opts = opts; | pf.opts = opts; | ||||
pf.optimize = optimize; | pf.optimize = optimize; | ||||
pf.loadopt = loadopt; | pf.loadopt = loadopt; | ||||
TAILQ_INIT(&pf.eth_rules); | |||||
/* non-brace anchor, create without resolving the path */ | /* non-brace anchor, create without resolving the path */ | ||||
if ((pf.anchor = calloc(1, sizeof(*pf.anchor))) == NULL) | if ((pf.anchor = calloc(1, sizeof(*pf.anchor))) == NULL) | ||||
ERRX("pfctl_rules: calloc"); | ERRX("pfctl_rules: calloc"); | ||||
rs = &pf.anchor->ruleset; | rs = &pf.anchor->ruleset; | ||||
pf_init_ruleset(rs); | pf_init_ruleset(rs); | ||||
rs->anchor = pf.anchor; | rs->anchor = pf.anchor; | ||||
if (strlcpy(pf.anchor->path, anchorname, | if (strlcpy(pf.anchor->path, anchorname, | ||||
sizeof(pf.anchor->path)) >= sizeof(pf.anchor->path)) | sizeof(pf.anchor->path)) >= sizeof(pf.anchor->path)) | ||||
errx(1, "pfctl_add_rule: strlcpy"); | errx(1, "pfctl_rules: strlcpy"); | ||||
if (strlcpy(pf.anchor->name, anchorname, | if (strlcpy(pf.anchor->name, anchorname, | ||||
sizeof(pf.anchor->name)) >= sizeof(pf.anchor->name)) | sizeof(pf.anchor->name)) >= sizeof(pf.anchor->name)) | ||||
errx(1, "pfctl_add_rule: strlcpy"); | errx(1, "pfctl_rules: strlcpy"); | ||||
pf.astack[0] = pf.anchor; | pf.astack[0] = pf.anchor; | ||||
pf.asd = 0; | pf.asd = 0; | ||||
if (anchorname[0]) | if (anchorname[0]) | ||||
pf.loadopt &= ~PFCTL_FLAG_ALTQ; | pf.loadopt &= ~PFCTL_FLAG_ALTQ; | ||||
pf.paltq = &pa; | pf.paltq = &pa; | ||||
pf.trans = t; | pf.trans = t; | ||||
pfctl_init_options(&pf); | pfctl_init_options(&pf); | ||||
/* Set up ethernet anchor */ | |||||
if ((pf.eanchor = calloc(1, sizeof(*pf.eanchor))) == NULL) | |||||
ERRX("pfctl_rules: calloc"); | |||||
if (strlcpy(pf.eanchor->path, anchorname, | |||||
sizeof(pf.eanchor->path)) >= sizeof(pf.eanchor->path)) | |||||
errx(1, "pfctl_rules: strlcpy"); | |||||
if (strlcpy(pf.eanchor->name, anchorname, | |||||
sizeof(pf.eanchor->name)) >= sizeof(pf.eanchor->name)) | |||||
errx(1, "pfctl_rules: strlcpy"); | |||||
ethrs = &pf.eanchor->ruleset; | |||||
pf_init_eth_ruleset(ethrs); | |||||
ethrs->anchor = pf.eanchor; | |||||
pf.eastack[0] = pf.eanchor; | |||||
if ((opts & PF_OPT_NOACTION) == 0) { | if ((opts & PF_OPT_NOACTION) == 0) { | ||||
/* | /* | ||||
* XXX For the time being we need to open transactions for | * XXX For the time being we need to open transactions for | ||||
* the main ruleset before parsing, because tables are still | * the main ruleset before parsing, because tables are still | ||||
* loaded at parse time. | * loaded at parse time. | ||||
*/ | */ | ||||
if (pfctl_ruleset_trans(&pf, anchorname, pf.anchor)) | if (pfctl_ruleset_trans(&pf, anchorname, pf.anchor, true)) | ||||
ERRX("pfctl_rules"); | ERRX("pfctl_rules"); | ||||
if (pf.loadopt & PFCTL_FLAG_ETH) | if (pf.loadopt & PFCTL_FLAG_ETH) | ||||
pf.eth_ticket = pfctl_get_ticket(t, PF_RULESET_ETH, anchorname); | pf.eth_ticket = pfctl_get_ticket(t, PF_RULESET_ETH, anchorname); | ||||
if (altqsupport && (pf.loadopt & PFCTL_FLAG_ALTQ)) | if (altqsupport && (pf.loadopt & PFCTL_FLAG_ALTQ)) | ||||
pa.ticket = | pa.ticket = | ||||
pfctl_get_ticket(t, PF_RULESET_ALTQ, anchorname); | pfctl_get_ticket(t, PF_RULESET_ALTQ, anchorname); | ||||
if (pf.loadopt & PFCTL_FLAG_TABLE) | if (pf.loadopt & PFCTL_FLAG_TABLE) | ||||
pf.astack[0]->ruleset.tticket = | pf.astack[0]->ruleset.tticket = | ||||
pfctl_get_ticket(t, PF_RULESET_TABLE, anchorname); | pfctl_get_ticket(t, PF_RULESET_TABLE, anchorname); | ||||
} | } | ||||
if (parse_config(filename, &pf) < 0) { | if (parse_config(filename, &pf) < 0) { | ||||
if ((opts & PF_OPT_NOACTION) == 0) | if ((opts & PF_OPT_NOACTION) == 0) | ||||
ERRX("Syntax error in config file: " | ERRX("Syntax error in config file: " | ||||
"pf rules not loaded"); | "pf rules not loaded"); | ||||
else | else | ||||
goto _error; | goto _error; | ||||
} | } | ||||
if (loadopt & PFCTL_FLAG_OPTION) | if (loadopt & PFCTL_FLAG_OPTION) | ||||
pfctl_adjust_skip_ifaces(&pf); | pfctl_adjust_skip_ifaces(&pf); | ||||
if ((pf.loadopt & PFCTL_FLAG_FILTER && | if ((pf.loadopt & PFCTL_FLAG_FILTER && | ||||
(pfctl_load_ruleset(&pf, path, rs, PF_RULESET_SCRUB, 0))) || | (pfctl_load_ruleset(&pf, path, rs, PF_RULESET_SCRUB, 0))) || | ||||
(pf.loadopt & PFCTL_FLAG_ETH && | (pf.loadopt & PFCTL_FLAG_ETH && | ||||
(pfctl_load_eth_ruleset(&pf))) || | (pfctl_load_eth_ruleset(&pf, path, ethrs, 0))) || | ||||
(pf.loadopt & PFCTL_FLAG_NAT && | (pf.loadopt & PFCTL_FLAG_NAT && | ||||
(pfctl_load_ruleset(&pf, path, rs, PF_RULESET_NAT, 0) || | (pfctl_load_ruleset(&pf, path, rs, PF_RULESET_NAT, 0) || | ||||
pfctl_load_ruleset(&pf, path, rs, PF_RULESET_RDR, 0) || | pfctl_load_ruleset(&pf, path, rs, PF_RULESET_RDR, 0) || | ||||
pfctl_load_ruleset(&pf, path, rs, PF_RULESET_BINAT, 0))) || | pfctl_load_ruleset(&pf, path, rs, PF_RULESET_BINAT, 0))) || | ||||
(pf.loadopt & PFCTL_FLAG_FILTER && | (pf.loadopt & PFCTL_FLAG_FILTER && | ||||
pfctl_load_ruleset(&pf, path, rs, PF_RULESET_FILTER, 0))) { | pfctl_load_ruleset(&pf, path, rs, PF_RULESET_FILTER, 0))) { | ||||
if ((opts & PF_OPT_NOACTION) == 0) | if ((opts & PF_OPT_NOACTION) == 0) | ||||
ERRX("Unable to load rules into kernel"); | ERRX("Unable to load rules into kernel"); | ||||
▲ Show 20 Lines • Show All 758 Lines • ▼ Show 20 Lines | if (anchoropt[len - 1] == '*') { | ||||
else | else | ||||
anchoropt[len - 1] = '\0'; | anchoropt[len - 1] = '\0'; | ||||
opts |= PF_OPT_RECURSE; | opts |= PF_OPT_RECURSE; | ||||
} | } | ||||
if (strlcpy(anchorname, anchoropt, | if (strlcpy(anchorname, anchoropt, | ||||
sizeof(anchorname)) >= sizeof(anchorname)) | sizeof(anchorname)) >= sizeof(anchorname)) | ||||
errx(1, "anchor name '%s' too long", | errx(1, "anchor name '%s' too long", | ||||
anchoropt); | anchoropt); | ||||
loadopt &= PFCTL_FLAG_FILTER|PFCTL_FLAG_NAT|PFCTL_FLAG_TABLE; | loadopt &= PFCTL_FLAG_FILTER|PFCTL_FLAG_NAT|PFCTL_FLAG_TABLE|PFCTL_FLAG_ETH; | ||||
} | } | ||||
if ((opts & PF_OPT_NOACTION) == 0) { | if ((opts & PF_OPT_NOACTION) == 0) { | ||||
dev = open(pf_device, mode); | dev = open(pf_device, mode); | ||||
if (dev == -1) | if (dev == -1) | ||||
err(1, "%s", pf_device); | err(1, "%s", pf_device); | ||||
altqsupport = pfctl_test_altqsupport(dev, opts); | altqsupport = pfctl_test_altqsupport(dev, opts); | ||||
} else { | } else { | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | case 'R': | ||||
break; | break; | ||||
case 't': | case 't': | ||||
pfctl_show_timeouts(dev, opts); | pfctl_show_timeouts(dev, opts); | ||||
break; | break; | ||||
case 'm': | case 'm': | ||||
pfctl_show_limits(dev, opts); | pfctl_show_limits(dev, opts); | ||||
break; | break; | ||||
case 'e': | case 'e': | ||||
pfctl_show_eth_rules(dev, opts, 0); | pfctl_show_eth_rules(dev, path, opts, 0, anchorname, 0); | ||||
break; | break; | ||||
case 'a': | case 'a': | ||||
opts |= PF_OPT_SHOWALL; | opts |= PF_OPT_SHOWALL; | ||||
pfctl_load_fingerprints(dev, opts); | pfctl_load_fingerprints(dev, opts); | ||||
pfctl_show_eth_rules(dev, opts, 0); | pfctl_show_eth_rules(dev, path, opts, 0, anchorname, 0); | ||||
pfctl_show_nat(dev, opts, anchorname); | pfctl_show_nat(dev, opts, anchorname); | ||||
pfctl_show_rules(dev, path, opts, 0, anchorname, 0); | pfctl_show_rules(dev, path, opts, 0, anchorname, 0); | ||||
pfctl_show_altq(dev, ifaceopt, opts, 0); | pfctl_show_altq(dev, ifaceopt, opts, 0); | ||||
pfctl_show_states(dev, ifaceopt, opts); | pfctl_show_states(dev, ifaceopt, opts); | ||||
pfctl_show_src_nodes(dev, opts); | pfctl_show_src_nodes(dev, opts); | ||||
pfctl_show_status(dev, opts); | pfctl_show_status(dev, opts); | ||||
pfctl_show_rules(dev, path, opts, 1, anchorname, 0); | pfctl_show_rules(dev, path, opts, 1, anchorname, 0); | ||||
Show All 11 Lines | case 'o': | ||||
break; | break; | ||||
case 'I': | case 'I': | ||||
pfctl_show_ifaces(ifaceopt, opts); | pfctl_show_ifaces(ifaceopt, opts); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if ((opts & PF_OPT_CLRRULECTRS) && showopt == NULL) { | if ((opts & PF_OPT_CLRRULECTRS) && showopt == NULL) { | ||||
pfctl_show_eth_rules(dev, opts, PFCTL_SHOW_NOTHING); | pfctl_show_eth_rules(dev, path, opts, PFCTL_SHOW_NOTHING, | ||||
anchorname, 0); | |||||
pfctl_show_rules(dev, path, opts, PFCTL_SHOW_NOTHING, | pfctl_show_rules(dev, path, opts, PFCTL_SHOW_NOTHING, | ||||
anchorname, 0); | anchorname, 0); | ||||
} | } | ||||
if (clearopt != NULL) { | if (clearopt != NULL) { | ||||
if (anchorname[0] == '_' || strstr(anchorname, "/_") != NULL) | if (anchorname[0] == '_' || strstr(anchorname, "/_") != NULL) | ||||
errx(1, "anchor names beginning with '_' cannot " | errx(1, "anchor names beginning with '_' cannot " | ||||
"be modified from the command line"); | "be modified from the command line"); | ||||
▲ Show 20 Lines • Show All 120 Lines • Show Last 20 Lines |