summaryrefslogtreecommitdiff
path: root/sbin/pfctl/pfctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/pfctl/pfctl.c')
-rw-r--r--sbin/pfctl/pfctl.c228
1 files changed, 93 insertions, 135 deletions
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index f93d1d1756a..7b16417fb30 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.c,v 1.27 2001/07/05 11:40:25 ho Exp $ */
+/* $OpenBSD: pfctl.c,v 1.28 2001/07/16 21:09:37 markus Exp $ */
/*
* Copyright (c) 2001, Daniel Hartmeier
@@ -54,7 +54,6 @@
#define PF_OPT_QUIET 0x0010
void usage(void);
-char *load_file(char *, size_t *);
int pfctl_enable(int, int);
int pfctl_disable(int, int);
int pfctl_clear_stats(int, int);
@@ -84,73 +83,6 @@ usage()
exit(1);
}
-char *
-load_file(char *name, size_t *len)
-{
- FILE *file;
- char *buf = 0, *buf2 = 0;
- u_int32_t i;
-
- if (!strcmp(name, "-"))
- file = stdin;
- else
- file = fopen(name, "r");
-
- *len = 0;
- if (file == NULL) {
- fprintf(stderr, "ERROR: couldn't open file %s (%s)\n",
- name, strerror(errno));
- return (0);
- }
-
- i = 512; /* Start with this. Grow it as req'd */
- *len = 0;
- if ((buf = malloc(i)) == NULL) {
- fprintf(stderr, "ERROR: could not allocate space "
- "for rules file\n");
- return (0);
- }
- while (!feof(file)) {
- *len += fread((buf + *len), 1, (i - *len), file);
- if (*len == i) {
- /* Out of space - realloc time */
- i *= 2;
- if ((buf2 = realloc(buf, i)) == NULL) {
- if (buf)
- free(buf);
- buf = NULL;
- fprintf(stderr, "ERROR: realloc of "
- "stdin buffer failed\n");
- return (0);
- }
- buf = buf2;
- }
- }
- if (*len == i) {
- /*
- * file is exactly the size of our buffer.
- * grow ours one so we can null terminate it
- */
- if ((buf2 = realloc(buf, i+1)) == NULL) {
- if (buf)
- free(buf);
- buf = NULL;
- fprintf(stderr, "ERROR: realloc of "
- "stdin buffer failed\n");
- return (0);
- }
- buf = buf2;
- }
- if (file != stdin)
- fclose(file);
- buf[*len]='\0';
- if (strlen(buf) != *len) {
- fprintf(stderr, "WARNING: nulls embedded in rules file\n");
- *len = strlen(buf);
- }
- return (buf);
-}
-
int
pfctl_enable(int dev, int opts)
{
@@ -303,56 +235,97 @@ pfctl_show_status(int dev)
return (0);
}
+/* callbacks for rule/nat/rdr */
+
int
-pfctl_rules(int dev, char *filename, int opts)
+pfctl_add_rule(struct pfctl *pf, struct pf_rule *r)
{
- struct pfioc_rule pr;
- char *buf, *s;
- size_t len;
- unsigned n, nr;
+ memcpy(&pf->prule->rule, r, sizeof(pf->prule->rule));
+ if ((pf->opts & PF_OPT_NOACTION) == 0) {
+ if (ioctl(pf->dev, DIOCADDRULE, pf->prule))
+ err(1, "DIOCADDRULE");
+ }
+ if (pf->opts & PF_OPT_VERBOSE)
+ print_rule(&pf->prule->rule);
+ return 0;
+}
- buf = load_file(filename, &len);
- if (buf == NULL)
+int
+pfctl_add_nat(struct pfctl *pf, struct pf_nat *n)
+{
+ memcpy(&pf->pnat->nat, n, sizeof(pf->pnat->nat));
+ if ((pf->opts & PF_OPT_NOACTION) == 0) {
+ if (ioctl(pf->dev, DIOCADDNAT, pf->pnat))
+ err(1, "DIOCADDNAT");
+ }
+ if (pf->opts & PF_OPT_VERBOSE)
+ print_nat(&pf->pnat->nat);
+ return 0;
+}
+
+int
+pfctl_add_rdr(struct pfctl *pf, struct pf_rdr *r)
+{
+ memcpy(&pf->prdr->rdr, r, sizeof(pf->prdr->rdr));
+ if ((pf->opts & PF_OPT_NOACTION) == 0) {
+ if (ioctl(pf->dev, DIOCADDRDR, pf->prdr))
+ err(1, "DIOCADDRDR");
+ }
+ if (pf->opts & PF_OPT_VERBOSE)
+ print_rdr(&pf->prdr->rdr);
+ return 0;
+}
+
+int
+pfctl_rules(int dev, char *filename, int opts)
+{
+ FILE *fin;
+ struct pfioc_rule pr;
+ struct pfctl pf;
+
+ if (strcmp(filename, "-") == 0)
+ fin = stdin;
+ else
+ fin = fopen(filename, "r");
+ if (fin == NULL)
return (1);
if ((opts & PF_OPT_NOACTION) == 0) {
if (ioctl(dev, DIOCBEGINRULES, &pr.ticket))
err(1, "DIOCBEGINRULES");
}
- n = 0;
- nr = 0;
- s = buf;
- do {
- char *line = next_line(&s);
- nr++;
- if (*line && (*line != '#'))
- if (parse_rule(nr, line, &pr.rule)) {
- if ((opts & PF_OPT_NOACTION) == 0) {
- if (ioctl(dev, DIOCADDRULE, &pr))
- err(1, "DIOCADDRULE");
- }
- if (opts & PF_OPT_VERBOSE)
- print_rule(&pr.rule);
- n++;
- }
- } while (s < (buf + len));
- free(buf);
+ /* fill in callback data */
+ pf.dev = dev;
+ pf.opts = opts;
+ pf.prule = &pr;
+ if (parse_rules(fin, &pf) < 0)
+ errx(1, "syntax error in rule file: pf rules not loaded");
if ((opts & PF_OPT_NOACTION) == 0) {
if (ioctl(dev, DIOCCOMMITRULES, &pr.ticket))
err(1, "DIOCCOMMITRULES");
+#if 0
if ((opts & PF_OPT_QUIET) == 0)
printf("%u rules loaded\n", n);
+#endif
}
+ if (fin != stdin)
+ fclose(fin);
return (0);
}
int
pfctl_nat(int dev, char *filename, int opts)
{
- struct pfioc_nat pn;
- struct pfioc_rdr pr;
- char *buf, *s;
- size_t len;
- unsigned n, r, nr;
+ FILE *fin;
+ struct pfioc_nat pn;
+ struct pfioc_rdr pr;
+ struct pfctl pf;
+
+ if (strcmp(filename, "-") == 0)
+ fin = stdin;
+ else
+ fin = fopen(filename, "r");
+ if (fin == NULL)
+ return (1);
if ((opts & PF_OPT_NOACTION) == 0) {
if (ioctl(dev, DIOCBEGINNATS, &pn.ticket))
@@ -361,48 +334,27 @@ pfctl_nat(int dev, char *filename, int opts)
if (ioctl(dev, DIOCBEGINRDRS, &pr.ticket))
err(1, "DIOCBEGINRDRS");
}
-
- buf = load_file(filename, &len);
- if (buf == NULL)
- return (1);
- n = 0;
- r = 0;
- nr = 0;
- s = buf;
- do {
- char *line = next_line(&s);
- nr++;
- if (*line && (*line == 'n'))
- if (parse_nat(nr, line, &pn.nat)) {
- if ((opts & PF_OPT_NOACTION) == 0)
- if (ioctl(dev, DIOCADDNAT, &pn))
- err(1, "DIOCADDNAT");
- if (opts & PF_OPT_VERBOSE)
- print_nat(&pn.nat);
- n++;
- }
- if (*line && (*line == 'r'))
- if (parse_rdr(nr, line, &pr.rdr)) {
- if ((opts & PF_OPT_NOACTION) == 0)
- if (ioctl(dev, DIOCADDRDR, &pr))
- err(1, "DIOCADDRDR");
- if (opts & PF_OPT_VERBOSE)
- print_rdr(&pr.rdr);
- r++;
- }
- } while (s < (buf + len));
-
+ /* fill in callback data */
+ pf.dev = dev;
+ pf.opts = opts;
+ pf.pnat = &pn;
+ pf.prdr = &pr;
+ if (parse_nat(fin, &pf) < 0)
+ errx(1, "syntax error in file: nat rules not loaded");
if ((opts & PF_OPT_NOACTION) == 0) {
if (ioctl(dev, DIOCCOMMITNATS, &pn.ticket))
err(1, "DIOCCOMMITNATS");
if (ioctl(dev, DIOCCOMMITRDRS, &pr.ticket))
err(1, "DIOCCOMMITRDRS");
+#if 0
if ((opts & PF_OPT_QUIET) == 0) {
printf("%u nat entries loaded\n", n);
printf("%u rdr entries loaded\n", r);
}
+#endif
}
- free(buf);
+ if (fin != stdin)
+ fclose(fin);
return (0);
}
@@ -425,7 +377,7 @@ main(int argc, char *argv[])
extern char *optarg;
extern int optind;
int error = 0;
- int dev;
+ int dev = -1;
int ch;
if (argc < 2)
@@ -470,9 +422,15 @@ main(int argc, char *argv[])
}
}
- dev = open("/dev/pf", O_RDWR);
- if (dev == -1)
- err(1, "open(\"/dev/pf\")");
+ if ((opts & PF_OPT_NOACTION) == 0) {
+ dev = open("/dev/pf", O_RDWR);
+ if (dev == -1)
+ err(1, "open(\"/dev/pf\")");
+ } else {
+ /* turn off options */
+ opts &= ~ (PF_OPT_DISABLE | PF_OPT_ENABLE);
+ clearopt = logopt = showopt = NULL;
+ }
if (opts & PF_OPT_DISABLE)
if (pfctl_disable(dev, opts))