summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2001-08-11 09:55:00 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2001-08-11 09:55:00 +0000
commit8eaeb9437587036beb8493da9d85cfc1e35828db (patch)
tree025e6c5acdee7ef283aa9e453a9d99e35f2cf35f
parent0f7af2ec36331a03bad16c30540312fa6454bb8a (diff)
\+\n support, and spit out cc-style error messages. the parser's line
counting is lex dependent, and will need to be tweaked
-rw-r--r--sbin/pfctl/parse.y158
-rw-r--r--sbin/pfctl/pfctl.c18
-rw-r--r--sbin/pfctl/pfctl_parser.h20
3 files changed, 109 insertions, 87 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 5fa56e07d2a..a6be808874d 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.16 2001/07/31 09:02:18 wilfried Exp $ */
+/* $OpenBSD: parse.y,v 1.17 2001/08/11 09:54:59 deraadt Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -38,6 +38,7 @@
#include <stdio.h>
#include <netdb.h>
+#include <stdarg.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
@@ -52,7 +53,7 @@ static int lineno = 1;
static int errors = 0;
static int natmode = 0;
-static int proto = 0; /* this is a synthesysed attribute */
+static int proto = 0; /* this is a synthesized attribute */
int rule_consistent(struct pf_rule *);
int yyparse(void);
@@ -110,10 +111,10 @@ pfrule: action direction log quick iface proto fromto flags icmpspec keep nodf
{
struct pf_rule r;
- if (natmode)
- errx(1, "line %d: filter rule in nat mode",
- lineno);
-
+ if (natmode) {
+ yyerror("filter rule not permitted in nat mode");
+ YYERROR;
+ }
memset(&r, 0, sizeof(r));
r.action = $1.b1;
@@ -127,7 +128,7 @@ pfrule: action direction log quick iface proto fromto flags icmpspec keep nodf
if ($5.string)
memcpy(r.ifname, $5.string, sizeof(r.ifname));
r.proto = $6;
- proto = 0; /* reset syntesysed attribute */
+ proto = 0; /* reset synthesized attribute */
memcpy(&r.src, $7.src, sizeof(r.src));
free($7.src);
@@ -146,7 +147,7 @@ pfrule: action direction log quick iface proto fromto flags icmpspec keep nodf
r.min_ttl = $12;
if (rule_consistent(&r) < 0)
- warnx("skipping rule due to errors");
+ yyerror("skipping rule due to errors");
else
pfctl_add_rule(pf, &r);
}
@@ -167,8 +168,7 @@ blockspec: { $$.b2 = 0; $$.w = 0; }
struct icmpcodeent *p;
if ((p = geticmpcodebyname(ICMP_UNREACH, $3)) == NULL) {
- warnx("line %d: unknown icmp code %s",
- lineno, $3);
+ yyerror("unknown icmp code %s", $3);
YYERROR;
}
$$.w = (p->type << 8) | p->code;
@@ -193,7 +193,7 @@ iface: { $$.string = NULL; }
| ON STRING { $$.string = strdup($2); }
| ON '!' STRING {
if (! natmode) {
- warnx("can't '!' interface in pf rule");
+ yyerror("can't '!' interface in pf rule");
YYERROR;
}
$$.string = strdup($3); $$.not = 1;
@@ -205,8 +205,7 @@ proto: { $$ = proto; }
struct protoent *p;
if ((p = getprotobynumber($2)) == NULL) {
- warnx("line %d: unknown protocol %d", lineno,
- $2);
+ yyerror("unknown protocol %d", $2);
YYERROR;
}
proto = $$ = p->p_proto;
@@ -215,8 +214,7 @@ proto: { $$ = proto; }
struct protoent *p;
if ((p = getprotobyname($2)) == NULL) {
- warnx("line %d: unknown protocol %s", lineno,
- $2);
+ yyerror("unknown protocol %s", $2);
YYERROR;
}
proto = $$ = p->p_proto;
@@ -258,7 +256,7 @@ host: address {
|
address '/' NUMBER {
if ($3 < 0 || $3 > 32) {
- warnx("illegal netmask value %d", $3);
+ yyerror("illegal netmask value %d", $3);
YYERROR;
}
$$ = new_addr();
@@ -272,8 +270,7 @@ address: STRING {
if (inet_pton(AF_INET, $1, &$$) != 1) {
if ((hp = gethostbyname($1)) == NULL) {
- warnx("line %d: cannot resolve %s",
- lineno, $1);
+ yyerror("cannot resolve %s", $1);
YYERROR;
}
memcpy(&$$, hp->h_addr, sizeof(u_int32_t));
@@ -282,7 +279,7 @@ address: STRING {
| NUMBER '.' NUMBER '.' NUMBER '.' NUMBER {
if ($1 < 0 || $3 < 0 || $5 < 0 || $7 < 0 ||
$1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
- warnx("illegal ip address %d.%d.%d.%d",
+ yyerror("illegal ip address %d.%d.%d.%d",
$1, $3, $5, $7);
YYERROR;
}
@@ -306,7 +303,7 @@ portspec: PORT PORTUNARY port {
port: NUMBER {
if (0 > $1 || $1 > 65535) {
- warnx("illegal port value %d", $1);
+ yyerror("illegal port value %d", $1);
YYERROR;
}
$$ = htons($1);
@@ -314,13 +311,12 @@ port: NUMBER {
| STRING {
struct servent *s = NULL;
- /* use synthesysed attribute */
+ /* use synthesized attribute */
if (proto) {
s = getservbyname($1,
proto == IPPROTO_TCP ? "tcp" : "udp");
if (s == NULL) {
- warnx("line %d: unknown protocol %s",
- lineno, $1);
+ yyerror("unknown protocol %s", $1);
YYERROR;
}
$$ = s->s_port;
@@ -335,7 +331,7 @@ flags: { $$.b1 = 0; $$.b2 = 0; }
int f;
if ((f = parse_flags($2)) < 0) {
- warnx("line %d: bad flags %s", lineno, $2);
+ yyerror("bad flags %s", $2);
YYERROR;
}
$$.b1 = f;
@@ -345,12 +341,12 @@ flags: { $$.b1 = 0; $$.b2 = 0; }
int f;
if ((f = parse_flags($2)) < 0) {
- warnx("line %d: bad flags %s", lineno, $2);
+ yyerror("bad flags %s", $2);
YYERROR;
}
$$.b1 = f;
if ((f = parse_flags($4)) < 0) {
- warnx("line %d: bad flags %s", lineno, $4);
+ yyerror("bad flags %s", $4);
YYERROR;
}
$$.b2 = f;
@@ -360,7 +356,7 @@ flags: { $$.b1 = 0; $$.b2 = 0; }
$$.b1 = 0;
if ((f = parse_flags($3)) < 0) {
- warnx("line %d: bad flags %s", lineno, $3);
+ yyerror("bad flags %s", $3);
YYERROR;
}
$$.b2 = f;
@@ -371,7 +367,7 @@ icmpspec: { $$.b1 = 0; $$.b2 = 0; }
| ICMPTYPE icmptype { $$.b1 = $2; $$.b2 = 0; }
| ICMPTYPE icmptype CODE NUMBER {
if ($4 < 0 || $4 > 255) {
- warnx("illegal icmp code %d", $4);
+ yyerror("illegal icmp code %d", $4);
YYERROR;
}
$$.b1 = $2;
@@ -382,8 +378,7 @@ icmpspec: { $$.b1 = 0; $$.b2 = 0; }
$$.b1 = $2;
if ((p = geticmpcodebyname($2, $4)) == NULL) {
- warnx("line %d: unknown icmp-code %s",
- lineno, $4);
+ yyerror("unknown icmp-code %s", $4);
YYERROR;
}
$$.b2 = p->code + 1;
@@ -394,15 +389,14 @@ icmptype: STRING {
struct icmptypeent *p;
if ((p = geticmptypebyname($1)) == NULL) {
- warnx("line %d: unknown icmp-type %s",
- lineno, $1);
+ yyerror("unknown icmp-type %s", $1);
YYERROR;
}
$$ = p->type + 1;
}
| NUMBER {
if ($1 < 0 || $1 > 255) {
- warnx("illegal icmp type %d", $1);
+ yyerror("illegal icmp type %d", $1);
YYERROR;
}
$$ = $1 + 1;
@@ -417,7 +411,7 @@ keep: { $$ = 0; }
minttl: { $$ = 0; }
| MINTTL NUMBER {
if ($2 < 0 || $2 > 255) {
- warnx("illegal min-ttl value %d", $2);
+ yyerror("illegal min-ttl value %d", $2);
YYERROR;
}
$$ = $2;
@@ -432,9 +426,10 @@ natrule: NAT iface proto FROM ipspec TO ipspec ARROW address
{
struct pf_nat nat;
- if (!natmode)
- errx(1, "line %d: nat rule in filter mode",
- lineno);
+ if (!natmode) {
+ yyerror("nat rule not permitted in filter mode");
+ YYERROR;
+ }
memset(&nat, 0, sizeof(nat));
@@ -444,7 +439,7 @@ natrule: NAT iface proto FROM ipspec TO ipspec ARROW address
nat.ifnot = $2.not;
}
nat.proto = $3;
- proto = 0; /* reset syntesysed attribute */
+ proto = 0; /* reset synthesized attribute */
nat.saddr = $5->addr;
nat.smask = $5->mask;
@@ -467,8 +462,8 @@ rdrrule: RDR { proto = IPPROTO_TCP; } iface proto FROM ipspec TO ipspec dport AR
struct pf_rdr rdr;
if (!natmode) {
- errx(1, "line %d: nat rule in filter mode",
- lineno);
+ yyerror("rdr rule not permitted in filter mode");
+ YYERROR;
}
memset(&rdr, 0, sizeof(rdr));
@@ -479,7 +474,7 @@ rdrrule: RDR { proto = IPPROTO_TCP; } iface proto FROM ipspec TO ipspec dport AR
rdr.ifnot = $3.not;
}
rdr.proto = $4;
- proto = 0; /* reset syntesysed attribute */
+ proto = 0; /* reset synthesized attribute */
rdr.saddr = $6->addr;
rdr.smask = $6->mask;
@@ -529,10 +524,17 @@ rport: PORT port {
%%
int
-yyerror(char *s)
+yyerror(char *fmt, ...)
{
+ va_list ap;
+ extern char *infile;
errors = 1;
- warnx("%s near line %d", s, lineno);
+
+ va_start(ap, fmt);
+ fprintf(stderr, "%s:%d: ", infile, lineno);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
return (0);
}
@@ -543,42 +545,42 @@ rule_consistent(struct pf_rule *r)
if (r->action == PF_SCRUB) {
if (r->quick) {
- warnx("quick does not apply to scrub");
+ yyerror("quick does not apply to scrub");
problems++;
}
if (r->keep_state) {
- warnx("keep state does not apply to scrub");
+ yyerror("keep state does not apply to scrub");
problems++;
}
if (r->src.port_op) {
- warnx("src port does not apply to scrub");
+ yyerror("src port does not apply to scrub");
problems++;
}
if (r->dst.port_op) {
- warnx("dst port does not apply to scrub");
+ yyerror("dst port does not apply to scrub");
problems++;
}
if (r->type || r->code) {
- warnx("icmp-type/code does not apply to scrub");
+ yyerror("icmp-type/code does not apply to scrub");
problems++;
}
} else {
if (r->rule_flag & PFRULE_NODF) {
- warnx("nodf applies only to scrub");
+ yyerror("nodf only applies to scrub");
problems++;
}
if (r->min_ttl) {
- warnx("min-ttl applies only to scrub");
+ yyerror("min-ttl only applies to scrub");
problems++;
}
}
if (r->proto != IPPROTO_TCP && r->proto != IPPROTO_UDP &&
(r->src.port_op || r->dst.port_op)) {
- warnx("ports do only apply to tcp/udp");
+ yyerror("port only applies to tcp/udp");
problems++;
}
if (r->proto != IPPROTO_ICMP && (r->type || r->code)) {
- warnx("icmp-type/code does only apply to icmp");
+ yyerror("icmp-type/code only applies to icmp");
problems++;
}
return (-problems);
@@ -636,19 +638,39 @@ lookup(char *s)
}
int
+lgetc(FILE *fin)
+{
+ int c, next;
+
+restart:
+ c = getc(fin);
+ if (c == '\\') {
+ next = getc(fin);
+ if (next != '\n') {
+ ungetc(next, fin);
+ return (c);
+ }
+ lineno++;
+ goto restart;
+ }
+ return (c);
+}
+
+int
yylex(void)
{
char *p, buf[8096];
int c, next;
int token;
- while ((c = getc(fin)) == ' ' || c == '\t')
+ while ((c = lgetc(fin)) == ' ' || c == '\t')
;
+
if (c == '#')
- while ((c = getc(fin)) != '\n' && c != EOF)
+ while ((c = lgetc(fin)) != '\n' && c != EOF)
;
if (c == '-') {
- next = getc(fin);
+ next = lgetc(fin);
if (next == '>')
return (ARROW);
ungetc(next, fin);
@@ -658,7 +680,7 @@ yylex(void)
yylval.i = PF_OP_EQ;
return (PORTUNARY);
case '!':
- next = getc(fin);
+ next = lgetc(fin);
if (next == '=') {
yylval.i = PF_OP_NE;
return (PORTUNARY);
@@ -666,7 +688,7 @@ yylex(void)
ungetc(next, fin);
break;
case '<':
- next = getc(fin);
+ next = lgetc(fin);
if (next == '>') {
yylval.i = PF_OP_XRG;
return (PORTBINARY);
@@ -679,7 +701,7 @@ yylex(void)
return (PORTUNARY);
break;
case '>':
- next = getc(fin);
+ next = lgetc(fin);
if (next == '<') {
yylval.i = PF_OP_IRG;
return (PORTBINARY);
@@ -697,11 +719,11 @@ yylex(void)
do {
u_int64_t n = (u_int64_t)yylval.number * 10 + c - '0';
if (n > 0xffffffff) {
- warnx("line %d: number is too large", lineno);
+ yyerror("number is too large");
return (ERROR);
}
yylval.number = (u_int32_t)n;
- } while ((c = getc(fin)) != EOF && isdigit(c));
+ } while ((c = lgetc(fin)) != EOF && isdigit(c));
ungetc(c, fin);
if (debug > 1)
fprintf(stderr, "number: %d\n", yylval.number);
@@ -709,26 +731,18 @@ yylex(void)
}
#define allowed_in_string(x) \
- isalnum(x) || \
- ( ispunct(x) && \
- x != '(' && \
- x != ')' && \
- x != '<' && \
- x != '>' && \
- x != '!' && \
- x != '=' && \
- x != '/' && \
- x != '#' )
+ isalnum(x) || (ispunct(x) && x != '(' && x != ')' && x != '<' \
+ && x != '>' && x != '!' && x != '=' && x != '/' && x != '#')
if (isalnum(c)) {
p = buf;
do {
*p++ = c;
if (p-buf >= sizeof buf) {
- warnx("line %d: string too long", lineno);
+ yyerror("string too long");
return (ERROR);
}
- } while ((c = getc(fin)) != EOF && (allowed_in_string(c)));
+ } while ((c = lgetc(fin)) != EOF && (allowed_in_string(c)));
ungetc(c, fin);
*p = '\0';
token = lookup(buf);
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 3787d2d6c76..79edf2e06e4 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.c,v 1.30 2001/07/26 12:55:15 dhartmei Exp $ */
+/* $OpenBSD: pfctl.c,v 1.31 2001/08/11 09:54:59 deraadt Exp $ */
/*
* Copyright (c) 2001, Daniel Hartmeier
@@ -75,6 +75,8 @@ char *natopt;
char *rulesopt;
char *showopt;
+char *infile;
+
void
usage()
{
@@ -286,10 +288,13 @@ pfctl_rules(int dev, char *filename, int opts)
struct pfioc_rule pr;
struct pfctl pf;
- if (strcmp(filename, "-") == 0)
+ if (strcmp(filename, "-") == 0) {
+ infile = "stdin";
fin = stdin;
- else
+ } else {
fin = fopen(filename, "r");
+ infile = filename;
+ }
if (fin == NULL)
return (1);
if ((opts & PF_OPT_NOACTION) == 0) {
@@ -323,10 +328,13 @@ pfctl_nat(int dev, char *filename, int opts)
struct pfioc_rdr pr;
struct pfctl pf;
- if (strcmp(filename, "-") == 0)
+ if (strcmp(filename, "-") == 0) {
fin = stdin;
- else
+ infile = "stdin";
+ } else {
fin = fopen(filename, "r");
+ infile = filename;
+ }
if (fin == NULL)
return (1);
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
index ce7eab8a4b2..2a658b8e788 100644
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.h,v 1.6 2001/07/16 21:09:38 markus Exp $ */
+/* $OpenBSD: pfctl_parser.h,v 1.7 2001/08/11 09:54:59 deraadt Exp $ */
/*
* Copyright (c) 2001, Daniel Hartmeier
@@ -49,11 +49,11 @@ int parse_rules(FILE *, struct pfctl *);
int parse_nat(FILE *, struct pfctl *);
int parse_flags(char *);
-void print_rule (struct pf_rule *);
-void print_nat (struct pf_nat *);
-void print_rdr (struct pf_rdr *);
-void print_state (struct pf_state *);
-void print_status (struct pf_status *);
+void print_rule(struct pf_rule *);
+void print_nat(struct pf_nat *);
+void print_rdr(struct pf_rdr *);
+void print_state(struct pf_state *);
+void print_status(struct pf_status *);
struct icmptypeent {
char *name;
@@ -66,9 +66,9 @@ struct icmpcodeent {
u_int8_t code;
};
-struct icmptypeent * geticmptypebynumber(u_int8_t);
-struct icmptypeent * geticmptypebyname(char *);
-struct icmpcodeent * geticmpcodebynumber(u_int8_t, u_int8_t);
-struct icmpcodeent * geticmpcodebyname(u_long, char *);
+struct icmptypeent *geticmptypebynumber(u_int8_t);
+struct icmptypeent *geticmptypebyname(char *);
+struct icmpcodeent *geticmpcodebynumber(u_int8_t, u_int8_t);
+struct icmpcodeent *geticmpcodebyname(u_long, char *);
#endif /* _PFCTL_PARSER_H_ */